OpenCores
URL https://opencores.org/ocsvn/plasma/plasma/trunk

Subversion Repositories plasma

[/] [plasma/] [trunk/] [kernel/] [tcpip.c] - Blame information for rev 247

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 155 rhoads
/*--------------------------------------------------------------------
2
 * TITLE: Plasma TCP/IP Protocol Stack
3
 * AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4
 * DATE CREATED: 4/22/06
5
 * FILENAME: tcpip.c
6
 * PROJECT: Plasma CPU core
7
 * COPYRIGHT: Software placed into the public domain by the author.
8
 *    Software 'as is' without warranty.  Author liable for nothing.
9
 * DESCRIPTION:
10
 *    Plasma TCP/IP Protocol Stack
11
 *
12
 *    Possible call stack when receiving a packet:
13
 *       IPMainThread()
14
 *          IPProcessEthernetPacket()
15
 *             IPProcessTCPPacket()
16
 *                TCPSendPacket()
17
 *                   IPSendPacket()
18
 *                      IPChecksum()
19
 *                      IPSendFrame()
20
 *                         FrameInsert()
21
 *--------------------------------------------------------------------*/
22
#ifdef WIN32
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <assert.h>
27
#define _LIBC
28
#endif
29
#include "rtos.h"
30
#include "tcpip.h"
31
 
32
#ifdef WIN32
33
#undef OS_CriticalBegin
34
#undef OS_CriticalEnd
35
#define OS_CriticalBegin() 0
36
#define OS_CriticalEnd(A)
37
#define OS_ThreadCreate(A,B,C,D,E) 0
38
#define OS_ThreadSleep(A)
39
#define OS_ThreadTime() 0
40 157 rhoads
#define OS_ThreadSelf() 0
41
#define OS_MutexCreate(A) NULL
42
#define OS_MutexPend(A)
43
#define OS_MutexPost(A)
44 155 rhoads
#define OS_MQueueCreate(A,B,C) 0
45
#define OS_MQueueSend(A,B) 0
46
#define OS_MQueueGet(A,B,C) 0
47
#define UartPacketConfig(A,B,C)
48
#define UartPacketSend(A,B)
49
#define UartPrintf printf
50
#define UartPrintfCritical printf
51
#define Led(A)
52 225 rhoads
#define OS_Job(A,B,C,D) A(B,C,D)
53 155 rhoads
#endif
54
 
55
//ETHER FIELD                 OFFSET   LENGTH   VALUE
56
#define ETHERNET_DEST         0        //6
57
#define ETHERNET_SOURCE       6        //6
58
#define ETHERNET_FRAME_TYPE   12       //2      IP=0x0800; ARP=0x0806
59
 
60
//ARP   FIELD                 OFFSET   LENGTH   VALUE
61
#define ARP_HARD_TYPE         14       //2      0x0001
62
#define ARP_PROT_TYPE         16       //2      0x0800
63
#define ARP_HARD_SIZE         18       //1      0x06
64
#define ARP_PROT_SIZE         19       //1      0x04
65
#define ARP_OP                20       //2      ARP=1;ARPreply=2
66
#define ARP_ETHERNET_SENDER   22       //6
67
#define ARP_IP_SENDER         28       //4
68
#define ARP_ETHERNET_TARGET   32       //6
69
#define ARP_IP_TARGET         38       //4
70
#define ARP_PAD               42       //18     0
71
 
72
//IP    FIELD                 OFFSET   LENGTH   VALUE
73
#define IP_VERSION_LENGTH     14       //1      0x45
74
#define IP_TYPE_OF_SERVICE    15       //1      0x00
75
#define IP_LENGTH             16       //2
76
#define IP_ID16               18       //2
77
#define IP_FRAG_OFFSET        20       //2
78
#define IP_TIME_TO_LIVE       22       //1      0x80
79
#define IP_PROTOCOL           23       //1      TCP=0x06;PING=0x01;UDP=0x11
80
#define IP_CHECKSUM           24       //2
81
#define IP_SOURCE             26       //4
82
#define IP_DEST               30       //4
83
 
84
//PSEUDO FIELD                OFFSET   LENGTH   VALUE
85
#define PSEUDO_IP_SOURCE      0        //4
86
#define PSEUDO_IP_DEST        4        //4
87
#define PSEUDO_ZERO           8        //1      0
88
#define PSEUDO_IP_PROTOCOL    9        //1
89
#define PSEUDO_LENGTH         10       //2
90
 
91
//UDP   FIELD                 OFFSET   LENGTH   VALUE
92
#define UDP_SOURCE_PORT       34       //2
93
#define UDP_DEST_PORT         36       //2
94
#define UDP_LENGTH            38       //2
95
#define UDP_CHECKSUM          40       //2
96
#define UDP_DATA              42
97
 
98
//DHCP  FIELD                 OFFSET   LENGTH   VALUE
99
#define DHCP_OPCODE           42       //1      REQUEST=1;REPLY=2
100
#define DHCP_HW_TYPE          43       //1      1
101
#define DHCP_HW_LEN           44       //1      6
102
#define DHCP_HOP_COUNT        45       //1      0
103
#define DHCP_TRANS_ID         46       //4
104
#define DHCP_NUM_SEC          50       //2      0
105
#define DHCP_UNUSED           52       //2
106
#define DHCP_CLIENT_IP        54       //4
107
#define DHCP_YOUR_IP          58       //4
108
#define DHCP_SERVER_IP        62       //4
109
#define DHCP_GATEWAY_IP       66       //4
110
#define DHCP_CLIENT_ETHERNET  70       //16
111
#define DHCP_SERVER_NAME      86       //64
112
#define DHCP_BOOT_FILENAME    150      //128
113
#define DHCP_MAGIC_COOKIE     278      //4      0x63825363
114
#define DHCP_OPTIONS          282      //N
115
 
116
#define DHCP_MESSAGE_TYPE     53       //1 type
117
#define DHCP_DISCOVER         1
118
#define DHCP_OFFER            2
119
#define DHCP_REQUEST          3
120
#define DHCP_ACK              5
121
#define DHCP_REQUEST_IP       50       //4 ip
122
#define DHCP_REQUEST_SERV_IP  54       //4 ip
123
#define DHCP_CLIENT_ID        61       //7 1 ethernet
124
#define DHCP_HOST_NAME        12       //6 plasma
125
#define DHCP_PARAMS           55       //4 1=subnet; 15=domain_name; 3=router; 6=dns
126
#define DHCP_PARAM_SUBNET     1
127
#define DHCP_PARAM_ROUTER     3
128
#define DHCP_PARAM_DNS        6
129
#define DHCP_END_OPTION       0xff
130
 
131
//DHCP  FIELD                 OFFSET   LENGTH   VALUE
132 206 rhoads
#define DNS_ID                0        //2    
133
#define DNS_FLAGS             2        //2      
134
#define DNS_NUM_QUESTIONS     4        //2      1 
135
#define DNS_NUM_ANSWERS_RR    6        //2      0/1
136
#define DNS_NUM_AUTHORITY_RR  8        //2      0 
137 155 rhoads
#define DNS_NUM_ADDITIONAL_RR 10       //2      0
138
#define DNS_QUESTIONS         12       //2   
139
 
140
#define DNS_FLAGS_RESPONSE    0x8000
141
#define DNS_FLAGS_RECURSIVE   0x0100
142
#define DNS_FLAGS_ERROR       0x0003
143
#define DNS_FLAGS_OK          0x0000
144
#define DNS_QUERY_TYPE_IP     1
145
#define DNS_QUERY_CLASS       1
146
#define DNS_PORT              53
147
 
148
//TCP   FIELD                 OFFSET   LENGTH   VALUE
149
#define TCP_SOURCE_PORT       34       //2
150
#define TCP_DEST_PORT         36       //2
151
#define TCP_SEQ               38       //4
152
#define TCP_ACK               42       //4
153
#define TCP_HEADER_LENGTH     46       //1      0x50
154
#define TCP_FLAGS             47       //1      SYNC=0x2;ACK=0x10;FIN=0x1
155
#define TCP_WINDOW_SIZE       48       //2
156
#define TCP_CHECKSUM          50       //2
157
#define TCP_URGENT_POINTER    52       //2
158
#define TCP_DATA              54       //length-N
159
 
160
#define TCP_FLAGS_FIN         1
161
#define TCP_FLAGS_SYN         2
162
#define TCP_FLAGS_RST         4
163 209 rhoads
#define TCP_FLAGS_PSH         8
164 155 rhoads
#define TCP_FLAGS_ACK         16
165
 
166
//PING  FIELD                 OFFSET   LENGTH   VALUE
167
#define PING_TYPE             34       //1      SEND=8;REPLY=0
168
#define PING_CODE             35       //1      0
169
#define PING_CHECKSUM         36       //2
170
#define PING_ID               38       //2
171
#define PING_SEQUENCE         40       //2
172
#define PING_DATA             44
173
 
174
static void IPClose2(IPSocket *Socket);
175
 
