nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #define _XOPEN_SOURCE 700 |
2 | #define USE_LIBPCAP |
||
3 | |||
4 | #include <stdio.h> |
||
5 | #include <stdlib.h> |
||
6 | #include <argp.h> |
||
7 | #include <string.h> |
||
8 | #include <byteswap.h> |
||
9 | #include <pthread.h> |
||
10 | #ifdef USE_LIBPCAP |
||
11 | #include <pcap.h> |
||
12 | #endif |
||
13 | |||
14 | #include <arpa/inet.h> |
||
15 | #include <netinet/in.h> |
||
16 | #include <sys/types.h> |
||
17 | #include <sys/socket.h> |
||
18 | #include <unistd.h> |
||
19 | |||
20 | #define AS_STR2(TEXT) #TEXT |
||
21 | #define AS_STR(TEXT) AS_STR2(TEXT) |
||
22 | |||
23 | #ifdef USE_LIBPCAP |
||
24 | char *pcap_file_name = NULL; |
||
25 | #endif |
||
26 | |||
27 | int pid = -1; |
||
28 | int portin = 5555; |
||
29 | int discard_pcap = 0; |
||
30 | int discard_radiotap = 0; |
||
31 | pthread_t p1; |
||
32 | const char *argp_program_version = VERSION; |
||
33 | const char *argp_program_bug_address = "<mschulz@seemoo.tu-darmstadt.de>"; |
||
34 | |||
35 | static char doc[] = "rawproxy -- program to open a raw socket and forward frames as UDP datagrams."; |
||
36 | |||
37 | static struct argp_option options[] = { |
||
38 | #ifdef USE_LIBPCAP |
||
39 | {"interface", 'i', "INTERFACE", 0, "Interface used as RAW interface."}, |
||
40 | #endif |
||
41 | {"parent", 'p', "PID", 0, "Parent process id to monitor (default no monitor)."}, |
||
42 | {"out", 'o', "PORT", 0, "Port to use (default: 5555)."}, |
||
43 | {"header", 'h', 0, 0, "Discard pcap header."}, |
||
44 | {"radiotap", 'r', 0, 0, "Discard radiotap header."}, |
||
45 | { 0 } |
||
46 | }; |
||
47 | |||
48 | static error_t |
||
49 | parse_opt(int key, char *arg, struct argp_state *state) |
||
50 | { |
||
51 | switch (key) { |
||
52 | #ifdef USE_LIBPCAP |
||
53 | case 'i': |
||
54 | pcap_file_name = arg; |
||
55 | break; |
||
56 | #endif |
||
57 | case 'p': |
||
58 | pid = atoi(arg); |
||
59 | break; |
||
60 | case 'o': |
||
61 | portin = atoi(arg); |
||
62 | break; |
||
63 | case 'h': |
||
64 | discard_pcap = 1; |
||
65 | break; |
||
66 | case 'r': |
||
67 | discard_radiotap = 1; |
||
68 | break; |
||
69 | default: |
||
70 | return ARGP_ERR_UNKNOWN; |
||
71 | } |
||
72 | |||
73 | return 0; |
||
74 | } |
||
75 | |||
76 | struct map { |
||
77 | struct map *next; |
||
78 | unsigned int addr; |
||
79 | char *name; |
||
80 | }; |
||
81 | |||
82 | static struct argp argp = { options, parse_opt, 0, doc }; |
||
83 | |||
84 | #ifdef USE_LIBPCAP |
||
85 | void |
||
86 | analyse_pcap_file(char *filename) |
||
87 | { |
||
88 | pcap_t *pcap; |
||
89 | char errbuf[PCAP_ERRBUF_SIZE]; |
||
90 | const unsigned char *packet; |
||
91 | struct pcap_pkthdr header; |
||
92 | struct bpf_program fp; |
||
93 | char *fct_name; |
||
94 | int offset = 0, sock; |
||
95 | struct iovec iov[2]; |
||
96 | |||
97 | struct msghdr msg_hdr; |
||
98 | |||
99 | struct sockaddr_in sin = { |
||
100 | .sin_family = AF_INET, |
||
101 | .sin_port = htons(portin), |
||
102 | .sin_addr.s_addr = inet_addr("127.0.0.1"), |
||
103 | .sin_zero = { 0 } |
||
104 | }; |
||
105 | |||
106 | |||
107 | sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); |
||
108 | |||
109 | if(!sock) { |
||
110 | printf("ERR: socket\n"); |
||
111 | return; |
||
112 | } |
||
113 | |||
114 | if(!strcmp(filename, "wlan0")) { |
||
115 | pcap = pcap_open_live("wlan0", BUFSIZ, 1, 0, errbuf); |
||
116 | } else if(!strcmp(filename, "any")) { |
||
117 | pcap = pcap_open_live("any", BUFSIZ, 1, 0, errbuf); |
||
118 | offset = 2; |
||
119 | } else { |
||
120 | pcap = pcap_open_offline(filename, errbuf); |
||
121 | } |
||
122 | |||
123 | if(!pcap) { |
||
124 | printf("ERR: %s\n", errbuf); |
||
125 | return; |
||
126 | } |
||
127 | |||
128 | |||
129 | int i = 0; |
||
130 | int p_len; |
||
131 | while ((packet = pcap_next(pcap, &header)) != NULL) { |
||
132 | |||
133 | if(discard_radiotap) { |
||
134 | int rtap_len = ((packet[3] & 0xff) << 8) | (packet[2] & 0xff); |
||
135 | packet = packet + rtap_len; |
||
136 | } |
||
137 | |||
138 | |||
139 | if(discard_pcap) { |
||
140 | iov[0].iov_base = (caddr_t) packet; |
||
141 | iov[0].iov_len = header.caplen; |
||
142 | msg_hdr.msg_iovlen = 1; |
||
143 | } else { |
||
144 | iov[0].iov_base = (caddr_t) &header; |
||
145 | iov[0].iov_len = sizeof(struct pcap_pkthdr); |
||
146 | iov[1].iov_base = (caddr_t) packet; |
||
147 | iov[1].iov_len = header.caplen; |
||
148 | msg_hdr.msg_iovlen = 2; |
||
149 | } |
||
150 | |||
151 | msg_hdr.msg_name = (caddr_t) &sin; |
||
152 | msg_hdr.msg_namelen = sizeof(sin); |
||
153 | msg_hdr.msg_iov = iov; |
||
154 | |||
155 | if(!sendmsg(sock, &msg_hdr, 0)) |
||
156 | printf("ERR: %d\n", errno); |
||
157 | } |
||
158 | } |
||
159 | #endif |
||
160 | |||
161 | void *check_parent(void *unused) |
||
162 | { |
||
163 | |||
164 | if(pid != -1) { |
||
165 | while(1) { |
||
166 | if(kill(pid, 0) != 0) { |
||
167 | exit(EXIT_SUCCESS); |
||
168 | } else { |
||
169 | sleep(1); |
||
170 | } |
||
171 | } |
||
172 | } |
||
173 | return NULL; |
||
174 | } |
||
175 | |||
176 | int |
||
177 | main(int argc, char **argv) |
||
178 | { |
||
179 | |||
180 | argp_parse(&argp, argc, argv, 0, 0, 0); |
||
181 | |||
182 | pthread_create(&p1, NULL, check_parent, (void *)NULL); |
||
183 | |||
184 | #ifdef USE_LIBPCAP |
||
185 | if (pcap_file_name) |
||
186 | analyse_pcap_file(pcap_file_name); |
||
187 | #else |
||
188 | if (0); |
||
189 | #endif |
||
190 | else |
||
191 | fprintf(stderr, "ERR: no source selected.\n"); |
||
192 | |||
193 | exit(EXIT_SUCCESS); |
||
194 | } |