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:
Thu Oct 19 20:56:58 2017 +0000
Revision:
43:bc028d5a6424
Parent:
37:793b39683406
Child:
44:83ce5ace337b
Added verbose option to trace

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