30 #ifndef _SIM_TCP_SEGMENT_
31 #define _SIM_TCP_SEGMENT_
58 std::deque<AxisTcp> segQ;
62 void setLen(
int segLen) {
76 return this->segQ.front();
80 return this->segQ.front();
84 this->segQ.pop_back();
88 this->segQ.pop_front();
91 void push_back(
AxisTcp tcpChunk) {
92 this->segQ.push_back(tcpChunk);
99 this->myName =
"SimTcpSegment";
101 if (segLen > 0 && segLen <=
MTU) {
102 int noBytes = segLen;
104 pushChunk(
AxisTcp(0x0000000000000000, 0xFF, 0));
111 this->myName =
"SimTcpSegment";
117 if (this->
size() > 0) {
119 this->segQ[this->
size()-1].setLE_TLast(0);
121 this->push_back(tcpChunk);
122 this->setLen(this->getLen() + tcpChunk.
getLen());
127 AxisTcp headingChunk = this->front();
129 setLen(getLen() - headingChunk.
getLen());
140 return this->segQ.size();
149 for (
int i=0; i<tcpSeg.segQ.size(); i++) {
150 newAxisTcp = tcpSeg.segQ[i];
151 this->segQ.push_back(newAxisTcp);
153 this->setLen(tcpSeg.getLen());
165 while(cloneBytes > 0) {
166 if (cloneBytes > 8) {
167 this->pushChunk(tcpSeg.segQ[inpChunkCnt]);
170 AxisTcp lastHdrChunk(tcpSeg.segQ[inpChunkCnt].getLE_TData(),
172 this->pushChunk(lastHdrChunk);
240 printFatal(this->myName,
"Empty segment is expected to be of length %d bytes (was found to be %d bytes).\n",
243 int hdrLen = this->getLen();
244 int pldLen = pldStr.size();
245 int q = (hdrLen / 8);
246 int b = (hdrLen % 8);
253 currChunk = this->back();
258 unsigned char datByte = pldStr[i];
268 pushChunk(currChunk);
301 ap_uint<32> csum = 0;
308 for (
int i=0; i<this->
size(); ++i) {
310 if (segQ[i].getLE_TKeep() & 0x01)
311 tempInput.range( 7, 0) = (segQ[i].getLE_TData()).range( 7, 0);
312 if (segQ[i].getLE_TKeep() & 0x02)
313 tempInput.range(15, 8) = (segQ[i].getLE_TData()).range(15, 8);
314 if (segQ[i].getLE_TKeep() & 0x04)
315 tempInput.range(23,16) = (segQ[i].getLE_TData()).range(23,16);
316 if (segQ[i].getLE_TKeep() & 0x08)
317 tempInput.range(31,24) = (segQ[i].getLE_TData()).range(31,24);
318 if (segQ[i].getLE_TKeep() & 0x10)
319 tempInput.range(39,32) = (segQ[i].getLE_TData()).range(39,32);
320 if (segQ[i].getLE_TKeep() & 0x20)
321 tempInput.range(47,40) = (segQ[i].getLE_TData()).range(47,40);
322 if (segQ[i].getLE_TKeep() & 0x40)
323 tempInput.range(55,48) = (segQ[i].getLE_TData()).range(55,48);
324 if (segQ[i].getLE_TKeep() & 0x80)
325 tempInput.range(63,56) = (segQ[i].getLE_TData()).range(63,56);
327 tempInput.range(63, 48)) + tempInput.range(47, 32)) +
328 tempInput.range(31, 16)) + tempInput.range(15, 0));
331 csum = (csum & 0xFFFF) + (csum >> 16);
334 TcpCsum tcpCsum = csum.range(15, 0);
350 this->setTcpChecksum(0x0000);
351 TcpCsum newTcpCsum = calculateTcpChecksum(ipSa, ipDa, segLen);
353 this->setTcpChecksum(newTcpCsum);
368 TcpCsum tcpCsum = this->getTcpChecksum();
369 TcpCsum calcCsum = this->reCalculateTcpChecksum(ipSa, ipDa, (
Ip4DatLen)this->getLen());
370 if ((tcpCsum != 0xDEAD) and (tcpCsum != calcCsum)) {
372 printWarn(callerName,
"Malformed TCP segment: 'Checksum' field does not match the checksum of the pseudo-packet.\n");
373 printWarn(callerName,
"\tFound 'Checksum' field=0x%4.4X, Was expecting 0x%4.4X)\n",
374 tcpCsum.to_uint(), calcCsum.to_ushort());
385 for (
int q=0; q < this->
size(); q++) {
386 AxisTcp axisData = this->segQ[q];
387 for (
int b=7; b >= 0; b--) {
389 int hi = ((b*8) + 7);
390 int lo = ((b*8) + 0);
391 ap_uint<8> octet = axisData.
getTData().range(hi, lo);
396 bool endOfSeg =
false;
403 for (
int c=0; c < 16*2; c+=2) {
404 if (i < segStr.length()) {
405 hexaStr += segStr.substr(i, 2);
406 char ch = std::strtoul(segStr.substr(i, 2).c_str(), &ptr, 16);
420 printf(
"%4.4X %s %s \n", offset, hexaStr.c_str(), asciiStr.c_str());
422 }
while (not endOfSeg);
432 if (!outFileStream.is_open()) {
437 outFileStream << hex << noshowbase << setfill(
'0') << setw(16) << axisTcp.
getLE_TData().to_uint64();
438 outFileStream <<
" ";
439 outFileStream << setw(1) << axisTcp.
getLE_TLast().to_int();
440 outFileStream <<
" ";
441 outFileStream << hex << noshowbase << setfill(
'0') << setw(2) << axisTcp.
getLE_TKeep().to_int() <<
"\n";
443 outFileStream <<
"\n";
454 for (
int i=0; i < this->
size(); i++) {
455 AxisTcp axisTcp = this->segQ[i];
456 if (not this->writeAxisTcpToFile(axisTcp, outFileStream)) {
469 for (
int i=1; i < this->
size(); i++) {
470 AxisTcp axisWord = this->segQ[i];
471 if (not this->writeAxisTcpToFile(axisWord, outFileStream)) {
: A class to access TCP header fields within data chunks transmitted over an AXI4-Stream interface.
: Utilities for the simulation of the Network-Transport-Stack (NTS) components.
tData getTData(int leHi=64 -1, int leLo=0) const
LE_tKeep getLE_TKeep(int leHi=64/8-1, int leLo=0) const
LE_tData getLE_TData(int leHi=64 -1, int leLo=0) const
void setLE_TLast(LE_tLast last)
void setLE_TData(LE_tData data, int leHi=64 -1, int leLo=0)
tKeep getTKeep(int leHi=64/8-1, int leLo=0) const
void setLE_TKeep(LE_tKeep keep, int leHi=64/8-1, int leLo=0)
LE_tLast getLE_TLast() const
void setTcpControlAck(TcpCtrlBit bit)
void cloneHeader(SimTcpSegment &tcpSeg)
Clone the header of a TCP segment.
void setTcpDataOffset(int offset)
void setTcpOptionKind(TcpOptKind val)
void setTcpControlUrg(TcpCtrlBit bit)
TcpCtrlBit getTcpControlSyn()
void setTcpAcknowledgeNumber(TcpAckNum num)
void pushChunk(AxisTcp tcpChunk)
TcpCtrlBit getTcpControlAck()
TcpCtrlBit getTcpControlRst()
TcpCtrlBit getTcpControlFin()
TcpAckNum getTcpAcknowledgeNumber()
TcpCtrlBit getTcpControlUrg()
void setTcpControlSyn(TcpCtrlBit bit)
SimTcpSegment(int segLen)
void setTcpControlRst(TcpCtrlBit bit)
TcpCsum calculateTcpChecksum(Ip4Addr ipSa, Ip4Addr ipDa, Ip4DatLen tcpSegLen)
Calculate the TCP checksum of the segment.
void setTcpWindow(TcpWindow win)
void setTcpSourcePort(TcpPort port)
TcpOptKind getTcpOptionKind()
TcpUrgPtr getTcpUrgentPointer()
bool writePayloadToDatFile(ofstream &outFileStream)
Dump the payload of this segment as AxisTcp chunks into a file.
void setTcpOptionMss(TcpOptMss val)
void clone(SimTcpSegment &tcpSeg)
Clone a TCP segment.
void setTcpUrgentPointer(TcpUrgPtr ptr)
TcpPort getTcpSourcePort()
bool writeToDatFile(ofstream &outFileStream)
Dump this TCP segment as raw AxisTcp chunks into a file.
void setTcpControlFin(TcpCtrlBit bit)
LE_TcpPort getLE_TcpDestinationPort()
TcpCtrlBit getTcpControlPsh()
void dump()
Dump this TCP segment as HEX and ASCII characters to screen.
void setTcpChecksum(TcpChecksum csum)
void addTcpPayload(string pldStr)
Append data payload to a TCP header.
TcpPort getTcpDestinationPort()
bool isWellFormed(const char *callerName, Ip4Addr ipSa, Ip4Addr ipDa)
Checks if the segment header fields are properly set.
TcpSeqNum getTcpSequenceNumber()
bool writeAxisTcpToFile(AxisTcp &axisTcp, ofstream &outFileStream)
Dump an AxisTcp chunk to a file.
void setTcpDestinationPort(TcpPort port)
void setTcpSequenceNumber(TcpSeqNum num)
LE_TcpPort getLE_TcpSourcePort()
void setTcpControlPsh(TcpCtrlBit bit)
TcpCsum reCalculateTcpChecksum(Ip4Addr ipSa, Ip4Addr ipDa, Ip4DatLen segLen)
Recalculate the TCP checksum of this segment.
TcpOptMss getTcpOptionMss()
string myUint8ToStrHex(ap_uint< 8 > inputNumber)
Converts an UINT8 into a string of 2 HEX characters.
#define printError(callerName, format,...)
A macro to print an error message.
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...
#define printWarn(callerName, format,...)
A macro to print a warning message.
#define printFatal(callerName, format,...)
A macro to print a fatal error message and exit.
ap_uint< 16 > TcpChecksum
void uppercase(ap_uint< 32 > *pi_rank, ap_uint< 32 > *pi_size, stream< NetworkWord > &siSHL_This_Data, stream< NetworkWord > &soTHIS_Shl_Data, stream< NetworkMetaStream > &siNrc_meta, stream< NetworkMetaStream > &soNrc_meta, ap_uint< 32 > *po_rx_ports)
Main process of the Uppercase Application directives.
: Utilities and helpers for the Network-Transport-Stack (NTS) components.
ap_uint< 16 > byteSwap16(ap_uint< 16 > inputVector)