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

Subversion Repositories plasma

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

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

powered by: WebSVN 2.1.0

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