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

Subversion Repositories mlite

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

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

powered by: WebSVN 2.1.0

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