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

Committer:
andrewboyson
Date:
Mon Nov 13 08:06:55 2017 +0000
Revision:
54:84ef2b29cf7e
Parent:
52:fbc5a46b5e16
Child:
55:e64b8b47a2b6
Tidied HTTP files

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 37:793b39683406 1 #include "mbed.h"
andrewboyson 37:793b39683406 2 #include "log.h"
andrewboyson 37:793b39683406 3 #include "net.h"
andrewboyson 37:793b39683406 4 #include "action.h"
andrewboyson 37:793b39683406 5 #include "tcp.h"
andrewboyson 37:793b39683406 6 #include "tcb.h"
andrewboyson 37:793b39683406 7 #include "ip4.h"
andrewboyson 37:793b39683406 8 #include "dhcp.h"
andrewboyson 49:1a6336f2b3f9 9 #include "http.h"
andrewboyson 10:f0854784e960 10
andrewboyson 10:f0854784e960 11 #define MAX_MSS 536 //This is 576 - 20 - 20
andrewboyson 10:f0854784e960 12
andrewboyson 52:fbc5a46b5e16 13 bool TcpTrace = false;
andrewboyson 52:fbc5a46b5e16 14
andrewboyson 10:f0854784e960 15 __packed struct header
andrewboyson 10:f0854784e960 16 {
andrewboyson 10:f0854784e960 17 uint16_t srcPort;
andrewboyson 10:f0854784e960 18 uint16_t dstPort;
andrewboyson 10:f0854784e960 19 uint32_t seqnum;
andrewboyson 10:f0854784e960 20 uint32_t acknum;
andrewboyson 10:f0854784e960 21 uint8_t dataOffset;
andrewboyson 10:f0854784e960 22 uint8_t flags;
andrewboyson 10:f0854784e960 23 uint16_t window;
andrewboyson 10:f0854784e960 24 uint16_t checksum;
andrewboyson 10:f0854784e960 25 uint16_t urgent;
andrewboyson 10:f0854784e960 26 };
andrewboyson 10:f0854784e960 27
andrewboyson 10:f0854784e960 28 //Header variables
andrewboyson 10:f0854784e960 29
andrewboyson 54:84ef2b29cf7e 30 static uint16_t srcPort;
andrewboyson 54:84ef2b29cf7e 31 static uint16_t dstPort;
andrewboyson 54:84ef2b29cf7e 32 static uint32_t seqnum;
andrewboyson 54:84ef2b29cf7e 33 static uint32_t acknum;
andrewboyson 54:84ef2b29cf7e 34 static int headersize;
andrewboyson 54:84ef2b29cf7e 35 static uint8_t flags;
andrewboyson 54:84ef2b29cf7e 36 static bool URG; //indicates that the Urgent pointer field is significant
andrewboyson 54:84ef2b29cf7e 37 static bool ACK; //indicates that the Acknowledgment field is significant. All packets after the initial SYN packet sent by the client should have this flag set.
andrewboyson 54:84ef2b29cf7e 38 static bool PSH; //Push function. Asks to push the buffered data to the receiving application.
andrewboyson 54:84ef2b29cf7e 39 static bool RST; //Reset the connection
andrewboyson 54:84ef2b29cf7e 40 static bool SYN; //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.
andrewboyson 54:84ef2b29cf7e 41 static bool FIN; //No more data from sender
andrewboyson 10:f0854784e960 42
andrewboyson 54:84ef2b29cf7e 43 static uint16_t window;
andrewboyson 54:84ef2b29cf7e 44 static uint16_t checksum;
andrewboyson 54:84ef2b29cf7e 45 static uint16_t urgent;
andrewboyson 54:84ef2b29cf7e 46 static int optionLength;
andrewboyson 10:f0854784e960 47
andrewboyson 54:84ef2b29cf7e 48 static char* pOptions;
andrewboyson 54:84ef2b29cf7e 49 static char* pData;
andrewboyson 54:84ef2b29cf7e 50 static int dataLength;
andrewboyson 54:84ef2b29cf7e 51 static uint16_t mss;
andrewboyson 54:84ef2b29cf7e 52
andrewboyson 54:84ef2b29cf7e 53 static bool isSend = false;
andrewboyson 54:84ef2b29cf7e 54
andrewboyson 54:84ef2b29cf7e 55 static void (*pTraceback)(void);
andrewboyson 54:84ef2b29cf7e 56
andrewboyson 54:84ef2b29cf7e 57 static struct tcb* pTcb;
andrewboyson 54:84ef2b29cf7e 58
andrewboyson 52:fbc5a46b5e16 59 static void logFlags()
andrewboyson 52:fbc5a46b5e16 60 {
andrewboyson 52:fbc5a46b5e16 61 if (URG) Log(" URG");
andrewboyson 52:fbc5a46b5e16 62 if (ACK) Log(" ACK");
andrewboyson 52:fbc5a46b5e16 63 if (PSH) Log(" PSH");
andrewboyson 52:fbc5a46b5e16 64 if (RST) Log(" RST");
andrewboyson 52:fbc5a46b5e16 65 if (SYN) Log(" SYN");
andrewboyson 52:fbc5a46b5e16 66 if (FIN) Log(" FIN");
andrewboyson 52:fbc5a46b5e16 67 }
andrewboyson 37:793b39683406 68 void TcpLogHeader(uint16_t calculatedChecksum)
andrewboyson 43:bc028d5a6424 69 {
andrewboyson 43:bc028d5a6424 70 if (NetTraceVerbose)
andrewboyson 43:bc028d5a6424 71 {
andrewboyson 43:bc028d5a6424 72 Log("TCP header\r\n");
andrewboyson 43:bc028d5a6424 73 LogF(" Source port %hu\r\n", srcPort);
andrewboyson 43:bc028d5a6424 74 LogF(" Destination port %hu\r\n", dstPort);
andrewboyson 54:84ef2b29cf7e 75 if (isSend)
andrewboyson 54:84ef2b29cf7e 76 {
andrewboyson 54:84ef2b29cf7e 77 LogF(" Sequence number %u (%u)\r\n", seqnum - pTcb->locIsn, seqnum);
andrewboyson 54:84ef2b29cf7e 78 LogF(" Ack number %u (%u)\r\n", acknum - pTcb->remIsn, acknum);
andrewboyson 54:84ef2b29cf7e 79 }
andrewboyson 54:84ef2b29cf7e 80 else
andrewboyson 54:84ef2b29cf7e 81 {
andrewboyson 54:84ef2b29cf7e 82 LogF(" Sequence number %u (%u)\r\n", seqnum - pTcb->remIsn, seqnum);
andrewboyson 54:84ef2b29cf7e 83 LogF(" Ack number %u (%u)\r\n", acknum - pTcb->locIsn, acknum);
andrewboyson 54:84ef2b29cf7e 84 }
andrewboyson 43:bc028d5a6424 85 LogF(" Header size %u\r\n", headersize);
andrewboyson 52:fbc5a46b5e16 86 Log (" Flags "); logFlags(); Log("\r\n");
andrewboyson 43:bc028d5a6424 87 LogF(" Window %hu\r\n", window);
andrewboyson 43:bc028d5a6424 88 LogF(" Checksum (hex) %04hX\r\n", checksum);
andrewboyson 43:bc028d5a6424 89 LogF(" Calculated (hex) %04hX\r\n", calculatedChecksum);
andrewboyson 43:bc028d5a6424 90 LogF(" Urgent pointer %hu\r\n", urgent);
andrewboyson 43:bc028d5a6424 91 LogF(" Option length %d\r\n", optionLength);
andrewboyson 43:bc028d5a6424 92 LogF(" Data length %d\r\n", dataLength);
andrewboyson 54:84ef2b29cf7e 93 LogF(" locIsn %u\r\n", pTcb->locIsn);
andrewboyson 54:84ef2b29cf7e 94 LogF(" remIsn %u\r\n", pTcb->remIsn);
andrewboyson 54:84ef2b29cf7e 95 LogF(" locSeq %u\r\n", pTcb->locSeq);
andrewboyson 54:84ef2b29cf7e 96 LogF(" remSeq %u\r\n", pTcb->remSeq);
andrewboyson 54:84ef2b29cf7e 97
andrewboyson 43:bc028d5a6424 98 }
andrewboyson 43:bc028d5a6424 99 else
andrewboyson 43:bc028d5a6424 100 {
andrewboyson 44:83ce5ace337b 101 LogF("TCP header %hu >>> %hu", srcPort, dstPort);
andrewboyson 52:fbc5a46b5e16 102 logFlags();
andrewboyson 54:84ef2b29cf7e 103 if (isSend) LogF(", seq %u, ack %u", seqnum - pTcb->locIsn, acknum - pTcb->remIsn);
andrewboyson 54:84ef2b29cf7e 104 else LogF(", seq %u, ack %u", seqnum - pTcb->remIsn, acknum - pTcb->locIsn);
andrewboyson 52:fbc5a46b5e16 105 Log("\r\n");
andrewboyson 43:bc028d5a6424 106 }
andrewboyson 10:f0854784e960 107 }
andrewboyson 10:f0854784e960 108 void TcpAddChecksum(void* pPacket, uint16_t checksum)
andrewboyson 10:f0854784e960 109 {
andrewboyson 10:f0854784e960 110 struct header* pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 111 pHeader->checksum = checksum;
andrewboyson 10:f0854784e960 112 }
andrewboyson 10:f0854784e960 113 static void readOptions()
andrewboyson 10:f0854784e960 114 {
andrewboyson 10:f0854784e960 115 mss = 536; //default MSS for IPv4 [576 - 20(TCP) - 20(IP)];
andrewboyson 10:f0854784e960 116 for (char* p = pOptions; p < pOptions + optionLength; p++)
andrewboyson 10:f0854784e960 117 {
andrewboyson 10:f0854784e960 118 switch (*p)
andrewboyson 10:f0854784e960 119 {
andrewboyson 10:f0854784e960 120 case 0: break; //End of options - used to pad to 32 bit boundary
andrewboyson 10:f0854784e960 121 case 1: break; //NOP, padding - optional
andrewboyson 10:f0854784e960 122 case 2:
andrewboyson 10:f0854784e960 123 p++;
andrewboyson 10:f0854784e960 124 if (*p != 4) LogTimeF("MSS option width %d when expected 4\r\n", *p);
andrewboyson 10:f0854784e960 125 p++;
andrewboyson 10:f0854784e960 126 mss = ((uint16_t)*p) << 8;
andrewboyson 10:f0854784e960 127 p++;
andrewboyson 10:f0854784e960 128 mss += *p;
andrewboyson 10:f0854784e960 129 return;
andrewboyson 10:f0854784e960 130 default: LogTimeF("Unrecognised TCP option %d\r\n", *p);
andrewboyson 10:f0854784e960 131 }
andrewboyson 10:f0854784e960 132 }
andrewboyson 10:f0854784e960 133 if (mss > MAX_MSS) mss = MAX_MSS;
andrewboyson 10:f0854784e960 134 }
andrewboyson 10:f0854784e960 135 static void writeOptions()
andrewboyson 10:f0854784e960 136 {
andrewboyson 10:f0854784e960 137 pOptions[0] = 2;
andrewboyson 10:f0854784e960 138 pOptions[1] = 4;
andrewboyson 10:f0854784e960 139 pOptions[2] = mss >> 8;
andrewboyson 10:f0854784e960 140 pOptions[3] = mss & 0xFF;
andrewboyson 10:f0854784e960 141 optionLength = 4;
andrewboyson 10:f0854784e960 142 }
andrewboyson 10:f0854784e960 143
andrewboyson 10:f0854784e960 144 void TcpReadHeader(void* pPacket, uint16_t size)
andrewboyson 10:f0854784e960 145 {
andrewboyson 10:f0854784e960 146 struct header* pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 147
andrewboyson 10:f0854784e960 148 srcPort = NetToHost16(pHeader->srcPort);
andrewboyson 10:f0854784e960 149 dstPort = NetToHost16(pHeader->dstPort);
andrewboyson 10:f0854784e960 150 seqnum = NetToHost32(pHeader->seqnum);
andrewboyson 10:f0854784e960 151 acknum = NetToHost32(pHeader->acknum);
andrewboyson 10:f0854784e960 152 headersize = (pHeader->dataOffset >> 2) & 0xFC; //Same as right shifting by 4 bits and multiplying by 4
andrewboyson 10:f0854784e960 153 flags = pHeader->flags;
andrewboyson 10:f0854784e960 154 URG = flags & 0x20; //indicates that the Urgent pointer field is significant
andrewboyson 10:f0854784e960 155 ACK = 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.
andrewboyson 10:f0854784e960 156 PSH = flags & 0x08; //Push function. Asks to push the buffered data to the receiving application.
andrewboyson 10:f0854784e960 157 RST = flags & 0x04; //Reset the connection
andrewboyson 10:f0854784e960 158 SYN = 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.
andrewboyson 10:f0854784e960 159 FIN = flags & 0x01; //No more data from sender
andrewboyson 10:f0854784e960 160
andrewboyson 10:f0854784e960 161 window = NetToHost16(pHeader->window);
andrewboyson 10:f0854784e960 162 checksum = NetToHost16(pHeader->checksum);
andrewboyson 10:f0854784e960 163 urgent = NetToHost16(pHeader->urgent);
andrewboyson 10:f0854784e960 164 pOptions = (char*)pPacket + 20;
andrewboyson 10:f0854784e960 165 optionLength = headersize - 20;
andrewboyson 10:f0854784e960 166
andrewboyson 10:f0854784e960 167 pData = (char*)pPacket + headersize;
andrewboyson 10:f0854784e960 168 dataLength = size - headersize;
andrewboyson 10:f0854784e960 169 }
andrewboyson 10:f0854784e960 170
andrewboyson 10:f0854784e960 171 void TcpMakeHeader(int size, void* pPacket)
andrewboyson 10:f0854784e960 172 {
andrewboyson 10:f0854784e960 173 struct header* pHeader = (header*)pPacket;
andrewboyson 10:f0854784e960 174
andrewboyson 10:f0854784e960 175 pHeader->dstPort = NetToHost16(dstPort);
andrewboyson 10:f0854784e960 176 pHeader->srcPort = NetToHost16(srcPort);
andrewboyson 10:f0854784e960 177 pHeader->seqnum = NetToHost32(seqnum); //This is the sequence number of the first byte of this message
andrewboyson 10:f0854784e960 178 pHeader->acknum = NetToHost32(acknum); //This is the sequence number we expect in the next message
andrewboyson 10:f0854784e960 179 pHeader->dataOffset = headersize << 2; //Same as dividing by 4 to get bytes and left shifting by 4 bits
andrewboyson 10:f0854784e960 180 flags = 0;
andrewboyson 10:f0854784e960 181 if(URG) flags |= 0x20; //indicates that the Urgent pointer field is significant
andrewboyson 10:f0854784e960 182 if(ACK) 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.
andrewboyson 10:f0854784e960 183 if(PSH) flags |= 0x08; //Push function. Asks to push the buffered data to the receiving application.
andrewboyson 10:f0854784e960 184 if(RST) flags |= 0x04; //Reset the connection
andrewboyson 10:f0854784e960 185 if(SYN) 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.
andrewboyson 10:f0854784e960 186 if(FIN) flags |= 0x01; //No more data from sender
andrewboyson 10:f0854784e960 187 pHeader->flags = flags;
andrewboyson 10:f0854784e960 188 pHeader->window = NetToHost16(window);
andrewboyson 10:f0854784e960 189 pHeader->urgent = NetToHost16(urgent);
andrewboyson 10:f0854784e960 190
andrewboyson 10:f0854784e960 191 pHeader->checksum = 0;
andrewboyson 10:f0854784e960 192 }
andrewboyson 54:84ef2b29cf7e 193 static int stateClosed()
andrewboyson 10:f0854784e960 194 {
andrewboyson 10:f0854784e960 195 if (!SYN) //Reset if anything other than a request to establish conection from client
andrewboyson 10:f0854784e960 196 {
andrewboyson 10:f0854784e960 197 dataLength = 0;
andrewboyson 10:f0854784e960 198 headersize = 20;
andrewboyson 10:f0854784e960 199 seqnum = acknum;
andrewboyson 10:f0854784e960 200 acknum = 0;
andrewboyson 10:f0854784e960 201 ACK = false; //Send RST
andrewboyson 10:f0854784e960 202 PSH = false;
andrewboyson 10:f0854784e960 203 RST = true;
andrewboyson 10:f0854784e960 204 SYN = false;
andrewboyson 10:f0854784e960 205 FIN = false;
andrewboyson 10:f0854784e960 206 return 1;
andrewboyson 10:f0854784e960 207 }
andrewboyson 10:f0854784e960 208
andrewboyson 10:f0854784e960 209 readOptions(); //Get the MSS
andrewboyson 52:fbc5a46b5e16 210 pTcb->mss = mss;
andrewboyson 52:fbc5a46b5e16 211 pTcb->state = TCB_SYN_RECEIVED;
andrewboyson 52:fbc5a46b5e16 212 pTcb->elapsed = TcbElapsed;
andrewboyson 52:fbc5a46b5e16 213 pTcb->port = srcPort;
andrewboyson 52:fbc5a46b5e16 214 pTcb->locIsn = TcbGetIsn();
andrewboyson 52:fbc5a46b5e16 215 pTcb->locSeq = pTcb->locIsn;
andrewboyson 52:fbc5a46b5e16 216 pTcb->remIsn = seqnum;
andrewboyson 52:fbc5a46b5e16 217 pTcb->remSeq = pTcb->remIsn;
andrewboyson 10:f0854784e960 218
andrewboyson 10:f0854784e960 219 pTcb->remSeq += 1; //Add one to acknowledge the SYN
andrewboyson 10:f0854784e960 220 acknum = pTcb->remSeq;
andrewboyson 10:f0854784e960 221
andrewboyson 10:f0854784e960 222 seqnum = pTcb->locSeq; //Set the sequence number to the first byte of this message
andrewboyson 10:f0854784e960 223 pTcb->locSeq += 1; //Add one to the next sequence number as we are sending a SYN
andrewboyson 10:f0854784e960 224
andrewboyson 10:f0854784e960 225 dataLength = 0;
andrewboyson 10:f0854784e960 226
andrewboyson 10:f0854784e960 227 mss = MAX_MSS; //Ethernet 1500 - 20 - 20; or, in our case 768 - 20 - 20
andrewboyson 10:f0854784e960 228 writeOptions();
andrewboyson 10:f0854784e960 229 headersize = 24; //20 header plus 4 option
andrewboyson 10:f0854784e960 230
andrewboyson 10:f0854784e960 231 ACK = true; //Send ACK and SYN
andrewboyson 10:f0854784e960 232 PSH = false;
andrewboyson 10:f0854784e960 233 RST = false;
andrewboyson 10:f0854784e960 234 SYN = true;
andrewboyson 10:f0854784e960 235 FIN = false;
andrewboyson 10:f0854784e960 236
andrewboyson 10:f0854784e960 237 return 1;
andrewboyson 10:f0854784e960 238 }
andrewboyson 54:84ef2b29cf7e 239 static int stateSynReceived()
andrewboyson 10:f0854784e960 240 {
andrewboyson 10:f0854784e960 241 if (dataLength) LogTimeF("%d bytes data received before TCB established\r\n", dataLength);
andrewboyson 10:f0854784e960 242 if (ACK)
andrewboyson 10:f0854784e960 243 {
andrewboyson 52:fbc5a46b5e16 244 pTcb->state = TCB_ESTABLISHED;
andrewboyson 52:fbc5a46b5e16 245 pTcb->elapsed = TcbElapsed;
andrewboyson 54:84ef2b29cf7e 246 pTcb->todo = 0;
andrewboyson 10:f0854784e960 247 }
andrewboyson 10:f0854784e960 248 return 0;
andrewboyson 10:f0854784e960 249 }
andrewboyson 54:84ef2b29cf7e 250 static int stateEstablished()
andrewboyson 10:f0854784e960 251 {
andrewboyson 10:f0854784e960 252 if (!ACK) return 0; //Ignore any packets which don't contain an ACK
andrewboyson 10:f0854784e960 253
andrewboyson 10:f0854784e960 254 //Handle reception of data
andrewboyson 54:84ef2b29cf7e 255 pTcb->remSeq = seqnum + dataLength;
andrewboyson 10:f0854784e960 256 acknum = pTcb->remSeq; //Set the ack num to the next byte expected from the client
andrewboyson 54:84ef2b29cf7e 257 int positionInRequestStream = seqnum - pTcb->remIsn - 1;
andrewboyson 54:84ef2b29cf7e 258 int positionInReplyStream = pTcb->locSeq - pTcb->locIsn - 1;
andrewboyson 54:84ef2b29cf7e 259 char* pRequestStream = pData;
andrewboyson 54:84ef2b29cf7e 260 char* pReplyStream = pOptions;
andrewboyson 54:84ef2b29cf7e 261
andrewboyson 54:84ef2b29cf7e 262 HttpHandleRequest(pTraceback, &dataLength, pRequestStream, positionInRequestStream, pReplyStream, positionInReplyStream, mss, &pTcb->todo);
andrewboyson 10:f0854784e960 263
andrewboyson 10:f0854784e960 264 //Rearrange the buffers
andrewboyson 10:f0854784e960 265 headersize = 20;
andrewboyson 54:84ef2b29cf7e 266 pData = pReplyStream;
andrewboyson 10:f0854784e960 267
andrewboyson 10:f0854784e960 268 seqnum = pTcb->locSeq; //Set the sequence number to the first byte of this message
andrewboyson 10:f0854784e960 269
andrewboyson 10:f0854784e960 270 ACK = true; //Send ACK
andrewboyson 10:f0854784e960 271 RST = false;
andrewboyson 10:f0854784e960 272 SYN = false;
andrewboyson 22:914b970356f0 273 PSH = false;
andrewboyson 10:f0854784e960 274
andrewboyson 22:914b970356f0 275 pTcb->locSeq += dataLength; //Record the next sequence number
andrewboyson 22:914b970356f0 276
andrewboyson 22:914b970356f0 277 if (dataLength < mss) //If a part packet then there can be no more to send
andrewboyson 10:f0854784e960 278 {
andrewboyson 22:914b970356f0 279 FIN = true; //Inform the client that we have no more to send after this
andrewboyson 22:914b970356f0 280 pTcb->locSeq += 1; //Record the FIN in the sequence
andrewboyson 10:f0854784e960 281 pTcb->state = TCB_CLOSING; //Start closing
andrewboyson 10:f0854784e960 282 }
andrewboyson 22:914b970356f0 283
andrewboyson 52:fbc5a46b5e16 284 pTcb->elapsed = TcbElapsed;
andrewboyson 10:f0854784e960 285 return 1;
andrewboyson 10:f0854784e960 286 }
andrewboyson 54:84ef2b29cf7e 287 static int stateClosing()
andrewboyson 10:f0854784e960 288 {
andrewboyson 10:f0854784e960 289 if (!FIN) return 0; //Ignore any packets which don't contain a FIN
andrewboyson 10:f0854784e960 290
andrewboyson 10:f0854784e960 291 pTcb->remSeq += 1; //Add one to acknowledge the FIN
andrewboyson 10:f0854784e960 292 acknum = pTcb->remSeq;
andrewboyson 10:f0854784e960 293
andrewboyson 10:f0854784e960 294 seqnum = pTcb->locSeq; //Set the sequence number to the first byte of this message
andrewboyson 10:f0854784e960 295 //but don't change it for the next
andrewboyson 10:f0854784e960 296
andrewboyson 10:f0854784e960 297 ACK = true; //Send ACK
andrewboyson 10:f0854784e960 298 PSH = false;
andrewboyson 10:f0854784e960 299 RST = false;
andrewboyson 10:f0854784e960 300 SYN = false;
andrewboyson 10:f0854784e960 301 FIN = false;
andrewboyson 10:f0854784e960 302
andrewboyson 10:f0854784e960 303 headersize = 20;
andrewboyson 10:f0854784e960 304 dataLength = 0;
andrewboyson 10:f0854784e960 305
andrewboyson 10:f0854784e960 306 pTcb->state = TCB_CLOSED;
andrewboyson 10:f0854784e960 307
andrewboyson 10:f0854784e960 308 return 1;
andrewboyson 10:f0854784e960 309 }
andrewboyson 10:f0854784e960 310
andrewboyson 37:793b39683406 311 int TcpHandleReceivedPacket(void (*traceback)(void), int* pSize, void* pPacket)
andrewboyson 10:f0854784e960 312 {
andrewboyson 54:84ef2b29cf7e 313 pTraceback = traceback;
andrewboyson 54:84ef2b29cf7e 314 isSend = false;
andrewboyson 54:84ef2b29cf7e 315 pTcb = TcbGetExisting(srcPort);
andrewboyson 10:f0854784e960 316 if (!pTcb) pTcb = TcbGetEmpty();
andrewboyson 52:fbc5a46b5e16 317 if (!pTcb)
andrewboyson 52:fbc5a46b5e16 318 {
andrewboyson 52:fbc5a46b5e16 319 if (TcpTrace)
andrewboyson 52:fbc5a46b5e16 320 {
andrewboyson 52:fbc5a46b5e16 321 LogTime("TCP no more tcbs are available\r\n");
andrewboyson 52:fbc5a46b5e16 322 traceback(); //This will already include the TCP header
andrewboyson 52:fbc5a46b5e16 323 }
andrewboyson 52:fbc5a46b5e16 324 return DO_NOTHING; //Bomb out if no more tcbs are available
andrewboyson 52:fbc5a46b5e16 325 }
andrewboyson 10:f0854784e960 326
andrewboyson 10:f0854784e960 327 if (RST)
andrewboyson 10:f0854784e960 328 {
andrewboyson 10:f0854784e960 329 pTcb->state = TCB_CLOSED; //Reset connection
andrewboyson 10:f0854784e960 330 return DO_NOTHING; //Bomb out
andrewboyson 10:f0854784e960 331 }
andrewboyson 10:f0854784e960 332
andrewboyson 52:fbc5a46b5e16 333 //Filter out unwanted links
andrewboyson 10:f0854784e960 334 switch (dstPort)
andrewboyson 10:f0854784e960 335 {
andrewboyson 10:f0854784e960 336 case 80: break;
andrewboyson 52:fbc5a46b5e16 337 default:
andrewboyson 52:fbc5a46b5e16 338 if (TcpTrace)
andrewboyson 52:fbc5a46b5e16 339 {
andrewboyson 52:fbc5a46b5e16 340 LogTimeF("TCP unknown port %d\r\n", dstPort);
andrewboyson 52:fbc5a46b5e16 341 traceback(); //This will already include the TCP header
andrewboyson 52:fbc5a46b5e16 342 }
andrewboyson 52:fbc5a46b5e16 343 return DO_NOTHING; //This needs to become a reset
andrewboyson 10:f0854784e960 344 }
andrewboyson 10:f0854784e960 345
andrewboyson 52:fbc5a46b5e16 346 if (TcpTrace)
andrewboyson 52:fbc5a46b5e16 347 {
andrewboyson 52:fbc5a46b5e16 348 if (!SYN && (int32_t)(seqnum - pTcb->remSeq))
andrewboyson 52:fbc5a46b5e16 349 {
andrewboyson 52:fbc5a46b5e16 350 LogTime("TCP");
andrewboyson 52:fbc5a46b5e16 351 logFlags();
andrewboyson 52:fbc5a46b5e16 352 LogF(" off=%d seq num=%u expected=%u packet length %d from port %u\r\n", (int32_t)(seqnum - pTcb->remSeq), seqnum, pTcb->remSeq, *pSize, srcPort);
andrewboyson 52:fbc5a46b5e16 353 }
andrewboyson 52:fbc5a46b5e16 354 }
andrewboyson 10:f0854784e960 355 //Drop duplicate packets
andrewboyson 52:fbc5a46b5e16 356 /*
andrewboyson 52:fbc5a46b5e16 357 if (!TCB_CLOSED && (int32_t)(seqnum - pTcb->remSeq) < 0)
andrewboyson 52:fbc5a46b5e16 358 {
andrewboyson 52:fbc5a46b5e16 359 if (TcpTrace)
andrewboyson 52:fbc5a46b5e16 360 {
andrewboyson 52:fbc5a46b5e16 361 LogTimeF("TCP Dropped duplicate seq num=%d expected=%d packet length %d from port %u\r\n", seqnum, pTcb->remSeq, *pSize, srcPort);
andrewboyson 52:fbc5a46b5e16 362 traceback();
andrewboyson 52:fbc5a46b5e16 363 }
andrewboyson 52:fbc5a46b5e16 364 return DO_NOTHING;
andrewboyson 52:fbc5a46b5e16 365 }
andrewboyson 52:fbc5a46b5e16 366 */
andrewboyson 54:84ef2b29cf7e 367 if (TcpTrace)
andrewboyson 54:84ef2b29cf7e 368 {
andrewboyson 54:84ef2b29cf7e 369 if (NetTraceNewLine) Log("\r\n");
andrewboyson 54:84ef2b29cf7e 370 LogF("TCP server request\r\n");
andrewboyson 54:84ef2b29cf7e 371 traceback();
andrewboyson 54:84ef2b29cf7e 372 }
andrewboyson 10:f0854784e960 373
andrewboyson 54:84ef2b29cf7e 374 isSend = true;
andrewboyson 10:f0854784e960 375 switch (pTcb->state)
andrewboyson 10:f0854784e960 376 {
andrewboyson 54:84ef2b29cf7e 377 case TCB_CLOSED: if (stateClosed ()) break; return DO_NOTHING;
andrewboyson 54:84ef2b29cf7e 378 case TCB_SYN_RECEIVED: if (stateSynReceived()) break; return DO_NOTHING;
andrewboyson 54:84ef2b29cf7e 379 case TCB_ESTABLISHED: if (stateEstablished()) break; return DO_NOTHING;
andrewboyson 54:84ef2b29cf7e 380 case TCB_CLOSING: if (stateClosing ()) break; return DO_NOTHING;
andrewboyson 10:f0854784e960 381 }
andrewboyson 10:f0854784e960 382
andrewboyson 10:f0854784e960 383 srcPort = dstPort;
andrewboyson 10:f0854784e960 384 dstPort = pTcb->port;
andrewboyson 10:f0854784e960 385
andrewboyson 10:f0854784e960 386 *pSize = dataLength + headersize;
andrewboyson 54:84ef2b29cf7e 387
andrewboyson 54:84ef2b29cf7e 388 return ActionMakeFromDestAndTrace(UNICAST, TcpTrace && NetTraceStack);
andrewboyson 10:f0854784e960 389
andrewboyson 10:f0854784e960 390 }