1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00
Files
nmap/nping/NpingOps.cc

3117 lines
98 KiB
C++

/***************************************************************************
* NpingOps.cc -- The NpingOps class contains global options, mostly based *
* on user-provided command-line settings. *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2020 Insecure.Com LLC ("The Nmap *
* Project"). Nmap is also a registered trademark of the Nmap Project. *
* *
* This program is distributed under the terms of the Nmap Public Source *
* License (NPSL). The exact license text applying to a particular Nmap *
* release or source code control revision is contained in the LICENSE *
* file distributed with that version of Nmap or source code control *
* revision. More Nmap copyright/legal information is available from *
* https://nmap.org/book/man-legal.html, and further information on the *
* NPSL license itself can be found at https://nmap.org/npsl. This header *
* summarizes some key points from the Nmap license, but is no substitute *
* for the actual license text. *
* *
* Nmap is generally free for end users to download and use themselves, *
* including commercial use. It is available from https://nmap.org. *
* *
* The Nmap license generally prohibits companies from using and *
* redistributing Nmap in commercial products, but we sell a special Nmap *
* OEM Edition with a more permissive license and special features for *
* this purpose. See https://nmap.org/oem *
* *
* If you have received a written Nmap license agreement or contract *
* stating terms other than these (such as an Nmap OEM license), you may *
* choose to use and redistribute Nmap under those terms instead. *
* *
* The official Nmap Windows builds include the Npcap software *
* (https://npcap.org) for packet capture and transmission. It is under *
* separate license terms which forbid redistribution without special *
* permission. So the official Nmap Windows builds may not be *
* redistributed without special permission (such as an Nmap OEM *
* license). *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes. *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to submit your *
* changes as a Github PR or by email to the dev@nmap.org mailing list *
* for possible incorporation into the main distribution. Unless you *
* specify otherwise, it is understood that you are offering us very *
* broad rights to use your submissions as described in the Nmap Public *
* Source License Contributor Agreement. This is important because we *
* fund the project by selling licenses with various terms, and also *
* because the inability to relicense code has caused devastating *
* problems for other Free Software projects (such as KDE and NASM). *
* *
* The free version of Nmap is distributed in the hope that it will be *
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Warranties, *
* indemnification and commercial support are all available through the *
* Npcap OEM program--see https://nmap.org/oem. *
* *
***************************************************************************/
#ifdef WIN32
#include "winfix.h"
#endif
#include "nping.h"
#include "nbase.h"
#include "NpingOps.h"
#include "utils.h"
#include "utils_net.h"
#include "ArgParser.h"
#include "output.h"
#include "common.h"
/******************************************************************************
* Constructors and destructors *
******************************************************************************/
/* Constructor */
NpingOps::NpingOps() {
/* Probe modes */
mode=0;
mode_set=false;
traceroute=false;
traceroute_set=false;
/* Output */
vb=DEFAULT_VERBOSITY;
vb_set=false;
dbg=DEFAULT_DEBUGGING;
dbg_set=false;
show_sent_pkts=true;
show_sent_pkts_set=false;
/* Operation and Performance */
pcount=0;
pcount_set=false;
sendpref=0;
sendpref_set=false;
send_eth=false;
send_eth_set=false;
delay=0;
delay_set=false;
memset(device, 0, MAX_DEV_LEN);
device_set=false;
spoofsource=false;
spoofsource_set=false;
bpf_filter_spec=NULL;
bpf_filter_spec_set=false;
current_round=0;
have_pcap=true;
disable_packet_capture=false;
disable_packet_capture_set=false;
/* Privileges */
/* If user did not specify --privileged or --unprivileged explicitly, try to
* determine if has root privileges. */
#if defined WIN32 || defined __amigaos__
/* TODO: Check this because although nmap does exactly the same, it has a this->have_pcap that may affect to this */
isr00t=true;
#else
if (getenv("NMAP_PRIVILEGED") || getenv("NPING_PRIVILEGED"))
isr00t=true;
else if (getenv("NMAP_UNPRIVILEGED") || getenv("NPING_UNPRIVILEGED"))
isr00t=false;
else
isr00t = !(geteuid());
#endif
/* Payloads */
payload_type=PL_NONE;
payload_type_set=false;
payload_buff=NULL;
payload_buff_set=false;
payload_len=0;
payload_len_set=false;
/* Roles */
role=0;
role_set=false;
/* IP */
ttl=0;
ttl_set=false;
tos=0;
tos_set=false;
identification=0;
identification_set=false;
mf=false;
mf_set=false;
df=false;
df_set=false;
mtu=0;
mtu_set=false;
badsum_ip=false;
badsum_ip_set=false;
ipversion=0;
ipversion_set=false;
memset(&ipv4_src_address, 0, sizeof(struct in_addr));
ipv4_src_address_set=false;
ip_options=NULL;
ip_options_set=false;
/* IPv6 */
ipv6_tclass=0;
ipv6_tclass_set=false;
ipv6_flowlabel=0;
ipv6_flowlabel_set=false;
memset(&ipv6_src_address, 0, sizeof(struct in6_addr));
ipv6_src_address_set=false;
/* TCP / UDP */
target_ports=NULL;
tportcount=0;
target_ports_set=false;
source_port=0;
source_port_set=false;
tcpseq=0;
tcpseq_set=false;
memset(tcpflags, 0, 8);
tcpflags_set=false;
tcpack=0;
tcpack_set=false;
tcpwin=0;
tcpwin_set=false;
badsum=false;
badsum_set=false;
/* ICMP */
icmp_type=0;
icmp_type_set=false;
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;
icmp_paramprob_pnt=0;
icmp_paramprob_pnt_set=false;
icmp_routeadv_ltime=0;
icmp_routeadv_ltime_set=false;
icmp_id=0;
icmp_id_set=false;
icmp_seq=0;
icmp_seq_set=false;
icmp_orig_time=0;
icmp_orig_time_set=false;
icmp_recv_time=0;
icmp_recv_time_set=false;
icmp_trans_time=0;
icmp_trans_time_set=false;
memset( icmp_advert_entry_addr, 0, sizeof(u32)*MAX_ICMP_ADVERT_ENTRIES );
memset( icmp_advert_entry_pref, 0, sizeof(u32)*MAX_ICMP_ADVERT_ENTRIES );
icmp_advert_entry_count=0;
icmp_advert_entry_set=false;
/* Ethernet */
memset(src_mac, 0, 6);
src_mac_set=false;
memset(dst_mac, 0, 6);
dst_mac_set=false;
eth_type=0;
eth_type_set=false;
arp_htype=0;
arp_htype_set=false;
/* ARP/RARP */
arp_ptype=0;
arp_ptype_set=false;
arp_hlen=0;
arp_hlen_set=false;
arp_plen=0;
arp_plen_set=false;
arp_opcode=0;
arp_opcode_set=false;
memset(arp_sha, 0, 6);
arp_sha_set=false;
memset(arp_tha, 0, 6);
arp_tha_set=false;
arp_spa.s_addr=0;
arp_spa_set=false;
arp_tpa.s_addr=0;
arp_tpa_set=false;
/* Echo mode */
echo_port=DEFAULT_ECHO_PORT;
echo_port_set=false;
do_crypto=true;
echo_payload=false;
echo_server_once=false;
echo_server_once_set=false;
memset(echo_passphrase, 0, sizeof(echo_passphrase));
echo_passphrase_set=false;
memset(&last_sent_pkt_time, 0, sizeof(struct timeval));
delayed_rcvd_str=NULL;
delayed_rcvd_str_set=false;
} /* End of NpingOps() */
/* Destructor */
NpingOps::~NpingOps() {
if (payload_buff!=NULL)
free(payload_buff);
if ( ip_options!=NULL )
free(ip_options);
if ( target_ports!=NULL )
free(target_ports);
if (delayed_rcvd_str_set)
free(delayed_rcvd_str);
return;
} /* End of ~NpingOps() */
/******************************************************************************
* Nping probe modes *
******************************************************************************/
/** Sets attribute "mode". Mode must be one of: TCP_CONNECT TCP, UDP, ICMP,
* ARP
* @return OP_SUCCESS on success.
* @return OP_FAILURE in case of error. */
int NpingOps::setMode(int md) {
if ( md!=TCP_CONNECT && md!=TCP && md!=UDP && md!=UDP_UNPRIV && md!=ICMP && md!=ARP )
return OP_FAILURE;
else{
this->mode=md;
this->mode_set=true;
}
return OP_SUCCESS;
} /* End of setMode() */
/** Returns value of attribute "mode". The value returned is supposed to be
* one of : TCP_CONNECT, TCP, UDP, UDP_UNPRIV, ICMP, ARP */
int NpingOps::getMode() {
return mode;
} /* End of getMode() */
/* Returns true if option has been set */
bool NpingOps::issetMode(){
return this->mode_set;
} /* End of isset() */
/** Takes a probe mode and returns an ASCII string with the name of the mode.
* @warning Returned pointer is a static buffer that subsequent calls
* will overwrite.
* @return Pointer to the appropriate string on success and pointer to a
* string containing "Unknown probe" in case of failure.
* */
char * NpingOps::mode2Ascii(int md) {
static char buff[24];
switch( md ){
case TCP_CONNECT:
sprintf(buff, "TCP-Connect");
break;
case TCP:
sprintf(buff, "TCP");
break;
case UDP:
sprintf(buff, "UDP");
break;
case UDP_UNPRIV:
sprintf(buff, "UDP-Unprivileged");
break;
case ICMP:
sprintf(buff, "ICMP");
break;
case ARP:
sprintf(buff, "ARP");
break;
default:
sprintf(buff, "Unknown mode");
break;
}
return buff;
} /* End of mode2Ascii() */
/** Returns value of attribute "traceroute" */
bool NpingOps::getTraceroute() {
return traceroute;
} /* End of getTraceroute() */
/** Sets attribute traceroute to "true".
* @return previous value of the attribute. */
bool NpingOps::enableTraceroute() {
bool prev = traceroute;
this->traceroute=true;
this->traceroute_set=true;
return prev;
} /* End of enableTraceroute() */
/** Sets attribute traceroute to "false".
* @return previous value of the attribute. */
bool NpingOps::disableTraceroute() {
bool prev = traceroute;
this->traceroute=false;
this->traceroute_set=true;
return prev;
} /* End of disableTraceroute() */
/* Returns true if option has been set */
bool NpingOps::issetTraceroute(){
return this->traceroute_set;
} /* End of issetTraceroute() */
/******************************************************************************
* Output *
******************************************************************************/
/** Sets verbosity level. Supplied level must be an integer between -4 and
* 4. Check man pages for details.
*
* The thing here is that what the argument parser gets from the user is
* number in the range [-4, 4]. However, in NpingOps we don't store negative
* verbosity values, we just convert the supplied level into our internal
* levels (QT_4, QT_3, ... , VB_0, VB_1, ..., VB_4)
* So the rest of the code in Nping should check for these defines, rather
* than checking for numbers. Check nping.h for more information on how to
* handle verbosity levels.
*
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setVerbosity(int level){
if( level < -4 || level > 4 ){
nping_fatal(QT_3,"setVerbosity(): Invalid verbosity level supplied\n");
return OP_FAILURE;
}else{
switch(level){
case -4: vb=QT_4; break;
case -3: vb=QT_3; break;
case -2: vb=QT_2; break;
case -1: vb=QT_1; break;
case 0: vb=VB_0; break;
case 1: vb=VB_1; break;
case 2: vb=VB_2; break;
case 3: vb=VB_3; break;
case 4: vb=VB_4; break;
default:
nping_fatal(QT_3,"setVerbosity():2: Invalid verbosity level supplied\n");
break;
}
}
this->vb_set=true;
return OP_SUCCESS;
} /* End of setVerbosity() */
/** Returns value of attribute vb (current verbosity level) */
int NpingOps::getVerbosity(){
return vb;
} /* End of getVerbosity() */
/* Returns true if option has been set */
bool NpingOps::issetVerbosity(){
return this->vb_set;
} /* End of issetVerbosity() */
/** Increments verbosity level by one. (When it reaches VB_4 it stops
* getting incremented)
* @return previous verbosity level */
int NpingOps::increaseVerbosity(){
this->vb_set=true;
if (vb < VB_4){
vb++;
return vb-1;
}else{
return vb;
}
} /* End of increaseVerbosity() */
/** Decreases verbosity level by one. (When it reaches QT_4 it stops
* getting incremented)
* @return previous verbosity level */
int NpingOps::decreaseVerbosity(){
this->vb_set=true;
if (vb > QT_4){
vb--;
return vb+1;
}else{
return vb;
}
} /* End of decreaseVerbosity() */
/** Sets debugging level. Supplied level must be an integer between DBG_0 and
* DBG_9. Check file nping.h for details
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setDebugging(int level){
if( level < 0 || level > 9){
nping_fatal(QT_3,"setDebugging(): Invalid debugging level supplied\n");
return OP_FAILURE;
}else{
this->dbg= DBG_0 + level;
}
this->dbg_set=true;
return OP_SUCCESS;
} /* End of setDebugging() */
/** Returns value of attribute dbg (current debugging level) */
int NpingOps::getDebugging(){
return dbg;
} /* End of getDebugging() */
/** Increments debugging level by one. (When it reaches DBG_9 it stops
* getting incremented)
* * @return previous verbosity level */
int NpingOps::increaseDebugging(){
this->dbg_set=true;
if (dbg < DBG_9){
dbg++;
return dbg-1;
}else{
return dbg;
}
} /* End of increaseDebugging() */
/* Returns true if option has been set */
bool NpingOps::issetDebugging(){
return this->dbg_set;
} /* End of issetDebugging() */
/** Sets ShowSentPackets.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setShowSentPackets(bool val){
this->show_sent_pkts=val;
this->show_sent_pkts_set=true;
return OP_SUCCESS;
} /* End of setShowSentPackets() */
/** Returns value of attribute show_sent_pkts */
bool NpingOps::showSentPackets(){
return this->show_sent_pkts;
} /* End of showSentPackets() */
/* Returns true if option has been set */
bool NpingOps::issetShowSentPackets(){
return this->show_sent_pkts_set;
} /* End of issetShowSentPackets() */
/******************************************************************************
* Operation and Performance *
******************************************************************************/
/** Sets packet count (number of packets that should be sent to each target)
* Supplied parameter must be a non-negative integer.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setPacketCount(u32 val){
/* If zero is supplied, use the highest possible value */
if( val==0 )
this->pcount=0xFFFFFFFF;
else
pcount=val;
this->pcount_set=true;
return OP_SUCCESS;
} /* End of setPacketCount() */
/** Returns value of attribute pcount (number of packets that should be sent
* to each target) */
u32 NpingOps::getPacketCount(){
return this->pcount;
} /* End of getPacketCount() */
/* Returns true if option has been set */
bool NpingOps::issetPacketCount(){
return this->pcount_set;
} /* End of issetPacketCount() */
/** Sets attribute sendpref which defines user's preference for packet
* sending. Supplied parameter must be an integer with one of these values:
* PACKET_SEND_NOPREF, PACKET_SEND_ETH_WEAK, PACKET_SEND_ETH_STRONG,
* PACKET_SEND_ETH, PACKET_SEND_IP_WEAK, PACKET_SEND_IP_STRONG, PACKET_SEND_IP
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setSendPreference(int v){
if( v!=PACKET_SEND_NOPREF && v!=PACKET_SEND_ETH_WEAK &&
v!=PACKET_SEND_ETH_STRONG && v!=PACKET_SEND_ETH &&
v!=PACKET_SEND_IP_WEAK && v!=PACKET_SEND_IP_STRONG &&
v!=PACKET_SEND_IP ){
nping_fatal(QT_3,"setSendPreference(): Invalid value supplied\n");
return OP_FAILURE;
}else{
sendpref=v;
}
this->sendpref_set=true;
return OP_SUCCESS;
} /* End of setSendPreference() */
/** Returns value of attribute sendpref */
int NpingOps::getSendPreference(){
return this->sendpref;
} /* End of getSendPreference() */
/* Returns true if option has been set */
bool NpingOps::issetSendPreference(){
return this->sendpref_set;
} /* End of issetSendPreference() */
/* Returns true if send preference is Ethernet */
bool NpingOps::sendPreferenceEthernet(){
if ( this->getSendPreference()==PACKET_SEND_ETH_WEAK )
return true;
else if (this->getSendPreference()==PACKET_SEND_ETH_STRONG)
return true;
else if (this->getSendPreference()==PACKET_SEND_ETH )
return true;
else
return false;
} /* End of sendPreferenceEthernet() */
/* Returns true if send preference is Ethernet */
bool NpingOps::sendPreferenceIP(){
if ( this->getSendPreference()==PACKET_SEND_IP_WEAK )
return true;
else if (this->getSendPreference()==PACKET_SEND_IP_STRONG)
return true;
else if (this->getSendPreference()==PACKET_SEND_IP )
return true;
else
return false;
} /* End of sendPreferenceIP() */
/** Sets SendEth.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setSendEth(bool val){
this->send_eth=val;
this->send_eth_set=true;
return OP_SUCCESS;
} /* End of setSendEth() */
/** Returns value of attribute send_eth */
bool NpingOps::sendEth(){
return this->send_eth;
} /* End of getSendEth() */
/* Returns true if option has been set */
bool NpingOps::issetSendEth(){
return this->send_eth_set;
} /* End of issetSendEth() */
/** Sets inter-probe delay. Supplied parameter is assumed to be in milliseconds
* and must be a long integer greater than zero.
* @warning timeout is assumed to be in milliseconds. Use tval2msecs() from
* nbase to obtain a proper value.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setDelay(long t){
if( t < 0 )
nping_fatal(QT_3,"setDelay(): Invalid time supplied\n");
this->delay=t;
this->delay_set=true;
return OP_SUCCESS;
} /* End of setDelay() */
/** Returns value of attribute delay */
long NpingOps::getDelay(){
return delay;
} /* End of getDelay() */
/* Returns true if option has been set */
bool NpingOps::issetDelay(){
return this->delay_set;
} /* End of issetDelay() */
/** Sets network device. Supplied parameter must be a valid network interface
* name.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setDevice(char *n){
if( n==NULL ){
nping_fatal(QT_3,"setDevice(): Invalid value supplied\n");
}else{
Strncpy(this->device, n, MAX_DEV_LEN-1);
}
this->device_set=true;
return OP_SUCCESS;
} /* End of setDevice() */
char *NpingOps::getDevice(){
return this->device;
} /* End of getDevice() */
/* Returns true if option has been set */
bool NpingOps::issetDevice(){
return this->device_set;
} /* End of issetDevice() */
/** Returns true if user requested explicitly that he wants IP source
* spoofing */
bool NpingOps::spoofSource(){
return this->spoofsource;
} /* End of spoofSource() */
bool NpingOps::getSpoofSource(){
return this->spoofsource;
} /* End of getSpoofSource() */
int NpingOps::setSpoofSource(){
this->spoofsource=true;
this->spoofsource_set=true;
return OP_SUCCESS;
} /* End of spoofSource() */
/* Returns true if option has been set */
bool NpingOps::issetSpoofSource(){
return this->spoofsource_set;
} /* End of issetSpoofSource() */
/** Sets BPFFilterSpec.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setBPFFilterSpec(char *val){
this->bpf_filter_spec=val;
this->bpf_filter_spec_set=true;
return OP_SUCCESS;
} /* End of setBPFFilterSpec() */
/** Returns value of attribute bpf_filter_spec */
char *NpingOps::getBPFFilterSpec(){
return this->bpf_filter_spec;
} /* End of getBPFFilterSpec() */
/* Returns true if option has been set */
bool NpingOps::issetBPFFilterSpec(){
return this->bpf_filter_spec_set;
} /* End of issetBPFFilterSpec() */
/** Sets CurrentRound.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setCurrentRound(int val){
this->current_round=val;
return OP_SUCCESS;
} /* End of setCurrentRound() */
/** Returns value of attribute current_round */
int NpingOps::getCurrentRound(){
return this->current_round;
} /* End of getCurrentRound() */
bool NpingOps::havePcap(){
return this->have_pcap;
} /* End of havePcap() */
int NpingOps::setHavePcap(bool val){
this->have_pcap=val;
return OP_SUCCESS;
} /* End of setHavePcap() */
/** Sets DisablePacketCapture.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setDisablePacketCapture(bool val){
this->disable_packet_capture=val;
this->disable_packet_capture_set=true;
return OP_SUCCESS;
} /* End of setDisablePacketCapture() */
/** Returns value of attribute disable_packet_capture */
bool NpingOps::disablePacketCapture(){
return this->disable_packet_capture;
} /* End of disablePacketCapture() */
/* Returns true if option has been set */
bool NpingOps::issetDisablePacketCapture(){
return this->disable_packet_capture_set;
} /* End of issetDisablePacketCapture() */
/** Sets the IP version that will be used in all packets. Supplied parameter
* must be either IP_VERSION_4 or IP_VERSION_&.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setIPVersion(u8 val){
if( val!=IP_VERSION_4 && val!=IP_VERSION_6 ){
nping_fatal(QT_3,"setIPVersion(): Invalid value supplied\n");
return OP_FAILURE;
}else{
this-> ipversion=val;
}
this->ipversion_set=true;
return OP_SUCCESS;
} /* End of setIPVersion() */
/** Returns value of attribute ipversion. */
int NpingOps::getIPVersion(){
return ipversion;
} /* End of getIPVersion() */
/* Returns true if option has been set */
bool NpingOps::issetIPVersion(){
return this->ipversion_set;
} /* End of issetIPversion() */
/* Returns true if we are using IPv4 */
bool NpingOps::ipv4(){
if( this->getIPVersion() == IP_VERSION_4 )
return true;
else
return false;
} /* End of ipv4() */
/* Returns true if we are using IPv6 */
bool NpingOps::ipv6(){
if( this->getIPVersion() == IP_VERSION_6 )
return true;
else
return false;
} /* End of ipv6() */
/* Returns true if we are sending IPv6 packets at raw TCP level (using a
* useless and boring IPv6 socket that doesn't let us include our own IPv6
* header)*/
bool NpingOps::ipv6UsingSocket(){
if( this->getIPVersion() == IP_VERSION_6 && this->sendEth()==false)
return true;
else
return false;
} /* End of ipv6UsingSocket() */
/* Returns AF_INET or AF_INET6, depending on current configuration */
int NpingOps::af(){
if( this->getIPVersion() == IP_VERSION_6 )
return AF_INET6;
else
return AF_INET;
} /* End of af() */
/******************************************************************************
* User types and Privileges *
******************************************************************************/
/** Sets value of attribute isr00t.
* @returns previous isr00t value */
int NpingOps::setIsRoot(int v) {
int prev=this->isr00t;
this->isr00t = (v==0) ? 0 : 1;
return prev;
} /* End of setIsRoot() */
/** Sets attribute isr00t to value 1.
* @returns previous isr00t value */
int NpingOps::setIsRoot() {
int prev=this->isr00t;
this->isr00t=1;
return prev;
} /* End of setIsRoot() */
/* Returns the state of attribute isr00t */
bool NpingOps::isRoot() {
return (this->isr00t);
} /* End of isRoot() */
/******************************************************************************
* Payloads *
******************************************************************************/
/** Sets payload type. Supplied parameter must be one of: PL_RAND, PL_HEX or
* PL_FILE;
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setPayloadType(int t){
if( t!=PL_RAND && t!=PL_HEX && t!=PL_FILE && t!=PL_STRING){
nping_fatal(QT_3,"setPayloadType(): Invalid value supplied\n");
return OP_FAILURE;
}else{
payload_type=t;
}
this->payload_type_set=true;
return OP_SUCCESS;
} /* End of setPayloadType() */
/** Returns value of attribute payload_type */
int NpingOps::getPayloadType(){
return payload_type;
} /* End of getPayloadType() */
/* Returns true if option has been set */
bool NpingOps::issetPayloadType(){
return this->payload_type_set;
} /* End of issetPayloadType() */
/** Sets payload buffer pointer. Supplied pointer must be a free()able
* non-NULL pointer; Supplied length must be a positive integer.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setPayloadBuffer(u8 *p, int len){
if( p==NULL || len < 0 ){
nping_fatal(QT_3,"setPayloadBuffer(): Invalid value supplied\n");
return OP_FAILURE;
}else{
this->payload_buff=p;
this->payload_len=len;
}
this->payload_buff_set=true;
this->payload_len_set=true;
return OP_SUCCESS;
} /* End of setPayloadBuffer() */
/** Returns value of attribute payload_type */
u8 *NpingOps::getPayloadBuffer(){
return this->payload_buff;
} /* End of getPayloadBuffer() */
/* Returns true if option has been set */
bool NpingOps::issetPayloadBuffer(){
return this->payload_buff_set;
} /* End of issetPayloadBuffer() */
/** Returns value of attribute payload_len */
int NpingOps::getPayloadLen(){
return this->payload_len;
} /* End of getPayloadLen() */
/* Returns true if option has been set */
bool NpingOps::issetPayloadLen(){
return this->payload_len_set;
} /* End of issetPayloadLen() */
/******************************************************************************
* Roles (normal, client, server... ) *
******************************************************************************/
/** Sets nping's role. Supplied argument must be one of: ROLE_NORMAL,
* ROLE_CLIENT or ROLE_SERVER.
* @return previous value of attribute "role" or OP_FAILURE in case of error.
* */
int NpingOps::setRole(int r){
int prev = this->role;
if (r!=ROLE_NORMAL && r!=ROLE_CLIENT && r!=ROLE_SERVER){
nping_warning(QT_2,"setRoleClient(): Invalid role supplied");
return OP_FAILURE;
}
else
this->role=r;
this->role_set=true;
return prev;
} /* End of setRole() */
/** Sets nping's role to ROLE_CLIENT.
* @return previous value of attribute "role". */
int NpingOps::setRoleClient(){
int prev = this->role;
this->role=ROLE_CLIENT;
this->role_set=true;
return prev;
} /* End of setRoleClient() */
/** Sets nping's role to ROLE_SERVER.
* @return previous value of attribute "role". */
int NpingOps::setRoleServer(){
int prev = this->role;
this->role=ROLE_SERVER;
this->role_set=true;
return prev;
} /* End of setRoleServer() */
/** Sets nping's role to ROLE_NORMAL.
* @return previous value of attribute "role". */
int NpingOps::setRoleNormal(){
int prev = this->role;
this->role=ROLE_NORMAL;
this->role_set=true;
return prev;
} /* End of setRoleNormal() */
/* Returns nping role. */
int NpingOps::getRole(){
return this->role;
} /* End of getRole() */
/* Returns true if option has been set */
bool NpingOps::issetRole(){
return this->role_set;
} /* End of issetRole() */
/******************************************************************************
* Internet Protocol Version 4 *
******************************************************************************/
/** Sets IPv4 TTL / IPv6 hop limit. Supplied parameter must be an integer
* between 0 and 255 (included).
* @return OP_SUCCESS */
int NpingOps::setTTL(u8 t){
this->ttl=t;
this->ttl_set=true;
return OP_SUCCESS;
} /* End of setTTL() */
/** Sets IPv4 TTL / IPv6 hop limit. This a wrapper for setTTL(). It is provided
* for consistency with IPv6 option setters.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setHopLimit(u8 t){
return setTTL(t);
} /* End of setHopLimit() */
/** Returns value of attribute ttl */
u8 NpingOps::getTTL(){
return ttl;
} /* End of getTTL() */
/** Returns value of attribute ttl */
u8 NpingOps::getHopLimit(){
return getTTL();
} /* End of getHopLimit() */
/* Returns true if option has been set */
bool NpingOps::issetTTL(){
return this->ttl_set;
} /* End of issetTTL() */
/* Returns true if option has been set */
bool NpingOps::issetHopLimit(){
return issetTTL();
} /* End of issetHopLimit() */
/** Sets IP TOS. Supplied parameter must be 0<=n<=255
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setTOS(u8 val){
this->tos=val;
this->tos_set=true;
return OP_SUCCESS;
} /* End of setTOS() */
/** Returns value of attribute TOS */
u8 NpingOps::getTOS(){
return this->tos;
} /* End of getTOS() */
/* Returns true if option has been set */
bool NpingOps::issetTOS(){
return this->tos_set;
} /* End of isset() */
/** Sets IP Identification. Supplied parameter must be 0<=n<=255
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setIdentification(u16 val){
this->identification=val;
this->identification_set=true;
return OP_SUCCESS;
} /* End of setIdentification() */
/** Returns value of attribute Identification */
u16 NpingOps::getIdentification(){
return this->identification;
} /* End of getIdentification() */
/* Returns true if option has been set */
bool NpingOps::issetIdentification(){
return this->identification_set;
} /* End of issetIdentification() */
int NpingOps::setMF(){
this->mf = true;
this->mf_set=true;
return OP_SUCCESS;
} /* End of setMF() */
/* Get MF flag */
bool NpingOps::getMF(){
return this->mf;
} /* End of getMF() */
/** Set DF flag */
int NpingOps::setDF(){
this->df = true;
this->df_set=true;
return OP_SUCCESS;
} /* End of setDF() */
/** Get DF flag */
bool NpingOps::getDF(){
return this->df;
} /* End of getDF() */
/* Returns true if option has been set */
bool NpingOps::issetMF(){
return this->mf_set;
} /* End of isset() */
/* Returns true if option has been set */
bool NpingOps::issetDF(){
return this->df_set;
} /* End of isset() */
/** Sets Maximum Transmission Unit length. Supplied parameter must be a positive
* integer and must be a multiple of 8.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setMTU(u32 t){
if(t==0 || (t%8)!=0){
nping_fatal(QT_3,"setMTU(): Invalid mtu supplied\n");
}else{
this->mtu=t;
this->mtu_set=true;
}
return OP_SUCCESS;
} /* End of setMTU() */
/** Returns value of attribute mtu */
u32 NpingOps::getMTU(){
return this->mtu;
} /* End of getMTU() */
/* Returns true if option has been set */
bool NpingOps::issetMTU(){
return this->mtu_set;
} /* End of issetMTU() */
/** Sets attribute badsum_ip to "true". (Generate invalid checksums in IP
* packets)
* @return previous value of the attribute. */
bool NpingOps::enableBadsumIP() {
bool prev = this->badsum_ip;
this->badsum_ip=true;
this->badsum_ip_set=true;
return prev;
} /* End of enableBadsumIP() */
/** Sets attribute badsum_ip to "false". (Do NOT Generate invalid checksums
* in IP packets)
* @return previous value of the attribute. */
bool NpingOps::disableBadsumIP() {
bool prev = badsum_ip;
badsum_ip=false;
this->badsum_ip_set=true;
return prev;
} /* End of disableBadsumIP() */
/** Returns value of attribute badsum_ip */
bool NpingOps::getBadsumIP() {
return this->badsum_ip;
} /* End of getBadsumIP() */
/* Returns true if option has been set */
bool NpingOps::issetBadsumIP(){
return this->badsum_ip_set;
} /* End of issetBadsumIP() */
/** @warning Supplied parameter must be in NETWORK byte order */
int NpingOps::setIPv4SourceAddress(struct in_addr i){
this->ipv4_src_address=i;
this->ipv4_src_address_set=true;
return OP_SUCCESS;
} /* End of setIPv4SourceAddress() */
struct in_addr NpingOps::getIPv4SourceAddress(){
return ipv4_src_address;
} /* End of getIPv4SourceAddress() */
/* Returns true if option has been set */
bool NpingOps::issetIPv4SourceAddress(){
return this->ipv4_src_address_set;
} /* End of issetIPv4SourceAddress() */
/** @warning This method makes a copy of the supplied buffer. That copy will
* be free()ed by the NpingOps destructor. */
int NpingOps::setIPOptions(char *txt){
if (txt==NULL)
nping_fatal(QT_3,"setIPOptions(): NULL pointer supplied\n");
this->ip_options=strdup(txt) ;
this->ip_options_set=true;
return OP_SUCCESS;
} /* End of setIPOptions() */
char *NpingOps::getIPOptions(){
return this->ip_options;
} /* End of getIPOptions() */
bool NpingOps::issetIPOptions(){
return this->ip_options_set;
} /* End of issetIPOptions() */
/******************************************************************************
* Internet Protocol Version 6 *
******************************************************************************/
/** Sets TrafficClass.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setTrafficClass(u8 val){
this->ipv6_tclass=val;
this->ipv6_tclass_set=true;
return OP_SUCCESS;
} /* End of setTrafficClass() */
/** Returns value of attribute ipv6_tclass */
u8 NpingOps::getTrafficClass(){
return this->ipv6_tclass;
} /* End of getTrafficClass() */
/* Returns true if option has been set */
bool NpingOps::issetTrafficClass(){
return this->ipv6_tclass_set;
} /* End of issetTrafficClass() */
/** Sets FlowLabel.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setFlowLabel(u32 val){
this->ipv6_flowlabel=val;
this->ipv6_flowlabel_set=true;
return OP_SUCCESS;
} /* End of setFlowLabel() */
/** Returns value of attribute ipv6_flowlabel */
u32 NpingOps::getFlowLabel(){
return this->ipv6_flowlabel;
} /* End of getFlowLabel() */
/* Returns true if option has been set */
bool NpingOps::issetFlowLabel(){
return this->ipv6_flowlabel_set;
} /* End of issetFlowLabel() */
int NpingOps::setIPv6SourceAddress(u8 *val){
if(val==NULL)
nping_fatal(QT_3,"setIPv6SourceAddress(): NULL pointer supplied\n");
memcpy(this->ipv6_src_address.s6_addr, val, 16);
this->ipv6_src_address_set=true;
return OP_SUCCESS;
} /* End of setIPv6SourceAddress() */
int NpingOps::setIPv6SourceAddress(struct in6_addr val){
this->ipv6_src_address = val;
this->ipv6_src_address_set=true;
return OP_SUCCESS;
} /* End of setIPv6SourceAddress() */
struct in6_addr NpingOps::getIPv6SourceAddress(){
return ipv6_src_address;
} /* End of getIPv6SourceAddress() */
/* Returns true if option has been set */
bool NpingOps::issetIPv6SourceAddress(){
return this->ipv6_src_address_set;
} /* End of issetIPv6SourceAddress() */
/* Returns a pointer to a sockaddr_storage structure that contains the
* source IP address. This function takes into account this->getIPVersion()
* an returns an IPv4 sockaddr_in or an IPv6 sockaddr_in6 struct. */
struct sockaddr_storage *NpingOps::getSourceSockAddr(){
static struct sockaddr_storage ss;
return getSourceSockAddr(&ss);
} /* End of getSourceSockAddr() */
/* Returns a pointer to the supplied sockaddr_storage structure that now
* contains the source IP address. This function takes into account
* this->getIPVersion() an returns an IPv4 sockaddr_in or an IPv6
* sockaddr_in6 struct. */
struct sockaddr_storage *NpingOps::getSourceSockAddr(struct sockaddr_storage *ss){
struct sockaddr_in *s4 = (struct sockaddr_in*)ss;
struct sockaddr_in6 *s6 = (struct sockaddr_in6*)ss;
memset(ss, 0, sizeof(struct sockaddr_storage));
if( this->getIPVersion() == IP_VERSION_4){
if(this->spoofSource())
s4->sin_addr=getIPv4SourceAddress();
else
s4->sin_addr.s_addr=INADDR_ANY;
s4->sin_family=AF_INET;
if(this->issetSourcePort())
s4->sin_port=htons(this->getSourcePort());
else
s4->sin_port=0;
}
else if (this->getIPVersion() == IP_VERSION_6){
if(this->spoofSource())
s6->sin6_addr=this->getIPv6SourceAddress();
else
s6->sin6_addr=in6addr_any;
s6->sin6_addr=this->getIPv6SourceAddress();
s6->sin6_family=AF_INET6;
if(this->issetSourcePort())
s6->sin6_port=htons(this->getSourcePort());
else
s6->sin6_port=0;
}else{
nping_fatal(QT_3, "NpingOps::getSourceSockAddr(): IP version unset.");
}
return ss;
} /* End of getSourceSockAddr() */
/******************************************************************************
* Transmission Control Protocol and User Datagram Protocol *
******************************************************************************/
/** @warning Returned ports are in HOST byte order */
u16 *NpingOps::getTargetPorts( int *len ){
if( this->tportcount <= 0)
return NULL;
if(len!=NULL)
*len=this->tportcount;
return this->target_ports;
} /* End of getTargetPorts() */
/** @warning ports in the supplied array must be in HOST byte order */
int NpingOps::setTargetPorts( u16 *pnt, int n ){
if(this->tportcount>65536 || this->tportcount<0)
nping_fatal(QT_3, "setTargetPorts():: Invalid number of ports supplied.");
this->target_ports=pnt;
this->tportcount=n;
this->target_ports_set=true;
return OP_SUCCESS;
} /* End of setTargetPorts() */
/* Returns true if option has been set */
bool NpingOps::issetTargetPorts(){
return this->target_ports_set;
} /* End of issetTargetPorts() */
/*Returns true if the scan type can use the -p option*/
bool NpingOps::scan_mode_uses_target_ports(int mode){
return (mode==TCP_CONNECT || mode==TCP || mode == UDP || mode == UDP_UNPRIV);
} /*End of scan_mode_uses_target_ports*/
/** Sets TCP/UPD source port. Supplied parameter must be an integer >=0 &&
* <=65535
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setSourcePort(u16 val){
this->source_port=val;
this->source_port_set=true;
return OP_SUCCESS;
} /* End of setSourcePort() */
/** Returns value of attribute source_port */
u16 NpingOps::getSourcePort(){
return this->source_port;
} /* End of getSourcePort() */
/* Returns true if option has been set */
bool NpingOps::issetSourcePort(){
return this->source_port_set;
} /* End of issetSourcePort() */
/** Sets TCP Seq number. Supplied parameter must be a positive integer between
* 0 and 2^32 -1
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setTCPSequence(u32 val){
this->tcpseq=val;
this->tcpseq_set=true;
return OP_SUCCESS;
} /* End of setTCPSequence() */
/** Returns value of attribute tcpseq */
u32 NpingOps::getTCPSequence(){
return this->tcpseq;
} /* End of getTCPSequence() */
/** Returns true if option has been set */
bool NpingOps::issetTCPSequence(){
return this->tcpseq_set;
} /* End of issetTCPSequence() */
/** Sets TCP Ack. Supplied parameter must be a positive integer between 0 and
* 2^32 -1
* @return OP_SUCCESS */
int NpingOps::setTCPAck(u32 val){
this->tcpack=val;
this->tcpack_set=true;
return OP_SUCCESS;
} /* End of setTCPAck() */
/** Returns value of attribute tcpack */
u32 NpingOps::getTCPAck(){
return this->tcpack;
} /* End of getTCPAck() */
/** Returns true if option has been set */
bool NpingOps::issetTCPAck(){
return this->tcpack_set;
} /* End of issetTCPAck() */
int NpingOps::setFlagTCP(int flag){
if (flag < FLAG_CWR || flag > FLAG_FIN)
nping_fatal(QT_3,"setFlagTCP(): Invalid flag supplied\n");
else
this->tcpflags[flag]=1;
this->tcpflags_set=true;
return OP_SUCCESS;
} /* End of setFlagTCP() */
int NpingOps::setAllFlagsTCP(){
for(int i=FLAG_CWR; i<=FLAG_FIN; i++)
this->tcpflags[i]=1;
this->tcpflags_set=true;
return OP_SUCCESS;
} /* End of setFlagTCP() */
int NpingOps::unsetAllFlagsTCP(){
for(int i=FLAG_CWR; i<=FLAG_FIN; i++)
this->tcpflags[i]=0;
this->tcpflags_set=true;
return OP_SUCCESS;
} /* End of setFlagTCP() */
int NpingOps::getFlagTCP(int flag){
if (flag < FLAG_CWR || flag > FLAG_FIN)
nping_fatal(QT_3,"setFlagTCP(): Invalid flag supplied\n");
return this->tcpflags[flag];
} /* End of getFlagTCP() */
u8 NpingOps::getTCPFlags(){
u8 octet=0x00;
if(this->getFlagTCP(FLAG_CWR))
octet |= TH_CWR;
if(this->getFlagTCP(FLAG_ECN))
octet |= TH_ECN;
if(this->getFlagTCP(FLAG_URG))
octet |= TH_URG;
if(this->getFlagTCP(FLAG_ACK))
octet |= TH_ACK;
if(this->getFlagTCP(FLAG_PSH))
octet |= TH_PSH;
if(this->getFlagTCP(FLAG_RST))
octet |= TH_RST;
if(this->getFlagTCP(FLAG_SYN))
octet |= TH_SYN;
if(this->getFlagTCP(FLAG_FIN))
octet |= TH_FIN;
return octet;
} /* End of getTCPFlags() */
/* Returns true if option has been set */
bool NpingOps::issetTCPFlags(){
return this->tcpflags_set;
} /* End of isset() */
/** Sets TCP Window. Supplied parameter must be a positive integer between 0 and
* 2^32 -1
* @return OP_SUCCESS */
int NpingOps::setTCPWindow(u16 val){
this->tcpwin=val;
this->tcpwin_set=true;
return OP_SUCCESS;
} /* End of setTCPWindow() */
/** Returns value of attribute tcpwin */
u16 NpingOps::getTCPWindow(){
return this->tcpwin;
} /* End of getTCPWindow() */
/** Returns true if option has been set */
bool NpingOps::issetTCPWindow(){
return this->tcpwin_set;
} /* End of issetTCPWindow() */
/** Sets attribute badsum to "true". (Generate invalid checksums in UDP / TCP
* packets)
* @return previous value of the attribute. */
bool NpingOps::enableBadsum() {
bool prev = this->badsum;
this->badsum=true;
this->badsum_set=true;
return prev;
} /* End of enableBadsumTCP() */
/** Sets attribute traceroute to "false". (Do NOT Generate invalid checksums
* in UDP / TCP packets)
* @return previous value of the attribute. */
bool NpingOps::disableBadsum() {
bool prev = this->badsum;
this->badsum=false;
this->badsum_set=true;
return prev;
} /* End of disableBadsum() */
/** Returns value of attribute badsum */
bool NpingOps::getBadsum() {
return this->badsum;
} /* End of getBadsum() */
/* Returns true if option has been set */
bool NpingOps::issetBadsum(){
return this->badsum_set;
} /* End of issetBadsum() */
/******************************************************************************
* Internet Control Message Protocol *
******************************************************************************/
/** Sets ICMPType.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setICMPType(u8 val){
this->icmp_type=val;
this->icmp_type_set=true;
return OP_SUCCESS;
} /* End of setICMPType() */
/** Returns value of attribute icmp_type */
u8 NpingOps::getICMPType(){
return this->icmp_type;
} /* End of getICMPType() */
/* Returns true if option has been set */
bool NpingOps::issetICMPType(){
return this->icmp_type_set;
} /* End of issetICMPType() */
/** Sets ICMPCode.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setICMPCode(u8 val){
this->icmp_code=val;
this->icmp_code_set=true;
return OP_SUCCESS;
} /* End of setICMPCode() */
/** Returns value of attribute icmp_code */
u8 NpingOps::getICMPCode(){
return this->icmp_code;
} /* End of getICMPCode() */
/* Returns true if option has been set */
bool NpingOps::issetICMPCode(){
return this->icmp_code_set;
} /* 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){
this->icmp_redir_addr=val;
this->icmp_redir_addr_set=true;
return OP_SUCCESS;
} /* End of setICMPRedirectAddress() */
/** Returns value of attribute icmp_redir_addr */
struct in_addr NpingOps::getICMPRedirectAddress(){
return this->icmp_redir_addr;
} /* End of getICMPRedirectAddress() */
/* Returns true if option has been set */
bool NpingOps::issetICMPRedirectAddress(){
return this->icmp_redir_addr_set;
} /* End of issetICMPRedirectAddress() */
/** Sets ICMPParamProblemPointer.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setICMPParamProblemPointer(u8 val){
this->icmp_paramprob_pnt=val;
this->icmp_paramprob_pnt_set=true;
return OP_SUCCESS;
} /* End of setICMPParamProblemPointer() */
/** Returns value of attribute icmp_paramprob_pnt */
u8 NpingOps::getICMPParamProblemPointer(){
return this->icmp_paramprob_pnt;
} /* End of getICMPParamProblemPointer() */
/* Returns true if option has been set */
bool NpingOps::issetICMPParamProblemPointer(){
return this->icmp_paramprob_pnt_set;
} /* End of issetICMPParamProblemPointer() */
/** Sets ICMPRouterAdvLifetime.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setICMPRouterAdvLifetime(u16 val){
this->icmp_routeadv_ltime=val;
this->icmp_routeadv_ltime_set=true;
return OP_SUCCESS;
} /* End of setICMPRouterAdvLifetime() */
/** Returns value of attribute icmp_routeadv_ltime */
u16 NpingOps::getICMPRouterAdvLifetime(){
return this->icmp_routeadv_ltime;
} /* End of getICMPRouterAdvLifetime() */
/* Returns true if option has been set */
bool NpingOps::issetICMPRouterAdvLifetime(){
return this->icmp_routeadv_ltime_set;
} /* End of issetICMPRouterAdvLifetime() */
/** Sets ICMPIdentifier.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setICMPIdentifier(u16 val){
this->icmp_id=val;
this->icmp_id_set=true;
return OP_SUCCESS;
} /* End of setICMPIdentifier() */
/** Returns value of attribute icmp_id */
u16 NpingOps::getICMPIdentifier(){
return this->icmp_id;
} /* End of getICMPIdentifier() */
/* Returns true if option has been set */
bool NpingOps::issetICMPIdentifier(){
return this->icmp_id_set;
} /* End of issetICMPIdentifier() */
/** Sets ICMPSequence.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setICMPSequence(u16 val){
this->icmp_seq=val;
this->icmp_seq_set=true;
return OP_SUCCESS;
} /* End of setICMPSequence() */
/** Returns value of attribute icmp_seq */
u16 NpingOps::getICMPSequence(){
return this->icmp_seq;
} /* End of getICMPSequence() */
/* Returns true if option has been set */
bool NpingOps::issetICMPSequence(){
return this->icmp_seq_set;
} /* End of issetICMPSequence() */
/** Sets ICMPOriginateTimestamp.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setICMPOriginateTimestamp(u32 val){
this->icmp_orig_time=val;
this->icmp_orig_time_set=true;
return OP_SUCCESS;
} /* End of setICMPOriginateTimestamp() */
/** Returns value of attribute icmp_orig_time */
u32 NpingOps::getICMPOriginateTimestamp(){
return this->icmp_orig_time;
} /* End of getICMPOriginateTimestamp() */
/* Returns true if option has been set */
bool NpingOps::issetICMPOriginateTimestamp(){
return this->icmp_orig_time_set;
} /* End of issetICMPOriginateTimestamp() */
/** Sets ICMPReceiveTimestamp.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setICMPReceiveTimestamp(u32 val){
this->icmp_recv_time=val;
this->icmp_recv_time_set=true;
return OP_SUCCESS;
} /* End of setICMPReceiveTimestamp() */
/** Returns value of attribute icmp_recv_time */
u32 NpingOps::getICMPReceiveTimestamp(){
return this->icmp_recv_time;
} /* End of getICMPReceiveTimestamp() */
/* Returns true if option has been set */
bool NpingOps::issetICMPReceiveTimestamp(){
return this->icmp_recv_time_set;
} /* End of issetICMPReceiveTimestamp() */
/** Sets ICMPTransmitTimestamp.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setICMPTransmitTimestamp(u32 val){
this->icmp_trans_time=val;
this->icmp_trans_time_set=true;
return OP_SUCCESS;
} /* End of setICMPTransmitTimestamp() */
/** Returns value of attribute icmp_trans_time */
u32 NpingOps::getICMPTransmitTimestamp(){
return this->icmp_trans_time;
} /* End of getICMPTransmitTimestamp() */
/* Returns true if option has been set */
bool NpingOps::issetICMPTransmitTimestamp(){
return this->icmp_trans_time_set;
} /* End of issetICMPTransmitTimestamp() */
int NpingOps::addICMPAdvertEntry(struct in_addr addr, u32 pref ){
if( this->icmp_advert_entry_count > MAX_ICMP_ADVERT_ENTRIES )
return OP_FAILURE;
this->icmp_advert_entry_addr[this->icmp_advert_entry_count] = addr;
this->icmp_advert_entry_pref[this->icmp_advert_entry_count] = pref;
this->icmp_advert_entry_count++;
this->icmp_advert_entry_set=true;
return OP_SUCCESS;
} /* End of addICMPAdvertEntry() */
/** @param num means that the caller wants to obtain the num-th entry.
* Count starts in 0 so the supplied value must be
* 0 <= num < getICMPAdvertEntryCount() */
int NpingOps::getICMPAdvertEntry(int num, struct in_addr *addr, u32 *pref){
if( num<0 || num>=icmp_advert_entry_count )
nping_fatal(QT_3,"getICMPAdvertEntry(): Supplied index is out of bounds.\n");
if( addr==NULL || pref==NULL)
nping_fatal(QT_3,"getICMPAdvertEntry(): NULL pointer supplied\n");
*addr = this->icmp_advert_entry_addr[num];
*pref = this->icmp_advert_entry_pref[num];
return OP_SUCCESS;
} /* End of getICMPAdvertEntry() */
int NpingOps::getICMPAdvertEntryCount(){
return this->icmp_advert_entry_count;
} /* End of getICMPAdvertEntryCount()*/
bool NpingOps::issetICMPAdvertEntry(){
return this->icmp_advert_entry_set;
} /* End of issetICMPAdvertEntry()*/
/******************************************************************************
* Ethernet *
******************************************************************************/
/** Sets SourceMAC.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setSourceMAC(u8 * val){
memcpy(this->src_mac, val, 6);
this->src_mac_set=true;
return OP_SUCCESS;
} /* End of setSourceMAC() */
/** Returns value of attribute src_mac */
u8 * NpingOps::getSourceMAC(){
return this->src_mac;
} /* End of getSourceMAC() */
/* Returns true if option has been set */
bool NpingOps::issetSourceMAC(){
return this->src_mac_set;
} /* End of issetSourceMAC() */
/** Sets DestMAC.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setDestMAC(u8 * val){
memcpy(this->dst_mac, val, 6);
this->dst_mac_set=true;
return OP_SUCCESS;
} /* End of setDestMAC() */
/** Returns value of attribute dst_mac */
u8 * NpingOps::getDestMAC(){
return this->dst_mac;
} /* End of getDestMAC() */
/* Returns true if option has been set */
bool NpingOps::issetDestMAC(){
return this->dst_mac_set;
} /* End of issetDestMAC() */
/** Sets EtherType.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setEtherType(u16 val){
this->eth_type=val;
this->eth_type_set=true;
return OP_SUCCESS;
} /* End of setEtherType() */
/** Returns value of attribute eth_type */
u16 NpingOps::getEtherType(){
return this->eth_type;
} /* End of getEtherType() */
/* Returns true if option has been set */
bool NpingOps::issetEtherType(){
return this->eth_type_set;
} /* End of issetEtherType() */
/******************************************************************************
* Address Resolution Protocol / Reverse Address Resolution Protocol *
******************************************************************************/
/** Sets ARPHardwareType.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setARPHardwareType(u16 val){
this->arp_htype=val;
this->arp_htype_set=true;
return OP_SUCCESS;
} /* End of setARPHardwareType() */
/** Returns value of attribute arp_htype */
u16 NpingOps::getARPHardwareType(){
return this->arp_htype;
} /* End of getARPHardwareType() */
/* Returns true if option has been set */
bool NpingOps::issetARPHardwareType(){
return this->arp_htype_set;
} /* End of issetARPHardwareType() */
/** Sets ARPProtocolType.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setARPProtocolType(u16 val){
this->arp_ptype=val;
this->arp_ptype_set=true;
return OP_SUCCESS;
} /* End of setARPProtocolType() */
/** Returns value of attribute arp_ptype */
u16 NpingOps::getARPProtocolType(){
return this->arp_ptype;
} /* End of getARPProtocolType() */
/* Returns true if option has been set */
bool NpingOps::issetARPProtocolType(){
return this->arp_ptype_set;
} /* End of issetARPProtocolType() */
/** Sets ARPHwAddrLen.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setARPHwAddrLen(u8 val){
this->arp_hlen=val;
this->arp_hlen_set=true;
return OP_SUCCESS;
} /* End of setARPHwAddrLen() */
/** Returns value of attribute arp_hlen */
u8 NpingOps::getARPHwAddrLen(){
return this->arp_hlen;
} /* End of getARPHwAddrLen() */
/* Returns true if option has been set */
bool NpingOps::issetARPHwAddrLen(){
return this->arp_hlen_set;
} /* End of issetARPHwAddrLen() */
/** Sets ARPProtoAddrLen.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setARPProtoAddrLen(u8 val){
this->arp_plen=val;
this->arp_plen_set=true;
return OP_SUCCESS;
} /* End of setARPProtoAddrLen() */
/** Returns value of attribute arp_plen */
u8 NpingOps::getARPProtoAddrLen(){
return this->arp_plen;
} /* End of getARPProtoAddrLen() */
/* Returns true if option has been set */
bool NpingOps::issetARPProtoAddrLen(){
return this->arp_plen_set;
} /* End of issetARPProtoAddrLen() */
/** Sets ARPOpCode.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setARPOpCode(u16 val){
this->arp_opcode=val;
this->arp_opcode_set=true;
return OP_SUCCESS;
} /* End of setARPOpCode() */
/** Returns value of attribute arp_opcode */
u16 NpingOps::getARPOpCode(){
return this->arp_opcode;
} /* End of getARPOpCode() */
/* Returns true if option has been set */
bool NpingOps::issetARPOpCode(){
return this->arp_opcode_set;
} /* End of issetARPOpCode() */
/** Sets ARPSenderHwAddr.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setARPSenderHwAddr(u8 * val){
memcpy(this->arp_sha, val, 6); /* MAC Address (6 bytes) */
this->arp_sha_set=true;
return OP_SUCCESS;
} /* End of setARPSenderHwAddr() */
/** Returns value of attribute arp_sha */
u8 * NpingOps::getARPSenderHwAddr(){
return this->arp_sha;
} /* End of getARPSenderHwAddr() */
/* Returns true if option has been set */
bool NpingOps::issetARPSenderHwAddr(){
return this->arp_sha_set;
} /* End of issetARPSenderHwAddr() */
/** Sets ARPTargetHwAddr.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setARPTargetHwAddr(u8 * val){
memcpy(this->arp_tha, val, 6); /* MAC Address (6 bytes) */
this->arp_tha_set=true;
return OP_SUCCESS;
} /* End of setARPTargetHwAddr() */
/** Returns value of attribute arp_tha */
u8 * NpingOps::getARPTargetHwAddr(){
return this->arp_tha;
} /* End of getARPTargetHwAddr() */
/* Returns true if option has been set */
bool NpingOps::issetARPTargetHwAddr(){
return this->arp_tha_set;
} /* End of issetARPTargetHwAddr() */
/** Sets ARPSenderProtoAddr.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setARPSenderProtoAddr(struct in_addr val){
this->arp_spa=val;
this->arp_spa_set=true;
return OP_SUCCESS;
} /* End of setARPSenderProtoAddr() */
/** Returns value of attribute arp_spa */
struct in_addr NpingOps::getARPSenderProtoAddr(){
return this->arp_spa;
} /* End of getARPSenderProtoAddr() */
/* Returns true if option has been set */
bool NpingOps::issetARPSenderProtoAddr(){
return this->arp_spa_set;
} /* End of issetARPSenderProtoAddr() */
/** Sets ARPTargetProtoAddr.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setARPTargetProtoAddr(struct in_addr val){
this->arp_tpa=val;
this->arp_tpa_set=true;
return OP_SUCCESS;
} /* End of setARPTargetProtoAddr() */
/** Returns value of attribute arp_tpa */
struct in_addr NpingOps::getARPTargetProtoAddr(){
return this->arp_tpa;
} /* End of getARPTargetProtoAddr() */
/* Returns true if option has been set */
bool NpingOps::issetARPTargetProtoAddr(){
return this->arp_tpa_set;
} /* End of issetARPTargetProtoAddr() */
/** Sets EchoPort.
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
int NpingOps::setEchoPort(u16 val){
this->echo_port=val;
this->echo_port_set=true;
return OP_SUCCESS;
} /* End of setEchoPort() */
/** Returns value of attribute echo_port */
u16 NpingOps::getEchoPort(){
return this->echo_port;
} /* End of getEchoPort() */
/* Returns true if option has been set */
bool NpingOps::issetEchoPort(){
return this->echo_port_set;
} /* End of issetEchoPort() */
int NpingOps::setEchoPassphrase(const char *str){
strncpy(this->echo_passphrase, str, sizeof(echo_passphrase)-1);
this->echo_passphrase_set=true;
return OP_SUCCESS;
} /* End of setEchoPassphrase() */
char *NpingOps::getEchoPassphrase(){
return this->echo_passphrase;
} /* End of getEchoPassphrase() */
bool NpingOps::issetEchoPassphrase(){
return this->echo_passphrase_set;
} /* End of issetEchoPassphrase() */
/** Sets value of this->echo_server_once. When true, the echo server
* will exit after attending one client. */
int NpingOps::setOnce(bool val){
this->echo_server_once=val;
this->echo_server_once_set=true;
return OP_SUCCESS;
} /* End of once() */
/** Returns value of attribute echo_port */
bool NpingOps::once(){
return this->echo_server_once;
} /* End of once() */
/******************************************************************************
* Option Validation *
******************************************************************************/
void NpingOps::validateOptions() {
/** DETERMINE ROOT PRIVILEGES ************************************************/
const char *privreq = "root privileges";
#ifdef WIN32
//if (!this->have_pcap)
privreq = "Npcap, but it seems to be missing.\n\
Npcap is available from https://npcap.org. The Npcap driver service must\n\
be started by an administrator before Npcap can be used. Running nping.exe\n\
will open a UAC dialog where you can start the service if you have\n\
administrator privileges.";
#endif
if (this->havePcap()==false){
#ifdef WIN32
nping_fatal(QT_3, "Nping requires %s", privreq);
#else
nping_fatal(QT_3, "Nping requires libpcap to be installed on your system.");
#endif
}
/** ROLE SELECTION ***********************************************************/
/* Ensure that at least one role is selected */
if ( !this->issetRole() ) {
this->setRoleNormal();
}
/** TARGET SPECIFICATION *****************************************************/
/* Check if user entered at least one target spec */
if( this->getRole() == ROLE_NORMAL ){
if ( this->targets.getTargetSpecCount() <= 0 )
nping_fatal(QT_3,"WARNING: No targets were specified, so 0 hosts pinged.");
}else if( this->getRole() == ROLE_CLIENT ){
if ( this->targets.getTargetSpecCount() <= 0 )
nping_fatal(QT_3,"No echo server was specified.");
}
/** IP VERSION ***************************************************************/
/* Default to IP version 4 */
if( !this->issetIPVersion() )
this->setIPVersion( IP_VERSION_4 );
/** PROBE MODE SELECTION *****************************************************/
/* Ensure that one probe mode is selected */
if( !this->issetMode() ){
if ( this->isRoot() ){
if( !this->ipv6() )
this->setMode(ICMP);
else
this->setMode(TCP);
}
else
this->setMode(TCP_CONNECT);
}
/** PACKET COUNT / ROUNDS ****************************************************/
if( !this->issetPacketCount() ){
/* If --traceroute is set, the packet count is higher */
if(this->issetTraceroute() )
this->setPacketCount( TRACEROUTE_PACKET_COUNT );
else
this->setPacketCount( DEFAULT_PACKET_COUNT );
}
if( !this->issetDelay() )
this->setDelay( DEFAULT_DELAY );
/** UDP UNPRIVILEGED MODE? ***************************************************/
/* If user is NOT root and specified UDP mode, check if he did not specify
* any option that requires privileges. In that case, we enter
* UDP-Unprivileged mode, where users can send UDP packets and read responses
* trough a normal UDP socket. */
if( !this->isRoot() && this->getMode()==UDP && canRunUDPWithoutPrivileges() )
this->setMode( UDP_UNPRIV );
/** CHECK PRIVILEGES FOR CURRENT ROLE ****************************************/
if( !this->isRoot() && (this->getRole()==ROLE_SERVER || this->getRole()==ROLE_CLIENT) )
nping_fatal(QT_3,"Echo mode requires %s.", privreq);
/** CHECK PRIVILEGES FOR CURRENT MODE ****************************************/
if( !this->isRoot() && this->getMode()!=UDP_UNPRIV && this->getMode()!=TCP_CONNECT )
nping_fatal(QT_3,"Mode %s requires %s.", this->mode2Ascii( this->getMode() ), privreq);
/** DEFAULT HEADER PARAMETERS *************************************************/
this->setDefaultHeaderValues();
/** ARP MODE RELATED PARAMETERS *********************************************/
if(this->getMode()==ARP && this->ipv6()) {
nping_fatal(QT_3, "Sorry, ARP does not support IPv6 and Nping does not yet support NDP.");
}
/** TCP CONNECT RELATED PARAMETERS *********************************************/
if(this->getMode()==TCP_CONNECT) {
if(this->issetPayloadBuffer())
nping_print(VB_0, "Warning: Payload supplied in TCP Connect mode. Payload will be ignored.");
}
/** SOURCE IP, SOURCE MAC and NETWORK DEVICE *********************************/
/* If we are in a mode where we need to craft IP packets, then we need to
* obtain a network interface name and a source IP address. There are three
* different possibilities:
* 1. User did NOT specify both network interface and source IP address.
* 2. User did specify a network interface but not a source IP address.
* 3. User did actually supply a source IP but not a network interface name
*
* I know the following code is ugly but the thing is that we want to determine
* interface and source IP without user intervention, so we try in many ways
* until either we succeed or we run out of possibilities and fatal().
*/
if( this->getMode()!=TCP_CONNECT && this->getMode()!=UDP_UNPRIV && this->getRole()!=ROLE_SERVER){
char devbuff[32];
char *dev;
struct sockaddr_storage ss, ifaddr;
struct sockaddr_in *s4=(struct sockaddr_in *)&ifaddr;
struct sockaddr_in6 *s6=(struct sockaddr_in6 *)&ifaddr;
size_t ss_len;
char hostname[128];
memset(&ss, 0, sizeof(struct sockaddr_storage));
memset(&ifaddr, 0, sizeof(struct sockaddr_storage));
/* CASE 1: User did not specify a device so we have to select one. */
if( !this->issetDevice() ){
if( this->ipv4() ){
/* Ugly hack. Get the first resolvable target and determine net interface. Let's
* hope user did not specify something that mixes localhost with
* other targets, like "nping localhost google.com playboy.com" */
for(int z=0; z<this->targets.getTargetSpecCount(); z++){
if( this->targets.getNextTargetAddressAndName(&ss, &ss_len, hostname, sizeof(hostname)) == OP_SUCCESS )
break;
else if( z>=(this->targets.getTargetSpecCount()-1) )
nping_fatal(QT_3,"Cannot find a valid target. Please make sure the specified hosts are either IP addresses in standard notation or hostnames that can be resolved with DNS");
}
this->targets.rewind();
/* Try to obtain a device name from the target IP */
if ( getNetworkInterfaceName( &ss , devbuff) != OP_SUCCESS ) {
/* If that didn't work, ask libpcap */
char errbuf[PCAP_ERRBUF_SIZE];
if ( (dev = pcap_lookupdev(errbuf)) == NULL)
nping_fatal(QT_3, "Cannot obtain device for packet capture --> %s", errbuf);
else
this->setDevice( dev );
/* Libpcap gave us a device name, try to obtain it's IP */
if ( devname2ipaddr_alt(this->getDevice(), &ifaddr) != 0 ){
if( this->isRoot() )
nping_fatal(QT_3,"Cannot figure out what source address to use for device %s, does it even exist?", this->getDevice());
else
nping_fatal(QT_3,"Cannot figure out what source address to use for device %s, are you root?", this->getDevice());
}
else{
if( s4->sin_family==AF_INET )
this->setIPv4SourceAddress(s4->sin_addr);
else if ( s6->sin6_family==AF_INET6 )
this->setIPv6SourceAddress(s6->sin6_addr.s6_addr);
}
}else{
this->setDevice(devbuff);
}
}else{ /* In IPv6 we just select one in libpcap and hope is the right one */
char *selected_iface=this->select_network_iface();
if(selected_iface==NULL)
nping_fatal(QT_3, "Error trying to find a suitable network interface ");
else
this->setDevice( selected_iface );
}
} /* CASE 2: User did actually supply a device name */
else{
nping_print(DBG_2, "Using network interface \"%s\"", this->getDevice() );
}
/* The echo server needs to find out a network interface*/
}else if (this->getRole()==ROLE_SERVER && this->issetDevice()==false){
char *selected_iface=this->select_network_iface();
if(selected_iface==NULL)
nping_fatal(QT_3, "Error trying to find a suitable network interface ");
else
this->setDevice( selected_iface );
nping_print(DBG_2, "Using network interface \"%s\"", this->getDevice() );
}
/** RAW IP AND RAW ETHERNET TRANSMISSION MODES *******************************/
/* Determine if we need to send at raw ip level or at raw ethernet level */
if(this->getRole()!=ROLE_SERVER){
if (!this->issetSendPreference()) {
/* CASE 1: ARP requested. We have to do raw ethernet transmission */
if(this->getMode()==ARP ){
this->setSendEth(true);
this->setSendPreference( PACKET_SEND_ETH_STRONG );
}
/* CASE 2: If we are dealing with IPv6 we have two options: send at raw
* eth level or sent at raw transport layer level. So here, we check if the
* user has specified some IPv6 header specific options. If he has, we then
* have to use raw ethernet (since we cannot include our own IPv6 header in
* raw IPv6 sockets). If he hasn't, the best way is to send at raw TCP/UDP
* level so we disable sendEth() */
else if (this->ipv6() ){
/* CASE 2.A: If user did not specify custom IPv6 header or Ethernet
* field values go for raw transport layer level transmission */
if( this->canDoIPv6ThroughSocket() ){
this->setSendEth(false);
this->setSendPreference( PACKET_SEND_IP_STRONG );
}
/* CASE 2.B: User wants to set some IPv6 or Ethernet values. So here we
* check if enough parameters were supplied. */
else if (this->canDoIPv6Ethernet() ){
this->setSendEth(true);
this->setSendPreference( PACKET_SEND_ETH_STRONG );
}else{
nping_fatal(QT_3, "If you want to control some of the fields"
" in the IPv6 header you also have to supply source and"
" destination MAC address. However, you can always"
" choose to let the kernel create the IPv6 header"
" choosing not to pass --source-IP, --traffic-class"
" or --flow options. That should simplify things a bit");
}
}
/* CASE 3: We are dealing with regular, IPv4-based modes. In this case
* we just select transmission mode based on current OS. For Windows
* we choose raw eth level because MS has disable raw sockets support.
* For the rest of systems, we chose raw IP because it's easier for us
* as we don't have to deal with all the source MAC and next-hop MAC address
* determination process. */
else{
#ifdef WIN32
this->setSendPreference( PACKET_SEND_ETH_STRONG );
this->setSendEth(true);
#else
this->setSendPreference( PACKET_SEND_IP_WEAK );
this->setSendEth(false);
#endif
}
/* User did actually supplied his own sending preference. Let's check if we
* can actually send probes the way he wants. */
}else{
if( this->getMode()==ARP && !this->sendPreferenceEthernet() ){
this->setSendEth(true);
nping_warning(QT_2, "Warning: ARP mode requires raw ethernet frame transmission. Specified preference will be ignored.");
}
else if( this->ipv6() ){
/* CASE 1: User requested ethernet explicitly and supplied all
* necessary options. */
if( this->sendPreferenceEthernet() && this->canDoIPv6Ethernet() ){
this->setSendEth(true);
/* CASE 2: User requested Ethernet but did not really supplied all
* the information we need */
}else if( this->sendPreferenceEthernet() && !this->canDoIPv6Ethernet() ){
nping_fatal(QT_3, "You requested raw ethernet level transmission and IPv6."
" In this case, you need to supply source MAC address,"
" destination MAC address and IPv6 source address.");
/* CASE 3: User requested raw IP transmission and did not request
* any special IPv6 header options. */
}else if( this->sendPreferenceIP() && this->canDoIPv6ThroughSocket() ){
this->setSendEth(false);
/* CASE 4: User requested raw IP transmission but also wanted to
* set custom IPv6 header field values. */
}else if (this->sendPreferenceIP() && !this->canDoIPv6ThroughSocket()){
nping_fatal(QT_3, "You requested raw IP transmission mode for IPv6."
" Nping does not currently allow IPv6 header manipulation"
" when sending packets at raw IP level due to the limitations"
" on raw IPv6 sockets, imposed by RFC 2292. Please"
" use raw Ethernet transmission (option --send-eth)");
}
}
else if( this->sendPreferenceEthernet() ){
this->setSendEth(true);
}else{
this->setSendEth(false);
}
}
if( this->getMode()==TCP_CONNECT || this->getMode()==UDP_UNPRIV )
nping_print(DBG_2,"Nping will send packets in unprivileged mode using regular system calls");
else
nping_print(DBG_2,"Nping will send packets at %s", this->sendEth() ? "raw ethernet level" : "raw IP level" );
}
/** ECHO MODE ************************************************************/
if(this->getRole()==ROLE_CLIENT){
/* Make sure the nping echo client does not generate packets with tcp
* src port or tcp dst port 9929 (or --echo-port N, if that is set),
* because 1) the echo server does not capture those packets and 2) to
* avoid messing with the established side-channel tcp connection. */
if(this->getMode()==TCP){
for(int i=0; i<tportcount; i++){
if( this->target_ports[i]==this->getEchoPort())
nping_fatal(QT_3, "Packets can't be sent to the same port that is used to connect to the echo server (%d)", this->getEchoPort());
else if(this->getSourcePort()==this->getEchoPort())
nping_fatal(QT_3, "Packets can't be sent from the same port that is used to connect to the echo server (%d)", this->getEchoPort());
}
}
/* Check the echo client only produces TCP/UDP/ICMP packets */
switch( this->getMode() ){
case TCP:
case UDP:
case ICMP:
break;
default:
nping_fatal(QT_3, "The echo client can't be run with protocols other than TCP, UDP or ICMP.");
break;
}
}
#ifndef HAVE_OPENSSL
if(this->getRole()==ROLE_CLIENT || this->getRole()==ROLE_SERVER ){
if( this->doCrypto()==true ){
nping_fatal(QT_3, "Nping was compiled without OpenSSL so authentications need to be transmitted as cleartext. If you wish to continue, please specify --no-crypto.");
}
}
#endif
/** FRAGMENTATION ************************************************************/
#if !defined(LINUX) && !defined(OPENBSD) && !defined(FREEBSD) && !defined(NETBSD)
if (this->issetMTU()) {
error("Warning: Packet fragmentation selected on a host other than Linux, OpenBSD, FreeBSD, or NetBSD. This may or may not work.");
}
#endif
/** MISCELLANEOUS ************************************************************/
if( this->issetSourcePort() && this->getMode()==TCP_CONNECT && this->getPacketCount()>1 )
error("Warning: Setting a source port in TCP-Connect mode with %d rounds may not work after the first round. You may want to do just one round (use --count 1).", this->getPacketCount() );
} /* End of validateOptions() */
/** Returns true if requested mode is a simple TCP connect probe mode */
bool NpingOps::canRunUDPWithoutPrivileges(){
if( this->issetBadsumIP() ||
this->issetTTL() ||
this->issetHopLimit() ||
this->issetTOS() ||
this->issetIdentification() ||
this->issetMF() ||
this->issetDF() ||
this->issetIPv4SourceAddress() ||
this->issetIPv6SourceAddress() ||
this->issetIPOptions() ||
this->issetMTU() ||
this->issetSpoofSource() ||
this->issetSourceMAC() ||
this->issetDestMAC() ||
this->issetEtherType() ||
this->issetTraceroute() ||
this->issetBPFFilterSpec()
)
return false;
else
return true;
} /* End canRunUDPWithoutPrivileges() */
/** Returns true if user did not request any special ethernet or ipv6 header
* options */
bool NpingOps::canDoIPv6ThroughSocket(){
if( this->issetEtherType() ||
this->issetDestMAC() ||
this->issetSourceMAC() ||
this->issetHopLimit() ||
this->issetTrafficClass() ||
this->issetFlowLabel() ||
this->issetIPv6SourceAddress()
)
return false;
else
return true;
} /* End canDoIPv6ThroughSocket() */
/** Returns true if user supplied all necessary options to allow IPv6 at raw
* Ethernet level */
bool NpingOps::canDoIPv6Ethernet(){
if( this->issetDestMAC() && this->issetSourceMAC() && this->issetIPv6SourceAddress() )
return true;
else
return false;
} /* End canDoIPv6Ethernet() */
/******************************************************************************
* Miscellaneous *
******************************************************************************/
void NpingOps::displayNpingDoneMsg(){
if( this->getRole()==ROLE_SERVER ){
nping_print(QT_1, "Nping done: %lu %s served in %.2f seconds",
(unsigned long)this->stats.getEchoClientsServed(),
(this->stats.getEchoClientsServed() == 1)? "client" : "clients",
this->stats.elapsedRuntime()
);
}else{
nping_print(QT_1, "Nping done: %lu %s pinged in %.2f seconds",
this->targets.getTargetsFetched(),
(this->targets.getTargetsFetched() == 1)? "IP address" : "IP addresses",
this->stats.elapsedRuntime()
);
}
} /* End of displayNpingDoneMessage() */
/** @warning This method calls targets.rewind() */
void NpingOps::displayStatistics(){
char auxbuff[256];
memset(auxbuff, 0, 256);
NpingTarget *target=NULL;
this->targets.rewind();
nping_print(VB_0," "); /* Print newline */
/* Per-target statistics */
if( this->targets.getTargetsFetched() > 1){
while( (target=this->targets.getNextTarget()) != NULL )
target->printStats();
}else{
target=this->targets.getNextTarget();
if( target!= NULL)
target->printRTTs();
}
#ifdef WIN32
/* Sent/Recv/Echoed Packets */
if(this->getRole()==ROLE_CLIENT){
nping_print(QT_1|NO_NEWLINE, "Raw packets sent: %I64u ", this->stats.getSentPackets() );
nping_print(QT_1|NO_NEWLINE, "(%s) ", format_bytecount(this->stats.getSentBytes(), auxbuff, 256));
nping_print(QT_1|NO_NEWLINE,"| Rcvd: %I64u ", this->stats.getRecvPackets() );
nping_print(QT_1|NO_NEWLINE,"(%s) ", format_bytecount(this->stats.getRecvBytes(), auxbuff, 256));
nping_print(QT_1|NO_NEWLINE,"| Lost: %I64u ", this->stats.getLostPackets() );
nping_print(QT_1|NO_NEWLINE,"(%.2lf%%)", this->stats.getLostPacketPercentage100() );
nping_print(QT_1|NO_NEWLINE,"| Echoed: %I64u ", this->stats.getEchoedPackets() );
nping_print(QT_1,"(%s) ", format_bytecount(this->stats.getEchoedBytes(), auxbuff, 256));
}else if(this->getRole()==ROLE_SERVER){
nping_print(QT_1|NO_NEWLINE, "Raw packets captured: %I64u ", this->stats.getRecvPackets() );
nping_print(QT_1|NO_NEWLINE, "(%s) ", format_bytecount(this->stats.getRecvBytes(), auxbuff, 256));
nping_print(QT_1|NO_NEWLINE,"| Echoed: %I64u ", this->stats.getEchoedPackets() );
nping_print(QT_1|NO_NEWLINE,"(%s) ", format_bytecount(this->stats.getEchoedBytes(), auxbuff, 256));
nping_print(QT_1|NO_NEWLINE,"| Not Matched: %I64u ", this->stats.getUnmatchedPackets() );
nping_print(QT_1|NO_NEWLINE,"(%s) ", format_bytecount(this->stats.getRecvBytes()-this->stats.getEchoedBytes(), auxbuff, 256));
nping_print(QT_1,"(%.2lf%%)", this->stats.getUnmatchedPacketPercentage100() );
}else if(this->getMode()==TCP_CONNECT){
nping_print(QT_1|NO_NEWLINE, "TCP connection attempts: %I64u ", this->stats.getSentPackets() );
nping_print(QT_1|NO_NEWLINE,"| Successful connections: %I64u ", this->stats.getRecvPackets() );
nping_print(QT_1|NO_NEWLINE,"| Failed: %I64u ", this->stats.getLostPackets() );
nping_print(QT_1,"(%.2lf%%)", this->stats.getLostPacketPercentage100() );
} else if (this->getMode()==UDP_UNPRIV){
nping_print(QT_1|NO_NEWLINE, "UDP packets sent: %I64u ", this->stats.getSentPackets() );
nping_print(QT_1|NO_NEWLINE,"| Rcvd: %I64u ", this->stats.getRecvPackets() );
nping_print(QT_1|NO_NEWLINE,"| Lost: %I64u ", this->stats.getLostPackets() );
nping_print(QT_1,"(%.2lf%%)", this->stats.getLostPacketPercentage100() );
} else{
nping_print(QT_1|NO_NEWLINE, "Raw packets sent: %I64u ", this->stats.getSentPackets() );
nping_print(QT_1|NO_NEWLINE, "(%s) ", format_bytecount(this->stats.getSentBytes(), auxbuff, 256));
nping_print(QT_1|NO_NEWLINE,"| Rcvd: %I64u ", this->stats.getRecvPackets() );
nping_print(QT_1|NO_NEWLINE,"(%s) ", format_bytecount(this->stats.getRecvBytes(), auxbuff, 256));
nping_print(QT_1|NO_NEWLINE,"| Lost: %I64u ", this->stats.getLostPackets() );
nping_print(QT_1,"(%.2lf%%)", this->stats.getLostPacketPercentage100() );
}
#else
/* Sent/Recv/Echoed Packets */
if(this->getRole()==ROLE_CLIENT){
nping_print(QT_1|NO_NEWLINE, "Raw packets sent: %llu ", this->stats.getSentPackets() );
nping_print(QT_1|NO_NEWLINE, "(%s) ", format_bytecount(this->stats.getSentBytes(), auxbuff, 256));
nping_print(QT_1|NO_NEWLINE,"| Rcvd: %llu ", this->stats.getRecvPackets() );
nping_print(QT_1|NO_NEWLINE,"(%s) ", format_bytecount(this->stats.getRecvBytes(), auxbuff, 256));
nping_print(QT_1|NO_NEWLINE,"| Lost: %llu ", this->stats.getLostPackets() );
nping_print(QT_1|NO_NEWLINE,"(%.2lf%%)", this->stats.getLostPacketPercentage100() );
nping_print(QT_1|NO_NEWLINE,"| Echoed: %llu ", this->stats.getEchoedPackets() );
nping_print(QT_1,"(%s) ", format_bytecount(this->stats.getEchoedBytes(), auxbuff, 256));
}else if(this->getRole()==ROLE_SERVER){
nping_print(QT_1|NO_NEWLINE, "Raw packets captured: %llu ", this->stats.getRecvPackets() );
nping_print(QT_1|NO_NEWLINE, "(%s) ", format_bytecount(this->stats.getRecvBytes(), auxbuff, 256));
nping_print(QT_1|NO_NEWLINE,"| Echoed: %llu ", this->stats.getEchoedPackets() );
nping_print(QT_1|NO_NEWLINE,"(%s) ", format_bytecount(this->stats.getEchoedBytes(), auxbuff, 256));
nping_print(QT_1|NO_NEWLINE,"| Not Matched: %llu ", this->stats.getUnmatchedPackets() );
nping_print(QT_1|NO_NEWLINE,"(%s) ", format_bytecount(this->stats.getRecvBytes()-this->stats.getEchoedBytes(), auxbuff, 256));
nping_print(QT_1,"(%.2lf%%)", this->stats.getUnmatchedPacketPercentage100() );
}else if(this->getMode()==TCP_CONNECT){
nping_print(QT_1|NO_NEWLINE, "TCP connection attempts: %llu ", this->stats.getSentPackets() );
nping_print(QT_1|NO_NEWLINE,"| Successful connections: %llu ", this->stats.getRecvPackets() );
nping_print(QT_1|NO_NEWLINE,"| Failed: %llu ", this->stats.getLostPackets() );
nping_print(QT_1,"(%.2lf%%)", this->stats.getLostPacketPercentage100() );
} else if (this->getMode()==UDP_UNPRIV){
nping_print(QT_1|NO_NEWLINE, "UDP packets sent: %llu ", this->stats.getSentPackets() );
nping_print(QT_1|NO_NEWLINE,"| Rcvd: %llu ", this->stats.getRecvPackets() );
nping_print(QT_1|NO_NEWLINE,"| Lost: %llu ", this->stats.getLostPackets() );
nping_print(QT_1,"(%.2lf%%)", this->stats.getLostPacketPercentage100() );
} else{
nping_print(QT_1|NO_NEWLINE, "Raw packets sent: %llu ", this->stats.getSentPackets() );
nping_print(QT_1|NO_NEWLINE, "(%s) ", format_bytecount(this->stats.getSentBytes(), auxbuff, 256));
nping_print(QT_1|NO_NEWLINE,"| Rcvd: %llu ", this->stats.getRecvPackets() );
nping_print(QT_1|NO_NEWLINE,"(%s) ", format_bytecount(this->stats.getRecvBytes(), auxbuff, 256));
nping_print(QT_1|NO_NEWLINE,"| Lost: %llu ", this->stats.getLostPackets() );
nping_print(QT_1,"(%.2lf%%)", this->stats.getLostPacketPercentage100() );
}
#endif
/* Transmission times & rates */
nping_print(VB_1|NO_NEWLINE,"Tx time: %.5lfs ", this->stats.elapsedTx() );
nping_print(VB_1|NO_NEWLINE,"| Tx bytes/s: %.2lf ", this->stats.getOverallTxByteRate() );
nping_print(VB_1,"| Tx pkts/s: %.2lf", this->stats.getOverallTxPacketRate() );
nping_print(VB_1|NO_NEWLINE,"Rx time: %.5lfs ", this->stats.elapsedRx() );
nping_print(VB_1|NO_NEWLINE,"| Rx bytes/s: %.2lf ", this->stats.getOverallRxByteRate() );
nping_print(VB_1,"| Rx pkts/s: %.2lf", this->stats.getOverallRxPacketRate() );
} /* End of displayStatistics() */
/* Close open files, free allocated memory, etc. */
int NpingOps::cleanup(){
this->targets.freeTargets();
return OP_SUCCESS;
} /* End of cleanup() */
char *NpingOps::select_network_iface(){
char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *pcap_ifaces=NULL;
/* Vars for the current interface in the loop */
pcap_if_t *curr=NULL; /* Current pcap pcap_if_t element */
bool current_has_address=false; /* Does it have an addr of any type? */
bool current_has_ipv6=false; /* Does it have an IPv6 address? */
bool current_has_ipv4=false; /* Does it have an IPv4 address? */
bool current_is_loopback=false; /* Is it a loopback interface? */
bool select_current=false; /* Is current better than candidate? */
struct sockaddr_in6 devaddr6; /* We store iface's IPv6 address */
struct sockaddr_in devaddr4; /* And also its IPv4 address */
/* Vars for our candidate interface */
pcap_if_t *candidate=NULL;
bool candidate_has_address=false;
bool candidate_has_ipv6=false;
bool candidate_has_ipv4=false;
bool candidate_is_loopback=false;
//struct sockaddr_in6 candidate_addr6;
//struct sockaddr_in candidate_addr4;
/* Ask libpcap for a list of network interfaces */
if( pcap_findalldevs(&pcap_ifaces, errbuf) != 0 )
nping_fatal(QT_3, "Cannot obtain device for packet capture --> %s. You may want to specify one explicitly using option -e", errbuf);
/* Iterate over the interface list and select the best one */
for(curr=pcap_ifaces; curr!=NULL; curr=curr->next){
current_has_address=false; candidate_has_ipv6=false;
candidate_is_loopback=false; candidate_has_ipv4=false;
select_current=false;
if( curr->flags==PCAP_IF_LOOPBACK)
current_is_loopback=true;
/* Loop through the list of addresses */
for(pcap_addr_t *curraddr=curr->addresses; curraddr!=NULL; curraddr=curraddr->next){
current_has_address=true;
if( curraddr->addr->sa_family==AF_INET){
current_has_ipv4=true;
memcpy( &devaddr4, curraddr->addr, sizeof(struct sockaddr_in));
} else if( curraddr->addr->sa_family==AF_INET6){
current_has_ipv6=true;
memcpy( &devaddr6, curraddr->addr, sizeof(struct sockaddr_in6));
}
}
/* If we still have no candidate, take the first one we find */
if( candidate==NULL){
select_current=true;
}
/* If we already have a candidate, check if the one we are
* processing right now is better than the one we've already got */
else{
/* If our candidate does not have an IPv6 address but this one does,
* select the new one. */
if( candidate_has_ipv6==false && current_has_ipv6==true ){
select_current=true;
}
/* If our candidate does not even have an IPv4 address but this
* one does, select the new one. */
else if( candidate_has_ipv4==false && candidate_has_ipv6==false && current_has_ipv4){
select_current=true;
}
/* If our candidate is a loopback iface, select the new one */
else if( candidate_is_loopback && !current_is_loopback){
/* Select the new one only if it has an IPv6 address
* and the old one didn't. If our old loopback iface
* has an IPv6 address and this one does not, we
* prefer to keep the loopback one, even though the
* other is not loopback */
if(current_has_ipv6==true){
select_current=true;
}
/* We also prefer IPv4 capable interfaces than */
else if(candidate_has_ipv6==false && current_has_ipv4==true){
select_current=true;
}
}
/* If both are loopback, select the best one. */
else if( candidate->flags==PCAP_IF_LOOPBACK && curr->flags==PCAP_IF_LOOPBACK){
if( candidate_has_ipv6==false && current_has_ipv6 )
select_current=true;
}
}
/* Did we determine that we should discard our old candidate? */
if( select_current ){
candidate=curr;
candidate_has_address=current_has_address;
candidate_has_ipv4=current_has_ipv4;
candidate_has_ipv6=current_has_ipv6;
candidate_is_loopback=current_is_loopback;
}
/* Let's see if we have the interface of our dreams... */
if( candidate_has_address && candidate_has_ipv6 && candidate_has_ipv4 && candidate_is_loopback==false){
break;
}
}
if(candidate==NULL)
return NULL;
else
return candidate->name;
} /* End of select_network_iface() */
int NpingOps::setDefaultHeaderValues(){
if(this->ipv6()){ /* IPv6 */
if(!this->issetTrafficClass())
this->ipv6_tclass=DEFAULT_IPv6_TRAFFIC_CLASS;
if(!this->issetFlowLabel())
this->ipv6_flowlabel=(get_random_u32() % 1048575);
if(!this->issetHopLimit() && !this->issetTraceroute())
this->ttl=DEFAULT_IPv6_TTL;
}else{ /* IPv4 */
if(!this->issetTOS())
this->tos=DEFAULT_IP_TOS;
if(!this->issetIdentification())
this->identification=get_random_u16();
if(!this->issetTTL() && !this->issetTraceroute())
this->ttl=DEFAULT_IP_TTL;
}
switch( this->getMode() ){
case TCP:
if(!this->issetTargetPorts()){
u16 *list = (u16 *)safe_zalloc( sizeof(u16) );
list[0]=DEFAULT_TCP_TARGET_PORT;
this->setTargetPorts(list, 1);
}
if(!this->issetSourcePort()){
/* Generate any source port higher than 1024 */
if(this->getRole()!=ROLE_CLIENT){
this->source_port=(1024 + ( get_random_u16()%(65535-1024) ));
}else{
/* For the echo client, avoid choosing the port used for the echo side channel */
while( (this->source_port=(1024 + ( get_random_u16()%(65535-1024) )))==this->echo_port );
}
}
if(!this->issetTCPSequence())
this->tcpseq=get_random_u32();
if(!this->issetTCPAck()){
if(this->getFlagTCP(FLAG_ACK))
this->tcpack=get_random_u32();
else
this->tcpack=0;
}
if(!this->issetTCPFlags())
this->setFlagTCP(FLAG_SYN);
if(!this->issetTCPWindow())
this->tcpwin=DEFAULT_TCP_WINDOW_SIZE;
/* @todo ADD urgent pointer handling here when it gets implemented */
break;
case UDP:
if(!this->issetTargetPorts()){
u16 *list = (u16 *)safe_zalloc( sizeof(u16) );
list[0]=DEFAULT_UDP_TARGET_PORT;
this->setTargetPorts(list, 1);
}
if(!this->issetSourcePort())
this->source_port=DEFAULT_UDP_SOURCE_PORT;
break;
case ICMP:
if(this->ipv6()){
if(!this->issetICMPType()) /* Default to ICMP Echo */
this->icmp_type=DEFAULT_ICMPv6_TYPE;
if(!this->issetICMPCode())
this->icmp_code=DEFAULT_ICMPv6_CODE;
}else{
if(!this->issetICMPType()) /* Default to ICMP Echo */
this->icmp_type=DEFAULT_ICMP_TYPE;
if(!this->issetICMPCode())
this->icmp_code=DEFAULT_ICMP_CODE;
}
break;
case ARP:
if(!this->issetARPOpCode())
this->arp_opcode=DEFAULT_ARP_OP;
break;
case UDP_UNPRIV:
if(!this->issetTargetPorts()){
u16 *list = (u16 *)safe_zalloc( sizeof(u16) );
list[0]=DEFAULT_UDP_TARGET_PORT;
this->setTargetPorts(list, 1);
}
if(!this->issetSourcePort())
this->source_port=DEFAULT_UDP_SOURCE_PORT;
break;
case TCP_CONNECT:
if( !this->issetTargetPorts() ) {
u16 *list = (u16 *)safe_zalloc( sizeof(u16) );
list[0]=DEFAULT_TCP_TARGET_PORT;
this->setTargetPorts(list, 1);
}
default:
return OP_FAILURE;
break;
}
return OP_SUCCESS;
} /* End of setDefaultHeaderValues() */
int NpingOps::setLastPacketSentTime(struct timeval t){
this->last_sent_pkt_time=t;
return OP_SUCCESS;
} /* End of setLastPacketSentTime() */
struct timeval NpingOps::getLastPacketSentTime(){
return this->last_sent_pkt_time;
} /* End of getLastPacketSentTime() */
/** Sets the RCVD output to be delayed. The supplied string is strdup()ed, so
* the caller may safely free() it or modify after calling this function.
* The "id" parameter is the nsock timer event scheduled for the output of
* the RCVD string (usually scheduled by ProbeMode). It is provided to allow
* other objects (like EchoClient) to cancel the event if they take care of
* printing the RCVD string before the timer goes off.*/
int NpingOps::setDelayedRcvd(const char *str, nsock_event_id id){
if(str==NULL)
return OP_FAILURE;
this->delayed_rcvd_str=strdup(str);
this->delayed_rcvd_event=id;
this->delayed_rcvd_str_set=true;
return OP_SUCCESS;
} /* End of setDelayedRcvd() */
/** Returns a pointer to a delayed RCVD output string. It returns non-NULL
* strings only once per prior setDelayedRcvd() call. This is, when a string
* has been set through a setDelayRcdv() call, the first time getDelayRcvd()
* is called, it returns that string. Subsequent calls will return NULL until
* another string is set, using setDelayRcdv() again.
* The "id" parameter will be filled with the timer event that was supposed
* to print the message. If getDelayedRcvd() is called by the timer handler
* itself, then NULL can be passed safely since the event id is not needed.
* If the caller is some other method that wants to print the RCVD string
* before the timer goes off, it may use the event ID to cancel the scheduled
* event since it's no longer necessary.
* @warning returned string is the strdup()ed version of the string passed
* in the call to setDelayedRcvd(), so the caller MUST free the returned
* pointer when it's done using it. */
char *NpingOps::getDelayedRcvd(nsock_event_id *id){
if(delayed_rcvd_str_set==false){
return NULL;
}else{
this->delayed_rcvd_str_set=false;
char *old=this->delayed_rcvd_str;
this->delayed_rcvd_str=NULL;
if(id!=NULL)
*id=this->delayed_rcvd_event;
return old;
}
} /* End of getDelayedRcvd() */
bool NpingOps::doCrypto(){
return this->do_crypto;
}
int NpingOps::doCrypto(bool value){
this->do_crypto=value;
return OP_SUCCESS;
}
/* Returns true if the echo server is allowed to include payloads in NEP_ECHO
* messages. */
bool NpingOps::echoPayload(){
return this->echo_payload;
}
/* Enables or disables payload echo for the echo server. Pass true to enable
* or false to disable. */
int NpingOps::echoPayload(bool value){
this->echo_payload=value;
this->echo_payload_set=true;
return OP_SUCCESS;
}
/** Returns the total number of probes to be sent (this takes into account
* the number of rounds, ports, and targets. It returns a positive integer
* on success and n<=0 in case of error. */
int NpingOps::getTotalProbes(){
int total_ports=0;
this->getTargetPorts(&total_ports);
u64 tmp = (u64) this->getPacketCount() * total_ports;
if (tmp > INT_MAX) {
return -1;
}
tmp *= this->targets.Targets.size();
if (tmp > INT_MAX) {
return -1;
}
return (int) tmp;
}
/******************************************************************************
* Code templates. *
******************************************************************************/
/*
Attributes for NpingOps:
TYPE ATTRNAME;
bool ATTRNAME_set;
Prototypes for NpingOps:
int setMETHNAME(TYPE val);
TYPE getMETHNAME();
bool issetMETHNAME();
Initialization for NpingOps::NpingOps()
ATTRNAME=0;
ATTRNAME_set=false;
*/
/** Sets METHNAME. Supplied parameter must be XXXXXXXX
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
/*int NpingOps::setMETHNAME(TYPE val){
if( 0 ){
nping_fatal(QT_3,"setMETHNAME(): Invalid value supplied\n");
return OP_FAILURE;
}else{
ATTRNAME=val;
ATTRNAME_set=true;
}
return OP_SUCCESS;
} *//* End of setMETHNAME() */
/** Returns value of attribute ATTRNAME */
/*TYPE NpingOps::getMETHNAME(){
return this->ATTRNAME;
} *//* End of getMETHNAME() */
/* Returns true if option has been set */
/*bool NpingOps::issetMETHNAME(){
return this->ATTRNAME_set;
} *//* End of issetMETHNAME() */