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

Subversion Repositories mlite

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

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 160 rhoads
   if(frame->packet[TCP_FLAGS] & (TCP_FLAGS_FIN | TCP_FLAGS_SYN))
361 155 rhoads
      ++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 160 rhoads
   length2 = length - TCP_DATA;
458
   if(socket && (packet[TCP_FLAGS] & (TCP_FLAGS_FIN | TCP_FLAGS_SYN)))
459 155 rhoads
      length2 = 1;
460
   frame->socket = socket;
461
   frame->timeout = 0;
462
   frame->retryCnt = 0;
463
   if(socket)
464
      frame->seqEnd = socket->seq + length2;
465
   IPSendFrame(frame);
466
}
467
 
468
 
469
static void TCPSendPacket(IPSocket *socket, IPFrame *frame, int length)
470
{
471
   uint8 *packet = frame->packet;
472 160 rhoads
   int flags, count;
473 155 rhoads
 
474
   flags = packet[TCP_FLAGS];
475
   memcpy(packet, socket->headerSend, TCP_SEQ);
476
   packet[TCP_FLAGS] = (uint8)flags;
477
   if(flags & TCP_FLAGS_SYN)
478
      packet[TCP_HEADER_LENGTH] = 0x60;  //set maximum segment size
479
   else
480
      packet[TCP_HEADER_LENGTH] = 0x50;
481
   packet[TCP_SEQ]   = (uint8)(socket->seq >> 24);
482
   packet[TCP_SEQ+1] = (uint8)(socket->seq >> 16);
483
   packet[TCP_SEQ+2] = (uint8)(socket->seq >> 8);
484
   packet[TCP_SEQ+3] = (uint8)socket->seq;
485
   packet[TCP_ACK]   = (uint8)(socket->ack >> 24);
486
   packet[TCP_ACK+1] = (uint8)(socket->ack >> 16);
487
   packet[TCP_ACK+2] = (uint8)(socket->ack >> 8);
488
   packet[TCP_ACK+3] = (uint8)socket->ack;
489 160 rhoads
   count = FrameFreeCount - FRAME_COUNT_WINDOW;
490
   if(count < 1)
491
      count = 1;
492
   count *= 512;
493
   packet[TCP_WINDOW_SIZE] = (uint8)(count >> 8);
494
   packet[TCP_WINDOW_SIZE+1] = (uint8)count;
495 155 rhoads
   packet[TCP_URGENT_POINTER] = 0;
496
   packet[TCP_URGENT_POINTER+1] = 0;
497
   IPSendPacket(socket, frame, length);
498
}
499
 
500
 
501
static void EthernetCreateResponse(unsigned char *packetOut,
502
                                   const unsigned char *packet,
503
                                   int length)
504
{
505
   //Swap destination and source fields
506
   memcpy(packetOut, packet, length);
507
   memcpy(packetOut+ETHERNET_DEST, packet+ETHERNET_SOURCE, 6);
508
   memcpy(packetOut+ETHERNET_SOURCE, packet+ETHERNET_DEST, 6);
509
   if(packet[ETHERNET_FRAME_TYPE+1] == 0x00)  //IP
510
   {
511
      memcpy(packetOut+IP_SOURCE, packet+IP_DEST, 4);
512
      memcpy(packetOut+IP_DEST, packet+IP_SOURCE, 4);
513
      if(packet[IP_PROTOCOL] == 0x06 || packet[IP_PROTOCOL] == 0x11)   //TCP/UDP
514
      {
515
         memcpy(packetOut+TCP_SOURCE_PORT, packet+TCP_DEST_PORT, 2);
516
         memcpy(packetOut+TCP_DEST_PORT, packet+TCP_SOURCE_PORT, 2);
517
      }
518
   }
519
}
520
 
521
 
