nping: Add --badsum option for ICMP mode

This adds support for --badsum flag that already exists and used for
TCP/UDP modes to work for ICMP packets as well.
This commit is contained in:
Slava Bacherikov 2026-01-11 11:11:08 +02:00
parent ce0c08997e
commit c4bdee677c
7 changed files with 32 additions and 42 deletions

View file

@ -453,6 +453,17 @@ int ICMPv4Header::setSum(u16 s){
} /* End of setSum() */
/** Set the ICMP checksum field to a random value that will never
* match the correct checksum. This is achieved by computing the correct
* checksum first and then XORing it with a random value that can
* never be zero. */
int ICMPv4Header::setSumRandom(){
this->setSum();
this->h.checksum = this->getSum() ^ (1 + (get_random_u16() % (65535-1)));
return OP_SUCCESS;
} /* End of setSumRandom() */
/** Returns the value of the checksum field.
* @warning The returned value is in NETWORK byte order, no conversion is
* performed */

View file

@ -459,6 +459,7 @@ class ICMPv4Header : public ICMPHeader {
/* Checksum */
int setSum();
int setSum(u16 s);
int setSumRandom();
u16 getSum() const;
/* Unused and reserved fields */

View file

@ -424,6 +424,14 @@ u16 ICMPv6Header::getSum() const{
} /* End of getSum() */
/** Set the ICMP checksum field to a random value that will never
* match the correct checksum */
int ICMPv6Header::setSumRandom(){
this->setSum();
this->h.checksum = this->getSum() ^ (1 + (get_random_u16() % (65535-1)));
return OP_SUCCESS;
} /* End of setSumRandom() */
/** @warning Supplied value MUST be in host byte order because it will get
* converted by this method using htonl() */
int ICMPv6Header::setReserved(u32 val){

View file

@ -135,6 +135,8 @@ int ArgParser::parseArguments(int argc, char *argv[]) {
{"flags", required_argument, 0, 0},
{"ack", required_argument, 0, 0},
{"win", required_argument, 0, 0},
/* TCP/UDP/ICMP */
{"badsum", no_argument, 0, 0},
/* ICMP */
@ -1180,6 +1182,7 @@ void ArgParser::printUsage(void){
" --icmp-orig-time <timestamp> : Set originate timestamp.\n"
" --icmp-recv-time <timestamp> : Set receive timestamp.\n"
" --icmp-trans-time <timestamp> : Set transmit timestamp.\n"
" --badsum : Use a random invalid checksum. \n"
"ARP/RARP PROBE MODE:\n"
" --arp-type <type> : Type: ARP, ARP-reply, RARP, RARP-reply.\n"
" --arp-sender-mac <mac> : Set sender MAC address.\n"

View file

@ -225,9 +225,6 @@ NpingOps::NpingOps() {
icmp_code=0;
icmp_code_set=false;
badsum_icmp=false;
badsum_icmp_set=false;
icmp_redir_addr.s_addr=0;
icmp_redir_addr_set=false;
@ -1672,40 +1669,6 @@ bool NpingOps::issetICMPCode(){
} /* End of issetICMPCode() */
/** Sets attribute badsum_icmp to "true". (Generate invalid checksums in ICMP
* packets)
* @return previous value of the attribute. */
bool NpingOps::enableBadsumICMP() {
bool prev = this->badsum_icmp;
this->badsum_icmp=true;
this->badsum_icmp_set=true;
return prev;
} /* End of enableBadsumICMPTCP() */
/** Sets attribute traceroute to "false". (Do NOT Generate invalid checksums
* in UDP / TCP packets)
* @return previous value of the attribute. */
bool NpingOps::disableBadsumICMP() {
bool prev = this->badsum_icmp;
this->badsum_icmp=false;
this->badsum_icmp_set=true;
return prev;
} /* End of disableBadsumICMP() */
/** Returns value of attribute badsum_icmp */
bool NpingOps::getBadsumICMP() {
return this->badsum_icmp;
} /* End of getBadsumICMP() */
/* Returns true if option has been set */
bool NpingOps::issetBadsumICMP(){
return this->badsum_icmp_set;
} /* End of issetBadsumICMP() */
/** Sets ICMPRedirectAddress.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setICMPRedirectAddress(struct in_addr val){

View file

@ -210,7 +210,7 @@ class NpingOps {
bool tcpflags_set;
u16 tcpwin; /* TCP Window */
bool tcpwin_set;
bool badsum; /* Generate invalid TCP/UDP checksums? */
bool badsum; /* Generate invalid TCP/UDP/ICMP checksums? */
bool badsum_set;
/* ICMP */
@ -218,8 +218,6 @@ class NpingOps {
bool icmp_type_set;
u8 icmp_code; /* ICMP Code */
bool icmp_code_set;
bool badsum_icmp; /* Generate invalid ICMP checksums? */
bool badsum_icmp_set;
struct in_addr icmp_redir_addr; /* ICMP Redirect Address */ /* ##TODO## Turn this into an IPAddress object */
bool icmp_redir_addr_set;
u8 icmp_paramprob_pnt; /* ICMP Parameter Problem pointer */

View file

@ -1082,7 +1082,10 @@ int ProbeMode::fillPacketICMP(NpingTarget *target, u8 *buff, int bufflen, int *f
}
/* Compute checksum */
c4.setSum(); /* TODO: Do we want to implement --badsum-icmp? */
if( o.getBadsum() == true )
c4.setSumRandom();
else
c4.setSum();
/* Fill the IPv4Header object with the info from NpingOps */
createIPv4(&i, &c4, "ICMP", target);
@ -1122,7 +1125,10 @@ int ProbeMode::fillPacketICMP(NpingTarget *target, u8 *buff, int bufflen, int *f
createIPv6(&i6, &c6, "ICMPv6", target);
/* Compute checksum */
c6.setSum();
if( o.getBadsum() == true )
c6.setSumRandom();
else
c6.setSum();
/* Store result in user supplied buffer */
*filledlen = i6.dumpToBinaryBuffer(buff, bufflen);