📄 tcpip.c
字号:
} 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 + -