Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Wed Oct 04 07:51:02 2017 +0000
Revision:
37:793b39683406
Parent:
22:914b970356f0
Child:
43:bc028d5a6424
Added trace back and trace forward to log messages

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