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

Subversion Repositories mlite

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

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

powered by: WebSVN 2.1.0

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