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

Subversion Repositories mlite

[/] [mlite/] [trunk/] [kernel/] [tcpip.c] - Blame information for rev 220

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

powered by: WebSVN 2.1.0

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