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

Subversion Repositories plasma

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

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

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

powered by: WebSVN 2.1.0

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