docs: minor: use long version
[netsniff-ng.git] / src / mausezahn.c
blob89ee8b5c3cfb9b0c4a83cafcbce327655022ef3f
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;
159 // Reset all globals
160 (void) reset(0);
162 // Get all CLI options (sets globals, see mz.h)
163 if ( getopts(argc, argv) )
165 (void) fprintf(stderr, " Invalid command line parameters!\n");
166 usage();
169 // Check whether hires timers are supported or not:
170 (void) check_timer();
174 // *********************************************************************
175 // First prefer data in a mausezahn description file!
176 // *********************************************************************
180 // >>> TODO:
181 // Note that argument 'device' is also used here!
182 // Support libpcap
183 // Must end in state machine!
187 // *********************************************************************
188 // If no MDF given, then send packet according CLI specifications
189 // *********************************************************************
192 (void) signal(SIGINT, clean_up); // to close all file pointers etc upon SIGINT
194 switch (mode)
196 case BYTE_STREAM:
197 send_eth();
198 break;
200 case ARP:
201 (void) send_arp();
202 break;
204 case BPDU:
205 (void) send_bpdu();
206 break;
208 case CDP:
209 (void) send_cdp();
210 break;
212 case IP: // From now on a new much more modular method is used:
213 l = get_link_context();
214 t3 = create_ip_packet(l); // t3 can be used for later header changes
215 if (!quiet) complexity();
216 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
217 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
218 else
219 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
220 break;
222 case ICMP:
223 tx.ip_proto = 1;
224 l = get_link_context();
225 t4 = create_icmp_packet(l); // t4 can be used for later header changes
226 t3 = create_ip_packet(l); // t3 can be used for later header changes
227 if (!quiet) complexity();
228 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
229 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
230 else
231 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
232 break;
234 case ICMP6:
235 tx.ip_proto = 58;
236 l = get_link_context();
237 t4 = create_icmp6_packet(l); // t4 can be used for later header changes
238 t3 = create_ip_packet(l); // t3 can be used for later header changes
239 if (ipv6_mode)
240 update_ISUM(l, t4);
241 if (!quiet) complexity();
242 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
243 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
244 else
245 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
246 break;
248 case UDP:
249 tx.ip_proto = 17;
250 l = get_link_context();
251 t4 = create_udp_packet(l); // t4 can be used for later header changes
252 t3 = create_ip_packet(l); // t3 can be used for later header changes
253 if (ipv6_mode)
254 update_USUM(l, t4);
255 if (!quiet) complexity();
256 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
257 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
258 else
259 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
260 break;
262 case TCP:
263 tx.ip_proto = 6;
264 l = get_link_context();
265 t4 = create_tcp_packet(l); // t4 can be used for later header changes
266 t3 = create_ip_packet(l); // t3 can be used for later header changes
267 if (ipv6_mode)
268 update_TSUM(l, t4);
269 if (!quiet) complexity();
270 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
271 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
272 else
273 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
274 break;
276 case DNS:
277 tx.ip_proto = 17;
278 l = get_link_context();
279 (void) create_dns_packet();
280 t4 = create_udp_packet(l); // t4 can be used for later header changes
281 t3 = create_ip_packet(l); // t3 can be used for later header changes
282 if (!quiet) complexity();
283 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
284 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
285 else
286 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
287 break;
289 case RTP:
290 tx.ip_proto = 17;
291 l = get_link_context();
292 if (!quiet) fprintf(stderr, " mz: RTP mode! (count=%u, delay=%u usec)\n\n", tx.count, tx.delay);
293 (void) create_rtp_packet();
294 t4 = create_udp_packet(l); // t4 can be used for later header changes
295 t3 = create_ip_packet(l); // t3 can be used for later header changes
296 if (!quiet) complexity();
297 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
298 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
299 else
300 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
301 break;
303 case RX_RTP: // Receive RTP packets
304 rcv_rtp_init();
305 rcv_rtp();
306 break;
308 case SYSLOG:
309 tx.ip_proto = 17;
310 l = get_link_context();
311 (void) create_syslog_packet();
312 t4 = create_udp_packet(l); // t4 can be used for later header changes
313 t3 = create_ip_packet(l); // t3 can be used for later header changes
314 if (!quiet) complexity();
316 if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst
317 t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes
318 else
319 send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly
320 break;
322 case LLDP: // start with a new concept here
323 //l = get_link_context();
324 //(void) create_lldp_packet();
325 // // // printf("SIZE=%lu\n",sizeof(struct tx_struct));
326 fprintf(stderr, "LLDP is currently only supported via the interactive mode\n");
327 exit(1);
328 break;
331 default:
332 (void) fprintf(stderr," mz/main: unknown mode! Stop.\n");
333 return (1);
336 if (!quiet)
338 mz_stop = clock();
339 cpu_time_used = ((double) (mz_stop - mz_start)) / CLOCKS_PER_SEC;
340 if (cpu_time_used > 0)
342 total_d /= cpu_time_used;
343 fprintf(stderr, "%.2f seconds (%.Lf packets per second)\n",cpu_time_used,total_d);
345 else
347 fprintf(stderr, "\n");
351 return(0);