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

📄 tcpip.c

📁 Plasma IP Core 你可以利用这个组件在FPGA中设计MIPS结构的CPU
💻 C
📖 第 1 页 / 共 4 页
字号:
      //Wakeup sender thread      message[0] = 2;      OS_MQueueSend(IPMQueue, message);   }}static void IPSendPacket(IPSocket *socket, IPFrame *frame, int length){   int checksum, length2=length;   unsigned char pseudo[12], *packet=frame->packet;   frame->length = (uint16)length;   //Calculate checksums   if(packet[ETHERNET_FRAME_TYPE+1] == 0x00)  //IP   {      length2 = length - IP_VERSION_LENGTH;      packet[IP_LENGTH] = (uint8)(length2 >> 8);      packet[IP_LENGTH+1] = (uint8)length2;      memset(packet+IP_CHECKSUM, 0, 2);      checksum = IPChecksum(0xffff, packet+IP_VERSION_LENGTH, 20);      packet[IP_CHECKSUM] = (unsigned char)(checksum >> 8);      packet[IP_CHECKSUM+1] = (unsigned char)checksum;      if(packet[IP_PROTOCOL] == 0x01)         //PING      {         memset(packet+PING_CHECKSUM, 0, 2);         checksum = IPChecksum(0xffff, packet+PING_TYPE, length-PING_TYPE);         packet[PING_CHECKSUM] = (unsigned char)(checksum >> 8);         packet[PING_CHECKSUM+1] = (unsigned char)checksum;      }      else if(packet[IP_PROTOCOL] == 0x11)    //UDP      {         length2 = length - UDP_SOURCE_PORT;         packet[UDP_LENGTH] = (uint8)(length2 >> 8);         packet[UDP_LENGTH+1] = (uint8)length2;         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);         memset(packet+UDP_CHECKSUM, 0, 2);         length2 = (packet[UDP_LENGTH] << 8) + packet[UDP_LENGTH+1];         checksum = IPChecksum(checksum, packet+UDP_SOURCE_PORT, length2);         packet[UDP_CHECKSUM] = (unsigned char)(checksum >> 8);         packet[UDP_CHECKSUM+1] = (unsigned char)checksum;      }      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];         length2 = (packet[IP_LENGTH] << 8) + packet[IP_LENGTH+1];         length2 = length2 - 20;         pseudo[PSEUDO_LENGTH] = (unsigned char)(length2 >> 8);         pseudo[PSEUDO_LENGTH+1] = (unsigned char)length2;         checksum = IPChecksum(0xffff, pseudo, 12);         memset(packet+TCP_CHECKSUM, 0, 2);         checksum = IPChecksum(checksum, packet+TCP_SOURCE_PORT, length2);         packet[TCP_CHECKSUM] = (unsigned char)(checksum >> 8);         packet[TCP_CHECKSUM+1] = (unsigned char)checksum;      }   }   length2 = length - TCP_DATA;   if(socket && (packet[TCP_FLAGS] & (TCP_FLAGS_FIN | TCP_FLAGS_SYN)))      length2 = 1;   frame->socket = socket;   frame->timeout = 0;   frame->retryCnt = 0;   if(socket)      frame->seqEnd = socket->seq + length2;   IPSendFrame(frame);}static void TCPSendPacket(IPSocket *socket, IPFrame *frame, int length){   uint8 *packet = frame->packet;   int flags, count;   flags = packet[TCP_FLAGS];   memcpy(packet, socket->headerSend, TCP_SEQ);   packet[TCP_FLAGS] = (uint8)flags | (socket->headerSend[TCP_FLAGS] & TCP_FLAGS_PSH);   if(flags & TCP_FLAGS_SYN)      packet[TCP_HEADER_LENGTH] = 0x60;  //set maximum segment size   else      packet[TCP_HEADER_LENGTH] = 0x50;   packet[TCP_SEQ]   = (uint8)(socket->seq >> 24);   packet[TCP_SEQ+1] = (uint8)(socket->seq >> 16);   packet[TCP_SEQ+2] = (uint8)(socket->seq >> 8);   packet[TCP_SEQ+3] = (uint8)socket->seq;   packet[TCP_ACK]   = (uint8)(socket->ack >> 24);   packet[TCP_ACK+1] = (uint8)(socket->ack >> 16);   packet[TCP_ACK+2] = (uint8)(socket->ack >> 8);   packet[TCP_ACK+3] = (uint8)socket->ack;   count = FrameFreeCount - FRAME_COUNT_WINDOW;   if(count < 1)      count = 1;   if(count > 4)      count = 4;   count *= 512;   packet[TCP_WINDOW_SIZE] = (uint8)(count >> 8);   packet[TCP_WINDOW_SIZE+1] = (uint8)count;   packet[TCP_URGENT_POINTER] = 0;   packet[TCP_URGENT_POINTER+1] = 0;   IPSendPacket(socket, frame, length);}static void EthernetCreateResponse(unsigned char *packetOut,                                   const unsigned char *packet,                                   int length){   //Swap destination and source fields   memcpy(packetOut, packet, length);   memcpy(packetOut+ETHERNET_DEST, packet+ETHERNET_SOURCE, 6);   memcpy(packetOut+ETHERNET_SOURCE, packet+ETHERNET_DEST, 6);   if(packet[ETHERNET_FRAME_TYPE+1] == 0x00)  //IP   {      memcpy(packetOut+IP_SOURCE, packet+IP_DEST, 4);      memcpy(packetOut+IP_DEST, packet+IP_SOURCE, 4);      if(packet[IP_PROTOCOL] == 0x06 || packet[IP_PROTOCOL] == 0x11)   //TCP/UDP      {         memcpy(packetOut+TCP_SOURCE_PORT, packet+TCP_DEST_PORT, 2);         memcpy(packetOut+TCP_DEST_PORT, packet+TCP_SOURCE_PORT, 2);      }   }}static void IPDhcp(const unsigned char *packet, int length, int state){   uint8 *packetOut, *ptr;   const uint8 *ptr2;   IPFrame *frame;   static int request=0;   if(state == 1)   {      //Create DHCP Discover      frame = IPFrameGet(0);      if(frame == NULL)         return;      packetOut = frame->packet;      memset(packetOut, 0, 512);      memcpy(packetOut, dhcpDiscover, sizeof(dhcpDiscover));      memcpy(packetOut+ETHERNET_SOURCE, ethernetAddressPlasma, 6);      memcpy(packetOut+DHCP_CLIENT_ETHERNET, ethernetAddressPlasma, 6);      memcpy(packetOut+DHCP_MAGIC_COOKIE, dhcpOptions, sizeof(dhcpOptions));      memcpy(packetOut+DHCP_MAGIC_COOKIE+10, ethernetAddressPlasma, 6);      IPSendPacket(NULL, frame, 400);      request = DHCP_DISCOVER;      DhcpRetrySeconds = RETRANSMIT_TIME;   }   else if(state == 2 && memcmp(packet+DHCP_CLIENT_ETHERNET, ethernetAddressPlasma, 6) == 0)   {      if(packet[DHCP_MAGIC_COOKIE+6] == DHCP_OFFER && request == DHCP_DISCOVER)      {         //Process DHCP Offer and send DHCP Request         frame = IPFrameGet(0);         if(frame == NULL)            return;         packetOut = frame->packet;         memset(packetOut, 0, 512);         memcpy(packetOut, dhcpDiscover, sizeof(dhcpDiscover));         memcpy(packetOut+ETHERNET_SOURCE, ethernetAddressPlasma, 6);         memcpy(packetOut+DHCP_CLIENT_ETHERNET, ethernetAddressPlasma, 6);         memcpy(packetOut+DHCP_MAGIC_COOKIE, dhcpOptions, sizeof(dhcpOptions));         memcpy(packetOut+DHCP_MAGIC_COOKIE+10, ethernetAddressPlasma, 6);         request = DHCP_REQUEST;         packetOut[DHCP_MAGIC_COOKIE+6] = DHCP_REQUEST;         ptr = packetOut+DHCP_MAGIC_COOKIE+sizeof(dhcpOptions)-1;         ptr[0] = DHCP_REQUEST_IP;         ptr[1] = 4;         memcpy(ptr+2, packet+DHCP_YOUR_IP, 4);         ptr[6] = DHCP_REQUEST_SERV_IP;         ptr[7] = 4;         memcpy(ptr+8, packet+DHCP_SERVER_IP, 4);         ptr[12] = DHCP_END_OPTION;         IPSendPacket(NULL, frame, 400);      }      else if(packet[DHCP_MAGIC_COOKIE+6] == DHCP_ACK && request == DHCP_REQUEST)      {         //Process DHCP Ack         request = 0;         DhcpRetrySeconds = 3600*4;         memcpy(ipAddressPlasma, packet+DHCP_YOUR_IP, 4);         printf("IP=%d.%d.%d.%d ", ipAddressPlasma[0], ipAddressPlasma[1],            ipAddressPlasma[2], ipAddressPlasma[3]);         memcpy(ipAddressGateway, packet+DHCP_GATEWAY_IP, 4);         if(ipAddressGateway[0] == 0 && ipAddressGateway[1] == 0 &&            ipAddressGateway[2] == 0 && ipAddressGateway[3] == 0)            memcpy(ipAddressGateway, packet+DHCP_SERVER_IP, 4);         printf("GW=%d.%d.%d.%d ", ipAddressGateway[0], ipAddressGateway[1],            ipAddressGateway[2], ipAddressGateway[3]);         memcpy(ethernetAddressGateway, packet+ETHERNET_SOURCE, 6);         ptr2 = packet+DHCP_MAGIC_COOKIE+4;         while(ptr2[0] != DHCP_END_OPTION && (int)(ptr2 - packet) < length)         {            if(ptr2[0] == DHCP_PARAM_DNS)            {               ipAddressDns = (ptr2[2] << 24) | (ptr2[3] << 16) | (ptr2[4] << 8) | ptr2[5];               printf("DNS=%d.%d.%d.%d ", ptr2[2], ptr2[3], ptr2[4], ptr2[5]);            }            ptr2 += ptr2[1] + 2;         }         //Check if DHCP reply came from gateway         if(memcmp(packet+IP_SOURCE, ipAddressGateway, 4))         {            //Send ARP to gateway            frame = IPFrameGet(0);            if(frame == NULL)               return;            packetOut = frame->packet;            memset(packetOut, 0, 512);            memset(packetOut+ETHERNET_DEST, 0xff, 6);            memcpy(packetOut+ETHERNET_SOURCE, ethernetAddressPlasma, 6);            packetOut[ETHERNET_FRAME_TYPE] = 0x08;            packetOut[ETHERNET_FRAME_TYPE+1] = 0x06;            packetOut[ARP_HARD_TYPE+1] = 0x01;            packetOut[ARP_PROT_TYPE] = 0x08;            packetOut[ARP_HARD_SIZE] = 0x06;            packetOut[ARP_PROT_SIZE] = 0x04;            packetOut[ARP_OP+1] = 1;            memcpy(packetOut+ARP_ETHERNET_SENDER, ethernetAddressPlasma, 6);            memcpy(packetOut+ARP_IP_SENDER, ipAddressPlasma, 4);            memcpy(packetOut+ARP_IP_TARGET, ipAddressGateway, 4);            IPSendPacket(NULL, frame, 60);         }      }   }}uint32 IPAddressSelf(void){   return (ipAddressPlasma[0] << 24) | (ipAddressPlasma[1] << 16) |          (ipAddressPlasma[2] << 8) | ipAddressPlasma[3];}static int IPProcessTCPPacket(IPFrame *frameIn){   uint32 seq, ack;   int length, ip_length, bytes;   IPSocket *socket, *socketNew;   IPFrame *frameOut, *frame2, *framePrev;   uint8 *packet, *packetOut;   packet = frameIn->packet;   length = frameIn->length;   ip_length = (packet[IP_LENGTH] << 8) | packet[IP_LENGTH+1];   seq = (packet[TCP_SEQ] << 24) | (packet[TCP_SEQ+1] << 16) |          (packet[TCP_SEQ+2] << 8) | packet[TCP_SEQ+3];   ack = (packet[TCP_ACK] << 24) | (packet[TCP_ACK+1] << 16) |          (packet[TCP_ACK+2] << 8) | packet[TCP_ACK+3];   //Check if start of connection   if((packet[TCP_FLAGS] & (TCP_FLAGS_SYN | TCP_FLAGS_ACK)) == TCP_FLAGS_SYN)   {      if(IPVerbose)         printf("S");      //Check if duplicate SYN      for(socket = SocketHead; socket; socket = socket->next)      {         if(socket->state != IP_LISTEN &&            packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&            memcmp(packet+IP_SOURCE, socket->headerRcv+IP_SOURCE, 8) == 0 &&            memcmp(packet+TCP_SOURCE_PORT, socket->headerRcv+TCP_SOURCE_PORT, 4) == 0)         {            if(IPVerbose)               printf("s");            return 0;         }      }      //Find an open port      for(socket = SocketHead; socket; socket = socket->next)      {         if(socket->state == IP_LISTEN &&            packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&            memcmp(packet+TCP_DEST_PORT, socket->headerRcv+TCP_DEST_PORT, 2) == 0)         {            //Create a new socket            frameOut = IPFrameGet(FRAME_COUNT_SYNC);            if(frameOut == NULL)               return 0;            socketNew = (IPSocket*)malloc(sizeof(IPSocket));            if(socketNew == NULL)               return 0;            memcpy(socketNew, socket, sizeof(IPSocket));            socketNew->state = IP_TCP;            socketNew->timeout = RETRANSMIT_TIME * 3;            socketNew->ack = seq;            socketNew->seq = socketNew->ack + 0x12345678;            socketNew->seqReceived = socketNew->seq;            //Send ACK            packetOut = frameOut->packet;            EthernetCreateResponse(packetOut, packet, length);            memcpy(socketNew->headerRcv, packet, TCP_SEQ);            memcpy(socketNew->headerSend, packetOut, TCP_SEQ);            packetOut[TCP_FLAGS] = TCP_FLAGS_SYN | TCP_FLAGS_ACK;            ++socketNew->ack;            packetOut[TCP_DATA] = 2;    //maximum segment size = 536            packetOut[TCP_DATA+1] = 4;            packetOut[TCP_DATA+2] = 2;            packetOut[TCP_DATA+3] = 24;            TCPSendPacket(socketNew, frameOut, TCP_DATA+4);            ++socketNew->seq;            //Add socket to linked list            OS_MutexPend(IPMutex);            socketNew->next = SocketHead;            socketNew->prev = NULL;            if(SocketHead)               SocketHead->prev = socketNew;            SocketHead = socketNew;            OS_MutexPost(IPMutex);            return 0;         }      }      return 0;   }   //Find an open socket   for(socket = SocketHead; socket; socket = socket->next)   {      if(packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&         memcmp(packet+IP_SOURCE, socket->headerRcv+IP_SOURCE, 8) == 0 &&         memcmp(packet+TCP_SOURCE_PORT, socket->headerRcv+TCP_SOURCE_PORT, 4) == 0)      {         break;      }   }   if(socket == NULL)      return 0;   //Check if FIN flag set   if(packet[TCP_FLAGS] & TCP_FLAGS_FIN)   {      socket->timeout = SOCKET_TIMEOUT;      if(IPVerbose)         printf("F");      frameOut = IPFrameGet(0);      if(frameOut == NULL)         return 0;      packetOut = frameOut->packet;      packetOut[TCP_FLAGS] = TCP_FLAGS_ACK;      ++socket->ack;      TCPSendPacket(socket, frameOut, TCP_DATA);      if(socket->state == IP_FIN_SERVER)         IPClose2(socket);      else      {         socket->state = IP_FIN_CLIENT;         if(socket->funcPtr)            socket->funcPtr(socket);      }   }   else if(packet[TCP_FLAGS] & TCP_FLAGS_RST)   {      if(socket->state == IP_FIN_SERVER)         IPClose2(socket);      else      {         socket->state = IP_FIN_CLIENT;         if(socket->funcPtr)            socket->funcPtr(socket);      }   }   else   {      //Check if packets can be removed from retransmition list      if(ack != socket->seqReceived)      {         OS_MutexPend(IPMutex);         for(frame2 = FrameResendHead; frame2; )         {            framePrev = frame2;            frame2 = frame2->next;            if(framePrev->socket == socket && (int)(ack - framePrev->seqEnd) >= 0)            {               //Remove packet from retransmition queue               if(socket->timeout)                  socket->timeout = SOCKET_TIMEOUT;               FrameRemove(&FrameResendHead, &FrameResendTail, framePrev);               FrameFree(framePrev);            }         }         OS_MutexPost(IPMutex);         socket->seqReceived = ack;

⌨️ 快捷键说明

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