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

Subversion Repositories plasma

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

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 318 rhoads
         socket->resentDone = 0;
768 155 rhoads
      }
769 317 rhoads
      else if(ack == socket->seqReceived && bytes == 0 &&
770 318 rhoads
         (packet[TCP_FLAGS] & (TCP_FLAGS_RST | TCP_FLAGS_FIN)) == 0 &&
771
         socket->resentDone == 0)
772 317 rhoads
      {
773
         //Detected that packet was lost, resend all
774
         if(IPVerbose)
775
            printf("A");
776
         OS_MutexPend(IPMutex);
777
         for(frame2 = FrameResendHead; frame2; )
778
         {
779
            framePrev = frame2;
780
            frame2 = frame2->next;
781
            if(framePrev->socket == socket)
782
            {
783
               //Remove packet from retransmition queue
784
               FrameRemove(&FrameResendHead, &FrameResendTail, framePrev);
785
               IPSendFrame(framePrev);
786
            }
787
         }
788
         OS_MutexPost(IPMutex);
789 318 rhoads
         socket->resentDone = 1;
790 317 rhoads
      }
791 225 rhoads
   }
792 155 rhoads
 
793 225 rhoads
   //Check if SYN/ACK
794
   if((packet[TCP_FLAGS] & (TCP_FLAGS_SYN | TCP_FLAGS_ACK)) ==
795
      (TCP_FLAGS_SYN | TCP_FLAGS_ACK))
796
   {
797
      //Ack SYN/ACK
798
      socket->ack = seq + 1;
799 317 rhoads
      socket->ackProcessed = seq + 1;
800 225 rhoads
      frameOut = IPFrameGet(FRAME_COUNT_SEND);
801
      if(frameOut)
802 160 rhoads
      {
803 225 rhoads
         frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
804
         TCPSendPacket(socket, frameOut, TCP_DATA);
805 160 rhoads
      }
806 225 rhoads
      if(socket->funcPtr)
807
         OS_Job(socket->funcPtr, socket, 0, 0);
808
      return 0;
809
   }
810
   if(packet[TCP_HEADER_LENGTH] != 0x50)
811
   {
812
      if(IPVerbose)
813
         printf("length error\n");
814
      return 0;
815
   }
816
 
817 257 rhoads
   //Check if RST flag set
818
   if(packet[TCP_FLAGS] & TCP_FLAGS_RST)
819
   {
820 304 rhoads
      notify = 1;
821 257 rhoads
      if(socket->state == IP_FIN_SERVER)
822
         IPClose2(socket);
823
      else if(socket->state == IP_TCP)
824
         socket->state = IP_FIN_CLIENT;
825
   }
826 225 rhoads
   //Copy packet into socket
827 257 rhoads
   else if(socket->ack == seq && bytes > 0)
828 225 rhoads
   {
829
      //Insert packet into socket linked list
830 304 rhoads
      notify = 1;
831 225 rhoads
      if(socket->timeout)
832 231 rhoads
         socket->timeout = socket->timeoutReset;
833 225 rhoads
      if(IPVerbose)
834
         printf("D");
835
      if(frameIn->length > ip_length + IP_VERSION_LENGTH)
836 231 rhoads
         frameIn->length = (uint16)(ip_length + IP_VERSION_LENGTH);
837 225 rhoads
      FrameInsert(&socket->frameReadHead, &socket->frameReadTail, frameIn);
838
      socket->ack += bytes;
839
 
840
      //Ack data
841
      frameOut = IPFrameGet(FRAME_COUNT_SEND);
842
      if(frameOut)
843 160 rhoads
      {
844 225 rhoads
         frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
845
         TCPSendPacket(socket, frameOut, TCP_DATA);
846 160 rhoads
      }
847
 
848 225 rhoads
      //Using frame
849
      rc = 1;
850
   }
851
   else if(bytes)
852
   {
853
      //Ack with current offset since data missing
854
      frameOut = IPFrameGet(FRAME_COUNT_SEND);
855
      if(frameOut)
856 155 rhoads
      {
857 225 rhoads
         frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
858
         TCPSendPacket(socket, frameOut, TCP_DATA);
859
      }
860
   }
861 155 rhoads
 
862 225 rhoads
   //Check if FIN flag set
863
   if(packet[TCP_FLAGS] & TCP_FLAGS_FIN)
864
   {
865 304 rhoads
      notify = 1;
866 225 rhoads
      socket->timeout = SOCKET_TIMEOUT;
867
      if(IPVerbose)
868
         printf("F");
869
      frameOut = IPFrameGet(0);
870
      if(frameOut == NULL)
871
         return 0;
872
      packetOut = frameOut->packet;
873
      packetOut[TCP_FLAGS] = TCP_FLAGS_ACK;
874
      ++socket->ack;
875
      TCPSendPacket(socket, frameOut, TCP_DATA);
876
      if(socket->state == IP_FIN_SERVER)
877
         IPClose2(socket);
878 231 rhoads
      else if(socket->state == IP_TCP)
879 225 rhoads
         socket->state = IP_FIN_CLIENT;
880
   }
881 155 rhoads
 
