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

Subversion Repositories plasma

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

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

powered by: WebSVN 2.1.0

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