1 /*
2 *
3 * Arpoison -- The UNIX Arp Cache Update Utility
4 *
5 * $Id: arpoison.c,v 1.2 2014/02/07 01:17:03 buer Exp $
6 *
7 */
8
9
10 #include <stdio.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <errno.h>
14 #include <libnet.h>
15
16 #define ARP_REPLY 2
17 #define ARP_REQUEST 1
18
usage()19 void usage()
20 {
21 printf("Usage: -i <device> -d <dest IP> -s <src IP> -t <target MAC> -r <src MAC> "
22 "[-a] [-w time between packets] [-n number to send]\n");
23 exit(1);
24 }
25
main(int argc,char * argv[])26 int main(int argc, char *argv[])
27 {
28 int n,c,z,o,op_code,wait;
29 int packets_to_send = 0;
30 int packets_sent = 0;
31 int count = 0;
32 u_long SrcIP, DstIP;
33 char *device;
34 char err_buf[LIBNET_ERRBUF_SIZE];
35 unsigned int p[6];
36 u_char DstHW[6];
37 u_char SrcHW[6];
38
39 /* added for libnet 1.1 */
40 libnet_t *l;
41 libnet_ptag_t eth_tag;
42 libnet_ptag_t arp_tag;
43
44 /* init */
45
46 eth_tag = arp_tag = LIBNET_PTAG_INITIALIZER;
47 wait = 1;
48 op_code = ARP_REPLY;
49 device = "eth0";
50 SrcIP = DstIP = 0;
51 SrcHW[0] = DstHW[0] = 'N';
52
53 while ((z = getopt(argc, argv, "ad:f:hi:r:n:s:t:w:")) != EOF) {
54
55 switch (z) {
56
57 case 'h':
58
59 usage();
60 break;
61
62 case 'd':
63
64 DstIP = inet_addr(optarg);
65 if (DstIP == -1) {
66
67 printf("Not a valid ip\n");
68 exit(1);
69 }
70 break;
71
72 case 's':
73
74 SrcIP = inet_addr(optarg);
75 if (SrcIP == -1) {
76 printf("Not a valid ip\n");
77 exit(1);
78 }
79 break;
80
81 case 'i':
82
83 device = optarg;
84 break;
85
86 case 't':
87
88 n = sscanf(optarg, "%x:%x:%x:%x:%x:%x",
89 &p[0],
90 &p[1],
91 &p[2],
92 &p[3],
93 &p[4],
94 &p[5]);
95
96 if (n != 6) {
97
98 printf("error parsing MAC\n");
99 exit(1);
100 }
101
102 for ( c = 0 ; c < 6 ; c++)
103 DstHW[c] = p[c];
104
105 break;
106
107 case 'r':
108
109 n = sscanf(optarg, "%x:%x:%x:%x:%x:%x",
110 &p[0],
111 &p[1],
112 &p[2],
113 &p[3],
114 &p[4],
115 &p[5]);
116
117 if (n != 6) {
118
119 printf("error parsing MAC\n");
120 exit(1);
121 }
122
123 for ( c = 0 ; c < 6 ; c++)
124 SrcHW[c] = p[c];
125
126 break;
127
128 case 'w':
129
130 wait = atoi(optarg);
131 break;
132
133 case 'n':
134
135 packets_to_send = atoi(optarg);
136 break;
137
138 case 'f':
139
140 o++;
141 break;
142
143 case 'a':
144
145 op_code = ARP_REQUEST;
146 break;
147
148 default:
149 usage();
150
151 } // switch
152
153 } // while
154
155 if(SrcIP == 0 || DstIP == 0 || SrcHW[0] == 'N' || DstHW[0] == 'N')
156 usage();
157
158 if (getuid()) {
159
160 printf("Must be run as root\n");
161 exit(1);
162 }
163
164 l = libnet_init(LIBNET_LINK, device, err_buf );
165
166 if (l == NULL) {
167
168 printf("libnet_init: error %s\n", err_buf);
169 exit(1);
170 }
171
172 /* ARP header */
173
174 arp_tag = libnet_build_arp(
175 1, /* hardware type */
176 0x0800, /* proto type */
177 6, /* hw addr size */
178 4, /* proto addr size */
179 op_code, /* ARP OPCODE */
180 SrcHW, /* source HW addr */
181 (u_char *)&SrcIP, /* src proto addr */
182 DstHW, /* dst HW addr */
183 (u_char *)&DstIP, /* dst IP addr */
184 NULL, /* no payload */
185 0, /* payload length */
186 l, /* libnet tag */
187 0); /* ptag see man */
188
189 if (arp_tag == -1) {
190
191 perror("libnet_build_arp");
192 exit(1);
193 }
194
195 /* ethernet header */
196
197 eth_tag = libnet_build_ethernet(
198 DstHW, /* dst HW addr */
199 SrcHW, /* src HW addr */
200 0x0806, /* ether packet type */
201 NULL, /* ptr to payload */
202 0, /* payload size */
203 l,
204 0); /* ptr to packet memory */
205
206 if (eth_tag == -1) {
207
208 perror("libnet_build_ethernet");
209 exit(1);
210 }
211
212 for (;;) {
213
214 n = libnet_write(l);
215
216 if (n == -1 )
217 printf("libnet write error");
218
219 count++;
220
221 printf("ARP %s %d sent via %s\n", (op_code == ARP_REQUEST) ? "request" : "reply", count, device);
222
223 if (packets_to_send) {
224
225 packets_sent++;
226
227 if (packets_sent >= packets_to_send)
228 break;
229 }
230
231 sleep(wait);
232 }
233
234 libnet_destroy(l);
235
236 return 0;
237 }
238
239 //////////////////////////////////////////////////////////////////////
240 // //
241 // ///\\\ /*////\/\\/*/ /**********/ //
242 // /*/ \*\ /*/ /*/ /*/ /*/ //
243 // /*/ \*\ /*/ /*/ /*/ /*/ //
244 // /*/ \*\ /*/ /*/ /*/ /*/ //
245 // /*//\/\/\/\\*\ /*/\//\\/*/ /********/ //
246 // /*/ \*\ /*/\\\\ /*/ //
247 // /*/ \*\ /*/ \\\\ /*/ //
248 // /*/ \*\ /*/ \\\\ /*/ //
249 // /*/ \*\ /*/ \\\\ /*/ //
250 // //
251 //////////////////////////////////////////////////////////////////////
252