67 #define THIS_NAME "ICMP"
69 #define TRACE_OFF 0x0000
70 #define TRACE_CMB 1 << 1
71 #define TRACE_ICC 1 << 2
72 #define TRACE_ICI 1 << 3
73 #define TRACE_IHA 1 << 4
74 #define TRACE_IPD 1 << 5
75 #define TRACE_ALL 0xFFFF
77 #define DEBUG_LEVEL (TRACE_OFF)
118 stream<AxisIp4> &siIPRX_Data,
119 stream<AxisIp4> &soIPd_Data,
120 stream<ValBool> &soIPd_DropCmd,
121 stream<IcmpCsum> &soICi_Csum)
124 #pragma HLS INLINE off
125 #pragma HLS PIPELINE II=1 enable_flush
130 static bool icc_writeLastOne=
false;
131 #pragma HLS RESET variable=icc_writeLastOne
132 static bool icc_computeCs=
false;
133 #pragma HLS RESET variable=icc_computeCs
134 static ap_uint<7> icc_chunkCount=0;
135 #pragma HLS RESET variable=icc_chunkCount
136 static enum FsmStates { S0=0, S1, S2, S3 } icc_csumState=S0;
137 #pragma HLS RESET variable=icc_csumState
141 static Sum17 icc_subSums[4];
143 static Sum17 icc_newHCsum;
155 if (icc_writeLastOne) {
157 soIPd_Data.write(icc_prevChunk);
158 icc_writeLastOne =
false;
160 else if (icc_computeCs) {
161 switch (icc_csumState) {
163 icc_subSums[0] += icc_subSums[2];
164 icc_subSums[0] = (icc_subSums[0] + (icc_subSums[0] >> 16)) & 0xFFFF;
165 icc_subSums[1] += icc_subSums[3];
166 icc_subSums[1] = (icc_subSums[1] + (icc_subSums[1] >> 16)) & 0xFFFF;
168 icc_newHCsum = ~icc_oldHCsum & 0xFFFF;
172 icc_subSums[0] += icc_subSums[1];
173 icc_subSums[0] = (icc_subSums[0] + (icc_subSums[0] >> 16)) & 0xFFFF;
177 icc_newHCsum = icc_newHCsum + (~0x0800 & 0xFFFF) + 0x0000;
178 icc_newHCsum = (icc_newHCsum + (icc_newHCsum >> 16)) & 0xFFFF;
183 icc_subSums[0] = ~icc_subSums[0];
185 icc_newHCsum = ~icc_newHCsum & 0xFFFF;
189 if (icc_subSums[0](15, 0) == 0) {
191 printInfo(myName,
"\tThe checksum is valid.\n");
194 soICi_Csum.write(icc_newHCsum.range(15, 0));
197 printInfo(myName,
"\tThe control message is ECHO-REQUEST (.i.e Ping).\n");
198 printInfo(myName,
"\t\tThe computed new checksum for ECHO-REPLY is 0x%4.4X.\n",
199 icc_newHCsum.range(15, 0).to_uint());
205 printWarn(myName,
"\tThis control message is not supported.\n");
206 printInfo(myName,
"\t\tThe message-type is %d and message-code is %d.\n",
207 icc_icmpType.to_int(), icc_icmpCode.to_int());
214 printWarn(myName,
"\tThe checksum is invalid.\n");
218 icc_computeCs =
false;
222 else if (!siIPRX_Data.empty()) {
223 siIPRX_Data.read(currChunk);
224 switch (icc_chunkCount) {
232 sendChunk = icc_prevChunk;
233 soIPd_Data.write(sendChunk);
247 soIPd_Data.write(sendChunk);
249 for (
int i=2; i<4; i++) {
252 temp( 7, 0) = currChunk.
getLE_TData(i*16+15, i*16+8);
253 temp(15, 8) = currChunk.
getLE_TData(i*16+ 7, i*16+0);
254 icc_subSums[i] += temp;
255 icc_subSums[i] = (icc_subSums[i] + (icc_subSums[i] >> 16)) & 0xFFFF;
264 for (
int i=0; i<4; i++) {
268 temp( 7, 0) = currChunk.
getLE_TData(i*16+15, i*16+8);
269 temp(15, 8) = currChunk.
getLE_TData(i*16+ 7, i*16+0);
270 icc_subSums[i] += temp;
271 icc_subSums[i] = (icc_subSums[i] + (icc_subSums[i] >> 16)) & 0xFFFF;
276 icc_subSums[i] += temp;
277 icc_subSums[i] = (icc_subSums[i] + (icc_subSums[i] >> 16)) & 0xFFFF;
280 sendChunk = icc_prevChunk;
281 soIPd_Data.write(sendChunk);
285 icc_prevChunk = currChunk;
290 icc_writeLastOne =
true;
291 icc_computeCs =
true;
293 printInfo(myName,
"Received a new message (checksum=0x%4.4X)\n",
294 icc_oldHCsum.to_uint());
317 stream<AxisIcmp> &siUOE_Data,
318 stream<AxisIp4> &siIPRX_Derr,
319 stream<AxisIcmp> &soIHa_Data,
320 stream<AxisIp4> &soIHa_IpHdr,
321 stream<IcmpCsum> &soICi_Csum)
324 #pragma HLS INLINE off
325 #pragma HLS pipeline II=1
330 static enum FsmStates { BCM_IDLE, BCM_IP, \
331 BCM_STREAM, BCM_CS } bcm_fsmState=BCM_IDLE;
332 #pragma HLS reset variable=bcm_fsmState
335 static ap_uint<3> ipChunkCounter;
336 static ap_uint<20> checksumAcc;
338 static ap_uint<1> streamSource = 0;
344 udpInEmpty = siUOE_Data.empty();
345 iprxInEmpty = siIPRX_Derr.empty();
347 switch(bcm_fsmState) {
350 if ((udpInEmpty == 0 || iprxInEmpty == 0) && !soIHa_Data.full()) {
355 if (udpInEmpty == 0) {
360 else if (iprxInEmpty == 0) {
367 soIHa_Data.write(axisIcmp);
368 bcm_fsmState = BCM_IP;
373 if (((streamSource == 0 && udpInEmpty == 0) || (streamSource == 1 && iprxInEmpty == 0)) &&
374 !soIHa_Data.full() && !soIHa_IpHdr.full()) {
377 if (streamSource == 0) {
378 axisIcmp = siUOE_Data.read();
380 else if (streamSource == 1) {
381 axisIcmp = siIPRX_Derr.read();
383 checksumAcc = (checksumAcc +
386 soIHa_Data.write(axisIcmp);
387 soIHa_IpHdr.write(axisIcmp);
388 if (ipChunkCounter == 2) {
389 bcm_fsmState = BCM_STREAM;
397 if (((streamSource == 0 && udpInEmpty == 0) || (streamSource == 1 && iprxInEmpty == 0)) && !soIHa_Data.full()) {
399 if (streamSource == 0) {
400 axisIcmp = siUOE_Data.read();
402 else if (streamSource == 1) {
403 axisIcmp = siIPRX_Derr.read();
405 checksumAcc = (checksumAcc +
408 soIHa_Data.write(axisIcmp);
410 bcm_fsmState = BCM_CS;
415 if (!soICi_Csum.full()) {
416 checksumAcc = (checksumAcc & 0xFFFF) + (checksumAcc >> 16);
417 checksumAcc = (checksumAcc & 0xFFFF) + (checksumAcc >> 16);
419 checksumAcc = ~checksumAcc;
420 soICi_Csum.write(checksumAcc.range(15, 0));
421 bcm_fsmState = BCM_IDLE;
438 stream<AxisIcmp> &siCMb_Data,
439 stream<AxisIp4> &siIHa_IpHdr,
440 stream<AxisIp4> &soICi_Data)
443 #pragma HLS INLINE off
444 #pragma HLS pipeline II=1
447 static enum FsmStates { AIH_IDLE=0, AIH_IP, AIH_MERGE, \
448 AIH_STREAM, AIH_RESIDUE } aih_fsmState=AIH_IDLE;
449 #pragma HLS RESET variable=aih_fsmState
452 static AxisIcmp iha_icmpData(0, 0, 0);
453 static AxisIp4 iha_ipHdrChunk(0, 0, 0);
454 static Ip4Addr iha_remoteIpHostAddr;
456 switch(aih_fsmState) {
458 if (!siIHa_IpHdr.empty() && !soICi_Data.full()) {
460 siIHa_IpHdr.read(iha_ipHdrChunk);
465 soICi_Data.write(iha_ipHdrChunk);
466 aih_fsmState = AIH_IP;
470 if (!siIHa_IpHdr.empty() && !soICi_Data.full()) {
472 siIHa_IpHdr.read(iha_ipHdrChunk);
480 soICi_Data.write(iha_ipHdrChunk);
481 aih_fsmState = AIH_MERGE;
485 if (!siIHa_IpHdr.empty() && !siCMb_Data.empty() &&
486 !soICi_Data.full()) {
489 iha_icmpData = siCMb_Data.read();
490 AxisIp4 thirdChunk(0, 0xFF, 0);
495 soICi_Data.write(thirdChunk);
496 aih_fsmState = AIH_STREAM;
500 if (!siCMb_Data.empty() && !soICi_Data.full()) {
501 AxisIp4 outputChunk(0, 0xFF, 0);
503 iha_icmpData = siCMb_Data.read();
509 aih_fsmState = AIH_IDLE;
512 aih_fsmState = AIH_RESIDUE;
515 soICi_Data.write(outputChunk);
519 if (!soICi_Data.full()) {
523 soICi_Data.write(outputChunk);
524 aih_fsmState = AIH_IDLE;
543 stream<AxisIp4> &siICc_Data,
544 stream<ValBool> &siICc_DropCmd,
545 stream<AxisIp4> &soICi_Data)
548 static bool ipd_isFirstChunk=
true;
549 #pragma HLS RESET variable=ipd_isFirstChunk
552 static bool ipd_drop;
560 if (!siICc_Data.empty()) {
561 if(ipd_isFirstChunk) {
562 if (!siICc_DropCmd.empty()) {
563 siICc_Data.read(currChunk);
564 siICc_DropCmd.read(dropCmd);
566 soICi_Data.write(currChunk);
571 ipd_isFirstChunk =
false;
576 siICc_Data.read(currChunk);
580 siICc_Data.read(currChunk);
581 soICi_Data.write(currChunk);
585 ipd_isFirstChunk =
true;
603 stream<AxisIp4> siXYz_Data[2],
604 stream<IcmpCsum> siUVw_Csum[2],
605 stream<AxisIp4> &soIPTX_Data)
608 #pragma HLS INLINE off
609 #pragma HLS pipeline II=1
614 static ap_uint<7> ici_chunkCount=0;
615 #pragma HLS RESET variable=ici_chunkCount
618 static ap_uint<1> ici_dataStreamSource;
624 switch(ici_chunkCount) {
626 bool streamEmptyStatus[2];
627 for (
int i=0; i<2; ++i) {
628 streamEmptyStatus[i] = siXYz_Data[i].empty();
630 for (
int i=0; i<2; ++i) {
631 if(!streamEmptyStatus[i]) {
632 ici_dataStreamSource = i;
633 inputChunk = siXYz_Data[i].read();
634 soIPTX_Data.write(inputChunk);
641 if (!siXYz_Data[ici_dataStreamSource].empty() &&
642 !siUVw_Csum[ici_dataStreamSource].empty()) {
643 siXYz_Data[ici_dataStreamSource].read(inputChunk);
644 icmpChecksum = siUVw_Csum[ici_dataStreamSource].read();
646 soIPTX_Data.write(inputChunk);
651 if (!siXYz_Data[ici_dataStreamSource].empty()) {
652 siXYz_Data[ici_dataStreamSource].read(inputChunk);
653 soIPTX_Data.write(inputChunk);
696 stream<AxisIp4> &siIPRX_Data,
697 stream<AxisIp4> &siIPRX_Derr,
702 stream<AxisIcmp> &siUOE_Data,
707 stream<AxisIp4> &soIPTX_Data)
712 #pragma HLS INTERFACE ap_ctrl_none port=return
719 static stream<AxisIp4> ssICcToIPd_Data (
"ssICcToIPd_Data");
720 #pragma HLS stream variable=ssICcToIPd_Data depth=64
721 #pragma HLS DATA_PACK variable=ssICcToIPd_Data
723 static stream<ValBool> ssICcToIPd_DropCmd (
"ssICcToIPd_DropCmd");
724 #pragma HLS stream variable=ssICcToIPd_DropCmd depth=8
727 static stream<AxisIcmp> ssCMbToIHa_Data (
"ssCMbToIHa_Data");
728 #pragma HLS stream variable=ssCMbToIHa_Data depth=192
729 static stream<AxisIp4> ssCMbToIHa_IpHdr (
"ssCMbToIHa_IpHdr");
730 #pragma HLS stream variable=ssCMbToIHa_IpHdr depth=64
733 static stream<AxisIp4> ssXYzToICi_Data[2];
734 #pragma HLS STREAM variable=ssXYzToICi_Data depth=16
737 static stream<IcmpCsum> ssUVwToICi_Csum[2];
738 #pragma HLS STREAM variable=ssUVwToICi_Csum depth=16
782 #if HLS_VERSION == 2017
791 stream<AxisIp4> &siIPRX_Data,
792 stream<AxisIp4> &siIPRX_Derr,
796 stream<AxisIcmp> &siUOE_Data,
800 stream<AxisIp4> &soIPTX_Data)
803 #pragma HLS INTERFACE ap_ctrl_none port=return
809 #pragma HLS INTERFACE ap_stable port=piMMIO_Ip4Address
811 #pragma HLS RESOURCE core=AXI4Stream variable=siIPRX_Data metadata="-bus_bundle siIPRX_Data"
812 #pragma HLS RESOURCE core=AXI4Stream variable=siIPRX_Derr metadata="-bus_bundle siIPRX_Derr"
813 #pragma HLS RESOURCE core=AXI4Stream variable=siUOE_Data metadata="-bus_bundle siUOE_Data"
814 #pragma HLS RESOURCE core=AXI4Stream variable=soIPTX_Data metadata="-bus_bundle soIPTX_Data"
840 stream<AxisRaw> &siIPRX_Data,
841 stream<AxisRaw> &siIPRX_Derr,
845 stream<AxisRaw> &siUOE_Data,
849 stream<AxisRaw> &soIPTX_Data)
852 #pragma HLS INTERFACE ap_ctrl_none port=return
854 #pragma HLS INTERFACE ap_stable port=piMMIO_Ip4Address
856 #pragma HLS INTERFACE axis off port=siIPRX_Data
857 #pragma HLS INTERFACE axis off port=siIPRX_Derr
858 #pragma HLS INTERFACE axis off port=siUOE_Data
859 #pragma HLS INTERFACE axis register both port=soIPTX_Data
862 #pragma HLS DATAFLOW disable_start_propagation
865 static stream<AxisIp4> ssiIPRX_Data (
"ssiIPRX_Data");
866 #pragma HLS STREAM variable=ssiIPRX_Data depth=32
867 static stream<AxisIp4> ssiIPRX_Derr (
"ssiIPRX_Derr");
868 static stream<AxisIcmp> ssiUOE_Data (
"ssiUOE_Data");
869 static stream<AxisIp4> ssoIPTX_Data (
"ssoIPTX_Data");
void setIcmpType(IcmpType type)
void setIcmpCode(IcmpCode code)
void setIcmpType(IcmpType type)
void setIp4Prot(Ip4Prot prot)
void setIcmpCode(IcmpCode code)
Ip4TotalLen getIp4TotalLen()
void setIp4HdrCsum(Ip4HdrCsum csum)
void setIp4DstAddr(Ip4Addr addr)
void setIp4TotalLen(Ip4TotalLen len)
void setIcmpCsum(IcmpCsum csum)
void setIp4SrcAddr(Ip4Addr addr)
void setIp4TtL(Ip4TtL ttl)
Ip4HdrCsum getIp4HdrCsum()
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)
void setLE_TKeep(LE_tKeep keep, int leHi=64/8-1, int leLo=0)
LE_tLast getLE_TLast() const
const IcmpType ICMP_TIME_EXCEEDED
void pInvalidPacketDropper(stream< AxisIp4 > &siICc_Data, stream< ValBool > &siICc_DropCmd, stream< AxisIp4 > &soICi_Data)
const IcmpCode ICMP_DESTINATION_PORT_UNREACHABLE
void pControlMessageBuilder(stream< AxisIcmp > &siUOE_Data, stream< AxisIp4 > &siIPRX_Derr, stream< AxisIcmp > &soIHa_Data, stream< AxisIp4 > &soIHa_IpHdr, stream< IcmpCsum > &soICi_Csum)
void icmp_top(Ip4Addr piMMIO_Ip4Address, stream< AxisRaw > &siIPRX_Data, stream< AxisRaw > &siIPRX_Derr, stream< AxisRaw > &siUOE_Data, stream< AxisRaw > &soIPTX_Data)
Top of the Internet Control Message Protocol (ICMP) Server.
const IcmpType ICMP_ECHO_REPLY
const Ip4Prot ICMP_PROTOCOL
const IcmpType ICMP_ECHO_REQUEST
void pIpHeaderAppender(Ip4Addr piMMIO_Ip4Address, stream< AxisIcmp > &siCMb_Data, stream< AxisIp4 > &siIHa_IpHdr, stream< AxisIp4 > &soICi_Data)
void pIcmpChecksumInserter(stream< AxisIp4 > siXYz_Data[2], stream< IcmpCsum > siUVw_Csum[2], stream< AxisIp4 > &soIPTX_Data)
const IcmpCode ICMP_TTL_EXPIRED_IN_TRANSIT
void pIcmpChecksumChecker(stream< AxisIp4 > &siIPRX_Data, stream< AxisIp4 > &soIPd_Data, stream< ValBool > &soIPd_DropCmd, stream< IcmpCsum > &soICi_Csum)
void icmp(Ip4Addr piMMIO_Ip4Address, stream< AxisIp4 > &siIPRX_Data, stream< AxisIp4 > &siIPRX_Derr, stream< AxisIcmp > &siUOE_Data, stream< AxisIp4 > &soIPTX_Data)
Main process of the Internet Control Message Protocol (ICMP) Server.
const IcmpType ICMP_DESTINATION_UNREACHABLE
ap_uint< 16 > LE_IcmpCsum
void pAxisRawCast(hls::stream< TypeIn > &si, hls::stream< TypeOut > &so)
AxisRaw cast - Casts an AxisRaw stream to/from an AxisRaw derived class.
#define printInfo(callerName, format,...)
A macro to print an information message.
ap_uint< 16 > Ip4TotalLen
#define printWarn(callerName, format,...)
A macro to print a warning message.
#define concat3(firstCharConst, secondCharConst, thirdCharConst)
: Internet Control Message Protocol (ICMP) Server