176
static uint8 ethernetAddressNull[] =    {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
177 206 rhoads
static uint8 ethernetAddressGateway[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
178
#ifndef WIN32
179 155 rhoads
static uint8 ethernetAddressPlasma[] =  {0x00, 0x10, 0xdd, 0xce, 0x15, 0xd4};
180 206 rhoads
#else
181
static uint8 ethernetAddressPlasma[] =  {0x00, 0x10, 0xdd, 0xce, 0x15, 0xd5};
182
#endif
183 155 rhoads
 
184
static uint8 ipAddressPlasma[] =  {0x9d, 0xfe, 0x28, 10};   //changed by DHCP
185
static uint8 ipAddressGateway[] = {0xff, 0xff, 0xff, 0xff}; //changed by DHCP
186
static uint32 ipAddressDns;                                 //changed by DHCP
187
 
188 157 rhoads
static OS_Mutex_t *IPMutex;
189 155 rhoads
static int FrameFreeCount=FRAME_COUNT;
190
static IPFrame *FrameFreeHead;
191
static IPFrame *FrameSendHead;
192
static IPFrame *FrameSendTail;
193
static IPFrame *FrameResendHead;
194
static IPFrame *FrameResendTail;
195
static IPSocket *SocketHead;
196
static uint32 Seconds;
197
static int DhcpRetrySeconds;
198
static IPFuncPtr FrameSendFunc;
199
static OS_MQueue_t *IPMQueue;
200 157 rhoads
static OS_Thread_t *IPThread;
201 155 rhoads
int IPVerbose=1;
202
 
203
static const unsigned char dhcpDiscover[] = {
204
   0xff, 0xff, 0xff, 0xff, 0xff, 0xff,             //dest
205
   0x00, 0x10, 0xdd, 0xce, 0x15, 0xd4,             //src
206
   0x08, 0x00,
207
   0x45, 0x00, 0x01, 0x48, 0x2e, 0xf5, 0x00, 0x00, //ip
208
   0x80, 0x11, 0x0a, 0xb1, 0x00, 0x00, 0x00, 0x00,
209
   0xff, 0xff, 0xff, 0xff,
210
   0x00, 0x44, 0x00, 0x43, 0x01, 0x34, 0x45, 0x66, //udp
211
   0x01, 0x01, 0x06, 0x00, 0x69, 0x26, 0xb5, 0x52  //dhcp
212
};
213
 
214
static const unsigned char dhcpOptions[] = {
215
   0x63, 0x82, 0x53, 0x63,      //cookie
216
   0x35, 0x01, 0x01,            //DHCP Discover
217
   0x3d, 0x07, 0x01, 0x00, 0x10, 0xdd, 0xce, 0x15, 0xd4, //Client identifier
218 206 rhoads
#ifndef WIN32
219 155 rhoads
   0x0c, 0x06, 'p', 'l', 'a', 's', 'm', 'a',             //Host name
220 206 rhoads
#else
221
   0x0c, 0x06, 'p', 'l', 'a', 's', 'm', 'b',             //Host name
222
#endif
223 155 rhoads
   0x37, 0x03, DHCP_PARAM_SUBNET, DHCP_PARAM_ROUTER, DHCP_PARAM_DNS, //Parameters
224
   DHCP_END_OPTION
225
};
226
 
227
 
228
//Get a free frame; can be called from an ISR
229 157 rhoads
IPFrame *IPFrameGet(int freeCount)
230 155 rhoads
{
231
   IPFrame *frame=NULL;
232
   uint32 state;
233 157 rhoads
 
234
   state = OS_CriticalBegin();
235
   if(FrameFreeCount > freeCount)
236 155 rhoads
   {
237 157 rhoads
      --FrameFreeCount;
238
      frame = FrameFreeHead;
239
      if(FrameFreeHead)
240
         FrameFreeHead = FrameFreeHead->next;
241 155 rhoads
   }
242 157 rhoads
   OS_CriticalEnd(state);
243 155 rhoads
   if(frame)
244
   {
245 157 rhoads
      assert(frame->state == 0);
246
      frame->state = 1;
247 155 rhoads
   }
248
   return frame;
249
}
250
 
251
 
252
static void FrameFree(IPFrame *frame)
253
{
254
   uint32 state;
255
 
256
   assert(frame->state == 1);
257
   frame->state = 0;
258
   state = OS_CriticalBegin();
259
   frame->next = FrameFreeHead;
260
   FrameFreeHead = frame;
261
   ++FrameFreeCount;
262
   OS_CriticalEnd(state);
263
}
264
 
265
 
266
static void FrameInsert(IPFrame **head, IPFrame **tail, IPFrame *frame)
267
{
268
   assert(frame->state == 1);
269
   frame->state = 2;
270 157 rhoads
   OS_MutexPend(IPMutex);
271 155 rhoads
   frame->prev = NULL;
272
   frame->next = *head;
273
   if(*head)
274
      (*head)->prev = frame;
275
   *head = frame;
276
   if(*tail == NULL)
277
      *tail = frame;
278 157 rhoads
   OS_MutexPost(IPMutex);
279 155 rhoads
}
280
 
281
 
282
static void FrameRemove(IPFrame **head, IPFrame **tail, IPFrame *frame)
283
{
284
   assert(frame->state == 2);
285
   frame->state = 1;
286
   if(frame->prev)
287
      frame->prev->next = frame->next;
288
   else
289
      *head = frame->next;
290
   if(frame->next)
291
      frame->next->prev = frame->prev;
292
   else
293
      *tail = frame->prev;
294
   frame->prev = NULL;
295
   frame->next = NULL;
296
}
297
 
298
 
299
static int IPChecksum(int checksum, const unsigned char *data, int length)
300
{
301
   int i;
302
   checksum = ~checksum & 0xffff;
303
   for(i = 0; i < length-1; i += 2)
304
   {
305
      checksum += (data[i] << 8) | data[i+1];
306
   }
307
   if(i < length)
308
      checksum += data[i] << 8;
309
   while(checksum >> 16)
310
      checksum = (checksum & 0xffff) + (checksum >> 16);
311
   checksum = ~checksum & 0xffff;
312
   return checksum;
313
}
314
 
315
 
316
static int EthernetVerifyChecksums(const unsigned char *packet, int length)
317
{
318
   int checksum, length2;
319
   unsigned char pseudo[12];
320
 
321
   //Calculate checksums
322
   if(packet[ETHERNET_FRAME_TYPE+1] == 0x00)  //IP
323
   {
324
      checksum = IPChecksum(0xffff, packet+IP_VERSION_LENGTH, 20);
325
      if(checksum)
326
         return -1;
327
      if(packet[IP_PROTOCOL] == 0x01)         //PING
328
      {
329
         checksum = IPChecksum(0xffff, packet+PING_TYPE, length-PING_TYPE);
330
      }
331
      else if(packet[IP_PROTOCOL] == 0x11)    //UDP
332
      {
333
         if(packet[UDP_CHECKSUM] == 0 && packet[UDP_CHECKSUM+1] == 0)
334
            return 0;
335
         memcpy(pseudo+PSEUDO_IP_SOURCE, packet+IP_SOURCE, 4);
336
         memcpy(pseudo+PSEUDO_IP_DEST, packet+IP_DEST, 4);
337
         pseudo[PSEUDO_ZERO] = 0;
338
         pseudo[PSEUDO_IP_PROTOCOL] = packet[IP_PROTOCOL];
339
         memcpy(pseudo+PSEUDO_LENGTH, packet+UDP_LENGTH, 2);
340
         checksum = IPChecksum(0xffff, pseudo, 12);
341
         length2 = (packet[UDP_LENGTH] << 8) + packet[UDP_LENGTH+1];
342
         checksum = IPChecksum(checksum, packet+UDP_SOURCE_PORT, length);
343
      }
344
      else if(packet[IP_PROTOCOL] == 0x06)    //TCP
345
      {
346
         memcpy(pseudo+PSEUDO_IP_SOURCE, packet+IP_SOURCE, 4);
347
         memcpy(pseudo+PSEUDO_IP_DEST, packet+IP_DEST, 4);
348
         pseudo[PSEUDO_ZERO] = 0;
349
         pseudo[PSEUDO_IP_PROTOCOL] = packet[IP_PROTOCOL];
350
         length = (packet[IP_LENGTH] << 8) + packet[IP_LENGTH+1];
351
         length2 = length - 20;
352
         pseudo[PSEUDO_LENGTH] = (unsigned char)(length2 >> 8);
353
         pseudo[PSEUDO_LENGTH+1] = (unsigned char)length2;
354
         checksum = IPChecksum(0xffff, pseudo, 12);
355
         checksum = IPChecksum(checksum, packet+TCP_SOURCE_PORT, length2);
356
      }
357
      if(checksum)
358
         return -1;
359
   }
360
   return 0;
361
}
362
 
363
 
364
static void IPFrameReschedule(IPFrame *frame)
365
{
366
   int length;
367
   length = frame->length - TCP_DATA;
368 160 rhoads
   if(frame->packet[TCP_FLAGS] & (TCP_FLAGS_FIN | TCP_FLAGS_SYN))
369 155 rhoads
      ++length;
370
   if(frame->socket == NULL || frame->socket->state == IP_UDP || length == 0 ||
371 209 rhoads
      frame->socket->state == IP_PING || ++frame->retryCnt > 4)
372 155 rhoads
   {
373
      FrameFree(frame);     //can't be ACK'ed
374
   }
375
   else
376
   {
377
      //Put on resend list until TCP ACK'ed
378
      frame->timeout = RETRANSMIT_TIME;
379
      FrameInsert(&FrameResendHead, &FrameResendTail, frame);
380
   }
381
}
382
 
383
 
384
static void IPSendFrame(IPFrame *frame)
385
{
386
   uint32 message[4];
387
 
388
   if(FrameSendFunc)
389
   {
390
      //Single threaded
391
      FrameSendFunc(frame->packet, frame->length);
392
      IPFrameReschedule(frame);
393
   }
394
   else
395
   {
396
      //Add Packet to send queue
397
      FrameInsert(&FrameSendHead, &FrameSendTail, frame);
398
 
399
      //Wakeup sender thread
400
      message[0] = 2;
401
      OS_MQueueSend(IPMQueue, message);
402
   }
403
}
404
 
405
 
406
static void IPSendPacket(IPSocket *socket, IPFrame *frame, int length)
407
{
408
   int checksum, length2=length;
409
   unsigned char pseudo[12], *packet=frame->packet;
410
 
411
   frame->length = (uint16)length;
412
 
413
   //Calculate checksums
414
   if(packet[ETHERNET_FRAME_TYPE+1] == 0x00)  //IP
415
   {
416
      length2 = length - IP_VERSION_LENGTH;
417
      packet[IP_LENGTH] = (uint8)(length2 >> 8);
418
      packet[IP_LENGTH+1] = (uint8)length2;
419
      memset(packet+IP_CHECKSUM, 0, 2);
420
      checksum = IPChecksum(0xffff, packet+IP_VERSION_LENGTH, 20);
421
      packet[IP_CHECKSUM] = (unsigned char)(checksum >> 8);
422
      packet[IP_CHECKSUM+1] = (unsigned char)checksum;
423 220 rhoads
      if(packet[IP_PROTOCOL] == 0x01)         //ICMP & PING
424 155 rhoads
      {
425
         memset(packet+PING_CHECKSUM, 0, 2);
426
         checksum = IPChecksum(0xffff, packet+PING_TYPE, length-PING_TYPE);
427
         packet[PING_CHECKSUM] = (unsigned char)(checksum >> 8);
428
         packet[PING_CHECKSUM+1] = (unsigned char)checksum;
429
      }
430
      else if(packet[IP_PROTOCOL] == 0x11)    //UDP
431
      {
432
         length2 = length - UDP_SOURCE_PORT;
433
         packet[UDP_LENGTH] = (uint8)(length2 >> 8);
434
         packet[UDP_LENGTH+1] = (uint8)length2;
435
         memcpy(pseudo+PSEUDO_IP_SOURCE, packet+IP_SOURCE, 4);
436
         memcpy(pseudo+PSEUDO_IP_DEST, packet+IP_DEST, 4);
437
         pseudo[PSEUDO_ZERO] = 0;
438
         pseudo[PSEUDO_IP_PROTOCOL] = packet[IP_PROTOCOL];
439
         memcpy(pseudo+PSEUDO_LENGTH, packet+UDP_LENGTH, 2);
440
         checksum = IPChecksum(0xffff, pseudo, 12);
441
         memset(packet+UDP_CHECKSUM, 0, 2);
442
         length2 = (packet[UDP_LENGTH] << 8) + packet[UDP_LENGTH+1];
443
         checksum = IPChecksum(checksum, packet+UDP_SOURCE_PORT, length2);
444
         packet[UDP_CHECKSUM] = (unsigned char)(checksum >> 8);
445
         packet[UDP_CHECKSUM+1] = (unsigned char)checksum;
446
      }
447
      else if(packet[IP_PROTOCOL] == 0x06)    //TCP
448
      {
449
         memcpy(pseudo+PSEUDO_IP_SOURCE, packet+IP_SOURCE, 4);
450
         memcpy(pseudo+PSEUDO_IP_DEST, packet+IP_DEST, 4);
451
         pseudo[PSEUDO_ZERO] = 0;
452
         pseudo[PSEUDO_IP_PROTOCOL] = packet[IP_PROTOCOL];
453
         length2 = (packet[IP_LENGTH] << 8) + packet[IP_LENGTH+1];
454
         length2 = length2 - 20;
455
         pseudo[PSEUDO_LENGTH] = (unsigned char)(length2 >> 8);
456
         pseudo[PSEUDO_LENGTH+1] = (unsigned char)length2;
457
         checksum = IPChecksum(0xffff, pseudo, 12);
458
         memset(packet+TCP_CHECKSUM, 0, 2);
459
         checksum = IPChecksum(checksum, packet+TCP_SOURCE_PORT, length2);
460
         packet[TCP_CHECKSUM] = (unsigned char)(checksum >> 8);
461
         packet[TCP_CHECKSUM+1] = (unsigned char)checksum;
462
      }
463
   }
464
 
465 160 rhoads
   length2 = length - TCP_DATA;
466
   if(socket && (packet[TCP_FLAGS] & (TCP_FLAGS_FIN | TCP_FLAGS_SYN)))
467 155 rhoads
      length2 = 1;
468
   frame->socket = socket;
469
   frame->timeout = 0;
470
   frame->retryCnt = 0;
471
   if(socket)
472
      frame->seqEnd = socket->seq + length2;
473
   IPSendFrame(frame);
474
}
475
 
476
 
477
static void TCPSendPacket(IPSocket *socket, IPFrame *frame, int length)
478
{
479
   uint8 *packet = frame->packet;
480 160 rhoads
   int flags, count;
481 155 rhoads
 
482
   flags = packet[TCP_FLAGS];
483
   memcpy(packet, socket->headerSend, TCP_SEQ);
484 220 rhoads
   packet[TCP_FLAGS] = (uint8)flags;
485 155 rhoads
   if(flags & TCP_FLAGS_SYN)
486
      packet[TCP_HEADER_LENGTH] = 0x60;  //set maximum segment size
487
   else
488
      packet[TCP_HEADER_LENGTH] = 0x50;
489
   packet[TCP_SEQ]   = (uint8)(socket->seq >> 24);
490
   packet[TCP_SEQ+1] = (uint8)(socket->seq >> 16);
491
   packet[TCP_SEQ+2] = (uint8)(socket->seq >> 8);
492
   packet[TCP_SEQ+3] = (uint8)socket->seq;
493
   packet[TCP_ACK]   = (uint8)(socket->ack >> 24);
494
   packet[TCP_ACK+1] = (uint8)(socket->ack >> 16);
495
   packet[TCP_ACK+2] = (uint8)(socket->ack >> 8);
496
   packet[TCP_ACK+3] = (uint8)socket->ack;
497 160 rhoads
   count = FrameFreeCount - FRAME_COUNT_WINDOW;
498
   if(count < 1)
499
      count = 1;
500 165 rhoads
   if(count > 4)
501
      count = 4;
502 160 rhoads
   count *= 512;
503
   packet[TCP_WINDOW_SIZE] = (uint8)(count >> 8);
504
   packet[TCP_WINDOW_SIZE+1] = (uint8)count;
505 155 rhoads
   packet[TCP_URGENT_POINTER] = 0;
506
   packet[TCP_URGENT_POINTER+1] = 0;
507
   IPSendPacket(socket, frame, length);
508
}
509
 
510
 
511
static void EthernetCreateResponse(unsigned char *packetOut,
512
                                   const unsigned char *packet,
513
                                   int length)
514
{
515
   //Swap destination and source fields
516
   memcpy(packetOut, packet, length);
517
   memcpy(packetOut+ETHERNET_DEST, packet+ETHERNET_SOURCE, 6);
518
   memcpy(packetOut+ETHERNET_SOURCE, packet+ETHERNET_DEST, 6);
519
   if(packet[ETHERNET_FRAME_TYPE+1] == 0x00)  //IP
520
   {
521
      memcpy(packetOut+IP_SOURCE, packet+IP_DEST, 4);
522
      memcpy(packetOut+IP_DEST, packet+IP_SOURCE, 4);
523
      if(packet[IP_PROTOCOL] == 0x06 || packet[IP_PROTOCOL] == 0x11)   //TCP/UDP
524
      {
525
         memcpy(packetOut+TCP_SOURCE_PORT, packet+TCP_DEST_PORT, 2);
526
         memcpy(packetOut+TCP_DEST_PORT, packet+TCP_SOURCE_PORT, 2);
527
      }
528
   }
529
}
530
 
531
 
532
static void IPDhcp(const unsigned char *packet, int length, int state)
533
{
534
   uint8 *packetOut, *ptr;
535
   const uint8 *ptr2;
536
   IPFrame *frame;
537
   static int request=0;
538
 
539
   if(state == 1)
540
   {
541
      //Create DHCP Discover
542 157 rhoads
      frame = IPFrameGet(0);
543 155 rhoads
      if(frame == NULL)
544
         return;
545
      packetOut = frame->packet;
546
      memset(packetOut, 0, 512);
547
      memcpy(packetOut, dhcpDiscover, sizeof(dhcpDiscover));
548
      memcpy(packetOut+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
549
      memcpy(packetOut+DHCP_CLIENT_ETHERNET, ethernetAddressPlasma, 6);
550
      memcpy(packetOut+DHCP_MAGIC_COOKIE, dhcpOptions, sizeof(dhcpOptions));
551
      memcpy(packetOut+DHCP_MAGIC_COOKIE+10, ethernetAddressPlasma, 6);
552
      IPSendPacket(NULL, frame, 400);
553
      request = DHCP_DISCOVER;
554
      DhcpRetrySeconds = RETRANSMIT_TIME;
555
   }
556
   else if(state == 2 && memcmp(packet+DHCP_CLIENT_ETHERNET, ethernetAddressPlasma, 6) == 0)
557
   {
558
      if(packet[DHCP_MAGIC_COOKIE+6] == DHCP_OFFER && request == DHCP_DISCOVER)
559
      {
560
         //Process DHCP Offer and send DHCP Request
561 157 rhoads
         frame = IPFrameGet(0);
562 155 rhoads
         if(frame == NULL)
563
            return;
564
         packetOut = frame->packet;
565
         memset(packetOut, 0, 512);
566
         memcpy(packetOut, dhcpDiscover, sizeof(dhcpDiscover));
567
         memcpy(packetOut+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
568
         memcpy(packetOut+DHCP_CLIENT_ETHERNET, ethernetAddressPlasma, 6);
569
         memcpy(packetOut+DHCP_MAGIC_COOKIE, dhcpOptions, sizeof(dhcpOptions));
570 206 rhoads
         memcpy(packetOut+DHCP_MAGIC_COOKIE+10, ethernetAddressPlasma, 6);
571 155 rhoads
         request = DHCP_REQUEST;
572
         packetOut[DHCP_MAGIC_COOKIE+6] = DHCP_REQUEST;
573
         ptr = packetOut+DHCP_MAGIC_COOKIE+sizeof(dhcpOptions)-1;
574
         ptr[0] = DHCP_REQUEST_IP;
575
         ptr[1] = 4;
576
         memcpy(ptr+2, packet+DHCP_YOUR_IP, 4);
577
         ptr[6] = DHCP_REQUEST_SERV_IP;
578
         ptr[7] = 4;
579
         memcpy(ptr+8, packet+DHCP_SERVER_IP, 4);
580
         ptr[12] = DHCP_END_OPTION;
581
         IPSendPacket(NULL, frame, 400);
582
      }
583
      else if(packet[DHCP_MAGIC_COOKIE+6] == DHCP_ACK && request == DHCP_REQUEST)
584
      {
585
         //Process DHCP Ack
586
         request = 0;
587
         DhcpRetrySeconds = 3600*4;
588
         memcpy(ipAddressPlasma, packet+DHCP_YOUR_IP, 4);
589
         printf("IP=%d.%d.%d.%d ", ipAddressPlasma[0], ipAddressPlasma[1],
590
            ipAddressPlasma[2], ipAddressPlasma[3]);
591
         memcpy(ipAddressGateway, packet+DHCP_GATEWAY_IP, 4);
592
         if(ipAddressGateway[0] == 0 && ipAddressGateway[1] == 0 &&
593
            ipAddressGateway[2] == 0 && ipAddressGateway[3] == 0)
594
            memcpy(ipAddressGateway, packet+DHCP_SERVER_IP, 4);
595
         printf("GW=%d.%d.%d.%d ", ipAddressGateway[0], ipAddressGateway[1],
596
            ipAddressGateway[2], ipAddressGateway[3]);
597
         memcpy(ethernetAddressGateway, packet+ETHERNET_SOURCE, 6);
598
         ptr2 = packet+DHCP_MAGIC_COOKIE+4;
599
         while(ptr2[0] != DHCP_END_OPTION && (int)(ptr2 - packet) < length)
600
         {
601
            if(ptr2[0] == DHCP_PARAM_DNS)
602
            {
603
               ipAddressDns = (ptr2[2] << 24) | (ptr2[3] << 16) | (ptr2[4] << 8) | ptr2[5];
604
               printf("DNS=%d.%d.%d.%d ", ptr2[2], ptr2[3], ptr2[4], ptr2[5]);
605
            }
606
            ptr2 += ptr2[1] + 2;
607
         }
608
 
609
         //Check if DHCP reply came from gateway
610
         if(memcmp(packet+IP_SOURCE, ipAddressGateway, 4))
611
         {
612
            //Send ARP to gateway
613 157 rhoads
            frame = IPFrameGet(0);
614 155 rhoads
            if(frame == NULL)
615
               return;
616
            packetOut = frame->packet;
617
            memset(packetOut, 0, 512);
618
            memset(packetOut+ETHERNET_DEST, 0xff, 6);
619
            memcpy(packetOut+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
620
            packetOut[ETHERNET_FRAME_TYPE] = 0x08;
621
            packetOut[ETHERNET_FRAME_TYPE+1] = 0x06;
622
            packetOut[ARP_HARD_TYPE+1] = 0x01;
623
            packetOut[ARP_PROT_TYPE] = 0x08;
624
            packetOut[ARP_HARD_SIZE] = 0x06;
625
            packetOut[ARP_PROT_SIZE] = 0x04;
626
            packetOut[ARP_OP+1] = 1;
627
            memcpy(packetOut+ARP_ETHERNET_SENDER, ethernetAddressPlasma, 6);
628
            memcpy(packetOut+ARP_IP_SENDER, ipAddressPlasma, 4);
629
            memcpy(packetOut+ARP_IP_TARGET, ipAddressGateway, 4);
630
            IPSendPacket(NULL, frame, 60);
631
         }
632
      }
633
   }
634
}
635
 
636
 
637 209 rhoads
uint32 IPAddressSelf(void)
638
{
639
   return (ipAddressPlasma[0] << 24) | (ipAddressPlasma[1] << 16) |
640
          (ipAddressPlasma[2] << 8) | ipAddressPlasma[3];
641
}
642
 
643
 
644 155 rhoads
static int IPProcessTCPPacket(IPFrame *frameIn)
645
{
646
   uint32 seq, ack;
647 225 rhoads
   int length, ip_length, bytes, rc=0;
648 155 rhoads
   IPSocket *socket, *socketNew;
649
   IPFrame *frameOut, *frame2, *framePrev;
650
   uint8 *packet, *packetOut;
651
 
652
   packet = frameIn->packet;
653
   length = frameIn->length;
654
 
655
   ip_length = (packet[IP_LENGTH] << 8) | packet[IP_LENGTH+1];
656
   seq = (packet[TCP_SEQ] << 24) | (packet[TCP_SEQ+1] << 16) |
657
         (packet[TCP_SEQ+2] << 8) | packet[TCP_SEQ+3];
658
   ack = (packet[TCP_ACK] << 24) | (packet[TCP_ACK+1] << 16) |
659
         (packet[TCP_ACK+2] << 8) | packet[TCP_ACK+3];
660
 
661
   //Check if start of connection
662 160 rhoads
   if((packet[TCP_FLAGS] & (TCP_FLAGS_SYN | TCP_FLAGS_ACK)) == TCP_FLAGS_SYN)
663 155 rhoads
   {
664
      if(IPVerbose)
665
         printf("S");
666
      //Check if duplicate SYN
667
      for(socket = SocketHead; socket; socket = socket->next)
668
      {
669
         if(socket->state != IP_LISTEN &&
670
            packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
671
            memcmp(packet+IP_SOURCE, socket->headerRcv+IP_SOURCE, 8) == 0 &&
672
            memcmp(packet+TCP_SOURCE_PORT, socket->headerRcv+TCP_SOURCE_PORT, 4) == 0)
673
         {
674
            if(IPVerbose)
675
               printf("s");
676
            return 0;
677
         }
678
      }
679
 
680
      //Find an open port
681
      for(socket = SocketHead; socket; socket = socket->next)
682
      {
683
         if(socket->state == IP_LISTEN &&
684
            packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
685
            memcmp(packet+TCP_DEST_PORT, socket->headerRcv+TCP_DEST_PORT, 2) == 0)
686
         {
687
            //Create a new socket
688 174 rhoads
            frameOut = IPFrameGet(FRAME_COUNT_SYNC);
689 155 rhoads
            if(frameOut == NULL)
690
               return 0;
691
            socketNew = (IPSocket*)malloc(sizeof(IPSocket));
692
            if(socketNew == NULL)
693
               return 0;
694
            memcpy(socketNew, socket, sizeof(IPSocket));
695
            socketNew->state = IP_TCP;
696
            socketNew->timeout = RETRANSMIT_TIME * 3;
697
            socketNew->ack = seq;
698
            socketNew->seq = socketNew->ack + 0x12345678;
699
            socketNew->seqReceived = socketNew->seq;
700
 
701
            //Send ACK
702
            packetOut = frameOut->packet;
703
            EthernetCreateResponse(packetOut, packet, length);
704
            memcpy(socketNew->headerRcv, packet, TCP_SEQ);
705
            memcpy(socketNew->headerSend, packetOut, TCP_SEQ);
706
            packetOut[TCP_FLAGS] = TCP_FLAGS_SYN | TCP_FLAGS_ACK;
707
            ++socketNew->ack;
708
            packetOut[TCP_DATA] = 2;    //maximum segment size = 536
709
            packetOut[TCP_DATA+1] = 4;
710
            packetOut[TCP_DATA+2] = 2;
711
            packetOut[TCP_DATA+3] = 24;
712
            TCPSendPacket(socketNew, frameOut, TCP_DATA+4);
713
            ++socketNew->seq;
714
 
715
            //Add socket to linked list
716 157 rhoads
            OS_MutexPend(IPMutex);
717 155 rhoads
            socketNew->next = SocketHead;
718
            socketNew->prev = NULL;
719
            if(SocketHead)
720
               SocketHead->prev = socketNew;
721
            SocketHead = socketNew;
722 157 rhoads
            OS_MutexPost(IPMutex);
723 155 rhoads
            return 0;
724
         }
725
      }
726 220 rhoads
 
727
      //Send reset
728
      frameOut = IPFrameGet(0);
729
      if(frameOut == NULL)
730
         return 0;
731
      packetOut = frameOut->packet;
732
      EthernetCreateResponse(packetOut, packet, TCP_DATA);
733
      memset(packetOut+TCP_SEQ, 0, 4);
734
      ++seq;
735
      packetOut[TCP_ACK]   = (uint8)(seq >> 24);
736
      packetOut[TCP_ACK+1] = (uint8)(seq >> 16);
737
      packetOut[TCP_ACK+2] = (uint8)(seq >> 8);
738
      packetOut[TCP_ACK+3] = (uint8)seq;
739
      packetOut[TCP_HEADER_LENGTH] = 0x50;
740
      packetOut[TCP_FLAGS] = TCP_FLAGS_RST;
741
      IPSendPacket(NULL, frameOut, TCP_DATA);
742 155 rhoads
      return 0;
743
   }
744
 
745
   //Find an open socket
746
   for(socket = SocketHead; socket; socket = socket->next)
747
   {
748
      if(packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
749
         memcmp(packet+IP_SOURCE, socket->headerRcv+IP_SOURCE, 8) == 0 &&
750
         memcmp(packet+TCP_SOURCE_PORT, socket->headerRcv+TCP_SOURCE_PORT, 4) == 0)
751
      {
752
         break;
753
      }
754
   }
755
   if(socket == NULL)
756 220 rhoads
   {
757 155 rhoads
      return 0;
758 220 rhoads
   }
759 155 rhoads
 
760 225 rhoads
   //Check if packets can be removed from retransmition list
761
   if(packet[TCP_FLAGS] & TCP_FLAGS_ACK)
762 155 rhoads
   {
763
      if(ack != socket->seqReceived)
764
      {
765 157 rhoads
         OS_MutexPend(IPMutex);
766 155 rhoads
         for(frame2 = FrameResendHead; frame2; )
767
         {
768
            framePrev = frame2;
769
            frame2 = frame2->next;
770
            if(framePrev->socket == socket && (int)(ack - framePrev->seqEnd) >= 0)
771
            {
772
               //Remove packet from retransmition queue
773 160 rhoads
               if(socket->timeout)
774 231 rhoads
                  socket->timeout = socket->timeoutReset;
775 155 rhoads
               FrameRemove(&FrameResendHead, &FrameResendTail, framePrev);
776
               FrameFree(framePrev);
777
            }
778
         }
779 157 rhoads
         OS_MutexPost(IPMutex);
780 155 rhoads
         socket->seqReceived = ack;
781
      }
782 225 rhoads
   }
783 155 rhoads
 
784 225 rhoads
   bytes = ip_length - (TCP_DATA - IP_VERSION_LENGTH);
785 155 rhoads
 
786 225 rhoads
   //Check if SYN/ACK
787
   if((packet[TCP_FLAGS] & (TCP_FLAGS_SYN | TCP_FLAGS_ACK)) ==
788
      (TCP_FLAGS_SYN | TCP_FLAGS_ACK))
789
   {
790
      //Ack SYN/ACK
791
      socket->ack = seq + 1;
792
      frameOut = IPFrameGet(FRAME_COUNT_SEND);
793
      if(frameOut)
794 160 rhoads
      {
795 225 rhoads
         frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
796
         TCPSendPacket(socket, frameOut, TCP_DATA);
797 160 rhoads
      }
798 225 rhoads
      if(socket->funcPtr)
799
         OS_Job(socket->funcPtr, socket, 0, 0);
800
      return 0;
801
   }
802
   if(packet[TCP_HEADER_LENGTH] != 0x50)
803
   {
804
      if(IPVerbose)
805
         printf("length error\n");
806
      return 0;
807
   }
808
 
809
   //Copy packet into socket
810
   if(socket->ack == seq && bytes > 0)
811
   {
812
      //Insert packet into socket linked list
813
      if(socket->timeout)
814 231 rhoads
         socket->timeout = socket->timeoutReset;
815 225 rhoads
      if(IPVerbose)
816
         printf("D");
817
      if(frameIn->length > ip_length + IP_VERSION_LENGTH)
818 231 rhoads
         frameIn->length = (uint16)(ip_length + IP_VERSION_LENGTH);
819 225 rhoads
      FrameInsert(&socket->frameReadHead, &socket->frameReadTail, frameIn);
820
      socket->ack += bytes;
821
 
822
      //Ack data
823
      frameOut = IPFrameGet(FRAME_COUNT_SEND);
824
      if(frameOut)
825 160 rhoads
      {
826 225 rhoads
         frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
827
         TCPSendPacket(socket, frameOut, TCP_DATA);
828 160 rhoads
      }
829
 
830 225 rhoads
      //Determine window
831
      socket->seqWindow = (packet[TCP_WINDOW_SIZE] << 8) | packet[TCP_WINDOW_SIZE+1];
832
      if(socket->seqWindow < 8)
833
         socket->seqWindow = 8;
834
 
835
      //Using frame
836
      rc = 1;
837
   }
838
   else if(bytes)
839
   {
840
      //Ack with current offset since data missing
841
      frameOut = IPFrameGet(FRAME_COUNT_SEND);
842
      if(frameOut)
843 155 rhoads
      {
844 225 rhoads
         frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
845
         TCPSendPacket(socket, frameOut, TCP_DATA);
846
      }
847
   }
848 155 rhoads
 
849 225 rhoads
   //Check if FIN flag set
850
   if(packet[TCP_FLAGS] & TCP_FLAGS_FIN)
851
   {
852
      socket->timeout = SOCKET_TIMEOUT;
853
      if(IPVerbose)
854
         printf("F");
855
      frameOut = IPFrameGet(0);
856
      if(frameOut == NULL)
857
         return 0;
858
      packetOut = frameOut->packet;
859
      packetOut[TCP_FLAGS] = TCP_FLAGS_ACK;
860
      ++socket->ack;
861
      TCPSendPacket(socket, frameOut, TCP_DATA);
862
      if(socket->state == IP_FIN_SERVER)
863
         IPClose2(socket);
864 231 rhoads
      else if(socket->state == IP_TCP)
865 225 rhoads
         socket->state = IP_FIN_CLIENT;
866
   }
867 155 rhoads
 
868 225 rhoads
   //Check if RST flag set
869
   if(packet[TCP_FLAGS] & TCP_FLAGS_RST)
870
   {
871
      if(socket->state == IP_FIN_SERVER)
872
         IPClose2(socket);
873 231 rhoads
      else if(socket->state == IP_TCP)
874 225 rhoads
         socket->state = IP_FIN_CLIENT;
875
   }
876 165 rhoads
 
877 225 rhoads
   //Notify application
878
   if(socket->funcPtr)
879
      OS_Job(socket->funcPtr, socket, 0, 0);
880
   return rc;
881 155 rhoads
}
882
 
883
 
884 247 rhoads
int IPProcessEthernetPacket(IPFrame *frameIn, int length)
885 155 rhoads
{
886
   int ip_length, rc;
887
   IPSocket *socket;
888
   IPFrame *frameOut;
889
   uint8 *packet, *packetOut;
890
 
891
   packet = frameIn->packet;
892 247 rhoads
   frameIn->length = (uint16)length;
893 155 rhoads
 
894
   if(packet[ETHERNET_FRAME_TYPE] != 0x08 || frameIn->length > PACKET_SIZE)
895
      return 0;  //wrong ethernet type, packet not used
896
 
897
   //ARP?
898
   if(packet[ETHERNET_FRAME_TYPE+1] == 0x06)
899
   {
900
      //Check if ARP reply
901
      if(memcmp(packet+ETHERNET_DEST, ethernetAddressPlasma, 6) == 0 &&
902
         packet[ARP_OP+1] == 2 && memcmp(packet+ARP_IP_SENDER, ipAddressGateway, 4) == 0)
903
      {
904
         //Found MAC address for gateway
905
         memcpy(ethernetAddressGateway, packet+ARP_ETHERNET_SENDER, 6);
906
         return 0;
907
      }
908
 
909
      //Check if ARP request
910
      if(memcmp(packet+ETHERNET_DEST, ethernetAddressNull, 6) ||
911
         packet[ARP_OP] != 0 || packet[ARP_OP+1] != 1 ||
912
         memcmp(packet+ARP_IP_TARGET, ipAddressPlasma, 4))
913
         return 0;
914
      //Create ARP response
915 157 rhoads
      frameOut = IPFrameGet(0);
916 155 rhoads
      if(frameOut == NULL)
917
         return 0;
918
      packetOut = frameOut->packet;
919
      memcpy(packetOut, packet, frameIn->length);
920
      memcpy(packetOut+ETHERNET_DEST, packet+ETHERNET_SOURCE, 6);
921
      memcpy(packetOut+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
922
      packetOut[ARP_OP+1] = 2; //ARP reply
923
      memcpy(packetOut+ARP_ETHERNET_SENDER, ethernetAddressPlasma, 6);
924
      memcpy(packetOut+ARP_IP_SENDER, packet+ARP_IP_TARGET, 4);
925
      memcpy(packetOut+ARP_ETHERNET_TARGET, packet+ARP_ETHERNET_SENDER, 6);
926
      memcpy(packetOut+ARP_IP_TARGET, packet+ARP_IP_SENDER, 4);
927
      IPSendPacket(NULL, frameOut, frameIn->length);
928
      return 0;
929
   }
930
 
931
   //Check if proper type of packet
932
   ip_length = (packet[IP_LENGTH] << 8) | packet[IP_LENGTH+1];
933
   if(frameIn->length < UDP_DATA || ip_length > frameIn->length - IP_VERSION_LENGTH)
934
      return 0;
935
   if(packet[ETHERNET_FRAME_TYPE+1] != 0x00 ||
936
      packet[IP_VERSION_LENGTH] != 0x45)
937
      return 0;
938
 
939
   //Check if DHCP reply
940
   if(packet[IP_PROTOCOL] == 0x11 &&
941
      packet[UDP_SOURCE_PORT] == 0 && packet[UDP_SOURCE_PORT+1] == 67 &&
942
      packet[UDP_DEST_PORT] == 0 && packet[UDP_DEST_PORT+1] == 68)
943
   {
944
      IPDhcp(packet, frameIn->length, 2);            //DHCP reply
945
      return 0;
946
   }
947
 
948
   //Check if correct destination address
949
   if(memcmp(packet+ETHERNET_DEST, ethernetAddressPlasma, 6) ||
950
      memcmp(packet+IP_DEST, ipAddressPlasma, 4))
951
      return 0;
952
   rc = EthernetVerifyChecksums(packet, frameIn->length);
953
   //if(rc)
954
   //{
955
   //   printf("C ");
956
   //   return;
957
   //}
958
 
959
   //PING request?
960
   if(packet[IP_PROTOCOL] == 1)
961
   {
962 209 rhoads
      if(packet[PING_TYPE] == 0)  //PING reply
963
      {
964
         for(socket = SocketHead; socket; socket = socket->next)
965
         {
966
            if(socket->state == IP_PING &&
967
               memcmp(packet+IP_SOURCE, socket->headerSend+IP_DEST, 4) == 0)
968
            {
969 225 rhoads
               OS_Job(socket->funcPtr, socket, 0, 0);
970 209 rhoads
               return 0;
971
            }
972
         }
973
      }
974 155 rhoads
      if(packet[PING_TYPE] != 8)
975
         return 0;
976 160 rhoads
      frameOut = IPFrameGet(FRAME_COUNT_SEND);
977 155 rhoads
      if(frameOut == NULL)
978
         return 0;
979
      packetOut = frameOut->packet;
980
      EthernetCreateResponse(packetOut, packet, frameIn->length);
981
      frameOut->packet[PING_TYPE] = 0;       //PING reply
982
      IPSendPacket(NULL, frameOut, frameIn->length);
983
      return 0;
984
   }
985
 
986
   //TCP packet?
987
   if(packet[IP_PROTOCOL] == 0x06)
988
   {
989
      return IPProcessTCPPacket(frameIn);
990
   }
991
 
992
   //UDP packet?
993
   if(packet[IP_PROTOCOL] == 0x11)
994
   {
995
      //Find open socket
996
      for(socket = SocketHead; socket; socket = socket->next)
997
      {
998
         if(packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
999
            memcmp(packet+IP_SOURCE, socket->headerRcv+IP_SOURCE, 8) == 0 &&
1000
            memcmp(packet+UDP_SOURCE_PORT, socket->headerRcv+UDP_SOURCE_PORT, 2) == 0)
1001
         {
1002
            break;
1003
         }
1004
      }
1005
 
1006
      if(socket == NULL)
1007
      {
1008
         //Find listening socket
1009
         for(socket = SocketHead; socket; socket = socket->next)
1010
         {
1011
            if(packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
1012
               memcmp(packet+UDP_DEST_PORT, socket->headerRcv+UDP_DEST_PORT, 2) == 0)
1013
            {
1014 209 rhoads
               EthernetCreateResponse(socket->headerSend, packet, UDP_DATA);
1015 155 rhoads
               break;
1016
            }
1017
         }
1018
      }
1019
 
1020
      if(socket)
1021
      {
1022
         if(IPVerbose)
1023
            printf("U");
1024
         FrameInsert(&socket->frameReadHead, &socket->frameReadTail, frameIn);
1025 225 rhoads
         OS_Job(socket->funcPtr, socket, 0, 0);
1026 155 rhoads
         return 1;
1027
      }
1028
   }
1029
   return 0;
1030
}
1031
 
1032
 
1033 220 rhoads
#ifndef WIN32
1034 209 rhoads
static void IPMainThread(void *arg)
1035 155 rhoads
{
1036
   uint32 message[4];
1037
   int rc;
1038
   IPFrame *frame, *frameOut=NULL;
1039
   uint32 ticks, ticksLast;
1040 209 rhoads
   (void)arg;
1041 155 rhoads
 
1042
   ticksLast = OS_ThreadTime();
1043
   memset(message, 0, sizeof(message));
1044
 
1045
   for(;;)
1046
   {
1047
      Led(0);
1048
      rc = OS_MQueueGet(IPMQueue, message, 10);
1049
      if(rc == 0)
1050
      {
1051
         frame = (IPFrame*)message[1];
1052
         if(message[0] == 0)       //frame received
1053
         {
1054
            Led(1);
1055
            frame->length = (uint16)message[2];
1056 247 rhoads
            rc = IPProcessEthernetPacket(frame, frame->length);
1057 155 rhoads
            if(rc == 0)
1058
               FrameFree(frame);
1059
         }
1060
         else if(message[0] == 1)  //frame sent
1061
         {
1062
            Led(2);
1063
            assert(frame == frameOut);
1064
            IPFrameReschedule(frame);
1065
            frameOut = NULL;
1066
         }
1067
         else if(message[0] == 2)  //frame ready to send
1068
         {
1069
         }
1070
      }
1071
 
1072
      if(frameOut == NULL)
1073
      {
1074 157 rhoads
         OS_MutexPend(IPMutex);
1075 155 rhoads
         frameOut = FrameSendTail;
1076
         if(frameOut)
1077
            FrameRemove(&FrameSendHead, &FrameSendTail, frameOut);
1078 157 rhoads
         OS_MutexPost(IPMutex);
1079 155 rhoads
         if(frameOut)
1080
         {
1081
            Led(4);
1082
            UartPacketSend(frameOut->packet, frameOut->length);
1083
         }
1084
      }
1085
 
1086
      ticks = OS_ThreadTime();
1087
      if(ticks - ticksLast > 100)
1088
      {
1089
         IPTick();
1090
         ticksLast = ticks;
1091
      }
1092
   }
1093
}
1094 220 rhoads
#endif
1095 155 rhoads
 
1096
 
1097 157 rhoads
uint8 *MyPacketGet(void)
1098 155 rhoads
{
1099 160 rhoads
   return (uint8*)IPFrameGet(FRAME_COUNT_RCV);
1100 155 rhoads
}
1101
 
1102
 
1103
//Set FrameSendFunction only if single threaded
1104 209 rhoads
void IPInit(IPFuncPtr frameSendFunction)
1105 155 rhoads
{
1106
   int i;
1107
   IPFrame *frame;
1108
 
1109 209 rhoads
   FrameSendFunc = frameSendFunction;
1110 157 rhoads
   IPMutex = OS_MutexCreate("IPSem");
1111 155 rhoads
   IPMQueue = OS_MQueueCreate("IPMQ", FRAME_COUNT*2, 32);
1112
   for(i = 0; i < FRAME_COUNT; ++i)
1113
   {
1114
      frame = (IPFrame*)malloc(sizeof(IPFrame));
1115
      memset(frame, 0, sizeof(IPFrame));
1116
      frame->next = FrameFreeHead;
1117
      frame->prev = NULL;
1118
      FrameFreeHead = frame;
1119
   }
1120
   UartPacketConfig(MyPacketGet, PACKET_SIZE, IPMQueue);
1121 209 rhoads
   if(frameSendFunction == NULL)
1122 157 rhoads
      IPThread = OS_ThreadCreate("TCP/IP", IPMainThread, NULL, 240, 6000);
1123 155 rhoads
   IPDhcp(NULL, 360, 1);        //Send DHCP request
1124
}
1125
 
1126
 
1127 209 rhoads
//To open a socket for listen set ipAddress to 0
1128
IPSocket *IPOpen(IPMode_e mode, uint32 ipAddress, uint32 port, IPFuncPtr funcPtr)
1129 155 rhoads
{
1130
   IPSocket *socket;
1131 160 rhoads
   uint8 *ptrSend, *ptrRcv;
1132
   IPFrame *frame;
1133
   static int portSource=0x1007;
1134 155 rhoads
 
1135
   socket = (IPSocket*)malloc(sizeof(IPSocket));
1136
   if(socket == NULL)
1137
      return socket;
1138
   memset(socket, 0, sizeof(IPSocket));
1139
   socket->prev = NULL;
1140
   socket->state = IP_LISTEN;
1141
   socket->timeout = 0;
1142 231 rhoads
   socket->timeoutReset = SOCKET_TIMEOUT;
1143 155 rhoads
   socket->frameReadHead = NULL;
1144
   socket->frameReadTail = NULL;
1145
   socket->readOffset = 0;
1146
   socket->funcPtr = funcPtr;
1147
   socket->userData = 0;
1148
   socket->userFunc = NULL;
1149
   socket->userPtr = NULL;
1150 160 rhoads
   ptrSend = socket->headerSend;
1151
   ptrRcv = socket->headerRcv;
1152 155 rhoads
 
1153 209 rhoads
   if(ipAddress == 0)
1154 155 rhoads
   {
1155
      //Setup listing port
1156 209 rhoads
      socket->headerRcv[TCP_DEST_PORT] = (uint8)(port >> 8);
1157
      socket->headerRcv[TCP_DEST_PORT+1] = (uint8)port;
1158 155 rhoads
   }
1159
   else
1160
   {
1161 160 rhoads
      //Setup sending packet
1162
      memset(ptrSend, 0, UDP_LENGTH);
1163
      memset(ptrRcv, 0, UDP_LENGTH);
1164 155 rhoads
 
1165 160 rhoads
      //Setup Ethernet
1166 209 rhoads
      if(ipAddress != IPAddressSelf())
1167
         memcpy(ptrSend+ETHERNET_DEST, ethernetAddressGateway, 6);
1168
      else
1169
         memcpy(ptrSend+ETHERNET_DEST, ethernetAddressPlasma, 6);
1170 160 rhoads
      memcpy(ptrSend+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
1171
      ptrSend[ETHERNET_FRAME_TYPE] = 0x08;
1172
 
1173
      //Setup IP
1174
      ptrSend[IP_VERSION_LENGTH] = 0x45;
1175
      ptrSend[IP_TIME_TO_LIVE] = 0x80;
1176
 
1177
      //Setup IP addresses
1178
      memcpy(ptrSend+IP_SOURCE, ipAddressPlasma, 4);
1179 209 rhoads
      ptrSend[IP_DEST] = (uint8)(ipAddress >> 24);
1180
      ptrSend[IP_DEST+1] = (uint8)(ipAddress >> 16);
1181
      ptrSend[IP_DEST+2] = (uint8)(ipAddress >> 8);
1182
      ptrSend[IP_DEST+3] = (uint8)ipAddress;
1183
      ptrRcv[IP_SOURCE] = (uint8)(ipAddress >> 24);
1184
      ptrRcv[IP_SOURCE+1] = (uint8)(ipAddress >> 16);
1185
      ptrRcv[IP_SOURCE+2] = (uint8)(ipAddress >> 8);
1186
      ptrRcv[IP_SOURCE+3] = (uint8)ipAddress;
1187 160 rhoads
      memcpy(ptrRcv+IP_DEST, ipAddressPlasma, 4);
1188
 
1189
      //Setup ports
1190
      ptrSend[TCP_SOURCE_PORT] = (uint8)(portSource >> 8);
1191
      ptrSend[TCP_SOURCE_PORT+1] = (uint8)portSource;
1192 209 rhoads
      ptrSend[TCP_DEST_PORT] = (uint8)(port >> 8);
1193
      ptrSend[TCP_DEST_PORT+1] = (uint8)port;
1194
      ptrRcv[TCP_SOURCE_PORT] = (uint8)(port >> 8);
1195
      ptrRcv[TCP_SOURCE_PORT+1] = (uint8)port;
1196 160 rhoads
      ptrRcv[TCP_DEST_PORT] = (uint8)(portSource >> 8);
1197
      ptrRcv[TCP_DEST_PORT+1] = (uint8)portSource;
1198 155 rhoads
      ++portSource;
1199
   }
1200
 
1201 209 rhoads
   if(mode == IP_MODE_TCP)
1202 155 rhoads
   {
1203 209 rhoads
      if(ipAddress)
1204 160 rhoads
         socket->state = IP_TCP;
1205
      else
1206
         socket->state = IP_LISTEN;
1207
      ptrSend[IP_PROTOCOL] = 0x06;  //TCP
1208
      ptrRcv[IP_PROTOCOL] = 0x06;
1209 155 rhoads
   }
1210 209 rhoads
   else if(mode == IP_MODE_UDP)
1211 155 rhoads
   {
1212
      socket->state = IP_UDP;
1213 160 rhoads
      ptrSend[IP_PROTOCOL] = 0x11;  //UDP
1214
      ptrRcv[IP_PROTOCOL] = 0x11;
1215 155 rhoads
   }
1216 209 rhoads
   else if(mode == IP_MODE_PING)
1217
   {
1218
      socket->state = IP_PING;
1219
      ptrSend[IP_PROTOCOL] = 0x01;  //PING
1220
      memset(ptrSend+PING_TYPE, 0, 8);
1221
      ptrSend[PING_TYPE] = 8;       //SEND
1222
   }
1223 155 rhoads
 
1224 160 rhoads
   //Add socket to linked list
1225 157 rhoads
   OS_MutexPend(IPMutex);
1226 155 rhoads
   socket->next = SocketHead;
1227 160 rhoads
   socket->prev = NULL;
1228
   if(SocketHead)
1229
      SocketHead->prev = socket;
1230 155 rhoads
   SocketHead = socket;
1231 157 rhoads
   OS_MutexPost(IPMutex);
1232 160 rhoads
 
1233 209 rhoads
   if(mode == IP_MODE_TCP && ipAddress)
1234 160 rhoads
   {
1235
      //Send TCP SYN
1236 206 rhoads
      socket->seq = 0x01234567;
1237 160 rhoads
      frame = IPFrameGet(0);
1238
      if(frame)
1239
      {
1240
         frame->packet[TCP_FLAGS] = TCP_FLAGS_SYN;
1241
         frame->packet[TCP_DATA] = 2;    //maximum segment size = 536
1242
         frame->packet[TCP_DATA+1] = 4;
1243
         frame->packet[TCP_DATA+2] = 2;
1244
         frame->packet[TCP_DATA+3] = 24;
1245
         TCPSendPacket(socket, frame, TCP_DATA+4);
1246
         ++socket->seq;
1247
      }
1248
   }
1249 155 rhoads
   return socket;
1250
}
1251
 
1252
 
1253 209 rhoads
void IPWriteFlush(IPSocket *socket)
1254 155 rhoads
{
1255
   uint8 *packetOut;
1256 209 rhoads
   if(socket->frameSend && socket->state != IP_UDP &&
1257
      socket->state != IP_PING)
1258 155 rhoads
   {
1259 209 rhoads
      packetOut = socket->frameSend->packet;
1260 220 rhoads
      packetOut[TCP_FLAGS] = TCP_FLAGS_ACK | TCP_FLAGS_PSH;
1261 209 rhoads
      TCPSendPacket(socket, socket->frameSend, TCP_DATA + socket->sendOffset);
1262
      socket->seq += socket->sendOffset;
1263
      socket->frameSend = NULL;
1264
      socket->sendOffset = 0;
1265 155 rhoads
   }
1266
}
1267
 
1268
 
1269 209 rhoads
uint32 IPWrite(IPSocket *socket, const uint8 *buf, uint32 length)
1270 155 rhoads
{
1271
   IPFrame *frameOut;
1272
   uint8 *packetOut;
1273 206 rhoads
   uint32 bytes, count=0, tries=0;
1274 155 rhoads
   int offset;
1275 165 rhoads
   OS_Thread_t *self;
1276 155 rhoads
 
1277 231 rhoads
   if(socket->timeout)
1278
      socket->timeout = socket->timeoutReset;
1279
 
1280 155 rhoads
   //printf("IPWrite(0x%x, %d)", Socket, Length);
1281 165 rhoads
   self = OS_ThreadSelf();
1282 209 rhoads
   while(length)
1283 155 rhoads
   {
1284 206 rhoads
      //Rate limit output
1285 209 rhoads
      if(socket->seq - socket->seqReceived >= 5120)
1286 206 rhoads
      {
1287
         if(self == IPThread || ++tries > 200)
1288
            break;
1289
         else
1290
         {
1291
            OS_ThreadSleep(1);
1292
            continue;
1293
         }
1294
      }
1295 165 rhoads
      tries = 0;
1296 209 rhoads
      while(socket->frameSend == NULL)
1297 155 rhoads
      {
1298 209 rhoads
         socket->frameSend = IPFrameGet(FRAME_COUNT_SEND);
1299
         socket->sendOffset = 0;
1300
         if(socket->frameSend == NULL)
1301 165 rhoads
         {
1302
            if(self == IPThread || ++tries > 200)
1303
               break;
1304
            else
1305
               OS_ThreadSleep(1);
1306
         }
1307 155 rhoads
      }
1308 209 rhoads
      frameOut = socket->frameSend;
1309
      offset = socket->sendOffset;
1310 155 rhoads
      if(frameOut == NULL)
1311
         break;
1312
      packetOut = frameOut->packet;
1313
 
1314 209 rhoads
      if(socket->state == IP_PING)
1315 155 rhoads
      {
1316 209 rhoads
         bytes = length;
1317
         memcpy(packetOut, socket->headerSend, PING_DATA);
1318
         memcpy(packetOut+PING_DATA, buf, bytes);
1319
         IPSendPacket(socket, socket->frameSend, PING_DATA + bytes);
1320
         socket->frameSend = NULL;
1321
      }
1322
      else if(socket->state != IP_UDP)
1323
      {
1324
         bytes = 512 - offset;
1325
         if(bytes > length)
1326
            bytes = length;
1327
         socket->sendOffset += bytes;
1328
         memcpy(packetOut+TCP_DATA+offset, buf, bytes);
1329
         if(socket->sendOffset >= 512)
1330
            IPWriteFlush(socket);
1331 165 rhoads
         //if(Socket->seq - Socket->seqReceived > Socket->seqWindow)
1332
         //{
1333
         //   printf("W");
1334
         //   OS_ThreadSleep(10);
1335
         //}
1336 155 rhoads
      }
1337
      else  //UDP
1338
      {
1339 209 rhoads
         bytes = length;
1340
         memcpy(packetOut+UDP_DATA+offset, buf, bytes);
1341
         memcpy(packetOut, socket->headerSend, UDP_LENGTH);
1342
         IPSendPacket(socket, socket->frameSend, UDP_DATA + bytes);
1343
         socket->frameSend = NULL;
1344 155 rhoads
      }
1345
      count += bytes;
1346 209 rhoads
      buf += bytes;
1347
      length -= bytes;
1348 155 rhoads
   }
1349
   return count;
1350
}
1351
 
1352
 
1353 209 rhoads
uint32 IPRead(IPSocket *socket, uint8 *buf, uint32 length)
1354 155 rhoads
{
1355
   IPFrame *frame, *frame2;
1356
   int count=0, bytes, offset;
1357
 
1358 225 rhoads
   if(socket->state == IP_UDP)
1359
      offset = UDP_DATA;
1360
   else
1361 155 rhoads
      offset = TCP_DATA;
1362
 
1363 157 rhoads
   OS_MutexPend(IPMutex);
1364 209 rhoads
   for(frame = socket->frameReadTail; length && frame; )
1365 155 rhoads
   {
1366 209 rhoads
      bytes = frame->length - offset - socket->readOffset;
1367
      if(bytes > (int)length)
1368
         bytes = length;
1369
      memcpy(buf, frame->packet + offset + socket->readOffset, bytes);
1370
      buf += bytes;
1371
      socket->readOffset += bytes;
1372
      length -= bytes;
1373 155 rhoads
      count += bytes;
1374
 
1375
      //Check if done with packet
1376
      frame2 = frame;
1377
      frame = frame->prev;
1378 209 rhoads
      if(socket->readOffset == frame2->length - offset)
1379 155 rhoads
      {
1380
         //Remove packet from socket linked list
1381 209 rhoads
         socket->readOffset = 0;
1382
         FrameRemove(&socket->frameReadHead, &socket->frameReadTail, frame2);
1383 155 rhoads
         FrameFree(frame2);
1384
      }
1385
   }
1386 157 rhoads
   OS_MutexPost(IPMutex);
1387 155 rhoads
   return count;
1388
}
1389
 
1390
 
1391 209 rhoads
static void IPClose2(IPSocket *socket)
1392 155 rhoads
{
1393
   IPFrame *frame, *framePrev;
1394
 
1395 157 rhoads
   OS_MutexPend(IPMutex);
1396 155 rhoads
 
1397 157 rhoads
   //Mark packets as don't retransmit
1398
   for(frame = FrameSendHead; frame; frame = frame->next)
1399 155 rhoads
   {
1400 209 rhoads
      if(frame->socket == socket)
1401 157 rhoads
         frame->socket = NULL;
1402 155 rhoads
   }
1403
 
1404
   //Remove packets from retransmision list
1405
   for(frame = FrameResendHead; frame; )
1406
   {
1407
      framePrev = frame;
1408
      frame = frame->next;
1409 209 rhoads
      if(framePrev->socket == socket)
1410 155 rhoads
      {
1411
         FrameRemove(&FrameResendHead, &FrameResendTail, framePrev);
1412
         FrameFree(framePrev);
1413
      }
1414
   }
1415
 
1416
   //Remove packets from socket read linked list
1417 209 rhoads
   for(frame = socket->frameReadHead; frame; )
1418 155 rhoads
   {
1419
      framePrev = frame;
1420
      frame = frame->next;
1421 209 rhoads
      FrameRemove(&socket->frameReadHead, &socket->frameReadTail, framePrev);
1422 155 rhoads
      FrameFree(framePrev);
1423
   }
1424
 
1425
   //Remove socket
1426 225 rhoads
   if(socket->state == IP_CLOSED)
1427
   {
1428
      if(socket->prev == NULL)
1429
         SocketHead = socket->next;
1430
      else
1431
         socket->prev->next = socket->next;
1432
      if(socket->next)
1433
         socket->next->prev = socket->prev;
1434
      free(socket);
1435
   }
1436 155 rhoads
   else
1437 225 rhoads
   {
1438
      //Give application 10 seconds to stop using socket
1439
      socket->state = IP_CLOSED;
1440
      socket->timeout = 10;
1441
   }
1442 157 rhoads
   OS_MutexPost(IPMutex);
1443 155 rhoads
}
1444
 
1445
 
1446 209 rhoads
void IPClose(IPSocket *socket)
1447 155 rhoads
{
1448
   IPFrame *frameOut;
1449
 
1450 209 rhoads
   IPWriteFlush(socket);
1451
   if(socket->state <= IP_UDP)
1452 157 rhoads
   {
1453 209 rhoads
      IPClose2(socket);
1454 157 rhoads
      return;
1455
   }
1456
   frameOut = IPFrameGet(0);
1457 231 rhoads
   if(frameOut == NULL)
1458 155 rhoads
      return;
1459
   frameOut->packet[TCP_FLAGS] = TCP_FLAGS_FIN | TCP_FLAGS_ACK;
1460 209 rhoads
   TCPSendPacket(socket, frameOut, TCP_DATA);
1461
   ++socket->seq;
1462
   if(socket->state == IP_FIN_CLIENT)
1463
      IPClose2(socket);
1464 157 rhoads
   else
1465 209 rhoads
      socket->state = IP_FIN_SERVER;
1466 155 rhoads
}
1467
 
1468
 
1469 209 rhoads
void IPPrintf(IPSocket *socket, char *message)
1470
{
1471
   IPWrite(socket, (uint8*)message, (int)strlen(message));
1472
   IPWriteFlush(socket);
1473
}
1474 155 rhoads
 
1475
 
1476
void IPTick(void)
1477
{
1478
   IPFrame *frame, *frame2;
1479
   IPSocket *socket, *socket2;
1480
 
1481
   if(IPVerbose && (Seconds % 60) == 0)
1482 157 rhoads
   {
1483
      if(FrameFreeCount == FRAME_COUNT)
1484
         printf("T");
1485
      else
1486
         printf("T(%d)", FrameFreeCount);
1487
   }
1488 155 rhoads
   ++Seconds;
1489
   if(--DhcpRetrySeconds <= 0)
1490
      IPDhcp(NULL, 400, 1);   //DHCP request
1491
   //if(Seconds == 10)
1492
   //   IPResolve("plasmacpu.no-ip.org", ShowIP);
1493
 
1494 157 rhoads
   OS_MutexPend(IPMutex);
1495 155 rhoads
 
1496
   //Retransmit timeout packets
1497
   for(frame = FrameResendHead; frame; )
1498
   {
1499
      frame2 = frame;
1500
      frame = frame->next;
1501
      if(--frame2->timeout == 0)
1502
      {
1503
         if(IPVerbose)
1504
            printf("r");
1505
         FrameRemove(&FrameResendHead, &FrameResendTail, frame2);
1506
         IPSendFrame(frame2);
1507
      }
1508
   }
1509
 
1510
   //Close timed out sockets
1511
   for(socket = SocketHead; socket; )
1512
   {
1513
      socket2 = socket;
1514
      socket = socket->next;
1515
      if(socket2->timeout && --socket2->timeout == 0)
1516
      {
1517
         socket2->timeout = 10;
1518 225 rhoads
         if(IPVerbose && socket2->state != IP_CLOSED)
1519 174 rhoads
            printf("t(%d,%d)", socket2->state, FrameFreeCount);
1520 157 rhoads
         if(socket2->state == IP_TCP)
1521
            IPClose(socket2);
1522
         else if(socket2->state == IP_FIN_CLIENT)
1523
            IPClose(socket2);
1524
         else
1525 155 rhoads
            IPClose2(socket2);
1526
      }
1527
   }
1528 157 rhoads
   OS_MutexPost(IPMutex);
1529 155 rhoads
}
1530
 
1531
 
1532
static void DnsCallback(IPSocket *socket)
1533
{
1534
   uint8 buf[200], *ptr;
1535
   uint32 ipAddress;
1536 209 rhoads
   int bytes;
1537 155 rhoads
 
1538
   memset(buf, 0, sizeof(buf));
1539 209 rhoads
   bytes = IPRead(socket, buf, sizeof(buf));
1540 155 rhoads
   if(buf[DNS_NUM_ANSWERS_RR+1])
1541
   {
1542 209 rhoads
      for(ptr = buf + DNS_QUESTIONS; ptr + 14 <= buf + bytes; ++ptr)
1543 155 rhoads
      {
1544 211 rhoads
         if(ptr[0] == 0 && ptr[1] == 1 && ptr[2] == 0 && ptr[3] == 1 &&
1545
            ptr[8] == 0 && ptr[9] == 4)
1546 155 rhoads
         {
1547 211 rhoads
            ipAddress = (ptr[10] << 24) | (ptr[11] << 16) | (ptr[12] << 8) | ptr[13];
1548
            printf("ipAddress = %d.%d.%d.%d\n", ptr[10], ptr[11], ptr[12], ptr[13]);
1549 155 rhoads
            socket->userData = ipAddress;
1550
            if(socket->userFunc)
1551
            {
1552 209 rhoads
               socket->userFunc(socket, ipAddress, socket->userPtr);
1553 155 rhoads
            }
1554
            break;
1555
         }
1556
      }
1557
   }
1558 220 rhoads
   IPClose(socket);
1559 155 rhoads
}
1560
 
1561
 
1562 220 rhoads
void IPResolve(char *name, IPFuncPtr resolvedFunc, void *arg)
1563 155 rhoads
{
1564
   uint8 buf[200], *ptr;
1565
   int length, i;
1566
   IPSocket *socket;
1567
 
1568
   socket = IPOpen(IP_MODE_UDP, ipAddressDns, DNS_PORT, DnsCallback);
1569
   memset(buf, 0, sizeof(buf));
1570
   buf[DNS_ID+1] = 1;
1571
   buf[DNS_FLAGS] = 1;
1572
   buf[DNS_NUM_QUESTIONS+1] = 1;
1573
 
1574
   //Setup name
1575
   ptr = buf + DNS_QUESTIONS;
1576 209 rhoads
   strncpy((char*)ptr+1, name, 100);
1577 155 rhoads
   ptr[0] = 1;
1578
   while(ptr[0])
1579
   {
1580
      for(i = 0; i < 100; ++i)
1581
      {
1582
         if(ptr[i+1] == '.' || ptr[i+1] == 0)
1583
         {
1584
            ptr[0] = (uint8)i;
1585
            ptr += i+1;
1586
            break;
1587
         }
1588
      }
1589
   }
1590
   ++ptr;
1591
   ptr[1] = DNS_QUERY_TYPE_IP;
1592
   ptr[3] = DNS_QUERY_CLASS;
1593
   length = (int)(ptr - buf) + 4;
1594
   if(length < 60)
1595
      length = 60;
1596
 
1597
   socket->userFunc = (IPFuncPtr)resolvedFunc;
1598 209 rhoads
   socket->userPtr = arg;
1599 155 rhoads
   socket->userData = 0;
1600
   IPWrite(socket, buf, length);
1601
}
1602
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.