1 /*
2  * macof.c
3  *
4  * C port of macof-1.1 from the Perl Net::RawIP distribution.
5  * Tests network devices by flooding local network with MAC-addresses.
6  *
7  * Perl macof originally written by Ian Vitek <ian.vitek@infosec.se>.
8  *
9  * Copyright (c) 1999 Dug Song <dugsong@monkey.org>
10  *
11  * $Id: macof.c,v 1.15 2001/03/15 08:33:04 dugsong Exp $
12  */
13 
14 #include "config.h"
15 
16 #include <sys/types.h>
17 #include <sys/param.h>
18 #include <netinet/in.h>
19 
20 #include <stdio.h>
21 #include <string.h>
22 #include <err.h>
23 #include <libnet.h>
24 #include <pcap.h>
25 
26 #include "version.h"
27 
28 extern char *ether_ntoa(struct ether_addr *);
29 extern struct ether_addr *ether_aton(char *);
30 
31 in_addr_t	Src = 0;
32 in_addr_t	Dst = 0;
33 u_char *Tha = NULL;
34 u_short	Dport = 0;
35 u_short Sport = 0;
36 char   *Intf = NULL;
37 int	Repeat = -1;
38 
39 static void
usage(void)40 usage(void)
41 {
42 	fprintf(stderr, "Version: " VERSION "\n"
43 		"Usage: macof [-s src] [-d dst] [-e tha] [-x sport] [-y dport]"
44 		"\n             [-i interface] [-n times]\n");
45 	exit(1);
46 }
47 
48 static void
gen_mac(u_char * mac)49 gen_mac(u_char *mac)
50 {
51 	*((in_addr_t *)mac) = libnet_get_prand(LIBNET_PRu32);
52 	*((u_short *)(mac + 4)) = libnet_get_prand(LIBNET_PRu16);
53 }
54 
55 int
main(int argc,char * argv[])56 main(int argc, char *argv[])
57 {
58 	extern char *optarg;
59 	extern int optind;
60 	int c, i;
61 	struct libnet_link_int *llif;
62 	char pcap_ebuf[PCAP_ERRBUF_SIZE];
63 	char libnet_ebuf[LIBNET_ERRBUF_SIZE];
64 	u_char sha[ETHER_ADDR_LEN], tha[ETHER_ADDR_LEN];
65 	in_addr_t src, dst;
66 	u_short sport, dport;
67 	u_int32_t seq;
68 	libnet_t *l;
69 
70 	while ((c = getopt(argc, argv, "vs:d:e:x:y:i:n:h?V")) != -1) {
71 		switch (c) {
72 		case 'v':
73 			break;
74 		case 's':
75 			Src = libnet_name2addr4(l, optarg, 0);
76 			break;
77 		case 'd':
78 			Dst = libnet_name2addr4(l, optarg, 0);
79 			break;
80 		case 'e':
81 			Tha = (u_char *)ether_aton(optarg);
82 			break;
83 		case 'x':
84 			Sport = atoi(optarg);
85 			break;
86 		case 'y':
87 			Dport = atoi(optarg);
88 			break;
89 		case 'i':
90 			Intf = optarg;
91 			break;
92 		case 'n':
93 			Repeat = atoi(optarg);
94 			break;
95 		default:
96 			usage();
97 		}
98 	}
99 	argc -= optind;
100 	argv += optind;
101 
102 	if (argc != 0)
103 		usage();
104 
105 	if (!Intf && (Intf = pcap_lookupdev(pcap_ebuf)) == NULL)
106 		errx(1, "%s", pcap_ebuf);
107 
108 	if ((l = libnet_init(LIBNET_LINK, Intf, libnet_ebuf)) == NULL)
109 		errx(1, "%s", libnet_ebuf);
110 
111 	libnet_seed_prand(l);
112 
113 	for (i = 0; i != Repeat; i++) {
114 
115 		gen_mac(sha);
116 
117 		if (Tha == NULL) gen_mac(tha);
118 		else memcpy(tha, Tha, sizeof(tha));
119 
120 		if (Src != 0) src = Src;
121 		else src = libnet_get_prand(LIBNET_PRu32);
122 
123 		if (Dst != 0) dst = Dst;
124 		else dst = libnet_get_prand(LIBNET_PRu32);
125 
126 		if (Sport != 0) sport = Sport;
127 		else sport = libnet_get_prand(LIBNET_PRu16);
128 
129 		if (Dport != 0) dport = Dport;
130 		else dport = libnet_get_prand(LIBNET_PRu16);
131 
132 		seq = libnet_get_prand(LIBNET_PRu32);
133 
134 		libnet_build_tcp(sport, dport, seq, 0, TH_SYN, 512,
135 				 0, 0, LIBNET_TCP_H, NULL, 0, l, 0);
136 
137 		libnet_build_ipv4(LIBNET_TCP_H, 0,
138 				  libnet_get_prand(LIBNET_PRu16), 0, 64,
139 				  IPPROTO_TCP, 0, src, dst, NULL, 0, l, 0);
140 
141 		libnet_build_ethernet(tha, sha, ETHERTYPE_IP, NULL, 0, l, 0);
142 
143 		if (libnet_write(l) < 0)
144 			errx(1, "write");
145 
146 		libnet_clear_packet(l);
147 
148 		fprintf(stderr, "%s ",
149 			ether_ntoa((struct ether_addr *)sha));
150 		fprintf(stderr, "%s %s.%d > %s.%d: S %u:%u(0) win 512\n",
151 			ether_ntoa((struct ether_addr *)tha),
152 			libnet_addr2name4(Src, 0), sport,
153 			libnet_addr2name4(Dst, 0), dport, seq, seq);
154 	}
155 	exit(0);
156 }
157