cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
SimIp4Packet.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2016 -- 2021 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
30 #ifndef _SIM_IP4_PACKET_
31 #define _SIM_IP4_PACKET_
32 
33 #include "nts.hpp"
34 #include "nts_utils.hpp"
35 
36 #include "AxisIp4.hpp"
37 #include "AxisTcp.hpp"
38 #include "AxisUdp.hpp"
39 #include "AxisPsd4.hpp" // [TODO-Create a SimPsd4Packet class]
40 #include "SimIcmpPacket.hpp"
41 #include "SimTcpSegment.hpp"
42 #include "SimUdpDatagram.hpp"
43 
44 
55 class SimIp4Packet {
56 
57  private:
58  int len; // In bytes
59  std::deque<AxisIp4> pktQ; // A double-ended queue to store IP4 chunks
60  const char *myName;
61 
62  // Set the length of this IPv4 packet (in bytes)
63  void setLen(int pktLen) {
64  this->len = pktLen;
65  }
66  // Get the length of this IPv4 packet (in bytes)
67  int getLen() {
68  return this->len;
69  }
70 
71  // Return the front chunk element of the IPv4 packet queue but does not remove it from the queue
72  AxisIp4 front() {
73  return this->pktQ.front();
74  }
75  // Remove the first chunk element of the IPv4 packet queue
76  void pop_front() {
77  this->pktQ.pop_front();
78  }
79  // Add an element at the end of the IPv4 packet queue
80  void push_back(AxisIp4 ipChunk) {
81  this->pktQ.push_back(ipChunk);
82  }
83 
84 
88  Ip4HdrCsum calculateIpHeaderChecksum() {
89  LE_Ip4HdrCsum leIp4HdrCsum;
90  unsigned int csum = 0;
91  int ihl = this->getIpInternetHeaderLength();
92  csum += this->pktQ[0].getLE_TData().range(15, 0); // [ToS|VerIhl]
93  csum += this->pktQ[0].getLE_TData().range(31, 16); // [TotalLength]
94  csum += this->pktQ[0].getLE_TData().range(47, 32); // [Identification]
95  csum += this->pktQ[0].getLE_TData().range(63, 48); // [FragOff|Flags]]
96  ihl -= 2;
97  csum += this->pktQ[1].getLE_TData().range(15, 0); // [Protocol|TTL]
98  // Skip this->pktQ[1].getLE_TData().range(31, 16); // [Header Checksum]
99  csum += this->pktQ[1].getLE_TData().range(47, 32); // [SourceAddrLow]
100  csum += this->pktQ[1].getLE_TData().range(63, 48); // [SourceAddrHigh]
101  ihl -= 2;
102  csum += this->pktQ[2].getLE_TData().range(15, 0); // [DestinAddrLow]
103  csum += this->pktQ[2].getLE_TData().range(31, 16); // [DestinAddrHigh]
104  ihl -= 1;
105  // Accumulates options
106  int qw = 2;
107  bool incRaw = true;
108  while (ihl) {
109  if (incRaw) {
110  csum += this->pktQ[qw].getLE_TData().range(47, 32);
111  csum += this->pktQ[qw].getLE_TData().range(63, 48);
112  ihl--;
113  incRaw = false;
114  qw++;
115  }
116  else {
117  csum += this->pktQ[qw].getLE_TData().range(15, 0);
118  csum += this->pktQ[qw].getLE_TData().range(31, 16);
119  ihl--;
120  incRaw = true;
121  }
122  }
123  while (csum > 0xFFFF) {
124  csum = (csum & 0xFFFF) + (csum >> 16);
125  }
126  leIp4HdrCsum = ~csum;
127  return byteSwap16(leIp4HdrCsum);
128  }
129 
130 
136  int checksumCalculation(deque<AxisPsd4> pseudoPacket) {
137  ap_uint<32> ipChecksum = 0;
138  for (int i=0; i<pseudoPacket.size(); ++i) {
139  ap_uint<64> tempInput = 0;
140  ap_uint<64> toto = (pseudoPacket[i].getLE_TData().range( 7, 0),
141  pseudoPacket[i].getLE_TData().range(15, 8),
142  pseudoPacket[i].getLE_TData().range(23, 16),
143  pseudoPacket[i].getLE_TData().range(31, 24),
144  pseudoPacket[i].getLE_TData().range(39, 32),
145  pseudoPacket[i].getLE_TData().range(47, 40),
146  pseudoPacket[i].getLE_TData().range(55, 48),
147  pseudoPacket[i].getLE_TData().range(63, 56));
148  for (int b=0; b<8; b++) {
149  if (pseudoPacket[i].getLE_TKeep()[b]) {
150  tempInput(63-((b*8)+0), 63-((b*8)+7)) = pseudoPacket[i].getLE_TData().range((b*8)+7, (b*8)+0);
151  }
152  }
153  ipChecksum = ((((ipChecksum +
154  tempInput.range(63, 48)) + tempInput.range(47, 32)) +
155  tempInput.range(31, 16)) + tempInput.range(15, 0));
156  ipChecksum = (ipChecksum & 0xFFFF) + (ipChecksum >> 16);
157  ipChecksum = (ipChecksum & 0xFFFF) + (ipChecksum >> 16);
158  }
159  // Reverse the bits of the result
160  ipChecksum = ~ipChecksum;
161  return ipChecksum.range(15, 0).to_int();
162  }
163 
164 
172  void tcpAssemblePseudoHeaderAndData(deque<AxisPsd4> &tcpBuffer) {
173  int ipPktLen = this->getIpTotalLength();
174  int tcpDataLen = ipPktLen - (4 * this->getIpInternetHeaderLength());
175 
176  // Create 1st pseudo-header chunk - [IP_SA|IP_DA]
177  AxisPsd4 firstAxisPsd4(0, 0xFF, 0);
178  firstAxisPsd4.setPsd4SrcAddr(this->getIpSourceAddress());
179  firstAxisPsd4.setPsd4DstAddr(this->getIpDestinationAddress());
180  tcpBuffer.push_back(firstAxisPsd4);
181 
182  // Create 2nd pseudo-header chunk - [0x00|Prot|Length|TC_SP|TCP_DP]
183  AxisPsd4 secondAxisPsd4(0, 0xFF, 0);
184  secondAxisPsd4.setPsd4ResBits(0x00);
185  secondAxisPsd4.setPsd4Prot(this->getIpProtocol());
186  secondAxisPsd4.setPsd4Len(tcpDataLen);
187  secondAxisPsd4.setTcpSrcPort(this->getTcpSourcePort());
188  secondAxisPsd4.setTcpDstPort(this->getTcpDestinationPort());
189  tcpBuffer.push_back(secondAxisPsd4);
190 
191  // Clear the Checksum of the current packet before continuing building the pseudo header
192  this->setTcpChecksum(0x000);
193 
194  // Now, append the content of the TCP segment
195  for (int i=2; i<pktQ.size()-1; ++i) {
196  AxisPsd4 axisPsd4(this->pktQ[i+1].getLE_TData(),
197  this->pktQ[i+1].getLE_TKeep(),
198  this->pktQ[i+1].getLE_TLast());
199  tcpBuffer.push_back(axisPsd4);
200  }
201  }
202 
203  public:
204 
205  // Default Constructor
207  this->myName = "SimIp4Packet";
208  this->len = 0;
209  }
210  // Construct a packet of length 'pktLen' (must be > 20) and header length 'hdrLen'.
211  SimIp4Packet(int pktLen, int hdrLen=IP4_HEADER_LEN) {
212  this->myName = "SimIp4Packet";
213  setLen(0);
214  if (pktLen >= hdrLen && pktLen <= MTU) {
215  int noBytes = pktLen;
216  while(noBytes > 8) {
217  pushChunk(AxisIp4(0x0000000000000000, 0xFF, 0));
218  noBytes -= 8;
219  }
220  pushChunk(AxisIp4(0x0000000000000000, lenToLE_tKeep(noBytes), TLAST));
221  // Set all the default IP packet fields.
222  setIpInternetHeaderLength(hdrLen/4);
223  setIpVersion(4);
225  setIpTotalLength(this->length());
228  setIpFlags(0);
229  setIpTimeToLive(255);
230  setIpProtocol(0);
232  // Set all the default TCP segment fields
233  setTcpDataOffset(5);
234  }
235  else {
236  // [TODO-ThrowException]
237  }
238  }
239 
240  // Add a chunk of bytes at the end of the double-ended queue
241  void pushChunk(AxisIp4 ip4Chunk) {
242  if (this->size() > 0) {
243  // Always clear 'TLAST' bit of previous chunck
244  this->pktQ[this->size()-1].setTLast(0);
245  }
246  this->push_back(ip4Chunk);
247  setLen(getLen() + ip4Chunk.getLen());
248  }
249 
250  // Return the chunk of bytes at the front of the queue and remove that chunk from the queue
252  AxisIp4 headingChunk = this->front();
253  this->pop_front();
254  setLen(getLen() - headingChunk.getLen());
255  return headingChunk;
256  }
257 
258  // Return the length of the IPv4 packet (in bytes)
259  int length() {
260  return this->len;
261  }
262 
263  // Return the number of chunks in the IPv4 packet (in AxisRaw chunks)
264  int size() {
265  return this->pktQ.size();
266  }
267 
268  // Clear the content of the IPv4 packet queue
269  void clear() {
270  this->pktQ.clear();
271  this->len = 0;
272  }
273 
274 
278  void clone(SimIp4Packet &ipPkt) {
279  AxisIp4 newAxisIp4;
280  for (int i=0; i<ipPkt.pktQ.size(); i++) {
281  newAxisIp4 = ipPkt.pktQ[i];
282  this->pktQ.push_back(newAxisIp4);
283  }
284  this->setLen(ipPkt.getLen());
285  }
286 
287 
291  void cloneHeader(SimIp4Packet &ipPkt) {
292  int hdrLen = ipPkt.getIpInternetHeaderLength() * 4; // in bytes
293  if (hdrLen > 0 && hdrLen <= MTU) {
294  int cloneBytes = hdrLen;
295  int inpWordCnt = 0;
296  while(cloneBytes > 0) {
297  if (cloneBytes > 8) {
298  this->pushChunk(ipPkt.pktQ[inpWordCnt]);
299  }
300  else {
301  AxisIp4 lastHdrWord(ipPkt.pktQ[inpWordCnt].getLE_TData(),
302  lenToLE_tKeep(cloneBytes), TLAST);
303  this->pushChunk(lastHdrWord);
304  }
305  cloneBytes -= 8;
306  inpWordCnt++;
307  }
308  }
309  }
310 
311  //*********************************************************
312  //** IPV4 PACKET FIELDS - SETTERS and GETTERS
313  //*********************************************************
314  // Set the IP Version field
315  void setIpVersion(int version) { pktQ[0].setIp4Version(version);}
316  // Get the IP Version field
317  int getIpVersion() { return pktQ[0].getIp4Version(); }
318  // Set the IP Internet Header Length field
319  void setIpInternetHeaderLength(int ihl) { pktQ[0].setIp4HdrLen(ihl); }
320  // Get the IP Internet Header Length field
321  int getIpInternetHeaderLength() { return pktQ[0].getIp4HdrLen(); }
322  // Set the IP Type of Service field
323  void setIpTypeOfService(int tos) { pktQ[0].setIp4ToS(tos); }
324  // Get the IP Type of Service field
325  int getIpTypeOfService() { return pktQ[0].getIp4ToS(); }
326  // Set the IP Total Length field
327  void setIpTotalLength(int totLen) { pktQ[0].setIp4TotalLen(totLen);}
328  // Get the IP Total Length field
329  int getIpTotalLength() { return pktQ[0].getIp4TotalLen(); }
330  // Set the IP Identification field
331  void setIpIdentification(int id) { pktQ[0].setIp4Ident(id); }
332  // Get the IP Identification field
333  int getIpIdentification() { return pktQ[0].getIp4Ident(); }
334  // Set the IP Fragment Offset field
335  void setIpFragmentOffset(int offset) { pktQ[0].setIp4FragOff(offset); }
336  // Get the IP Fragment Offset field
337  int getIpFragmentOffset() { return pktQ[0].getIp4FragOff(); }
338  // Set the IP Flags field
339  void setIpFlags(int flags) { pktQ[0].setIp4Flags(flags); }
340  // Set the IP Time To Live field
341  void setIpTimeToLive(Ip4TtL ttl) { pktQ[1].setIp4TtL(ttl); }
342  // Get the IP Time To Live field
343  int getIpTimeToLive() { return pktQ[1].getIp4TtL(); }
344  // Set the IP Protocol field
345  void setIpProtocol(int prot) { pktQ[1].setIp4Prot(prot); }
346  // Get the IP Protocol field
347  int getIpProtocol() { return pktQ[1].getIp4Prot(); }
348  // Set the IP Header Checksum field
349  void setIpHeaderChecksum(int csum) { pktQ[1].setIp4HdrCsum(csum); }
350  // Get the IP Header Checksum field
351  Ip4HdrCsum getIpHeaderChecksum() { return pktQ[1].getIp4HdrCsum(); }
352  // Set the IP Source Address field
353  void setIpSourceAddress(int addr) { pktQ[1].setIp4SrcAddr(addr); }
354  // Get the IP Source Address field
355  Ip4Addr getIpSourceAddress() { return pktQ[1].getIp4SrcAddr(); }
356  LE_Ip4Addr getLE_IpSourceAddress() { return pktQ[1].getLE_Ip4SrcAddr(); }
357  // Set the IP Destination Address field
358  void setIpDestinationAddress(int addr) { pktQ[2].setIp4DstAddr(addr); }
359  // Get the IP Destination Address field
360  Ip4Addr getIpDestinationAddress() { return pktQ[2].getIp4DstAddr(); }
361  LE_Ip4Addr getLE_IpDestinationAddress() { return pktQ[2].getLE_Ip4DstAddr(); }
362 
363  //*********************************************************
364  //** TCP SEGMENT FIELDS - SETTERS and GETTERS
365  //*********************************************************
366  // Set-Get the TCP Source Port field
367  void setTcpSourcePort(int port) { pktQ[2].setTcpSrcPort(port); }
368  int getTcpSourcePort() { return pktQ[2].getTcpSrcPort(); }
369  LE_TcpPort getLE_TcpSourcePort() { return pktQ[2].getLE_TcpSrcPort(); }
370  // Set-Get the TCP Destination Port field
371  void setTcpDestinationPort(int port) { pktQ[2].setTcpDstPort(port); }
372  int getTcpDestinationPort() { return pktQ[2].getTcpDstPort(); }
373  LE_TcpPort getLE_TcpDestinationPort() { return pktQ[2].getLE_TcpDstPort(); }
374  // Set-Get the TCP Sequence Number field
375  void setTcpSequenceNumber(TcpSeqNum num) { pktQ[3].setTcpSeqNum(num); }
376  TcpSeqNum getTcpSequenceNumber() { return pktQ[3].getTcpSeqNum(); }
377  // Set the TCP Acknowledgment Number
378  void setTcpAcknowledgeNumber(TcpAckNum num){ pktQ[3].setTcpAckNum(num); }
379  TcpAckNum getTcpAcknowledgeNumber() { return pktQ[3].getTcpAckNum(); }
380  // Set-Get the TCP Data Offset field
381  void setTcpDataOffset(int offset) { pktQ[4].setTcpDataOff(offset); }
382  int getTcpDataOffset() { return pktQ[4].getTcpDataOff(); }
383  // Set-Get the TCP Control Bits
384  void setTcpControlFin(int bit) { pktQ[4].setTcpCtrlFin(bit); }
385  TcpCtrlBit getTcpControlFin() { return pktQ[4].getTcpCtrlFin(); }
386  void setTcpControlSyn(int bit) { pktQ[4].setTcpCtrlSyn(bit); }
387  TcpCtrlBit getTcpControlSyn() { return pktQ[4].getTcpCtrlSyn(); }
388  void setTcpControlRst(int bit) { pktQ[4].setTcpCtrlRst(bit); }
389  TcpCtrlBit getTcpControlRst() { return pktQ[4].getTcpCtrlRst(); }
390  void setTcpControlPsh(int bit) { pktQ[4].setTcpCtrlPsh(bit); }
391  TcpCtrlBit getTcpControlPsh() { return pktQ[4].getTcpCtrlPsh(); }
392  void setTcpControlAck(int bit) { pktQ[4].setTcpCtrlAck(bit); }
393  TcpCtrlBit getTcpControlAck() { return pktQ[4].getTcpCtrlAck(); }
394  void setTcpControlUrg(int bit) { pktQ[4].setTcpCtrlUrg(bit); }
395  TcpCtrlBit getTcpControlUrg() { return pktQ[4].getTcpCtrlUrg(); }
396  // Set-Get the TCP Window field
397  void setTcpWindow(int win) { pktQ[4].setTcpWindow(win); }
398  int getTcpWindow() { return pktQ[4].getTcpWindow(); }
399  // Set-Get the TCP Checksum field
400  void setTcpChecksum(int csum) { pktQ[4].setTcpChecksum(csum); }
401  int getTcpChecksum() { return pktQ[4].getTcpChecksum(); }
402  // Set-Get the TCP Urgent Pointer field
403  void setTcpUrgentPointer(int ptr) { pktQ[4].setTcpUrgPtr(ptr); }
404  int getTcpUrgentPointer() { return pktQ[4].getTcpUrgPtr(); }
405  // Set-Get the TCP Option fields
406  void setTcpOptionKind(int val) { pktQ[5].setTcpOptKind(val); }
407  int getTcpOptionKind() { return pktQ[5].getTcpOptKind(); }
408  void setTcpOptionMss(int val) { pktQ[5].setTcpOptMss(val); }
409  int getTcpOptionMss() { return pktQ[5].getTcpOptMss(); }
410  // Additional Debug and Utilities Procedures
411 
412  //*********************************************************
413  //** UDP DATAGRAM FIELDS - SETTERS amnd GETTERS
414  //*********************************************************
415  // Set the UDP Source Port field
417  int ihl = this->getIpInternetHeaderLength();
418  int bit = (ihl*4*8) + 0; // Field starts at bit #00
419  int raw = bit/ARW;
420  pktQ[raw].setUdpSrcPort(port, (bit % ARW));
421  }
422  // Get the UDP Source Port field
424  int ihl = this->getIpInternetHeaderLength();
425  int bit = (ihl*4*8) + 0; // Field starts at bit #00
426  int raw = bit/ARW;
427  return pktQ[raw].getUdpSrcPort(bit % ARW);
428  }
429  // Set the UDP Destination Port field
431  int ihl = this->getIpInternetHeaderLength();
432  int bit = (ihl*4*8) + 16; // Field starts at bit #16
433  int raw = bit/ARW;
434  pktQ[raw].setUdpDstPort(port, (bit % ARW));
435  }
436  // Get the UDP Destination Port field
438  int ihl = this->getIpInternetHeaderLength();
439  int bit = (ihl*4*8) + 16; // Field starts at bit #16
440  int raw = bit/ARW;
441  return pktQ[raw].getUdpDstPort(bit % ARW);
442  }
443  // Set the UDP Length field
444  void setUdpLength(UdpLen len) {
445  int ihl = this->getIpInternetHeaderLength();
446  int bit = (ihl*4*8) + 32; // Field starts at bit #32
447  int raw = bit/ARW;
448  }
449  // Get the UDP Length field
451  int ihl = this->getIpInternetHeaderLength();
452  int bit = (ihl*4*8) + 32; // Field starts at bit #32
453  int raw = bit/ARW;
454  return pktQ[raw].getUdpLen(bit % ARW);
455  }
456  // Set the UDP Checksum field
457  void setUdpChecksum(UdpCsum csum) {
458  int ihl = this->getIpInternetHeaderLength();
459  int bit = (ihl*4*8) + 48; // Field starts at bit #48
460  int raw = bit/ARW;
461  pktQ[raw].setUdpCsum(csum, (bit % ARW));
462  }
463  // Get the UDP Checksum field
465  int ihl = this->getIpInternetHeaderLength();
466  int bit = (ihl*4*8) + 48; // Field starts at bit #48
467  int raw = bit/ARW;
468  return pktQ[raw].getUdpCsum(bit % ARW);
469  }
470 
471  // Return the IP4 header as a string
472  string getIpHeader() {
473  int q = 0;
474  string headerStr;
475  int hl = this->getIpInternetHeaderLength() * 4; // in bytes
476  while (hl != 0) {
477  for (int b=0; b<8; b++) {
478  unsigned char valByte = ((pktQ[q].getLE_TKeep().to_uchar() >> (1*b)) & 0x01);
479  unsigned char datByte = ((pktQ[q].getLE_TData().to_ulong() >> (8*b)) & 0xFF);
480  if (valByte) {
481  headerStr += datByte;
482  }
483  if (hl == 0) {
484  break;
485  }
486  hl--;
487  }
488  q += 1;
489  }
490  return headerStr;
491  }
492 
493  // Return the IP4 data payload as a string
494  string getIpPayload() {
495  string payloadStr;
496  int hdrLen = this->getIpInternetHeaderLength() * 4; // in bytes
497  int totLen = this->getIpTotalLength();
498  int pldLen = totLen - hdrLen;
499  int q = (hdrLen / 8);
500  int b = (hdrLen % 8);
501  while (pldLen != 0) {
502  while (b <= 7) {
503  unsigned char valByte = ((pktQ[q].getLE_TKeep().to_uchar() >> (1*b)) & 0x01);
504  unsigned char datByte = ((pktQ[q].getLE_TData().to_ulong() >> (8*b)) & 0xFF);
505  if (valByte) {
506  payloadStr += datByte;
507  pldLen--;
508  }
509  b++;
510  }
511  b = 0;
512  q += 1;
513  }
514  return payloadStr;
515  }
516 
517  // Return the IP4 data payload as an IcmpPacket (assuming IP4 w/o options)
519  SimIcmpPacket icmpPacket;
520  LE_tData newTData = 0;
521  LE_tKeep newTKeep = 0;
522  LE_tLast newTLast = 0;
523  int wordOutCnt = 0;
524  int wordInpCnt = 2; // Skip the 1st two IP4 words
525  bool alternate = true;
526  bool endOfPkt = false;
527  int ip4PktSize = this->size();
528  if (this->getIpInternetHeaderLength() != 5) {
529  printFatal(this->myName, "IPv4 options are not supported yet (sorry)");
530  }
531  while (wordInpCnt < ip4PktSize) {
532  if (endOfPkt) {
533  break;
534  }
535  else if (alternate) {
536  newTData = 0;
537  newTKeep = 0;
538  newTLast = 0;
539  if (this->pktQ[wordInpCnt].getLE_TKeep() & 0x10) {
540  newTData.range( 7, 0) = this->pktQ[wordInpCnt].getLE_TData().range(39, 32);
541  newTKeep = newTKeep | (0x01);
542  }
543  if (this->pktQ[wordInpCnt].getLE_TKeep() & 0x20) {
544  newTData.range(15, 8) = this->pktQ[wordInpCnt].getLE_TData().range(47, 40);
545  newTKeep = newTKeep | (0x02);
546  }
547  if (this->pktQ[wordInpCnt].getLE_TKeep() & 0x40) {
548  newTData.range(23, 16) = this->pktQ[wordInpCnt].getLE_TData().range(55, 48);
549  newTKeep = newTKeep | (0x04);
550  }
551  if (this->pktQ[wordInpCnt].getLE_TKeep() & 0x80) {
552  newTData.range(31, 24) = this->pktQ[wordInpCnt].getLE_TData().range(63, 56);
553  newTKeep = newTKeep | (0x08);
554  }
555  if (this->pktQ[wordInpCnt].getLE_TLast()) {
556  newTLast = TLAST;
557  endOfPkt = true;
558  icmpPacket.pushChunk(AxisIcmp(newTData, newTKeep, newTLast));
559  }
560  alternate = !alternate;
561  wordInpCnt++;
562  }
563  else {
564  if (this->pktQ[wordInpCnt].getLE_TKeep() & 0x01) {
565  newTData.range(39, 32) = this->pktQ[wordInpCnt].getLE_TData().range( 7, 0);
566  newTKeep = newTKeep | (0x10);
567  }
568  if (this->pktQ[wordInpCnt].getLE_TKeep() & 0x02) {
569  newTData.range(47, 40) = this->pktQ[wordInpCnt].getLE_TData().range(15, 8);
570  newTKeep = newTKeep | (0x20);
571  }
572  if (this->pktQ[wordInpCnt].getLE_TKeep() & 0x04) {
573  newTData.range(55, 48) = this->pktQ[wordInpCnt].getLE_TData().range(23, 16);
574  newTKeep = newTKeep | (0x40);
575  }
576  if (this->pktQ[wordInpCnt].getLE_TKeep() & 0x08) {
577  newTData.range(63, 56) = this->pktQ[wordInpCnt].getLE_TData().range(31, 24);
578  newTKeep = newTKeep | (0x80);
579  }
580  if (this->pktQ[wordInpCnt].getLE_TLast() && (not (this->pktQ[wordInpCnt].getLE_TKeep() & 0xC0))) {
581  newTLast = TLAST;
582  endOfPkt = true;
583  }
584  alternate = !alternate;
585  wordOutCnt++;
586  icmpPacket.pushChunk(AxisIcmp(newTData, newTKeep, newTLast));
587  }
588  }
589  return icmpPacket;
590  } // End-of: getIcmpPacket()
591 
592  // Return the IP4 data payload as a UdpDatagram
594  SimUdpDatagram udpDatagram;
595  LE_tData newTData = 0;
596  LE_tKeep newTKeep = 0;
597  LE_tLast newTLast = 0;
598  int wordOutCnt = 0;
599  bool alternate = true;
600  bool endOfPkt = false;
601  int ip4PktSize = this->size();
602  int ihl = this->getIpInternetHeaderLength();
603  int wordInpCnt = ihl/2; // Skip the IP header words
604  bool qwordAligned = (ihl % 2) ? false : true;
605  while (wordInpCnt < ip4PktSize) {
606  if (endOfPkt)
607  break;
608  if (qwordAligned) {
609  newTData = 0;
610  newTKeep = 0;
611  newTLast = 0;
612  for (int i=0; i<8; i++) {
613  if (this->pktQ[wordInpCnt].getLE_TKeep() & (0x01 << i)) {
614  newTData.range((i*8)+7, (i*8)+0) =
615  this->pktQ[wordInpCnt].getLE_TData().range((i*8)+7, (i*8)+0);
616  newTKeep = newTKeep | (0x01 << i);
617  }
618  }
619  newTLast = this->pktQ[wordInpCnt].getLE_TLast();
620  wordInpCnt++;
621  wordOutCnt++;
622  udpDatagram.pushChunk(AxisUdp(newTData, newTKeep, newTLast));
623  }
624  else if (alternate) {
625  //-- Populate the upper-half of a new chunk (.i.e, LE(31, 0))
626  newTData = 0;
627  newTKeep = 0;
628  newTLast = 0;
629  for (int i=0, hi=7, lo=0; i<4; i++) {
630  if (this->pktQ[wordInpCnt].getLE_TKeep() & (0x10<<i)) {
631  newTData.range(hi+8*i, lo+8*i) = this->pktQ[wordInpCnt].getLE_TData().range(32+hi+8*i, 32+lo+8*i);
632  newTKeep = newTKeep | (0x01<<i);
633  }
634  }
635  if (this->pktQ[wordInpCnt].getLE_TLast()) {
636  newTLast = TLAST;
637  endOfPkt = true;
638  udpDatagram.pushChunk(AxisUdp(newTData, newTKeep, newTLast));
639  }
640  alternate = !alternate;
641  wordInpCnt++;
642  }
643  else {
644  //-- Populate the lower-half of a new chunk (.i.e, LE(63,32))
645  for (int i=0, hi=7, lo=0; i<4; i++) {
646  if (this->pktQ[wordInpCnt].getLE_TKeep() & (0x01<<i)) {
647  newTData.range(32+hi+8*i, 32+lo+8*i) = this->pktQ[wordInpCnt].getLE_TData().range(hi+8*i, lo+8*i);
648  newTKeep = newTKeep | (0x10<<i);
649  }
650  }
651  if (this->pktQ[wordInpCnt].getLE_TLast()) {
652  LE_tKeep leTKeep = this->pktQ[wordInpCnt].getLE_TKeep();
653  if (not (leTKeep & 0xF0)) {
654  newTLast = TLAST;
655  endOfPkt = true;
656  }
657  }
658  alternate = !alternate;
659  wordOutCnt++;
660  udpDatagram.pushChunk(AxisUdp(newTData, newTKeep, newTLast));
661  }
662  }
663  return udpDatagram;
664  } // End-of: getUdpDatagram
665 
666  // Return the IP4 data payload as a TcpSegment
668  SimTcpSegment tcpSegment;
669  LE_tData newTData = 0;
670  LE_tKeep newTKeep = 0;
671  LE_tLast newTLast = 0;
672  int wordOutCnt = 0;
673  bool alternate = true;
674  bool endOfPkt = false;
675  int ip4PktSize = this->size();
676  int ihl = this->getIpInternetHeaderLength();
677  int wordInpCnt = ihl/2; // Skip the IP header words
678  bool qwordAligned = (ihl % 2) ? false : true;
679  while (wordInpCnt < ip4PktSize) {
680  if (endOfPkt)
681  break;
682  if (qwordAligned) {
683  newTData = 0;
684  newTKeep = 0;
685  newTLast = 0;
686  for (int i=0; i<8; i++) {
687  if (this->pktQ[wordInpCnt].getLE_TKeep() & (0x01 << i)) {
688  newTData.range((i*8)+7, (i*8)+0) =
689  this->pktQ[wordInpCnt].getLE_TData().range((i*8)+7, (i*8)+0);
690  newTKeep = newTKeep | (0x01 << i);
691  }
692  }
693  newTLast = this->pktQ[wordInpCnt].getLE_TLast();
694  wordInpCnt++;
695  wordOutCnt++;
696  tcpSegment.pushChunk(AxisTcp(newTData, newTKeep, newTLast));
697  }
698  else if (alternate) {
699  //-- Populate the upper-half of a new chunk (.i.e, LE(31, 0))
700  newTData = 0;
701  newTKeep = 0;
702  newTLast = 0;
703  for (int i=0, hi=7, lo=0; i<4; i++) {
704  if (this->pktQ[wordInpCnt].getLE_TKeep() & (0x10<<i)) {
705  newTData.range(hi+8*i, lo+8*i) = this->pktQ[wordInpCnt].getLE_TData().range(32+hi+8*i, 32+lo+8*i);
706  newTKeep = newTKeep | (0x01<<i);
707  }
708  }
709  if (this->pktQ[wordInpCnt].getLE_TLast()) {
710  newTLast = TLAST;
711  endOfPkt = true;
712  tcpSegment.pushChunk(AxisTcp(newTData, newTKeep, newTLast));
713  }
714  alternate = !alternate;
715  wordInpCnt++;
716  }
717  else {
718  //-- Populate the lower-half of a new chunk (.i.e, LE(63,32))
719  for (int i=0, hi=7, lo=0; i<4; i++) {
720  if (this->pktQ[wordInpCnt].getLE_TKeep() & (0x01<<i)) {
721  newTData.range(32+hi+8*i, 32+lo+8*i) = this->pktQ[wordInpCnt].getLE_TData().range(hi+8*i, lo+8*i);
722  newTKeep = newTKeep | (0x10<<i);
723  }
724  }
725  if (this->pktQ[wordInpCnt].getLE_TLast()) {
726  LE_tKeep leTKeep = this->pktQ[wordInpCnt].getLE_TKeep();
727  if (not (leTKeep & 0xF0)) {
728  newTLast = TLAST;
729  endOfPkt = true;
730  }
731  }
732  alternate = !alternate;
733  wordOutCnt++;
734  tcpSegment.pushChunk(AxisTcp(newTData, newTKeep, newTLast));
735  }
736  }
737  return tcpSegment;
738  } // End-of: getTcpSegment
739 
740  // Return the TCP segment length (.i.e, length of IPv4 data when Prot is TCP)
742  if (this->getIpProtocol() != IP4_PROT_TCP) {
743  printFatal(this->myName, "Cannot compute TCP segment length. The current IPv4 packet does not contain any TCP segment (prot=0x%2.2x).\n",
744  this->getIpProtocol());
745  }
746  return (this->getIpTotalLength() - (this->getIpInternetHeaderLength() * 4));
747  }
748 
749 
763  bool addIpPayload(SimUdpDatagram &udpDgm, int len=-1) {
764  bool alternate = true;
765  bool done = false;
766  AxisIp4 axisIp4(0, 0, 0);
767  AxisUdp axisUdp(0, 0, 0);
768  int bits = (this->length() * 8);
769  int axisIp4Cnt = bits/ARW;
770  int axisUdpCnt = 0;
771  bool ipIsQwordAligned = (bits % ARW) ? false : true;
772  int byteCnt = 0;
773 
774  if (this->getLen() < IP4_HEADER_LEN) {
775  printFatal(this->myName, "Minimum packet is expected to be of length %d bytes (was found to be %d bytes).\n",
776  IP4_HEADER_LEN, this->getLen());
777  }
778  if (len == -1) {
779  len = udpDgm.length();
780  }
781  else if (len > udpDgm.length()) {
782  printFatal(this->myName, "Requesting to append more bytes (%d) than present in the UDP datagram (%d).\n",
783  len, udpDgm.length());
784  }
785 
786  // Read and pop the very first chunk from the datagram
787  axisUdp = udpDgm.pullChunk();
788  while (!done) {
789  if (ipIsQwordAligned) {
790  for (int i=0; i<8; i++) {
791  if (axisUdp.getLE_TKeep() & (0x01 << i)) {
792  axisIp4.setLE_TData(axisIp4.getLE_TData() |
793  ((axisUdp.getLE_TData().range((i*8)+7, (i*8)+0)) << (i*8)));
794  axisIp4.setLE_TKeep(axisIp4.getLE_TKeep() | (0x01 << i));
795  byteCnt++;
796  }
797  }
798  axisIp4.setLE_TLast(axisUdp.getLE_TLast());
799  axisUdpCnt++;
800  axisIp4Cnt++;
801  this->pushChunk(axisIp4);
802  if ((axisUdp.getLE_TLast()) or (byteCnt >= len) ) {
803  done = true;
804  }
805  }
806  else {
807  if (alternate) {
808  this->pktQ[axisIp4Cnt].setTDataLo(axisUdp.getTDataHi());
809  this->pktQ[axisIp4Cnt].setTKeepLo(axisUdp.getTKeepHi());
810  if (axisUdp.getTLast() and (axisUdp.getLen() <= 4)) {
811  this->pktQ[axisIp4Cnt].setTLast(TLAST);
812  done = true;
813  }
814  else {
815  this->pktQ[axisIp4Cnt].setTLast(0);
816  }
817  this->setLen(this->getLen() + axisUdp.getLenHi());
818  byteCnt += axisUdp.getLenHi();
819  alternate = !alternate;
820  }
821  else {
822  // Build a new chunk, init its higher-half part with the
823  // lower-half-part of the UDP chunk and push the new chunk
824  // onto the packet queue
825  AxisIp4 newChunk(0, 0, 0);
826  newChunk.setTDataHi(axisUdp.getTDataLo());
827  newChunk.setTKeepHi(axisUdp.getTKeepLo());
828  byteCnt += axisUdp.getLenLo();
829  if ((axisUdp.getTLast()) or (byteCnt >= len) ) {
830  newChunk.setTLast(TLAST);
831  done = true;
832  }
833  else {
834  newChunk.setTLast(0);
835  axisIp4Cnt++;
836  // Read and pop a new chunk from the UDP datagram
837  axisUdp = udpDgm.pullChunk();
838  }
839  this->pushChunk(newChunk);
840  axisUdpCnt++;
841  alternate = !alternate;
842  }
843  }
844  } // End-of while(!endOfDgm)
846  return true;
847  } // End-of: addIpPayload(UdpDatagram udpDgm)
848 
849 
859  bool addIpPayload(SimIcmpPacket icmpPkt) {
860  bool alternate = true;
861  bool endOfPkt = false;
862  AxisIcmp axisIcmp(0, 0, 0);
863  int axisIcmpCnt = 0;
864  int axisIp4Cnt = 2; // Start with the 2nd word which contains IP_DA
865  if (this->getLen() != IP4_HEADER_LEN) {
866  printFatal(this->myName, "Packet is expected to be of length %d bytes (was found to be %d bytes).\n",
867  IP4_HEADER_LEN, this->getLen());
868  }
869  // Read and pop the very first chunk from the packet
870  axisIcmp = icmpPkt.pullChunk();
871  while (!endOfPkt) {
872  if (alternate) {
873  LE_tData tmpTData = this->pktQ[axisIp4Cnt].getLE_TData();
874  LE_tKeep tmpTKeep = this->pktQ[axisIp4Cnt].getLE_TKeep();
875  LE_tLast tmpTLast = this->pktQ[axisIp4Cnt].getLE_TLast();
876  if (axisIcmp.getLE_TKeep() & 0x01) {
877  tmpTData.range(39,32) = axisIcmp.getLE_TData().range( 7, 0);
878  tmpTKeep = tmpTKeep | 0x10;
879  this->setLen(this->getLen() + 1);
880  }
881  if (axisIcmp.getLE_TKeep() & 0x02) {
882  tmpTData.range(47,40) = axisIcmp.getLE_TData().range(15, 8);
883  tmpTKeep = tmpTKeep | 0x20;
884  this->setLen(this->getLen() + 1);
885  }
886  if (axisIcmp.getLE_TKeep() & 0x04) {
887  tmpTData.range(55,48) = axisIcmp.getLE_TData().range(23,16);
888  tmpTKeep = tmpTKeep | 0x40;
889  this->setLen(this->getLen() + 1);
890  }
891  if (axisIcmp.getLE_TKeep() & 0x08) {
892  tmpTData.range(63,56) = axisIcmp.getLE_TData().range(31,24);
893  tmpTKeep = tmpTKeep | 0x80;
894  this->setLen(this->getLen() + 1);
895  }
896  if ((axisIcmp.getLE_TLast()) && (axisIcmp.getLE_TKeep() <= 0x0F)) {
897  tmpTLast = TLAST;
898  endOfPkt = true;
899  }
900  else {
901  tmpTLast = 0;
902  }
903  this->pktQ[axisIp4Cnt].setLE_TData(tmpTData);
904  this->pktQ[axisIp4Cnt].setLE_TKeep(tmpTKeep);
905  this->pktQ[axisIp4Cnt].setLE_TLast(tmpTLast);
906  alternate = !alternate;
907  }
908  else {
909  // Build a new chunck and add it to the queue
910  LE_tData newTData = 0;
911  LE_tKeep newTKeep = 0;
912  LE_tLast newTLast = 0;
913  if (axisIcmp.getLE_TKeep() & 0x10) {
914  newTData.range( 7, 0) = axisIcmp.getLE_TData().range(39, 32);
915  newTKeep = newTKeep | (0x01);
916  }
917  if (axisIcmp.getLE_TKeep() & 0x20) {
918  newTData.range(15, 8) = axisIcmp.getLE_TData().range(47, 40);
919  newTKeep = newTKeep | (0x02);
920  }
921  if (axisIcmp.getLE_TKeep() & 0x40) {
922  newTData.range(23,16) = axisIcmp.getLE_TData().range(55, 48);
923  newTKeep = newTKeep | (0x04);
924  }
925  if (axisIcmp.getLE_TKeep() & 0x80) {
926  newTData.range(31,24) = axisIcmp.getLE_TData().range(63, 56);
927  newTKeep = newTKeep | (0x08);
928  }
929  // Done with the incoming ICMP word
930  axisIcmpCnt++;
931 
932  if (axisIcmp.getLE_TLast()) {
933  newTLast = TLAST;
934  this->pushChunk(AxisIp4(newTData, newTKeep, newTLast));
935  endOfPkt = true;
936  }
937  else {
938  newTLast = 0;
939  this->pushChunk(AxisIp4(newTData, newTKeep, newTLast));
940  axisIp4Cnt++;
941  // Read and pop a new chunk from the ICMP packet
942  axisIcmp = icmpPkt.pullChunk();
943  }
944  alternate = !alternate;
945  }
946  } // End-of while(!endOfPkt)
948  return true;
949  } // End-of: addIpPayload
950 
951 
959  bool setIpPayload(SimIcmpPacket icmpPkt) {
960  bool alternate = true;
961  bool endOfPkt = false;
962  AxisIcmp axisIcmp(0, 0, 0);
963  int axisIcmpCnt = 0;
964  int axisIp4Cnt = 2; // Start with the 2nd word which contains IP_DA
965 
966  if ((this->getLen() - IP4_HEADER_LEN) < icmpPkt.length()) {
967  printFatal(this->myName, "Packet length is expected to be larger than %d bytes (was found to be %d bytes).\n",
968  (IP4_HEADER_LEN+icmpPkt.length()), this->getLen());
969  }
970  // Read and pop the very first chunk from the ICMP packet
971  axisIcmp = icmpPkt.pullChunk();
972 
973  while (!endOfPkt) {
974  if (alternate) {
975  LE_tData tmpTData = this->pktQ[axisIp4Cnt].getLE_TData();
976  LE_tKeep tmpTKeep = this->pktQ[axisIp4Cnt].getLE_TKeep();
977  LE_tLast tmpTLast = this->pktQ[axisIp4Cnt].getLE_TLast();
978  if (axisIcmp.getLE_TKeep() & 0x01) {
979  tmpTData.range(39,32) = axisIcmp.getLE_TData().range( 7, 0);
980  tmpTKeep = tmpTKeep | (0x10);
981  this->setLen(this->getLen() + 1);
982  }
983  if (axisIcmp.getLE_TKeep() & 0x02) {
984  tmpTData.range(47,40) = axisIcmp.getLE_TData().range(15, 8);
985  tmpTKeep = tmpTKeep | (0x20);
986  this->setLen(this->getLen() + 1);
987  }
988  if (axisIcmp.getLE_TKeep() & 0x04) {
989  tmpTData.range(55,48) = axisIcmp.getLE_TData().range(23,16);
990  tmpTKeep = tmpTKeep | (0x40);
991  this->setLen(this->getLen() + 1);
992  }
993  if (axisIcmp.getLE_TKeep() & 0x08) {
994  tmpTData.range(63,56) = axisIcmp.getLE_TData().range(31,24);
995  tmpTKeep = tmpTKeep | (0x80);
996  this->setLen(this->getLen() + 1);
997  }
998  if ((axisIcmp.getLE_TLast()) && (axisIcmp.getLE_TKeep() <= 0x0F)) {
999  tmpTLast = TLAST;
1000  endOfPkt = true;
1001  }
1002  else {
1003  tmpTLast = 0;
1004  }
1005  this->pktQ[axisIp4Cnt].setLE_TData(tmpTData);
1006  this->pktQ[axisIp4Cnt].setLE_TKeep(tmpTKeep);
1007  this->pktQ[axisIp4Cnt].setLE_TLast(tmpTLast);
1008  alternate = !alternate;
1009  axisIp4Cnt++;
1010  }
1011  else {
1012  LE_tData tmpTData = this->pktQ[axisIp4Cnt].getLE_TData();
1013  LE_tKeep tmpTKeep = this->pktQ[axisIp4Cnt].getLE_TKeep();
1014  LE_tLast tmpTLast = this->pktQ[axisIp4Cnt].getLE_TLast();
1015  if (axisIcmp.getLE_TKeep() & 0x10) {
1016  tmpTData.range( 7, 0) = axisIcmp.getLE_TData().range(39, 32);
1017  tmpTKeep = tmpTKeep | (0x01);
1018  }
1019  if (axisIcmp.getLE_TKeep() & 0x20) {
1020  tmpTData.range(15, 8) = axisIcmp.getLE_TData().range(47, 40);
1021  tmpTKeep = tmpTKeep | (0x02);
1022  }
1023  if (axisIcmp.getLE_TKeep() & 0x40) {
1024  tmpTData.range(23,16) = axisIcmp.getLE_TData().range(55, 48);
1025  tmpTKeep = tmpTKeep | (0x04);
1026  }
1027  if (axisIcmp.getLE_TKeep() & 0x80) {
1028  tmpTData.range(31,24) = axisIcmp.getLE_TData().range(63, 56);
1029  tmpTKeep = tmpTKeep | (0x08);
1030  }
1031  // Done with the incoming ICMP word
1032  axisIcmpCnt++;
1033 
1034  if (axisIcmp.getLE_TLast()) {
1035  tmpTLast = TLAST;
1036  endOfPkt = true;
1037  }
1038  else {
1039  tmpTLast = 0;
1040  // Read and pop a new chunk from the ICMP packet
1041  axisIcmp = icmpPkt.pullChunk();
1042  }
1043  this->pktQ[axisIp4Cnt].setLE_TData(tmpTData);
1044  this->pktQ[axisIp4Cnt].setLE_TKeep(tmpTKeep);
1045  this->pktQ[axisIp4Cnt].setLE_TLast(tmpTLast);
1046  alternate = !alternate;
1047  }
1048  } // End-of while(!endOfPkt)
1049  return true;
1050  } // End-of: setIpPayload
1051 
1052  // [TODO]-Return the IP4 data payload as a TcpSegment
1053  // [TODO] TcpSegment getTcpSegment() {}
1054 
1055 
1059  string getTcpData() {
1060  string tcpDataStr = "";
1061  int tcpDataSize = this->sizeOfTcpData();
1062 
1063  if(tcpDataSize > 0) {
1064  int ip4DataOffset = (4 * this->getIpInternetHeaderLength());
1065  int tcpDataOffset = ip4DataOffset + (4 * this->getTcpDataOffset());
1066  int bytCnt = 0;
1067 
1068  for (int chunkNum=0; chunkNum<this->pktQ.size(); chunkNum++) {
1069  for (int bytNum=0; bytNum<8; bytNum++) {
1070  if ((bytCnt >= tcpDataOffset) & (bytCnt < (tcpDataOffset + tcpDataSize))) {
1071  if (this->pktQ[chunkNum].getLE_TKeep().bit(bytNum)) {
1072  int hi = ((bytNum*8) + 7);
1073  int lo = ((bytNum*8) + 0);
1074  ap_uint<8> octet = this->pktQ[chunkNum].getLE_TData().range(hi, lo);
1075  tcpDataStr += myUint8ToStrHex(octet);
1076  }
1077  }
1078  bytCnt++;
1079  }
1080  }
1081  }
1082  return tcpDataStr;
1083  }
1084 
1085 
1088  bool isFIN() {
1089  if (this->getTcpControlFin())
1090  return true;
1091  else
1092  return false;
1093  }
1094 
1095 
1098  bool isSYN() {
1099  if (this->getTcpControlSyn())
1100  return true;
1101  else
1102  return false;
1103  }
1104 
1105 
1108  bool isACK() {
1109  if (this->getTcpControlAck())
1110  return true;
1111  else
1112  return false;
1113  }
1114 
1115 
1116  // [TODO] bool isRST();
1117  // [TODO] bool isPSH();
1118  // [TODO] bool isURG();
1119 
1120 
1129  bool isWellFormed(const char *callerName,
1130  bool checkIp4TotLen=true, bool checkIp4HdrCsum=true,
1131  bool checkUdpLen=true, bool checkLy4Csum=true) {
1132  bool rc = true;
1133  if (checkIp4TotLen) {
1134  if (this->getIpTotalLength() != this->getLen()) {
1135  printError(callerName, "Malformed IPv4 packet: 'Total Length' field does not match the length of the packet.\n");
1136  printError(callerName, "\tFound Total Length field=0x%4.4X, Was expecting 0x%4.4X)\n",
1137  this->getIpTotalLength(), this->getLen());
1138  rc = false;
1139  }
1140  }
1141  if (checkIp4HdrCsum) {
1142  if (this->getIpHeaderChecksum() != this->calculateIpHeaderChecksum()) {
1143  if (this->getIpHeaderChecksum() == 0) {
1144  printWarn(callerName, "Malformed IPv4 packet: 'Header Checksum' field does not match the computed header checksum.\n");
1145  printWarn(callerName, "\tFound Header Checksum field=0x%4.4X, Was expecting 0x%4.4X)\n",
1146  this->getIpHeaderChecksum().to_ushort(), this->calculateIpHeaderChecksum().to_ushort());
1147  printWarn(callerName, "\t[1] You should disable this checking if the IP packet is generated by the TOE because the header checksum will be computed and inserted later by IPTX.\n");
1148  printWarn(callerName, "\t[2] Otherwise, you can also disable this checking if you want to skip computing and providing the IP header checksum in your test vectors files.\n");
1149  }
1150  else {
1151  printError(callerName, "Malformed IPv4 packet: 'Header Checksum' field does not match the computed header checksum.\n");
1152  printError(callerName, "\tFound Header Checksum field=0x%4.4X, Was expecting 0x%4.4X)\n",
1153  this->getIpHeaderChecksum().to_ushort(), this->calculateIpHeaderChecksum().to_ushort());
1154  rc = false;
1155  }
1156  }
1157  }
1158  if (this->getIpProtocol() == IP4_PROT_UDP) {
1159  // Asses UDP datagram
1160  SimUdpDatagram udpDatagram = this->getUdpDatagram();
1161  if (checkUdpLen) {
1162  UdpLen udpHLen = this->getUdpLength();
1163  int calcLen = udpDatagram.length();
1164  if (udpHLen != calcLen) {
1165  printError(callerName, "Malformed IPv4 packet: UDP 'Length' field does not match the length of the datagram.\n");
1166  printError(callerName, "\tFound IPV4/UDP/Length field=0x%4.4X, Was expecting 0x%4.4X)\n",
1167  udpHLen.to_uint(), calcLen);
1168  rc = false;
1169  }
1170  }
1171  if (checkLy4Csum) {
1172  UdpCsum udpHCsum = this->getUdpChecksum();
1173  UdpCsum calcCsum = udpDatagram.reCalculateUdpChecksum( \
1174  this->getIpSourceAddress(),
1175  this->getIpDestinationAddress());
1176  if ((udpHCsum != 0) and (udpHCsum != calcCsum)) {
1177  // UDP datagram comes with an invalid checksum
1178  printError(callerName, "Malformed IPv4 packet: UDP 'Checksum' field does not match the checksum of the pseudo-packet.\n");
1179  printError(callerName, "\tFound IPv4/UDP/Checksum field=0x%4.4X, Was expecting 0x%4.4X)\n",
1180  udpHCsum.to_uint(), calcCsum.to_ushort());
1181  if (udpHCsum == 0xDEAD) {
1182  printWarn(callerName, "This will not be considered an error but an intentional corrupted checksum inserted by the user for testing purpose.\n");
1183  }
1184  else {
1185  rc = false;
1186  }
1187  }
1188  }
1189  }
1190  else if (this->getIpProtocol() == IP4_PROT_TCP) {
1191  // Asses TCP segment
1192  SimTcpSegment tcpSegment = this->getTcpSegment();
1193  if (0) { tcpSegment.dump(); }
1194  if (checkLy4Csum) {
1195  // Assess IPv4/TCP/Checksum field vs segment checksum
1196  TcpCsum tcpHCsum = this->getTcpChecksum();
1197  TcpCsum calcCsum = tcpSegment.reCalculateTcpChecksum(this->getIpSourceAddress(),
1198  this->getIpDestinationAddress(),
1199  this->getTcpSegmentLength());
1200  if (tcpHCsum != calcCsum) {
1201  // TCP segment comes with an invalid checksum
1202  printError(callerName, "Malformed IPv4 packet: TCP 'Checksum' field does not match the checksum of the pseudo-packet.\n");
1203  printError(callerName, "\tFound IPv4/TCP/Checksum field=0x%4.4X, Was expecting 0x%4.4X)\n",
1204  tcpHCsum.to_uint(), calcCsum.to_ushort());
1205  if (tcpHCsum == 0xDEAD) {
1206  printWarn(callerName, "This will not be considered an error but an intentional corrupted checksum inserted by the user for testing purpose.\n");
1207  }
1208  else {
1209  rc = false;
1210  }
1211  }
1212  }
1213  }
1214  else if (this->getIpProtocol() == IP4_PROT_ICMP) {
1215  // Asses ICMP packet
1216  printWarn(myName, "[TODO-Must check if message is well-formed !!!\n");
1217  }
1218  return rc;
1219  }
1220 
1221 
1225  void printHdr(const char *callerName) {
1226  LE_Ip4TotalLen leIp4TotalLen = byteSwap16(this->getIpTotalLength());
1227  LE_Ip4SrcAddr leIp4SrcAddr = byteSwap32(this->getIpSourceAddress());
1228  LE_Ip4DstAddr leIp4DstAddr = byteSwap32(this->getIpDestinationAddress());
1229 
1230  LE_TcpSrcPort leTcpSrcPort = byteSwap16(this->getTcpSourcePort());
1231  LE_TcpDstPort leTcpDstPort = byteSwap16(this->getTcpDestinationPort());
1232  LE_TcpSeqNum leTcpSeqNum = byteSwap32(this->getTcpSequenceNumber());
1233  LE_TcpAckNum leTcpAckNum = byteSwap32(this->getTcpAcknowledgeNumber());
1234 
1235  LE_TcpWindow leTcpWindow = byteSwap16(this->getTcpWindow());
1236  LE_TcpChecksum leTcpCSum = byteSwap16(this->getTcpChecksum());
1237  LE_TcpUrgPtr leTcpUrgPtr = byteSwap16(this->getTcpUrgentPointer());
1238 
1239  printInfo(callerName, "IP PACKET HEADER (HEX numbers are in LITTLE-ENDIAN order): \n");
1240  printInfo(callerName, "IP4 IHL = %15u \n",
1241  this->getIpInternetHeaderLength());
1242  printInfo(callerName, "IP4 Version = %15u \n",
1243  this->getIpVersion());
1244  printInfo(callerName, "IP4 Type Of Service = %15u \n",
1245  this->getIpTypeOfService());
1246  printInfo(callerName, "IP4 Total Length = %15u (0x%4.4X) \n",
1247  this->getIpTotalLength(), leIp4TotalLen.to_uint());
1248  printInfo(callerName, "IP4 Identification = %15u \n",
1249  this->getIpIdentification());
1250  printInfo(callerName, "IP4 Fragment Offset = %15u \n",
1251  this->getIpFragmentOffset());
1252  printInfo(callerName, "IP4 Type To Live = %15u \n",
1253  this->getIpTimeToLive());
1254  printInfo(callerName, "IP4 Protocol = %15u \n",
1255  this->getIpProtocol());
1256  printInfo(callerName, "IP4 Header Checksum = %15u \n",
1257  this->getIpHeaderChecksum().to_ushort());
1258  printInfo(callerName, "IP4 Source Address = %3.3d.%3.3d.%3.3d.%3.3d (0x%8.8X) \n",
1259  (this->getIpSourceAddress().to_uint() & 0xFF000000) >> 24,
1260  (this->getIpSourceAddress().to_uint() & 0x00FF0000) >> 16,
1261  (this->getIpSourceAddress().to_uint() & 0x0000FF00) >> 8,
1262  (this->getIpSourceAddress().to_uint() & 0x000000FF) >> 0,
1263  leIp4SrcAddr.to_uint());
1264  printInfo(callerName, "IP4 Destination Address = %3.3d.%3.3d.%3.3d.%3.3d (0x%8.8X) \n",
1265  (this->getIpDestinationAddress().to_uint() & 0xFF000000) >> 24,
1266  (this->getIpDestinationAddress().to_uint() & 0x00FF0000) >> 16,
1267  (this->getIpDestinationAddress().to_uint() & 0x0000FF00) >> 8,
1268  (this->getIpDestinationAddress().to_uint() & 0x000000FF) >> 0,
1269  leIp4DstAddr.to_uint());
1270  printInfo(callerName, "TCP Source Port = %15u (0x%4.4X) \n",
1271  this->getTcpSourcePort(), leTcpSrcPort.to_uint());
1272  printInfo(callerName, "TCP Destination Port = %15u (0x%4.4X) \n",
1273  this->getTcpDestinationPort(), leTcpDstPort.to_uint());
1274  printInfo(callerName, "TCP Sequence Number = %15u (0x%8.8X) \n",
1275  this->getTcpSequenceNumber().to_uint(), leTcpSeqNum.to_uint());
1276  printInfo(callerName, "TCP Acknowledge Number = %15u (0x%8.8X) \n",
1277  this->getTcpAcknowledgeNumber().to_uint(), leTcpAckNum.to_uint());
1278  printInfo(callerName, "TCP Data Offset = %15d (0x%1.1X) \n",
1279  this->getTcpDataOffset(), this->getTcpDataOffset());
1280  printInfo(callerName, "TCP Control Bits = %s%s%s%s%s%s\n",
1281  this->getTcpControlFin() ? "FIN |" : "",
1282  this->getTcpControlSyn() ? "SYN |" : "",
1283  this->getTcpControlRst() ? "RST |" : "",
1284  this->getTcpControlPsh() ? "PSH |" : "",
1285  this->getTcpControlAck() ? "ACK |" : "",
1286  this->getTcpControlUrg() ? "URG |" : "");
1287  printInfo(callerName, "TCP Window = %15u (0x%4.4X) \n",
1288  this->getTcpWindow(), leTcpWindow.to_uint());
1289  printInfo(callerName, "TCP Checksum = %15u (0x%4.4X) \n",
1290  this->getTcpChecksum(), leTcpCSum.to_uint());
1291  printInfo(callerName, "TCP Urgent Pointer = %15u (0x%4.4X) \n",
1292  this->getTcpUrgentPointer(), leTcpUrgPtr.to_uint());
1293  if (this->getTcpDataOffset() == 6) {
1294  printInfo(callerName, "TCP Option:\n");
1295  switch (this->getTcpOptionKind()) {
1296  case 0x02:
1297  printInfo(callerName, " Maximum Segment Size = %15u \n",
1298  this->getTcpOptionMss());
1299  }
1300  }
1301  printInfo(callerName, "TCP Data Length = %15u \n",
1302  this->sizeOfTcpData());
1303  }
1304 
1305 
1309  void printRaw(const char *callerName) {
1310  printInfo(callerName, "Current packet is : \n");
1311  for (int c=0; c<this->pktQ.size(); c++) {
1312  printf("\t\t%16.16lX %2.2X %d \n",
1313  this->pktQ[c].getLE_TData().to_ulong(),
1314  this->pktQ[c].getLE_TKeep().to_ushort(),
1315  this->pktQ[c].getLE_TLast().to_uchar());
1316  }
1317  }
1318 
1319 
1327  Ip4HdrCsum newIp4HdrCsum = calculateIpHeaderChecksum();
1328  // Overwrite the former IP header checksum
1329  this->setIpHeaderChecksum(newIp4HdrCsum);
1330  return (newIp4HdrCsum);
1331  }
1332 
1333 
1341  int newChecksum = 0;
1342  deque<AxisPsd4> tcpBuffer;
1343  // Assemble a TCP buffer with a pseudo-header and TCP data
1344  tcpAssemblePseudoHeaderAndData(tcpBuffer);
1345  // Compute the TCP checksum
1346  int tcpCsum = checksumCalculation(tcpBuffer);
1347  // Overwrite the former checksum
1348  this->setTcpChecksum(tcpCsum);
1349  return tcpCsum;
1350  }
1351 
1352 
1356  int ipDataLen = this->getIpTotalLength() - (4 * this->getIpInternetHeaderLength());
1357  int tcpDatalen = ipDataLen - (4 * this->getTcpDataOffset());
1358  return tcpDatalen;
1359  }
1360 
1361 
1367  Ip4HdrCsum computedCsum = this->calculateIpHeaderChecksum();
1368  Ip4HdrCsum packetCsum = this->getIpHeaderChecksum();
1369  if (computedCsum == packetCsum) {
1370  return true;
1371  }
1372  else {
1373  return false;
1374  }
1375  }
1376 
1377 
1385  SimUdpDatagram udpDatagram = this->getUdpDatagram();
1386  UdpCsum computedCsum = udpDatagram.reCalculateUdpChecksum( \
1387  this->getIpSourceAddress(),
1388  this->getIpDestinationAddress());
1389  // Overwrite the former checksum
1390  this->setUdpChecksum(computedCsum);
1391  return computedCsum;
1392  }
1393 
1394 
1400  TcpChecksum tcpChecksum = this->getTcpChecksum();
1401  TcpChecksum computedCsum = this->tcpRecalculateChecksum();
1402  if (computedCsum == tcpChecksum) {
1403  return true;
1404  }
1405  else {
1406  printWarn(this->myName, " Embedded TCP checksum = 0x%8.8X \n", tcpChecksum.to_uint());
1407  printWarn(this->myName, " Computed TCP checksum = 0x%8.8X \n", computedCsum.to_uint());
1408  return false;
1409  }
1410  }
1411 
1412 
1418  UdpCsum udpChecksum = this->getUdpChecksum();
1419  SimUdpDatagram udpDatagram = this->getUdpDatagram();
1420  UdpCsum computedCsum = udpDatagram.reCalculateUdpChecksum( \
1421  this->getIpSourceAddress(),
1422  this->getIpDestinationAddress());
1423  if (computedCsum == udpChecksum) {
1424  return true;
1425  }
1426  else {
1427  printWarn(this->myName, " Embedded UDP checksum = 0x%8.8X \n", udpChecksum.to_uint());
1428  printWarn(this->myName, " Computed UDP checksum = 0x%8.8X \n", computedCsum.to_uint());
1429  return false;
1430  }
1431  }
1432 
1433 
1438  bool writeToDatFile(ofstream &outFileStream) {
1439  for (int i=0; i < this->size(); i++) {
1440  AxisIp4 axisIp4 = this->pktQ[i];
1441  if (not writeAxisRawToFile(axisIp4, outFileStream)) {
1442  return false;
1443  }
1444  }
1445  return true;
1446  }
1447 
1448 
1453  void writeTcpDataToDatFile(ofstream &outFile) {
1454  if(this->sizeOfTcpData() > 0) {
1455  string tcpData = this->getTcpData();
1456  if (tcpData.size() > 0) {
1457  outFile << tcpData << endl;
1458  }
1459  }
1460  }
1461 
1462 }; // End of: SimIp4Packet
1463 
1464 #endif
1465 
: A class to access an IPv4 data chunk transmitted over an AXI4-Stream interface.
: A class to access the fields of a TCP/IPv4 or UDP/IPv4 pseudo packet when transmitted over an AXI4-...
: A class to access TCP header fields within data chunks transmitted over an AXI4-Stream interface.
: A class to access UDP header fields within data chunks transmitted over an AXI4-Stream interface.
: A simulation class to build and handle ICMP packets.
: A simulation class to build TCP segments.
: A simulation class to build UDP datagrams.
void setTcpDstPort(TcpPort port)
Definition: AxisPsd4.hpp:148
void setPsd4Len(Ly4Len len)
Definition: AxisPsd4.hpp:138
void setTcpSrcPort(TcpPort port)
Definition: AxisPsd4.hpp:145
void setPsd4ResBits(Psd4Res res)
Definition: AxisPsd4.hpp:132
void setPsd4Prot(Ip4Prot prot)
Definition: AxisPsd4.hpp:135
void setTLast(tLast last)
Definition: AxisRaw.hpp:246
void setTDataHi(tDataHalf halfData)
Definition: AxisRaw.hpp:326
tLast getTLast() const
Definition: AxisRaw.hpp:219
tDataHalf getTDataLo() const
Definition: AxisRaw.hpp:301
LE_tKeep getLE_TKeep(int leHi=64/8-1, int leLo=0) const
Definition: AxisRaw.hpp:264
tKeepHalf getTKeepHi() const
Definition: AxisRaw.hpp:309
int getLenHi()
Definition: AxisRaw.hpp:415
LE_tData getLE_TData(int leHi=64 -1, int leLo=0) const
Definition: AxisRaw.hpp:260
void setLE_TLast(LE_tLast last)
Definition: AxisRaw.hpp:280
void setTKeepHi(tKeepHalf halfKeep)
Definition: AxisRaw.hpp:348
void setLE_TData(LE_tData data, int leHi=64 -1, int leLo=0)
Definition: AxisRaw.hpp:272
int getLen() const
Definition: AxisRaw.hpp:411
tDataHalf getTDataHi() const
Definition: AxisRaw.hpp:293
void setLE_TKeep(LE_tKeep keep, int leHi=64/8-1, int leLo=0)
Definition: AxisRaw.hpp:276
int getLenLo()
Definition: AxisRaw.hpp:424
tKeepHalf getTKeepLo() const
Definition: AxisRaw.hpp:317
LE_tLast getLE_TLast() const
Definition: AxisRaw.hpp:268
Class ICMP Packet for simulation.
void pushChunk(AxisIcmp icmpChunk)
AxisIcmp pullChunk()
Class IPv4 Packet for simulation.
void writeTcpDataToDatFile(ofstream &outFile)
Dump the TCP payload of this IP packet into a file. Data is written as a string.
int sizeOfTcpData()
Return the size of the TCP data payload in octets.
TcpSeqNum getTcpSequenceNumber()
bool tcpVerifyChecksum()
Recalculate the TCP checksum and compare it with the one embedded into the segment.
int getIpTotalLength()
void setUdpSourcePort(UdpPort port)
void setTcpOptionMss(int val)
bool isACK()
Returns true if packet is an ACK.
int getIpTypeOfService()
void setIpTotalLength(int totLen)
void setTcpSequenceNumber(TcpSeqNum num)
LE_Ip4Addr getLE_IpDestinationAddress()
void setTcpUrgentPointer(int ptr)
LE_TcpPort getLE_TcpSourcePort()
string getIpPayload()
int getIpTimeToLive()
void setTcpControlFin(int bit)
void setIpFragmentOffset(int offset)
int tcpRecalculateChecksum()
Recalculate the checksum of a TCP segment after it was modified.
SimTcpSegment getTcpSegment()
UdpCsum udpRecalculateChecksum()
Recalculate checksum of an UDP datagram after it was modified.
int getTcpDataOffset()
void setIpSourceAddress(int addr)
string getTcpData()
Get TCP data from the current IPv4 packet.
void setTcpDataOffset(int offset)
int getTcpOptionMss()
bool isWellFormed(const char *callerName, bool checkIp4TotLen=true, bool checkIp4HdrCsum=true, bool checkUdpLen=true, bool checkLy4Csum=true)
Checks if the IP header and embedded protocol fields are properly set.
TcpAckNum getTcpAcknowledgeNumber()
void setIpInternetHeaderLength(int ihl)
void setIpFlags(int flags)
void setUdpChecksum(UdpCsum csum)
Ip4Addr getIpSourceAddress()
void setIpTypeOfService(int tos)
UdpCsum getUdpChecksum()
bool verifyIpHeaderChecksum()
Recalculate the IPv4 header checksum and compare it with the one embedded into the packet.
int getIpIdentification()
void setTcpControlPsh(int bit)
void setIpVersion(int version)
string getIpHeader()
void setIpHeaderChecksum(int csum)
void setIpTimeToLive(Ip4TtL ttl)
TcpCtrlBit getTcpControlUrg()
int getIpInternetHeaderLength()
int getTcpDestinationPort()
int getTcpChecksum()
void setTcpControlRst(int bit)
int getTcpUrgentPointer()
void setTcpControlUrg(int bit)
void pushChunk(AxisIp4 ip4Chunk)
Ip4HdrCsum getIpHeaderChecksum()
SimUdpDatagram getUdpDatagram()
UdpLen getUdpLength()
void clone(SimIp4Packet &ipPkt)
Clone an IP packet.
SimIp4Packet(int pktLen, int hdrLen=20)
bool isFIN()
Returns true if packet is a FIN.
TcpCtrlBit getTcpControlRst()
int getTcpOptionKind()
void setTcpAcknowledgeNumber(TcpAckNum num)
LE_Ip4Addr getLE_IpSourceAddress()
bool udpVerifyChecksum()
Recalculate the UDP checksum and compare it with the one embedded into the datagram.
void cloneHeader(SimIp4Packet &ipPkt)
Clone the header of an IP packet.
void setTcpWindow(int win)
void setTcpControlAck(int bit)
void setIpProtocol(int prot)
void setIpDestinationAddress(int addr)
void setUdpDestinationPort(UdpPort port)
void setTcpOptionKind(int val)
TcpCtrlBit getTcpControlSyn()
UdpPort getUdpDestinationPort()
UdpPort getUdpSourcePort()
Ip4HdrCsum reCalculateIpHeaderChecksum()
Recalculate the IPv4 header checksum of a packet.
TcpCtrlBit getTcpControlAck()
void setIpIdentification(int id)
Ip4Addr getIpDestinationAddress()
int getIpFragmentOffset()
bool setIpPayload(SimIcmpPacket icmpPkt)
Set the data payload of this packet as an ICMP packet.
void printHdr(const char *callerName)
Print the header details of an IP packet.
void setTcpSourcePort(int port)
void printRaw(const char *callerName)
Raw print of an IP packet (.i.e, as AxisRaw chunks).
bool addIpPayload(SimUdpDatagram &udpDgm, int len=-1)
Append some data to this packet from a UDP datagram.
Ip4DatLen getTcpSegmentLength()
void setTcpControlSyn(int bit)
TcpCtrlBit getTcpControlFin()
bool isSYN()
Returns true if packet is a SYN.
bool writeToDatFile(ofstream &outFileStream)
Dump this IP packet as AxisIp4 chunks into a file.
bool addIpPayload(SimIcmpPacket icmpPkt)
Append the data payload of this packet as an ICMP packet.
void setTcpChecksum(int csum)
TcpCtrlBit getTcpControlPsh()
int getTcpSourcePort()
void setTcpDestinationPort(int port)
LE_TcpPort getLE_TcpDestinationPort()
AxisIp4 pullChunk()
void setUdpLength(UdpLen len)
SimIcmpPacket getIcmpPacket()
Class TCP Segment.
void pushChunk(AxisTcp tcpChunk)
void dump()
Dump this TCP segment as HEX and ASCII characters to screen.
TcpCsum reCalculateTcpChecksum(Ip4Addr ipSa, Ip4Addr ipDa, Ip4DatLen segLen)
Recalculate the TCP checksum of this segment.
Class UDP Datagram.
void pushChunk(AxisUdp udpChunk)
UdpCsum reCalculateUdpChecksum(Ip4Addr ipSa, Ip4Addr ipDa)
Recalculate the UDP checksum of a datagram.
ap_uint< 16 > UdpLen
Definition: nal.hpp:250
int byteCnt
Definition: tb_nal.cpp:829
ap_uint< 16 > UdpPort
Definition: nal.hpp:249
string myUint8ToStrHex(ap_uint< 8 > inputNumber)
Converts an UINT8 into a string of 2 HEX characters.
bool writeAxisRawToFile(AxisRaw &axisRaw, ofstream &outFileStream)
Dump an Axis raw data chunk to a file.
ap_uint< 16 > LE_TcpPort
Definition: AxisTcp.hpp:88
#define IP4_PROT_ICMP
Definition: nts_types.hpp:183
ap_uint< 32 > LE_Ip4DstAddr
Definition: AxisIp4.hpp:147
ap_uint< 32 > TcpSeqNum
Definition: AxisTcp.hpp:106
ap_uint< 32 > LE_Ip4SrcAddr
Definition: AxisIp4.hpp:146
#define printError(callerName, format,...)
A macro to print an error message.
Definition: nts_utils.hpp:195
ap_uint< 16 > LE_TcpDstPort
Definition: AxisTcp.hpp:87
ap_uint< 32 > LE_Ip4Addr
Definition: AxisIp4.hpp:149
LE_tKeep lenToLE_tKeep(ap_uint< 4 > noValidBytes)
A function to set a number of '1' in an 8-bit field. It is used here to set the number of valid bytes...
Definition: nts_utils.cpp:307
ap_uint< 32 > LE_TcpAckNum
Definition: AxisTcp.hpp:90
ap_uint< 64 > LE_tData
Definition: AxisRaw.hpp:122
#define IP4_PROT_UDP
Definition: nts_types.hpp:185
ap_uint< 16 > TcpCsum
Definition: AxisTcp.hpp:114
#define ARW
Definition: AxisRaw.hpp:114
ap_uint< 16 > Ip4DatLen
Definition: AxisIp4.hpp:173
ap_uint< 1 > TcpCtrlBit
Definition: AxisTcp.hpp:111
ap_uint< 64/8 > LE_tKeep
Definition: AxisRaw.hpp:124
ap_uint< 32 > Ip4Addr
Definition: AxisIp4.hpp:169
ap_uint< 16 > Ip4HdrCsum
Definition: AxisIp4.hpp:165
ap_uint< 16 > LE_TcpUrgPtr
Definition: AxisTcp.hpp:96
ap_uint< 1 > LE_tLast
Definition: AxisRaw.hpp:125
#define IP4_PROT_TCP
Definition: nts_types.hpp:184
ap_uint< 16 > LE_TcpSrcPort
Definition: AxisTcp.hpp:86
ap_uint< 32 > LE_TcpSeqNum
Definition: AxisTcp.hpp:89
ap_uint< 16 > LE_TcpChecksum
Definition: AxisTcp.hpp:95
#define IP4_HEADER_LEN
Definition: AxisIp4.hpp:133
#define printInfo(callerName, format,...)
A macro to print an information message.
Definition: nts_utils.hpp:169
ap_uint< 16 > LE_Ip4HdrCsum
Definition: AxisIp4.hpp:145
ap_uint< 16 > LE_Ip4TotalLen
Definition: AxisIp4.hpp:142
#define printWarn(callerName, format,...)
A macro to print a warning message.
Definition: nts_utils.hpp:182
ap_uint< 16 > UdpCsum
Definition: AxisUdp.hpp:101
ap_uint< 8 > Ip4TtL
Definition: AxisIp4.hpp:163
ap_uint< 32 > TcpAckNum
Definition: AxisTcp.hpp:107
#define printFatal(callerName, format,...)
A macro to print a fatal error message and exit.
Definition: nts_utils.hpp:208
#define TLAST
Definition: AxisRaw.hpp:116
ap_uint< 16 > LE_TcpWindow
Definition: AxisTcp.hpp:94
ap_uint< 16 > TcpChecksum
Definition: AxisTcp.hpp:113
: Definition of the Network Transport Stack (NTS) component as if it was an HLS IP core.
: Utilities and helpers for the Network-Transport-Stack (NTS) components.
ap_uint< 32 > byteSwap32(ap_uint< 32 > inputVector)
Definition: udp.cpp:78
ap_uint< 16 > byteSwap16(ap_uint< 16 > inputVector)
Definition: udp.cpp:82
#define MTU
Definition: udp.hpp:71