summaryrefslogtreecommitdiff
path: root/README
blob: 6bcf5b9c59cd89b332cd41eeb323a8aa0098b13c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
arping/README

 ARP Ping 1.x

    By Thomas Habets <thomas@habets.pp.se>


Introduction
------------
First of all, this is a legacy package for people that can't run
libnet 1.1.x. Arping 1.x only works with libnet 1.0.x.

Installing libnet 1.1.x and Arping 2.x is recommended.

Arping is a util to find out it a specific IP address on the LAN is 'taken'
and what MAC address owns it. Sure, you *could* just use 'ping' to find out if
it's taken and even if the computer blocks ping (and everything else) you still
get an entry in your ARP cache. But what if you aren't on a routable net? Or
the host blocks ping (all ICMP even)? Then you're screwed. Or you use arping.

Why it's not stupid
-------------------
Say you have a block of N real ARIN-assigned IP-addresses. You want to debug
the net and you don't know which IP addresses are taken. You can't ping anyone
before you take the IP, and you can't pick an IP before you know which are
already taken. Catch 22. But with arping you can 'ping' the IP and if you get
no response, the IP is available.

Example uses
------------
If some box is dumping non-IP (like IPX) garbage and you don't know which box
it is, you can ping by MAC to get the IP and fix the problem.

If you are on someone else's net and want to 'borrow' a real IP address instead
of using one of those 10.x.x.x-addresses the DHCP hands out you probably want
to know which ones are taken, or people will get mad (a friend of mine got a
call on his cellphone about 15 seconds after he accidentally 'stole' an IP,
oops).

Compiling
---------
You will need libpcap and libnet 1.0.x. Not libnet 1.1.x. If you have
libnet 1.1.x then you must use arping 2.x. This is recommended anyway.

Run "make osname", where osname is one of linux, freebsd, openbsd,
netbsd, solaris or macosx.

'make install' will copy arping to /usr/local/bin, and put the manpage where
it belongs.

Mailing list
------------
Check out http://www.habets.pp.se/synscan/mailinglists.php for information
on how to subscribe to help- and announce-lists.

How it does it
--------------
See 'Technical' at the bottom of this file.

FAQ
---
Q: It doesn't compile!

A: Maybe u_int32_t and co. are not defined. Try uncommenting the line:
   #include <stdint.h> in arping-2/arping.c. This has been an issue on
   MacOS X, I think. I don't have access to such a box so it's a bit hard
   to fix.

A: Arping 1.x will not work with Libnet 1.1.x. This is This is due to
   libnet 1.1.x being completely different from 1.0.x. There is no
   real way to write code that works on both 1.0.x and 1.1.x.

   Since I wanted to do some other things a bit differently, I wrote
   arping 2.x. It isn't as widely tested as arping 1.x, but it seems
   to work fine.

   Arping 1.x and 2.x are no longer in the same tarball.

A: On BSD, you'll probably need to type something like:
   gmake MAKE=gmake openbsd
---
Q: Where's the Windows version? A compiled .exe would be nice.

A: I don't have a windows box, so the .exe I'm providing was NOT compiled
   by me. If something is strange about it tell me, but there won't be much
   I can do about it.
   That being said:
   http://www.habets.pp.se/synscan/files/arping-for-windows-not-compiled-by-me.exe
---
Q: On sparc64, the IP shown in the output is 0.0.0.0.

A: Libnets fault, should be fixed there.
---
Q: After compiling arping without any problem, i test it first with
   localhost... but it doesn't respond. Isn't that strange?

A: Not really, as you can see by typing 'ifconfig' the lo (local) interface
   does not have a MAC address. It's not a physical device! MAC addresses are
   there to differentiate computers on a shared medium (the aether, or ether)
   and since packets to localhost does not go over any wire there is no need
   to identify which box is talking to which. There is only one.
---
Q: Arping can't ping anything!

A: Check which interface is active with -v. If it's the wrong one, use -i
   to set it right.
---
Q: Arping finds some hosts, but not others. why?   BTW, I have several NICs.

A: You have to choose interface with the -i switch if the default is wrong for
   you.
---
Q: I tried to ping my own MAC address, but it doesn't work.