882 225 rhoads
   //Notify application
883 304 rhoads
   if(socket->funcPtr && notify)
884 225 rhoads
      OS_Job(socket->funcPtr, socket, 0, 0);
885
   return rc;
886 155 rhoads
}
887
 
888
 
889 247 rhoads
int IPProcessEthernetPacket(IPFrame *frameIn, int length)
890 155 rhoads
{
891
   int ip_length, rc;
892
   IPSocket *socket;
893
   IPFrame *frameOut;
894
   uint8 *packet, *packetOut;
895
 
896
   packet = frameIn->packet;
897 247 rhoads
   frameIn->length = (uint16)length;
898 155 rhoads
 
899
   if(packet[ETHERNET_FRAME_TYPE] != 0x08 || frameIn->length > PACKET_SIZE)
900
      return 0;  //wrong ethernet type, packet not used
901
 
902
   //ARP?
903
   if(packet[ETHERNET_FRAME_TYPE+1] == 0x06)
904
   {
905
      //Check if ARP reply
906
      if(memcmp(packet+ETHERNET_DEST, ethernetAddressPlasma, 6) == 0 &&
907
         packet[ARP_OP+1] == 2 && memcmp(packet+ARP_IP_SENDER, ipAddressGateway, 4) == 0)
908
      {
909
         //Found MAC address for gateway
910
         memcpy(ethernetAddressGateway, packet+ARP_ETHERNET_SENDER, 6);
911
         return 0;
912
      }
913
 
914
      //Check if ARP request
915
      if(memcmp(packet+ETHERNET_DEST, ethernetAddressNull, 6) ||
916
         packet[ARP_OP] != 0 || packet[ARP_OP+1] != 1 ||
917
         memcmp(packet+ARP_IP_TARGET, ipAddressPlasma, 4))
918
         return 0;
919
      //Create ARP response
920 157 rhoads
      frameOut = IPFrameGet(0);
921 155 rhoads
      if(frameOut == NULL)
922
         return 0;
923
      packetOut = frameOut->packet;
924
      memcpy(packetOut, packet, frameIn->length);
925
      memcpy(packetOut+ETHERNET_DEST, packet+ETHERNET_SOURCE, 6);
926
      memcpy(packetOut+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
927
      packetOut[ARP_OP+1] = 2; //ARP reply
928
      memcpy(packetOut+ARP_ETHERNET_SENDER, ethernetAddressPlasma, 6);
929
      memcpy(packetOut+ARP_IP_SENDER, packet+ARP_IP_TARGET, 4);
930
      memcpy(packetOut+ARP_ETHERNET_TARGET, packet+ARP_ETHERNET_SENDER, 6);
931
      memcpy(packetOut+ARP_IP_TARGET, packet+ARP_IP_SENDER, 4);
932
      IPSendPacket(NULL, frameOut, frameIn->length);
933
      return 0;
934
   }
935
 
936
   //Check if proper type of packet
937
   ip_length = (packet[IP_LENGTH] << 8) | packet[IP_LENGTH+1];
938
   if(frameIn->length < UDP_DATA || ip_length > frameIn->length - IP_VERSION_LENGTH)
939
      return 0;
940
   if(packet[ETHERNET_FRAME_TYPE+1] != 0x00 ||
941
      packet[IP_VERSION_LENGTH] != 0x45)
942
      return 0;
943
 
944
   //Check if DHCP reply
945
   if(packet[IP_PROTOCOL] == 0x11 &&
946
      packet[UDP_SOURCE_PORT] == 0 && packet[UDP_SOURCE_PORT+1] == 67 &&
947
      packet[UDP_DEST_PORT] == 0 && packet[UDP_DEST_PORT+1] == 68)
948
   {
949
      IPDhcp(packet, frameIn->length, 2);            //DHCP reply
950
      return 0;
951
   }
952
 
953
   //Check if correct destination address
954
   if(memcmp(packet+ETHERNET_DEST, ethernetAddressPlasma, 6) ||
955
      memcmp(packet+IP_DEST, ipAddressPlasma, 4))
956
      return 0;
957
   rc = EthernetVerifyChecksums(packet, frameIn->length);
958
   //if(rc)
959
   //{
960
   //   printf("C ");
961
   //   return;
962
   //}
963
 
964
   //PING request?
965
   if(packet[IP_PROTOCOL] == 1)
966
   {
967 209 rhoads
      if(packet[PING_TYPE] == 0)  //PING reply
968
      {
969
         for(socket = SocketHead; socket; socket = socket->next)
970
         {
971
            if(socket->state == IP_PING &&
972
               memcmp(packet+IP_SOURCE, socket->headerSend+IP_DEST, 4) == 0)
973
            {
974 225 rhoads
               OS_Job(socket->funcPtr, socket, 0, 0);
975 209 rhoads
               return 0;
976
            }
977
         }
978
      }
979 155 rhoads
      if(packet[PING_TYPE] != 8)
980
         return 0;
981 160 rhoads
      frameOut = IPFrameGet(FRAME_COUNT_SEND);
982 155 rhoads
      if(frameOut == NULL)
983
         return 0;
984
      packetOut = frameOut->packet;
985
      EthernetCreateResponse(packetOut, packet, frameIn->length);
986
      frameOut->packet[PING_TYPE] = 0;       //PING reply
987
      IPSendPacket(NULL, frameOut, frameIn->length);
988
      return 0;
989
   }
990
 
991
   //TCP packet?
992
   if(packet[IP_PROTOCOL] == 0x06)
993
   {
994
      return IPProcessTCPPacket(frameIn);
995
   }
996
 
997
   //UDP packet?
998
   if(packet[IP_PROTOCOL] == 0x11)
999
   {
1000
      //Find open socket
1001
      for(socket = SocketHead; socket; socket = socket->next)
1002
      {
1003
         if(packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
1004
            memcmp(packet+IP_SOURCE, socket->headerRcv+IP_SOURCE, 8) == 0 &&
1005
            memcmp(packet+UDP_SOURCE_PORT, socket->headerRcv+UDP_SOURCE_PORT, 2) == 0)
1006
         {
1007
            break;
1008
         }
1009
      }
1010
 
1011
      if(socket == NULL)
1012
      {
1013
         //Find listening socket
1014
         for(socket = SocketHead; socket; socket = socket->next)
1015
         {
1016
            if(packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
1017
               memcmp(packet+UDP_DEST_PORT, socket->headerRcv+UDP_DEST_PORT, 2) == 0)
1018
            {
1019 209 rhoads
               EthernetCreateResponse(socket->headerSend, packet, UDP_DATA);
1020 155 rhoads
               break;
1021
            }
1022
         }
1023
      }
1024
 
1025
      if(socket)
1026
      {
1027
         if(IPVerbose)
1028
            printf("U");
1029
         FrameInsert(&socket->frameReadHead, &socket->frameReadTail, frameIn);
1030 225 rhoads
         OS_Job(socket->funcPtr, socket, 0, 0);
1031 155 rhoads
         return 1;
1032
      }
1033
   }
1034
   return 0;
1035
}
1036
 
1037
 
1038 220 rhoads
#ifndef WIN32
1039 209 rhoads
static void IPMainThread(void *arg)
1040 155 rhoads
{
1041
   uint32 message[4];
1042
   int rc;
1043
   IPFrame *frame, *frameOut=NULL;
1044
   uint32 ticks, ticksLast;
1045 209 rhoads
   (void)arg;
1046 155 rhoads
 
1047
   ticksLast = OS_ThreadTime();
1048
   memset(message, 0, sizeof(message));
1049
 
1050
   for(;;)
1051
   {
1052
      Led(0);
1053
      rc = OS_MQueueGet(IPMQueue, message, 10);
1054
      if(rc == 0)
1055
      {
1056
         frame = (IPFrame*)message[1];
1057
         if(message[0] == 0)       //frame received
1058
         {
1059
            Led(1);
1060
            frame->length = (uint16)message[2];
1061 247 rhoads
            rc = IPProcessEthernetPacket(frame, frame->length);
1062 155 rhoads
            if(rc == 0)
1063
               FrameFree(frame);
1064
         }
1065
         else if(message[0] == 1)  //frame sent
1066
         {
1067
            Led(2);
1068
            assert(frame == frameOut);
1069
            IPFrameReschedule(frame);
1070
            frameOut = NULL;
1071
         }
1072
         else if(message[0] == 2)  //frame ready to send
1073
         {
1074
         }
1075
      }
1076
 
1077
      if(frameOut == NULL)
1078
      {
1079 157 rhoads
         OS_MutexPend(IPMutex);
1080 155 rhoads
         frameOut = FrameSendTail;
1081
         if(frameOut)
1082
            FrameRemove(&FrameSendHead, &FrameSendTail, frameOut);
1083 157 rhoads
         OS_MutexPost(IPMutex);
1084 155 rhoads
         if(frameOut)
1085
         {
1086
            Led(4);
1087
            UartPacketSend(frameOut->packet, frameOut->length);
1088
         }
1089
      }
1090
 
1091
      ticks = OS_ThreadTime();
1092
      if(ticks - ticksLast > 100)
1093
      {
1094
         IPTick();
1095
         ticksLast = ticks;
1096
      }
1097
   }
1098
}
1099 220 rhoads
#endif
1100 155 rhoads
 
1101
 
1102 157 rhoads
uint8 *MyPacketGet(void)
1103 155 rhoads
{
1104 160 rhoads
   return (uint8*)IPFrameGet(FRAME_COUNT_RCV);
1105 155 rhoads
}
1106
 
1107
 
1108
//Set FrameSendFunction only if single threaded
1109 296 rhoads
void IPInit(IPFuncPtr frameSendFunction, uint8 macAddress[6], char name[6])
1110 155 rhoads
{
1111
   int i;
1112
   IPFrame *frame;
1113
 
1114 296 rhoads
   if(macAddress)
1115
      memcpy(ethernetAddressPlasma, macAddress, 6);
1116
   if(name)
1117
      memcpy(dhcpOptions+18, name, 6);
1118 209 rhoads
   FrameSendFunc = frameSendFunction;
1119 157 rhoads
   IPMutex = OS_MutexCreate("IPSem");
1120 155 rhoads
   IPMQueue = OS_MQueueCreate("IPMQ", FRAME_COUNT*2, 32);
1121
   for(i = 0; i < FRAME_COUNT; ++i)
1122
   {
1123
      frame = (IPFrame*)malloc(sizeof(IPFrame));
1124
      memset(frame, 0, sizeof(IPFrame));
1125
      frame->next = FrameFreeHead;
1126
      frame->prev = NULL;
1127
      FrameFreeHead = frame;
1128
   }
1129 296 rhoads
   FrameFreeCount = FRAME_COUNT;
1130 302 rhoads
#ifndef WIN32
1131 155 rhoads
   UartPacketConfig(MyPacketGet, PACKET_SIZE, IPMQueue);
1132 209 rhoads
   if(frameSendFunction == NULL)
1133 157 rhoads
      IPThread = OS_ThreadCreate("TCP/IP", IPMainThread, NULL, 240, 6000);
1134 302 rhoads
#endif
1135 155 rhoads
   IPDhcp(NULL, 360, 1);        //Send DHCP request
1136
}
1137
 
1138
 
1139 209 rhoads
//To open a socket for listen set ipAddress to 0
1140
IPSocket *IPOpen(IPMode_e mode, uint32 ipAddress, uint32 port, IPFuncPtr funcPtr)
1141 155 rhoads
{
1142
   IPSocket *socket;
1143 160 rhoads
   uint8 *ptrSend, *ptrRcv;
1144
   IPFrame *frame;
1145
   static int portSource=0x1007;
1146 155 rhoads
 
1147
   socket = (IPSocket*)malloc(sizeof(IPSocket));
1148
   if(socket == NULL)
1149
      return socket;
1150
   memset(socket, 0, sizeof(IPSocket));
1151
   socket->prev = NULL;
1152
   socket->state = IP_LISTEN;
1153
   socket->timeout = 0;
1154 231 rhoads
   socket->timeoutReset = SOCKET_TIMEOUT;
1155 155 rhoads
   socket->frameReadHead = NULL;
1156
   socket->frameReadTail = NULL;
1157
   socket->readOffset = 0;
1158
   socket->funcPtr = funcPtr;
1159
   socket->userData = 0;
1160
   socket->userFunc = NULL;
1161
   socket->userPtr = NULL;
1162 317 rhoads
   socket->seqWindow = 2048;
1163 160 rhoads
   ptrSend = socket->headerSend;
1164
   ptrRcv = socket->headerRcv;
1165 155 rhoads
 
1166 209 rhoads
   if(ipAddress == 0)
1167 155 rhoads
   {
1168
      //Setup listing port
1169 209 rhoads
      socket->headerRcv[TCP_DEST_PORT] = (uint8)(port >> 8);
1170
      socket->headerRcv[TCP_DEST_PORT+1] = (uint8)port;
1171 155 rhoads
   }
1172
   else
1173
   {
1174 160 rhoads
      //Setup sending packet
1175
      memset(ptrSend, 0, UDP_LENGTH);
1176
      memset(ptrRcv, 0, UDP_LENGTH);
1177 155 rhoads
 
1178 160 rhoads
      //Setup Ethernet
1179 209 rhoads
      if(ipAddress != IPAddressSelf())
1180
         memcpy(ptrSend+ETHERNET_DEST, ethernetAddressGateway, 6);
1181
      else
1182
         memcpy(ptrSend+ETHERNET_DEST, ethernetAddressPlasma, 6);
1183 160 rhoads
      memcpy(ptrSend+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
1184
      ptrSend[ETHERNET_FRAME_TYPE] = 0x08;
1185
 
1186
      //Setup IP
1187
      ptrSend[IP_VERSION_LENGTH] = 0x45;
1188
      ptrSend[IP_TIME_TO_LIVE] = 0x80;
1189
 
1190
      //Setup IP addresses
1191
      memcpy(ptrSend+IP_SOURCE, ipAddressPlasma, 4);
1192 209 rhoads
      ptrSend[IP_DEST] = (uint8)(ipAddress >> 24);
1193
      ptrSend[IP_DEST+1] = (uint8)(ipAddress >> 16);
1194
      ptrSend[IP_DEST+2] = (uint8)(ipAddress >> 8);
1195
      ptrSend[IP_DEST+3] = (uint8)ipAddress;
1196
      ptrRcv[IP_SOURCE] = (uint8)(ipAddress >> 24);
1197
      ptrRcv[IP_SOURCE+1] = (uint8)(ipAddress >> 16);
1198
      ptrRcv[IP_SOURCE+2] = (uint8)(ipAddress >> 8);
1199
      ptrRcv[IP_SOURCE+3] = (uint8)ipAddress;
1200 160 rhoads
      memcpy(ptrRcv+IP_DEST, ipAddressPlasma, 4);
1201
 
1202
      //Setup ports
1203
      ptrSend[TCP_SOURCE_PORT] = (uint8)(portSource >> 8);
1204
      ptrSend[TCP_SOURCE_PORT+1] = (uint8)portSource;
1205 209 rhoads
      ptrSend[TCP_DEST_PORT] = (uint8)(port >> 8);
1206
      ptrSend[TCP_DEST_PORT+1] = (uint8)port;
1207
      ptrRcv[TCP_SOURCE_PORT] = (uint8)(port >> 8);
1208
      ptrRcv[TCP_SOURCE_PORT+1] = (uint8)port;
1209 160 rhoads
      ptrRcv[TCP_DEST_PORT] = (uint8)(portSource >> 8);
1210
      ptrRcv[TCP_DEST_PORT+1] = (uint8)portSource;
1211 155 rhoads
      ++portSource;
1212
   }
1213
 
1214 209 rhoads
   if(mode == IP_MODE_TCP)
1215 155 rhoads
   {
1216 209 rhoads
      if(ipAddress)
1217 160 rhoads
         socket->state = IP_TCP;
1218
      else
1219
         socket->state = IP_LISTEN;
1220
      ptrSend[IP_PROTOCOL] = 0x06;  //TCP
1221
      ptrRcv[IP_PROTOCOL] = 0x06;
1222 155 rhoads
   }
1223 209 rhoads
   else if(mode == IP_MODE_UDP)
1224 155 rhoads
   {
1225
      socket->state = IP_UDP;
1226 160 rhoads
      ptrSend[IP_PROTOCOL] = 0x11;  //UDP
1227
      ptrRcv[IP_PROTOCOL] = 0x11;
1228 155 rhoads
   }
1229 209 rhoads
   else if(mode == IP_MODE_PING)
1230
   {
1231
      socket->state = IP_PING;
1232
      ptrSend[IP_PROTOCOL] = 0x01;  //PING
1233
      memset(ptrSend+PING_TYPE, 0, 8);
1234
      ptrSend[PING_TYPE] = 8;       //SEND
1235
   }
1236 155 rhoads
 
1237 160 rhoads
   //Add socket to linked list
1238 157 rhoads
   OS_MutexPend(IPMutex);
1239 155 rhoads
   socket->next = SocketHead;
1240 160 rhoads
   socket->prev = NULL;
1241
   if(SocketHead)
1242
      SocketHead->prev = socket;
1243 155 rhoads
   SocketHead = socket;
1244 157 rhoads
   OS_MutexPost(IPMutex);
1245 160 rhoads
 
1246 209 rhoads
   if(mode == IP_MODE_TCP && ipAddress)
1247 160 rhoads
   {
1248
      //Send TCP SYN
1249 206 rhoads
      socket->seq = 0x01234567;
1250 160 rhoads
      frame = IPFrameGet(0);
1251
      if(frame)
1252
      {
1253
         frame->packet[TCP_FLAGS] = TCP_FLAGS_SYN;
1254
         frame->packet[TCP_DATA] = 2;    //maximum segment size = 536
1255
         frame->packet[TCP_DATA+1] = 4;
1256
         frame->packet[TCP_DATA+2] = 2;
1257
         frame->packet[TCP_DATA+3] = 24;
1258
         TCPSendPacket(socket, frame, TCP_DATA+4);
1259
         ++socket->seq;
1260
      }
1261
   }
1262 155 rhoads
   return socket;
1263
}
1264
 
1265
 
1266 209 rhoads
void IPWriteFlush(IPSocket *socket)
1267 155 rhoads
{
1268
   uint8 *packetOut;
1269 209 rhoads
   if(socket->frameSend && socket->state != IP_UDP &&
1270
      socket->state != IP_PING)
1271 155 rhoads
   {
1272 209 rhoads
      packetOut = socket->frameSend->packet;
1273 220 rhoads
      packetOut[TCP_FLAGS] = TCP_FLAGS_ACK | TCP_FLAGS_PSH;
1274 209 rhoads
      TCPSendPacket(socket, socket->frameSend, TCP_DATA + socket->sendOffset);
1275
      socket->seq += socket->sendOffset;
1276
      socket->frameSend = NULL;
1277
      socket->sendOffset = 0;
1278 155 rhoads
   }
1279
}
1280
 
1281
 
1282 209 rhoads
uint32 IPWrite(IPSocket *socket, const uint8 *buf, uint32 length)
1283 155 rhoads
{
1284
   IPFrame *frameOut;
1285
   uint8 *packetOut;
1286 206 rhoads
   uint32 bytes, count=0, tries=0;
1287 155 rhoads
   int offset;
1288 165 rhoads
   OS_Thread_t *self;
1289 155 rhoads
 
1290 231 rhoads
   if(socket->timeout)
1291
      socket->timeout = socket->timeoutReset;
1292
 
1293 155 rhoads
   //printf("IPWrite(0x%x, %d)", Socket, Length);
1294 165 rhoads
   self = OS_ThreadSelf();
1295 209 rhoads
   while(length)
1296 155 rhoads
   {
1297 206 rhoads
      //Rate limit output
1298 317 rhoads
      if(socket->seq - socket->seqReceived >= SEND_WINDOW)
1299 206 rhoads
      {
1300 302 rhoads
         //printf("l(%d,%d,%d) ", socket->seq - socket->seqReceived, socket->seq, socket->seqReceived);
1301 206 rhoads
         if(self == IPThread || ++tries > 200)
1302
            break;
1303
         else
1304
         {
1305
            OS_ThreadSleep(1);
1306
            continue;
1307
         }
1308
      }
1309 165 rhoads
      tries = 0;
1310 209 rhoads
      while(socket->frameSend == NULL)
1311 155 rhoads
      {
1312 209 rhoads
         socket->frameSend = IPFrameGet(FRAME_COUNT_SEND);
1313
         socket->sendOffset = 0;
1314
         if(socket->frameSend == NULL)
1315 165 rhoads
         {
1316 302 rhoads
            //printf("L");
1317 165 rhoads
            if(self == IPThread || ++tries > 200)
1318
               break;
1319
            else
1320
               OS_ThreadSleep(1);
1321
         }
1322 155 rhoads
      }
1323 209 rhoads
      frameOut = socket->frameSend;
1324
      offset = socket->sendOffset;
1325 155 rhoads
      if(frameOut == NULL)
1326
         break;
1327
      packetOut = frameOut->packet;
1328
 
1329 209 rhoads
      if(socket->state == IP_PING)
1330 155 rhoads
      {
1331 209 rhoads
         bytes = length;
1332
         memcpy(packetOut, socket->headerSend, PING_DATA);
1333
         memcpy(packetOut+PING_DATA, buf, bytes);
1334
         IPSendPacket(socket, socket->frameSend, PING_DATA + bytes);
1335
         socket->frameSend = NULL;
1336
      }
1337
      else if(socket->state != IP_UDP)
1338
      {
1339
         bytes = 512 - offset;
1340
         if(bytes > length)
1341
            bytes = length;
1342
         socket->sendOffset += bytes;
1343
         memcpy(packetOut+TCP_DATA+offset, buf, bytes);
1344
         if(socket->sendOffset >= 512)
1345
            IPWriteFlush(socket);
1346 165 rhoads
         //if(Socket->seq - Socket->seqReceived > Socket->seqWindow)
1347
         //{
1348
         //   printf("W");
1349
         //   OS_ThreadSleep(10);
1350
         //}
1351 155 rhoads
      }
1352
      else  //UDP
1353
      {
1354 209 rhoads
         bytes = length;
1355
         memcpy(packetOut+UDP_DATA+offset, buf, bytes);
1356
         memcpy(packetOut, socket->headerSend, UDP_LENGTH);
1357
         IPSendPacket(socket, socket->frameSend, UDP_DATA + bytes);
1358
         socket->frameSend = NULL;
1359 155 rhoads
      }
1360
      count += bytes;
1361 209 rhoads
      buf += bytes;
1362
      length -= bytes;
1363 155 rhoads
   }
1364
   return count;
1365
}
1366
 
1367
 
1368 209 rhoads
uint32 IPRead(IPSocket *socket, uint8 *buf, uint32 length)
1369 155 rhoads
{
1370
   IPFrame *frame, *frame2;
1371
   int count=0, bytes, offset;
1372
 
1373 225 rhoads
   if(socket->state == IP_UDP)
1374
      offset = UDP_DATA;
1375
   else
1376 155 rhoads
      offset = TCP_DATA;
1377
 
1378 157 rhoads
   OS_MutexPend(IPMutex);
1379 209 rhoads
   for(frame = socket->frameReadTail; length && frame; )
1380 155 rhoads
   {
1381 209 rhoads
      bytes = frame->length - offset - socket->readOffset;
1382
      if(bytes > (int)length)
1383
         bytes = length;
1384
      memcpy(buf, frame->packet + offset + socket->readOffset, bytes);
1385
      buf += bytes;
1386
      socket->readOffset += bytes;
1387
      length -= bytes;
1388 155 rhoads
      count += bytes;
1389
 
1390
      //Check if done with packet
1391
      frame2 = frame;
1392
      frame = frame->prev;
1393 209 rhoads
      if(socket->readOffset == frame2->length - offset)
1394 155 rhoads
      {
1395
         //Remove packet from socket linked list
1396 209 rhoads
         socket->readOffset = 0;
1397
         FrameRemove(&socket->frameReadHead, &socket->frameReadTail, frame2);
1398 317 rhoads
         socket->ackProcessed += frame2->length - offset;
1399
         if(socket->state == IP_TCP &&
1400
            socket->ack - socket->ackProcessed > RECEIVE_WINDOW - 2048)
1401
         {
1402
            //Update receive window for flow control
1403
            frame2->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
1404
            TCPSendPacket(socket, frame2, TCP_DATA);
1405
         }
1406
         else
1407
            FrameFree(frame2);
1408 155 rhoads
      }
1409
   }
1410 157 rhoads
   OS_MutexPost(IPMutex);
1411 155 rhoads
   return count;
1412
}
1413
 
1414
 
1415 209 rhoads
static void IPClose2(IPSocket *socket)
1416 155 rhoads
{
1417
   IPFrame *frame, *framePrev;
1418
 
1419 157 rhoads
   OS_MutexPend(IPMutex);
1420 155 rhoads
 
1421 157 rhoads
   //Mark packets as don't retransmit
1422
   for(frame = FrameSendHead; frame; frame = frame->next)
1423 155 rhoads
   {
1424 209 rhoads
      if(frame->socket == socket)
1425 157 rhoads
         frame->socket = NULL;
1426 155 rhoads
   }
1427
 
1428
   //Remove packets from retransmision list
1429
   for(frame = FrameResendHead; frame; )
1430
   {
1431
      framePrev = frame;
1432
      frame = frame->next;
1433 209 rhoads
      if(framePrev->socket == socket)
1434 155 rhoads
      {
1435
         FrameRemove(&FrameResendHead, &FrameResendTail, framePrev);
1436
         FrameFree(framePrev);
1437
      }
1438
   }
1439
 
1440
   //Remove packets from socket read linked list
1441 209 rhoads
   for(frame = socket->frameReadHead; frame; )
1442 155 rhoads
   {
1443
      framePrev = frame;
1444
      frame = frame->next;
1445 209 rhoads
      FrameRemove(&socket->frameReadHead, &socket->frameReadTail, framePrev);
1446 155 rhoads
      FrameFree(framePrev);
1447
   }
1448
 
1449
   //Remove socket
1450 317 rhoads
   if(socket->state == IP_CLOSED || socket->state <= IP_UDP)
1451 225 rhoads
   {
1452
      if(socket->prev == NULL)
1453
         SocketHead = socket->next;
1454
      else
1455
         socket->prev->next = socket->next;
1456
      if(socket->next)
1457
         socket->next->prev = socket->prev;
1458
      free(socket);
1459
   }
1460 155 rhoads
   else
1461 225 rhoads
   {
1462
      //Give application 10 seconds to stop using socket
1463 317 rhoads
      if(socket->state > IP_UDP)
1464
         socket->state = IP_CLOSED;
1465 225 rhoads
      socket->timeout = 10;
1466
   }
1467 157 rhoads
   OS_MutexPost(IPMutex);
1468 155 rhoads
}
1469
 
1470
 
1471 209 rhoads
void IPClose(IPSocket *socket)
1472 155 rhoads
{
1473
   IPFrame *frameOut;
1474
 
1475 209 rhoads
   IPWriteFlush(socket);
1476
   if(socket->state <= IP_UDP)
1477 157 rhoads
   {
1478 209 rhoads
      IPClose2(socket);
1479 157 rhoads
      return;
1480
   }
1481
   frameOut = IPFrameGet(0);
1482 231 rhoads
   if(frameOut == NULL)
1483 155 rhoads
      return;
1484
   frameOut->packet[TCP_FLAGS] = TCP_FLAGS_FIN | TCP_FLAGS_ACK;
1485 209 rhoads
   TCPSendPacket(socket, frameOut, TCP_DATA);
1486
   ++socket->seq;
1487
   if(socket->state == IP_FIN_CLIENT)
1488
      IPClose2(socket);
1489 157 rhoads
   else
1490 209 rhoads
      socket->state = IP_FIN_SERVER;
1491 155 rhoads
}
1492
 
1493
 
1494 317 rhoads
void IPPrintf(IPSocket *socket, char *message,
1495
              int arg0, int arg1, int arg2, int arg3)
1496 209 rhoads
{
1497 317 rhoads
   char buf[500], *ptr;
1498
   if(socket == NULL)
1499
   {
1500
      printf(message, arg0, arg1, arg2, arg3);
1501
      return;
1502
   }
1503
   ptr = strstr(message, "%");
1504
   if(ptr == NULL)
1505
      IPWrite(socket, (uint8*)message, (int)strlen(message));
1506
   else
1507
   {
1508
      sprintf(buf, message, arg0, arg1, arg2, arg3, 0, 0, 0, 0);
1509
      IPWrite(socket, (uint8*)buf, (int)strlen(buf));
1510
   }
1511
   if(socket->dontFlush == 0)
1512
      IPWriteFlush(socket);
1513 209 rhoads
}
1514 155 rhoads
 
1515
 
1516
void IPTick(void)
1517
{
1518
   IPFrame *frame, *frame2;
1519
   IPSocket *socket, *socket2;
1520 296 rhoads
   unsigned long ticks;
1521
   static unsigned long ticksPrev=0, ticksPrev2=0;
1522 155 rhoads
 
1523 296 rhoads
   ticks = OS_ThreadTime();
1524
   if(ticks - ticksPrev >= 95)
1525 157 rhoads
   {
1526 296 rhoads
      if(IPVerbose && (Seconds % 60) == 0)
1527
      {
1528
         if(FrameFreeCount >= FRAME_COUNT-1)
1529
            printf("T");
1530
         else
1531
            printf("T(%d)", FrameFreeCount);
1532
      }
1533
      ++Seconds;
1534
      if(--DhcpRetrySeconds <= 0)
1535
         IPDhcp(NULL, 400, 1);   //DHCP request
1536 157 rhoads
   }
1537 155 rhoads
 
1538 157 rhoads
   OS_MutexPend(IPMutex);
1539 155 rhoads
 
1540
   //Retransmit timeout packets
1541
   for(frame = FrameResendHead; frame; )
1542
   {
1543
      frame2 = frame;
1544
      frame = frame->next;
1545 302 rhoads
      frame2->timeout = (short)(frame2->timeout - (ticks - ticksPrev2));
1546 296 rhoads
      if(--frame2->timeout <= 0)
1547 155 rhoads
      {
1548
         if(IPVerbose)
1549
            printf("r");
1550
         FrameRemove(&FrameResendHead, &FrameResendTail, frame2);
1551
         IPSendFrame(frame2);
1552
      }
1553
   }
1554
 
1555 296 rhoads
   if(ticks - ticksPrev >= 95)
1556 155 rhoads
   {
1557 296 rhoads
      //Close timed out sockets
1558
      for(socket = SocketHead; socket; )
1559 155 rhoads
      {
1560 296 rhoads
         socket2 = socket;
1561
         socket = socket->next;
1562
         if(socket2->timeout && --socket2->timeout == 0)
1563
         {
1564
            socket2->timeout = 10;
1565
            if(IPVerbose && socket2->state != IP_CLOSED &&
1566
                            socket2->state != IP_FIN_SERVER)
1567
               printf("t(%d,%d)", socket2->state, FrameFreeCount);
1568
            if(socket2->state == IP_TCP)
1569
               IPClose(socket2);
1570
            else if(socket2->state == IP_FIN_CLIENT)
1571
               IPClose(socket2);
1572
            else
1573
               IPClose2(socket2);
1574
         }
1575 155 rhoads
      }
1576 296 rhoads
      ticksPrev = ticks;
1577 155 rhoads
   }
1578 157 rhoads
   OS_MutexPost(IPMutex);
1579 296 rhoads
   ticksPrev2 = ticks;
1580 155 rhoads
}
1581
 
1582
 
1583
static void DnsCallback(IPSocket *socket)
1584
{
1585
   uint8 buf[200], *ptr;
1586
   uint32 ipAddress;
1587 209 rhoads
   int bytes;
1588 155 rhoads
 
1589
   memset(buf, 0, sizeof(buf));
1590 209 rhoads
   bytes = IPRead(socket, buf, sizeof(buf));
1591 155 rhoads
   if(buf[DNS_NUM_ANSWERS_RR+1])
1592
   {
1593 209 rhoads
      for(ptr = buf + DNS_QUESTIONS; ptr + 14 <= buf + bytes; ++ptr)
1594 155 rhoads
      {
1595 211 rhoads
         if(ptr[0] == 0 && ptr[1] == 1 && ptr[2] == 0 && ptr[3] == 1 &&
1596
            ptr[8] == 0 && ptr[9] == 4)
1597 155 rhoads
         {
1598 211 rhoads
            ipAddress = (ptr[10] << 24) | (ptr[11] << 16) | (ptr[12] << 8) | ptr[13];
1599
            printf("ipAddress = %d.%d.%d.%d\n", ptr[10], ptr[11], ptr[12], ptr[13]);
1600 155 rhoads
            socket->userData = ipAddress;
1601
            if(socket->userFunc)
1602
            {
1603 209 rhoads
               socket->userFunc(socket, ipAddress, socket->userPtr);
1604 155 rhoads
            }
1605
            break;
1606
         }
1607
      }
1608
   }
1609 220 rhoads
   IPClose(socket);
1610 155 rhoads
}
1611
 
1612
 
1613 220 rhoads
void IPResolve(char *name, IPFuncPtr resolvedFunc, void *arg)
1614 155 rhoads
{
1615
   uint8 buf[200], *ptr;
1616
   int length, i;
1617
   IPSocket *socket;
1618
 
1619
   socket = IPOpen(IP_MODE_UDP, ipAddressDns, DNS_PORT, DnsCallback);
1620
   memset(buf, 0, sizeof(buf));
1621
   buf[DNS_ID+1] = 1;
1622
   buf[DNS_FLAGS] = 1;
1623
   buf[DNS_NUM_QUESTIONS+1] = 1;
1624
 
1625
   //Setup name
1626
   ptr = buf + DNS_QUESTIONS;
1627 209 rhoads
   strncpy((char*)ptr+1, name, 100);
1628 155 rhoads
   ptr[0] = 1;
1629
   while(ptr[0])
1630
   {
1631
      for(i = 0; i < 100; ++i)
1632
      {
1633
         if(ptr[i+1] == '.' || ptr[i+1] == 0)
1634
         {
1635
            ptr[0] = (uint8)i;
1636
            ptr += i+1;
1637
            break;
1638
         }
1639
      }
1640
   }
1641
   ++ptr;
1642
   ptr[1] = DNS_QUERY_TYPE_IP;
1643
   ptr[3] = DNS_QUERY_CLASS;
1644
   length = (int)(ptr - buf) + 4;
1645
   if(length < 60)
1646
      length = 60;
1647
 
1648
   socket->userFunc = (IPFuncPtr)resolvedFunc;
1649 209 rhoads
   socket->userPtr = arg;
1650 155 rhoads
   socket->userData = 0;
1651
   IPWrite(socket, buf, length);
1652
}
1653
 

powered by: WebSVN 2.1.0

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