720 lines
19 KiB
C
720 lines
19 KiB
C
/* parseoptions.c -- options handling
|
|
* Copyright(C) 1999-2001 Salvatore Sanfilippo
|
|
* Under GPL, see the COPYING file for more information about
|
|
* the license. */
|
|
|
|
/* $Id: parseoptions.c,v 1.25 2003/08/08 14:39:00 antirez Exp $ */
|
|
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/time.h>
|
|
#include <ctype.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include "antigetopt.h"
|
|
|
|
#include "hping2.h"
|
|
#include "globals.h"
|
|
|
|
enum { OPT_COUNT, OPT_INTERVAL, OPT_NUMERIC, OPT_QUIET, OPT_INTERFACE,
|
|
OPT_HELP, OPT_VERSION, OPT_DESTPORT, OPT_BASEPORT, OPT_TTL, OPT_ID,
|
|
OPT_WIN, OPT_SPOOF, OPT_FIN, OPT_SYN, OPT_RST, OPT_PUSH, OPT_ACK,
|
|
OPT_URG, OPT_XMAS, OPT_YMAS, OPT_FRAG, OPT_MOREFRAG, OPT_DONTFRAG,
|
|
OPT_FRAGOFF, OPT_TCPOFF, OPT_REL, OPT_DATA, OPT_RAWIP, OPT_ICMP,
|
|
OPT_UDP, OPT_BIND, OPT_UNBIND, OPT_DEBUG, OPT_VERBOSE, OPT_WINID,
|
|
OPT_KEEP, OPT_FILE, OPT_DUMP, OPT_PRINT, OPT_SIGN, OPT_LISTEN,
|
|
OPT_SAFE, OPT_TRACEROUTE, OPT_TOS, OPT_MTU, OPT_SEQNUM, OPT_BADCKSUM,
|
|
OPT_SETSEQ, OPT_SETACK, OPT_ICMPTYPE, OPT_ICMPCODE, OPT_END,
|
|
OPT_RROUTE, OPT_IPPROTO, OPT_ICMP_IPVER, OPT_ICMP_IPHLEN,
|
|
OPT_ICMP_IPLEN, OPT_ICMP_IPID, OPT_ICMP_IPPROTO, OPT_ICMP_CKSUM,
|
|
OPT_ICMP_TS, OPT_ICMP_ADDR, OPT_TCPEXITCODE, OPT_FAST, OPT_TR_KEEP_TTL,
|
|
OPT_TCP_TIMESTAMP, OPT_TR_STOP, OPT_TR_NO_RTT, OPT_ICMP_HELP,
|
|
OPT_RAND_DEST, OPT_RAND_SOURCE, OPT_LSRR, OPT_SSRR, OPT_ROUTE_HELP,
|
|
OPT_ICMP_IPSRC, OPT_ICMP_IPDST, OPT_ICMP_SRCPORT, OPT_ICMP_DSTPORT,
|
|
OPT_ICMP_GW, OPT_FORCE_ICMP, OPT_APD_SEND, OPT_SCAN, OPT_FASTER,
|
|
OPT_BPS, OPT_PPS, OPT_IPV6, OPT_LHS ,OPT_FLOOD };
|
|
|
|
static struct ago_optlist hping_optlist[] = {
|
|
{ 'c', "count", OPT_COUNT, AGO_NEEDARG },
|
|
{ 'i', "interval", OPT_INTERVAL, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 'n', "numeric", OPT_NUMERIC, AGO_NOARG },
|
|
{ 'q', "quiet", OPT_QUIET, AGO_NOARG },
|
|
{ 'I', "interface", OPT_INTERFACE, AGO_NEEDARG },
|
|
{ 'h', "help", OPT_HELP, AGO_NOARG },
|
|
{ 'v', "version", OPT_VERSION, AGO_NOARG },
|
|
{ 'p', "destport", OPT_DESTPORT, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 's', "baseport", OPT_BASEPORT, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 't', "ttl", OPT_TTL, AGO_NEEDARG },
|
|
{ 'N', "id", OPT_ID, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 'w', "win", OPT_WIN, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 'a', "spoof", OPT_SPOOF, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 'F', "fin", OPT_FIN, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'S', "syn", OPT_SYN, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'R', "rst", OPT_RST, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'P', "push", OPT_PUSH, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'A', "ack", OPT_ACK, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'U', "urg", OPT_URG, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'X', "xmas", OPT_XMAS, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'Y', "ymas", OPT_YMAS, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'f', "frag", OPT_FRAG, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'x', "morefrag", OPT_MOREFRAG, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'y', "dontfrag", OPT_DONTFRAG, AGO_NOARG },
|
|
{ 'g', "fragoff", OPT_FRAGOFF, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 'O', "tcpoff", OPT_TCPOFF, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 'r', "rel", OPT_REL, AGO_NOARG },
|
|
{ 'd', "data", OPT_DATA, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '0', "rawip", OPT_RAWIP, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ '1', "icmp", OPT_ICMP, AGO_NOARG },
|
|
{ '2', "udp", OPT_UDP, AGO_NOARG },
|
|
{ '8', "scan", OPT_SCAN, AGO_NEEDARG },
|
|
{ 'z', "bind", OPT_BIND, AGO_NOARG },
|
|
{ 'Z', "unbind", OPT_UNBIND, AGO_NOARG },
|
|
{ 'D', "debug", OPT_DEBUG, AGO_NOARG },
|
|
{ 'V', "verbose", OPT_VERBOSE, AGO_NOARG },
|
|
{ 'W', "winid", OPT_WINID, AGO_NOARG },
|
|
{ 'k', "keep", OPT_KEEP, AGO_NOARG },
|
|
{ 'E', "file", OPT_FILE, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 'j', "dump", OPT_DUMP, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'J', "print", OPT_PRINT, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'e', "sign", OPT_SIGN, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '9', "listen", OPT_LISTEN, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 'B', "safe", OPT_SAFE, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'T', "traceroute", OPT_TRACEROUTE, AGO_NOARG },
|
|
{ 'o', "tos", OPT_TOS, AGO_NEEDARG },
|
|
{ 'm', "mtu", OPT_MTU, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 'Q', "seqnum", OPT_SEQNUM, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'b', "badcksum", OPT_BADCKSUM, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'M', "setseq", OPT_SETSEQ, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 'L', "setack", OPT_SETACK, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 'C', "icmptype", OPT_ICMPTYPE, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 'K', "icmpcode", OPT_ICMPCODE, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ 'u', "end", OPT_END, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ 'G', "rroute", OPT_RROUTE, AGO_NOARG },
|
|
{ 'H', "ipproto", OPT_IPPROTO, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "icmp-help", OPT_ICMP_HELP, AGO_NOARG },
|
|
{ '\0', "icmp-ipver", OPT_ICMP_IPVER, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "icmp-iphlen", OPT_ICMP_IPHLEN, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "icmp-iplen", OPT_ICMP_IPLEN, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "icmp-ipid", OPT_ICMP_IPID, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "icmp-ipproto", OPT_ICMP_IPPROTO, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "icmp-cksum", OPT_ICMP_CKSUM, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "icmp-ts", OPT_ICMP_TS, AGO_NOARG },
|
|
{ '\0', "icmp-addr", OPT_ICMP_ADDR, AGO_NOARG },
|
|
{ '\0', "tcpexitcode", OPT_TCPEXITCODE, AGO_NOARG },
|
|
{ '\0', "fast", OPT_FAST, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ '\0', "faster", OPT_FASTER, AGO_NOARG|AGO_EXCEPT0 },
|
|
{ '\0', "tr-keep-ttl", OPT_TR_KEEP_TTL, AGO_NOARG },
|
|
{ '\0', "tcp-timestamp",OPT_TCP_TIMESTAMP, AGO_NOARG },
|
|
{ '\0', "tr-stop", OPT_TR_STOP, AGO_NOARG },
|
|
{ '\0', "tr-no-rtt", OPT_TR_NO_RTT, AGO_NOARG },
|
|
{ '\0', "rand-dest", OPT_RAND_DEST, AGO_NOARG },
|
|
{ '\0', "rand-source", OPT_RAND_SOURCE, AGO_NOARG },
|
|
{ '\0', "lsrr", OPT_LSRR, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "ssrr", OPT_SSRR, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "route-help", OPT_ROUTE_HELP, AGO_NOARG },
|
|
{ '\0', "apd-send", OPT_APD_SEND, AGO_NEEDARG },
|
|
{ '\0', "icmp-ipsrc", OPT_ICMP_IPSRC, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "icmp-ipdst", OPT_ICMP_IPDST, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "icmp-gw", OPT_ICMP_GW, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "icmp-srcport", OPT_ICMP_SRCPORT, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "icmp-dstport", OPT_ICMP_DSTPORT, AGO_NEEDARG|AGO_EXCEPT0 },
|
|
{ '\0', "force-icmp", OPT_FORCE_ICMP, AGO_NOARG },
|
|
{ '\0', "bps", OPT_BPS, AGO_NEEDARG },
|
|
{ '\0', "pps", OPT_PPS, AGO_NEEDARG },
|
|
{ '6', "ipv6", OPT_IPV6, AGO_NOARG },
|
|
{ '\0', "lhs", OPT_LHS, AGO_NEEDARG },
|
|
{ '\0', "flood", OPT_FLOOD, AGO_NOARG },
|
|
AGO_LIST_TERM
|
|
};
|
|
|
|
/* The following var is turned to 1 if the -i option is used.
|
|
* This allows to assign a different delay default value if
|
|
* the scanning mode is selected. */
|
|
static int delay_changed = 0;
|
|
|
|
static int suidtester(void)
|
|
{
|
|
return (getuid() != geteuid());
|
|
}
|
|
|
|
void fail_parse_route(void)
|
|
{
|
|
fprintf(stderr, "RECTUM\n");
|
|
exit(1);
|
|
}
|
|
|
|
void parse_route(unsigned char *route, unsigned int *route_len, char *str)
|
|
{
|
|
struct in_addr ip;
|
|
unsigned int i = 0;
|
|
unsigned int j;
|
|
unsigned int n = 0;
|
|
unsigned int route_ptr = 256;
|
|
char c;
|
|
|
|
route += 3;
|
|
while (str[i] != '\0')
|
|
{
|
|
for (j = i; isalnum(str[j]) || str[j] == '.'; j++);
|
|
switch(c = str[j])
|
|
{
|
|
case '\0':
|
|
case '/':
|
|
if (n >= 62)
|
|
{
|
|
fprintf(stderr, "too long route\n");
|
|
fail_parse_route();
|
|
}
|
|
str[j] = '\0';
|
|
if (inet_aton(str+i, &ip))
|
|
{
|
|
memcpy(route+4*n, &ip.s_addr, 4);
|
|
n++;
|
|
if (c == '/')
|
|
str[j++] = '/';
|
|
break;
|
|
}
|
|
fprintf(stderr, "invalid IP adress in route\n");
|
|
fail_parse_route();
|
|
case ':':
|
|
if ((!i) && j && j < 4)
|
|
{
|
|
sscanf(str, "%u:%n", &route_ptr, &i);
|
|
if (i == ++j)
|
|
{
|
|
if (route_ptr < 256)
|
|
break;
|
|
}
|
|
}
|
|
default:
|
|
fail_parse_route();
|
|
}
|
|
i = j;
|
|
}
|
|
if (route_ptr == 256)
|
|
route[-1] = (unsigned char) ( n ? 8 : 4 );
|
|
else
|
|
route[-1] = (unsigned char) route_ptr;
|
|
*route_len = 4*n + 3;
|
|
route[-2] = (unsigned char) *route_len;
|
|
}
|
|
|
|
int parse_options(int argc, char **argv)
|
|
{
|
|
int src_ttl_set = 0;
|
|
int targethost_set = 0;
|
|
int o;
|
|
char *mult;
|
|
int typeset = 0;
|
|
|
|
if (argc < 2)
|
|
return -1;
|
|
|
|
ago_set_exception(0, suidtester, "Option disabled when setuid");
|
|
|
|
while ((o = antigetopt(argc, argv, hping_optlist)) != AGO_EOF) {
|
|
switch(o) {
|
|
case AGO_UNKNOWN:
|
|
case AGO_REQARG:
|
|
case AGO_AMBIG:
|
|
ago_gnu_error("hping", o);
|
|
fprintf(stderr, "Try hping --help\n");
|
|
exit(1);
|
|
case AGO_ALONE:
|
|
if (targethost_set == 1) {
|
|
fprintf(stderr, "hping: you must specify only "
|
|
"one target host at a time\n");
|
|
exit(1);
|
|
} else {
|
|
strlcpy(targetname, ago_optarg, 1024);
|
|
targethost_set = 1;
|
|
}
|
|
break;
|
|
case OPT_COUNT:
|
|
count = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_INTERVAL:
|
|
delay_changed = 1;
|
|
if (*ago_optarg == 'u') {
|
|
opt_waitinusec = TRUE;
|
|
usec_delay.it_value.tv_sec =
|
|
usec_delay.it_interval.tv_sec = 0;
|
|
usec_delay.it_value.tv_usec =
|
|
usec_delay.it_interval.tv_usec =
|
|
atol(ago_optarg+1);
|
|
}
|
|
else
|
|
sending_wait = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_NUMERIC:
|
|
opt_numeric = TRUE;
|
|
break;
|
|
case OPT_QUIET:
|
|
opt_quiet = TRUE;
|
|
break;
|
|
case OPT_INTERFACE:
|
|
strlcpy (ifname, ago_optarg, 1024);
|
|
break;
|
|
case OPT_HELP:
|
|
show_usage();
|
|
break;
|
|
case OPT_VERSION:
|
|
show_version();
|
|
break;
|
|
case OPT_DESTPORT:
|
|
if (*ago_optarg == '+')
|
|
{
|
|
opt_incdport = TRUE;
|
|
ago_optarg++;
|
|
}
|
|
if (*ago_optarg == '+')
|
|
{
|
|
opt_force_incdport = TRUE;
|
|
ago_optarg++;
|
|
}
|
|
base_dst_port = dst_port = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_BASEPORT:
|
|
initsport = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_TTL:
|
|
src_ttl = strtol(ago_optarg, NULL, 0);
|
|
src_ttl_set = 1;
|
|
break;
|
|
case OPT_ID:
|
|
src_id = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_WIN:
|
|
src_winsize = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_SPOOF:
|
|
strlcpy (spoofaddr, ago_optarg, 1024);
|
|
break;
|
|
case OPT_FIN:
|
|
tcp_th_flags |= TH_FIN;
|
|
break;
|
|
case OPT_SYN:
|
|
tcp_th_flags |= TH_SYN;
|
|
break;
|
|
case OPT_RST:
|
|
tcp_th_flags |= TH_RST;
|
|
break;
|
|
case OPT_PUSH:
|
|
tcp_th_flags |= TH_PUSH;
|
|
break;
|
|
case OPT_ACK:
|
|
tcp_th_flags |= TH_ACK;
|
|
break;
|
|
case OPT_URG:
|
|
tcp_th_flags |= TH_URG;
|
|
break;
|
|
case OPT_XMAS:
|
|
tcp_th_flags |= TH_X;
|
|
break;
|
|
case OPT_YMAS:
|
|
tcp_th_flags |= TH_Y;
|
|
break;
|
|
case OPT_FRAG:
|
|
opt_fragment = TRUE;
|
|
break;
|
|
case OPT_MOREFRAG:
|
|
opt_mf = TRUE;
|
|
break;
|
|
case OPT_DONTFRAG:
|
|
opt_df = TRUE;
|
|
break;
|
|
case OPT_FRAGOFF:
|
|
ip_frag_offset = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_TCPOFF:
|
|
src_thoff = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_REL:
|
|
opt_relid = TRUE;
|
|
break;
|
|
case OPT_DATA:
|
|
data_size = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_RAWIP:
|
|
opt_rawipmode = TRUE;
|
|
break;
|
|
case OPT_ICMP:
|
|
opt_icmpmode = TRUE;
|
|
break;
|
|
case OPT_ICMP_TS:
|
|
opt_icmpmode = TRUE;
|
|
opt_icmptype = 13;
|
|
break;
|
|
case OPT_ICMP_ADDR:
|
|
opt_icmpmode = TRUE;
|
|
opt_icmptype = 17;
|
|
break;
|
|
case OPT_UDP:
|
|
opt_udpmode = TRUE;
|
|
break;
|
|
case OPT_SCAN:
|
|
opt_scanmode = TRUE;
|
|
opt_scanports = strdup(ago_optarg);
|
|
break;
|
|
case OPT_LISTEN:
|
|
opt_listenmode = TRUE;
|
|
strlcpy(sign, ago_optarg, 1024);
|
|
signlen = strlen(ago_optarg);
|
|
break;
|
|
case OPT_IPPROTO:
|
|
raw_ip_protocol = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_ICMPTYPE:
|
|
opt_icmpmode= TRUE;
|
|
opt_icmptype = strtol(ago_optarg, NULL, 0);
|
|
typeset = 1;
|
|
break;
|
|
case OPT_ICMPCODE:
|
|
opt_icmpmode= TRUE;
|
|
opt_icmpcode = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_BIND:
|
|
ctrlzbind = BIND_TTL;
|
|
break;
|
|
case OPT_UNBIND:
|
|
ctrlzbind = BIND_NONE;
|
|
break;
|
|
case OPT_DEBUG:
|
|
opt_debug = TRUE;
|
|
break;
|
|
case OPT_VERBOSE:
|
|
opt_verbose = TRUE;
|
|
break;
|
|
case OPT_WINID:
|
|
opt_winid_order = TRUE;
|
|
break;
|
|
case OPT_KEEP:
|
|
opt_keepstill = TRUE;
|
|
break;
|
|
case OPT_FILE:
|
|
opt_datafromfile = TRUE;
|
|
strlcpy(datafilename, ago_optarg, 1024);
|
|
break;
|
|
case OPT_DUMP:
|
|
opt_hexdump = TRUE;
|
|
break;
|
|
case OPT_PRINT:
|
|
opt_contdump = TRUE;
|
|
break;
|
|
case OPT_SIGN:
|
|
opt_sign = TRUE;
|
|
strlcpy(sign, ago_optarg, 1024);
|
|
signlen = strlen(ago_optarg);
|
|
break;
|
|
case OPT_SAFE:
|
|
opt_safe = TRUE;
|
|
break;
|
|
case OPT_END:
|
|
opt_end = TRUE;
|
|
break;
|
|
case OPT_TRACEROUTE:
|
|
opt_traceroute = TRUE;
|
|
break;
|
|
case OPT_TOS:
|
|
if (!strcmp(ago_optarg, "help"))
|
|
tos_help();
|
|
else
|
|
{
|
|
static unsigned int tos_tmp = 0;
|
|
|
|
sscanf(ago_optarg, "%2x", &tos_tmp);
|
|
ip_tos |= tos_tmp; /* OR tos */
|
|
}
|
|
break;
|
|
case OPT_MTU:
|
|
virtual_mtu = strtol(ago_optarg, NULL, 0);
|
|
opt_fragment = TRUE;
|
|
if(virtual_mtu > 65535) {
|
|
virtual_mtu = 65535;
|
|
printf("Specified MTU too high, "
|
|
"fixed to 65535.\n");
|
|
}
|
|
break;
|
|
case OPT_SEQNUM:
|
|
opt_seqnum = TRUE;
|
|
break;
|
|
case OPT_BADCKSUM:
|
|
opt_badcksum = TRUE;
|
|
break;
|
|
case OPT_SETSEQ:
|
|
set_seqnum = TRUE;
|
|
tcp_seqnum = strtoul(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_SETACK:
|
|
set_ack = TRUE;
|
|
tcp_ack = strtoul(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_RROUTE:
|
|
opt_rroute = TRUE;
|
|
break;
|
|
case OPT_ICMP_HELP:
|
|
icmp_help(); /* ICMP options help */
|
|
break;
|
|
case OPT_ICMP_IPVER:
|
|
icmp_ip_version = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_ICMP_IPHLEN:
|
|
icmp_ip_ihl = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_ICMP_IPLEN:
|
|
icmp_ip_tot_len = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_ICMP_IPID:
|
|
icmp_ip_id = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_ICMP_IPPROTO:
|
|
icmp_ip_protocol = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_ICMP_IPSRC:
|
|
strlcpy (icmp_ip_srcip, ago_optarg, 1024);
|
|
break;
|
|
case OPT_ICMP_IPDST:
|
|
strlcpy (icmp_ip_dstip, ago_optarg, 1024);
|
|
break;
|
|
case OPT_ICMP_GW:
|
|
strlcpy (icmp_gwip, ago_optarg, 1024);
|
|
break;
|
|
case OPT_ICMP_SRCPORT:
|
|
icmp_ip_srcport = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_ICMP_DSTPORT:
|
|
icmp_ip_dstport = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_FORCE_ICMP:
|
|
opt_force_icmp = TRUE;
|
|
break;
|
|
case OPT_ICMP_CKSUM:
|
|
icmp_cksum = strtol(ago_optarg, NULL, 0);
|
|
break;
|
|
case OPT_TCPEXITCODE:
|
|
opt_tcpexitcode = TRUE;
|
|
break;
|
|
case OPT_FAST:
|
|
delay_changed = 1;
|
|
opt_waitinusec = TRUE;
|
|
usec_delay.it_value.tv_sec =
|
|
usec_delay.it_interval.tv_sec = 0;
|
|
usec_delay.it_value.tv_usec =
|
|
usec_delay.it_interval.tv_usec = 100000;
|
|
break;
|
|
case OPT_FASTER:
|
|
delay_changed = 1;
|
|
opt_waitinusec = TRUE;
|
|
usec_delay.it_value.tv_sec =
|
|
usec_delay.it_interval.tv_sec = 0;
|
|
usec_delay.it_value.tv_usec =
|
|
usec_delay.it_interval.tv_usec = 1;
|
|
case OPT_TR_KEEP_TTL:
|
|
opt_tr_keep_ttl = TRUE;
|
|
break;
|
|
case OPT_TCP_TIMESTAMP:
|
|
opt_tcp_timestamp = TRUE;
|
|
break;
|
|
case OPT_TR_STOP:
|
|
opt_tr_stop = TRUE;
|
|
break;
|
|
case OPT_TR_NO_RTT:
|
|
opt_tr_no_rtt = TRUE;
|
|
break;
|
|
case OPT_RAND_DEST:
|
|
opt_rand_dest = TRUE;
|
|
break;
|
|
case OPT_RAND_SOURCE:
|
|
opt_rand_source = TRUE;
|
|
break;
|
|
case OPT_LSRR:
|
|
opt_lsrr = TRUE;
|
|
parse_route(lsr, &lsr_length, ago_optarg);
|
|
if (lsr[0])
|
|
printf("Warning: erasing previously given "
|
|
"loose source route");
|
|
lsr[0] = 131;
|
|
break;
|
|
case OPT_SSRR:
|
|
opt_ssrr = TRUE;
|
|
parse_route(ssr, &ssr_length, ago_optarg);
|
|
if (ssr[0])
|
|
printf("Warning: erasing previously given "
|
|
"strong source route");
|
|
ssr[0] = 137;
|
|
break;
|
|
case OPT_ROUTE_HELP:
|
|
route_help();
|
|
break;
|
|
case OPT_APD_SEND:
|
|
hping_ars_send(ago_optarg);
|
|
break;
|
|
case OPT_FLOOD:
|
|
opt_flood = TRUE;
|
|
break;
|
|
case OPT_BPS:
|
|
opt_bps = strtol(ago_optarg, &mult, 0);
|
|
switch(*mult)
|
|
{
|
|
case 'k':
|
|
case 'K':
|
|
opt_bps *= 1000;
|
|
break;
|
|
case 'm':
|
|
case 'M':
|
|
opt_bps *= 1000000;
|
|
break;
|
|
case 'g':
|
|
case 'G':
|
|
opt_bps *= 1000000000;
|
|
break;
|
|
case 0:
|
|
break;
|
|
default:
|
|
printf("invalid character in --bps argument: `%c'\n", *mult);
|
|
exit(1);
|
|
}
|
|
opt_bps /= 8;
|
|
break;
|
|
case OPT_PPS:
|
|
opt_pps = strtol(ago_optarg, &mult, 0);
|
|
switch(*mult)
|
|
{
|
|
case 'k':
|
|
case 'K':
|
|
opt_pps *= 1000;
|
|
break;
|
|
case 'm':
|
|
case 'M':
|
|
opt_pps *= 1000000;
|
|
break;
|
|
case 'g':
|
|
case 'G':
|
|
opt_bps *= 1000000000;
|
|
break;
|
|
case 0:
|
|
break;
|
|
default:
|
|
printf("invalid character in --pps argument: `%c'\n", *mult);
|
|
exit(1);
|
|
}
|
|
break;
|
|
case OPT_IPV6:
|
|
opt_ipv6 = TRUE;
|
|
opt_af = AF_INET6;
|
|
break;
|
|
case OPT_LHS:
|
|
linkhdr_size = atoi(ago_optarg);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(typeset == 0 && opt_icmptype == DEFAULT_ICMP_TYPE && opt_ipv6 == 1)
|
|
opt_icmptype = ICMP6_ECHO;
|
|
|
|
/* missing target host? */
|
|
if (targethost_set == 0 && opt_listenmode && opt_safe)
|
|
{
|
|
printf(
|
|
"you must specify a target host if you require safe protocol\n"
|
|
"because hping needs a target for HCMP packets\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (targethost_set == 0 && !opt_listenmode) return -1;
|
|
|
|
if (opt_numeric == TRUE) opt_gethost = FALSE;
|
|
|
|
/* some error condition */
|
|
if (data_size+IPHDR_SIZE+TCPHDR_SIZE > 65535) {
|
|
printf("Option error: sorry, data size must be <= %lu\n",
|
|
(unsigned long)(65535-IPHDR_SIZE+TCPHDR_SIZE));
|
|
exit(1);
|
|
}
|
|
else if (count <= 0 && count != -1) {
|
|
printf("Option error: count must > 0\n");
|
|
exit(1);
|
|
}
|
|
else if (sending_wait < 0) {
|
|
printf("Option error: bad timing interval\n");
|
|
exit(1);
|
|
}
|
|
else if (opt_waitinusec == TRUE && usec_delay.it_value.tv_usec < 0)
|
|
{
|
|
printf("Option error: bad timing interval\n");
|
|
exit(1);
|
|
}
|
|
else if (opt_datafromfile == TRUE && data_size == 0)
|
|
{
|
|
printf("Option error: -E option useless without -d\n");
|
|
exit(1);
|
|
}
|
|
else if (opt_sign && data_size && signlen > data_size)
|
|
{
|
|
printf(
|
|
"Option error: signature (%d bytes) is larger than data size\n"
|
|
"check -d option, don't specify -d to let hping compute it\n", signlen);
|
|
exit(1);
|
|
}
|
|
else if ((opt_sign || opt_listenmode) && signlen > 1024)
|
|
{
|
|
printf("Option error: signature too big\n");
|
|
exit(1);
|
|
}
|
|
else if (opt_safe == TRUE && src_id != -1)
|
|
{
|
|
printf("Option error: sorry, you can't set id and "
|
|
"use safe protocol at some time\n");
|
|
exit(1);
|
|
}
|
|
else if (opt_safe == TRUE && opt_datafromfile == FALSE &&
|
|
opt_listenmode == FALSE)
|
|
{
|
|
printf("Option error: sorry, safe protocol is useless "
|
|
"without 'data from file' option\n");
|
|
exit(1);
|
|
}
|
|
else if (opt_safe == TRUE && opt_sign == FALSE &&
|
|
opt_listenmode == FALSE)
|
|
{
|
|
printf("Option error: sorry, safe protocol require you "
|
|
"sign your packets, see --sign | -e option\n");
|
|
exit(1);
|
|
} else if (opt_rand_dest == TRUE && ifname[0] == '\0') {
|
|
printf("Option error: you need to specify an interface "
|
|
"when the --rand-dest option is enabled\n");
|
|
exit(1);
|
|
}
|
|
|
|
/* dependences */
|
|
if (opt_safe == TRUE)
|
|
src_id = 1;
|
|
|
|
if (opt_traceroute == TRUE && ctrlzbind == BIND_DPORT)
|
|
ctrlzbind = BIND_TTL;
|
|
|
|
if (opt_traceroute == TRUE && src_ttl_set == 0)
|
|
src_ttl = DEFAULT_TRACEROUTE_TTL;
|
|
|
|
/* set the data size to the signature len if the no data size
|
|
* was specified */
|
|
if (opt_sign && !data_size)
|
|
data_size = signlen;
|
|
|
|
/* If scan mode is on, and the -i option was not used,
|
|
* set the default delay to zero, that's send packets
|
|
* as fast as possible. */
|
|
if (opt_scanmode && !delay_changed) {
|
|
opt_waitinusec = TRUE;
|
|
usec_delay.it_value.tv_sec =
|
|
usec_delay.it_interval.tv_sec = 0;
|
|
usec_delay.it_value.tv_usec =
|
|
usec_delay.it_interval.tv_usec = 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|