hping3/parseoptions.c

720 lines
19 KiB
C
Raw Normal View History

2022-04-13 18:01:39 +08:00
/* 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;
}