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

Subversion Repositories plasma

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

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

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

powered by: WebSVN 2.1.0

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