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

Subversion Repositories plasma

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

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

powered by: WebSVN 2.1.0

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