Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
Diff: tcp/tcphdr.c
- Revision:
- 73:43e3d7fb3d60
- Child:
- 74:c3756bfa960e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tcp/tcphdr.c Tue Oct 23 06:46:50 2018 +0000
@@ -0,0 +1,157 @@
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "log.h"
+#include "net.h"
+
+__packed struct header
+{
+ uint16_t srcPort;
+ uint16_t dstPort;
+ uint32_t seqnum;
+ uint32_t acknum;
+ uint8_t dataOffset;
+ uint8_t flags;
+ uint16_t window;
+ uint16_t checksum;
+ uint16_t urgent;
+};
+
+//Header variables
+uint16_t TcpHdrSrcPort;
+uint16_t TcpHdrDstPort;
+uint32_t TcpHdrSeqNum;
+uint32_t TcpHdrAckNum;
+int TcpHdrSize;
+bool TcpHdrURG; //indicates that the Urgent pointer field is significant
+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.
+bool TcpHdrPSH; //Push function. Asks to push the buffered data to the receiving application.
+bool TcpHdrRST; //Reset the connection
+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.
+bool TcpHdrFIN; //No more data from sender
+uint16_t TcpHdrWindow;
+uint16_t TcpHdrChecksum;
+uint16_t TcpHdrUrgent;
+
+//Option variables
+uint16_t TcpHdrMss;
+
+void TcpHdrRead(void* pPacket)
+{
+ struct header* pHeader = (struct header*)pPacket;
+
+ TcpHdrSrcPort = NetToHost16(pHeader->srcPort);
+ TcpHdrDstPort = NetToHost16(pHeader->dstPort);
+ TcpHdrSeqNum = NetToHost32(pHeader->seqnum);
+ TcpHdrAckNum = NetToHost32(pHeader->acknum);
+ TcpHdrSize = (pHeader->dataOffset >> 2) & 0xFC; //Same as right shifting by 4 bits and multiplying by 4
+ uint8_t flags = pHeader->flags;
+ TcpHdrURG = flags & 0x20; //indicates that the Urgent pointer field is significant
+ 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.
+ TcpHdrPSH = flags & 0x08; //Push function. Asks to push the buffered data to the receiving application.
+ TcpHdrRST = flags & 0x04; //Reset the connection
+ 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.
+ TcpHdrFIN = flags & 0x01; //No more data from sender
+ TcpHdrWindow = NetToHost16(pHeader->window);
+ TcpHdrChecksum = NetToHost16(pHeader->checksum);
+ TcpHdrUrgent = NetToHost16(pHeader->urgent);
+}
+
+static void logFlags()
+{
+ if (TcpHdrURG) Log(" URG");
+ if (TcpHdrACK) Log(" ACK");
+ if (TcpHdrPSH) Log(" PSH");
+ if (TcpHdrRST) Log(" RST");
+ if (TcpHdrSYN) Log(" SYN");
+ if (TcpHdrFIN) Log(" FIN");
+}
+void TcpHdrLog(uint16_t calculatedChecksum)
+{
+ if (NetTraceVerbose)
+ {
+ Log("TCP header\r\n");
+ Log(" Source port "); LogF("%hu", TcpHdrSrcPort ); Log("\r\n");
+ Log(" Destination port "); LogF("%hu", TcpHdrDstPort ); Log("\r\n");
+ Log(" Seq number "); LogF("%u", TcpHdrSeqNum ); Log("\r\n");
+ Log(" Ack number "); LogF("%u", TcpHdrAckNum ); Log("\r\n");
+ Log(" Header size "); LogF("%u", TcpHdrSize ); Log("\r\n");
+ Log(" Flags " ); logFlags( ); Log("\r\n");
+ Log(" Window "); LogF("%hu", TcpHdrWindow ); Log("\r\n");
+ Log(" Checksum (hex) "); LogF("%04hX", TcpHdrChecksum ); Log("\r\n");
+ Log(" Calculated (hex) "); LogF("%04hX", calculatedChecksum ); Log("\r\n");
+ Log(" Urgent pointer "); LogF("%hu", TcpHdrUrgent ); Log("\r\n");
+
+ }
+ else
+ {
+ LogF("TCP header %hu >>> %hu", TcpHdrSrcPort, TcpHdrDstPort);
+ logFlags();
+ Log("\r\n");
+ }
+}
+void TcpHdrAddChecksum(void* pPacket, uint16_t checksum)
+{
+ struct header* pHeader = (struct header*)pPacket;
+ pHeader->checksum = checksum;
+}
+void TcpHdrReadOptions(void* pPacket)
+{
+ char* pOptions = (char*)pPacket + sizeof(struct header);
+ int optionLength = TcpHdrSize - sizeof(struct header);
+
+ TcpHdrMss = 536; //default MSS for IPv4 [576 - 20(TCP) - 20(IP)];
+ for (char* p = pOptions; p < pOptions + optionLength; p++)
+ {
+ switch (*p)
+ {
+ case 0: break; //End of options - used to pad to 32 bit boundary
+ case 1: break; //NOP, padding - optional
+ case 2:
+ p++;
+ if (*p != 4) LogTimeF("MSS option width %d when expected 4\r\n", *p);
+ p++;
+ TcpHdrMss = ((uint16_t)*p) << 8;
+ p++;
+ TcpHdrMss += *p;
+ return;
+ default: LogTimeF("Unrecognised TCP option %d\r\n", *p);
+ }
+ }
+}
+void TcpHdrWriteOptions(void* pPacket)
+{
+ char* pOptions = (char*)pPacket + sizeof(struct header);
+ pOptions[0] = 2;
+ pOptions[1] = 4;
+ pOptions[2] = TcpHdrMss >> 8;
+ pOptions[3] = TcpHdrMss & 0xFF;
+ TcpHdrSize += sizeof(struct header) + 4;
+}
+void TcpHdrClearOptions()
+{
+ TcpHdrSize = sizeof(struct header);
+}
+
+void TcpHdrWrite(int size, void* pPacket)
+{
+ struct header* pHeader = (struct header*)pPacket;
+
+ pHeader->dstPort = NetToHost16(TcpHdrDstPort);
+ pHeader->srcPort = NetToHost16(TcpHdrSrcPort);
+ pHeader->seqnum = NetToHost32(TcpHdrSeqNum); //This is the sequence number of the first byte of this message
+ pHeader->acknum = NetToHost32(TcpHdrAckNum); //This is the sequence number we expect in the next message
+ pHeader->dataOffset = TcpHdrSize << 2; //Same as dividing by 4 to get bytes and left shifting by 4 bits
+ uint8_t flags = 0;
+ if (TcpHdrURG) flags |= 0x20; //indicates that the Urgent pointer field is significant
+ 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.
+ if (TcpHdrPSH) flags |= 0x08; //Push function. Asks to push the buffered data to the receiving application.
+ if (TcpHdrRST) flags |= 0x04; //Reset the connection
+ 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.
+ if (TcpHdrFIN) flags |= 0x01; //No more data from sender
+ pHeader->flags = flags;
+ pHeader->window = NetToHost16(TcpHdrWindow);
+ pHeader->urgent = NetToHost16(TcpHdrUrgent);
+
+ pHeader->checksum = 0;
+}
\ No newline at end of file