⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpip.c

📁 Plasma IP Core 你可以利用这个组件在FPGA中设计MIPS结构的CPU
💻 C
📖 第 1 页 / 共 4 页
字号:
/*-------------------------------------------------------------------- * TITLE: Plasma TCP/IP Protocol Stack * AUTHOR: Steve Rhoads (rhoadss@yahoo.com) * DATE CREATED: 4/22/06 * FILENAME: tcpip.c * PROJECT: Plasma CPU core * COPYRIGHT: Software placed into the public domain by the author. *    Software 'as is' without warranty.  Author liable for nothing. * DESCRIPTION: *    Plasma TCP/IP Protocol Stack * *    Possible call stack when receiving a packet: *       IPMainThread() *          IPProcessEthernetPacket() *             IPProcessTCPPacket() *                TCPSendPacket() *                   IPSendPacket() *                      IPChecksum() *                      IPSendFrame() *                         FrameInsert() *--------------------------------------------------------------------*/#ifdef WIN32#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#define _LIBC#endif#include "rtos.h"#include "tcpip.h"#ifdef WIN32#undef OS_CriticalBegin#undef OS_CriticalEnd#define OS_CriticalBegin() 0#define OS_CriticalEnd(A)#define OS_ThreadCreate(A,B,C,D,E) 0#define OS_ThreadSleep(A)#define OS_ThreadTime() 0#define OS_ThreadSelf() 0#define OS_MutexCreate(A) NULL#define OS_MutexPend(A)#define OS_MutexPost(A)#define OS_MQueueCreate(A,B,C) 0#define OS_MQueueSend(A,B) 0#define OS_MQueueGet(A,B,C) 0#define UartPacketConfig(A,B,C)#define UartPacketSend(A,B)#define UartPrintf printf#define UartPrintfCritical printf#define Led(A)#endif//ETHER FIELD                 OFFSET   LENGTH   VALUE#define ETHERNET_DEST         0        //6#define ETHERNET_SOURCE       6        //6#define ETHERNET_FRAME_TYPE   12       //2      IP=0x0800; ARP=0x0806//ARP   FIELD                 OFFSET   LENGTH   VALUE#define ARP_HARD_TYPE         14       //2      0x0001#define ARP_PROT_TYPE         16       //2      0x0800#define ARP_HARD_SIZE         18       //1      0x06#define ARP_PROT_SIZE         19       //1      0x04#define ARP_OP                20       //2      ARP=1;ARPreply=2#define ARP_ETHERNET_SENDER   22       //6#define ARP_IP_SENDER         28       //4#define ARP_ETHERNET_TARGET   32       //6#define ARP_IP_TARGET         38       //4#define ARP_PAD               42       //18     0//IP    FIELD                 OFFSET   LENGTH   VALUE#define IP_VERSION_LENGTH     14       //1      0x45#define IP_TYPE_OF_SERVICE    15       //1      0x00#define IP_LENGTH             16       //2#define IP_ID16               18       //2#define IP_FRAG_OFFSET        20       //2#define IP_TIME_TO_LIVE       22       //1      0x80#define IP_PROTOCOL           23       //1      TCP=0x06;PING=0x01;UDP=0x11#define IP_CHECKSUM           24       //2#define IP_SOURCE             26       //4#define IP_DEST               30       //4//PSEUDO FIELD                OFFSET   LENGTH   VALUE#define PSEUDO_IP_SOURCE      0        //4#define PSEUDO_IP_DEST        4        //4#define PSEUDO_ZERO           8        //1      0#define PSEUDO_IP_PROTOCOL    9        //1#define PSEUDO_LENGTH         10       //2//UDP   FIELD                 OFFSET   LENGTH   VALUE#define UDP_SOURCE_PORT       34       //2#define UDP_DEST_PORT         36       //2#define UDP_LENGTH            38       //2#define UDP_CHECKSUM          40       //2#define UDP_DATA              42//DHCP  FIELD                 OFFSET   LENGTH   VALUE#define DHCP_OPCODE           42       //1      REQUEST=1;REPLY=2#define DHCP_HW_TYPE          43       //1      1#define DHCP_HW_LEN           44       //1      6#define DHCP_HOP_COUNT        45       //1      0#define DHCP_TRANS_ID         46       //4#define DHCP_NUM_SEC          50       //2      0#define DHCP_UNUSED           52       //2#define DHCP_CLIENT_IP        54       //4#define DHCP_YOUR_IP          58       //4#define DHCP_SERVER_IP        62       //4#define DHCP_GATEWAY_IP       66       //4#define DHCP_CLIENT_ETHERNET  70       //16#define DHCP_SERVER_NAME      86       //64#define DHCP_BOOT_FILENAME    150      //128#define DHCP_MAGIC_COOKIE     278      //4      0x63825363#define DHCP_OPTIONS          282      //N#define DHCP_MESSAGE_TYPE     53       //1 type#define DHCP_DISCOVER         1#define DHCP_OFFER            2#define DHCP_REQUEST          3#define DHCP_ACK              5#define DHCP_REQUEST_IP       50       //4 ip#define DHCP_REQUEST_SERV_IP  54       //4 ip#define DHCP_CLIENT_ID        61       //7 1 ethernet#define DHCP_HOST_NAME        12       //6 plasma#define DHCP_PARAMS           55       //4 1=subnet; 15=domain_name; 3=router; 6=dns#define DHCP_PARAM_SUBNET     1#define DHCP_PARAM_ROUTER     3#define DHCP_PARAM_DNS        6#define DHCP_END_OPTION       0xff//DHCP  FIELD                 OFFSET   LENGTH   VALUE#define DNS_ID                0        //2    #define DNS_FLAGS             2        //2      #define DNS_NUM_QUESTIONS     4        //2      1 #define DNS_NUM_ANSWERS_RR    6        //2      0/1#define DNS_NUM_AUTHORITY_RR  8        //2      0 #define DNS_NUM_ADDITIONAL_RR 10       //2      0#define DNS_QUESTIONS         12       //2   #define DNS_FLAGS_RESPONSE    0x8000#define DNS_FLAGS_RECURSIVE   0x0100#define DNS_FLAGS_ERROR       0x0003#define DNS_FLAGS_OK          0x0000#define DNS_QUERY_TYPE_IP     1#define DNS_QUERY_CLASS       1#define DNS_PORT              53//TCP   FIELD                 OFFSET   LENGTH   VALUE#define TCP_SOURCE_PORT       34       //2#define TCP_DEST_PORT         36       //2#define TCP_SEQ               38       //4#define TCP_ACK               42       //4#define TCP_HEADER_LENGTH     46       //1      0x50#define TCP_FLAGS             47       //1      SYNC=0x2;ACK=0x10;FIN=0x1#define TCP_WINDOW_SIZE       48       //2#define TCP_CHECKSUM          50       //2#define TCP_URGENT_POINTER    52       //2#define TCP_DATA              54       //length-N#define TCP_FLAGS_FIN         1#define TCP_FLAGS_SYN         2#define TCP_FLAGS_RST         4#define TCP_FLAGS_PSH         8#define TCP_FLAGS_ACK         16//PING  FIELD                 OFFSET   LENGTH   VALUE#define PING_TYPE             34       //1      SEND=8;REPLY=0#define PING_CODE             35       //1      0#define PING_CHECKSUM         36       //2#define PING_ID               38       //2#define PING_SEQUENCE         40       //2#define PING_DATA             44static void IPClose2(IPSocket *Socket);static uint8 ethernetAddressNull[] =    {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};static uint8 ethernetAddressGateway[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};#ifndef WIN32static uint8 ethernetAddressPlasma[] =  {0x00, 0x10, 0xdd, 0xce, 0x15, 0xd4};#elsestatic uint8 ethernetAddressPlasma[] =  {0x00, 0x10, 0xdd, 0xce, 0x15, 0xd5};#endifstatic uint8 ipAddressPlasma[] =  {0x9d, 0xfe, 0x28, 10};   //changed by DHCPstatic uint8 ipAddressGateway[] = {0xff, 0xff, 0xff, 0xff}; //changed by DHCPstatic uint32 ipAddressDns;                                 //changed by DHCPstatic OS_Mutex_t *IPMutex;static int FrameFreeCount=FRAME_COUNT;static IPFrame *FrameFreeHead;static IPFrame *FrameSendHead;static IPFrame *FrameSendTail;static IPFrame *FrameResendHead;static IPFrame *FrameResendTail;static IPSocket *SocketHead;static uint32 Seconds;static int DhcpRetrySeconds;static IPFuncPtr FrameSendFunc;static OS_MQueue_t *IPMQueue;static OS_Thread_t *IPThread;int IPVerbose=1;static const unsigned char dhcpDiscover[] = {   0xff, 0xff, 0xff, 0xff, 0xff, 0xff,             //dest   0x00, 0x10, 0xdd, 0xce, 0x15, 0xd4,             //src   0x08, 0x00,    0x45, 0x00, 0x01, 0x48, 0x2e, 0xf5, 0x00, 0x00, //ip   0x80, 0x11, 0x0a, 0xb1, 0x00, 0x00, 0x00, 0x00,    0xff, 0xff, 0xff, 0xff,   0x00, 0x44, 0x00, 0x43, 0x01, 0x34, 0x45, 0x66, //udp   0x01, 0x01, 0x06, 0x00, 0x69, 0x26, 0xb5, 0x52  //dhcp};static const unsigned char dhcpOptions[] = {   0x63, 0x82, 0x53, 0x63,      //cookie   0x35, 0x01, 0x01,            //DHCP Discover   0x3d, 0x07, 0x01, 0x00, 0x10, 0xdd, 0xce, 0x15, 0xd4, //Client identifier#ifndef WIN32   0x0c, 0x06, 'p', 'l', 'a', 's', 'm', 'a',             //Host name#else   0x0c, 0x06, 'p', 'l', 'a', 's', 'm', 'b',             //Host name#endif   0x37, 0x03, DHCP_PARAM_SUBNET, DHCP_PARAM_ROUTER, DHCP_PARAM_DNS, //Parameters   DHCP_END_OPTION};//Get a free frame; can be called from an ISRIPFrame *IPFrameGet(int freeCount){   IPFrame *frame=NULL;   uint32 state;   state = OS_CriticalBegin();   if(FrameFreeCount > freeCount)   {      --FrameFreeCount;      frame = FrameFreeHead;      if(FrameFreeHead)         FrameFreeHead = FrameFreeHead->next;   }   OS_CriticalEnd(state);   if(frame)   {      assert(frame->state == 0);      frame->state = 1;   }   return frame;}static void FrameFree(IPFrame *frame){   uint32 state;   assert(frame->state == 1);   frame->state = 0;   state = OS_CriticalBegin();   frame->next = FrameFreeHead;   FrameFreeHead = frame;   ++FrameFreeCount;   OS_CriticalEnd(state);}static void FrameInsert(IPFrame **head, IPFrame **tail, IPFrame *frame){   assert(frame->state == 1);   frame->state = 2;   OS_MutexPend(IPMutex);   frame->prev = NULL;   frame->next = *head;   if(*head)      (*head)->prev = frame;   *head = frame;   if(*tail == NULL)      *tail = frame;   OS_MutexPost(IPMutex);}static void FrameRemove(IPFrame **head, IPFrame **tail, IPFrame *frame){   assert(frame->state == 2);   frame->state = 1;   if(frame->prev)      frame->prev->next = frame->next;   else      *head = frame->next;   if(frame->next)      frame->next->prev = frame->prev;   else      *tail = frame->prev;   frame->prev = NULL;   frame->next = NULL;}static int IPChecksum(int checksum, const unsigned char *data, int length){   int i;   checksum = ~checksum & 0xffff;   for(i = 0; i < length-1; i += 2)   {      checksum += (data[i] << 8) | data[i+1];   }   if(i < length)      checksum += data[i] << 8;   while(checksum >> 16)      checksum = (checksum & 0xffff) + (checksum >> 16);   checksum = ~checksum & 0xffff;   return checksum;}static int EthernetVerifyChecksums(const unsigned char *packet, int length){   int checksum, length2;   unsigned char pseudo[12];   //Calculate checksums   if(packet[ETHERNET_FRAME_TYPE+1] == 0x00)  //IP   {      checksum = IPChecksum(0xffff, packet+IP_VERSION_LENGTH, 20);      if(checksum)         return -1;      if(packet[IP_PROTOCOL] == 0x01)         //PING      {         checksum = IPChecksum(0xffff, packet+PING_TYPE, length-PING_TYPE);      }      else if(packet[IP_PROTOCOL] == 0x11)    //UDP      {         if(packet[UDP_CHECKSUM] == 0 && packet[UDP_CHECKSUM+1] == 0)            return 0;         memcpy(pseudo+PSEUDO_IP_SOURCE, packet+IP_SOURCE, 4);         memcpy(pseudo+PSEUDO_IP_DEST, packet+IP_DEST, 4);         pseudo[PSEUDO_ZERO] = 0;         pseudo[PSEUDO_IP_PROTOCOL] = packet[IP_PROTOCOL];         memcpy(pseudo+PSEUDO_LENGTH, packet+UDP_LENGTH, 2);         checksum = IPChecksum(0xffff, pseudo, 12);         length2 = (packet[UDP_LENGTH] << 8) + packet[UDP_LENGTH+1];         checksum = IPChecksum(checksum, packet+UDP_SOURCE_PORT, length);      }      else if(packet[IP_PROTOCOL] == 0x06)    //TCP      {         memcpy(pseudo+PSEUDO_IP_SOURCE, packet+IP_SOURCE, 4);         memcpy(pseudo+PSEUDO_IP_DEST, packet+IP_DEST, 4);         pseudo[PSEUDO_ZERO] = 0;         pseudo[PSEUDO_IP_PROTOCOL] = packet[IP_PROTOCOL];         length = (packet[IP_LENGTH] << 8) + packet[IP_LENGTH+1];         length2 = length - 20;         pseudo[PSEUDO_LENGTH] = (unsigned char)(length2 >> 8);         pseudo[PSEUDO_LENGTH+1] = (unsigned char)length2;         checksum = IPChecksum(0xffff, pseudo, 12);         checksum = IPChecksum(checksum, packet+TCP_SOURCE_PORT, length2);      }      if(checksum)         return -1;   }   return 0;}static void IPFrameReschedule(IPFrame *frame){   int length;   length = frame->length - TCP_DATA;   if(frame->packet[TCP_FLAGS] & (TCP_FLAGS_FIN | TCP_FLAGS_SYN))      ++length;   if(frame->socket == NULL || frame->socket->state == IP_UDP || length == 0 ||      frame->socket->state == IP_PING || ++frame->retryCnt > 4)   {      FrameFree(frame);     //can't be ACK'ed   }   else   {      //Put on resend list until TCP ACK'ed      frame->timeout = RETRANSMIT_TIME;      FrameInsert(&FrameResendHead, &FrameResendTail, frame);   }}static void IPSendFrame(IPFrame *frame){   uint32 message[4];   if(FrameSendFunc)   {      //Single threaded      FrameSendFunc(frame->packet, frame->length);      IPFrameReschedule(frame);   }   else   {      //Add Packet to send queue      FrameInsert(&FrameSendHead, &FrameSendTail, frame);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -