@@ -43,11 +43,14 @@ static int poison_reverse;
43
43
static uint8_t * my_ha = NULL ;
44
44
static uint8_t * brd_ha = "\xff\xff\xff\xff\xff\xff" ;
45
45
46
+ static int cleanup_src_own = 1 ;
47
+ static int cleanup_src_host = 0 ;
48
+
46
49
static void
47
50
usage (void )
48
51
{
49
52
fprintf (stderr , "Version: " VERSION "\n"
50
- "Usage: arpspoof [-i interface] [-t target] [-r] host\n" );
53
+ "Usage: arpspoof [-i interface] [-c own|host|both] [- t target] [-r] host\n" );
51
54
exit (1 );
52
55
}
53
56
@@ -152,18 +155,23 @@ cleanup(int sig)
152
155
int fw = arp_find (spoof .ip , & spoof .mac );
153
156
int bw = poison_reverse && targets [0 ].ip && arp_find_all ();
154
157
int i ;
158
+ int rounds = (cleanup_src_own * 5 + cleanup_src_host * 5 );
155
159
156
160
fprintf (stderr , "Cleaning up and re-arping targets...\n" );
157
- for (i = 0 ; i < 10 ; i ++ ) {
161
+ for (i = 0 ; i < rounds ; i ++ ) {
158
162
struct host * target = targets ;
159
163
while (target -> ip ) {
164
+ uint8_t * src_ha = NULL ;
165
+ if (cleanup_src_own && (i %2 || !cleanup_src_host )) {
166
+ src_ha = my_ha ;
167
+ }
160
168
/* XXX - on BSD, requires ETHERSPOOF kernel. */
161
169
if (fw ) {
162
170
arp_send (l , ARPOP_REPLY ,
163
171
(u_int8_t * )& spoof .mac , spoof .ip ,
164
172
(target -> ip ? (u_int8_t * )& target -> mac : brd_ha ),
165
173
target -> ip ,
166
- ( i % 2 ? my_ha : NULL ) );
174
+ src_ha );
167
175
/* we have to wait a moment before sending the next packet */
168
176
sleep (1 );
169
177
}
@@ -172,7 +180,7 @@ cleanup(int sig)
172
180
(u_int8_t * )& target -> mac , target -> ip ,
173
181
(u_int8_t * )& spoof .mac ,
174
182
spoof .ip ,
175
- ( i % 2 ? my_ha : NULL ) );
183
+ src_ha );
176
184
sleep (1 );
177
185
}
178
186
target ++ ;
@@ -191,6 +199,7 @@ main(int argc, char *argv[])
191
199
char libnet_ebuf [LIBNET_ERRBUF_SIZE ];
192
200
int c ;
193
201
int n_targets ;
202
+ char * cleanup_src = NULL ;
194
203
195
204
spoof .ip = 0 ;
196
205
intf = NULL ;
@@ -200,7 +209,7 @@ main(int argc, char *argv[])
200
209
/* allocate enough memory for target list */
201
210
targets = calloc ( argc + 1 , sizeof (struct host ) );
202
211
203
- while ((c = getopt (argc , argv , "ri:t:h?V" )) != -1 ) {
212
+ while ((c = getopt (argc , argv , "ri:t:c: h?V" )) != -1 ) {
204
213
switch (c ) {
205
214
case 'i' :
206
215
intf = optarg ;
@@ -212,6 +221,9 @@ main(int argc, char *argv[])
212
221
case 'r' :
213
222
poison_reverse = 1 ;
214
223
break ;
224
+ case 'c' :
225
+ cleanup_src = optarg ;
226
+ break ;
215
227
default :
216
228
usage ();
217
229
}
@@ -227,6 +239,28 @@ main(int argc, char *argv[])
227
239
usage ();
228
240
}
229
241
242
+ if (!cleanup_src || strcmp (cleanup_src , "host" )== 0 ) { /* default! */
243
+ /* only use the target hw address when cleaning up;
244
+ * this can screw up some bridges and scramble access
245
+ * for our own host.
246
+ */
247
+ cleanup_src_own = 0 ;
248
+ cleanup_src_host = 1 ;
249
+ } else if (strcmp (cleanup_src , "own" )== 0 ) {
250
+ /* only use our own hw address when cleaning up,
251
+ * not jeopardizing any bridges on the way to our
252
+ * target
253
+ */
254
+ cleanup_src_own = 1 ;
255
+ cleanup_src_host = 0 ;
256
+ } else if (strcmp (cleanup_src , "both" )== 0 ) {
257
+ cleanup_src_own = 1 ;
258
+ cleanup_src_host = 1 ;
259
+ } else {
260
+ errx (1 , "Invalid parameter to -c: use 'own', 'host' or 'both'." );
261
+ usage ();
262
+ }
263
+
230
264
if ((spoof .ip = libnet_name2addr4 (l , argv [0 ], LIBNET_RESOLVE )) == -1 )
231
265
usage ();
232
266
0 commit comments