src: make mausezahn build, lots of cleanups on todo
[netsniff-ng.git] / src / mausezahn.c
blob247e8bd73d1a0f9ad00195728a329729ff3dfc67
1 /*
2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-2010 Herbert Haas
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 * details.
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html
19 #include "mz.h"
20 #include "cli.h"
21 #include "mops.h"
22 #include "llist.h"
25 // Catch SIGINT and clean up, close everything...
26 void clean_up(int sig)
28 int i;
29 struct arp_table_struct *cur, *next;
31 if (!quiet) fprintf(stderr, "\nMausezahn cleans up...\n");
33 if (fp!=NULL) {
34 if (verbose) fprintf(stderr, " close files (1) ...\n");
35 (void) fflush(fp);
36 (void) fclose(fp);
39 if (fp2!=NULL) {
40 if (verbose) fprintf(stderr, " close files (2) ...\n");
41 (void) fflush(fp2);
42 (void) fclose(fp2);
45 // interactive mode?
46 if (mz_port) {
47 if (verbose) fprintf(stderr, " clear mops list...\n");
48 mops_cleanup (mp_head);
49 if (verbose) fprintf(stderr, " clear automops list...\n");
50 automops_cleanup (amp_head);
51 if (verbose) fprintf(stderr, " clear packet sequences...\n");
52 mz_ll_delete_list (packet_sequences);
55 for (i=0; i<device_list_entries; i++) {
56 if (device_list[i].p_arp!=NULL) {
57 pcap_close(device_list[i].p_arp);
58 fprintf(stderr, " stopped ARP process for device %s\n", device_list[i].dev);
60 if (device_list[i].arprx_thread!=0) {
61 pthread_cancel(device_list[i].arprx_thread);
62 if (verbose)
63 fprintf(stderr, " (ARP thread for device %s done)\n", device_list[i].dev);
66 if (device_list[i].arp_table!=NULL) {
67 cur=device_list[i].arp_table;
68 while (cur!=NULL) {
69 next = cur->next;
70 if (cur!=NULL) free(cur);
71 cur=next;
75 // close packet sockets
76 if (device_list[i].ps>=0) {
77 close(device_list[i].ps);
84 if (verbose) fprintf(stderr, "finished.\n");
85 exit(sig);
90 void usage()
92 (void) fprintf (stderr,"\n"
93 MAUSEZAHN_VERSION
94 "\n"
95 "|\n"
96 "| USAGE: mz [options] [interface] keyword | arg_string | hex_string\n"
97 "|\n"
98 "| Short option description (see doc or manpage for more information):\n"
99 "| -h Prints this information.\n"
100 "| -4 IPv4 mode (default)\n"
101 "| -6 IPv6 mode\n"
102 "| -c <count> Send the packet count times (default: 1, infinite: 0).\n"
103 "| -d <delay> Apply delay between transmissions. The delay value can be\n"
104 "| specified in usec (default, no additional unit needed), or in\n"
105 "| msec (e. g. 100m or 100msec), or in seconds (e. g. 100s or 100sec).\n"
106 "| -r Multiplies the specified delay with a random value.\n"
107 "| -p <length> Pad the raw frame to specified length (using random bytes).\n"
108 "| -a <Src_MAC|keyword> Use specified source mac address, no matter what has\n"
109 "| been specified with other arguments. Keywords see below.\n"
110 "| Default is own interface MAC.\n"
111 "| -b <Dst_MAC|keyword> Same with destination mac address.\n"
112 "| Keywords are: \n"
113 "| rand use a random MAC address\n"
114 "| bc use a broadcast MAC address\n"
115 "| own use own interface MAC address (default for source MAC)\n"
116 "| stp use IEEE 802.1d STP multicast address\n"
117 "| cisco use Cisco multicast address as used for CDP, VTP, or PVST+\n"
118 "| -A <Src_IP> Use specified source IP address (default is own interface IP).\n"
119 "| -B <Dst_IP|DNS_name> Send packet to specified destination IP or domain name.\n"
120 "| -P <ASCII Payload> Use the specified ASCII payload.\n"
121 "| -f <filename> Read the ASCII payload from a file.\n"
122 "| -F <filename> Read the hexadecimal payload from a file.\n"
123 "| -Q <[CoS:]vlan> Specify 802.1Q VLAN tag and optional Class of Service. You can\n"
124 "| specify multiple 802.1Q VLAN tags (QinQ...) by separating them\n"
125 "| via a comma or a period (e. g. '5:10,20,2:30').\n"
126 "| -t <packet_type> Specify packet type for autobuild (you don't need to care for\n"
127 "| encapsulations in lower layers. Most packet types allow/require\n"
128 "| additional packet-specific arguments in an arg_string.\n"
129 "| Currently supported types: arp, bpdu, cdp, ip, icmp, udp, tcp,\n"
130 "| dns, rtp, syslog, lldp.\n"
131 "| For context-help use 'help' as arg_string!\n"
132 "| -T <packet_type> Specify packet type for server mode. Currently only rtp is supported.\n"
133 "| Enter -T help or -T rtp help for further information.\n"
134 "| -M <MPLS label> Insert a MPLS label. Enter '-M help' for a syntax description.\n"
135 "| -v|V Verbose and more verbose mode\n"
136 "| -q Quiet mode, i. e. even omit 'important standard short messages'.\n"
137 "| -S Simulation mode: DOES NOT put anything on the wire. This is\n"
138 "| typically combined with one of the verbose modes (v or V).\n"
139 "\n"
141 exit(0);
148 int main(int argc, char *argv[])
152 // These handles are only used when creating L3 and above packets.
153 libnet_t *l; // the context
154 libnet_ptag_t t2=0, t3=0, t4=0; // handles to layers
156 double cpu_time_used;
158 // Check if we have root priviliges
159 if ( (getuid()!=0) && (geteuid()!=0) )
161 fprintf(stderr, " Mausezahn requires root privileges.\n Exit.\n");
162 return 1;
166 // Reset all globals
167 (void) reset(0);
169 // Get all CLI options (sets globals, see mz.h)
170 if ( getopts(argc, argv) )
172 (void) fprintf(stderr, " Invalid command line parameters!\n");
173 usage();
176 // Check whether hires timers are supported or not:
177 (void) check_timer();
181 // *********************************************************************
182 // First prefer data in a mausezahn description file!
183 // *********************************************************************
187 // >>> TODO:
188 // Note that argument 'device' is also used here!
189 // Support libpcap
190 // Must end in state machine!
194 // *********************************************************************
195 // If no MDF given, then send packet according CLI specifications
196 // *********************************************************************
199 (void) signal(SIGINT, clean_up); // to close all file pointers etc upon SIGINT
201 switch (mode)
203 case BYTE_STREAM:
204 send_eth();
205 break;
207 case ARP:
208 (void) send_arp();
209 break;
211 case BPDU:
212 (void) send_bpdu();
213 break;
215 case CDP:
216 (void) send_cdp();
217 break;
219 case IP: // From now on a new much more modular method is used:
220 l = get_link_context();
221 t3 = create_ip_packet(l); // t3 can be used for later header changes
222 if (!quiet) complexity();
223 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
224 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
225 else
226 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
227 break;
229 case ICMP:
230 tx.ip_proto = 1;
231 l = get_link_context();
232 t4 = create_icmp_packet(l); // t4 can be used for later header changes
233 t3 = create_ip_packet(l); // t3 can be used for later header changes
234 if (!quiet) complexity();
235 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
236 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
237 else
238 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
239 break;
241 case ICMP6:
242 tx.ip_proto = 58;
243 l = get_link_context();
244 t4 = create_icmp6_packet(l); // t4 can be used for later header changes
245 t3 = create_ip_packet(l); // t3 can be used for later header changes
246 if (ipv6_mode)
247 update_ISUM(l, t4);
248 if (!quiet) complexity();
249 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
250 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
251 else
252 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
253 break;
255 case UDP:
256 tx.ip_proto = 17;
257 l = get_link_context();
258 t4 = create_udp_packet(l); // t4 can be used for later header changes
259 t3 = create_ip_packet(l); // t3 can be used for later header changes
260 if (ipv6_mode)
261 update_USUM(l, t4);
262 if (!quiet) complexity();
263 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
264 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
265 else
266 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
267 break;
269 case TCP:
270 tx.ip_proto = 6;
271 l = get_link_context();
272 t4 = create_tcp_packet(l); // t4 can be used for later header changes
273 t3 = create_ip_packet(l); // t3 can be used for later header changes
274 if (ipv6_mode)
275 update_TSUM(l, t4);
276 if (!quiet) complexity();
277 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
278 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
279 else
280 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
281 break;
283 case DNS:
284 tx.ip_proto = 17;
285 l = get_link_context();
286 (void) create_dns_packet();
287 t4 = create_udp_packet(l); // t4 can be used for later header changes
288 t3 = create_ip_packet(l); // t3 can be used for later header changes
289 if (!quiet) complexity();
290 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
291 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
292 else
293 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
294 break;
296 case RTP:
297 tx.ip_proto = 17;
298 l = get_link_context();
299 if (!quiet) fprintf(stderr, " mz: RTP mode! (count=%u, delay=%u usec)\n\n", tx.count, tx.delay);
300 (void) create_rtp_packet();
301 t4 = create_udp_packet(l); // t4 can be used for later header changes
302 t3 = create_ip_packet(l); // t3 can be used for later header changes
303 if (!quiet) complexity();
304 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
305 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
306 else
307 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
308 break;
310 case RX_RTP: // Receive RTP packets
311 rcv_rtp_init();
312 rcv_rtp();
313 break;
315 case SYSLOG:
316 tx.ip_proto = 17;
317 l = get_link_context();
318 (void) create_syslog_packet();
319 t4 = create_udp_packet(l); // t4 can be used for later header changes
320 t3 = create_ip_packet(l); // t3 can be used for later header changes
321 if (!quiet) complexity();
323 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
324 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
325 else
326 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
327 break;
329 case LLDP: // start with a new concept here
330 //l = get_link_context();
331 //(void) create_lldp_packet();
332 // // // printf("SIZE=%lu\n",sizeof(struct tx_struct));
333 fprintf(stderr, "LLDP is currently only supported via the interactive mode\n");
334 exit(1);
335 break;
338 default:
339 (void) fprintf(stderr," mz/main: unknown mode! Stop.\n");
340 return (1);
343 if (!quiet)
345 mz_stop = clock();
346 cpu_time_used = ((double) (mz_stop - mz_start)) / CLOCKS_PER_SEC;
347 if (cpu_time_used > 0)
349 total_d /= cpu_time_used;
350 fprintf(stderr, "%.2f seconds (%.Lf packets per second)\n",cpu_time_used,total_d);
352 else
354 fprintf(stderr, "\n");
358 return(0);