26#include "TCP_Header.h"
28bool isSynPacket(NetSim_PACKET* packet)
30 PTCP_SEGMENT_HDR hdr = TCP_GET_SEGMENT_HDR(packet);
38bool isSynbitSet(NetSim_PACKET* packet)
40 PTCP_SEGMENT_HDR hdr = TCP_GET_SEGMENT_HDR(packet);
41 return hdr->Syn ? true :
false;
45void set_tcp_option(PTCP_SEGMENT_HDR hdr,
void* option, TCP_OPTION type, UINT32 size)
47 PTCPOPTION opt = (PTCPOPTION)calloc(1,
sizeof* opt);
52 hdr->HdrLength += size;
56 PTCPOPTION o = hdr->option;
65void* get_tcp_option(PTCP_SEGMENT_HDR hdr, TCP_OPTION type)
67 PTCPOPTION o = hdr->option;
77static void add_tcp_extra_option(PTCP_SEGMENT_HDR hdr, UINT32 l)
80 for (i = 0; i < 4-l; i++)
84 PEXTRA_OPTION end = calloc(1,
sizeof* end);
85 end->type = TCP_OPTION_END;
86 set_tcp_option(hdr, end, TCP_OPTION_END, EXTRA_OPTION_LEN);
90 PEXTRA_OPTION nop = calloc(1,
sizeof* nop);
91 nop->type = TCP_OPTION_NOOPERATION;
92 set_tcp_option(hdr, nop, TCP_OPTION_NOOPERATION, EXTRA_OPTION_LEN);
97static void set_tcp_packet_size(NetSim_PACKET* p)
99 PTCP_SEGMENT_HDR hdr = TCP_GET_SEGMENT_HDR(p);
100 if (hdr->HdrLength % 4)
102 add_tcp_extra_option(hdr, hdr->HdrLength % 4);
104 p->pstruTransportData->dOverhead = hdr->HdrLength;
105 p->pstruTransportData->dPacketSize = p->pstruTransportData->dPayload +
106 p->pstruTransportData->dOverhead;
109static void add_tcp_mss_option(PNETSIM_SOCKET s,
110 PTCP_SEGMENT_HDR hdr)
112 PMSS_OPTION opt = (PMSS_OPTION)calloc(1,
sizeof* opt);
113 opt->type = TCP_OPTION_MSS;
114 opt->len = MSS_OPTION_LEN;
115 opt->MSSData = s->tcb->get_MSS(s);
116 set_tcp_option(hdr, opt, TCP_OPTION_MSS, MSS_OPTION_LEN);
119static void add_tcp_sack_permitted_option(PNETSIM_SOCKET s,
120 PTCP_SEGMENT_HDR hdr)
123 PSACKPERMITTED_OPTION opt = (PSACKPERMITTED_OPTION)calloc(1,
sizeof* opt);
124 opt->type = TCP_OPTION_SACK_PERMITTED;
125 opt->len = SACKPERMITTED_OPTION_LEN;
126 set_tcp_option(hdr, opt, TCP_OPTION_SACK_PERMITTED, SACKPERMITTED_OPTION_LEN);
129static void add_tcp_window_scale_option(PNETSIM_SOCKET s,
130 PTCP_SEGMENT_HDR hdr)
132 PWsopt opt = (PWsopt)calloc(1,
sizeof* opt);
133 opt->type = TCP_OPTION_WINDOW_SCALE;
134 opt->len = WSOPT_LEN;
135 opt->Shift_cnt = s->tcb->Snd.Wind_Shift;
136 set_tcp_option(hdr, opt, TCP_OPTION_WINDOW_SCALE, WSOPT_LEN);
138 PEXTRA_OPTION ex = (PEXTRA_OPTION)calloc(1,
sizeof* ex);
139 ex->type = TCP_OPTION_NOOPERATION;
140 set_tcp_option(hdr, ex, TCP_OPTION_NOOPERATION, EXTRA_OPTION_LEN);
143static void add_tcp_timestamp_option(PNETSIM_SOCKET s,
144 PTCP_SEGMENT_HDR hdr)
146 PTSopt opt = (PTSopt)calloc(1,
sizeof* opt);
147 opt->type = TCP_OPTION_TIMESTAMP;
148 opt->len = TSOPT_LEN;
150 opt->TSval = (UINT)pstruEventDetails->dEventTime;
155 opt->TSecr = s->tcb->TSVal;
157 set_tcp_option(hdr, opt, TCP_OPTION_TIMESTAMP, TSOPT_LEN);
159 PEXTRA_OPTION ex = (PEXTRA_OPTION)calloc(1,
sizeof* ex);
160 ex->type = TCP_OPTION_NOOPERATION;
161 set_tcp_option(hdr, ex, TCP_OPTION_NOOPERATION, EXTRA_OPTION_LEN);
164NetSim_PACKET* create_tcp_ctrl_packet(PNETSIM_SOCKET s,
168 PTCP_SEGMENT_HDR hdr = (PTCP_SEGMENT_HDR)calloc(1,
sizeof* hdr);
169 hdr->HdrLength = TCP_HDR_SIZE;
170 hdr->SrcPort = s->localAddr->port;
171 hdr->DstPort = s->remoteAddr->port;
173 NetSim_PACKET* p = fn_NetSim_Packet_CreatePacket(TRANSPORT_LAYER);
174 p->nControlDataType = type;
175 add_dest_to_packet(p, s->remoteDeviceId);
176 p->nPacketType = PacketType_Control;
177 p->nSourceId = s->localDeviceId;
178 p->pstruTransportData->dArrivalTime = time;
179 p->pstruTransportData->dOverhead = TCP_HDR_SIZE;
180 p->pstruTransportData->dPayload = 0;
181 p->pstruTransportData->dPacketSize = TCP_HDR_SIZE;
182 p->pstruTransportData->nDestinationPort = s->remoteAddr->port;
183 p->pstruTransportData->nSourcePort = s->localAddr->port;
184 p->pstruTransportData->nTransportProtocol = TX_PROTOCOL_TCP;
185 p->pstruTransportData->Packet_TransportProtocol = hdr;
187 p->pstruNetworkData->szSourceIP = s->localAddr->ip;
188 p->pstruNetworkData->szDestIP = s->remoteAddr->ip;
189 p->pstruNetworkData->nTTL = MAX_TTL;
190 p->pstruNetworkData->IPProtocol = IPPROTOCOL_TCP;
195NetSim_PACKET* create_syn(PNETSIM_SOCKET s,
198 NetSim_PACKET* p = create_tcp_ctrl_packet(s,
202 PTCP_SEGMENT_HDR hdr = TCP_GET_SEGMENT_HDR(p);
205 hdr->SeqNum = s->tcb->ISS;
206 hdr->Window = s->tcb->get_WND(s);
208 add_tcp_mss_option(s, hdr);
210 if (s->tcb->isSackPermitted)
211 add_tcp_sack_permitted_option(s, hdr);
214 add_tcp_timestamp_option(s, hdr);
216 if (s->tcb->isWindowScaling)
217 add_tcp_window_scale_option(s, hdr);
219 set_tcp_packet_size(p);
224NetSim_PACKET* create_synAck(PNETSIM_SOCKET s,
227 NetSim_PACKET* p = create_tcp_ctrl_packet(s,
231 PTCP_SEGMENT_HDR hdr = TCP_GET_SEGMENT_HDR(p);
235 hdr->SeqNum = s->tcb->ISS;
236 hdr->AckNum = s->tcb->RCV.NXT;
237 hdr->Window = s->tcb->get_WND(s);
239 add_tcp_mss_option(s, hdr);
241 if (s->tcb->isWindowScaling)
242 add_tcp_window_scale_option(s, hdr);
244 if (s->tcb->isSackPermitted)
245 add_tcp_sack_permitted_option(s, hdr);
248 add_tcp_timestamp_option(s, hdr);
250 set_tcp_packet_size(p);
255NetSim_PACKET* create_rst(NetSim_PACKET* p,
262 l.ip = p->pstruNetworkData->szDestIP;
263 l.port = p->pstruTransportData->nDestinationPort;
266 r.ip = p->pstruNetworkData->szSourceIP;
267 r.port = p->pstruTransportData->nSourcePort;
268 temp.remoteAddr = &r;
270 temp.localDeviceId = get_first_dest_from_packet(p);
271 temp.remoteDeviceId = p->nSourceId;
273 NetSim_PACKET* packet = create_tcp_ctrl_packet(&temp,
277 PTCP_SEGMENT_HDR hdr = TCP_GET_SEGMENT_HDR(packet);
278 PTCP_SEGMENT_HDR seg = TCP_GET_SEGMENT_HDR(p);
280 if (seg->Ack || c == 1)
282 hdr->SeqNum = seg->AckNum;
288 hdr->AckNum = seg->SeqNum + seg->HdrLength;
293 set_tcp_packet_size(p);
298NetSim_PACKET* create_ack(PNETSIM_SOCKET s,
303 NetSim_PACKET* p = create_tcp_ctrl_packet(s,
307 PTCP_SEGMENT_HDR hdr = TCP_GET_SEGMENT_HDR(p);
312 hdr->Window = s->tcb->get_WND(s);
315 add_tcp_timestamp_option(s, hdr);
317 set_sack_option(s, hdr, time);
318 set_tcp_packet_size(p);
323NetSim_PACKET* create_fin(PNETSIM_SOCKET s,
326 NetSim_PACKET* p = create_tcp_ctrl_packet(s,
330 PTCP_SEGMENT_HDR hdr = TCP_GET_SEGMENT_HDR(p);
333 hdr->SeqNum = s->tcb->ISS + 1 == s->tcb->SND.NXT ?
334 s->tcb->SND.NXT + 1 : s->tcb->SND.NXT;
335 hdr->Window = window_scale_get_wnd(s);
337 set_tcp_packet_size(p);
342void add_tcp_hdr(NetSim_PACKET* p, PNETSIM_SOCKET s)
344 PTCP_SEGMENT_HDR hdr = (PTCP_SEGMENT_HDR)calloc(1,
sizeof* hdr);
345 hdr->DstPort = s->remoteAddr->port;
346 hdr->HdrLength = TCP_HDR_SIZE;
347 hdr->SeqNum = s->tcb->SND.NXT;
348 hdr->SrcPort = s->localAddr->port;
349 hdr->Window = window_scale_get_wnd(s);
352 add_tcp_timestamp_option(s, hdr);
354 p->pstruTransportData->dArrivalTime = pstruEventDetails->dEventTime;
355 p->pstruTransportData->dEndTime = pstruEventDetails->dEventTime;
356 p->pstruTransportData->dOverhead = TCP_HDR_SIZE;
357 p->pstruTransportData->dPayload = p->pstruAppData->dPacketSize;
358 p->pstruTransportData->dStartTime = pstruEventDetails->dEventTime;
359 p->pstruTransportData->Packet_TransportProtocol = hdr;
360 p->pstruTransportData->nTransportProtocol = TX_PROTOCOL_TCP;
362 p->pstruNetworkData->IPProtocol = IPPROTOCOL_TCP;
364 set_tcp_packet_size(p);
367static PTCPOPTION copy_tcp_mss_option(PTCPOPTION opt)
369 PTCPOPTION o = (PTCPOPTION)calloc(1,
sizeof* o);
370 memcpy(o, opt,
sizeof* o);
372 PMSS_OPTION mss = opt->option;
373 PMSS_OPTION m = (PMSS_OPTION)calloc(1,
sizeof* m);
374 memcpy(m, mss,
sizeof* m);
379static PTCPOPTION copy_tcp_sack_permitted_option(PTCPOPTION opt)
381 PTCPOPTION o = (PTCPOPTION)calloc(1,
sizeof* o);
382 memcpy(o, opt,
sizeof* o);
384 PSACKPERMITTED_OPTION sackPermitted = opt->option;
385 PSACKPERMITTED_OPTION sp = (PSACKPERMITTED_OPTION)calloc(1,
sizeof* sp);
386 memcpy(sp, sackPermitted,
sizeof* sp);
391static PTCPOPTION copy_tcp_extra_option(PTCPOPTION opt)
393 PTCPOPTION o = (PTCPOPTION)calloc(1,
sizeof* o);
394 memcpy(o, opt,
sizeof* o);
396 PEXTRA_OPTION ex = opt->option;
397 PEXTRA_OPTION dex = (PEXTRA_OPTION)calloc(1,
sizeof* dex);
398 memcpy(dex, ex,
sizeof* dex);
403static PTCPOPTION copy_sack_option(PTCPOPTION t)
405 PSACK_OPTION sack = t->option;
406 PSACK_OPTION s = (PSACK_OPTION)calloc(1,
sizeof* s);
407 memcpy(s, sack,
sizeof* s);
409 UINT c = get_sack_data_count(sack);
410 s->sackData = (PSACKDATA*)calloc(c,
sizeof* s->sackData);
411 for (UINT i = 0; i < c; i++)
413 s->sackData[i] = (PSACKDATA)calloc(1,
sizeof* s->sackData[i]);
414 memcpy(s->sackData[i], sack->sackData[i],
sizeof* s->sackData[i]);
416 PTCPOPTION r = (PTCPOPTION)calloc(1,
sizeof* r);
423static PTCPOPTION copy_window_scale_option(PTCPOPTION opt)
425 PTCPOPTION o = (PTCPOPTION)calloc(1,
sizeof* o);
426 memcpy(o, opt,
sizeof* o);
428 PWsopt ex = opt->option;
429 PWsopt dex = (PWsopt)calloc(1,
sizeof* dex);
430 memcpy(dex, ex,
sizeof* dex);
435static PTCPOPTION copy_timestamp_option(PTCPOPTION opt)
437 PTCPOPTION o = (PTCPOPTION)calloc(1,
sizeof* o);
438 memcpy(o, opt,
sizeof* o);
440 PTSopt ex = opt->option;
441 PTSopt dex = (PTSopt)calloc(1,
sizeof* dex);
442 memcpy(dex, ex,
sizeof* dex);
447static void copy_tcp_option(PTCP_SEGMENT_HDR dhdr, PTCP_SEGMENT_HDR hdr)
449 PTCPOPTION opt = hdr->option;
453 PTCPOPTION dopt = NULL;
457 case TCP_OPTION_NOOPERATION:
458 dopt = copy_tcp_extra_option(opt);
461 dopt = copy_tcp_mss_option(opt);
463 case TCP_OPTION_SACK_PERMITTED:
464 dopt = copy_tcp_sack_permitted_option(opt);
466 case TCP_OPTION_SACK:
467 dopt = copy_sack_option(opt);
469 case TCP_OPTION_WINDOW_SCALE:
470 dopt = copy_window_scale_option(opt);
472 case TCP_OPTION_TIMESTAMP:
473 dopt = copy_timestamp_option(opt);
476 fnNetSimError(
"Unknown TCP option %d\n", opt->type);
481 PTCPOPTION o = dhdr->option;
494PTCP_SEGMENT_HDR copy_tcp_hdr(PTCP_SEGMENT_HDR hdr)
498 PTCP_SEGMENT_HDR dhdr = (PTCP_SEGMENT_HDR)calloc(1,
sizeof * dhdr);
499 memcpy(dhdr, hdr,
sizeof * dhdr);
500 copy_tcp_option(dhdr, hdr);
506static void free_tcp_mss_option(PMSS_OPTION mss)
511static void free_tcp_sack_permitted_option(PSACKPERMITTED_OPTION sackPermitted)
516static void free_tcp_extra_option(PEXTRA_OPTION ex)
521static void free_tcp_sack_option(PSACK_OPTION sack)
523 UINT c = get_sack_data_count(sack);
524 for (UINT i = 0; i < c; i++)
526 free(sack->sackData[i]);
528 free(sack->sackData);
532static void free_tcp_window_scale_option(PWsopt opt)
537static void free_tcp_timestamp_option(PTSopt opt)
542static void free_tcp_option(PTCPOPTION opt)
546 PTCPOPTION o = opt->next;
550 case TCP_OPTION_NOOPERATION:
551 free_tcp_extra_option(opt->option);
554 free_tcp_mss_option(opt->option);
556 case TCP_OPTION_SACK_PERMITTED:
557 free_tcp_sack_permitted_option(opt->option);
559 case TCP_OPTION_SACK:
560 free_tcp_sack_option(opt->option);
562 case TCP_OPTION_WINDOW_SCALE:
563 free_tcp_window_scale_option(opt->option);
565 case TCP_OPTION_TIMESTAMP:
566 free_tcp_timestamp_option(opt->option);
569 fnNetSimError(
"Unknown TCP option %d\n", opt->type);
577void free_tcp_hdr(PTCP_SEGMENT_HDR hdr)
579 free_tcp_option(hdr->option);