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