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:
Wed Nov 08 20:46:36 2017 +0000
Revision:
52:fbc5a46b5e16
Parent:
49:1a6336f2b3f9
Child:
54:84ef2b29cf7e
Fixed bug in NDP options decoder which was crashing the system

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