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

Subversion Repositories plasma

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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