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

📄 tcpip.c

📁 Plasma IP Core 你可以利用这个组件在FPGA中设计MIPS结构的CPU
💻 C
📖 第 1 页 / 共 4 页
字号:
      }      bytes = ip_length - (TCP_DATA - IP_VERSION_LENGTH);      //Check if SYN/ACK      if((packet[TCP_FLAGS] & (TCP_FLAGS_SYN | TCP_FLAGS_ACK)) ==          (TCP_FLAGS_SYN | TCP_FLAGS_ACK))      {         //Ack SYN/ACK         socket->ack = seq + 1;         frameOut = IPFrameGet(FRAME_COUNT_SEND);         if(frameOut)         {            frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;            TCPSendPacket(socket, frameOut, TCP_DATA);         }         if(socket->funcPtr)            socket->funcPtr(socket);         return 0;      }      else if(packet[TCP_HEADER_LENGTH] != 0x50)      {         if(IPVerbose)            printf("length error\n");         return 0;      }      //Copy packet into socket      if(socket->ack == seq && bytes > 0)      {         //Insert packet into socket linked list         if(socket->timeout)            socket->timeout = SOCKET_TIMEOUT;         if(IPVerbose)            printf("D");         FrameInsert(&socket->frameReadHead, &socket->frameReadTail, frameIn);         socket->ack += bytes;         //Ack data         frameOut = IPFrameGet(FRAME_COUNT_SEND);         if(frameOut)         {            frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;            TCPSendPacket(socket, frameOut, TCP_DATA);         }         //Determine window         socket->seqWindow = (packet[TCP_WINDOW_SIZE] << 8) | packet[TCP_WINDOW_SIZE+1];         if(socket->seqWindow < 8)            socket->seqWindow = 8;         //Notify application         if(socket->funcPtr)            socket->funcPtr(socket);         //Using frame         return 1;           }      if(bytes)      {         //Ack with current offset since data missing         frameOut = IPFrameGet(FRAME_COUNT_SEND);         if(frameOut)         {            frameOut->packet[TCP_FLAGS] = TCP_FLAGS_ACK;            TCPSendPacket(socket, frameOut, TCP_DATA);         }      }      if(socket->funcPtr)         socket->funcPtr(socket);   }   return 0;}int IPProcessEthernetPacket(IPFrame *frameIn){   int ip_length, rc;   IPSocket *socket;   IPFrame *frameOut;   uint8 *packet, *packetOut;   packet = frameIn->packet;   if(packet[ETHERNET_FRAME_TYPE] != 0x08 || frameIn->length > PACKET_SIZE)      return 0;  //wrong ethernet type, packet not used   //ARP?   if(packet[ETHERNET_FRAME_TYPE+1] == 0x06)   {      //Check if ARP reply      if(memcmp(packet+ETHERNET_DEST, ethernetAddressPlasma, 6) == 0 &&         packet[ARP_OP+1] == 2 && memcmp(packet+ARP_IP_SENDER, ipAddressGateway, 4) == 0)      {         //Found MAC address for gateway         memcpy(ethernetAddressGateway, packet+ARP_ETHERNET_SENDER, 6);         return 0;      }      //Check if ARP request      if(memcmp(packet+ETHERNET_DEST, ethernetAddressNull, 6) ||         packet[ARP_OP] != 0 || packet[ARP_OP+1] != 1 ||           memcmp(packet+ARP_IP_TARGET, ipAddressPlasma, 4))         return 0;      //Create ARP response      frameOut = IPFrameGet(0);      if(frameOut == NULL)         return 0;      packetOut = frameOut->packet;      memcpy(packetOut, packet, frameIn->length);      memcpy(packetOut+ETHERNET_DEST, packet+ETHERNET_SOURCE, 6);      memcpy(packetOut+ETHERNET_SOURCE, ethernetAddressPlasma, 6);      packetOut[ARP_OP+1] = 2; //ARP reply      memcpy(packetOut+ARP_ETHERNET_SENDER, ethernetAddressPlasma, 6);      memcpy(packetOut+ARP_IP_SENDER, packet+ARP_IP_TARGET, 4);      memcpy(packetOut+ARP_ETHERNET_TARGET, packet+ARP_ETHERNET_SENDER, 6);      memcpy(packetOut+ARP_IP_TARGET, packet+ARP_IP_SENDER, 4);      IPSendPacket(NULL, frameOut, frameIn->length);      return 0;   }   //Check if proper type of packet   ip_length = (packet[IP_LENGTH] << 8) | packet[IP_LENGTH+1];   if(frameIn->length < UDP_DATA || ip_length > frameIn->length - IP_VERSION_LENGTH)      return 0;   if(packet[ETHERNET_FRAME_TYPE+1] != 0x00 ||      packet[IP_VERSION_LENGTH] != 0x45)      return 0;   //Check if DHCP reply   if(packet[IP_PROTOCOL] == 0x11 &&      packet[UDP_SOURCE_PORT] == 0 && packet[UDP_SOURCE_PORT+1] == 67 &&      packet[UDP_DEST_PORT] == 0 && packet[UDP_DEST_PORT+1] == 68)   {      IPDhcp(packet, frameIn->length, 2);            //DHCP reply      return 0;   }   //Check if correct destination address   if(memcmp(packet+ETHERNET_DEST, ethernetAddressPlasma, 6) ||      memcmp(packet+IP_DEST, ipAddressPlasma, 4))      return 0;   rc = EthernetVerifyChecksums(packet, frameIn->length);   //if(rc)   //{   //   printf("C ");   //   return;   //}   //PING request?   if(packet[IP_PROTOCOL] == 1)   {      if(packet[PING_TYPE] == 0)  //PING reply      {         for(socket = SocketHead; socket; socket = socket->next)         {            if(socket->state == IP_PING &&                memcmp(packet+IP_SOURCE, socket->headerSend+IP_DEST, 4) == 0)            {               socket->funcPtr(socket);               return 0;            }         }      }      if(packet[PING_TYPE] != 8)         return 0;      frameOut = IPFrameGet(FRAME_COUNT_SEND);      if(frameOut == NULL)         return 0;      packetOut = frameOut->packet;      EthernetCreateResponse(packetOut, packet, frameIn->length);      frameOut->packet[PING_TYPE] = 0;       //PING reply      IPSendPacket(NULL, frameOut, frameIn->length);      return 0;   }   //TCP packet?   if(packet[IP_PROTOCOL] == 0x06)   {      return IPProcessTCPPacket(frameIn);   }   //UDP packet?   if(packet[IP_PROTOCOL] == 0x11)   {      //Find 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+UDP_SOURCE_PORT, socket->headerRcv+UDP_SOURCE_PORT, 2) == 0)         {            break;         }      }      if(socket == NULL)      {         //Find listening socket         for(socket = SocketHead; socket; socket = socket->next)         {            if(packet[IP_PROTOCOL] == socket->headerRcv[IP_PROTOCOL] &&               memcmp(packet+UDP_DEST_PORT, socket->headerRcv+UDP_DEST_PORT, 2) == 0)            {               EthernetCreateResponse(socket->headerSend, packet, UDP_DATA);               break;            }         }      }      if(socket)      {         if(IPVerbose)            printf("U");         FrameInsert(&socket->frameReadHead, &socket->frameReadTail, frameIn);         socket->funcPtr(socket);         return 1;      }   }   return 0;}static void IPMainThread(void *arg){   uint32 message[4];   int rc;   IPFrame *frame, *frameOut=NULL;   uint32 ticks, ticksLast;   (void)arg;   ticksLast = OS_ThreadTime();   memset(message, 0, sizeof(message));   for(;;)   {      Led(0);      rc = OS_MQueueGet(IPMQueue, message, 10);      if(rc == 0)      {         frame = (IPFrame*)message[1];         if(message[0] == 0)       //frame received         {            Led(1);            frame->length = (uint16)message[2];            rc = IPProcessEthernetPacket(frame);            if(rc == 0)               FrameFree(frame);         }         else if(message[0] == 1)  //frame sent         {            Led(2);            assert(frame == frameOut);            IPFrameReschedule(frame);            frameOut = NULL;         }         else if(message[0] == 2)  //frame ready to send         {         }      }      if(frameOut == NULL)      {         OS_MutexPend(IPMutex);         frameOut = FrameSendTail;         if(frameOut)            FrameRemove(&FrameSendHead, &FrameSendTail, frameOut);         OS_MutexPost(IPMutex);         if(frameOut)         {            Led(4);            UartPacketSend(frameOut->packet, frameOut->length);         }      }      ticks = OS_ThreadTime();      if(ticks - ticksLast > 100)      {         IPTick();         ticksLast = ticks;      }   }}uint8 *MyPacketGet(void){   return (uint8*)IPFrameGet(FRAME_COUNT_RCV);}//Set FrameSendFunction only if single threadedvoid IPInit(IPFuncPtr frameSendFunction){   int i;   IPFrame *frame;   FrameSendFunc = frameSendFunction;   IPMutex = OS_MutexCreate("IPSem");   IPMQueue = OS_MQueueCreate("IPMQ", FRAME_COUNT*2, 32);   for(i = 0; i < FRAME_COUNT; ++i)   {      frame = (IPFrame*)malloc(sizeof(IPFrame));      memset(frame, 0, sizeof(IPFrame));      frame->next = FrameFreeHead;      frame->prev = NULL;      FrameFreeHead = frame;   }   UartPacketConfig(MyPacketGet, PACKET_SIZE, IPMQueue);   if(frameSendFunction == NULL)      IPThread = OS_ThreadCreate("TCP/IP", IPMainThread, NULL, 240, 6000);   IPDhcp(NULL, 360, 1);        //Send DHCP request}//To open a socket for listen set ipAddress to 0IPSocket *IPOpen(IPMode_e mode, uint32 ipAddress, uint32 port, IPFuncPtr funcPtr){   IPSocket *socket;   uint8 *ptrSend, *ptrRcv;   IPFrame *frame;   static int portSource=0x1007;   socket = (IPSocket*)malloc(sizeof(IPSocket));   if(socket == NULL)      return socket;   memset(socket, 0, sizeof(IPSocket));   socket->prev = NULL;   socket->state = IP_LISTEN;   socket->timeout = 0;   socket->frameReadHead = NULL;   socket->frameReadTail = NULL;   socket->readOffset = 0;   socket->funcPtr = funcPtr;   socket->userData = 0;   socket->userFunc = NULL;   socket->userPtr = NULL;   ptrSend = socket->headerSend;   ptrRcv = socket->headerRcv;   if(ipAddress == 0)   {      //Setup listing port      socket->headerRcv[TCP_DEST_PORT] = (uint8)(port >> 8);      socket->headerRcv[TCP_DEST_PORT+1] = (uint8)port;   }   else   {      //Setup sending packet      memset(ptrSend, 0, UDP_LENGTH);      memset(ptrRcv, 0, UDP_LENGTH);      //Setup Ethernet      if(ipAddress != IPAddressSelf())         memcpy(ptrSend+ETHERNET_DEST, ethernetAddressGateway, 6);      else         memcpy(ptrSend+ETHERNET_DEST, ethernetAddressPlasma, 6);      memcpy(ptrSend+ETHERNET_SOURCE, ethernetAddressPlasma, 6);      ptrSend[ETHERNET_FRAME_TYPE] = 0x08;      //Setup IP      ptrSend[IP_VERSION_LENGTH] = 0x45;      ptrSend[IP_TIME_TO_LIVE] = 0x80;      //Setup IP addresses      memcpy(ptrSend+IP_SOURCE, ipAddressPlasma, 4);      ptrSend[IP_DEST] = (uint8)(ipAddress >> 24);      ptrSend[IP_DEST+1] = (uint8)(ipAddress >> 16);      ptrSend[IP_DEST+2] = (uint8)(ipAddress >> 8);      ptrSend[IP_DEST+3] = (uint8)ipAddress;      ptrRcv[IP_SOURCE] = (uint8)(ipAddress >> 24);      ptrRcv[IP_SOURCE+1] = (uint8)(ipAddress >> 16);      ptrRcv[IP_SOURCE+2] = (uint8)(ipAddress >> 8);      ptrRcv[IP_SOURCE+3] = (uint8)ipAddress;      memcpy(ptrRcv+IP_DEST, ipAddressPlasma, 4);      //Setup ports      ptrSend[TCP_SOURCE_PORT] = (uint8)(portSource >> 8);      ptrSend[TCP_SOURCE_PORT+1] = (uint8)portSource;      ptrSend[TCP_DEST_PORT] = (uint8)(port >> 8);      ptrSend[TCP_DEST_PORT+1] = (uint8)port;      ptrRcv[TCP_SOURCE_PORT] = (uint8)(port >> 8);      ptrRcv[TCP_SOURCE_PORT+1] = (uint8)port;      ptrRcv[TCP_DEST_PORT] = (uint8)(portSource >> 8);      ptrRcv[TCP_DEST_PORT+1] = (uint8)portSource;      ++portSource;   }   if(mode == IP_MODE_TCP)   {      if(ipAddress)         socket->state = IP_TCP;      else         socket->state = IP_LISTEN;      ptrSend[IP_PROTOCOL] = 0x06;  //TCP      ptrRcv[IP_PROTOCOL] = 0x06;

⌨️ 快捷键说明

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