A: A sane OS will think it's suspicious if you send packets to yourself over
   the wire and will ignore them.

   And why would you want to lookup the IP or MAC of yourself? ifconfig
   can tell you that.
---
Q: I can't ping any/some MAC address on my LAN.

A: Arping when pinging a MAC relies on the host to answer a broadcast ping
   (icmp echo request) properly (IIRC: not the windows way). If you want a
   host to pop up on MAC ping, you have to config it to respond to broadcast
   pings.
   (for linux, make sure /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts is 0)
A: -T <IP/host> allows you to restrict the arping to a limited subnet, which
   may or may not work for you. For example if the box 00:01:02:03:04:05 is on
   192.168.0.0/24 then the broadcast probably is 192.168.0.255, so try:
   # arping -T 192.168.0.255 00:01:02:03:04:05
---
Q: It doesn't compile, I get some error message about libnet and/or libpcap

A: Arping depends on libnet and libpcap, get libnet at:
   http://www.packetfactory.net/libnet and libpcap from your distribution.
   (alt. you can search for libpcap on http://freshmeat.net)
---
Q: I get this when I compile: "/bin/sh: libnet-config: command not found"

A: You didn't really read the last question, did you? Go back up 6 lines.
---
Q: I get bus error on my bigendian box

A: Damn, I thought I fixed those. Tell me how you got it and I'll try to fix
   it.
---
Q: I get "libnet_get_ipaddr(): no error" when I run arping with IP (src or dst)
   255.255.255.255.

A: Use the -b/-B switches. Libnet sucks (ha ha only serious) and returns -1 for
   error == int32 encoded 255.255.255.255.
---
Q: I used to be able to use -S 255.255.255.255, now it fails. What's going on?
Q: Why can't I arping 255.255.255.255?

A: Argh! Why would you want to? Anyway, this one is due to libnets resolving,
   and my unwillingness to reimplement it (in a portable manner, ugh).

   -S 255.255.255.255 can be replaced with -b, and pinging broadcast (why you
   would do that eludes me) -B.

   To be extra perverted, try:
   # ./arping -b -B
   (yes, I added -b and -B just so that version 1.0 should be complete)
---
Q: 1.01 is out, didn't you just say 1.0 was supposed to be the last one?

A: Shut up.
---
Q: The roundtrip times are off, sometimes by milliseconds!

A: I know.
   Short answer:
     'ping' does the same thing. (ping from iputils-ss010824 anyway)

   Long answer:
     I can't (portably anyway) do anything other than queue a packet
     to the network. That means I don't know exactly when it arrived. Also,
     I can't tell when a packet arrives on the wire, only when arping gets
     it from the kernel. Just make sure neither the network (whole segment
     if you are hubbed, just your NIC if you are switched) nor your box is
     loaded when you care about timing, and/or run arping with higher
     priority.

     # nice -n -15 arping foobar

     But if you find way to get more exact timing portably (or just for one
     OS really), let me know.
---
Q: Is it OK to make arping suid root?

A: Be my guest, but if care about security *at all* you will have to restrict
   execution of arping to trusted users. I could remove "dangerous" features
   from the code when it's running suid, but I honestly don't want to. This is
   a network debugging tool, which generates low-level network packets that
   ordinary users have absolutely no business generating.

   For example, I don't protect against an ALRM signal flood, which will result
   in a packet flood. (arping 2.x doesn't have this issue)

   If you are honestly debugging the network then I don't see why you aren't
   root already.

   If you think I'm wrong, tell me why.
---
Q: What's this -A switch all about, I don't understand it.

A: Normally arping packets are sent out to some kind of broadcast (MAC or IPv4
   broadcast) and hosts reply with source address == their address.

   If -A is given, only packets coming in with a *source* address equal
   to the *destination* address in the query is accepted.

   If you don't understand, don't worry. You won't need it. But for an
   example use, see the arping-scan-net.sh script.
---
Q: Arping used to work (0.97 and down) for pinging MACs, but not with 0.98 and
   up. What did you screw up?

A: Ah, I see. A broadcast was changed to unicast, I don't know why I set it to
   be broadcast in the first place, and even wrote a comment justifying it.
   It still worked for me when I tested it now (with unicast) but if it
   doesn't for you, search the source for KEYWORD and you'll find
   instructions on how to change it back.
   ... Or you can run arping -s ff:ff:ff:ff:ff:ff <host>.
   If this fixes it please LET ME KNOW.
---
Q: 1.08 and up is broken, 1.07 and down worked. What's up with that?

A: If there are any problems, it should be with the interface-finding code.
   Try compiling with 'make linux-nofindif'.
   Also, try with the -F switch, and mail me if that worked (or didn't work).
---

Misc
----
There, I added the stupid roundtrip time feature. Now I dare you to think of
any other applicable features. (IPv4 only, for now and probably forever)

Ok, two more were thought of. Both of which are non-trivially-portable.
1) Automatically select interface depending on IP address pinged for more than
   Linux.
2) Don't use SIGARLM. Non-trivial because you can't (AFAIK) select() on a pcap-
   opened device.

Arping 2.x solves the second one, and the first one has a beta solution in
Linux and BSD.

License
-------
It's GPL, see the LICENSE file.

Technical
---------
Yes, I've finally bothered to write how it works.
tcpdumps were taken with "tcpdump -vven 'arp or icmp'".

The source box is 192.168.0.2/0:10:5a:3e:c5:b4 and the target box is
192.168.0.1/0:60:93:34:91:99.

For pinging IP addresses:
 When a host wants to send an IP packet to another host, it sends out an ARP
 packet asking what MAC the destination IP address has, a so-called 'who-has'
 packet. This is then answered by another ARP packet, the 'is-at' packet.
 
 18:16:07.179699 0:10:5a:3e:c5:b4 ff:ff:ff:ff:ff:ff 0806 42:
                 arp who-has 192.168.0.1 tell 192.168.0.2
 
 This is the packet generated by arping.
 An Ethernet frame from my 3com card to the broadcast address carrying an arp
 packet asking what MAC 192.168.0.1 has (who-has).
 
 18:16:07.180221 0:60:93:34:91:99 0:10:5a:3e:c5:b4 0806 60:
                 arp reply 192.168.0.1 is-at 0:60:93:34:91:99
 
 The answer, that 192.168.0.1 has MAC 0:60:93:34:91:99 (is-at).
 
For pinging MAC addresses:
 A broadcast ping (255.255.255.255, or any address supplied with -T, see below)
 is sent out on the Ethernet, but in an Ethernet frame addressed to the target
 MAC only.
 
 18:20:09.627321 0:10:5a:3e:c5:b4 0:60:93:34:91:99 0800 42:
                 192.168.0.2 > 255.255.255.255: icmp: echo request
                 (ttl 48, id 17767, len 28)
 
 This is the packet generated by arping.
 Ethernet frame from my 3com NIC to the destination MAC, carrying a broadcast
 ping.
 
 18:20:09.628432 0:60:93:34:91:99 0:10:5a:3e:c5:b4 0800 60:
                 192.168.0.1 > 192.168.0.2: icmp: echo reply
                 (ttl 255, id 7593, len 28)
 
 The answer, including the source address of the target host. Note that this
 is not how every OS responds to a broadcast ping (if at all). Some answer with
 a source address equal to the broadcast address, and others don't' answer at
 all.
 This is why pinging a raw MAC doesn't always work, and you may need to play
 with -T to get it to answer correctly (or at all). You can always brute-force
 if you can't even find a broadcast that the box will answer correctly to.
 -------
 for d in $(seq 0 255); do
     sudo arping -q -c 1 -T $a.$b.$c.$d 0:60:93:34:91:99
     if [ $? = 0 ]; then
       echo "Got answer with address: 192.168.0.$d"
     fi
 done
 --------
 Note that this script will take 1 second per IP since that is how long arping
 waits, so scanning a C-class net will take 256 seconds. If you have a bigger
 net, then write a program that will run several arpings at the same time to
 go through more in less time, or check out arping-scan-net.sh, which is a
 more capable script for scanning, but you need to edit it since the address
 range it searches is hard-coded.
 I may add this to arping some day, but don't hold your breath. 

----------------------------------------------------------------------------
Send questions/suggestions/patches/rants/money/alphas to thomas@habets.pp.se