522
static void IPDhcp(const unsigned char *packet, int length, int state)
523
{
524
   uint8 *packetOut, *ptr;
525
   const uint8 *ptr2;
526
   IPFrame *frame;
527
   static int request=0;
528
 
529
   if(state == 1)
530
   {
531
      //Create DHCP Discover
532 157 rhoads
      frame = IPFrameGet(0);
533 155 rhoads
      if(frame == NULL)
534
         return;
535
      packetOut = frame->packet;
536
      memset(packetOut, 0, 512);
537
      memcpy(packetOut, dhcpDiscover, sizeof(dhcpDiscover));
538
      memcpy(packetOut+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
539
      memcpy(packetOut+DHCP_CLIENT_ETHERNET, ethernetAddressPlasma, 6);
540
      memcpy(packetOut+DHCP_MAGIC_COOKIE, dhcpOptions, sizeof(dhcpOptions));
541
      memcpy(packetOut+DHCP_MAGIC_COOKIE+10, ethernetAddressPlasma, 6);
542
      IPSendPacket(NULL, frame, 400);
543
      request = DHCP_DISCOVER;
544
      DhcpRetrySeconds = RETRANSMIT_TIME;
545
   }
546
   else if(state == 2 && memcmp(packet+DHCP_CLIENT_ETHERNET, ethernetAddressPlasma, 6) == 0)
547
   {
548
      if(packet[DHCP_MAGIC_COOKIE+6] == DHCP_OFFER && request == DHCP_DISCOVER)
549
      {
550
         //Process DHCP Offer and send DHCP Request
551 157 rhoads
         frame = IPFrameGet(0);
552 155 rhoads
         if(frame == NULL)
553
            return;
554
         packetOut = frame->packet;
555
         memset(packetOut, 0, 512);
556
         memcpy(packetOut, dhcpDiscover, sizeof(dhcpDiscover));
557
         memcpy(packetOut+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
558
         memcpy(packetOut+DHCP_CLIENT_ETHERNET, ethernetAddressPlasma, 6);
559
         memcpy(packetOut+DHCP_MAGIC_COOKIE, dhcpOptions, sizeof(dhcpOptions));
560
         //memcpy(packetOut+DHCP_MAGIC_COOKIE+10, ethernetAddressPlasma, 6);
561
         request = DHCP_REQUEST;
562
         packetOut[DHCP_MAGIC_COOKIE+6] = DHCP_REQUEST;
563
         ptr = packetOut+DHCP_MAGIC_COOKIE+sizeof(dhcpOptions)-1;
564
         ptr[0] = DHCP_REQUEST_IP;
565
         ptr[1] = 4;
566
         memcpy(ptr+2, packet+DHCP_YOUR_IP, 4);
567
         ptr[6] = DHCP_REQUEST_SERV_IP;
568
         ptr[7] = 4;
569
         memcpy(ptr+8, packet+DHCP_SERVER_IP, 4);
570
         ptr[12] = DHCP_END_OPTION;
571
         IPSendPacket(NULL, frame, 400);
572
      }
573
      else if(packet[DHCP_MAGIC_COOKIE+6] == DHCP_ACK && request == DHCP_REQUEST)
574
      {
575
         //Process DHCP Ack
576
         request = 0;
577
         DhcpRetrySeconds = 3600*4;
578
         memcpy(ipAddressPlasma, packet+DHCP_YOUR_IP, 4);
579
         printf("IP=%d.%d.%d.%d ", ipAddressPlasma[0], ipAddressPlasma[1],
580
            ipAddressPlasma[2], ipAddressPlasma[3]);
581
         memcpy(ipAddressGateway, packet+DHCP_GATEWAY_IP, 4);
582
         if(ipAddressGateway[0] == 0 && ipAddressGateway[1] == 0 &&
583
            ipAddressGateway[2] == 0 && ipAddressGateway[3] == 0)
584
            memcpy(ipAddressGateway, packet+DHCP_SERVER_IP, 4);
585
         printf("GW=%d.%d.%d.%d ", ipAddressGateway[0], ipAddressGateway[1],
586
            ipAddressGateway[2], ipAddressGateway[3]);
587
         memcpy(ethernetAddressGateway, packet+ETHERNET_SOURCE, 6);
588
         ptr2 = packet+DHCP_MAGIC_COOKIE+4;
589
         while(ptr2[0] != DHCP_END_OPTION && (int)(ptr2 - packet) < length)
590
         {
591
            if(ptr2[0] == DHCP_PARAM_DNS)
592
            {
593
               ipAddressDns = (ptr2[2] << 24) | (ptr2[3] << 16) | (ptr2[4] << 8) | ptr2[5];
594
               printf("DNS=%d.%d.%d.%d ", ptr2[2], ptr2[3], ptr2[4], ptr2[5]);
595
            }
596
            ptr2 += ptr2[1] + 2;
597
         }
598
 
599
         //Check if DHCP reply came from gateway
600
         if(memcmp(packet+IP_SOURCE, ipAddressGateway, 4))
601
         {
602
            //Send ARP to gateway
603 157 rhoads
            frame = IPFrameGet(0);
604 155 rhoads
            if(frame == NULL)
605
               return;
606
            packetOut = frame->packet;
607
            memset(packetOut, 0, 512);
608
            memset(packetOut+ETHERNET_DEST, 0xff, 6);
609
            memcpy(packetOut+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
610
            packetOut[ETHERNET_FRAME_TYPE] = 0x08;
611
            packetOut[ETHERNET_FRAME_TYPE+1] = 0x06;
612
            packetOut[ARP_HARD_TYPE+1] = 0x01;
613
            packetOut[ARP_PROT_TYPE] = 0x08;
614
            packetOut[ARP_HARD_SIZE] = 0x06;
615
            packetOut[ARP_PROT_SIZE] = 0x04;
616
            packetOut[ARP_OP+1] = 1;
617
            memcpy(packetOut+ARP_ETHERNET_SENDER, ethernetAddressPlasma, 6);
618
            memcpy(packetOut+ARP_IP_SENDER, ipAddressPlasma, 4);
619
            memcpy(packetOut+ARP_IP_TARGET, ipAddressGateway, 4);
620
            IPSendPacket(NULL, frame, 60);
621
         }
622
      }
623
   }
624
}
625
 
626
 
627
static int IPProcessTCPPacket(IPFrame *frameIn)
628
{
629
   uint32 seq, ack;
630
   int length, ip_length, bytes;
631
   IPSocket *socket, *socketNew;
632
   IPFrame *frameOut, *frame2, *framePrev;
633
   uint8 *packet, *packetOut;
634
 
635
   packet = frameIn->packet;
636
   length = frameIn->length;
637
 
638
   ip_length = (packet[IP_LENGTH] << 8) | packet[IP_LENGTH+1];
639
   seq = (packet[TCP_SEQ] << 24) | (packet[TCP_SEQ+1] << 16) |
640
         (packet[TCP_SEQ+2] << 8) | packet[TCP_SEQ+3];
641
   ack = (packet[TCP_ACK] << 24) | (packet[TCP_ACK+1] << 16) |
642
         (packet[TCP_ACK+2] << 8) | packet[TCP_ACK+3];
643
 
644
   //Check if start of connection
645 160 rhoads
   if((packet[TCP_FLAGS] & (TCP_FLAGS_SYN | TCP_FLAGS_ACK)) == TCP_FLAGS_SYN)
646 155 rhoads
   {
647
      if(IPVerbose)
648
         printf("S");
649
      //Check if duplicate SYN
650
      for(socket = SocketHead; socket; socket = socket->next)
651
      {
652
         if(socket->state != IP_LISTEN &&
653
            packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
654
            memcmp(packet+IP_SOURCE, socket->headerRcv+IP_SOURCE, 8) == 0 &&
655
            memcmp(packet+TCP_SOURCE_PORT, socket->headerRcv+TCP_SOURCE_PORT, 4) == 0)
656
         {
657
            if(IPVerbose)
658
               printf("s");
659
            return 0;
660
         }
661
      }
662
 
663
      //Find an open port
664
      for(socket = SocketHead; socket; socket = socket->next)
665
      {
666
         if(socket->state == IP_LISTEN &&
667
            packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
668
            memcmp(packet+TCP_DEST_PORT, socket->headerRcv+TCP_DEST_PORT, 2) == 0)
669
         {
670
            //Create a new socket
671 160 rhoads
            frameOut = IPFrameGet(FRAME_COUNT_SEND);
672 155 rhoads
            if(frameOut == NULL)
673
               return 0;
674
            socketNew = (IPSocket*)malloc(sizeof(IPSocket));
675
            if(socketNew == NULL)
676
               return 0;
677
            memcpy(socketNew, socket, sizeof(IPSocket));
678
            socketNew->state = IP_TCP;
679
            socketNew->timeout = RETRANSMIT_TIME * 3;
680
            socketNew->ack = seq;
681
            socketNew->seq = socketNew->ack + 0x12345678;
682
            socketNew->seqReceived = socketNew->seq;
683
 
684
            //Send ACK
685
            packetOut = frameOut->packet;
686
            EthernetCreateResponse(packetOut, packet, length);
687
            memcpy(socketNew->headerRcv, packet, TCP_SEQ);
688
            memcpy(socketNew->headerSend, packetOut, TCP_SEQ);
689
            packetOut[TCP_FLAGS] = TCP_FLAGS_SYN | TCP_FLAGS_ACK;
690
            ++socketNew->ack;
691
            packetOut[TCP_DATA] = 2;    //maximum segment size = 536
692
            packetOut[TCP_DATA+1] = 4;
693
            packetOut[TCP_DATA+2] = 2;
694
            packetOut[TCP_DATA+3] = 24;
695
            TCPSendPacket(socketNew, frameOut, TCP_DATA+4);
696
            ++socketNew->seq;
697
 
698
            //Add socket to linked list
699 157 rhoads
            OS_MutexPend(IPMutex);
700 155 rhoads
            socketNew->next = SocketHead;
701
            socketNew->prev = NULL;
702
            if(SocketHead)
703
               SocketHead->prev = socketNew;
704
            SocketHead = socketNew;
705 157 rhoads
            OS_MutexPost(IPMutex);
706 155 rhoads
            return 0;
707
         }
708
      }
709
      return 0;
710
   }
711
 
712
   //Find an open socket
713
   for(socket = SocketHead; socket; socket = socket->next)
714
   {
715
      if(packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
716
         memcmp(packet+IP_SOURCE, socket->headerRcv+IP_SOURCE, 8) == 0 &&
717
         memcmp(packet+TCP_SOURCE_PORT, socket->headerRcv+TCP_SOURCE_PORT, 4) == 0)
718
      {
719
         break;
720
      }
721
   }
722
   if(socket == NULL)
723
      return 0;
724
 
725
   //Check if FIN flag set
726
   if(packet[TCP_FLAGS] & TCP_FLAGS_FIN)
727
   {
728
      socket->timeout = SOCKET_TIMEOUT;
729
      if(IPVerbose)
730
         printf("F");
731 157 rhoads
      frameOut = IPFrameGet(0);
732 155 rhoads
      if(frameOut == NULL)
733
         return 0;
734
      packetOut = frameOut->packet;
735
      packetOut[TCP_FLAGS] = TCP_FLAGS_ACK;
736
      ++socket->ack;
737
      TCPSendPacket(socket, frameOut, TCP_DATA);
738
      if(socket->state == IP_FIN_SERVER)
739
         IPClose2(socket);
740
      else
741 160 rhoads
      {
742 155 rhoads
         socket->state = IP_FIN_CLIENT;
743 160 rhoads
         if(socket->funcPtr)
744
            socket->funcPtr(socket);
745
      }
746 155 rhoads
   }
747
   else if(packet[TCP_FLAGS] & TCP_FLAGS_RST)
748
   {
749
      if(socket->state == IP_FIN_SERVER)
750
         IPClose2(socket);
751
      else
752 160 rhoads
      {
753 155 rhoads
         socket->state = IP_FIN_CLIENT;
754 160 rhoads
         if(socket->funcPtr)
755
            socket->funcPtr(socket);
756
      }
757 155 rhoads
   }
758
   else
759
   {
760
      //Check if packets can be removed from retransmition list
761
      if(ack != socket->seqReceived)
762
      {
763 157 rhoads
         OS_MutexPend(IPMutex);
764 155 rhoads
         for(frame2 = FrameResendHead; frame2; )
765
         {
766
            framePrev = frame2;
767
            frame2 = frame2->next;
768
            if(framePrev->socket == socket && (int)(ack - framePrev->seqEnd) >= 0)
769
            {
770
               //Remove packet from retransmition queue
771 160 rhoads
               if(socket->timeout)
772
                  socket->timeout = SOCKET_TIMEOUT;
773 155 rhoads
               FrameRemove(&FrameResendHead, &FrameResendTail, framePrev);
774
               FrameFree(framePrev);
775
            }
776
         }
777 157 rhoads
         OS_MutexPost(IPMutex);
778 155 rhoads
         socket->seqReceived = ack;
779
      }
780
 
781
      bytes = ip_length - (TCP_DATA - IP_VERSION_LENGTH);
782
 
783 160 rhoads
      //Check if SYN/ACK
784
      if((packet[TCP_FLAGS] & (TCP_FLAGS_SYN | TCP_FLAGS_ACK)) ==
785
         (TCP_FLAGS_SYN | TCP_FLAGS_ACK))
786
      {
787
         //Ack SYN/ACK
788
         socket->ack = seq + 1;
789
         frameOut = IPFrameGet(FRAME_COUNT_SEND);
790
         if(frameOut)
791
         {
792
            frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
793
            TCPSendPacket(socket, frameOut, TCP_DATA);
794
         }
795
         if(socket->funcPtr)
796
            socket->funcPtr(socket);
797
         return 0;
798
      }
799
      else if(packet[TCP_HEADER_LENGTH] != 0x50)
800
      {
801
         if(IPVerbose)
802
            printf("length error\n");
803
         return 0;
804
      }
805
 
806 155 rhoads
      //Copy packet into socket
807
      if(socket->ack == seq && bytes > 0)
808
      {
809
         //Insert packet into socket linked list
810 160 rhoads
         if(socket->timeout)
811
            socket->timeout = SOCKET_TIMEOUT;
812 155 rhoads
         if(IPVerbose)
813
            printf("D");
814
         FrameInsert(&socket->frameReadHead, &socket->frameReadTail, frameIn);
815
         socket->ack += bytes;
816
 
817
         //Ack data
818 160 rhoads
         frameOut = IPFrameGet(FRAME_COUNT_SEND);
819 155 rhoads
         if(frameOut)
820
         {
821
            frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
822
            TCPSendPacket(socket, frameOut, TCP_DATA);
823
         }
824
 
825
         //Notify application
826
         if(socket->funcPtr)
827
            socket->funcPtr(socket);
828 157 rhoads
         //Using frame
829
         return 1;
830 155 rhoads
      }
831 157 rhoads
 
832 160 rhoads
      if(bytes)
833 157 rhoads
      {
834
         //Ack with current offset since data missing
835 160 rhoads
         frameOut = IPFrameGet(FRAME_COUNT_SEND);
836 157 rhoads
         if(frameOut)
837
         {
838
            frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;
839
            TCPSendPacket(socket, frameOut, TCP_DATA);
840
         }
841
      }
842 155 rhoads
   }
843
   return 0;
844
}
845
 
846
 
847
int IPProcessEthernetPacket(IPFrame *frameIn)
848
{
849
   int ip_length, rc;
850
   IPSocket *socket;
851
   IPFrame *frameOut;
852
   uint8 *packet, *packetOut;
853
 
854
   packet = frameIn->packet;
855
 
856
   if(packet[ETHERNET_FRAME_TYPE] != 0x08 || frameIn->length > PACKET_SIZE)
857
      return 0;  //wrong ethernet type, packet not used
858
 
859
   //ARP?
860
   if(packet[ETHERNET_FRAME_TYPE+1] == 0x06)
861
   {
862
      //Check if ARP reply
863
      if(memcmp(packet+ETHERNET_DEST, ethernetAddressPlasma, 6) == 0 &&
864
         packet[ARP_OP+1] == 2 && memcmp(packet+ARP_IP_SENDER, ipAddressGateway, 4) == 0)
865
      {
866
         //Found MAC address for gateway
867
         memcpy(ethernetAddressGateway, packet+ARP_ETHERNET_SENDER, 6);
868
         return 0;
869
      }
870
 
871
      //Check if ARP request
872
      if(memcmp(packet+ETHERNET_DEST, ethernetAddressNull, 6) ||
873
         packet[ARP_OP] != 0 || packet[ARP_OP+1] != 1 ||
874
         memcmp(packet+ARP_IP_TARGET, ipAddressPlasma, 4))
875
         return 0;
876
      //Create ARP response
877 157 rhoads
      frameOut = IPFrameGet(0);
878 155 rhoads
      if(frameOut == NULL)
879
         return 0;
880
      packetOut = frameOut->packet;
881
      memcpy(packetOut, packet, frameIn->length);
882
      memcpy(packetOut+ETHERNET_DEST, packet+ETHERNET_SOURCE, 6);
883
      memcpy(packetOut+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
884
      packetOut[ARP_OP+1] = 2; //ARP reply
885
      memcpy(packetOut+ARP_ETHERNET_SENDER, ethernetAddressPlasma, 6);
886
      memcpy(packetOut+ARP_IP_SENDER, packet+ARP_IP_TARGET, 4);
887
      memcpy(packetOut+ARP_ETHERNET_TARGET, packet+ARP_ETHERNET_SENDER, 6);
888
      memcpy(packetOut+ARP_IP_TARGET, packet+ARP_IP_SENDER, 4);
889
      IPSendPacket(NULL, frameOut, frameIn->length);
890
      return 0;
891
   }
892
 
893
   //Check if proper type of packet
894
   ip_length = (packet[IP_LENGTH] << 8) | packet[IP_LENGTH+1];
895
   if(frameIn->length < UDP_DATA || ip_length > frameIn->length - IP_VERSION_LENGTH)
896
      return 0;
897
   if(packet[ETHERNET_FRAME_TYPE+1] != 0x00 ||
898
      packet[IP_VERSION_LENGTH] != 0x45)
899
      return 0;
900
 
901
   //Check if DHCP reply
902
   if(packet[IP_PROTOCOL] == 0x11 &&
903
      packet[UDP_SOURCE_PORT] == 0 && packet[UDP_SOURCE_PORT+1] == 67 &&
904
      packet[UDP_DEST_PORT] == 0 && packet[UDP_DEST_PORT+1] == 68)
905
   {
906
      IPDhcp(packet, frameIn->length, 2);            //DHCP reply
907
      return 0;
908
   }
909
 
910
   //Check if correct destination address
911
   if(memcmp(packet+ETHERNET_DEST, ethernetAddressPlasma, 6) ||
912
      memcmp(packet+IP_DEST, ipAddressPlasma, 4))
913
      return 0;
914
   rc = EthernetVerifyChecksums(packet, frameIn->length);
915
   //if(rc)
916
   //{
917
   //   printf("C ");
918
   //   return;
919
   //}
920
 
921
   //PING request?
922
   if(packet[IP_PROTOCOL] == 1)
923
   {
924
      if(packet[PING_TYPE] != 8)
925
         return 0;
926 160 rhoads
      frameOut = IPFrameGet(FRAME_COUNT_SEND);
927 155 rhoads
      if(frameOut == NULL)
928
         return 0;
929
      packetOut = frameOut->packet;
930
      EthernetCreateResponse(packetOut, packet, frameIn->length);
931
      frameOut->packet[PING_TYPE] = 0;       //PING reply
932
      IPSendPacket(NULL, frameOut, frameIn->length);
933
      return 0;
934
   }
935
 
936
   //TCP packet?
937
   if(packet[IP_PROTOCOL] == 0x06)
938
   {
939
      return IPProcessTCPPacket(frameIn);
940
   }
941
 
942
   //UDP packet?
943
   if(packet[IP_PROTOCOL] == 0x11)
944
   {
945
      //Find open socket
946
      for(socket = SocketHead; socket; socket = socket->next)
947
      {
948
         if(packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
949
            memcmp(packet+IP_SOURCE, socket->headerRcv+IP_SOURCE, 8) == 0 &&
950
            memcmp(packet+UDP_SOURCE_PORT, socket->headerRcv+UDP_SOURCE_PORT, 2) == 0)
951
         {
952
            break;
953
         }
954
      }
955
 
956
      if(socket == NULL)
957
      {
958
         //Find listening socket
959
         for(socket = SocketHead; socket; socket = socket->next)
960
         {
961
            if(packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&
962
               memcmp(packet+UDP_DEST_PORT, socket->headerRcv+UDP_DEST_PORT, 2) == 0)
963
            {
964
               break;
965
            }
966
         }
967
      }
968
 
969
      if(socket)
970
      {
971
         if(IPVerbose)
972
            printf("U");
973
         FrameInsert(&socket->frameReadHead, &socket->frameReadTail, frameIn);
974
         socket->funcPtr(socket);
975
         return 1;
976
      }
977
   }
978
   return 0;
979
}
980
 
981
 
982
void IPMainThread(void *Arg)
983
{
984
   uint32 message[4];
985
   int rc;
986
   IPFrame *frame, *frameOut=NULL;
987
   uint32 ticks, ticksLast;
988
   (void)Arg;
989
 
990
   ticksLast = OS_ThreadTime();
991
   memset(message, 0, sizeof(message));
992
 
993
   for(;;)
994
   {
995
      Led(0);
996
      rc = OS_MQueueGet(IPMQueue, message, 10);
997
      if(rc == 0)
998
      {
999
         frame = (IPFrame*)message[1];
1000
         if(message[0] == 0)       //frame received
1001
         {
1002
            Led(1);
1003
            frame->length = (uint16)message[2];
1004
            rc = IPProcessEthernetPacket(frame);
1005
            if(rc == 0)
1006
               FrameFree(frame);
1007
         }
1008
         else if(message[0] == 1)  //frame sent
1009
         {
1010
            Led(2);
1011
            assert(frame == frameOut);
1012
            IPFrameReschedule(frame);
1013
            frameOut = NULL;
1014
         }
1015
         else if(message[0] == 2)  //frame ready to send
1016
         {
1017
         }
1018
      }
1019
 
1020
      if(frameOut == NULL)
1021
      {
1022 157 rhoads
         OS_MutexPend(IPMutex);
1023 155 rhoads
         frameOut = FrameSendTail;
1024
         if(frameOut)
1025
            FrameRemove(&FrameSendHead, &FrameSendTail, frameOut);
1026 157 rhoads
         OS_MutexPost(IPMutex);
1027 155 rhoads
         if(frameOut)
1028
         {
1029
            Led(4);
1030
            UartPacketSend(frameOut->packet, frameOut->length);
1031
         }
1032
      }
1033
 
1034
      ticks = OS_ThreadTime();
1035
      if(ticks - ticksLast > 100)
1036
      {
1037
         IPTick();
1038
         ticksLast = ticks;
1039
      }
1040
   }
1041
}
1042
 
1043
 
1044 157 rhoads
uint8 *MyPacketGet(void)
1045 155 rhoads
{
1046 160 rhoads
   return (uint8*)IPFrameGet(FRAME_COUNT_RCV);
1047 155 rhoads
}
1048
 
1049
 
1050
//Set FrameSendFunction only if single threaded
1051
void IPInit(IPFuncPtr FrameSendFunction)
1052
{
1053
   int i;
1054
   IPFrame *frame;
1055
 
1056
   FrameSendFunc = FrameSendFunction;
1057 157 rhoads
   IPMutex = OS_MutexCreate("IPSem");
1058 155 rhoads
   IPMQueue = OS_MQueueCreate("IPMQ", FRAME_COUNT*2, 32);
1059
   for(i = 0; i < FRAME_COUNT; ++i)
1060
   {
1061
      frame = (IPFrame*)malloc(sizeof(IPFrame));
1062
      memset(frame, 0, sizeof(IPFrame));
1063
      frame->next = FrameFreeHead;
1064
      frame->prev = NULL;
1065
      FrameFreeHead = frame;
1066
   }
1067
   UartPacketConfig(MyPacketGet, PACKET_SIZE, IPMQueue);
1068
   if(FrameSendFunction == NULL)
1069 157 rhoads
      IPThread = OS_ThreadCreate("TCP/IP", IPMainThread, NULL, 240, 6000);
1070 155 rhoads
 
1071
   IPDhcp(NULL, 360, 1);        //Send DHCP request
1072
}
1073
 
1074
 
1075
//To open a socket for listen set IPAddress to 0
1076
IPSocket *IPOpen(IPMode_e Mode, uint32 IPAddress, uint32 Port, IPFuncPtr funcPtr)
1077
{
1078
   IPSocket *socket;
1079 160 rhoads
   uint8 *ptrSend, *ptrRcv;
1080
   IPFrame *frame;
1081
   static int portSource=0x1007;
1082 155 rhoads
   (void)Mode;
1083
   (void)IPAddress;
1084
 
1085
   socket = (IPSocket*)malloc(sizeof(IPSocket));
1086
   if(socket == NULL)
1087
      return socket;
1088
   memset(socket, 0, sizeof(IPSocket));
1089
   socket->prev = NULL;
1090
   socket->state = IP_LISTEN;
1091
   socket->timeout = 0;
1092
   socket->frameReadHead = NULL;
1093
   socket->frameReadTail = NULL;
1094
   socket->readOffset = 0;
1095
   socket->funcPtr = funcPtr;
1096
   socket->userData = 0;
1097
   socket->userFunc = NULL;
1098
   socket->userPtr = NULL;
1099 160 rhoads
   ptrSend = socket->headerSend;
1100
   ptrRcv = socket->headerRcv;
1101 155 rhoads
 
1102
   if(IPAddress == 0)
1103
   {
1104
      //Setup listing port
1105
      socket->headerRcv[TCP_DEST_PORT] = (uint8)(Port >> 8);
1106
      socket->headerRcv[TCP_DEST_PORT+1] = (uint8)Port;
1107
   }
1108
   else
1109
   {
1110 160 rhoads
      //Setup sending packet
1111
      memset(ptrSend, 0, UDP_LENGTH);
1112
      memset(ptrRcv, 0, UDP_LENGTH);
1113 155 rhoads
 
1114 160 rhoads
      //Setup Ethernet
1115
      memcpy(ptrSend+ETHERNET_DEST, ethernetAddressGateway, 6);
1116
      memcpy(ptrSend+ETHERNET_SOURCE, ethernetAddressPlasma, 6);
1117
      ptrSend[ETHERNET_FRAME_TYPE] = 0x08;
1118
 
1119
      //Setup IP
1120
      ptrSend[IP_VERSION_LENGTH] = 0x45;
1121
      ptrSend[IP_TIME_TO_LIVE] = 0x80;
1122
 
1123
      //Setup IP addresses
1124
      memcpy(ptrSend+IP_SOURCE, ipAddressPlasma, 4);
1125
      ptrSend[IP_DEST] = (uint8)(IPAddress >> 24);
1126
      ptrSend[IP_DEST+1] = (uint8)(IPAddress >> 16);
1127
      ptrSend[IP_DEST+2] = (uint8)(IPAddress >> 8);
1128
      ptrSend[IP_DEST+3] = (uint8)IPAddress;
1129
      ptrRcv[IP_SOURCE] = (uint8)(IPAddress >> 24);
1130
      ptrRcv[IP_SOURCE+1] = (uint8)(IPAddress >> 16);
1131
      ptrRcv[IP_SOURCE+2] = (uint8)(IPAddress >> 8);
1132
      ptrRcv[IP_SOURCE+3] = (uint8)IPAddress;
1133
      memcpy(ptrRcv+IP_DEST, ipAddressPlasma, 4);
1134
 
1135
      //Setup ports
1136
      ptrSend[TCP_SOURCE_PORT] = (uint8)(portSource >> 8);
1137
      ptrSend[TCP_SOURCE_PORT+1] = (uint8)portSource;
1138
      ptrSend[TCP_DEST_PORT] = (uint8)(Port >> 8);
1139
      ptrSend[TCP_DEST_PORT+1] = (uint8)Port;
1140
      ptrRcv[TCP_SOURCE_PORT] = (uint8)(Port >> 8);
1141
      ptrRcv[TCP_SOURCE_PORT+1] = (uint8)Port;
1142
      ptrRcv[TCP_DEST_PORT] = (uint8)(portSource >> 8);
1143
      ptrRcv[TCP_DEST_PORT+1] = (uint8)portSource;
1144 155 rhoads
      ++portSource;
1145
   }
1146
 
1147
   if(Mode == IP_MODE_TCP)
1148
   {
1149 160 rhoads
      if(IPAddress)
1150
         socket->state = IP_TCP;
1151
      else
1152
         socket->state = IP_LISTEN;
1153
      ptrSend[IP_PROTOCOL] = 0x06;  //TCP
1154
      ptrRcv[IP_PROTOCOL] = 0x06;
1155 155 rhoads
   }
1156
   else if(Mode == IP_MODE_UDP)
1157
   {
1158
      socket->state = IP_UDP;
1159 160 rhoads
      ptrSend[IP_PROTOCOL] = 0x11;  //UDP
1160
      ptrRcv[IP_PROTOCOL] = 0x11;
1161 155 rhoads
   }
1162
 
1163 160 rhoads
   //Add socket to linked list
1164 157 rhoads
   OS_MutexPend(IPMutex);
1165 155 rhoads
   socket->next = SocketHead;
1166 160 rhoads
   socket->prev = NULL;
1167
   if(SocketHead)
1168
      SocketHead->prev = socket;
1169 155 rhoads
   SocketHead = socket;
1170 157 rhoads
   OS_MutexPost(IPMutex);
1171 160 rhoads
 
1172
   if(Mode == IP_MODE_TCP && IPAddress)
1173
   {
1174
      //Send TCP SYN
1175
      frame = IPFrameGet(0);
1176
      if(frame)
1177
      {
1178
         frame->packet[TCP_FLAGS] = TCP_FLAGS_SYN;
1179
         frame->packet[TCP_DATA] = 2;    //maximum segment size = 536
1180
         frame->packet[TCP_DATA+1] = 4;
1181
         frame->packet[TCP_DATA+2] = 2;
1182
         frame->packet[TCP_DATA+3] = 24;
1183
         TCPSendPacket(socket, frame, TCP_DATA+4);
1184
         ++socket->seq;
1185
      }
1186
   }
1187 155 rhoads
   return socket;
1188
}
1189
 
1190
 
1191
void IPWriteFlush(IPSocket *Socket)
1192
{
1193
   uint8 *packetOut;
1194
   if(Socket->frameSend && Socket->state != IP_UDP)
1195
   {
1196
      packetOut = Socket->frameSend->packet;
1197
      packetOut[TCP_FLAGS] = TCP_FLAGS_ACK;
1198
      TCPSendPacket(Socket, Socket->frameSend, TCP_DATA + Socket->sendOffset);
1199
      Socket->seq += Socket->sendOffset;
1200
      Socket->frameSend = NULL;
1201
      Socket->sendOffset = 0;
1202
   }
1203
}
1204
 
1205
 
1206
uint32 IPWrite(IPSocket *Socket, const uint8 *Buf, uint32 Length)
1207
{
1208
   IPFrame *frameOut;
1209
   uint8 *packetOut;
1210
   uint32 bytes, count=0;
1211
   int offset;
1212
 
1213
   //printf("IPWrite(0x%x, %d)", Socket, Length);
1214
   while(Length)
1215
   {
1216
      if(Socket->frameSend == NULL)
1217
      {
1218 160 rhoads
         Socket->frameSend = IPFrameGet(FRAME_COUNT_SEND);
1219 155 rhoads
         Socket->sendOffset = 0;
1220
      }
1221
      frameOut = Socket->frameSend;
1222
      offset = Socket->sendOffset;
1223
      if(frameOut == NULL)
1224
         break;
1225
      packetOut = frameOut->packet;
1226
      bytes = 512 - offset;
1227
      if(bytes > Length)
1228
         bytes = Length;
1229
      Socket->sendOffset += bytes;
1230
 
1231
      if(Socket->state != IP_UDP)
1232
      {
1233
         memcpy(packetOut+TCP_DATA+offset, Buf, bytes);
1234
         if(Socket->sendOffset >= 512)
1235
            IPWriteFlush(Socket);
1236
      }
1237
      else  //UDP
1238
      {
1239
         memcpy(packetOut+UDP_DATA+offset, Buf, bytes);
1240
         memcpy(packetOut, Socket->headerSend, UDP_LENGTH);
1241
         IPSendPacket(Socket, Socket->frameSend, UDP_DATA + Socket->sendOffset);
1242
         Socket->frameSend = NULL;
1243
      }
1244
      count += bytes;
1245
      Buf += bytes;
1246
      Length -= bytes;
1247
   }
1248
   return count;
1249
}
1250
 
1251
 
1252 157 rhoads
void IPWritePend(IPSocket *Socket, uint8 *Buf, uint32 Length)
1253
{
1254
   int bytes;
1255
   OS_Thread_t *self;
1256
 
1257
   self = OS_ThreadSelf();
1258
   assert(self != IPThread);
1259
   while(Length)
1260
   {
1261
      bytes = IPWrite(Socket, Buf, Length);
1262
      Buf += bytes;
1263
      Length -= bytes;
1264
      if(Length)
1265
         OS_ThreadSleep(1);
1266
   }
1267
}
1268
 
1269
 
1270 155 rhoads
uint32 IPRead(IPSocket *Socket, uint8 *Buf, uint32 Length)
1271
{
1272
   IPFrame *frame, *frame2;
1273
   int count=0, bytes, offset;
1274
 
1275
   if(Socket->state == IP_TCP)
1276
      offset = TCP_DATA;
1277
   else
1278
      offset = UDP_DATA;
1279
 
1280 157 rhoads
   OS_MutexPend(IPMutex);
1281 155 rhoads
   for(frame = Socket->frameReadTail; Length && frame; )
1282
   {
1283
      bytes = frame->length - offset - Socket->readOffset;
1284
      if(bytes > (int)Length)
1285
         bytes = Length;
1286
      memcpy(Buf, frame->packet + offset + Socket->readOffset, bytes);
1287
      Buf += bytes;
1288
      Socket->readOffset += bytes;
1289
      Length -= bytes;
1290
      count += bytes;
1291
 
1292
      //Check if done with packet
1293
      frame2 = frame;
1294
      frame = frame->prev;
1295
      if(Socket->readOffset == frame2->length - offset)
1296
      {
1297
         //Remove packet from socket linked list
1298
         Socket->readOffset = 0;
1299
         FrameRemove(&Socket->frameReadHead, &Socket->frameReadTail, frame2);
1300
         FrameFree(frame2);
1301
      }
1302
   }
1303 157 rhoads
   OS_MutexPost(IPMutex);
1304 155 rhoads
   return count;
1305
}
1306
 
1307
 
1308
static void IPClose2(IPSocket *Socket)
1309
{
1310
   IPFrame *frame, *framePrev;
1311
 
1312 157 rhoads
   OS_MutexPend(IPMutex);
1313 155 rhoads
 
1314 157 rhoads
   //Mark packets as don't retransmit
1315
   for(frame = FrameSendHead; frame; frame = frame->next)
1316 155 rhoads
   {
1317 157 rhoads
      if(frame->socket == Socket)
1318
         frame->socket = NULL;
1319 155 rhoads
   }
1320
 
1321
   //Remove packets from retransmision list
1322
   for(frame = FrameResendHead; frame; )
1323
   {
1324
      framePrev = frame;
1325
      frame = frame->next;
1326
      if(framePrev->socket == Socket)
1327
      {
1328
         FrameRemove(&FrameResendHead, &FrameResendTail, framePrev);
1329
         FrameFree(framePrev);
1330
      }
1331
   }
1332
 
1333
   //Remove packets from socket read linked list
1334
   for(frame = Socket->frameReadHead; frame; )
1335
   {
1336
      framePrev = frame;
1337
      frame = frame->next;
1338
      FrameRemove(&Socket->frameReadHead, &Socket->frameReadTail, framePrev);
1339
      FrameFree(framePrev);
1340
   }
1341
 
1342
   //Remove socket
1343
   if(Socket->prev == NULL)
1344
      SocketHead = Socket->next;
1345
   else
1346
      Socket->prev->next = Socket->next;
1347
   if(Socket->next)
1348
      Socket->next->prev = Socket->prev;
1349
   free(Socket);
1350 157 rhoads
   OS_MutexPost(IPMutex);
1351 155 rhoads
}
1352
 
1353
 
1354
void IPClose(IPSocket *Socket)
1355
{
1356
   IPFrame *frameOut;
1357
 
1358
   IPWriteFlush(Socket);
1359 157 rhoads
   if(Socket->state == IP_UDP)
1360
   {
1361
      IPClose2(Socket);
1362
      return;
1363
   }
1364
   frameOut = IPFrameGet(0);
1365 155 rhoads
   if(frameOut == 0)
1366
      return;
1367
   frameOut->packet[TCP_FLAGS] = TCP_FLAGS_FIN | TCP_FLAGS_ACK;
1368
   TCPSendPacket(Socket, frameOut, TCP_DATA);
1369
   ++Socket->seq;
1370
   if(Socket->state == IP_FIN_CLIENT)
1371
      IPClose2(Socket);
1372 157 rhoads
   else
1373
      Socket->state = IP_FIN_SERVER;
1374 155 rhoads
}
1375
 
1376
 
1377
//static void ShowIP(IPSocket *socket, uint32 ipAddress)
1378
//{
1379
//   (void)socket;
1380
//   printf("IP=0x%x\n", ipAddress);
1381
//}
1382
 
1383
 
1384
void IPTick(void)
1385
{
1386
   IPFrame *frame, *frame2;
1387
   IPSocket *socket, *socket2;
1388
 
1389
   if(IPVerbose && (Seconds % 60) == 0)
1390 157 rhoads
   {
1391
      if(FrameFreeCount == FRAME_COUNT)
1392
         printf("T");
1393
      else
1394
         printf("T(%d)", FrameFreeCount);
1395
   }
1396 155 rhoads
   ++Seconds;
1397
   if(--DhcpRetrySeconds <= 0)
1398
      IPDhcp(NULL, 400, 1);   //DHCP request
1399
   //if(Seconds == 10)
1400
   //   IPResolve("plasmacpu.no-ip.org", ShowIP);
1401
 
1402 157 rhoads
   OS_MutexPend(IPMutex);
1403 155 rhoads
 
1404
   //Retransmit timeout packets
1405
   for(frame = FrameResendHead; frame; )
1406
   {
1407
      frame2 = frame;
1408
      frame = frame->next;
1409
      if(--frame2->timeout == 0)
1410
      {
1411
         if(IPVerbose)
1412
            printf("r");
1413
         FrameRemove(&FrameResendHead, &FrameResendTail, frame2);
1414
         IPSendFrame(frame2);
1415
      }
1416
   }
1417
 
1418
   //Close timed out sockets
1419
   for(socket = SocketHead; socket; )
1420
   {
1421
      socket2 = socket;
1422
      socket = socket->next;
1423
      if(socket2->timeout && --socket2->timeout == 0)
1424
      {
1425
         socket2->timeout = 10;
1426 157 rhoads
         if(IPVerbose)
1427
            printf("t(%d)", socket2->state);
1428
         if(socket2->state == IP_TCP)
1429
            IPClose(socket2);
1430
         else if(socket2->state == IP_FIN_CLIENT)
1431
            IPClose(socket2);
1432
         else
1433 155 rhoads
            IPClose2(socket2);
1434
      }
1435
   }
1436 157 rhoads
   OS_MutexPost(IPMutex);
1437 155 rhoads
}
1438
 
1439
 
1440
static void DnsCallback(IPSocket *socket)
1441
{
1442
   uint8 buf[200], *ptr;
1443
   uint32 ipAddress;
1444
   int i, length;
1445
 
1446
   memset(buf, 0, sizeof(buf));
1447
   IPRead(socket, buf, sizeof(buf));
1448
   if(buf[DNS_NUM_ANSWERS_RR+1])
1449
   {
1450
      ptr = buf + DNS_QUESTIONS;
1451
      while(*ptr)
1452
         ++ptr;
1453
      ++ptr;
1454
      ptr += 4;
1455
      for(i = 0; (int)(ptr - buf) < sizeof(buf) && i < buf[DNS_NUM_ANSWERS_RR+1]; ++i)
1456
      {
1457
         if(ptr[2] == 0 && ptr[3] == 1 && ptr[4] == 0 && ptr[5] == 1)
1458
         {
1459
            ipAddress = (ptr[12] << 24) | (ptr[13] << 16) | (ptr[14] << 8) | ptr[15];
1460
            printf("ipAddress = %d.%d.%d.%d\n", ptr[12], ptr[13], ptr[14], ptr[16]);
1461
            socket->userData = ipAddress;
1462
            if(socket->userFunc)
1463
            {
1464
               socket->userFunc(socket, ipAddress);
1465
            }
1466
            break;
1467
         }
1468
         length = (ptr[10] << 8) | ptr[11];
1469
         ptr += 12 + length;
1470
      }
1471
   }
1472
   if(FrameSendFunc)
1473
      IPClose(socket);
1474
}
1475
 
1476
 
1477
uint32 IPResolve(char *Name, IPFuncPtr resolvedFunc)
1478
{
1479
   uint8 buf[200], *ptr;
1480
   int length, i;
1481
   IPSocket *socket;
1482
   uint32 ipAddress=0;
1483
 
1484
   socket = IPOpen(IP_MODE_UDP, ipAddressDns, DNS_PORT, DnsCallback);
1485
   memset(buf, 0, sizeof(buf));
1486
   buf[DNS_ID+1] = 1;
1487
   buf[DNS_FLAGS] = 1;
1488
   buf[DNS_NUM_QUESTIONS+1] = 1;
1489
 
1490
   //Setup name
1491
   ptr = buf + DNS_QUESTIONS;
1492
   strncpy((char*)ptr+1, Name, 100);
1493
   ptr[0] = 1;
1494
   while(ptr[0])
1495
   {
1496
      for(i = 0; i < 100; ++i)
1497
      {
1498
         if(ptr[i+1] == '.' || ptr[i+1] == 0)
1499
         {
1500
            ptr[0] = (uint8)i;
1501
            ptr += i+1;
1502
            break;
1503
         }
1504
      }
1505
   }
1506
   ++ptr;
1507
   ptr[1] = DNS_QUERY_TYPE_IP;
1508
   ptr[3] = DNS_QUERY_CLASS;
1509
   length = (int)(ptr - buf) + 4;
1510
   if(length < 60)
1511
      length = 60;
1512
 
1513
   socket->userFunc = (IPFuncPtr)resolvedFunc;
1514
   socket->userData = 0;
1515
   IPWrite(socket, buf, length);
1516
 
1517
   if(FrameSendFunc == NULL)
1518
   {
1519
      for(i = 0; i < 1000 && socket->userData == 0; ++i)
1520
         OS_ThreadSleep(1);
1521
      ipAddress = socket->userData;
1522
      IPClose(socket);
1523
   }
1524
   return ipAddress;
1525
}
1526
 

powered by: WebSVN 2.1.0

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