forked from unpbook/unpv13e
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
124 lines (103 loc) · 3.11 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/* include main1 */
#include "udpcksum.h"
/* DefinE global variables */
struct sockaddr *dest, *local;
struct sockaddr_in locallookup;
socklen_t destlen, locallen;
int datalink; /* from pcap_datalink(), in <net/bpf.h> */
char *device; /* pcap device */
pcap_t *pd; /* packet capture struct pointer */
int rawfd; /* raw socket to write on */
int snaplen = 200; /* amount of data to capture */
int verbose;
int zerosum; /* send UDP query with no checksum */
static void usage(const char *);
int
main(int argc, char *argv[])
{
int c, lopt=0;
char *ptr, localname[1024], *localport;
struct addrinfo *aip;
/* end main1 */
/* include main2 */
opterr = 0; /* don't want getopt() writing to stderr */
while ( (c = getopt(argc, argv, "0i:l:v")) != -1) {
switch (c) {
case '0':
zerosum = 1;
break;
case 'i':
device = optarg; /* pcap device */
break;
case 'l': /* local IP address and port #: a.b.c.d.p */
if ( (ptr = strrchr(optarg, '.')) == NULL)
usage("invalid -l option");
*ptr++ = 0; /* null replaces final period */
localport = ptr; /* service name or port number */
strncpy(localname, optarg, sizeof(localname));
lopt = 1;
break;
case 'v':
verbose = 1;
break;
case '?':
usage("unrecognized option");
}
}
/* end main2 */
/* include main3 */
if (optind != argc-2)
usage("missing <host> and/or <serv>");
/* 4convert destination name and service */
aip = Host_serv(argv[optind], argv[optind+1], AF_INET, SOCK_DGRAM);
dest = aip->ai_addr; /* don't freeaddrinfo() */
destlen = aip->ai_addrlen;
/*
* Need local IP address for source IP address for UDP datagrams.
* Can't specify 0 and let IP choose, as we need to know it for
* the pseudoheader to calculate the UDP checksum.
* If -l option supplied, then use those values; otherwise,
* connect a UDP socket to the destination to determine the right
* source address.
*/
if (lopt) {
/* 4convert local name and service */
aip = Host_serv(localname, localport, AF_INET, SOCK_DGRAM);
local = aip->ai_addr; /* don't freeaddrinfo() */
locallen = aip->ai_addrlen;
} else {
int s;
s = Socket(AF_INET, SOCK_DGRAM, 0);
Connect(s, dest, destlen);
/* kernel chooses correct local address for dest */
locallen = sizeof(locallookup);
local = (struct sockaddr *)&locallookup;
Getsockname(s, local, &locallen);
if (locallookup.sin_addr.s_addr == htonl(INADDR_ANY))
err_quit("Can't determine local address - use -l\n");
close(s);
}
open_output(); /* open output, either raw socket or libnet */
open_pcap(); /* open packet capture device */
setuid(getuid()); /* don't need superuser privileges anymore */
Signal(SIGTERM, cleanup);
Signal(SIGINT, cleanup);
Signal(SIGHUP, cleanup);
test_udp();
cleanup(0);
}
/* end main3 */
static void
usage(const char *msg)
{
err_msg(
"usage: udpcksum [ options ] <host> <serv>\n"
"options: -0 send UDP datagram with checksum set to 0\n"
" -i s packet capture device\n"
" -l a.b.c.d.p local IP=a.b.c.d, local port=p\n"
" -v verbose output"
);
if (msg[0] != 0)
err_quit("%s", msg);
exit(1);
}