13
19
* Also finds out IP of specified MAC
15
* $Id: arping.c,v 1.51 2002/02/12 18:17:47 marvin Exp $
18
* Copyright (C) 2000-2002 Thomas Habets <thomas@habets.pp.se>
20
* This library is free software; you can redistribute it and/or
21
* modify it under the terms of the GNU General Public
22
* License as published by the Free Software Foundation; either
23
* version 2 of the License, or (at your option) any later version.
25
* This library is distributed in the hope that it will be useful,
26
* but WITHOUT ANY WARRANTY; without even the implied warranty of
27
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28
* General Public License for more details.
30
* You should have received a copy of the GNU General Public
31
* License along with this library; if not, write to the Free Software
32
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
* $Id: arping.c,v 1.64 2003/08/03 23:06:58 marvin Exp $
24
* Copyright (C) 2000-2003 Thomas Habets <thomas@habets.pp.se>
26
* This program is free software; you can redistribute it and/or modify
27
* it under the terms of the GNU General Public License as published by
28
* the Free Software Foundation; either version 2 of the License, or
29
* (at your option) any later version.
31
* This program is distributed in the hope that it will be useful,
32
* but WITHOUT ANY WARRANTY; without even the implied warranty of
33
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34
* GNU General Public License for more details.
36
* You should have received a copy of the GNU General Public License
37
* along with this program; if not, write to the Free Software
38
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
42
* Test checklist: (cmac = mac in cisco format (0000.0000.0000)
43
* command expected response
45
* arping -a host audiable pongs
48
* arping -a mac audiable pongs
49
* arping -A host nothing
50
* arping -A mac nothing
51
* arping -t cmac -A host pongs
52
* arping -t mac -A host pongs
53
* arping -T ip -A mac pongs
54
* arping -T ip -A cmac pongs
55
* arping -T bcast mac pongs # bcast of current net
60
* arping -rR mac mac ip
61
* arping -rR ip mac ip
62
* ./arping-scan-net.sh mac ip
65
* Linux/x86 test with debian package libnet0-dev and libnet1-dev
69
* NetBSD/alpha (is libnet or arping unaligned? -- libnet I think)
70
* OpenBSD/sparc64 (libnet a bit buggy here)
35
74
#include <stdlib.h>
36
75
#include <unistd.h>
37
#include <net/ethernet.h>
39
77
#include <sys/time.h>
114
152
static unsigned int quiet = 0;
115
153
static unsigned int nullip = 0;
116
154
static unsigned int is_promisc = 0;
155
static unsigned int addr_must_be_same = 0;
158
const char *arping_lookupdev_default(u_int32_t srcip, u_int32_t dstip,
161
static const char *ifname;
162
if (!(ifname = pcap_lookupdev(ebuf))) {
168
#if defined(FINDIF) && defined(linux)
169
const char *arping_lookupdev(u_int32_t srcip, u_int32_t dstip, char *ebuf)
172
static char buf[1024];
178
libnet_host_lookup_r(dstip,0,buf2);
179
libnet_host_lookup_r(srcip,0,buf1);
182
* Construct and run command
184
snprintf(buf, 1023, "/sbin/ip route get %s from %s 2>&1",
186
DEBUG(printf("%s\n",buf));
187
if (!(f = popen(buf, "r"))) {
190
if (0 > (n = fread(buf, 1, sizeof(buf)-1, f))) {
195
if (-1 == pclose(f)) {
196
perror("arping: pclose()");
203
p = strstr(buf, "dev ");
217
return arping_lookupdev_default(srcip,dstip,ebuf);
220
const char *arping_lookupdev(u_int32_t srcip, u_int32_t dstip, char *ebuf)
222
return arping_lookupdev_default(srcip,dstip,ebuf);
118
226
static void sigint(int i)
249
hip = (struct iphdr*)((char*)eth + sizeof(struct libnet_ethernet_hdr));
358
hip = (struct iphdr*)((char*)eth
359
+ sizeof(struct libnet_ethernet_hdr));
250
360
hicmp = (struct icmphdr*)((char*)hip + sizeof(struct iphdr));
251
361
if ((htons(hicmp->type) == ICMP_ECHOREPLY)
252
362
&& ((!memcmp(eth->h_source, eth_target, ETH_ALEN)
266
383
printf("%.2x ", *cp++);
268
385
if (rawoutput & 1) {
270
libnet_host_lookup(hip->saddr,
387
memcpy(&tmp, &hip->saddr, 4);
388
printf("%s",libnet_host_lookup(tmp,0));
273
390
if (!rawoutput) {
275
* ugly code due to non-aligned saddr (bus error on sparc)
392
* ugly code due to non-aligned saddr
393
* (bus error on sparc)
278
memcpy(&tmp, &hip->saddr, sizeof(u_int32_t));
396
memcpy(&tmp, &hip->saddr,
279
398
printf("%s",libnet_host_lookup(tmp,0));
281
400
for (c = 0; c < ETH_ALEN-1; c++) {
282
401
printf("%.2x:", *cp++);
284
printf("%.2x): icmp_seq=%d time=%s", *cp,
403
printf("%.2x): icmp_seq=%d time=%s",
285
405
hicmp->un.echo.sequence,
286
tvtoda(&lastpacketsent, &recvtime));
406
tvtoda(&lastpacketsent,
296
harp = (struct arphdr*)((char*)eth + sizeof(struct libnet_ethernet_hdr));
417
harp = (struct arphdr*)((char*)eth
418
+ sizeof(struct libnet_ethernet_hdr));
297
419
if ((htons(harp->ar_op) == ARPOP_REPLY)
298
420
&& (htons(harp->ar_pro) == ETH_P_IP)
299
421
&& (htons(harp->ar_hrd) == ARPHRD_ETHER)) {
301
423
memcpy(&ip, (char*)harp + harp->ar_hln
302
424
+ sizeof(struct arphdr), 4);
425
if (addr_must_be_same
426
&& (memcmp((u_char*)harp+sizeof(struct arphdr),
427
eth_target, ETH_ALEN))) {
304
432
cp = (u_char*)harp + sizeof(struct arphdr);
305
433
if (!rawoutput && !finddup) {
306
434
printf("%d bytes from ", h->len);
309
438
if (rawoutput & 1) {
310
439
for (c = 0; c < harp->ar_hln-1;
367
501
memcpy(eth_target, eth_xmas, ETH_ALEN);
369
while ((c = getopt(argc, argv, "0bdS:T:Bvhi:rRc:qs:t:pa")) != EOF) {
503
while ((c = getopt(argc, argv, "aAbBc:dF0S:T:hi:rRqs:t:pv")) != EOF) {
506
addr_must_be_same = 1;
512
maxcount = atoi(optarg);
519
fprintf(stderr, "arping: find-interface support not "
522
dont_use_arping_lookupdev=1;
430
577
case 's': // spoofed source MAC
434
if (sscanf(optarg, "%x:%x:%x:%x:%x:%x",
442
fprintf(stderr, "Illegal MAC addr %s\n",
446
for (c = 0; c < 6; c++) {
447
eth_source[c] = n[c] & 0xff;
578
if (sscanf(optarg, "%x:%x:%x:%x:%x:%x",
587
} else if(sscanf(optarg, "%2x%x.%2x%x.%2x%x",
597
fprintf(stderr, "arping: Illegal MAC addr "
601
for (c = 0; c < 6; c++) {
602
eth_source[c] = n[c] & 0xff;
453
607
must_be_pingip = 1;
457
if (sscanf(optarg, "%x:%x:%x:%x:%x:%x",
465
fprintf(stderr, "Illegal MAC addr %s\n",
469
for (c = 0; c < 6; c++) {
470
eth_target[c] = n[c] & 0xff;
608
if (sscanf(optarg, "%x:%x:%x:%x:%x:%x",
617
} else if(sscanf(optarg, "%2x%x.%2x%x.%2x%x",
627
fprintf(stderr,"arping: Illegal MAC addr %s\n",
632
for (c = 0; c < 6; c++) {
633
eth_target[c] = n[c] & 0xff;
495
if (searchmac || (!dip && strchr(argv[optind], ':'))) {
501
if (must_be_pingip) {
502
fprintf(stderr, "Specified switch can't be used in "
507
if (sscanf(argv[optind], "%x:%x:%x:%x:%x:%x",
515
fprintf(stderr, "Illegal mac addr %s\n", argv[optind]);
518
for (c = 0; c < 6; c++) {
519
eth_target[c] = n[c] & 0xff;
658
if (sscanf(argv[optind], "%x:%x:%x:%x:%x:%x",
667
} else if(sscanf(argv[optind], "%2x%x.%2x%x.%2x%x",
522
676
} else if (!dip) {
524
if (-1 == (dip = libnet_name_resolve((u_char*)argv[optind],
677
if (-1 == (dip=libnet_name_resolve((u_char*)argv[optind],
526
679
fprintf(stderr, "arping: Can't resolve %s\n",
683
} else if (must_be_pingip) {
684
fprintf(stderr, "arping: Illegal IP %s\n", argv[optind]);
687
fprintf(stderr, "arping: Illegal mac %s\n", argv[optind]);
690
if (searchmac && !dip) {
694
if (searchmac && must_be_pingip) {
695
fprintf(stderr, "arping: Specified switch can't be used in "
701
for (c = 0; c < 6; c++) {
702
eth_target[c] = n[c] & 0xff;
531
705
if (finddup && maxcount == -1) {
538
if (!(ifname = pcap_lookupdev(ebuf))) {
539
fprintf(stderr, "pcap_lookupdev(): %s\n", ebuf);
712
if (dont_use_arping_lookupdev) {
713
ifname = arping_lookupdev_default(myip,dip,ebuf);
715
ifname = arping_lookupdev(myip,dip,ebuf);
718
fprintf(stderr,"arping_lookupdev(): %s\n", ebuf);
721
// FIXME: check for other probably-not interfaces
722
if (!strcmp(ifname, "ipsec")
723
|| !strcmp(ifname, "lo")) {
724
fprintf(stderr, "arping: Um.. %s looks like the wrong "
725
"interface to use. Is it? "
726
"(-i switch)\n", ifname);
727
fprintf(stderr, "arping: using it anyway this time\n");
544
731
if (!(linkint = libnet_open_link_interface(ifname, ebuf))) {