mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
3114 lines
96 KiB
C++
3114 lines
96 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-2025 Nmap Software 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.com) 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;
|
|
|
|
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(struct in_addr)*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){
|
|
// Validate: no extra bits set
|
|
if( (v & ~(PACKET_SEND_ETH | PACKET_SEND_IP))
|
|
// Validate: both ETH and IP cannot be STRONG
|
|
|| ((v & PACKET_SEND_ETH_STRONG) && (v & PACKET_SEND_IP_STRONG))) {
|
|
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(){
|
|
return (this->sendpref & PACKET_SEND_ETH);
|
|
} /* End of sendPreferenceEthernet() */
|
|
|
|
|
|
/* Returns true if send preference is Ethernet */
|
|
bool NpingOps::sendPreferenceIP(){
|
|
return (this->sendpref & PACKET_SEND_IP);
|
|
} /* End of sendPreferenceIP() */
|
|
|
|
|
|
/** Sets SendEth.
|
|
* @return OP_SUCCESS on success and OP_FAILURE in case of error. */
|
|
int NpingOps::setSendEth(bool val){
|
|
this->sendpref = PACKET_SEND_ETH;
|
|
this->sendpref_set = true;
|
|
return OP_SUCCESS;
|
|
} /* End of setSendEth() */
|
|
|
|
|
|
/** Returns value of attribute send_eth */
|
|
bool NpingOps::sendEth(){
|
|
return (this->sendpref & PACKET_SEND_ETH_STRONG);
|
|
} /* End of getSendEth() */
|
|
|
|
|
|
/** 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() */
|
|
|
|
|
|
/** Set Reserved / Evil flag */
|
|
int NpingOps::setRF(){
|
|
this->rf = true;
|
|
this->rf_set = true;
|
|
return OP_SUCCESS;
|
|
} /* End of setRF() */
|
|
|
|
|
|
/** Get Reserved / Evil flag */
|
|
bool NpingOps::getRF(){
|
|
return this->rf;
|
|
} /* End of getRF() */
|
|
|
|
|
|
/* 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() */
|
|
|
|
|
|
/* Returns true if option has been set */
|
|
bool NpingOps::issetRF(){
|
|
return this->rf_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_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.com. 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 */
|
|
if ( (dev = this->select_network_iface()) == NULL)
|
|
nping_fatal(QT_3, "Cannot obtain device for packet capture");
|
|
else
|
|
this->setDevice( dev );
|
|
/* Libpcap gave us a device name, try to obtain it's IP */
|
|
if ( devname2ipaddr(this->getDevice(), this->af(), &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->issetRF() ||
|
|
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() */
|