A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.
Dependents: oldheating gps motorhome heating
tcphdr.c
00001 #include <stdint.h> 00002 #include <stdbool.h> 00003 00004 #include "log.h" 00005 #include "net.h" 00006 #include "restart.h" 00007 00008 static char* hdrPtrSrcPort (char* pPacket) { return pPacket + 0; } //2 00009 static char* hdrPtrDstPort (char* pPacket) { return pPacket + 2; } //2 00010 static char* hdrPtrSeqnum (char* pPacket) { return pPacket + 4; } //4 00011 static char* hdrPtrAcknum (char* pPacket) { return pPacket + 8; } //4 00012 static char* hdrPtrDataOffset(char* pPacket) { return pPacket + 12; } //1 00013 static char* hdrPtrFlags (char* pPacket) { return pPacket + 13; } //1 00014 static char* hdrPtrWindow (char* pPacket) { return pPacket + 14; } //2 00015 static char* hdrPtrChecksum (char* pPacket) { return pPacket + 16; } //2 00016 static char* hdrPtrUrgent (char* pPacket) { return pPacket + 18; } //2 00017 static const int HEADER_LENGTH = 20; 00018 00019 void TcpHdrSetChecksum (char* pPacket, uint16_t value) { NetDirect16(hdrPtrChecksum (pPacket), &value); } //The checksum is calculated inverted so don't re-invert here 00020 00021 //Header variables 00022 uint16_t TcpHdrSrcPort; 00023 uint16_t TcpHdrDstPort; 00024 uint32_t TcpHdrSeqNum; 00025 uint32_t TcpHdrAckNum; 00026 bool TcpHdrURG; //indicates that the Urgent pointer field is significant 00027 bool TcpHdrACK; //indicates that the Acknowledgment field is significant. All packets after the initial SYN packet sent by the client should have this flag set. 00028 bool TcpHdrPSH; //Push function. Asks to push the buffered data to the receiving application. 00029 bool TcpHdrRST; //Reset the connection 00030 bool TcpHdrSYN; //Synchronize sequence numbers. Only the first packet sent from each end should have this flag set. Some other flags and fields change meaning based on this flag, and some are only valid for when it is set, and others when it is clear. 00031 bool TcpHdrFIN; //No more data from sender 00032 uint16_t TcpHdrWindow; 00033 uint16_t TcpHdrChecksum; 00034 uint16_t TcpHdrUrgent; 00035 00036 //Side effects 00037 static int headerSize; 00038 int TcpHdrSizeGet() { return headerSize; } 00039 00040 static uint16_t mss = 0; 00041 void TcpHdrMssSet(uint16_t value) 00042 { 00043 mss = value; 00044 headerSize = HEADER_LENGTH; 00045 if (mss) headerSize += 4; 00046 } 00047 uint16_t TcpHdrMssGet() { return mss; } 00048 00049 static void logFlags() 00050 { 00051 if (TcpHdrURG) Log(" URG"); 00052 if (TcpHdrACK) Log(" ACK"); 00053 if (TcpHdrPSH) Log(" PSH"); 00054 if (TcpHdrRST) Log(" RST"); 00055 if (TcpHdrSYN) Log(" SYN"); 00056 if (TcpHdrFIN) Log(" FIN"); 00057 } 00058 void TcpHdrLog(uint16_t calculatedChecksum) 00059 { 00060 if (NetTraceVerbose) 00061 { 00062 Log("TCP header\r\n"); 00063 Log(" Source port "); LogF("%hu", TcpHdrSrcPort ); Log("\r\n"); 00064 Log(" Destination port "); LogF("%hu", TcpHdrDstPort ); Log("\r\n"); 00065 Log(" Seq number "); LogF("%u", TcpHdrSeqNum ); Log("\r\n"); 00066 Log(" Ack number "); LogF("%u", TcpHdrAckNum ); Log("\r\n"); 00067 Log(" Header size "); LogF("%u", headerSize ); Log("\r\n"); 00068 Log(" Flags " ); logFlags( ); Log("\r\n"); 00069 Log(" Window "); LogF("%hu", TcpHdrWindow ); Log("\r\n"); 00070 Log(" Checksum (hex) "); LogF("%04hX", TcpHdrChecksum ); Log("\r\n"); 00071 Log(" Calculated (hex) "); LogF("%04hX", calculatedChecksum ); Log("\r\n"); 00072 Log(" Urgent pointer "); LogF("%hu", TcpHdrUrgent ); Log("\r\n"); 00073 00074 } 00075 else 00076 { 00077 LogF("TCP header %hu >>> %hu", TcpHdrSrcPort, TcpHdrDstPort); 00078 logFlags(); 00079 Log("\r\n"); 00080 } 00081 } 00082 void TcpHdrReadFromPacket(char* pPacket) 00083 { 00084 int lastRestartPoint = RestartPoint; 00085 RestartPoint = FAULT_POINT_TcpHdrReadFromPacket; 00086 00087 NetInvert16(&TcpHdrSrcPort, hdrPtrSrcPort (pPacket)); 00088 NetInvert16(&TcpHdrDstPort, hdrPtrDstPort (pPacket)); 00089 NetInvert32(&TcpHdrSeqNum, hdrPtrSeqnum (pPacket)); 00090 NetInvert32(&TcpHdrAckNum, hdrPtrAcknum (pPacket)); 00091 headerSize = (*hdrPtrDataOffset(pPacket) >> 2) & 0xFC; //Same as right shifting by 4 bits and multiplying by 4 00092 uint8_t flags = *hdrPtrFlags (pPacket); 00093 TcpHdrURG = flags & 0x20; //indicates that the Urgent pointer field is significant 00094 TcpHdrACK = flags & 0x10; //indicates that the Acknowledgment field is significant. All packets after the initial SYN packet sent by the client should have this flag set. 00095 TcpHdrPSH = flags & 0x08; //Push function. Asks to push the buffered data to the receiving application. 00096 TcpHdrRST = flags & 0x04; //Reset the connection 00097 TcpHdrSYN = flags & 0x02; //Synchronize sequence numbers. Only the first packet sent from each end should have this flag set. Some other flags and fields change meaning based on this flag, and some are only valid for when it is set, and others when it is clear. 00098 TcpHdrFIN = flags & 0x01; //No more data from sender 00099 NetInvert16(&TcpHdrWindow, hdrPtrWindow (pPacket)); 00100 NetInvert16(&TcpHdrChecksum, hdrPtrChecksum (pPacket)); 00101 NetInvert16(&TcpHdrUrgent, hdrPtrUrgent (pPacket)); 00102 00103 char* pOptions = pPacket + HEADER_LENGTH; 00104 int optionLength = headerSize - HEADER_LENGTH; 00105 00106 mss = 0; 00107 for (char* p = pOptions; p < pOptions + optionLength; p++) //If the header size is zero then optionLength will be negative and the for loop will do nothing. 00108 { 00109 switch (*p) 00110 { 00111 case 0: RestartPoint = lastRestartPoint; return; //End of options so stop 00112 case 1: break; //NOP, padding - optional used to pad to 32 bit boundary 00113 case 2: 00114 p++; 00115 if (*p != 4) LogTimeF("MSS option width %d when expected 4\r\n", *p); 00116 p++; 00117 mss = ((uint16_t)*p) << 8; 00118 p++; 00119 mss += *p; 00120 RestartPoint = lastRestartPoint; 00121 return; //Got what we want so stop 00122 default: LogTimeF("Unrecognised TCP option %d\r\n", *p); 00123 } 00124 } 00125 RestartPoint = lastRestartPoint; 00126 } 00127 00128 void TcpHdrWriteToPacket(char* pPacket) 00129 { 00130 headerSize = HEADER_LENGTH; 00131 if (mss) 00132 { 00133 char* pOptions = pPacket + headerSize; 00134 pOptions[0] = 2; 00135 pOptions[1] = 4; 00136 pOptions[2] = mss >> 8; 00137 pOptions[3] = mss & 0xFF; 00138 headerSize += 4; 00139 } 00140 00141 NetInvert16(hdrPtrDstPort (pPacket), &TcpHdrDstPort); 00142 NetInvert16(hdrPtrSrcPort (pPacket), &TcpHdrSrcPort); 00143 NetInvert32(hdrPtrSeqnum (pPacket), &TcpHdrSeqNum ); //This is the sequence number of the first byte of this message 00144 NetInvert32(hdrPtrAcknum (pPacket), &TcpHdrAckNum ); //This is the sequence number we expect in the next message 00145 *hdrPtrDataOffset(pPacket) = headerSize << 2; //Same as dividing by 4 to get bytes and left shifting by 4 bits 00146 uint8_t flags = 0; 00147 if (TcpHdrURG) flags |= 0x20; //indicates that the Urgent pointer field is significant 00148 if (TcpHdrACK) flags |= 0x10; //indicates that the Acknowledgment field is significant. All packets after the initial SYN packet sent by the client should have this flag set. 00149 if (TcpHdrPSH) flags |= 0x08; //Push function. Asks to push the buffered data to the receiving application. 00150 if (TcpHdrRST) flags |= 0x04; //Reset the connection 00151 if (TcpHdrSYN) flags |= 0x02; //Synchronize sequence numbers. Only the first packet sent from each end should have this flag set. Some other flags and fields change meaning based on this flag, and some are only valid for when it is set, and others when it is clear. 00152 if (TcpHdrFIN) flags |= 0x01; //No more data from sender 00153 *hdrPtrFlags (pPacket) = flags; 00154 NetInvert16(hdrPtrWindow (pPacket), &TcpHdrWindow); 00155 NetInvert16(hdrPtrUrgent (pPacket), &TcpHdrUrgent); 00156 TcpHdrSetChecksum( pPacket, 0); 00157 } 00158 00159 void TcpHdrMakeEmpty() 00160 { 00161 TcpHdrSrcPort = 0; 00162 TcpHdrDstPort = 0; 00163 TcpHdrSeqNum = 0; 00164 TcpHdrAckNum = 0; 00165 headerSize = HEADER_LENGTH; 00166 TcpHdrURG = 0; 00167 TcpHdrACK = 0; 00168 TcpHdrPSH = 0; 00169 TcpHdrRST = 0; 00170 TcpHdrSYN = 0; 00171 TcpHdrFIN = 0; 00172 TcpHdrWindow = 0; 00173 TcpHdrChecksum = 0; 00174 TcpHdrUrgent = 0; 00175 mss = 0; 00176 00177 }
Generated on Tue Jul 12 2022 18:53:40 by 1.7.2