hping3/main.c
2022-04-13 18:01:39 +08:00

391 lines
9.0 KiB
C

/*
* $smu-mark$
* $name: main.c$
* $author: Salvatore Sanfilippo <antirez@invece.org>$
* $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$
* $license: This software is under GPL version 2 of license$
* $date: Fri Nov 5 11:55:48 MET 1999$
* $rev: 8$
*/
/*
* hping official page at http://www.kyuzz.org/antirez
* Covered by GPL version 2, Read the COPYING file for more information
*/
/* $Id: main.c,v 1.26 2003/08/07 23:55:55 antirez Exp $ */
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include "hping2.h"
#if (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP)
#include <pcap.h>
#endif /* ! OSTYPE_LINUX || FORCE_LIBPCAP */
/* globals */
unsigned int
tcp_th_flags = 0,
linkhdr_size = -1, /* physical layer header size */
ip_tos = 0,
set_seqnum = FALSE,
tcp_seqnum = FALSE,
set_ack,
h_if_mtu,
virtual_mtu = DEFAULT_VIRTUAL_MTU,
ip_frag_offset = 0,
signlen,
lsr_length = 0,
ssr_length = 0,
tcp_ack;
unsigned short int
data_size = 0;
float
rtt_min = 0,
rtt_max = 0,
rtt_avg = 0;
int
sockpacket,
sockraw,
sent_pkt = 0,
recv_pkt = 0,
out_of_sequence_pkt = 0,
sending_wait = DEFAULT_SENDINGWAIT, /* see DEFAULT_SENDINGWAIT */
opt_rawipmode = FALSE,
opt_icmpmode = FALSE,
opt_udpmode = FALSE,
opt_scanmode = FALSE,
opt_listenmode = FALSE,
opt_waitinusec = FALSE,
opt_numeric = FALSE,
opt_gethost = TRUE,
opt_quiet = FALSE,
opt_relid = FALSE,
opt_fragment = FALSE,
opt_df = FALSE,
opt_mf = FALSE,
opt_debug = FALSE,
opt_verbose = FALSE,
opt_winid_order = FALSE,
opt_keepstill = FALSE,
opt_datafromfile= FALSE,
opt_hexdump = FALSE,
opt_contdump = FALSE,
opt_sign = FALSE,
opt_safe = FALSE,
opt_end = FALSE,
opt_traceroute = FALSE,
opt_seqnum = FALSE,
opt_incdport = FALSE,
opt_force_incdport = FALSE,
opt_icmptype = DEFAULT_ICMP_TYPE,
opt_icmpcode = DEFAULT_ICMP_CODE,
opt_rroute = FALSE,
opt_tcpexitcode = FALSE,
opt_badcksum = FALSE,
opt_tr_keep_ttl = FALSE,
opt_tcp_timestamp = FALSE,
opt_tr_stop = FALSE,
opt_tr_no_rtt = FALSE,
opt_rand_dest = FALSE,
opt_rand_source = FALSE,
opt_lsrr = FALSE,
opt_ssrr = FALSE,
opt_cplt_rte = FALSE,
opt_bps = 0,
opt_pps = 0,
tcp_exitcode = 0,
src_ttl = DEFAULT_TTL,
src_id = -1, /* random */
base_dst_port = DEFAULT_DPORT,
dst_port = DEFAULT_DPORT,
src_port,
sequence = 0,
initsport = DEFAULT_INITSPORT,
src_winsize = DEFAULT_SRCWINSIZE,
src_thoff = (TCPHDR_SIZE >> 2),
count = DEFAULT_COUNT,
ctrlzbind = DEFAULT_BIND,
delaytable_index= 0,
eof_reached = FALSE,
icmp_ip_version = DEFAULT_ICMP_IP_VERSION,
icmp_ip_ihl = DEFAULT_ICMP_IP_IHL,
icmp_ip_tos = DEFAULT_ICMP_IP_TOS,
icmp_ip_tot_len = DEFAULT_ICMP_IP_TOT_LEN,
icmp_ip_id = DEFAULT_ICMP_IP_ID,
icmp_ip_protocol= DEFAULT_ICMP_IP_PROTOCOL,
icmp_ip_srcport = DEFAULT_DPORT,
icmp_ip_dstport = DEFAULT_DPORT,
opt_force_icmp = FALSE,
icmp_cksum = DEFAULT_ICMP_CKSUM,
raw_ip_protocol = DEFAULT_RAW_IP_PROTOCOL,
opt_ipv6 = FALSE,
opt_af = AF_INET,
opt_flood = FALSE;
char
datafilename [1024],
targetname [1024],
targetstraddr [1024],
ifname [1024] = {'\0'},
ifstraddr [1024],
spoofaddr [1024],
icmp_ip_srcip [1024],
icmp_ip_dstip [1024],
icmp_gwip [1024],
sign [1024],
rsign [1024], /* reverse sign (hping -> gniph) */
ip_opt [40],
*opt_scanports = "";
unsigned char
lsr [255] = {0},
ssr [255] = {0};
unsigned
ip_optlen = 0;
struct sockaddr_in
icmp_ip_src,
icmp_ip_dst,
icmp_gw;
struct SOCKADDR
local,
remote;
struct itimerval usec_delay;
volatile struct delaytable_element delaytable[TABLESIZE];
struct hcmphdr *hcmphdr_p; /* global pointer used by send_hcmp to transfer
hcmp headers to data_handler */
#if (!defined OSTYPE_LINUX) || (defined FORCE_LIBPCAP)
pcap_t *pcapfp;
char errbuf[PCAP_ERRBUF_SIZE];
struct pcap_pkthdr hdr;
#endif /* ! OSTYPE_LINUX || FORCE_LIBPCAP */
/* main */
int main(int argc, char **argv)
{
char setflags[1024] = {'\0'};
int c, hdr_size;
if (parse_options(argc, argv) == -1) {
printf("hping6: missing host argument\n"
"Try `hping6 --help' for more information.\n");
exit(1);
}
/* reverse sign */
if (opt_sign || opt_listenmode) {
char *src = sign+strlen(sign)-1; /* last char before '\0' */
char *dst = rsign;
while(src>=sign)
*dst++ = *src--;
*dst = '\0';
if (opt_debug)
printf("DEBUG: reverse sign: %s\n", rsign);
}
/* get target address before interface processing */
if (opt_ipv6)
resolve6((struct sockaddr*)&remote, targetname);
else if ((!opt_listenmode && !opt_safe) && !opt_rand_dest)
resolve((struct sockaddr*)&remote, targetname);
if (opt_rand_dest) {
strlcpy(targetstraddr, targetname, sizeof(targetstraddr));
} else {
inet_ntop(opt_af, ADDR(&remote), targetstraddr, sizeof(targetstraddr));
}
/* get interface's name and address */
if ( get_if_name() == -1 ) {
printf("[main] no such device\n");
exit(1);
}
if (opt_verbose || opt_debug) {
printf("using %s, addr: %s, MTU: %d\n",
ifname, ifstraddr, h_if_mtu);
}
/* open raw socket */
sockraw = open_sockraw();
if (sockraw == -1) {
printf("[main] can't open raw socket\n");
exit(1);
}
/* set SO_BROADCAST option */
socket_broadcast(sockraw);
/* set SO_IPHDRINCL option */
if(!opt_ipv6)
socket_iphdrincl(sockraw);
/* open sock packet or libpcap socket */
#if (defined OSTYPE_LINUX) && (!defined FORCE_LIBPCAP)
sockpacket = open_sockpacket();
if (sockpacket == -1) {
printf("[main] can't open packet socket\n");
exit(1);
}
#else
if (open_pcap() == -1) {
printf("[main] open_pcap failed\n");
exit(1);
}
#endif /* OSTYPE_LINUX && !FORCE_LIBPCAP */
/* get physical layer header size */
if (linkhdr_size == -1 && get_linkhdr_size(ifname) == -1) {
printf("[main] physical layer header size unknown (try --lhs)\n");
exit(1);
}
if (spoofaddr[0] != '\0')
{
if(opt_ipv6)
resolve6((struct sockaddr*)&local, spoofaddr);
else
resolve((struct sockaddr*)&local, spoofaddr);
}
if (icmp_ip_srcip[0] == '\0')
resolve((struct sockaddr*)&icmp_ip_src, "1.2.3.4");
else
resolve((struct sockaddr*)&icmp_ip_src, icmp_ip_srcip);
if (icmp_ip_dstip[0] == '\0')
resolve((struct sockaddr*)&icmp_ip_dst, "5.6.7.8");
else
resolve((struct sockaddr*)&icmp_ip_dst, icmp_ip_dstip);
if (icmp_gwip[0] == '\0')
resolve((struct sockaddr*)&icmp_gw, "0.0.0.0");
else
resolve((struct sockaddr*)&icmp_gw, icmp_gwip);
srand(time(NULL));
/* set initial source port */
if (initsport == -1)
initsport = src_port = 1024 + (rand() % 2000);
else
src_port = initsport;
for (c = 0; c < TABLESIZE; c++)
delaytable[c].seq = -1;
/* use SIGALRM to send packets like ping do */
Signal(SIGALRM, send_packet);
/* binding */
if (ctrlzbind != BIND_NONE) Signal(SIGTSTP, inc_destparm);
Signal(SIGINT, print_statistics);
Signal(SIGTERM, print_statistics);
/* if we are in listemode enter in listenmain() else */
/* print HPING... bla bla bla and enter in wait_packet() */
if (opt_listenmode) {
fprintf(stderr, "hping6 listen mode\n");
/* memory protection */
if (memlockall() == -1) {
perror("[main] memlockall()");
fprintf(stderr, "Warning: can't disable memory paging!\n");
} else if (opt_verbose || opt_debug) {
printf("Memory paging disabled\n");
}
listenmain();
/* UNREACHED */
}
/* Scan mode */
if (opt_scanmode) {
fprintf(stderr, "Scanning %s (%s), port %s\n",
targetname, targetstraddr, opt_scanports);
scanmain();
/* UNREACHED */
}
if (opt_rawipmode) {
strcat(setflags, "raw IP mode");
hdr_size = IPHDR_SIZE;
} else if (opt_icmpmode) {
strcat(setflags, "icmp mode");
hdr_size = IPHDR_SIZE + ICMPHDR_SIZE;
} else if (opt_udpmode) {
strcat(setflags, "udp mode");
hdr_size = IPHDR_SIZE + UDPHDR_SIZE;
} else {
if (tcp_th_flags & TH_RST) strcat(setflags, "R");
if (tcp_th_flags & TH_SYN) strcat(setflags, "S");
if (tcp_th_flags & TH_ACK) strcat(setflags, "A");
if (tcp_th_flags & TH_FIN) strcat(setflags, "F");
if (tcp_th_flags & TH_PUSH) strcat(setflags, "P");
if (tcp_th_flags & TH_URG) strcat(setflags, "U");
if (tcp_th_flags & TH_X) strcat(setflags, "X");
if (tcp_th_flags & TH_Y) strcat(setflags, "Y");
if (setflags[0] == '\0') strcat(setflags, "NO FLAGS are");
hdr_size = IPHDR_SIZE + TCPHDR_SIZE;
}
if(opt_ipv6)
hdr_size += IP6HDR_SIZE - IPHDR_SIZE;
printf("HPING %s (%s %s): %s set, %d headers + %d data bytes\n",
targetname,
ifname,
targetstraddr,
setflags,
hdr_size,
data_size);
/* memory protection */
if (opt_datafromfile || opt_sign) {
if (memlockall() == -1) {
perror("[main] memlockall()");
fprintf(stderr,
"Warning: can't disable memory paging!\n");
} else if (opt_verbose || opt_debug) {
printf("Memory paging disabled\n");
}
}
/* start packet sending */
kill(getpid(), SIGALRM);
/* flood mode? */
if (opt_flood) {
fprintf(stderr,
"hping in flood mode, no replies will be shown\n");
while (1) {
send_packet(0);
}
}
/* main loop */
while(1)
wait_packet();
return 0;
}