├── .github
└── workflows
│ ├── c-cpp.yml
│ ├── code-coverage.yml
│ └── codeql.yml
├── .gitignore
├── AUTHORS
├── CONTRIBUTING.md
├── COPYING
├── ChangeLog
├── Makefile.am
├── NEWS
├── NEWS.md
├── README
├── README.md
├── SECURITY.md
├── TODO
├── arp-fingerprint
├── arp-fingerprint.1
├── arp-scan.1.dist
├── arp-scan.c
├── arp-scan.h
├── check-decode
├── check-error
├── check-host-list
├── check-ieee-reg
├── check-options
├── check-packet
├── check-prng
├── check-run1
├── configure.ac
├── error.c
├── format.c
├── get-oui
├── get-oui.1.dist
├── ieee-oui.txt
├── link-bpf.c
├── link-dlpi.c
├── link-packet-socket.c
├── m4
├── gcc-fortify-source.m4
├── gcc-stack-protect.m4
└── libcap-capabilities.m4
├── mac-vendor.5
├── mac-vendor.txt
├── mt19937ar-test.c
├── mt19937ar.c
├── mt19937ar.h
├── my_getopt.c
├── my_getopt.h
├── strlcpy.c
├── strlcpy.h
├── testdata
├── README.md
├── pkt-custom-request-llc.dat
├── pkt-custom-request-padding.dat
├── pkt-custom-request-vlan-llc.dat
├── pkt-custom-request-vlan.dat
├── pkt-custom-request.dat
├── pkt-diff-frame-addr.pcap
├── pkt-dup-response.pcap
├── pkt-ieee-regcheck.pcap
├── pkt-llc-response.pcap
├── pkt-local-admin.pcap
├── pkt-net1921681-response.pcap
├── pkt-padding-response.pcap
├── pkt-simple-request.dat
├── pkt-simple-response.pcap
├── pkt-too-short.pcap
├── pkt-trailer-response.pcap
├── pkt-vlan-llc-response.pcap
└── pkt-vlan-response.pcap
├── utils.c
└── wrappers.c
/.github/workflows/c-cpp.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 | on:
3 | push:
4 | branches: [ "master" ]
5 | pull_request:
6 | branches: [ "master" ]
7 |
8 | jobs:
9 | build:
10 | runs-on: ${{ matrix.os }}
11 |
12 | strategy:
13 | matrix:
14 | os: [ubuntu-latest, macos-latest]
15 |
16 | steps:
17 | - uses: actions/checkout@v3
18 | - name: install autotools on macos
19 | run: brew install automake
20 | if: matrix.os == 'macos-latest'
21 | - name: install libpcap on linux
22 | run: |
23 | sudo apt-get update -qq
24 | sudo apt-get install -qq libpcap0.8-dev libcap-dev
25 | if: matrix.os == 'ubuntu-latest'
26 | - name: autoreconf
27 | run: autoreconf --install
28 | - name: configure
29 | run: ./configure
30 | - name: make
31 | run: make
32 | - name: make distcheck
33 | run: make distcheck
34 | - name: localnet run
35 | run: |
36 | sudo make install
37 | arp-scan -vv --localnet --limit=1
38 | if: matrix.os == 'ubuntu-latest'
39 | - name: print info
40 | run: |
41 | uname -a
42 | lsb_release -a || true
43 | sw_vers || true
44 | gcc --version
45 | autoconf --version
46 | automake --version
47 | ./arp-scan --version
48 |
--------------------------------------------------------------------------------
/.github/workflows/code-coverage.yml:
--------------------------------------------------------------------------------
1 | # Coveralls code coverage test for arp-scan using github actions on Ubuntu runner.
2 |
3 | name: coverage
4 | on:
5 | push:
6 | branches: [ "master" ]
7 | pull_request:
8 | branches: [ "master" ]
9 |
10 | jobs:
11 | coverage:
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - uses: actions/checkout@v3
16 | - name: install libpcap and lcov
17 | run: |
18 | sudo apt-get update -qq
19 | sudo apt-get install -qq libpcap0.8-dev libcap-dev lcov
20 | - name: autoreconf
21 | run: autoreconf --install
22 | - name: configure with gcov
23 | run: ./configure --enable-gcov
24 | - name: make
25 | run: make
26 | - name: make check
27 | run: make check
28 | - name: localnet-run
29 | run: |
30 | sudo make install
31 | arp-scan -vv --localnet --limit=10
32 | - name: create lcov.info
33 | run: lcov --directory . --capture --output-file lcov.info
34 | - name: Coveralls
35 | uses: coverallsapp/github-action@master
36 | with:
37 | github-token: ${{ secrets.GITHUB_TOKEN }}
38 | path-to-lcov: ./lcov.info
39 |
--------------------------------------------------------------------------------
/.github/workflows/codeql.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ "master" ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ "master" ]
20 | schedule:
21 | - cron: '37 17 * * 2'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'cpp' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
38 |
39 | steps:
40 | - name: Checkout repository
41 | uses: actions/checkout@v3
42 | - name: install libpcap
43 | run: |
44 | sudo apt-get update -qq
45 | sudo apt-get install -qq libpcap0.8-dev libcap-dev
46 |
47 | # Initializes the CodeQL tools for scanning.
48 | - name: Initialize CodeQL
49 | uses: github/codeql-action/init@v2
50 | with:
51 | languages: ${{ matrix.language }}
52 | # If you wish to specify custom queries, you can do so here or in a config file.
53 | # By default, queries listed here will override any specified in a config file.
54 | # Prefix the list here with "+" to use these queries and those in the config file.
55 |
56 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
57 | # queries: security-extended,security-and-quality
58 |
59 |
60 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
61 | # If this step fails, then you should remove it and run the build manually (see below)
62 | - name: Autobuild
63 | uses: github/codeql-action/autobuild@v2
64 |
65 | # ℹ️ Command-line programs to run using the OS shell.
66 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
67 |
68 | # If the Autobuild fails above, remove it and uncomment the following three lines.
69 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
70 |
71 | # - run: |
72 | # echo "Run, Build Application using script"
73 | # ./location_of_script_within_repo/buildscript.sh
74 |
75 | - name: Perform CodeQL Analysis
76 | uses: github/codeql-action/analyze@v2
77 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Autoconf and automake generated files
2 | .deps/
3 | INSTALL
4 | Makefile
5 | Makefile.in
6 | aclocal.m4
7 | autom4te.cache/
8 | config.guess
9 | config.h
10 | config.h.in
11 | config.h.in~
12 | config.log
13 | config.status
14 | config.sub
15 | configure
16 | depcomp
17 | install-sh
18 | missing
19 | stamp-h1
20 | compile
21 | test-driver
22 | configure.ac~
23 | # Compiler output files
24 | *.o
25 | arp-scan
26 | *.gcno
27 | *.gcda
28 | *.gcov
29 | # IEEE OUI and IAB backup files
30 | ieee-iab.txt.bak
31 | ieee-oui.txt.bak
32 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | Roy Hills
2 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Notes for Contributors
2 |
3 | Most of the changes and improvements to arp-scan came from the community. So contributions are very welcome.
4 |
5 | - [Pull Requests](https://github.com/royhills/arp-scan/pulls): Please see the coding guidelines below.
6 | - [Issues](https://github.com/royhills/arp-scan/issues): For bug reports, feature requests, build problems, packaging issues, ideas, strange things you can't explain etc. Please check existing issues (both [open](https://github.com/royhills/arp-scan/issues?q=is%3Aopen+is%3Aissue) and [closed](https://github.com/royhills/arp-scan/issues?q=is%3Aissue+is%3Aclosed)) and the appropriate manual page before reporting, thanks.
7 |
8 | ## Coding Guidelines
9 |
10 | Please read these guidelines if you're submitting a pull request:
11 |
12 | - Must build and run on all supported platforms (possible exception for Solaris because it's moribund). The `arp-scan` team can help with porting, autoconf checks, unit tests etc.
13 | - Must compile without warnings with the GCC/Clang options that `arp-scan` builds with.
14 | - Source formatting style is `clang-format` with the following options (with a few exceptions):
15 | - `BasedOnStyle: LLVM`
16 | - `IndentWidth: 3`
17 | - `AlwaysBreakAfterDefinitionReturnType: All`
18 | - `IndentCaseLabels: true`
19 |
--------------------------------------------------------------------------------
/Makefile.am:
--------------------------------------------------------------------------------
1 | # Process this file with automake to produce Makefile.in
2 | #
3 | pkgsysconfdir = $(sysconfdir)/$(PACKAGE)
4 | AM_CPPFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" -DPKGSYSCONFDIR=\"$(sysconfdir)/$(PACKAGE)\"
5 | #
6 | bin_PROGRAMS = arp-scan
7 | #
8 | dist_bin_SCRIPTS = get-oui arp-fingerprint
9 | #
10 | dist_check_SCRIPTS = check-run1 check-packet check-decode check-host-list check-ieee-reg check-error check-options check-prng
11 | check_PROGRAMS = mt19937ar-test
12 | mt19937ar_test_SOURCES = mt19937ar-test.c mt19937ar.c mt19937ar.h
13 | #
14 | dist_man_MANS = arp-scan.1 get-oui.1 arp-fingerprint.1 mac-vendor.5
15 | #
16 | arp_scan_SOURCES = arp-scan.c arp-scan.h error.c wrappers.c utils.c mt19937ar.c format.c mt19937ar.h
17 | arp_scan_LDADD = $(LIBOBJS)
18 | #
19 | dist_pkgsysconf_DATA = mac-vendor.txt
20 | dist_pkgdata_DATA = ieee-oui.txt
21 | #
22 | TESTS = $(dist_check_SCRIPTS)
23 | EXTRA_DIST = arp-scan.1.dist get-oui.1.dist CONTRIBUTING.md SECURITY.md testdata/pkt-simple-request.dat testdata/pkt-custom-request.dat testdata/pkt-custom-request-padding.dat testdata/pkt-custom-request-llc.dat testdata/pkt-custom-request-vlan.dat testdata/pkt-simple-response.pcap testdata/pkt-padding-response.pcap testdata/pkt-vlan-response.pcap testdata/pkt-llc-response.pcap testdata/pkt-net1921681-response.pcap testdata/pkt-trailer-response.pcap testdata/pkt-vlan-llc-response.pcap testdata/pkt-custom-request-vlan-llc.dat testdata/pkt-dup-response.pcap testdata/pkt-diff-frame-addr.pcap testdata/pkt-local-admin.pcap testdata/pkt-ieee-regcheck.pcap testdata/pkt-too-short.pcap
24 | #
25 | # Substitute autoconf pkgdatadir variable in arp-scan.1 manpage
26 | CLEANFILES = arp-scan.1 get-oui.1
27 | do_subst = $(SED) -e 's,[@]PKGDATADIR[@],$(pkgdatadir),g;s,[@]PKGSYSCONFDIR[@],$(pkgsysconfdir),g'
28 | arp-scan.1: arp-scan.1.dist Makefile
29 | $(do_subst) < $(srcdir)/arp-scan.1.dist > arp-scan.1
30 | get-oui.1: get-oui.1.dist Makefile
31 | $(do_subst) < $(srcdir)/get-oui.1.dist > get-oui.1
32 | # Install arp-scan with cap_net_raw if possible, otherwise SUID root
33 | install-exec-hook:
34 | @if command -v setcap > /dev/null; then \
35 | if setcap cap_net_raw+p $(DESTDIR)$(bindir)/arp-scan$(EXEEXT); then \
36 | echo "setcap cap_net_raw+p $(DESTDIR)$(bindir)/arp-scan$(EXEEXT)"; \
37 | chmod u-s $(DESTDIR)$(bindir)/arp-scan$(EXEEXT); \
38 | else \
39 | echo "Setcap failed on $(DESTDIR)$(bindir)/arp-scan$(EXEEXT), falling back to setuid" >&2; \
40 | echo "chmod u+s $(DESTDIR)$(bindir)/arp-scan$(EXEEXT)"; \
41 | chmod u+s $(DESTDIR)$(bindir)/arp-scan$(EXEEXT); \
42 | fi \
43 | else \
44 | echo "Setcap is not installed, falling back to setuid" >&2 ; \
45 | echo "chmod u+s $(DESTDIR)$(bindir)/arp-scan$(EXEEXT)" ;\
46 | chmod u+s $(DESTDIR)$(bindir)/arp-scan$(EXEEXT) ;\
47 | fi
48 |
--------------------------------------------------------------------------------
/NEWS:
--------------------------------------------------------------------------------
1 | NEWS.md
--------------------------------------------------------------------------------
/NEWS.md:
--------------------------------------------------------------------------------
1 | **This file gives a brief overview of the major changes between each *arp-scan* release. For more details please read the `ChangeLog` file.**
2 |
3 | # 2023-02-26 arp-scan 1.10.1-git (in development)
4 |
5 | * New Features:
6 |
7 | - New `-m` option for `arp-fingerprint` to display the host MAC addresses.
8 | - OpenBSD: Call `pledge(2)` to enter restricted service mode once initial setup is complete. `arp-scan --version` output includes `Built with
9 | OpenBSD pledge(2) support` if applicable.
10 | - New `${IPnum}` field name for the `--format` option which displays the host IP address as a 32-bit unsigned integer. This allows sorting by IP address by numeric sort on the `${IPnum}` column.
11 | - New _--exclude-broadcast_ option to select whether generated IP ranges include the network and broadcast address.
12 |
13 | * Fixed Bugs:
14 |
15 | - Fall back to system mapping files if user lacks execute permission in the current directory, which can happen if a capabilities-aware *arp-scan* is run as root.
16 | - Add `pcap_freecode()` to free BPF program memory when no longer needed.
17 | - Do not enable promiscuous mode on the network interface as it is not needed.
18 |
19 | * General Improvements and Changes:
20 |
21 | - `get-oui` displays the underlying system error if the download fails instead of a generic "download failed" message.
22 | - CARP and IPv6 VRRP addresses added to mac-vendor.txt.
23 | - Append `-git` to version number for pre release git development versions.
24 | - wiki moved from mediawiki to [github wiki](https://github.com/royhills/arp-scan/wiki).
25 | - Self-test code coverage increased to 91.2% (see [code-coverage.yml](/.github/workflows/code-coverage.yml) for details of the code coverage tests).
26 | - `CONTRIBUTING.md` and `SECURITY.md` files added.
27 | - Change message about interface network and mask used for --localnet, and don't require --verbose to display it.
28 | - Source tree tidy-up: move test data files into separate _testdata_ directory; moved local autoconf macros to seperate files under _m4_ (requires autoconf >= 2.70 to build - v1.10.0 required autoconf >= 2.69).
29 | - Require a compiler with C99 support.
30 | - Change the HTTP user agent string used by the _get_oui_ script to mimic Chrome on Windows 10/x64 because the IEEE site rejects requests with the default libwww-perl user agent.
31 | - Removed "Ununsed variable" reported by Clang 16.0.
32 | - Various minor improvements to the code and documentation.
33 |
34 | # 2022-12-10 arp-scan 1.10.0 (git tag 1.10.0)
35 |
36 | ## New Features
37 |
38 | * **POSIX.1e capabilities support for Linux systems with libcap.**
39 |
40 | - Uses `CAP_NET_RAW` capability instead of superuser (root) permissions.
41 | - May need `libcap-dev` or similar package to build. *Note that `libcap`
42 | (capabilities) and `libpcap` (packet capture) are different libraries.*
43 | - configure option `--with-libcap`, defaults to auto.
44 | - Can set capability on exe with: `setcap cap_net_raw+p /path/to/arp-scan`
45 | - Initially clears effective set completely and clears everything except
46 | CAP_NET_RAW from the permitted set. Only enables CAP_NET_RAW in effective
47 | set for the functions that open raw sockets. Once sockets opened, removes
48 | CAP_NET_RAW from both effective and permitted set so process can never
49 | re enable it.
50 | - If arp-scan is SUID root, will drop all capabilities except CAP_NET_RAW
51 | as above and will also drop SUID with `setuid(getuid())`. So SUID root is
52 | essentially as secure as `setcap cap_net_raw+p /path/to/arp-scan` and is a
53 | safe alternative if the filesystem does not support extended attributes.
54 | - If arp-scan is run as root, e.g. `sudo`, it will drop all capabilities
55 | except CAP_NET_RAW and proceed as previously, but will remain as UID 0
56 | and may encounter file permissions issues if it tries to open files with
57 | e.g. `--pcapsavefile` or `--ouifile` in user directories.
58 | - `--version` displays `Built with libcap POSIX.1e capability support` if
59 | enabled.
60 | - `make install` installs the arp-scan executable with the `CAP_NET_RAW`
61 | capability if `setcap` is available and works. Otherwise will fallback to
62 | SUID. See `install-exec-hook` in `Makefile.am` for details.
63 |
64 | * **--format option allows flexible output format.**
65 |
66 | - Fields and text with \ character escapes, e.g. `${ip}\t${mac}\t${vendor}`
67 | - Optional left/right aligned width, e.g. `|${ip;-15}|${mac}|`
68 | - XML: `${ip}${mac}${vendor}`
69 | - JSON: `{"ipAddress":"${ip}", "macAddress":"${mac}", "vendor":"${vendor}"},`
70 | - See the arp-scan manpage for details of field names and more examples.
71 |
72 | * **Mac/Vendor mapping file changes.**
73 |
74 | - `ieee-oui.txt` now holds data for all IEEE registries: MA-L (OUI), MA-M,
75 | MA-S (OUI36) and IAB.
76 | - `ieee-iab.txt` file and `--iabfile` option have been removed.
77 | - `get-oui` now updates `ieee-oui.txt` from all registries. `get-iab` has been
78 | removed.
79 | - `get-oui` requires Perl module `Text::CSV` as it now uses the IEEE .csv
80 | files instead of the .txt files.
81 | - `get-oui` can be edited to use the data from the Debian `ieee-data` package.
82 | - `mac-vendor.txt` is now installed to `$(sysconfdir)/$(PACKAGE)` instead of
83 | `$(pkgdatadir)`. E.g. `/usr/local/etc/arp-scan` if ./configured with no
84 | directory options, or `/etc/arp-scan` with `--sysconfdir=/etc`. This is to
85 | permit local changes to persist across upgrades.
86 |
87 | ## General improvements
88 |
89 | * Put man pages and `--help` output on a diet. Updated for new options.
90 | * Option value length is now limited only by the maximum command line
91 | length (normally around 100K). This allows for complex `--format` options,
92 | long `--padding` lengths etc.
93 | * arp-scan now prints a brief error message instead of half a page of usage
94 | text for unknown options.
95 |
96 | # 2022-10-08 arp-scan 1.9.8 (git tag 1.9.8)
97 |
98 | * New Features:
99 |
100 | - Allow the use of Linux IP aliases such as `eth0:0` for the interface name.
101 | - Permit regular MAC addresses e.g. `00:0c:29:b9:43:1b` in `mac-vendor.txt`.
102 | - `--limit=n` option exits after n of hosts have responded, exit 1 for header file early in link-bpf.c to avoid BPF symbol
216 | problems on some BSD based operating systems.
217 |
218 | * Added arp-fingerprint patterns for GNU/Hurd, Amazon Kindle (Linux 2.6),
219 | BeOS, Windows 8, Recent Linux, FreeBSD, NetBSD and OpenBSD versions, and
220 | RiscOS.
221 |
222 | * Added data file "pkt-custom-request-vlan-llc.dat" to the tarball to allow
223 | the ARP request packet generation self test to complete successfully.
224 |
225 | * Various minor bug fixes and improvements.
226 |
227 | # 2011-03-01 arp-scan 1.8:
228 |
229 | * Updated IEEE OUI and IAB MAC/Vendor files. There are now 14707 OUI entries
230 | and 3542 IAB entries.
231 |
232 | * Added support for trailer ARP replies, which were used in early versions
233 | of BSD Unix on VAX.
234 |
235 | * Added support for ARP packets with both 802.1Q VLAN tag and LLC/SNAP framing.
236 |
237 | * The full help output is only displayed if specifically requested with
238 | arp-scan --help. Usage errors now result in smaller help output.
239 |
240 | * Added support for Apple Mac OS X with Xcode 2.5 and later. This allows
241 | arp-scan to build on Tiger, Leopard and Snow Leopard.
242 |
243 | * Changed license from GPLv2 to GPLv3.
244 |
245 | * Added warning about possible DoS when setting ar$spa to the destination IP
246 | address to the help output and man page.
247 |
248 | * Added arp-fingerprint patterns for 2.11BSD, NetBSD 4.0, FreeBSD 7.0,
249 | Vista SP1, Windows 7 and Blackberry OS.
250 |
251 | * Enabled compiler security options -fstack-protect, -D_FORTIFY_SOURCE=2 and
252 | -Wformat-security if they are supported by the compiler. Also enabled extra
253 | warnings -Wwrite-strings and -Wextra.
254 |
255 | * Added new "make check" tests to check packet generation, and packet decoding
256 | and display.
257 |
258 | * Modified get-oui and get-iab perl scripts so they will work on systems where
259 | the perl interpreter is not in /usr/bin, e.g. NetBSD.
260 |
261 | * Various minor bug fixes and improvements.
262 |
263 | # 2008-07-24 arp-scan 1.7:
264 |
265 | * new --pcapsavefile (-W) option to save the ARP response packets to a pcap
266 | savefile for later analysis with tcpdump, wireshark or another program that
267 | supports the pcap file format.
268 |
269 | * new --vlan (-Q) option to create outgoing ARP packets with an 802.1Q VLAN tag
270 | ARP responses with a VLAN tag are interpreted and displayed.
271 |
272 | * New --llc (-L) option to create outgoing ARP packets with RFC 1042 LLC/SNAP
273 | framing. Received ARP packets are decoded and displayed with either
274 | LLC/SNAP or the default Ethernet-II framing irrespective of this option.
275 |
276 | * Avoid double unmarshalling of packet data: once in callback, then again in
277 | display_packet().
278 |
279 | * New arp-fingerprint patterns for ARP fingerprinting: Cisco 79xx IP Phone
280 | SIP 5.x, 6.x and 7.x; Cisco 79xx IP Phone SIP 8.x.
281 |
282 | * Updated IEEE OUI and IAB MAC/Vendor files. There are now 11,697 OUI entries
283 | and 2,386 IAB entries.
284 |
285 | # 2007-04-12 arp-scan 1.6:
286 |
287 | * arp-scan wiki at http://www.nta-monitor.com/wiki/
288 | This contains detailed documentation on arp-scan, and is intended to be
289 | the primary documentation resource.
290 |
291 | * Added support for Sun Solaris. Tested on Solaris 9 (SPARC). arp-scan may
292 | also work on other systems that use DLPI, but only Solaris has been tested.
293 |
294 | * New arp-fingerprint patterns for ARP fingerprinting: IOS 11.2, 11.3 and 12.4;
295 | ScreenOS 5.1, 5.2, 5.3 and 5.4; Cisco VPN Concentrator 4.7; AIX 4.3 and 5.3;
296 | Nortel Contivity 6.00 and 6.05; Cisco PIX 5.1, 5.2, 5.3, 6.0, 6.1, 6.2, 6.3
297 | and 7.0.
298 |
299 | * Updated IEEE OUI and IAB MAC/Vendor files. There are now 10,214 OUI entries
300 | and 1,858 IAB entries.
301 |
302 | * Added HSRP MAC address to mac-vendor.txt.
303 |
304 | # 2006-07-22 arp-scan 1.5:
305 |
306 | * Reduced memory usage from 44 bytes per target to 28 bytes. This reduces
307 | the memory usage for a Class-B network from 2.75MB to 1.75MB, and a Class-A
308 | network from 704MB to 448MB.
309 |
310 | * Reduced the startup time for large target ranges. This reduces the startup
311 | time for a Class-A network from 80 seconds to 15 seconds on a Compaq laptop
312 | with 1.4GHz CPU.
313 |
314 | * Added support for FreeBSD, OpenBSD, NetBSD and MacOS X (Darwin). arp-scan
315 | will probably also work on other operating systems that implement BPF, but
316 | only those listed have been tested.
317 |
318 | * Improved operation of the --srcaddr option. Now this will change the
319 | source hardware address in the Ethernet header without changing the
320 | interface address.
321 |
322 | * Additional fingerprints for arp-fingerprint.
323 |
324 | * Improved manual pages.
325 |
326 | * Updated IEEE OUI and IAB files. There are now 9,426 OUI entries and 1,568
327 | IAB entries.
328 |
329 | # 2006-06-26 arp-scan 1.4:
330 |
331 | * Added IEEE IAB listings and associated get-iab update script and --iabfile
332 | option.
333 | * Added manual MAC/Vendor mapping file: mac-vendor.txt and associated
334 | --macfile option.
335 | * New --localnet option to scan all IP addresses on the specified interface
336 | network and mask.
337 |
338 | # 2006-06-23 arp-scan 1.3:
339 |
340 | * Initial public release. Source distribution only, which will compile and
341 | run on Linux.
342 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | README.md
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # arp-scan
2 |
3 | [](https://github.com/royhills/arp-scan/actions/workflows/c-cpp.yml)
4 | [](https://coveralls.io/github/royhills/arp-scan?branch=master)
5 | [](https://github.com/royhills/arp-scan/actions/workflows/codeql.yml)
6 |
7 | ---
8 |
9 | # About
10 |
11 | *arp-scan* is a network scanning tool that uses the ARP protocol to discover and fingerprint IPv4 hosts on the local network. It is available for Linux, BSD, macOS and Solaris under the [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html) licence.
12 |
13 | This is `README.md` for *arp-scan* version `1.10.1-git`.
14 |
15 | # Installation
16 |
17 | ## Building and Installing from Source
18 |
19 | *arp-scan* uses the GNU *automake* and *autoconf* tools. The installation process from the latest *github* source is:
20 |
21 | - `git clone https://github.com/royhills/arp-scan.git` to obtain the latest source code.
22 | - `cd arp-scan` to enter the source code directory.
23 | - `autoreconf --install` to generate a configure file (if you don't have `autoreconf` you can download a tarball instead as detailed below).
24 | - `./configure` to create a makefile for your system (see configuration options below).
25 | - `make` to build the project.
26 | - Optionally `make check` to verify that everything works as expected.
27 | - `make install` to install (you'll need to be root or use sudo/doas for this part).
28 |
29 | You will need these development tools and libraries:
30 |
31 | - GNU *automake* and *autoconf* (if you don't have these, you can download the latest tarball which includes `configure` instead: [arp-scan-1.10.0.tar.gz](https://github.com/royhills/arp-scan/releases/download/1.10.0/arp-scan-1.10.0.tar.gz)). Note that this might not be as up to date as the latest *github* development version.
32 | - The *make* utility (tested with BSD make and GNU make).
33 | - A C compiler (tested on *gcc* and *clang*, should work on any C compiler that supports C99).
34 | - Libraries and include files for *libpcap* version 1.5 or later. All modern distros have a binary package, some split the package into `libpcap` runtime and `libpcap-dev` or `libpcap-devel` development packages, in which case you need to install the development version to build.
35 | - *libcap* to build with [POSIX.1e capabilities](https://sites.google.com/site/fullycapable/) support on Linux. Most Linux distros come with runtime support by default and have a development package available. Linux has capabilities support since kernel version `2.6.24`.
36 |
37 | To run the Perl scripts `arp-fingerprint` and `get-oui`, you will also need the *perl* interpreter and the perl modules `LWP::UserAgent` and `Text::CSV`.
38 |
39 | You can pass options to `configure` to control the build process. Run `./configure --help` for a list of options. *arp-scan* has one package-specific configure option:
40 |
41 | - `--with-libcap[=auto/yes/no]` Build with libcap POSIX.1e capabilities support [default=`auto`]
42 |
43 | With `auto`, configure will enable capability support if the `libcap` library and headers are installed. Specifying `--with-libcap` will enable support and `--without-libpcap` will disable it.
44 |
45 | *arp-scan* is known to build and run on:
46 |
47 | - **Linux** (should work on any distribution and all architectures).
48 | - **FreeBSD**
49 | - **OpenBSD**
50 | - **NetBSD**
51 | - **DragonflyBSD**
52 | - **macOS**
53 | - **Solaris 10** (there are known problems with Solaris 11. If anyone cares please comment on [issue #31](https://github.com/royhills/arp-scan/issues/31)).
54 |
55 | It should be possible to build *arp-scan* on any OS that *libpcap* supports. If your OS supports *libpcap* but configure gives the error `configure: error: Host operating system your-os-name is not supported` please open an [issue](https://github.com/royhills/arp-scan/issues) to request porting to your OS.
56 |
57 | ## Installing from a Binary Package
58 |
59 | Many distributions provide binary packages for *arp-scan* These won't be as up to date as the latest source on github and may not be as up to date as the latest release, but they are more convenient and will be kept up to date by the package manager. So using a binary package is often a good choice if you don't need the latest features.
60 |
61 | If you have installed a binary package and wonder if there are useful new features on github, use `arp-scan --version` to check the version you have then see the [NEWS](NEWS.md) and [ChangeLog](ChangeLog) files on github for details of what's changed.
62 |
63 | The details on how to install an *arp-scan* binary package depend on your distribution.
64 |
65 | ## Installing from a BSD Port
66 |
67 | If you are using a BSD operating system you may have the option of installing from a source ports collection as well as from a binary package.
68 |
69 | Ports automate the building and installation of source code and manage updates like a binary package. They also give the flexibility of installing from source. A source port won't be as up to date as the latest github though, but it might sometimes be more up to date than the corresponding binary package.
70 |
71 | The details on how to install an *arp-scan* source port depend on your distribution.
72 |
73 | # Documentation
74 |
75 | For usage information use:
76 |
77 | `arp-scan --help`
78 |
79 | For detailed information, see the manual pages: `arp-scan(1)`, `arp-fingerprint(1)`, `get-oui(1)` and `mac-vendor(5)`.
80 |
81 | See the *arp-scan* wiki at [https://github.com/royhills/arp-scan/wiki](https://github.com/royhills/arp-scan/wiki)
82 |
83 | See [`CONTRIBUTING.md`](CONTRIBUTING.md) if you are interested in contributing to *arp-scan*. If you think you have found a security vulnerability, please see [`SECURITY.md`](SECURITY.md).
84 |
85 | # Notes for Package Maintainers
86 |
87 | - Please raise a github issue or create a pull request if you have any local patches that could be applicable upstream.
88 | - If you are building on Linux, please build with `libcap` POSIX.1e capabilities support if you can. You may need to install the `libcap` development headers as well as the `libpcap` development headers before running `configure`.
89 | - Note that `Makefile.am` contains an `install-exec-hook` that will install *arp-scan* with `CAP_NET_RAW` capabilities if it can, and failing that it will install it suid root.
90 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Security
4 |
5 | The *arp-scan* team take application security seriously. As part of that we encourage quick reporting of any potential security vulnerabilities.
6 |
7 | ## Reporting a Vulnerability
8 |
9 | If you believe you have found a security vulnerability in *arp-scan*, please open an [issue](https://github.com/royhills/arp-scan/issues). Please add the *Security* label to the issue if you can. Please also include as much information as you can to help identify and, if possible, demonstrate the issue.
10 |
11 | Please see [`CONTRIBUTING.md`](CONTRIBUTING.md) for additional information about contributions.
12 |
--------------------------------------------------------------------------------
/TODO:
--------------------------------------------------------------------------------
1 | This file is no longer used by arp-scan.
2 | All valid items were moved from this file to github issues with the
3 | "From TODO file"
4 |
--------------------------------------------------------------------------------
/arp-fingerprint:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env perl
2 | #
3 | # Copyright 2006-2025 Roy Hills
4 | #
5 | # This file is part of arp-scan.
6 | #
7 | # arp-scan is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 3 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # arp-scan is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # You should have received a copy of the GNU General Public License
18 | # along with arp-scan. If not, see .
19 | #
20 | # arp-fingerprint -- Perl script to fingerprint system with arp-scan
21 | #
22 | # Author: Roy Hills
23 | # Date: 30th May 2006
24 | #
25 | # This script uses arp-scan to fingerprint the operating system on the
26 | # specified target.
27 | #
28 | # It sends various different ARP packets to the target, and records which
29 | # ones it responds to. From this, it constructs a fingerprint string
30 | # which is used to match against a hash containing known fingerprints.
31 | #
32 | use warnings;
33 | use strict;
34 | use Getopt::Std;
35 | #
36 | sub get_localnet($);
37 | #
38 | my $arpscan="arp-scan -q -r 1 -x";
39 | #
40 | # Hash of known fingerprints
41 | #
42 | # These fingerprints were observed on:
43 | #
44 | # FreeBSD 14.0 FreeBSD 14.0-RELEASE-p3 amd64 on VMware
45 | # FreeBSD 13.1 FreeBSD 13.1-RELEASE-p9 amd64 on VMware
46 | # FreeBSD 12.0 FreeBSD 12.0-RELEASE amd64 on VMware
47 | # FreeBSD 11.2 FreeBSD 11.2-RELEASE amd64 on VMware
48 | # FreeBSD 10.3 FreeBSD 10.3 amd64 on VMware
49 | # FreeBSD 9.1 FreeBSD 9.1 i386 on VMware
50 | # FreeBSD 8.2 FreeBSD 8.2 i386 on VMware
51 | # FreeBSD 7.0 FreeBSD 7.0 i386 on VMware
52 | # FreeBSD 5.3 FreeBSD 5.3 i386 on VMware
53 | # FreeBSD 4.3 FreeBSD 4.3 i386 on VMware
54 | # DragonflyBSD 2.0 Dragonfly BSD 2.0.0 i386 on VMware
55 | # DragonflyBSD 3.0 Dragonfly BSD 3.0.2 i386 on VMware
56 | # DragonflyBSD 3.2 Dragonfly BSD 3.2.2 amd64 on VMware
57 | # DragonflyBSD 4.6 Dragonfly BSD 4.6.0 amd64 on VMware
58 | # Win 3.11 Windows for Workgroups 3.11/DOS 6.22 on VMware
59 | # 95 Windows 95 OSR2 on VMware
60 | # Win98 Windows 98 SE on VMware
61 | # WinME Windows ME on VMware
62 | # Windows7 Windows 7 Professional 6.1.7600 Build 7600 on Dell Vostro 220
63 | # Windows8 Windows 8 Pro x64 6.2.9200 Build 9200 on VMware
64 | # Windows10 Windows 10 Pro 10.0.14393 Build 14393 on VMware
65 | # Windows11 Windows 11 Pro 10.0.22621 on VMware
66 | # NT 3.51 Windows NT Server 3.51 SP0 on VMware
67 | # NT4 Windows NT Workstation 4.0 SP6a on Pentium
68 | # 2000 Windows 2000
69 | # XP Windows XP Professional SP2 on Intel P4
70 | # 2003 Windows 2003 Server SP1 on Intel P4
71 | # Vista Windows Vista Beta 2 Build 5384 on VMware
72 | # Vista Windows Vista SP1 Build 6001 on Dell Inspiron
73 | # 2008 Windows 2008 Server Beta on i386
74 | # 2012R2 Windows Server 2012R2 x64 on HP proliant server
75 | # 2022 Windows Server 2022 x64 on VMware
76 | # Linux 2.0 Linux 2.0.29 on VMware (debian 1.3.1)
77 | # Linux 2.2 Linux 2.2.19 on VMware (debian potato)
78 | # Linux 2.4 Linux 2.4.29 on Intel P3 (debian sarge)
79 | # Linux 2.6 Linux 2.6.15.7 i686 on Intel P3 (debian sarge)
80 | # Linux 2.6 Kindle 3.1 on Amazon Kindle 3
81 | # Linux 2.6 Linux 2.6.32.60 x86_64 on VMware (debian squeeze)
82 | # Linux 3.2 Linux 3.2.0 686 on VMware (debian wheezy)
83 | # Linux 3.8 Linux 3.8.8 x86_64 on VMware (fedora 17)
84 | # Linux 4.0 Linux 4.0.6 x86_64 on VMware (fedora 22)
85 | # Linux 4.6 Linux 4.6.7 x86_64 on VMware (fedora 24)
86 | # Cisco IOS IOS 11.2(17) on Cisco 2503
87 | # Cisco IOS IOS 11.3(11b)T2 on Cisco 2503
88 | # Cisco IOS IOS 12.0(8) on Cisco 1601
89 | # Cisco IOS IOS 12.1(27b) on Cisco 2621
90 | # Cisco IOS IOS 12.2(32) on Cisco 1603
91 | # Cisco IOS IOS 12.3(15) on Cisco 2503
92 | # Cisco IOS IOS 12.4(3) on Cisco 2811
93 | # Cisco IOS IOS 12.4(24)T1 on Cisco 1841
94 | # Cisco IOS IOS 15.0(1)M on Cisco 7206 (dynamips)
95 | # Solaris 2.5.1 Solaris 2.5.1 (SPARC) on Sun SPARCstation 20
96 | # Solaris 2.6 Solaris 2.6 (SPARC) on Sun Ultra 5
97 | # Solaris 7 Solaris 7 (x86) on VMware
98 | # Solaris 8 Solaris 8 (SPARC) on Sun Ultra 5 (64 bit)
99 | # Solaris 9 Solaris 9 (SPARC) on Sun Ultra 5 (64 bit)
100 | # Solaris 10 Solaris 10 (x86) on VMware
101 | # ScreenOS 5.0 Juniper ScreenOS 5.0.0r9 on NetScreen 5XP
102 | # ScreenOS 5.1 Juniper ScreenOS 5.1.0r1.0 on NetScreen 5GT
103 | # ScreenOS 5.3 Juniper ScreenOS 5.3.0r4.0 on NetScreen 5GT
104 | # ScreenOS 5.4 Juniper ScreenOS 5.4.0r1.0 on NetScreen 5GT
105 | # ScreenOS 5.4 Juniper ScreenOS 5.4.0r22.0 on NetScreen 5GT
106 | # ScreenOS 6.2 Juniper ScreenOS 6.2.0r12.0 on Juniper SSG5
107 | # MacOS 10.4 MacOS 10.4.6 on powerbook G4
108 | # MacOS 10.3 MacOS 10.3.9 on imac G3
109 | # IRIX 6.5 IRIX64 IRIS 6.5 05190004 IP30 on SGI Octane
110 | # SCO OS 5.0.7 SCO OpenServer 5.0.7 on VMware
111 | # 2.11BSD 2.11BSD patch level 431 on PDP-11/73 (SIMH simulated)
112 | # 4.3BSD 4.3BSD (Quasijarus0c) on MicroVAX 3000 (SIMH simulated)
113 | # OpenBSD 3.1 OpenBSD 3.1 i386 on VMware
114 | # OpenBSD 3.9 OpenBSD 3.9 i386 on VMware
115 | # OpenBSD 4.8 OpenBSD 4.8 i386 on VMware
116 | # OpenBSD 5.1 OpenBSD 5.1 amd64 on VMware
117 | # OpenBSD 5.9 OpenBSD 5.9 amd64 on VMware
118 | # NetBSD 2.0.2 NetBSD 2.0.2 i386 on VMware
119 | # NetBSD 4.0 NetBSD 4.0 i386 on VMware
120 | # NetBSD 5.1 NetBSD 5.1.2 i386 on VMware
121 | # NetBSD 6.0 NetBSD 6.0.1 amd64 on VMware
122 | # NetBSD 7.0 NetBSD 7.0.1 amd64 on VMware
123 | # IPSO 3.2.1 IPSO 3.2.1-fcs1 on Nokia VPN 210
124 | # Netware 6.5 Novell NetWare 6.5 on VMware
125 | # HP-UX 11 HP-UX B.11.00 A 9000/712 (PA-RISC)
126 | # PIX OS PIX OS (unknown vsn) on Cisco PIX 525
127 | # PIX OS 4.4 PIX OS 4.4(4) on Cisco PIX 520
128 | # PIX OS 5.1 PIX OS 5.1(2) on Cisco PIX 520
129 | # PIX OS 5.2 PIX OS 5.2(9) on Cisco PIX 520
130 | # PIX OS 5.3 PIX OS 5.3(2) on Cisco PIX 520
131 | # PIX OS 6.0 PIX OS 6.0(4) on Cisco PIX 520
132 | # PIX OS 6.1 PIX OS 6.1(5) on Cisco PIX 520
133 | # PIX OS 6.2 PIX OS 6.2(4) on Cisco PIX 520
134 | # PIX OS 6.3 PIX OS 6.3(5) on Cisco PIX 520
135 | # PIX OS 7.0(1) PIX OS 7.0(1) on Cisco PIX 515E
136 | # PIX OS 7.0(2) PIX OS 7.0(2) on Cisco PIX 515E
137 | # PIX OS 7.0(4) PIX OS 7.0(4) on Cisco PIX 515E
138 | # PIX OS 7.0(6) PIX OS 7.0(6) on Cisco PIX 515E
139 | # PIX OS 7.1 PIX OS 7.1(1) on Cisco PIX 515E
140 | # PIX OS 7.2 PIX OS 7.2(1) on Cisco PIX 515E
141 | # PIX OS 8.0 PIX OS 8.0(2) on Cisco PIX 515E
142 | # Minix 3 Minix 3 1.2a on VMware
143 | # Nortel Contivity 6.00 Nortel Contivity V06_00 (VxWorks based)
144 | # Nortel Contivity 6.05 Nortel Contivity V06_05.135
145 | # AIX 4.3 IBM AIX Version 4.3 on RS/6000 7043-260
146 | # AIX 5.3 IBM AIX Version 5.3 on RS/6000 7043-260
147 | # Cisco VPN Concentrator 4.7 Cisco VPN Concentrator 3030 4.7.2E
148 | # Cisco IP Phone 79xx SIP 5.x,6.x,7.x 7940 SIP firmware version 5.3
149 | # Cisco IP Phone 79xx SIP 5.x,6.x,7.x 7940 SIP firmware version 6.3
150 | # Cisco IP Phone 79xx SIP 5.x,6.x,7.x 7940 SIP firmware version 7.5
151 | # Cisco IP Phone 79xx SIP 8.x 7940 SIP firmware version 8.6
152 | # Catalyst 1900 Cisco Catalyst 1900 V9.00.03 Standard Edition
153 | # Catalyst IOS 12.2 Cisco Catalyst 3550-48 running IOS 12.2(35)SE
154 | # Catalyst IOS 12.0 Cisco Catalyst 2924-XL running IOS 12.0(5)WC17
155 | # Catalyst IOS 12.1 Cisco Catalyst 3550-48 running IOS 12.1(11)EA1a SMI
156 | # FortiOS 3.00 FortiGate 100A running FortiOS 3.00,build0406,070126
157 | # Plan9 Plan9 release 4 on VMware
158 | # Blackberry OS Blackberry OS v5.0.0.681 on Blackberry 8900
159 | # GNU/Hurd Debian GNU/Hurd (GNU-Mach 1.3.99/Hurd-0.3) on VMware
160 | # BeOS BeOS 5.0.3 PE Max on VMware
161 | # RiscOS 5.19 RiscOS 5.19 on Raspberry Pi
162 | # WIZnet W5100 WIZnet W5100 on Ethernet chip on Arduino Ethernet shield
163 | # Android 4.1 Android 4.1.2 on Samsung Galaxy S3 Mini (wifi)
164 | # Android 4.4 Android 4.4.2 on Google Nexus 7 (wifi)
165 | #
166 | my %fp_hash = (
167 | '11110100000' => 'FreeBSD 5.3, 7.0, 8.2, 9.1, 10.3, 11.2, DragonflyBSD 2.0, 3.0, 3.2, 4.6, Win98, WinME, NT4, 2000, XP, 2003, Catalyst IOS 12.0, 12.1, 12.2, FortiOS 3.00',
168 | '01000100000' => 'Linux 2.2, 2.4, 2.6',
169 | '01010100000' => 'Linux 2.2, 2.4, 2.6, 3.2, 3.8, 4.0, 4.6, Vista, 2008, 2012R2, 2022, Windows7, Windows8, Windows10, Windows11', # Linux only if non-local IP is routed
170 | '00000100000' => 'Cisco IOS 11.2, 11.3, 12.0, 12.1, 12.2, 12.3, 12.4, 15.0',
171 | '11110110000' => 'Solaris 2.5.1, 2.6, 7, 8, 9, 10, HP-UX 11, NetBSD 6.0, 7.0',
172 | '01000111111' => 'ScreenOS 5.0, 5.1, 5.3, 5.4, 6.2',
173 | '11110000000' => 'Linux 2.0, MacOS 10.4, IPSO 3.2.1, Minix 3, Cisco VPN Concentrator 4.7, Catalyst 1900, BeOS, WIZnet W5100, FreeBSD 12.0, FreeBSD 13.1, FreeBSD 14.0',
174 | '11110100011' => 'MacOS 10.3, FreeBSD 4.3, IRIX 6.5, AIX 4.3, AIX 5.3',
175 | '10010100011' => 'SCO OS 5.0.7',
176 | '10110100000' => 'Win 3.11, 95, NT 3.51',
177 | '11110000011' => '2.11BSD, 4.3BSD, OpenBSD 3.1, 3.9, 4.8, 5.1, 5.9, Nortel Contivity 6.00, 6.05, RiscOS 5.19',
178 | '10110110000' => 'NetBSD 2.0.2, 4.0, 5.1',
179 | '10110111111' => 'PIX OS 4.4, 5.1, 5.2, 5.3, Android 4.1',
180 | '11110111111' => 'PIX OS 6.0, 6.1, 6.2, ScreenOS 5.0 (transparent), Plan9, Blackberry OS',
181 | '00010110011' => 'PIX OS 6.3, 7.0(1), 7.0(2)',
182 | '01010110011' => 'PIX OS 7.0(4)-7.0(6), 7.1, 7.2, 8.0',
183 | '00000110000' => 'Netware 6.5',
184 | '00010100000' => 'Unknown 1', # 14805 79.253 Cisco
185 | '00000110011' => 'Cisco IP Phone 79xx SIP 5.x,6.x,7.x',
186 | '11110110011' => 'Cisco IP Phone 79xx SIP 8.x', # Also 14805 63.11 Fujitsu Siemens
187 | '01010000000' => 'GNU/Hurd, Android 4.4',
188 | );
189 | #
190 | my $usage =
191 | qq/Usage: arp-fingerprint [options]
192 | Fingerprint the target system using arp-scan.
193 |
194 | 'options' is one or more of:
195 | -h Display this usage message.
196 | -v Give verbose progress messages.
197 | -o Pass specified options to arp-scan
198 | -l Fingerprint all targets in the local net.
199 | -m Include the MAC address of the target in the output
200 | /;
201 | my %opts;
202 | my $user_opts="";
203 | my $verbose;
204 | my $fingerprint="";
205 | my $fp_name;
206 | my @targets;
207 | my $target;
208 | my $show_mac;
209 | my $mac_address;
210 | #
211 | # Process options
212 | #
213 | die "$usage\n" unless getopts('hlvmo:',\%opts);
214 | if ($opts{h}) {
215 | print "$usage\n";
216 | exit(0);
217 | }
218 | $verbose=$opts{v} ? 1 : 0;
219 | if ($opts{o}) {
220 | $user_opts = $opts{o};
221 | }
222 | $show_mac=$opts{m} ? 1 : 0;
223 |
224 | #If we're working in localnet mode, we don't need arguments
225 | if ($#ARGV != 0 && !$opts{l}) {
226 | die "$usage\n";
227 | }
228 |
229 | if ($opts{l}) {
230 | @targets=get_localnet($user_opts);
231 | } else {
232 | @targets=@ARGV;
233 | }
234 |
235 | for $target (@targets) {
236 | $fingerprint="";
237 | #
238 | # Check that the target is not an IP range or network.
239 | #
240 | if ($target =~ /\d+\.\d+\.\d+\.\d+-\d+\.\d+\.\d+\.\d+/ ||
241 | $target =~ /\d+\.\d+\.\d+\.\d+\/\d+/ ||
242 | $target =~ /\d+\.\d+\.\d+\.\d+:\d+\.\d+\.\d+\.\d+/) {
243 | die "argument must be a single IP address or hostname\n";
244 | }
245 | #
246 | # Check that the system responds to an arp-scan with no options.
247 | # If it does, then fingerprint the target.
248 | #
249 | $mac_address = &fp("","$target");
250 | if ($mac_address ne "0") {
251 | # 1: source protocol address = localhost
252 | $fingerprint .= &fp("--arpspa=127.0.0.1","$target");
253 | # 2: source protocol address = zero
254 | $fingerprint .= &fp("--arpspa=0.0.0.0","$target");
255 | # 3: source protocol address = broadcast
256 | $fingerprint .= &fp("--arpspa=255.255.255.255","$target");
257 | # 4: source protocol address = non local (network 1 is reserved)
258 | $fingerprint .= &fp("--arpspa=1.0.0.1","$target"); # Non-local source IP
259 | # 5: invalid arp opcode
260 | $fingerprint .= &fp("--arpop=255","$target");
261 | # 6: arp hardware type = IEEE_802.2
262 | $fingerprint .= &fp("--arphrd=6","$target");
263 | # 7: invalid arp hardware type
264 | $fingerprint .= &fp("--arphrd=255","$target");
265 | # 8: invalid arp protocol type
266 | $fingerprint .= &fp("--arppro=0xffff","$target");
267 | # 9: arp protocol type = Novell IPX
268 | $fingerprint .= &fp("--arppro=0x8137","$target");
269 | # 10: invalid protocol address length
270 | $fingerprint .= &fp("--arppln=6","$target");
271 | # 11: Invalid hardware address length
272 | $fingerprint .= &fp("--arphln=8","$target");
273 | #
274 | if (defined $fp_hash{$fingerprint}) {
275 | $fp_name = "$fp_hash{$fingerprint}";
276 | } else {
277 | $fp_name = "UNKNOWN";
278 | }
279 | if ($show_mac) {
280 | print "$target\t$mac_address\t$fingerprint\t$fp_name\n";
281 | } else {
282 | print "$target\t$fingerprint\t$fp_name\n";
283 | }
284 | } else {
285 | print "$target\tNo Response\n";
286 | }
287 | }
288 | #
289 | # Scan the specified IP address with arp-scan using the given options.
290 | # If the options are empty, return the MAC address of the target, otherwise
291 | # return "1" if the target responds, or "0" if it does not respond.
292 | #
293 | sub fp ($$) {
294 | my $ip;
295 | my $options;
296 | my $response = "0";
297 | ($options, $ip) = @_;
298 |
299 | open(ARPSCAN, "$arpscan $user_opts $options $ip |") || die "arp-scan failed";
300 | while () {
301 | if (/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\t([0-9a-f:]+)$/) {
302 | if ($options eq "") {
303 | $response = $1; # MAC address from arp-scan output
304 | } else {
305 | $response = "1";
306 | }
307 | last;
308 | }
309 | }
310 | close(ARPSCAN);
311 |
312 | if ($verbose && $options ne "") {
313 | if ($response) {
314 | print "$options\tYes\n";
315 | } else {
316 | print "$options\tNo\n";
317 | }
318 | }
319 |
320 | return $response;
321 | }
322 |
323 | #
324 | # use -l flag on arp-scan to collect all IPs in the local network
325 | #
326 | sub get_localnet($) {
327 | my $user_opts = $_[0];
328 | my @targets;
329 |
330 | open(ARPSCAN, "$arpscan $user_opts -l |") || die "arp-scan failed";
331 | while () {
332 | if (/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\t/) {
333 | push @targets, $1;
334 | }
335 | }
336 | close(ARPSCAN);
337 |
338 | die "parse of arp-scan failed" unless @targets;
339 | return @targets;
340 | }
341 |
--------------------------------------------------------------------------------
/arp-fingerprint.1:
--------------------------------------------------------------------------------
1 | .\" Copyright (C) Roy Hills
2 | .\"
3 | .\" Copying and distribution of this file, with or without modification,
4 | .\" are permitted in any medium without royalty provided the copyright
5 | .\" notice and this notice are preserved.
6 | .\"
7 | .TH ARP-FINGERPRINT 1 "January 07, 2023"
8 | .\" Please adjust this date whenever revising the man page.
9 | .SH NAME
10 | arp-fingerprint \- Fingerprint a system using ARP
11 | .SH SYNOPSIS
12 | .B arp-fingerprint
13 | .RI [ options ]
14 | .I target
15 | .PP
16 | The target should be specified as a single IP address or hostname. You cannot specify multiple targets, IP networks or ranges.
17 | .PP
18 | If you use an IP address for the target, you can use the
19 | .B -o
20 | option to pass the
21 | .B --numeric
22 | option to
23 | .BR arp-scan ,
24 | which will prevent it from attempting DNS lookups. This can speed up the
25 | fingerprinting process, especially on systems with a slow or faulty DNS
26 | configuration.
27 | .SH DESCRIPTION
28 | .B arp-fingerprint
29 | fingerprints the specified target host using the ARP protocol.
30 | .PP
31 | It sends various different types of ARP request to the target, and records
32 | which types it responds to. From this, it constructs a fingerprint string
33 | consisting of "1" where the target responded and "0" where it did not.
34 | An example of a fingerprint string is
35 | .IR 01000100000 .
36 | This fingerprint string is then used to lookup the likely target operating system.
37 | .PP
38 | Many of the fingerprint strings are shared by several operating systems, so
39 | there is not always a one-to-one mapping between fingerprint strings and
40 | operating systems. Also the fact that a system's fingerprint matches a certain
41 | operating system (or list of operating systems) does not necessarily mean that
42 | the system being fingerprinted is that operating system, although it is quite
43 | likely. This is because the list of operating systems is not exhaustive; it is
44 | just what I have discovered to date, and there are bound to be operating
45 | systems that are not listed.
46 | .PP
47 | The ARP fingerprint of a system is generally a function of that system's
48 | kernel (although it is possible for the ARP function to be implemented in
49 | user space, it almost never is).
50 | .PP
51 | Sometimes, an operating system can give different fingerprints depending
52 | on the configuration. An example is Linux, which will respond to a non-local
53 | source IP address if that IP is routed through the interface being tested.
54 | This is both good and bad: on one hand it makes the fingerprinting task more
55 | complex; but on the other, it can allow some aspects of the system configuration
56 | to be determined.
57 | .PP
58 | Sometimes the fact that two different operating systems share a common ARP
59 | fingerprint string points to a re-use of networking code. One example of
60 | this is Windows NT and FreeBSD.
61 | .PP
62 | .B arp-fingerprint
63 | uses
64 | .B arp-scan
65 | to send the ARP requests and receive the replies.
66 | .PP
67 | There are other methods that can be used to fingerprint a system using
68 | .B arp-scan
69 | which can be used in addition to
70 | .BR arp-fingerprint .
71 | These additional methods are not included in
72 | .B arp-fingerprint
73 | either because they are likely to cause disruption to the target system, or
74 | because they require knowledge of the target's configuration that may not
75 | always be available.
76 | .PP
77 | Most of the ARP requests that \fBarp-fingerprint\fP sends are non-standard,
78 | so it could disrupt systems that don't have a robust TCP/IP stack.
79 | .SH OPTIONS
80 | .TP
81 | .B -h
82 | Display a brief usage message and exit.
83 | .TP
84 | .B -v
85 | Display verbose progress messages.
86 | .TP
87 | .B -o
88 | Pass specified options to arp-scan. You need to enclose the options
89 | string in quotes if it contains spaces. e.g.
90 | -o "-I eth1". The commonly used options are --interface (-I) and --numeric
91 | (-N).
92 | .TP
93 | .B -l
94 | Fingerprint all hosts on the local network. You do not need to specify any
95 | target hosts if this option is given.
96 | .TP
97 | .B -m
98 | Include the MAC address of the target in the output.
99 | .SH EXAMPLES
100 | .nf
101 | $ arp-fingerprint 192.168.0.1
102 | 192.168.0.1 01000100000 Linux 2.2, 2.4, 2.6
103 | .fi
104 | .PP
105 | .nf
106 | $ arp-fingerprint -o "-N -I eth1" 192.168.0.202
107 | 192.168.0.202 11110100000 FreeBSD 5.3, Win98, WinME, NT4, 2000, XP, 2003
108 | .fi
109 | .SH NOTES
110 | .B arp-fingerprint
111 | is implemented in Perl, so you need to have the Perl interpreter installed on
112 | your system to use it.
113 | .SH "SEE ALSO"
114 | .TP
115 | .BR arp-scan (1)
116 | .PP
117 | .I https://github.com/royhills/arp-scan/wiki
118 | The arp-scan wiki page.
119 |
--------------------------------------------------------------------------------
/arp-scan.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ARP Scan is Copyright (C) 2005-2025 Roy Hills
3 | *
4 | * This file is part of arp-scan.
5 | *
6 | * arp-scan is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * arp-scan is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with arp-scan. If not, see .
18 | *
19 | * arp-scan.h -- Header file for ARP scanner
20 | *
21 | * Author: Roy Hills
22 | * Date: 11 October 2005
23 | *
24 | */
25 | /* Includes */
26 | #ifdef HAVE_CONFIG_H
27 | #include "config.h"
28 | #endif
29 |
30 | /* C89 standard headers */
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 |
40 | /* C99 standard headers */
41 | #include
42 |
43 | /* headers first defined in POSIX-1 issue 1 */
44 | #ifdef HAVE_UNISTD_H
45 | #include
46 | #endif
47 |
48 | #ifdef HAVE_FCNTL_H
49 | #include
50 | #endif
51 |
52 | #ifdef HAVE_SEARCH_H
53 | #include
54 | #endif
55 |
56 | #ifdef HAVE_SYS_STAT_H
57 | #include
58 | #endif
59 |
60 | /* headers first defined in POSIX.1 issue 4 */
61 | #ifdef HAVE_REGEX_H
62 | #include
63 | #endif
64 |
65 | #ifdef HAVE_SYS_TIME_H
66 | #include
67 | #endif
68 |
69 | /* headers first defined in POSIX.1 issue 6 */
70 | #ifdef HAVE_NETDB_H
71 | #include
72 | #endif
73 |
74 | #ifdef HAVE_NETINET_IN_H
75 | #include
76 | #endif
77 |
78 | #ifdef HAVE_SYS_SOCKET_H
79 | #include
80 | #endif
81 |
82 | #ifdef HAVE_ARPA_INET_H
83 | #include
84 | #endif
85 |
86 | /* Other system headers */
87 |
88 | #ifdef HAVE_PCAP_H
89 | #include /* libpcap */
90 | #endif
91 |
92 | #ifdef HAVE_SYS_IOCTL_H
93 | #include
94 | #endif
95 |
96 | #ifdef ARP_PCAP_DLPI
97 | #ifdef HAVE_SYS_BUFMOD_H
98 | #include
99 | #endif
100 | #endif
101 |
102 | #ifdef HAVE_IFADDRS_H
103 | #include
104 | #endif
105 |
106 | /* Mersenne Twister random number generator prototypes */
107 | #include "mt19937ar.h"
108 |
109 | /* OpenBSD strlcpy prototype */
110 | #ifndef HAVE_STRLCPY
111 | #include "strlcpy.h"
112 | #endif
113 |
114 | /* Include the system getopt.h if getopt_long_only() is supported. Otherwise
115 | * include our replacement my_getopt.h */
116 | #ifdef HAVE_GETOPT_LONG_ONLY
117 | #ifdef HAVE_GETOPT_H
118 | #include
119 | #endif
120 | #else
121 | #include "my_getopt.h"
122 | #endif
123 |
124 | /* libpcap POSIX-1e capabilities support */
125 | #ifdef HAVE_SYS_CAPABILITY_H
126 | #include
127 | #include
128 | #endif
129 |
130 | /* Defines */
131 |
132 | #define MAXLINE 255 /* Max line length for input files */
133 | #define MAX_FRAME 2048 /* Maximum allowed frame size */
134 | #define REALLOC_COUNT 1000 /* Entries to realloc at once */
135 | #define DEFAULT_BANDWIDTH 256000 /* Default bandwidth in bits/sec */
136 | #define PACKET_OVERHEAD 18 /* layer 2 overhead (6+6+2 + 4) */
137 | #define MINIMUM_FRAME_SIZE 46 /* Minimum layer 2 date size */
138 | #define DEFAULT_BACKOFF_FACTOR 1.5 /* Default timeout backoff factor */
139 | #define DEFAULT_RETRY 2 /* Default number of retries */
140 | #define DEFAULT_TIMEOUT 500 /* Default per-host timeout in ms */
141 | #define SNAPLEN 64 /* 14 (ether) + 28 (ARP) + extra */
142 | #define PROMISC 0 /* Promiscuous mode 0=off, 1=on */
143 | #define TO_MS 1000 /* Timeout for pcap_set_timeout() */
144 | #define OPTIMISE 1 /* Optimise pcap filter */
145 | #define ARPHRD_ETHER 1 /* Ethernet ARP type */
146 | #define ARPOP_REQUEST 1 /* ARP Request */
147 | #define ARPOP_REPLY 2 /* ARP Reply */
148 | #define ETHER_HDR_SIZE 14 /* Size of Ethernet frame header in bytes */
149 | #define ARP_PKT_SIZE 28 /* Size of ARP Packet in bytes */
150 | #define ETH_ALEN 6 /* Octets in one ethernet addr */
151 | #define ETH_P_IP 0x0800 /* Internet Protocol packet */
152 | #define ETH_P_ARP 0x0806 /* Address Resolution packet */
153 | #define OUIFILENAME "ieee-oui.txt" /* Default IEEE OUI filename */
154 | #define MACFILENAME "mac-vendor.txt" /* Default MAC/Vendor filename */
155 | #define DEFAULT_ARP_OP ARPOP_REQUEST /* Default ARP operation */
156 | #define DEFAULT_ARP_HRD ARPHRD_ETHER /* Default ARP hardware type */
157 | #define DEFAULT_ARP_PRO ETH_P_IP /* Default ARP protocol */
158 | #define DEFAULT_ARP_HLN 6 /* Default hardware length */
159 | #define DEFAULT_ARP_PLN 4 /* Default protocol length */
160 | #define DEFAULT_ETH_PRO ETH_P_ARP /* Default Ethernet protocol */
161 | #define FRAMING_ETHERNET_II 0 /* Standard Ethernet-II Framing */
162 | #define FRAMING_LLC_SNAP 1 /* 802.3 with LLC/SNAP */
163 | #define OPT_WRITEPKTTOFILE 256 /* --writepkttofile option */
164 | #define OPT_READPKTFROMFILE 257 /* --readpktfromfile option */
165 | #define OPT_RANDOMSEED 258 /* --randomseed option */
166 | #define OPT_EXCLUDEBROADCAST 259 /* --exclude-broadcast option */
167 | #define HASH_TABLE_SIZE 70000 /* Max size of MAC/Vendor hash table */
168 | #define DEFAULT_RETRY_SEND 20 /* Default no. of send packet retries */
169 | #define DEFAULT_RETRY_SEND_INTERVAL 5000 /* Default interval between send
170 | * packet retries in microseconds */
171 | #define NUMFIELDS 12 /* Number of output fields */
172 |
173 | /* Structures */
174 |
175 | typedef struct {
176 | unsigned timeout; /* Timeout for this host in us */
177 | struct in_addr addr; /* Host IP address */
178 | struct timeval last_send_time; /* Time when last packet sent to this addr */
179 | unsigned short num_sent; /* Number of packets sent */
180 | unsigned short num_recv; /* Number of packets received */
181 | unsigned char live; /* Set when awaiting response */
182 | } host_entry;
183 |
184 | /* Ethernet frame header */
185 | typedef struct {
186 | uint8_t dest_addr[ETH_ALEN]; /* Destination hardware address */
187 | uint8_t src_addr[ETH_ALEN]; /* Source hardware address */
188 | uint16_t frame_type; /* Ethernet frame type */
189 | } ether_hdr;
190 |
191 | /* Ethernet ARP packet from RFC 826 */
192 | typedef struct {
193 | uint16_t ar_hrd; /* Format of hardware address */
194 | uint16_t ar_pro; /* Format of protocol address */
195 | uint8_t ar_hln; /* Length of hardware address */
196 | uint8_t ar_pln; /* Length of protocol address */
197 | uint16_t ar_op; /* ARP opcode (command) */
198 | uint8_t ar_sha[ETH_ALEN]; /* Sender hardware address */
199 | uint32_t ar_sip; /* Sender IP address */
200 | uint8_t ar_tha[ETH_ALEN]; /* Target hardware address */
201 | uint32_t ar_tip; /* Target IP address */
202 | } arp_ether_ipv4;
203 |
204 | /* name to ID lookup map */
205 | typedef struct {
206 | int id;
207 | const char *name;
208 | } id_name_map;
209 |
210 | /* output format */
211 | enum format_type {
212 | FORMAT_INVALID,
213 | FORMAT_STRING,
214 | FORMAT_FIELD
215 | };
216 |
217 | typedef struct format_element {
218 | struct format_element *next;
219 | enum format_type type;
220 | int width;
221 | char *data;
222 | } format_element;
223 |
224 | /* POSIX.1e Capability status */
225 | typedef enum {
226 | DISABLE = 0,
227 | ENABLE
228 | } cap_status;
229 |
230 | /* Functions - grouped by source file and listed in alphabetical order */
231 |
232 | /* arp-scan.c */
233 | void add_host(const char *, unsigned, int);
234 | void add_host_pattern(const char *, unsigned);
235 | int add_mac_vendor(const char *);
236 | void advance_cursor(void);
237 | void arp_scan_version(void);
238 | void callback(u_char *, const struct pcap_pkthdr *, const u_char *);
239 | void clean_up(pcap_t *);
240 | void display_packet(host_entry *, arp_ether_ipv4 *, const unsigned char *,
241 | size_t, int, int, ether_hdr *, const struct pcap_pkthdr *);
242 | void dump_list(void);
243 | host_entry *find_host(host_entry **, struct in_addr *);
244 | struct in_addr *get_host_address(const char *, struct in_addr *, char **);
245 | char *get_host_name(const struct in_addr, char **);
246 | char *get_mac_vendor_filename(const char *, const char *, const char *);
247 | int get_source_ip(const char *, struct in_addr *);
248 | void marshal_arp_pkt(unsigned char *, ether_hdr *, arp_ether_ipv4 *, size_t *,
249 | const unsigned char *, size_t);
250 | const char *my_ntoa(struct in_addr);
251 | void process_options(int, char *[]);
252 | void recvfrom_wto(int, int, pcap_t *);
253 | void remove_host(host_entry **);
254 | int send_packet(pcap_t *, host_entry *, struct timeval *);
255 | int unmarshal_arp_pkt(const unsigned char *, size_t, ether_hdr *,
256 | arp_ether_ipv4 *, unsigned char *, size_t *, int *);
257 | void usage(void);
258 |
259 | /* error.c */
260 | void err_msg(const char *, ...);
261 | void err_print(int, const char *, va_list);
262 | void err_sys(const char *, ...);
263 | void warn_msg(const char *, ...);
264 | void warn_sys(const char *, ...);
265 |
266 | /* format.c */
267 | format_element *format_parse(const char *);
268 |
269 | /* link-{bpf,packet-socket,dlpi}.c */
270 | void get_hardware_address(const char *, unsigned char []);
271 |
272 | /* utils.c */
273 | void drop_capabilities(void);
274 | char *dupstr(const char *);
275 | int get_ether_addr(const char *, unsigned char *);
276 | unsigned char *hex2data(const char *, size_t *);
277 | char *hexstring(const unsigned char *, size_t);
278 | unsigned int hstr_i(const char *);
279 | void limit_capabilities(void);
280 | char *make_message(const char *, ...);
281 | char *my_lookupdev(char *);
282 | int name_to_id(const char *, const id_name_map[]);
283 | void set_capability(cap_status);
284 | int str_ccmp(const char *, const char *);
285 | unsigned str_to_bandwidth(const char *);
286 | unsigned str_to_interval(const char *);
287 | void timeval_diff(const struct timeval *, const struct timeval *,
288 | struct timeval *);
289 |
290 | /* wrappers.c */
291 | int Gettimeofday(struct timeval *);
292 | void *Malloc(size_t);
293 | void *Realloc(void *, size_t);
294 | long int Strtol(const char *, int);
295 | unsigned long int Strtoul(const char *, int);
296 |
--------------------------------------------------------------------------------
/check-error:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # arp-scan is Copyright (C) 2005-2025 Roy Hills
3 | #
4 | # This file is part of arp-scan.
5 | #
6 | # arp-scan is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # arp-scan is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with arp-scan. If not, see .
18 | #
19 | # check-run1 -- Shell script to test arp-scan basic functionality
20 | #
21 | # Author: Roy Hills
22 | # Date: 7 November 2022
23 | #
24 | # This shell script checks various error conditions.
25 | #
26 | ARPSCANOUTPUT=/tmp/arp-scan-output.$$.tmp
27 | SAMPLE01="$srcdir/testdata/pkt-simple-response.pcap"
28 | SAMPLE02="$srcdir/testdata/pkt-too-short.pcap"
29 |
30 | # Check invalid option - should have non-zero exit status
31 | echo "Checking arp-scan --xyz (invalid option) ..."
32 | ./arp-scan --xyz > "$ARPSCANOUTPUT" 2>&1
33 | if test $? -eq 0; then
34 | rm -f "$ARPSCANOUTPUT"
35 | echo "FAILED"
36 | exit 1
37 | fi
38 | grep '^Use "arp-scan --help" for detailed information' "$ARPSCANOUTPUT" >/dev/null
39 | if test $? -ne 0; then
40 | rm -f "$ARPSCANOUTPUT"
41 | echo "FAILED"
42 | exit 1
43 | fi
44 | echo "ok"
45 | rm -f "$ARPSCANOUTPUT"
46 |
47 | # Check no target hosts - should have non-zero exit status
48 | echo "Checking arp-scan without target hosts ..."
49 | ./arp-scan > "$ARPSCANOUTPUT" 2>&1
50 | if test $? -eq 0; then
51 | rm -f "$ARPSCANOUTPUT"
52 | echo "FAILED"
53 | exit 1
54 | fi
55 | grep '^ERROR: No target hosts on command line ' "$ARPSCANOUTPUT" >/dev/null
56 | if test $? -ne 0; then
57 | rm -f "$ARPSCANOUTPUT"
58 | echo "FAILED"
59 | exit 1
60 | fi
61 | echo "ok"
62 | rm -f "$ARPSCANOUTPUT"
63 |
64 | # Try to use a host input file that doesn't exist - should have non-zero exit status
65 | echo "Checking arp-scan with non existent host file ..."
66 | ARPARGS="--retry=1"
67 | ./arp-scan $ARPARGS -f xxxFUNNYxxx --readpktfromfile="$SAMPLE01" > "$ARPSCANOUTPUT" 2>&1
68 | if test $? -eq 0; then
69 | rm -f "$ARPSCANOUTPUT"
70 | echo "FAILED"
71 | exit 1
72 | fi
73 | grep '^Cannot open xxxFUNNYxxx:' "$ARPSCANOUTPUT" >/dev/null
74 | if test $? -ne 0; then
75 | rm -f "$ARPSCANOUTPUT"
76 | echo "FAILED"
77 | exit 1
78 | fi
79 | echo "ok"
80 | rm -f "$ARPSCANOUTPUT"
81 |
82 | # Try to use a non-existent mac/vendor mapping file - should warn and continue
83 | echo "Checking arp-scan with non existent mac/vendor file ..."
84 | ARPARGS="--retry=1"
85 | ./arp-scan $ARPARGS -O xxxFUNNYxxx --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
86 | if test $? -ne 0; then
87 | rm -f "$ARPSCANOUTPUT"
88 | echo "FAILED"
89 | exit 1
90 | fi
91 | grep '^WARNING: Cannot open MAC/Vendor file xxxFUNNYxxx:' "$ARPSCANOUTPUT" >/dev/null
92 | if test $? -ne 0; then
93 | rm -f "$ARPSCANOUTPUT"
94 | echo "FAILED"
95 | exit 1
96 | fi
97 | echo "ok"
98 | rm -f "$ARPSCANOUTPUT"
99 |
100 | # Try to specify both --bandwidth and --interval - nonzero exit status.
101 | echo "Checking arp-scan with both --bandwidth and --interval ..."
102 | ARPARGS="--retry=1 --bandwidth=1 --interval=1"
103 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
104 | if test $? -eq 0; then
105 | rm -f "$ARPSCANOUTPUT"
106 | echo "FAILED"
107 | exit 1
108 | fi
109 | grep '^ERROR: You cannot specify both --bandwidth and --interval' "$ARPSCANOUTPUT" >/dev/null
110 | if test $? -ne 0; then
111 | rm -f "$ARPSCANOUTPUT"
112 | echo "FAILED"
113 | exit 1
114 | fi
115 | echo "ok"
116 | rm -f "$ARPSCANOUTPUT"
117 |
118 | # Try to specify targets with the --localnet option - nonzero exit
119 | echo "Checking arp-scan with both targets and --localnet ..."
120 | ARPARGS="--retry=1"
121 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" --localnet 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
122 | if test $? -eq 0; then
123 | rm -f "$ARPSCANOUTPUT"
124 | echo "FAILED"
125 | exit 1
126 | fi
127 | grep '^ERROR: You can not specify targets with the --localnet option' "$ARPSCANOUTPUT" >/dev/null
128 | if test $? -ne 0; then
129 | rm -f "$ARPSCANOUTPUT"
130 | echo "FAILED"
131 | exit 1
132 | fi
133 | echo "ok"
134 | rm -f "$ARPSCANOUTPUT"
135 |
136 | # Try to specify --file with --localnet option - nonzero exit
137 | echo "Checking arp-scan with --file and --localnet ..."
138 | ARPARGS="--retry=1"
139 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" --localnet --file=- > "$ARPSCANOUTPUT" 2>&1
140 | if test $? -eq 0; then
141 | rm -f "$ARPSCANOUTPUT"
142 | echo "FAILED"
143 | exit 1
144 | fi
145 | grep '^ERROR: You can not specify both --file and --localnet options' "$ARPSCANOUTPUT" >/dev/null
146 | if test $? -ne 0; then
147 | rm -f "$ARPSCANOUTPUT"
148 | echo "FAILED"
149 | exit 1
150 | fi
151 | echo "ok"
152 | rm -f "$ARPSCANOUTPUT"
153 |
154 | # Specify invalid IP address - warning followed by nonzero exit
155 | echo "Checking arp-scan with invalid IP address ..."
156 | ARPARGS="--retry=1 --numeric"
157 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 333.333.333.333 > "$ARPSCANOUTPUT" 2>&1
158 | if test $? -eq 0; then
159 | rm -f "$ARPSCANOUTPUT"
160 | echo "FAILED"
161 | exit 1
162 | fi
163 | grep '^WARNING: "333.333.333.333" is not a valid IPv4 address - target ignored' "$ARPSCANOUTPUT" >/dev/null
164 | if test $? -ne 0; then
165 | rm -f "$ARPSCANOUTPUT"
166 | echo "FAILED"
167 | exit 1
168 | fi
169 | echo "ok"
170 | rm -f "$ARPSCANOUTPUT"
171 |
172 | # Specify invalid IP network in CIDR notation - nonzero exit
173 | echo "Checking arp-scan with invalid IP network in CIDR notation ..."
174 | ARPARGS="--retry=1 --numeric"
175 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 333.0.0.0/24 > "$ARPSCANOUTPUT" 2>&1
176 | if test $? -eq 0; then
177 | rm -f "$ARPSCANOUTPUT"
178 | echo "FAILED"
179 | exit 1
180 | fi
181 | grep '^ERROR: 333.0.0.0 is not a valid IPv4 network' "$ARPSCANOUTPUT" >/dev/null
182 | if test $? -ne 0; then
183 | rm -f "$ARPSCANOUTPUT"
184 | echo "FAILED"
185 | exit 1
186 | fi
187 | echo "ok"
188 | rm -f "$ARPSCANOUTPUT"
189 |
190 | # Specify invalid CIDR mask - nonzero exit
191 | echo "Checking arp-scan with invalid CIDR address ..."
192 | ARPARGS="--retry=1"
193 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 10.0.0.0/0 > "$ARPSCANOUTPUT" 2>&1
194 | if test $? -eq 0; then
195 | rm -f "$ARPSCANOUTPUT"
196 | echo "FAILED"
197 | exit 1
198 | fi
199 | grep '^ERROR: Number of bits in 10.0.0.0/0 must be between 3 and 32' "$ARPSCANOUTPUT" >/dev/null
200 | if test $? -ne 0; then
201 | rm -f "$ARPSCANOUTPUT"
202 | echo "FAILED"
203 | exit 1
204 | fi
205 | echo "ok"
206 | rm -f "$ARPSCANOUTPUT"
207 |
208 | # Specify CIDR address with non-zero host part: warning
209 | echo "Checking arp-scan with nonzero host in CIDR address ..."
210 | ARPARGS="--retry=1"
211 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 10.0.0.1/30 > "$ARPSCANOUTPUT" 2>&1
212 | if test $? -ne 0; then
213 | rm -f "$ARPSCANOUTPUT"
214 | echo "FAILED"
215 | exit 1
216 | fi
217 | grep '^WARNING: host part of 10.0.0.1/30 is non-zero' "$ARPSCANOUTPUT" >/dev/null
218 | if test $? -ne 0; then
219 | rm -f "$ARPSCANOUTPUT"
220 | echo "FAILED"
221 | exit 1
222 | fi
223 | echo "ok"
224 | rm -f "$ARPSCANOUTPUT"
225 |
226 | # Specify invalid IP network in net:mask notation - nonzero exit
227 | echo "Checking arp-scan with invalid IP network in net:mask notation ..."
228 | ARPARGS="--retry=1 --numeric"
229 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 333.0.0.0:255.255.255.0 > "$ARPSCANOUTPUT" 2>&1
230 | if test $? -eq 0; then
231 | rm -f "$ARPSCANOUTPUT"
232 | echo "FAILED"
233 | exit 1
234 | fi
235 | grep '^ERROR: 333.0.0.0 is not a valid IPv4 network' "$ARPSCANOUTPUT" >/dev/null
236 | if test $? -ne 0; then
237 | rm -f "$ARPSCANOUTPUT"
238 | echo "FAILED"
239 | exit 1
240 | fi
241 | echo "ok"
242 | rm -f "$ARPSCANOUTPUT"
243 |
244 | # Specify invalid netmask - nonzero exit
245 | echo "Checking arp-scan with invalid netmask ..."
246 | ARPARGS="--retry=1"
247 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 10.0.0.0:333.0.0.0 > "$ARPSCANOUTPUT" 2>&1
248 | if test $? -eq 0; then
249 | rm -f "$ARPSCANOUTPUT"
250 | echo "FAILED"
251 | exit 1
252 | fi
253 | grep '^ERROR: 333.0.0.0 is not a valid netmask' "$ARPSCANOUTPUT" >/dev/null
254 | if test $? -ne 0; then
255 | rm -f "$ARPSCANOUTPUT"
256 | echo "FAILED"
257 | exit 1
258 | fi
259 | echo "ok"
260 | rm -f "$ARPSCANOUTPUT"
261 |
262 | # Specify net:mask address with non-zero host part: warning
263 | echo "Checking arp-scan with nonzero host in net:mask address ..."
264 | ARPARGS="--retry=1"
265 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 10.0.0.1:255.255.255.252 > "$ARPSCANOUTPUT" 2>&1
266 | if test $? -ne 0; then
267 | rm -f "$ARPSCANOUTPUT"
268 | echo "FAILED"
269 | exit 1
270 | fi
271 | grep '^WARNING: host part of 10.0.0.1:255.255.255.252 is non-zero' "$ARPSCANOUTPUT" >/dev/null
272 | if test $? -ne 0; then
273 | rm -f "$ARPSCANOUTPUT"
274 | echo "FAILED"
275 | exit 1
276 | fi
277 | echo "ok"
278 | rm -f "$ARPSCANOUTPUT"
279 |
280 | # Specify invalid starting IP address in range notation - nonzero exit
281 | echo "Checking arp-scan with invalid starting IP network in range notation ..."
282 | ARPARGS="--retry=1 --numeric"
283 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 333.0.0.0-10.0.0.1 > "$ARPSCANOUTPUT" 2>&1
284 | if test $? -eq 0; then
285 | rm -f "$ARPSCANOUTPUT"
286 | echo "FAILED"
287 | exit 1
288 | fi
289 | grep '^ERROR: Invalid range specification: 333.0.0.0 is not a valid IPv4 address' "$ARPSCANOUTPUT" >/dev/null
290 | if test $? -ne 0; then
291 | rm -f "$ARPSCANOUTPUT"
292 | echo "FAILED"
293 | exit 1
294 | fi
295 | echo "ok"
296 | rm -f "$ARPSCANOUTPUT"
297 |
298 | # Specify invalid ending IP address in range notation - nonzero exit
299 | echo "Checking arp-scan with invalid ending IP network in range notation ..."
300 | ARPARGS="--retry=1"
301 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 10.0.0.1-333.0.0.0 > "$ARPSCANOUTPUT" 2>&1
302 | if test $? -eq 0; then
303 | rm -f "$ARPSCANOUTPUT"
304 | echo "FAILED"
305 | exit 1
306 | fi
307 | grep '^ERROR: Invalid range specification: 333.0.0.0 is not a valid IPv4 address' "$ARPSCANOUTPUT" >/dev/null
308 | if test $? -ne 0; then
309 | rm -f "$ARPSCANOUTPUT"
310 | echo "FAILED"
311 | exit 1
312 | fi
313 | echo "ok"
314 | rm -f "$ARPSCANOUTPUT"
315 |
316 | # Invalid signed long int input - nonzero exit
317 | echo "Checking arp-scan with invalid CIDR address ..."
318 | ARPARGS="--retry=1 --retry-send=xyz"
319 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
320 | if test $? -eq 0; then
321 | rm -f "$ARPSCANOUTPUT"
322 | echo "FAILED"
323 | exit 1
324 | fi
325 | grep '^ERROR: "xyz" is not a valid numeric value' "$ARPSCANOUTPUT" >/dev/null
326 | if test $? -ne 0; then
327 | rm -f "$ARPSCANOUTPUT"
328 | echo "FAILED"
329 | exit 1
330 | fi
331 | echo "ok"
332 | rm -f "$ARPSCANOUTPUT"
333 |
334 | # Invalid unsigned long int input - nonzero exit
335 | echo "Checking arp-scan with invalid CIDR address ..."
336 | ARPARGS="--retry=1 --snap=xyz"
337 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
338 | if test $? -eq 0; then
339 | rm -f "$ARPSCANOUTPUT"
340 | echo "FAILED"
341 | exit 1
342 | fi
343 | grep '^ERROR: "xyz" is not a valid numeric value' "$ARPSCANOUTPUT" >/dev/null
344 | if test $? -ne 0; then
345 | rm -f "$ARPSCANOUTPUT"
346 | echo "FAILED"
347 | exit 1
348 | fi
349 | echo "ok"
350 | rm -f "$ARPSCANOUTPUT"
351 |
352 | # Invalid bandwidth multiplier - nonzero exit
353 | echo "Checking arp-scan with invalid bandwidth multiple ..."
354 | ARPARGS="--retry=1 --bandwidth=1x"
355 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
356 | if test $? -eq 0; then
357 | rm -f "$ARPSCANOUTPUT"
358 | echo "FAILED"
359 | exit 1
360 | fi
361 | grep '^ERROR: Unknown bandwidth multiplier character: "x"' "$ARPSCANOUTPUT" >/dev/null
362 | if test $? -ne 0; then
363 | rm -f "$ARPSCANOUTPUT"
364 | echo "FAILED"
365 | exit 1
366 | fi
367 | echo "ok"
368 | rm -f "$ARPSCANOUTPUT"
369 |
370 | # Invalid interval multiplier - nonzero exit
371 | echo "Checking arp-scan with invalid interval multiple ..."
372 | ARPARGS="--retry=1 --interval=1x"
373 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
374 | if test $? -eq 0; then
375 | rm -f "$ARPSCANOUTPUT"
376 | echo "FAILED"
377 | exit 1
378 | fi
379 | grep '^ERROR: Unknown interval multiplier character: "x"' "$ARPSCANOUTPUT" >/dev/null
380 | if test $? -ne 0; then
381 | rm -f "$ARPSCANOUTPUT"
382 | echo "FAILED"
383 | exit 1
384 | fi
385 | echo "ok"
386 | rm -f "$ARPSCANOUTPUT"
387 |
388 | # Invalid --format string: invalid field width
389 | echo "Checking arp-scan with invalid --format field width ..."
390 | ARPARGS="--retry=1 --format=\${ip;X}"
391 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
392 | if test $? -eq 0; then
393 | rm -f "$ARPSCANOUTPUT"
394 | echo "FAILED"
395 | exit 1
396 | fi
397 | grep '^ERROR: incorrect format string: invalid character \"X\" in field width' "$ARPSCANOUTPUT" >/dev/null
398 | if test $? -ne 0; then
399 | rm -f "$ARPSCANOUTPUT"
400 | echo "FAILED"
401 | exit 1
402 | fi
403 | echo "ok"
404 | rm -f "$ARPSCANOUTPUT"
405 |
406 | # Invalid --format string: field width out of range
407 | echo "Checking arp-scan with --format field width out of range ..."
408 | ARPARGS="--retry=1 --format=\${ip;5000000000}"
409 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
410 | if test $? -eq 0; then
411 | rm -f "$ARPSCANOUTPUT"
412 | echo "FAILED"
413 | exit 1
414 | fi
415 | grep '^ERROR: incorrect format string: field width out of range' "$ARPSCANOUTPUT" >/dev/null
416 | if test $? -ne 0; then
417 | rm -f "$ARPSCANOUTPUT"
418 | echo "FAILED"
419 | exit 1
420 | fi
421 | echo "ok"
422 | rm -f "$ARPSCANOUTPUT"
423 |
424 | # Invalid format string: missing closing brace
425 | echo "Checking arp-scan with --format field missing closing brace ..."
426 | ARPARGS="--retry=1 --format=\${ip"
427 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
428 | if test $? -eq 0; then
429 | rm -f "$ARPSCANOUTPUT"
430 | echo "FAILED"
431 | exit 1
432 | fi
433 | grep '^ERROR: incorrect format string: missing closing brace' "$ARPSCANOUTPUT" >/dev/null
434 | if test $? -ne 0; then
435 | rm -f "$ARPSCANOUTPUT"
436 | echo "FAILED"
437 | exit 1
438 | fi
439 | echo "ok"
440 | rm -f "$ARPSCANOUTPUT"
441 |
442 | # Invalid format string: empty string
443 | echo "Checking arp-scan with --format field empty string ..."
444 | ARPARGS="--retry=1 --format="
445 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
446 | if test $? -eq 0; then
447 | rm -f "$ARPSCANOUTPUT"
448 | echo "FAILED"
449 | exit 1
450 | fi
451 | grep '^ERROR: output format may not be empty string' "$ARPSCANOUTPUT" >/dev/null
452 | if test $? -ne 0; then
453 | rm -f "$ARPSCANOUTPUT"
454 | echo "FAILED"
455 | exit 1
456 | fi
457 | echo "ok"
458 | rm -f "$ARPSCANOUTPUT"
459 |
460 | # --destaddr invalid MAC address
461 | echo "Checking arp-scan with --destaddr invalid MAC address ..."
462 | ARPARGS="--retry=1 --destaddr=XX"
463 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
464 | if test $? -eq 0; then
465 | rm -f "$ARPSCANOUTPUT"
466 | echo "FAILED"
467 | exit 1
468 | fi
469 | grep '^Invalid MAC address: XX' "$ARPSCANOUTPUT" >/dev/null
470 | if test $? -ne 0; then
471 | rm -f "$ARPSCANOUTPUT"
472 | echo "FAILED"
473 | exit 1
474 | fi
475 | echo "ok"
476 | rm -f "$ARPSCANOUTPUT"
477 |
478 | # --arpsha invalid MAC address
479 | echo "Checking arp-scan with --arpsha invalid MAC address ..."
480 | ARPARGS="--retry=1 --arpsha=XX"
481 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
482 | if test $? -eq 0; then
483 | rm -f "$ARPSCANOUTPUT"
484 | echo "FAILED"
485 | exit 1
486 | fi
487 | grep '^Invalid MAC address: XX' "$ARPSCANOUTPUT" >/dev/null
488 | if test $? -ne 0; then
489 | rm -f "$ARPSCANOUTPUT"
490 | echo "FAILED"
491 | exit 1
492 | fi
493 | echo "ok"
494 | rm -f "$ARPSCANOUTPUT"
495 |
496 | # --arptha invalid MAC address
497 | echo "Checking arp-scan with --arptha invalid MAC address ..."
498 | ARPARGS="--retry=1 --arptha=XX"
499 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
500 | if test $? -eq 0; then
501 | rm -f "$ARPSCANOUTPUT"
502 | echo "FAILED"
503 | exit 1
504 | fi
505 | grep '^Invalid MAC address: XX' "$ARPSCANOUTPUT" >/dev/null
506 | if test $? -ne 0; then
507 | rm -f "$ARPSCANOUTPUT"
508 | echo "FAILED"
509 | exit 1
510 | fi
511 | echo "ok"
512 | rm -f "$ARPSCANOUTPUT"
513 |
514 | # --srcaddr invalid MAC address
515 | echo "Checking arp-scan with --srcaddr invalid MAC address ..."
516 | ARPARGS="--retry=1 --srcaddr=XX"
517 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
518 | if test $? -eq 0; then
519 | rm -f "$ARPSCANOUTPUT"
520 | echo "FAILED"
521 | exit 1
522 | fi
523 | grep '^Invalid MAC address: XX' "$ARPSCANOUTPUT" >/dev/null
524 | if test $? -ne 0; then
525 | rm -f "$ARPSCANOUTPUT"
526 | echo "FAILED"
527 | exit 1
528 | fi
529 | echo "ok"
530 | rm -f "$ARPSCANOUTPUT"
531 |
532 | # Non-existent pcap file for --readpktfromfile
533 | echo "Checking arp-scan with nonexistent --readpktfromfile file ..."
534 | ARPARGS="--retry=1 --readpktfromfile=xxxFUNNYxxx"
535 | ./arp-scan $ARPARGS 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
536 | if test $? -eq 0; then
537 | rm -f "$ARPSCANOUTPUT"
538 | echo "FAILED"
539 | exit 1
540 | fi
541 | grep '^pcap_open_offline: xxxFUNNYxxx: No such file or directory' "$ARPSCANOUTPUT" >/dev/null
542 | if test $? -ne 0; then
543 | rm -f "$ARPSCANOUTPUT"
544 | echo "FAILED"
545 | exit 1
546 | fi
547 | echo "ok"
548 | rm -f "$ARPSCANOUTPUT"
549 |
550 | # Invalid IP address for --arpspa option
551 | echo "Checking arp-scan with invalid --arpspa option ..."
552 | ARPARGS="--retry=1"
553 | ./arp-scan $ARPARGS --arpspa=333.0.0.1 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
554 | if test $? -eq 0; then
555 | rm -f "$ARPSCANOUTPUT"
556 | echo "FAILED"
557 | exit 1
558 | fi
559 | grep '^ERROR: Invalid IPv4 address: 333.0.0.1' "$ARPSCANOUTPUT" >/dev/null
560 | if test $? -ne 0; then
561 | rm -f "$ARPSCANOUTPUT"
562 | echo "FAILED"
563 | exit 1
564 | fi
565 | echo "ok"
566 | rm -f "$ARPSCANOUTPUT"
567 |
568 | # Odd --padding length
569 | echo "Checking arp-scan with odd --padding length ..."
570 | ARPARGS="--retry=1"
571 | ./arp-scan $ARPARGS --padding=a 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
572 | if test $? -eq 0; then
573 | rm -f "$ARPSCANOUTPUT"
574 | echo "FAILED"
575 | exit 1
576 | fi
577 | grep '^ERROR: Length of --padding argument must be even (multiple of 2).' "$ARPSCANOUTPUT" >/dev/null
578 | if test $? -ne 0; then
579 | rm -f "$ARPSCANOUTPUT"
580 | echo "FAILED"
581 | exit 1
582 | fi
583 | echo "ok"
584 | rm -f "$ARPSCANOUTPUT"
585 |
586 | # Packet too short to decode
587 | echo "Checking arp-scan with packet too short to decode ..."
588 | ARPARGS="--retry=1 --plain --quiet"
589 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE02" 127.0.0.1 > "$ARPSCANOUTPUT" 2>&1
590 | if test $? -ne 0; then
591 | rm -f "$ARPSCANOUTPUT"
592 | echo "FAILED"
593 | exit 1
594 | fi
595 | grep '^WARNING: 22 byte packet too short to decode.' "$ARPSCANOUTPUT" >/dev/null
596 | if test $? -ne 0; then
597 | rm -f "$ARPSCANOUTPUT"
598 | echo "FAILED"
599 | exit 1
600 | fi
601 | echo "ok"
602 | rm -f "$ARPSCANOUTPUT"
603 |
--------------------------------------------------------------------------------
/check-host-list:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # arp-scan is Copyright (C) 2005-2025 Roy Hills
3 | #
4 | # This file is part of arp-scan.
5 | #
6 | # arp-scan is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # arp-scan is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with arp-scan. If not, see .
18 | #
19 | # check-host-list - Shell script to test arp-scan host list creation
20 | #
21 | # Author: Roy Hills
22 | # Date: 4 February 2011
23 | #
24 | # This script checks that arp-scan creates the host list correctly.
25 | # It uses the undocumented arp-scan option --readpktfromfile to
26 | # read the packets from a pcap file rather than from the network.
27 | #
28 |
29 | ARPSCANOUTPUT=/tmp/arp-scan-output.$$.tmp
30 | EXAMPLEOUTPUT=/tmp/example-output.$$.tmp
31 | #
32 | SAMPLE01="$srcdir/testdata/pkt-net1921681-response.pcap"
33 |
34 | # 56 ARP responses from a Class-C sized network with various vendors
35 | echo "Checking host list creation using $SAMPLE01 ..."
36 | cat >"$EXAMPLEOUTPUT" <<_EOF_
37 | Host List:
38 |
39 | Entry IP Address
40 | 1 192.168.1.0
41 | 2 192.168.1.1
42 | 3 192.168.1.2
43 | 4 192.168.1.3
44 | 5 192.168.1.4
45 | 6 192.168.1.5
46 | 7 192.168.1.6
47 | 8 192.168.1.7
48 | 9 192.168.1.8
49 | 10 192.168.1.9
50 | 11 192.168.1.10
51 | 12 192.168.1.11
52 | 13 192.168.1.12
53 | 14 192.168.1.13
54 | 15 192.168.1.14
55 | 16 192.168.1.15
56 | 17 192.168.1.16
57 | 18 192.168.1.17
58 | 19 192.168.1.18
59 | 20 192.168.1.19
60 | 21 192.168.1.20
61 | 22 192.168.1.21
62 | 23 192.168.1.22
63 | 24 192.168.1.23
64 | 25 192.168.1.24
65 | 26 192.168.1.25
66 | 27 192.168.1.26
67 | 28 192.168.1.27
68 | 29 192.168.1.28
69 | 30 192.168.1.29
70 | 31 192.168.1.30
71 | 32 192.168.1.31
72 | 33 192.168.1.32
73 | 34 192.168.1.33
74 | 35 192.168.1.34
75 | 36 192.168.1.35
76 | 37 192.168.1.36
77 | 38 192.168.1.37
78 | 39 192.168.1.38
79 | 40 192.168.1.39
80 | 41 192.168.1.40
81 | 42 192.168.1.41
82 | 43 192.168.1.42
83 | 44 192.168.1.43
84 | 45 192.168.1.44
85 | 46 192.168.1.45
86 | 47 192.168.1.46
87 | 48 192.168.1.47
88 | 49 192.168.1.48
89 | 50 192.168.1.49
90 | 51 192.168.1.50
91 | 52 192.168.1.51
92 | 53 192.168.1.52
93 | 54 192.168.1.53
94 | 55 192.168.1.54
95 | 56 192.168.1.55
96 | 57 192.168.1.56
97 | 58 192.168.1.57
98 | 59 192.168.1.58
99 | 60 192.168.1.59
100 | 61 192.168.1.60
101 | 62 192.168.1.61
102 | 63 192.168.1.62
103 | 64 192.168.1.63
104 | 65 192.168.1.64
105 | 66 192.168.1.65
106 | 67 192.168.1.66
107 | 68 192.168.1.67
108 | 69 192.168.1.68
109 | 70 192.168.1.69
110 | 71 192.168.1.70
111 | 72 192.168.1.71
112 | 73 192.168.1.72
113 | 74 192.168.1.73
114 | 75 192.168.1.74
115 | 76 192.168.1.75
116 | 77 192.168.1.76
117 | 78 192.168.1.77
118 | 79 192.168.1.78
119 | 80 192.168.1.79
120 | 81 192.168.1.80
121 | 82 192.168.1.81
122 | 83 192.168.1.82
123 | 84 192.168.1.83
124 | 85 192.168.1.84
125 | 86 192.168.1.85
126 | 87 192.168.1.86
127 | 88 192.168.1.87
128 | 89 192.168.1.88
129 | 90 192.168.1.89
130 | 91 192.168.1.90
131 | 92 192.168.1.91
132 | 93 192.168.1.92
133 | 94 192.168.1.93
134 | 95 192.168.1.94
135 | 96 192.168.1.95
136 | 97 192.168.1.96
137 | 98 192.168.1.97
138 | 99 192.168.1.98
139 | 100 192.168.1.99
140 | 101 192.168.1.100
141 | 102 192.168.1.101
142 | 103 192.168.1.102
143 | 104 192.168.1.103
144 | 105 192.168.1.104
145 | 106 192.168.1.105
146 | 107 192.168.1.106
147 | 108 192.168.1.107
148 | 109 192.168.1.108
149 | 110 192.168.1.109
150 | 111 192.168.1.110
151 | 112 192.168.1.111
152 | 113 192.168.1.112
153 | 114 192.168.1.113
154 | 115 192.168.1.114
155 | 116 192.168.1.115
156 | 117 192.168.1.116
157 | 118 192.168.1.117
158 | 119 192.168.1.118
159 | 120 192.168.1.119
160 | 121 192.168.1.120
161 | 122 192.168.1.121
162 | 123 192.168.1.122
163 | 124 192.168.1.123
164 | 125 192.168.1.124
165 | 126 192.168.1.125
166 | 127 192.168.1.126
167 | 128 192.168.1.127
168 | 129 192.168.1.128
169 | 130 192.168.1.129
170 | 131 192.168.1.130
171 | 132 192.168.1.131
172 | 133 192.168.1.132
173 | 134 192.168.1.133
174 | 135 192.168.1.134
175 | 136 192.168.1.135
176 | 137 192.168.1.136
177 | 138 192.168.1.137
178 | 139 192.168.1.138
179 | 140 192.168.1.139
180 | 141 192.168.1.140
181 | 142 192.168.1.141
182 | 143 192.168.1.142
183 | 144 192.168.1.143
184 | 145 192.168.1.144
185 | 146 192.168.1.145
186 | 147 192.168.1.146
187 | 148 192.168.1.147
188 | 149 192.168.1.148
189 | 150 192.168.1.149
190 | 151 192.168.1.150
191 | 152 192.168.1.151
192 | 153 192.168.1.152
193 | 154 192.168.1.153
194 | 155 192.168.1.154
195 | 156 192.168.1.155
196 | 157 192.168.1.156
197 | 158 192.168.1.157
198 | 159 192.168.1.158
199 | 160 192.168.1.159
200 | 161 192.168.1.160
201 | 162 192.168.1.161
202 | 163 192.168.1.162
203 | 164 192.168.1.163
204 | 165 192.168.1.164
205 | 166 192.168.1.165
206 | 167 192.168.1.166
207 | 168 192.168.1.167
208 | 169 192.168.1.168
209 | 170 192.168.1.169
210 | 171 192.168.1.170
211 | 172 192.168.1.171
212 | 173 192.168.1.172
213 | 174 192.168.1.173
214 | 175 192.168.1.174
215 | 176 192.168.1.175
216 | 177 192.168.1.176
217 | 178 192.168.1.177
218 | 179 192.168.1.178
219 | 180 192.168.1.179
220 | 181 192.168.1.180
221 | 182 192.168.1.181
222 | 183 192.168.1.182
223 | 184 192.168.1.183
224 | 185 192.168.1.184
225 | 186 192.168.1.185
226 | 187 192.168.1.186
227 | 188 192.168.1.187
228 | 189 192.168.1.188
229 | 190 192.168.1.189
230 | 191 192.168.1.190
231 | 192 192.168.1.191
232 | 193 192.168.1.192
233 | 194 192.168.1.193
234 | 195 192.168.1.194
235 | 196 192.168.1.195
236 | 197 192.168.1.196
237 | 198 192.168.1.197
238 | 199 192.168.1.198
239 | 200 192.168.1.199
240 | 201 192.168.1.200
241 | 202 192.168.1.201
242 | 203 192.168.1.202
243 | 204 192.168.1.203
244 | 205 192.168.1.204
245 | 206 192.168.1.205
246 | 207 192.168.1.206
247 | 208 192.168.1.207
248 | 209 192.168.1.208
249 | 210 192.168.1.209
250 | 211 192.168.1.210
251 | 212 192.168.1.211
252 | 213 192.168.1.212
253 | 214 192.168.1.213
254 | 215 192.168.1.214
255 | 216 192.168.1.215
256 | 217 192.168.1.216
257 | 218 192.168.1.217
258 | 219 192.168.1.218
259 | 220 192.168.1.219
260 | 221 192.168.1.220
261 | 222 192.168.1.221
262 | 223 192.168.1.222
263 | 224 192.168.1.223
264 | 225 192.168.1.224
265 | 226 192.168.1.225
266 | 227 192.168.1.226
267 | 228 192.168.1.227
268 | 229 192.168.1.228
269 | 230 192.168.1.229
270 | 231 192.168.1.230
271 | 232 192.168.1.231
272 | 233 192.168.1.232
273 | 234 192.168.1.233
274 | 235 192.168.1.234
275 | 236 192.168.1.235
276 | 237 192.168.1.236
277 | 238 192.168.1.237
278 | 239 192.168.1.238
279 | 240 192.168.1.239
280 | 241 192.168.1.240
281 | 242 192.168.1.241
282 | 243 192.168.1.242
283 | 244 192.168.1.243
284 | 245 192.168.1.244
285 | 246 192.168.1.245
286 | 247 192.168.1.246
287 | 248 192.168.1.247
288 | 249 192.168.1.248
289 | 250 192.168.1.249
290 | 251 192.168.1.250
291 | 252 192.168.1.251
292 | 253 192.168.1.252
293 | 254 192.168.1.253
294 | 255 192.168.1.254
295 | 256 192.168.1.255
296 |
297 | Total of 256 host entries.
298 | _EOF_
299 | ARPARGS="--retry=1 --ouifile=$srcdir/ieee-oui.txt --macfile=$srcdir/mac-vendor.txt -v -v -v"
300 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 192.168.1.0/24 2>&1 | sed -n -e '/^Host List:/,/^Total of /p' > "$ARPSCANOUTPUT" 2>&1
301 | if test $? -ne 0; then
302 | rm -f "$ARPSCANOUTPUT"
303 | rm -f "$EXAMPLEOUTPUT"
304 | echo "FAILED"
305 | exit 1
306 | fi
307 | cmp -s "$ARPSCANOUTPUT" "$EXAMPLEOUTPUT"
308 | if test $? -ne 0; then
309 | rm -f "$ARPSCANOUTPUT"
310 | rm -f "$EXAMPLEOUTPUT"
311 | echo "FAILED"
312 | exit 1
313 | fi
314 | echo "ok"
315 | rm -f "$ARPSCANOUTPUT"
316 | rm -f "$EXAMPLEOUTPUT"
317 | #
318 | echo "Checking random host list creation using $SAMPLE01 ..."
319 | cat >"$EXAMPLEOUTPUT" <<_EOF_
320 | Host List:
321 |
322 | Entry IP Address
323 | 1 192.168.1.149
324 | 2 192.168.1.211
325 | 3 192.168.1.122
326 | 4 192.168.1.254
327 | 5 192.168.1.45
328 | 6 192.168.1.15
329 | 7 192.168.1.226
330 | 8 192.168.1.84
331 | 9 192.168.1.47
332 | 10 192.168.1.80
333 | 11 192.168.1.113
334 | 12 192.168.1.247
335 | 13 192.168.1.118
336 | 14 192.168.1.191
337 | 15 192.168.1.196
338 | 16 192.168.1.210
339 | 17 192.168.1.206
340 | 18 192.168.1.184
341 | 19 192.168.1.245
342 | 20 192.168.1.237
343 | 21 192.168.1.2
344 | 22 192.168.1.240
345 | 23 192.168.1.63
346 | 24 192.168.1.153
347 | 25 192.168.1.223
348 | 26 192.168.1.4
349 | 27 192.168.1.133
350 | 28 192.168.1.16
351 | 29 192.168.1.58
352 | 30 192.168.1.103
353 | 31 192.168.1.169
354 | 32 192.168.1.179
355 | 33 192.168.1.19
356 | 34 192.168.1.37
357 | 35 192.168.1.64
358 | 36 192.168.1.44
359 | 37 192.168.1.151
360 | 38 192.168.1.163
361 | 39 192.168.1.111
362 | 40 192.168.1.93
363 | 41 192.168.1.152
364 | 42 192.168.1.203
365 | 43 192.168.1.14
366 | 44 192.168.1.67
367 | 45 192.168.1.135
368 | 46 192.168.1.215
369 | 47 192.168.1.38
370 | 48 192.168.1.86
371 | 49 192.168.1.52
372 | 50 192.168.1.74
373 | 51 192.168.1.218
374 | 52 192.168.1.65
375 | 53 192.168.1.30
376 | 54 192.168.1.197
377 | 55 192.168.1.134
378 | 56 192.168.1.147
379 | 57 192.168.1.123
380 | 58 192.168.1.174
381 | 59 192.168.1.126
382 | 60 192.168.1.6
383 | 61 192.168.1.143
384 | 62 192.168.1.144
385 | 63 192.168.1.251
386 | 64 192.168.1.241
387 | 65 192.168.1.168
388 | 66 192.168.1.159
389 | 67 192.168.1.120
390 | 68 192.168.1.109
391 | 69 192.168.1.204
392 | 70 192.168.1.39
393 | 71 192.168.1.35
394 | 72 192.168.1.177
395 | 73 192.168.1.157
396 | 74 192.168.1.231
397 | 75 192.168.1.234
398 | 76 192.168.1.239
399 | 77 192.168.1.25
400 | 78 192.168.1.171
401 | 79 192.168.1.51
402 | 80 192.168.1.187
403 | 81 192.168.1.72
404 | 82 192.168.1.69
405 | 83 192.168.1.232
406 | 84 192.168.1.181
407 | 85 192.168.1.150
408 | 86 192.168.1.100
409 | 87 192.168.1.24
410 | 88 192.168.1.1
411 | 89 192.168.1.130
412 | 90 192.168.1.33
413 | 91 192.168.1.136
414 | 92 192.168.1.50
415 | 93 192.168.1.175
416 | 94 192.168.1.95
417 | 95 192.168.1.131
418 | 96 192.168.1.61
419 | 97 192.168.1.209
420 | 98 192.168.1.249
421 | 99 192.168.1.236
422 | 100 192.168.1.225
423 | 101 192.168.1.139
424 | 102 192.168.1.18
425 | 103 192.168.1.49
426 | 104 192.168.1.208
427 | 105 192.168.1.119
428 | 106 192.168.1.92
429 | 107 192.168.1.190
430 | 108 192.168.1.161
431 | 109 192.168.1.201
432 | 110 192.168.1.183
433 | 111 192.168.1.216
434 | 112 192.168.1.248
435 | 113 192.168.1.162
436 | 114 192.168.1.219
437 | 115 192.168.1.17
438 | 116 192.168.1.10
439 | 117 192.168.1.62
440 | 118 192.168.1.3
441 | 119 192.168.1.224
442 | 120 192.168.1.182
443 | 121 192.168.1.242
444 | 122 192.168.1.138
445 | 123 192.168.1.217
446 | 124 192.168.1.90
447 | 125 192.168.1.40
448 | 126 192.168.1.22
449 | 127 192.168.1.48
450 | 128 192.168.1.102
451 | 129 192.168.1.73
452 | 130 192.168.1.76
453 | 131 192.168.1.202
454 | 132 192.168.1.255
455 | 133 192.168.1.97
456 | 134 192.168.1.88
457 | 135 192.168.1.9
458 | 136 192.168.1.243
459 | 137 192.168.1.165
460 | 138 192.168.1.105
461 | 139 192.168.1.132
462 | 140 192.168.1.205
463 | 141 192.168.1.176
464 | 142 192.168.1.253
465 | 143 192.168.1.194
466 | 144 192.168.1.229
467 | 145 192.168.1.79
468 | 146 192.168.1.230
469 | 147 192.168.1.98
470 | 148 192.168.1.173
471 | 149 192.168.1.55
472 | 150 192.168.1.222
473 | 151 192.168.1.101
474 | 152 192.168.1.99
475 | 153 192.168.1.207
476 | 154 192.168.1.212
477 | 155 192.168.1.166
478 | 156 192.168.1.154
479 | 157 192.168.1.78
480 | 158 192.168.1.5
481 | 159 192.168.1.42
482 | 160 192.168.1.13
483 | 161 192.168.1.91
484 | 162 192.168.1.23
485 | 163 192.168.1.193
486 | 164 192.168.1.7
487 | 165 192.168.1.66
488 | 166 192.168.1.124
489 | 167 192.168.1.114
490 | 168 192.168.1.41
491 | 169 192.168.1.28
492 | 170 192.168.1.0
493 | 171 192.168.1.235
494 | 172 192.168.1.146
495 | 173 192.168.1.238
496 | 174 192.168.1.178
497 | 175 192.168.1.71
498 | 176 192.168.1.60
499 | 177 192.168.1.117
500 | 178 192.168.1.12
501 | 179 192.168.1.57
502 | 180 192.168.1.192
503 | 181 192.168.1.29
504 | 182 192.168.1.164
505 | 183 192.168.1.116
506 | 184 192.168.1.121
507 | 185 192.168.1.167
508 | 186 192.168.1.125
509 | 187 192.168.1.32
510 | 188 192.168.1.228
511 | 189 192.168.1.59
512 | 190 192.168.1.85
513 | 191 192.168.1.20
514 | 192 192.168.1.110
515 | 193 192.168.1.156
516 | 194 192.168.1.200
517 | 195 192.168.1.77
518 | 196 192.168.1.233
519 | 197 192.168.1.106
520 | 198 192.168.1.8
521 | 199 192.168.1.148
522 | 200 192.168.1.11
523 | 201 192.168.1.82
524 | 202 192.168.1.213
525 | 203 192.168.1.81
526 | 204 192.168.1.75
527 | 205 192.168.1.246
528 | 206 192.168.1.188
529 | 207 192.168.1.107
530 | 208 192.168.1.172
531 | 209 192.168.1.214
532 | 210 192.168.1.94
533 | 211 192.168.1.140
534 | 212 192.168.1.26
535 | 213 192.168.1.127
536 | 214 192.168.1.115
537 | 215 192.168.1.87
538 | 216 192.168.1.199
539 | 217 192.168.1.36
540 | 218 192.168.1.250
541 | 219 192.168.1.189
542 | 220 192.168.1.129
543 | 221 192.168.1.170
544 | 222 192.168.1.180
545 | 223 192.168.1.27
546 | 224 192.168.1.128
547 | 225 192.168.1.112
548 | 226 192.168.1.46
549 | 227 192.168.1.186
550 | 228 192.168.1.21
551 | 229 192.168.1.68
552 | 230 192.168.1.53
553 | 231 192.168.1.70
554 | 232 192.168.1.221
555 | 233 192.168.1.160
556 | 234 192.168.1.83
557 | 235 192.168.1.198
558 | 236 192.168.1.252
559 | 237 192.168.1.31
560 | 238 192.168.1.145
561 | 239 192.168.1.244
562 | 240 192.168.1.142
563 | 241 192.168.1.220
564 | 242 192.168.1.155
565 | 243 192.168.1.89
566 | 244 192.168.1.43
567 | 245 192.168.1.141
568 | 246 192.168.1.137
569 | 247 192.168.1.104
570 | 248 192.168.1.185
571 | 249 192.168.1.96
572 | 250 192.168.1.54
573 | 251 192.168.1.34
574 | 252 192.168.1.158
575 | 253 192.168.1.108
576 | 254 192.168.1.195
577 | 255 192.168.1.227
578 | 256 192.168.1.56
579 |
580 | Total of 256 host entries.
581 | _EOF_
582 | ARPARGS="--retry=1 --ouifile=$srcdir/ieee-oui.txt --macfile=$srcdir/mac-vendor.txt -v -v -v --random --randomseed=0xdeadbeef"
583 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 192.168.1.0/24 2>&1 | sed -n -e '/^Host List:/,/^Total of /p' > "$ARPSCANOUTPUT" 2>&1
584 | if test $? -ne 0; then
585 | rm -f "$ARPSCANOUTPUT"
586 | rm -f "$EXAMPLEOUTPUT"
587 | echo "FAILED"
588 | exit 1
589 | fi
590 | cmp -s "$ARPSCANOUTPUT" "$EXAMPLEOUTPUT"
591 | if test $? -ne 0; then
592 | rm -f "$ARPSCANOUTPUT"
593 | rm -f "$EXAMPLEOUTPUT"
594 | echo "FAILED"
595 | exit 1
596 | fi
597 | echo "ok"
598 | rm -f "$ARPSCANOUTPUT"
599 | rm -f "$EXAMPLEOUTPUT"
600 |
--------------------------------------------------------------------------------
/check-ieee-reg:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # arp-scan is Copyright (C) 2005-2025 Roy Hills
3 | #
4 | # This file is part of arp-scan.
5 | #
6 | # arp-scan is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # arp-scan is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with arp-scan. If not, see .
18 | #
19 | # check-ieee-reg - Shell script to test IEEE registry lookup
20 | #
21 | # Author: Roy Hills
22 | # Date: 01 November 2022
23 | #
24 | # This script checks that arp-scan correctly decodes and displays the vendor
25 | # details for selected entries in each of the IEEE Ethernet registries.
26 | #
27 |
28 | ARPSCANOUTPUT=/tmp/arp-scan-output.$$.tmp
29 | EXAMPLEOUTPUT=/tmp/example-output.$$.tmp
30 | #
31 | SAMPLE01="$srcdir/testdata/pkt-ieee-regcheck.pcap"
32 |
33 | # Responses from one MAC address in each of IAB, MA-M, MA-L and MA-S registries
34 | echo "Checking IEEE registry decode using $SAMPLE01 ..."
35 | cat >"$EXAMPLEOUTPUT" <<_EOF_
36 | 192.168.14.1,00:50:c2:7d:50:00,DEUTA-WERKE GmbH
37 | 192.168.14.2,74:1a:e0:90:00:00,Private
38 | 192.168.14.3,00:22:72:00:00:00,American Micro-Fuel Device Corp.
39 | 192.168.14.4,70:b3:d5:f2:f0:00,TELEPLATFORMS
40 |
41 | _EOF_
42 | ARPARGS="--retry=1 --ouifile=$srcdir/ieee-oui.txt --macfile=$srcdir/mac-vendor.txt --format=\${ip},\${mac},\${vendor}"
43 | ./arp-scan $ARPARGS --readpktfromfile="$SAMPLE01" 192.168.14.0/29 | grep -v '^Starting arp-scan ' | grep -v '^Interface: ' | grep -v '^Ending arp-scan ' | grep -v '^[0-9]* packets received ' > "$ARPSCANOUTPUT" 2>&1
44 | if test $? -ne 0; then
45 | rm -f "$ARPSCANOUTPUT"
46 | rm -f "$EXAMPLEOUTPUT"
47 | echo "FAILED"
48 | exit 1
49 | fi
50 | cmp -s "$ARPSCANOUTPUT" "$EXAMPLEOUTPUT"
51 | if test $? -ne 0; then
52 | rm -f "$ARPSCANOUTPUT"
53 | rm -f "$EXAMPLEOUTPUT"
54 | echo "FAILED"
55 | exit 1
56 | fi
57 | echo "ok"
58 | rm -f "$ARPSCANOUTPUT"
59 | rm -f "$EXAMPLEOUTPUT"
60 |
--------------------------------------------------------------------------------
/check-options:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # arp-scan is Copyright (C) 2005-2025 Roy Hills
3 | #
4 | # This file is part of arp-scan.
5 | #
6 | # arp-scan is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # arp-scan is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with arp-scan. If not, see .
18 | #
19 | # check-options -- Shell script to test arp-scan options
20 | #
21 | # Author: Roy Hills
22 | # Date: 9 November 2022
23 | #
24 | # This shell script checks various arp-scan options.
25 | #
26 | ARPSCANOUTPUT=/tmp/arp-scan-test.$$.tmp
27 | SAMPLE01="$srcdir/testdata/pkt-simple-response.pcap"
28 |
29 | # Check --bandwidth with multiple character "K" and --retry-send-interval with
30 | # appended multiple character "u".
31 | echo "Checking arp-scan --bandwidth ..."
32 | ARPARGS="--quiet --plain --retry=1 --bandwidth=256K --retry-send=1 --retry-send-interval=1000u --timeout=100 --backoff=1.0 --snap=128 --limit=1"
33 | ./arp-scan --readpktfromfile="$SAMPLE01" $ARPARGS 127.0.0.1 > "$ARPSCANOUTPUT"
34 | if test $? -ne 0; then
35 | rm -f "$ARPSCANOUTPUT"
36 | echo "FAILED"
37 | exit 1
38 | fi
39 | grep '^127.0.0.1 08:00:2b:06:07:08' "$ARPSCANOUTPUT" >/dev/null
40 | if test $? -ne 0; then
41 | rm -f "$ARPSCANOUTPUT"
42 | echo "FAILED"
43 | exit 1
44 | fi
45 | echo "ok"
46 | rm -f "$ARPSCANOUTPUT"
47 |
48 | # Check --bandwidth with appended multiple character "M"
49 | echo "Checking arp-scan --bandwidth with M multiple..."
50 | ARPARGS="--quiet --plain --retry=1 --bandwidth=1M"
51 | ./arp-scan --readpktfromfile="$SAMPLE01" $ARPARGS 127.0.0.1 > "$ARPSCANOUTPUT"
52 | if test $? -ne 0; then
53 | rm -f "$ARPSCANOUTPUT"
54 | echo "FAILED"
55 | exit 1
56 | fi
57 | grep '^127.0.0.1 08:00:2b:06:07:08' "$ARPSCANOUTPUT" >/dev/null
58 | if test $? -ne 0; then
59 | rm -f "$ARPSCANOUTPUT"
60 | echo "FAILED"
61 | exit 1
62 | fi
63 | echo "ok"
64 | rm -f "$ARPSCANOUTPUT"
65 |
66 | # Check --interval with appended multiple character "S"
67 | echo "Checking arp-scan --interval ..."
68 | ARPARGS="--quiet --plain --retry=1 --interval=1S"
69 | ./arp-scan --readpktfromfile="$SAMPLE01" $ARPARGS 127.0.0.1 > "$ARPSCANOUTPUT"
70 | if test $? -ne 0; then
71 | rm -f "$ARPSCANOUTPUT"
72 | echo "FAILED"
73 | exit 1
74 | fi
75 | grep '^127.0.0.1 08:00:2b:06:07:08' "$ARPSCANOUTPUT" >/dev/null
76 | if test $? -ne 0; then
77 | rm -f "$ARPSCANOUTPUT"
78 | echo "FAILED"
79 | exit 1
80 | fi
81 | echo "ok"
82 | rm -f "$ARPSCANOUTPUT"
83 |
84 | # Check --arpspa=dest
85 | echo "Checking arp-scan --arpspa=dest ..."
86 | ARPARGS="--quiet --plain --retry=1 --arpspa=dest"
87 | ./arp-scan --readpktfromfile="$SAMPLE01" $ARPARGS 127.0.0.1 > "$ARPSCANOUTPUT"
88 | if test $? -ne 0; then
89 | rm -f "$ARPSCANOUTPUT"
90 | echo "FAILED"
91 | exit 1
92 | fi
93 | grep '^127.0.0.1 08:00:2b:06:07:08' "$ARPSCANOUTPUT" >/dev/null
94 | if test $? -ne 0; then
95 | rm -f "$ARPSCANOUTPUT"
96 | echo "FAILED"
97 | exit 1
98 | fi
99 | echo "ok"
100 | rm -f "$ARPSCANOUTPUT"
101 |
102 | # Check --random without explicit --randomseed value
103 | echo "Checking arp-scan --random ..."
104 | ARPARGS="--quiet --plain --retry=1 --random"
105 | ./arp-scan --readpktfromfile="$SAMPLE01" $ARPARGS 127.0.0.1 > "$ARPSCANOUTPUT"
106 | if test $? -ne 0; then
107 | rm -f "$ARPSCANOUTPUT"
108 | echo "FAILED"
109 | exit 1
110 | fi
111 | grep '^127.0.0.1 08:00:2b:06:07:08' "$ARPSCANOUTPUT" >/dev/null
112 | if test $? -ne 0; then
113 | rm -f "$ARPSCANOUTPUT"
114 | echo "FAILED"
115 | exit 1
116 | fi
117 | echo "ok"
118 | rm -f "$ARPSCANOUTPUT"
119 |
--------------------------------------------------------------------------------
/check-packet:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # arp-scan is Copyright (C) 2005-2025 Roy Hills
3 | #
4 | # This file is part of arp-scan.
5 | #
6 | # arp-scan is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # arp-scan is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with arp-scan. If not, see .
18 | #
19 | # check-packet - Shell script to test arp-scan packet creation
20 | #
21 | # Author: Roy Hills
22 | # Date: 30 January 2011
23 | #
24 | # This script checks that arp-scan builds ARP request packets correctly.
25 | # It uses the undocumented arp-scan option --writepkttofile to write the
26 | # packet to a file rather than sending it via the network.
27 | #
28 |
29 | TMPFILE=/tmp/arp-scan-test.$$.tmp
30 | #
31 | SAMPLE01="$srcdir/testdata/pkt-simple-request.dat"
32 | SAMPLE02="$srcdir/testdata/pkt-custom-request.dat"
33 | SAMPLE03="$srcdir/testdata/pkt-custom-request-padding.dat"
34 | SAMPLE04="$srcdir/testdata/pkt-custom-request-llc.dat"
35 | SAMPLE05="$srcdir/testdata/pkt-custom-request-vlan.dat"
36 | SAMPLE06="$srcdir/testdata/pkt-custom-request-vlan-llc.dat"
37 |
38 | echo "Checking simple ARP request packet against $SAMPLE01 ..."
39 | ARPARGS="--retry=1 --file=- --srcaddr=00:01:02:03:04:05 --arpsha=00:01:02:03:04:05 --arpspa=127.0.0.1"
40 | echo "127.0.0.1" | ./arp-scan $ARPARGS --writepkttofile="$TMPFILE" >/dev/null 2>&1
41 | if test $? -ne 0; then
42 | rm -f "$TMPFILE"
43 | echo "FAILED"
44 | exit 1
45 | fi
46 | cmp -s "$TMPFILE" "$SAMPLE01"
47 | if test $? -ne 0; then
48 | rm -f "$TMPFILE"
49 | echo "FAILED"
50 | exit 1
51 | fi
52 | echo "ok"
53 | rm -f "$TMPFILE"
54 |
55 | echo "Checking custom ARP request packet against $SAMPLE02 ..."
56 | ARPARGS="--retry=1 --file=- --destaddr=11:11:11:11:11:11 --srcaddr=22:22:22:22:22:22 --prototype=0x3333 --arphrd=0x4444 --arppro=0x5555 --arphln=0x66 --arppln=0x77 --arpop=0x8888 --arpsha=99:99:99:99:99:99 --arpspa=170.170.170.170 --arptha=bb:bb:bb:bb:bb:bb"
57 | echo "204.204.204.204" | ./arp-scan $ARPARGS --writepkttofile="$TMPFILE" >/dev/null 2>&1
58 | if test $? -ne 0; then
59 | rm -f "$TMPFILE"
60 | echo "FAILED"
61 | exit 1
62 | fi
63 | cmp -s "$TMPFILE" "$SAMPLE02"
64 | if test $? -ne 0; then
65 | rm -f "$TMPFILE"
66 | echo "FAILED"
67 | exit 1
68 | fi
69 | echo "ok"
70 | rm -f "$TMPFILE"
71 |
72 | echo "Checking custom ARP request packet with padding against $SAMPLE03 ..."
73 | ARPARGS="--retry=1 --file=- --destaddr=11:11:11:11:11:11 --srcaddr=22:22:22:22:22:22 --prototype=0x3333 --arphrd=0x4444 --arppro=0x5555 --arphln=0x66 --arppln=0x77 --arpop=0x8888 --arpsha=99:99:99:99:99:99 --arpspa=170.170.170.170 --arptha=bb:bb:bb:bb:bb:bb --padding=dddddddddddddddd"
74 | echo "204.204.204.204" | ./arp-scan $ARPARGS --writepkttofile="$TMPFILE" >/dev/null 2>&1
75 | if test $? -ne 0; then
76 | rm -f "$TMPFILE"
77 | echo "FAILED"
78 | exit 1
79 | fi
80 | cmp -s "$TMPFILE" "$SAMPLE03"
81 | if test $? -ne 0; then
82 | rm -f "$TMPFILE"
83 | echo "FAILED"
84 | exit 1
85 | fi
86 | echo "ok"
87 | rm -f "$TMPFILE"
88 |
89 | echo "Checking custom ARP request packet with LLC/SNAP framing against $SAMPLE04 ..."
90 | ARPARGS="--retry=1 --file=- --destaddr=11:11:11:11:11:11 --srcaddr=22:22:22:22:22:22 --prototype=0x3333 --arphrd=0x4444 --arppro=0x5555 --arphln=0x66 --arppln=0x77 --arpop=0x8888 --arpsha=99:99:99:99:99:99 --arpspa=170.170.170.170 --arptha=bb:bb:bb:bb:bb:bb --llc"
91 | echo "204.204.204.204" | ./arp-scan $ARPARGS --writepkttofile="$TMPFILE" >/dev/null 2>&1
92 | if test $? -ne 0; then
93 | rm -f "$TMPFILE"
94 | echo "FAILED"
95 | exit 1
96 | fi
97 | cmp -s "$TMPFILE" "$SAMPLE04"
98 | if test $? -ne 0; then
99 | rm -f "$TMPFILE"
100 | echo "FAILED"
101 | exit 1
102 | fi
103 | echo "ok"
104 | rm -f "$TMPFILE"
105 |
106 | echo "Checking custom ARP request packet with VLAN tag against $SAMPLE05 ..."
107 | ARPARGS="--retry=1 --file=- --destaddr=11:11:11:11:11:11 --srcaddr=22:22:22:22:22:22 --prototype=0x3333 --arphrd=0x4444 --arppro=0x5555 --arphln=0x66 --arppln=0x77 --arpop=0x8888 --arpsha=99:99:99:99:99:99 --arpspa=170.170.170.170 --arptha=bb:bb:bb:bb:bb:bb --vlan=0xddd"
108 | echo "204.204.204.204" | ./arp-scan $ARPARGS --writepkttofile="$TMPFILE" >/dev/null 2>&1
109 | if test $? -ne 0; then
110 | rm -f "$TMPFILE"
111 | echo "FAILED"
112 | exit 1
113 | fi
114 | cmp -s "$TMPFILE" "$SAMPLE05"
115 | if test $? -ne 0; then
116 | rm -f "$TMPFILE"
117 | echo "FAILED"
118 | exit 1
119 | fi
120 | echo "ok"
121 | rm -f "$TMPFILE"
122 |
123 | echo "Checking custom ARP request packet with VLAN tag and LLC/SNAP framing against $SAMPLE06 ..."
124 | ARPARGS="--retry=1 --file=- --destaddr=11:11:11:11:11:11 --srcaddr=22:22:22:22:22:22 --prototype=0x3333 --arphrd=0x4444 --arppro=0x5555 --arphln=0x66 --arppln=0x77 --arpop=0x8888 --arpsha=99:99:99:99:99:99 --arpspa=170.170.170.170 --arptha=bb:bb:bb:bb:bb:bb --vlan=0xddd --llc"
125 | echo "204.204.204.204" | ./arp-scan $ARPARGS --writepkttofile="$TMPFILE" >/dev/null 2>&1
126 | if test $? -ne 0; then
127 | rm -f "$TMPFILE"
128 | echo "FAILED"
129 | exit 1
130 | fi
131 | cmp -s "$TMPFILE" "$SAMPLE06"
132 | if test $? -ne 0; then
133 | rm -f "$TMPFILE"
134 | echo "FAILED"
135 | exit 1
136 | fi
137 | echo "ok"
138 | rm -f "$TMPFILE"
139 |
--------------------------------------------------------------------------------
/check-run1:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # arp-scan is Copyright (C) 2005-2025 Roy Hills
3 | #
4 | # This file is part of arp-scan.
5 | #
6 | # arp-scan is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # arp-scan is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with arp-scan. If not, see .
18 | #
19 | # check-run1 -- Shell script to test arp-scan basic functionality
20 | #
21 | # Author: Roy Hills
22 | # Date: 9 March 2006
23 | #
24 | # This shell script checks that "arp-scan --help" and "arp-scan --version"
25 | # work. These options don't use much of the arp-scan functionality, so if
26 | # they fail, then there is a fundamental problem with the program.
27 | #
28 | ARPSCANOUTPUT=/tmp/arp-scan-test.$$.tmp
29 |
30 | # Check arp-scan --help
31 | echo "Checking arp-scan --help ..."
32 | ./arp-scan --help > "$ARPSCANOUTPUT"
33 | if test $? -ne 0; then
34 | rm -f "$ARPSCANOUTPUT"
35 | echo "FAILED"
36 | exit 1
37 | fi
38 | grep '^Report bugs or send suggestions at ' "$ARPSCANOUTPUT" >/dev/null
39 | if test $? -ne 0; then
40 | rm -f "$ARPSCANOUTPUT"
41 | echo "FAILED"
42 | exit 1
43 | fi
44 | echo "ok"
45 | rm -f "$ARPSCANOUTPUT"
46 |
47 | # Check arp-scan --version
48 | echo "Checking arp-scan --version ..."
49 | ./arp-scan --version > "$ARPSCANOUTPUT"
50 | if test $? -ne 0; then
51 | rm -f "$ARPSCANOUTPUT"
52 | echo "FAILED"
53 | exit 1
54 | fi
55 | grep '^Copyright (C) ' "$ARPSCANOUTPUT" >/dev/null
56 | if test $? -ne 0; then
57 | rm -f "$ARPSCANOUTPUT"
58 | echo "FAILED"
59 | exit 1
60 | fi
61 | echo "ok"
62 | rm -f "$ARPSCANOUTPUT"
63 |
--------------------------------------------------------------------------------
/configure.ac:
--------------------------------------------------------------------------------
1 | # Process this file with autoconf to produce a configure script.
2 |
3 | AC_INIT([arp-scan],[1.10.1-git],[https://github.com/royhills/arp-scan])
4 | AC_PREREQ([2.70])
5 | AC_CONFIG_SRCDIR([arp-scan.c])
6 | AC_CONFIG_AUX_DIR([build-aux])
7 | AC_CONFIG_MACRO_DIRS([m4])
8 | AM_INIT_AUTOMAKE
9 |
10 | AC_CONFIG_HEADERS([config.h])
11 |
12 | AC_CANONICAL_HOST
13 |
14 | # Define the appropriate compiler flags if the user has enabled gcov
15 | # code coverage. We do this before calling AC_PROG_CC because we override
16 | # the default compiler options when running with gcov.
17 | AC_MSG_CHECKING([if gcov code coverage is enabled])
18 | AC_ARG_ENABLE(gcov,
19 | AS_HELP_STRING([--enable-gcov],[enable gcov code coverage analysis]),
20 | [
21 | if test "x$enableval" != "xno" ; then
22 | AC_MSG_RESULT(yes)
23 | CFLAGS="-O0 -g -fno-inline -fprofile-arcs -ftest-coverage"
24 | else
25 | AC_MSG_RESULT(no)
26 | fi
27 | ],
28 | [
29 | AC_MSG_RESULT(no)
30 | ] )
31 |
32 | # Check for utility programs that we need.
33 | AC_PROG_SED
34 | AC_PROG_CC
35 | # Ensure the C compiler supports the C99 standard.
36 | if test "x$ac_cv_prog_cc_c99" = "xno"; then
37 | AC_MSG_ERROR([C compiler does not support C99 standard])
38 | fi
39 | # Add additional options if the C compiler identifies as GCC.
40 | # This applies to Clang/LLVM in addition to GCC.
41 | if test -n "$GCC"; then
42 | AC_DEFINE([ATTRIBUTE_UNUSED], [__attribute__ ((__unused__))],
43 | [Define to the compiler's unused pragma])
44 | CFLAGS="$CFLAGS -Wall -Wextra -Wformat-security -Wshadow -Wwrite-strings"
45 | GCC_STACK_PROTECT_CC
46 | GCC_FORTIFY_SOURCE
47 | # Uncomment the line below to compile with additional warnings enabled.
48 | # CFLAGS="$CFLAGS -pedantic -Wpointer-arith -Wcast-qual -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs"
49 | else
50 | AC_DEFINE([ATTRIBUTE_UNUSED], [],
51 | [Define to the compiler's unused pragma])
52 | fi
53 | AC_PROG_INSTALL
54 |
55 | # Checks for libraries.
56 | # Only Solaris 10 needs -lnsl for gethostbyname() and -lsocket for socket().
57 | # Everything needs -lpcap for pcap_open_live() and other functions.
58 | AC_SEARCH_LIBS([gethostbyname], [nsl])
59 | AC_SEARCH_LIBS([socket], [socket])
60 | AC_SEARCH_LIBS([pcap_open_live], [pcap], ,
61 | [
62 | AC_MSG_NOTICE([Cannot find pcap library containing pcap_open_live])
63 | AC_MSG_ERROR([Check that you have libpcap version 1.5 or later installed])
64 | ])
65 |
66 | # Check that the pcap library contains pcap_set_immediate_mode()
67 | # This was introduced in libpcap version 1.5, and the application requires it.
68 | #
69 | # We perform this check as a separate step, rather than just checking for
70 | # pcap_lib_version in the earlier AC_SEARCH_LIBS call, because it
71 | # allows us to provide different error messages for missing pcap and non
72 | # functional pcap and so avoids confusing generic error messages.
73 | #
74 | AC_MSG_CHECKING([for a compatible pcap library with pcap_set_immediate_mode])
75 | AC_LINK_IFELSE([AC_LANG_CALL([], [pcap_set_immediate_mode])],
76 | [AC_MSG_RESULT([yes])],
77 | [
78 | AC_MSG_RESULT([no])
79 | AC_MSG_NOTICE([Cannot find pcap_set_immediate_mode in pcap library])
80 | AC_MSG_ERROR([Check that the pcap library is at least version 1.5])
81 | ])
82 |
83 | # Check for libcap POSIX.1e capability support
84 | CHECK_LIBCAP
85 |
86 | # Checks for header files.
87 |
88 | # Check for C POSIX library header files
89 | AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h sys/socket.h sys/time.h unistd.h sys/stat.h fcntl.h search.h regex.h])
90 |
91 | # Check for other required header files
92 | AC_CHECK_HEADERS([getopt.h pcap.h sys/ioctl.h ifaddrs.h])
93 |
94 | # Checks for typedefs, structures, and compiler characteristics.
95 | AC_TYPE_SIZE_T
96 |
97 | # Checks for library functions.
98 | # All of these are defined by POSIX
99 | AC_CHECK_FUNCS([malloc gethostbyname gettimeofday inet_ntoa memset select socket strerror])
100 | # These functions might not be present on all systems
101 | AC_CHECK_FUNCS([getifaddrs pledge])
102 |
103 | #
104 | # Determine link-layer implementation to use based on the $host_os variable
105 | #
106 | case $host_os in
107 | *linux* )
108 | AC_MSG_NOTICE([Using packet socket link layer implementation.])
109 | AC_CHECK_HEADERS([netpacket/packet.h net/if.h])
110 | AC_LIBOBJ([link-packet-socket])
111 | ;;
112 | *freebsd* | *darwin* | *openbsd* | *netbsd* | *dragonfly* )
113 | AC_MSG_NOTICE([Using BPF link layer implementation.])
114 | # We need to specify additional headers to include here, because several
115 | # BSD variants require certain headers to be included before others will
116 | # work.
117 | # FreeBSD 5.2 needs sys/socket.h included for net/if, and
118 | # needs sys/types.h for sys/sysctl.h and net/bpf.h
119 | # OpenBSD 3.9 needs sys/param.h included for sys/sysctl.h
120 | AC_CHECK_HEADERS([net/if.h sys/param.h sys/sysctl.h net/route.h net/if_dl.h],,,
121 | [
122 | #include
123 | #ifdef HAVE_SYS_SOCKET_H
124 | #include
125 | #endif
126 | #ifdef HAVE_SYS_PARAM_H
127 | #include
128 | #endif
129 | ])
130 | AC_LIBOBJ([link-bpf])
131 | ;;
132 | *solaris* )
133 | AC_MSG_NOTICE([Using DLPI link layer implementation.])
134 | AC_MSG_NOTICE([NOTE: This works on Solaris 8,9 and 10 but fails on Solaris 11.])
135 | # Solaris 9 needs sys/types.h and sys/socket.h included before net/if.h.
136 | AC_CHECK_HEADERS([sys/dlpi.h sys/dlpihdr.h stropts.h sys/ioctl.h sys/sockio.h net/if.h sys/bufmod.h],,,
137 | [
138 | #include
139 | #ifdef HAVE_SYS_SOCKET_H
140 | #include
141 | #endif
142 | ])
143 | AC_LIBOBJ([link-dlpi])
144 | ;;
145 | * )
146 | AC_MSG_ERROR([Host operating system $host_os is not supported])
147 | ;;
148 | esac
149 |
150 | # Linux and most BSD systems have getopt_long_only, but NetBSD 7.0 doesn't.
151 | # Use the my_getopt.c implementation for systems that don't have it.
152 | AC_CHECK_FUNC([getopt_long_only],
153 | [AC_DEFINE(HAVE_GETOPT_LONG_ONLY, 1, [Define to 1 if the C library includes getopt_long_only])],
154 | [ AC_LIBOBJ([my_getopt])
155 | AC_LIBSOURCE([my_getopt.h]) ])
156 |
157 | # Check for strlcpy. If we don't have it, use the replacement function
158 | # from OpenBSD. This is needed for systems using glibc.
159 | AC_CHECK_FUNC([strlcpy],
160 | [AC_DEFINE(HAVE_STRLCPY, 1, [Define to 1 if the C library includes the strlcpy function])],
161 | [ AC_LIBOBJ([strlcpy])
162 | AC_LIBSOURCE([strlcpy.h]) ])
163 |
164 | AC_CONFIG_FILES([Makefile])
165 | AC_OUTPUT
166 |
--------------------------------------------------------------------------------
/error.c:
--------------------------------------------------------------------------------
1 | /*
2 | * arp-scan is Copyright (C) 2005-2025 Roy Hills
3 | *
4 | * This file is part of arp-scan.
5 | *
6 | * arp-scan is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * arp-scan is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with arp-scan. If not, see .
18 | *
19 | * error.c -- error routines for arp-scan
20 | *
21 | * Author: Roy Hills
22 | * Date: 1 December 2001
23 | */
24 |
25 | #include "arp-scan.h"
26 |
27 | int daemon_proc; /* Non-zero if process is a daemon */
28 |
29 | /*
30 | * Function to handle fatal system call errors.
31 | */
32 | void
33 | err_sys(const char *fmt,...) {
34 | va_list ap;
35 |
36 | va_start(ap, fmt);
37 | err_print(1, fmt, ap);
38 | va_end(ap);
39 | exit(EXIT_FAILURE);
40 | }
41 |
42 | /*
43 | * Function to handle non-fatal system call errors.
44 | */
45 | void
46 | warn_sys(const char *fmt,...) {
47 | va_list ap;
48 |
49 | va_start(ap, fmt);
50 | err_print(1, fmt, ap);
51 | va_end(ap);
52 | }
53 |
54 | /*
55 | * Function to handle fatal errors not from system calls.
56 | */
57 | void
58 | err_msg(const char *fmt,...) {
59 | va_list ap;
60 |
61 | va_start(ap, fmt);
62 | err_print(0, fmt, ap);
63 | va_end(ap);
64 | exit(EXIT_FAILURE);
65 | }
66 |
67 | /*
68 | * Function to handle non-fatal errors not from system calls.
69 | */
70 | void
71 | warn_msg(const char *fmt,...) {
72 | va_list ap;
73 |
74 | va_start(ap, fmt);
75 | err_print(0, fmt, ap);
76 | va_end(ap);
77 | }
78 |
79 | /*
80 | * General error printing function used by all the above
81 | * functions.
82 | */
83 | void
84 | err_print (int errnoflag, const char *fmt, va_list ap) {
85 | int n = 0;
86 | size_t size = 0;
87 | int errno_save;
88 | char *buf;
89 | va_list ap_copy;
90 | char *cp;
91 |
92 | errno_save=errno;
93 | /*
94 | * Determine required size for the resultant string using copy
95 | * arg ptr.
96 | */
97 | va_copy(ap_copy, ap);
98 | n = vsnprintf(NULL, 0, fmt, ap_copy);
99 | va_end(ap_copy);
100 | if (n < 0)
101 | return; /* vsnprintf output error */
102 |
103 | size = (size_t) n + 1; /* One extra byte for '\0' */
104 |
105 | buf = Malloc(size);
106 |
107 | vsnprintf(buf, size, fmt, ap);
108 | size=strlen(buf);
109 | cp = buf;
110 | if (errnoflag) {
111 | buf = make_message("%s: %s\n", cp, strerror(errno_save));
112 | } else {
113 | buf = make_message("%s\n", cp);
114 | }
115 | free(cp);
116 |
117 | fflush(stdout); /* In case stdout and stderr are the same */
118 | fputs(buf, stderr);
119 | fflush(stderr);
120 | }
121 |
--------------------------------------------------------------------------------
/format.c:
--------------------------------------------------------------------------------
1 | /*
2 | * arp-scan is Copyright (C) 2005-2025 Roy Hills
3 | *
4 | * This file is part of arp-scan.
5 | *
6 | * arp-scan is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * arp-scan is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with arp-scan. If not, see .
18 | *
19 | * You are encouraged to send comments, improvements or suggestions
20 | * at the github repository https://github.com/royhills/arp-scan
21 | *
22 | * Author: Roy Hills
23 | * Date: 24 October 2022
24 | *
25 | * This file contains output format functions, which were adapted
26 | * from the dpkg Debian package formatting functions in pkg-format.c.
27 | */
28 |
29 | #include "arp-scan.h"
30 |
31 | static format_element *
32 | format_element_new(void) {
33 | format_element *buf;
34 |
35 | buf = Malloc(sizeof(*buf));
36 | buf->type = FORMAT_INVALID;
37 | buf->next = NULL;
38 | buf->data = NULL;
39 | buf->width = 0;
40 |
41 | return buf;
42 | }
43 |
44 | static void
45 | parsefield(format_element *node, const char *fmt, const char *fmtend) {
46 |
47 | int len;
48 | const char *ws;
49 |
50 | len = fmtend - fmt + 1;
51 |
52 | ws = memchr(fmt, ';', len);
53 | if (ws) {
54 | char *endptr;
55 | long w;
56 |
57 | errno = 0;
58 | w = strtol(ws + 1, &endptr, 0);
59 | if (endptr[0] != '}') {
60 | err_msg("ERROR: incorrect format string: invalid character \"%c\" in "
61 | "field width", *endptr);
62 | }
63 | if (w < INT_MIN || w > INT_MAX || errno == ERANGE) {
64 | err_msg("ERROR: incorrect format string: field width out of range");
65 | }
66 |
67 | node->width = w;
68 | len = ws - fmt;
69 | }
70 |
71 | node->type = FORMAT_FIELD;
72 | node->data = Malloc(len + 1);
73 | memcpy(node->data, fmt, len);
74 | node->data[len] = '\0';
75 | }
76 |
77 | static void
78 | parsestring(format_element *node, const char *fmt, const char *fmtend) {
79 |
80 | int len;
81 | char *write;
82 |
83 | len = fmtend - fmt + 1;
84 |
85 | node->type = FORMAT_STRING;
86 | node->data = write = Malloc(len + 1);
87 |
88 | while (fmt <= fmtend) {
89 | if (*fmt == '\\') {
90 | fmt++;
91 | switch (*fmt) {
92 | case 'n':
93 | *write = '\n';
94 | break;
95 | case 't':
96 | *write = '\t';
97 | break;
98 | case 'r':
99 | *write = '\r';
100 | break;
101 | case '\\':
102 | default:
103 | *write = *fmt;
104 | break;
105 | }
106 | } else {
107 | *write = *fmt;
108 | }
109 | write++;
110 | fmt++;
111 | }
112 | *write = '\0';
113 | }
114 |
115 | format_element *
116 | format_parse(const char *fmt) {
117 |
118 | format_element *head, *node;
119 | const char *fmtend;
120 | const char *cp;
121 |
122 | head = node = NULL;
123 |
124 | while (*fmt) {
125 | if (node)
126 | node = node->next = format_element_new();
127 | else
128 | head = node = format_element_new();
129 |
130 | if (fmt[0] == '$' && fmt[1] == '{') { /* Field starting ${ */
131 | fmtend = strchr(fmt, '}'); /* Check for closing brace */
132 | if (!fmtend)
133 | err_msg("ERROR: incorrect format string: missing closing brace");
134 | parsefield(node, fmt + 2, fmtend - 1);
135 | fmt = fmtend + 1;
136 | } else { /* Not a field so presumably a string */
137 | fmtend = fmt;
138 | do {
139 | fmtend += 1;
140 | cp = strchr(fmtend, '$');
141 | if (!cp)
142 | fmtend = strchr(fmtend, '\0');
143 | } while (fmtend[0] && fmtend[1] != '{');
144 |
145 | parsestring(node, fmt, fmtend - 1);
146 | fmt = fmtend;
147 | }
148 | }
149 |
150 | if (!head)
151 | err_msg("ERROR: output format may not be empty string");
152 |
153 | return head;
154 | }
155 |
--------------------------------------------------------------------------------
/get-oui:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env perl
2 | #
3 | # Copyright 2006-2025 Roy Hills
4 | #
5 | # This file is part of arp-scan.
6 | #
7 | # arp-scan is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 3 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # arp-scan is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # You should have received a copy of the GNU General Public License
18 | # along with arp-scan. If not, see .
19 | #
20 | # get-oui -- Fetch the MAC/Vendor registry data from the IEEE website
21 | #
22 | # Author: Roy Hills
23 | # Date: 16 March 2006
24 | #
25 | # This script downloads the Ethernet MAC/Vendor registry data from the
26 | # IEEE website, and converts it to the format used by arp-scan.
27 | #
28 | use warnings;
29 | use strict;
30 | use Getopt::Std;
31 | use LWP::UserAgent;
32 | use Text::CSV;
33 | #
34 | # Use the file:// URLs to use the data from the debian ieee-data package.
35 | # Use the http:// URLs to use the data from the IEEE website.
36 | #
37 | # The entries will be written to the output in alphabetical key order, not
38 | # the order they are listed in the hash.
39 | my %ieee_reg_urls = (
40 | # OUI => 'file:///usr/share/ieee-data/oui.csv',
41 | # MAM => 'file:///usr/share/ieee-data/mam.csv',
42 | # OUI36 => 'file:///usr/share/ieee-data/oui36.csv',
43 | # IAB => 'file:///usr/share/ieee-data/iab.csv',
44 | OUI => 'https://standards-oui.ieee.org/oui/oui.csv',
45 | MAM => 'https://standards-oui.ieee.org/oui28/mam.csv',
46 | OUI36 => 'https://standards-oui.ieee.org/oui36/oui36.csv',
47 | IAB => 'https://standards-oui.ieee.org/iab/iab.csv'
48 | );
49 | my $default_filename='ieee-oui.txt';
50 | #
51 | my $usage =
52 | qq/Usage: get-oui [options]
53 | Fetch the Ethernet MAC-Vendor registry data from the IEEE website
54 | and save it in the format used by arp-scan.
55 |
56 | 'options' is one or more of:
57 | -h Display this usage message.
58 | -f FILE Specify the output file. Default=$default_filename
59 | -v Give verbose progress messages.
60 | /;
61 | my %opts;
62 | my $verbose;
63 | my $filename;
64 | my $url;
65 | my $key;
66 | my $status;
67 | my $line;
68 | my @columns;
69 | my $lineno;
70 | my $total_entries=0;
71 | #
72 | # Process options
73 | #
74 | die "$usage\n" unless getopts('hf:u:v',\%opts);
75 | if ($opts{h}) {
76 | print "$usage\n";
77 | exit(0);
78 | }
79 | if (defined $opts{f}) {
80 | $filename=$opts{f};
81 | } else {
82 | $filename=$default_filename;
83 | }
84 | $verbose=$opts{v} ? 1 : 0;
85 | #
86 | # If the output filename already exists, rename it to filename.bak before
87 | # we create the new output file.
88 | #
89 | if (-f $filename) {
90 | print "Renaming $filename to $filename.bak\n" if $verbose;
91 | rename $filename, "$filename.bak" || die "Could not rename $filename to $filename.bak\n";
92 | }
93 | #
94 | # Open the output file for writing.
95 | #
96 | print "Opening $filename for output\n" if $verbose;
97 | open OUTPUT, '>:encoding(UTF-8)', $filename || die "Could not open $filename for writing";
98 | #
99 | # Write the header comments to the output file.
100 | #
101 | my ($sec,$min,$hour,$mday,$mon,$year,undef,undef,undef) = localtime();
102 | $year += 1900;
103 | $mon++;
104 | my $date_string = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday,
105 | $hour, $min, $sec);
106 | my $header_comments =
107 | qq/# ieee-oui.txt -- IEEE Ethernet OUI-Vendor mapping file for arp-scan
108 | #
109 | # This file contains the IEEE Ethernet MAC address registry entries that are
110 | # used to determine the Ethernet vendor for a given MAC address.
111 | #
112 | # Each line of this file contains an OUI-vendor mapping in the form:
113 | #
114 | #
115 | #
116 | # Where is the prefix of the MAC address in hex, and
117 | # is the name of the vendor. The prefix can be of any length from two hex
118 | # digits (one octet) to twelve hex digits (six octets, the entire Ethernet
119 | # hardware address).
120 | #
121 | # The order of entries in this file are not important.
122 | #
123 | # arp-scan will attempt to match larger prefixes before trying to match
124 | # smaller ones, and will stop at the first match.
125 | #
126 | # Blank lines and lines beginning with "#" are ignored.
127 | #
128 | # This file was automatically generated by get-oui at $date_string
129 | #
130 | # Do not edit this file. If you want to add additional MAC-Vendor mappings,
131 | # edit the file mac-vendor.txt instead.
132 | #
133 | /;
134 | print OUTPUT $header_comments;
135 | #
136 | # Initialise Text::CSV object interface
137 | #
138 | my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1 });
139 | #
140 | # For each IEEE registry URL...
141 | #
142 | foreach $key (sort keys %ieee_reg_urls) {
143 | $url = $ieee_reg_urls{$key};
144 | #
145 | # Fetch the content from the URL
146 | #
147 | print "Processing IEEE $key registry data from $url\n" if $verbose;
148 | my $ua = LWP::UserAgent->new;
149 | # Set the HTTP User Agent to mimic Chrome on Windows 10/X64 because the IEEE
150 | # site rejects requests with the default libwww-perl UA string.
151 | # See https://github.com/royhills/arp-scan/issues/165
152 | $ua->agent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36');
153 | my $res = $ua->get($url);
154 | die $res->status_line unless $res->is_success;
155 | my $content = $res->content;
156 | my $content_length = length($content);
157 | die "Zero-sized response from from $url\n" unless ($content_length > 0);
158 | print "\tDownloaded $content_length bytes\n" if $verbose;
159 | #
160 | # Parse content and write MAC and Vendor fields to output file.
161 | #
162 | open(my $fh, '<:encoding(UTF-8)', \$content) || die "Could not open handle to content";
163 | $csv->header($fh);
164 | print OUTPUT "\n#\n# Start of IEEE $key registry data\n#\n";
165 | $lineno=0;
166 | while (my $row = $csv->getline ($fh)) {
167 | my $mac = ${$row}[1];
168 | my $vendor = ${$row}[2];
169 | $vendor =~ s/^\s+|\s+$//g; # Remove leading and trailing whitespace
170 | print OUTPUT "$mac\t$vendor\n";
171 | $lineno++;
172 | }
173 | print OUTPUT "#\n# End of IEEE $key registry data. $lineno entries.\n#\n";
174 | print "\t$lineno $key entries written to $filename\n" if $verbose;
175 | $total_entries += $lineno;
176 | }
177 | #
178 | # All done. Close the output file and print OUI entry count
179 | #
180 | close OUTPUT || die "Error closing output file\n";
181 | print "\nTotal of $total_entries MAC/Vendor mappings written to $filename\n";
182 |
--------------------------------------------------------------------------------
/get-oui.1.dist:
--------------------------------------------------------------------------------
1 | .\" Copyright (C) Roy Hills
2 | .\"
3 | .\" Copying and distribution of this file, with or without modification,
4 | .\" are permitted in any medium without royalty provided the copyright
5 | .\" notice and this notice are preserved.
6 | .\"
7 | .TH GET-OUI 1 "October 28, 2022"
8 | .\" Please adjust this date whenever revising the man page.
9 | .SH NAME
10 | get-oui \- Fetch the arp-scan OUI file from the IEEE website
11 | .SH SYNOPSIS
12 | .B get-oui
13 | .RI [ options ]
14 | .SH DESCRIPTION
15 | .B get-oui
16 | fetches the MAC/Vendor registry data from the IEEE website
17 | and converts it to the format used by arp-scan. The contents of
18 | the following registries are downloaded and processed:
19 | .sp
20 | .TS
21 | L L L .
22 | MA-L 24-bit The original OUI registry
23 | MA-M 28-bit Medium address block registry
24 | MA-S 36-bit Small address block registry (OUI-36)
25 | IAB 36-bit The IAB registry (closed for new applications)
26 | .TE
27 | .PP
28 | This script creates
29 | .I ieee-oui.txt
30 | from the latest data on the IEEE website.
31 | You can run
32 | .B get-oui
33 | occasionally to keep the OUI file up to date.
34 | .PP
35 | The OUI data is fetched from the URLs specified in the \fBget-oui\fP script
36 | and the output file is saved to the file
37 | .I ieee-oui.txt
38 | in the current directory.
39 | The output file name can be changed with the
40 | .B -f
41 | option.
42 | .PP
43 | The
44 | .I ieee-oui.txt
45 | file that is produced by this script is used by
46 | .B arp-scan
47 | to determine the Ethernet card vendor from its hardware address.
48 | .PP
49 | .B arp-scan
50 | will first look for
51 | .I ieee-oui.txt
52 | in the current directory. If that fails, it will use the system wide file
53 | \fI@PKGDATADIR@/ieee-oui.txt\fP.
54 | .SH OPTIONS
55 | .TP
56 | .B -h
57 | Display a brief usage message and exit.
58 | .TP
59 | \fB-f \fI\fR
60 | Write the output to the specified file instead of the default
61 | .I ieee-oui.txt.
62 | .TP
63 | .B -v
64 | Display verbose progress messages.
65 | .SH FILES
66 | .TP
67 | .I ieee-oui.txt
68 | The default output file.
69 | .SH EXAMPLES
70 | .nf
71 | $ ./get-oui -v
72 | Renaming ieee-oui.txt to ieee-oui.txt.bak
73 | Opening ieee-oui.txt for output
74 | Processing IEEE IAB registry data from https://standards-oui.ieee.org/iab/iab.csv
75 | Downloaded 381454 bytes
76 | 4575 IAB entries written to ieee-oui.txt
77 | Processing IEEE MAM registry data from https://standards-oui.ieee.org/oui28/mam.csv
78 | Downloaded 492756 bytes
79 | 4477 MAM entries written to ieee-oui.txt
80 | Processing IEEE OUI registry data from https://standards-oui.ieee.org/oui/oui.csv
81 | Downloaded 3051812 bytes
82 | 32845 OUI entries written to ieee-oui.txt
83 | Processing IEEE OUI36 registry data from https://standards-oui.ieee.org/oui36/oui36.csv
84 | Downloaded 466151 bytes
85 | 5131 OUI36 entries written to ieee-oui.txt
86 |
87 | Total of 47028 MAC/Vendor mappings written to ieee-oui.txt
88 | .fi
89 | .SH NOTES
90 | .B get-oui
91 | is implemented in Perl, so you need to have the Perl interpreter installed on
92 | your system to use it.
93 | .PP
94 | .B get-oui
95 | uses the
96 | .I LWP::UserAgent
97 | and
98 | .I Text::CSV
99 | Perl modules to fetch and process the IEEE registry data. You must have
100 | these modules installed on your system for
101 | it to work. These modules are available on most distributions, often called
102 | .I libwww-perl
103 | and
104 | .IR libtext-csv-perl .
105 | They are also available in source form from CPAN.
106 | .PP
107 | You can use a proxy server by defining the
108 | .I http_proxy
109 | environment variable.
110 | .SH "SEE ALSO"
111 | .TP
112 | .BR arp-scan (1)
113 | .TP
114 | .BR arp-fingerprint (1)
115 |
--------------------------------------------------------------------------------
/link-bpf.c:
--------------------------------------------------------------------------------
1 | /*
2 | * arp-scan is Copyright (C) 2005-2025 Roy Hills
3 | *
4 | * This file is part of arp-scan.
5 | *
6 | * arp-scan is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * arp-scan is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with arp-scan. If not, see .
18 | *
19 | * link-bpf.c -- BPF link layer functions for arp-scan
20 | *
21 | * Author: Roy Hills
22 | * Date: 1 July 2006
23 | *
24 | * Description:
25 | *
26 | * This contains the link layer functions using the BPF (Berkeley
27 | * Packet Filter) implementation. BPF is typically used on BSD systems such
28 | * as FreeBSD See bpf(4) on a FreeBSD system for details.
29 | *
30 | */
31 |
32 | #include "arp-scan.h"
33 |
34 | #ifdef HAVE_NET_IF_H
35 | #include
36 | #endif
37 |
38 | #ifdef HAVE_NET_ROUTE_H
39 | #include
40 | #endif
41 |
42 | /* OpenBSD needs sys/param.h */
43 | #ifdef HAVE_SYS_PARAM_H
44 | #include
45 | #endif
46 |
47 | #ifdef HAVE_SYS_SYSCTL_H
48 | #include
49 | #endif
50 |
51 | #ifdef HAVE_NET_IF_DL_H
52 | #include
53 | #endif
54 |
55 | /*
56 | * get_hardware_address -- Get the Ethernet MAC address associated
57 | * with the given device.
58 | * Inputs:
59 | *
60 | * if_name The name of the network interface
61 | * hw_address (output) the Ethernet MAC address
62 | *
63 | * Returns:
64 | *
65 | * None
66 | */
67 | void
68 | get_hardware_address(const char *if_name, unsigned char hw_address[]) {
69 | struct if_msghdr *ifm;
70 | struct sockaddr_dl *sdl = NULL;
71 | unsigned char *p;
72 | unsigned char *buf;
73 | size_t len;
74 | int mib[] = {CTL_NET, PF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0};
75 | /*
76 | * Use sysctl to obtain interface list.
77 | * We first call sysctl with the 3rd arg set to NULL to obtain the
78 | * required length, then malloc the buffer and call sysctl again to get
79 | * the data.
80 | */
81 | if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
82 | err_sys("sysctl");
83 |
84 | buf = Malloc(len);
85 |
86 | if (sysctl(mib, 6, buf, &len, NULL, 0) < 0)
87 | err_sys("sysctl");
88 | /*
89 | * Go through all the interfaces in the list until we find the one that
90 | * corresponds to the device we are using.
91 | */
92 | for (p = buf; p < buf + len; p += ifm->ifm_msglen) {
93 | ifm = (struct if_msghdr *)p;
94 | /*
95 | * Skip this message if the version isn't what we expect.
96 | */
97 | if (ifm->ifm_version != RTM_VERSION)
98 | continue;
99 | sdl = (struct sockaddr_dl *)(ifm + 1);
100 |
101 | if (ifm->ifm_type != RTM_IFINFO || (ifm->ifm_addrs & RTA_IFP) == 0)
102 | continue;
103 |
104 | if (sdl->sdl_family != AF_LINK || sdl->sdl_nlen == 0)
105 | continue;
106 |
107 | if ((memcmp(sdl->sdl_data, if_name, sdl->sdl_nlen)) == 0)
108 | break;
109 | }
110 |
111 | if (p >= buf + len)
112 | err_msg("Could not get hardware address for interface %s", if_name);
113 |
114 | memcpy(hw_address, sdl->sdl_data + sdl->sdl_nlen, ETH_ALEN);
115 | free(buf);
116 | }
117 |
--------------------------------------------------------------------------------
/link-dlpi.c:
--------------------------------------------------------------------------------
1 | /*
2 | * arp-scan is Copyright (C) 2005-2025 Roy Hills
3 | *
4 | * This file is part of arp-scan.
5 | *
6 | * arp-scan is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * arp-scan is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with arp-scan. If not, see .
18 | *
19 | * link-dlpi.c -- DLPI link layer functions for arp-scan
20 | *
21 | * Author: Roy Hills
22 | * Date: 22 July 2006
23 | *
24 | * Description:
25 | *
26 | * This contains the link layer functions using the DLPI (Data Link
27 | * Provider Interface) implementation. DLPI is typically used on SysV systems
28 | * such as Solaris.
29 | *
30 | * Note: The DLPI functions have been tested with Solaris 8, 9 and 10. However
31 | * they do not work with Solaris 11. See github issue
32 | * https://github.com/royhills/arp-scan/issues/31 for details.
33 | */
34 |
35 | #include "arp-scan.h"
36 |
37 | #ifdef HAVE_SYS_STAT_H
38 | #include
39 | #endif
40 |
41 | #ifdef HAVE_FCNTL_H
42 | #include
43 | #endif
44 |
45 | #ifdef HAVE_STROPTS_H
46 | #include
47 | #endif
48 |
49 | #ifdef HAVE_SYS_DLPI_H
50 | #include
51 | #endif
52 |
53 | #ifdef HAVE_SYS_DLPIHDR_H
54 | #include
55 | #endif
56 |
57 | #ifdef HAVE_SYS_IOCTL_H
58 | #include
59 | #endif
60 |
61 | #ifdef HAVE_SYS_SOCKIO_H
62 | #include
63 | #endif
64 |
65 | #ifdef HAVE_NET_IF_H
66 | #include
67 | #endif
68 |
69 | /* Neal Nuckolls' sample code defines MAXDLBUF as 8192 longwords, but we use
70 | * unsigned char for our buffers and so must multiply by four */
71 | #define MAXDLBUF 8192*4
72 |
73 | /*
74 | * Link layer handle structure for DLPI.
75 | */
76 | typedef struct link_handle {
77 | int fd;
78 | int sap_first;
79 | struct ifreq ifr;
80 | } link_t;
81 |
82 | #if defined(DLIOCRAW) || defined(HAVE_SYS_DLPIHDR_H)
83 | static int
84 | strioctl(int fd, int cmd, int len, char *dp) {
85 | struct strioctl str;
86 |
87 | str.ic_cmd = cmd;
88 | str.ic_timout = INFTIM;
89 | str.ic_len = len;
90 | str.ic_dp = dp;
91 |
92 | if (ioctl(fd, I_STR, &str) < 0)
93 | return -1;
94 |
95 | return str.ic_len;
96 | }
97 | #endif
98 |
99 | #ifdef HAVE_SYS_DLPIHDR_H
100 | #define ND_BASE ('N' << 8)
101 | #define ND_GET (ND_BASE + 0)
102 | static int
103 | link_match_ppa(link_t *handle, const char *device) {
104 | char *p;
105 | char dev[16];
106 | char buf[256];
107 |
108 | int len;
109 | int ppa;
110 |
111 | strlcpy(buf, "dl_ifnames", sizeof(buf));
112 |
113 | if ((len = strioctl(handle->fd, ND_GET, sizeof(buf), buf)) < 0)
114 | return -1;
115 |
116 | for (p = buf; p < buf + len; p += strlen(p) + 1) {
117 | ppa = -1;
118 | if (sscanf(p, "%s (PPA %d)\n", dev, &ppa) != 2)
119 | break;
120 | if (strcmp(dev, device) == 0)
121 | break;
122 | }
123 | return ppa;
124 | }
125 | #endif
126 |
127 | static int
128 | dlpi_msg(int fd, union DL_primitives *dlp, int rlen, int flags, unsigned ack,
129 | int alen, int size) {
130 |
131 | struct strbuf ctl;
132 |
133 | ctl.maxlen = 0;
134 | ctl.len = rlen;
135 | ctl.buf = (caddr_t)dlp;
136 |
137 | if (putmsg(fd, &ctl, NULL, flags) < 0)
138 | return -1;
139 |
140 | ctl.maxlen = size;
141 | ctl.len = 0;
142 | flags = 0;
143 |
144 | if (getmsg(fd, &ctl, NULL, &flags) < 0)
145 | return -1;
146 |
147 | if (dlp->dl_primitive != ack || ctl.len < alen)
148 | return -1;
149 |
150 | return 0;
151 | }
152 |
153 | /*
154 | * link_close -- Close the link
155 | *
156 | * Inputs:
157 | *
158 | * handle The handle for the link interface
159 | *
160 | * Returns:
161 | *
162 | * None
163 | */
164 | static void
165 | link_close(link_t *handle) {
166 | if (handle != NULL) {
167 | if (handle->fd >= 0) {
168 | close(handle->fd);
169 | }
170 | free(handle);
171 | }
172 | }
173 |
174 | /*
175 | * link_open -- Open the specified link-level device
176 | *
177 | * Inputs:
178 | *
179 | * device The name of the device to open
180 | *
181 | * Returns:
182 | *
183 | * A pointer to a link handle structure.
184 | */
185 | static link_t *
186 | link_open(const char *device) {
187 | union DL_primitives *dlp;
188 | unsigned char buf[MAXDLBUF];
189 | char *p;
190 | char dev[16];
191 | link_t *handle;
192 | int ppa;
193 |
194 | handle = Malloc(sizeof(*handle));
195 | memset(handle, '\0', sizeof(*handle));
196 |
197 | #ifdef HAVE_SYS_DLPIHDR_H
198 | if ((handle->fd = open("/dev/streams/dlb", O_RDWR)) < 0) {
199 | free(handle);
200 | return NULL;
201 | }
202 |
203 | if ((ppa = link_match_ppa(handle, device)) < 0) {
204 | link_close(handle);
205 | return NULL;
206 | }
207 | #else
208 | handle->fd = -1;
209 | snprintf(dev, sizeof(dev), "/dev/%s", device);
210 | if ((p = strpbrk(dev, "0123456789")) == NULL) {
211 | link_close(handle);
212 | return NULL;
213 | }
214 | ppa = atoi(p);
215 | *p = '\0';
216 |
217 | if ((handle->fd = open(dev, O_RDWR)) < 0) {
218 | snprintf(dev, sizeof(dev), "/dev/%s", device);
219 | if ((handle->fd = open(dev, O_RDWR)) < 0) {
220 | link_close(handle);
221 | return NULL;
222 | }
223 | }
224 | #endif
225 | memset(&(handle->ifr), 0, sizeof(struct ifreq));
226 | strlcpy(handle->ifr.ifr_name, device, sizeof(handle->ifr.ifr_name));
227 | dlp = (union DL_primitives *)buf;
228 | dlp->info_req.dl_primitive = DL_INFO_REQ;
229 |
230 | if (dlpi_msg(handle->fd, dlp, DL_INFO_REQ_SIZE, RS_HIPRI, DL_INFO_ACK,
231 | DL_INFO_ACK_SIZE, sizeof(buf)) < 0) {
232 | link_close(handle);
233 | return NULL;
234 | }
235 |
236 | handle->sap_first = (dlp->info_ack.dl_sap_length > 0);
237 |
238 | if (dlp->info_ack.dl_provider_style == DL_STYLE2) {
239 | dlp->attach_req.dl_primitive = DL_ATTACH_REQ;
240 | dlp->attach_req.dl_ppa = ppa;
241 |
242 | if (dlpi_msg(handle->fd, dlp, DL_ATTACH_REQ_SIZE, 0, DL_OK_ACK,
243 | DL_OK_ACK_SIZE, sizeof(buf)) < 0) {
244 | link_close(handle);
245 | return NULL;
246 | }
247 | }
248 | memset(&dlp->bind_req, 0, DL_BIND_REQ_SIZE);
249 | dlp->bind_req.dl_primitive = DL_BIND_REQ;
250 | #ifdef DL_HP_RAWDLS
251 | dlp->bind_req.dl_sap = 24; /* from HP-UX DLPI programmers guide */
252 | dlp->bind_req.dl_service_mode = DL_HP_RAWDLS;
253 | #else
254 | dlp->bind_req.dl_sap = DL_ETHER;
255 | dlp->bind_req.dl_service_mode = DL_CLDLS;
256 | #endif
257 | if (dlpi_msg(handle->fd, dlp, DL_BIND_REQ_SIZE, 0, DL_BIND_ACK,
258 | DL_BIND_ACK_SIZE, sizeof(buf)) < 0) {
259 | link_close(handle);
260 | return NULL;
261 | }
262 | #ifdef DLIOCRAW
263 | if (strioctl(handle->fd, DLIOCRAW, 0, NULL) < 0) {
264 | link_close(handle);
265 | return NULL;
266 | }
267 | #endif
268 | return (handle);
269 | }
270 |
271 | /*
272 | * get_hardware_address -- Get the Ethernet MAC address associated
273 | * with the given device.
274 | * Inputs:
275 | *
276 | * if_name The name of the network interface
277 | * hw_address (output) the Ethernet MAC address
278 | *
279 | * Returns:
280 | *
281 | * None
282 | */
283 | void
284 | get_hardware_address(const char *if_name, unsigned char hw_address[]) {
285 | union DL_primitives *dlp;
286 | unsigned char buf[MAXDLBUF];
287 | link_t *handle;
288 |
289 | handle = link_open(if_name);
290 | if (!handle)
291 | err_msg("ERROR: cannot open interface %s with DLPI", if_name);
292 |
293 | dlp = (union DL_primitives*) buf;
294 | dlp->physaddr_req.dl_primitive = DL_PHYS_ADDR_REQ;
295 | dlp->physaddr_req.dl_addr_type = DL_CURR_PHYS_ADDR;
296 | if (dlpi_msg(handle->fd, dlp, DL_PHYS_ADDR_REQ_SIZE, 0, DL_PHYS_ADDR_ACK,
297 | DL_PHYS_ADDR_ACK_SIZE, sizeof(buf)) < 0) {
298 | err_msg("dlpi_msg failed");
299 | }
300 |
301 | link_close(handle);
302 | memcpy(hw_address, buf + dlp->physaddr_ack.dl_addr_offset, ETH_ALEN);
303 | }
304 |
--------------------------------------------------------------------------------
/link-packet-socket.c:
--------------------------------------------------------------------------------
1 | /*
2 | * arp-scan is Copyright (C) 2005-2025 Roy Hills
3 | *
4 | * This file is part of arp-scan.
5 | *
6 | * arp-scan is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * arp-scan is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with arp-scan. If not, see .
18 | *
19 | * link-packet-socket.c -- Packet socket link layer functions for arp-scan
20 | *
21 | * Author: Roy Hills
22 | * Date: 1 July 2006
23 | *
24 | * Description:
25 | *
26 | * This contains the link layer functions using the packet socket
27 | * implementation. Packet socket is typically used on Linux with kernel
28 | * version 2.2 and above. See packet(7) on a Linux system for details.
29 | *
30 | */
31 |
32 | #include "arp-scan.h"
33 |
34 | #ifdef HAVE_NETPACKET_PACKET_H
35 | #include
36 | #endif
37 |
38 | #ifdef HAVE_NET_IF_H
39 | #include
40 | #endif
41 |
42 | /*
43 | * Link layer handle structure for packet socket.
44 | */
45 | typedef struct link_handle {
46 | int fd; /* Socket file descriptor */
47 | struct ifreq ifr;
48 | struct sockaddr_ll sll;
49 | } link_t;
50 |
51 | /*
52 | * link_open -- Open the specified link-level device
53 | *
54 | * Inputs:
55 | *
56 | * device The name of the device to open
57 | *
58 | * Returns:
59 | *
60 | * A pointer to a link handle structure.
61 | */
62 | static link_t *
63 | link_open(const char *device) {
64 | link_t *handle;
65 |
66 | handle = Malloc(sizeof(*handle));
67 | memset(handle, '\0', sizeof(*handle));
68 | if ((handle->fd = socket(PF_PACKET, SOCK_RAW, 0)) < 0)
69 | err_sys("ERROR: Cannot open raw packet socket: socket()");
70 | strlcpy(handle->ifr.ifr_name, device, sizeof(handle->ifr.ifr_name));
71 | if ((ioctl(handle->fd, SIOCGIFINDEX, &(handle->ifr))) != 0)
72 | err_sys("ioctl");
73 | handle->sll.sll_family = PF_PACKET;
74 | handle->sll.sll_ifindex = handle->ifr.ifr_ifindex;
75 | handle->sll.sll_halen = ETH_ALEN;
76 |
77 | return handle;
78 | }
79 |
80 | /*
81 | * link_close -- Close the link
82 | *
83 | * Inputs:
84 | *
85 | * handle The handle for the link interface
86 | *
87 | * Returns:
88 | *
89 | * None
90 | */
91 | static void
92 | link_close(link_t *handle) {
93 | if (handle != NULL) {
94 | if (handle->fd != 0)
95 | close(handle->fd);
96 | free(handle);
97 | }
98 | }
99 |
100 | /*
101 | * get_hardware_address -- Get the Ethernet MAC address associated
102 | * with the given device.
103 | * Inputs:
104 | *
105 | * if_name The name of the network interface
106 | * hw_address (output) the Ethernet MAC address
107 | *
108 | * Returns:
109 | *
110 | * None
111 | */
112 | void
113 | get_hardware_address(const char *if_name, unsigned char hw_address[]) {
114 | link_t *handle;
115 |
116 | handle = link_open(if_name); /* Errors handled in link_open() function */
117 |
118 | /* Obtain hardware address for specified interface */
119 | if ((ioctl(handle->fd, SIOCGIFHWADDR, &(handle->ifr))) != 0)
120 | err_sys("ioctl");
121 |
122 | memcpy(hw_address, handle->ifr.ifr_ifru.ifru_hwaddr.sa_data, ETH_ALEN);
123 |
124 | link_close(handle);
125 | }
126 |
--------------------------------------------------------------------------------
/m4/gcc-fortify-source.m4:
--------------------------------------------------------------------------------
1 | dnl Check whether GCC accepts -D_FORTIFY_SOURCE
2 | dnl
3 | dnl This was introduced in GCC 4.1 and glibc 2.4, but was present in earlier
4 | dnl versions on redhat systems (specifically GCC 3.4.3 and above).
5 | dnl
6 | dnl We define the GNUC_PREREQ macro to the same definition as __GNUC_PREREQ
7 | dnl in . We don't use __GNUC_PREREQ directly because
8 | dnl is not present on all the operating systems that we support, e.g. OpenBSD.
9 | dnl
10 | AC_DEFUN([GCC_FORTIFY_SOURCE],[
11 | if test "X$CC" != "X"; then
12 | AC_MSG_CHECKING([whether ${CC} accepts -D_FORTIFY_SOURCE])
13 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[
14 | #define GNUC_PREREQ(maj, min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
15 | #if !(GNUC_PREREQ (4, 1) \
16 | || (defined __GNUC_RH_RELEASE__ && GNUC_PREREQ (4, 0)) \
17 | || (defined __GNUC_RH_RELEASE__ && GNUC_PREREQ (3, 4) \
18 | && __GNUC_MINOR__ == 4 \
19 | && (__GNUC_PATCHLEVEL__ > 2 \
20 | || (__GNUC_PATCHLEVEL__ == 2 && __GNUC_RH_RELEASE__ >= 8))))
21 | #error No FORTIFY_SOURCE support
22 | #endif
23 | ]])],[
24 | AC_MSG_RESULT(yes)
25 | CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2"
26 | ],[
27 | AC_MSG_RESULT(no)
28 | ])
29 | fi
30 | ])
31 |
--------------------------------------------------------------------------------
/m4/gcc-stack-protect.m4:
--------------------------------------------------------------------------------
1 | dnl Useful macros for autoconf to check for ssp-patched gcc
2 | dnl 1.0 - September 2003 - Tiago Sousa
3 | dnl
4 | dnl Modified by ffontaine pull request: use AC_LINK_IFELSE instead of
5 | dnl AC_COMPILE_IFELSE because some systems may be missing the libssp library
6 | dnl even though the compiler accepts the option.
7 | dnl
8 | dnl About ssp:
9 | dnl GCC extension for protecting applications from stack-smashing attacks
10 | dnl http://www.research.ibm.com/trl/projects/security/ssp/
11 | dnl
12 | dnl Usage:
13 | dnl After calling the correct AC_LANG_*, use the corresponding macro:
14 | dnl
15 | dnl GCC_STACK_PROTECT_CC
16 | dnl checks -fstack-protector with the C compiler, if it exists then updates
17 | dnl CFLAGS and defines ENABLE_SSP_CC
18 | dnl
19 | dnl GCC_STACK_PROTECT_CXX
20 | dnl checks -fstack-protector with the C++ compiler, if it exists then updates
21 | dnl CXXFLAGS and defines ENABLE_SSP_CXX
22 | dnl
23 | AC_DEFUN([GCC_STACK_PROTECT_CC],[
24 | ssp_cc=yes
25 | if test "X$CC" != "X"; then
26 | AC_MSG_CHECKING([whether ${CC} accepts -fstack-protector])
27 | ssp_old_cflags="$CFLAGS"
28 | CFLAGS="$CFLAGS -fstack-protector"
29 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[],[ssp_cc=no])
30 | echo $ssp_cc
31 | if test "X$ssp_cc" = "Xno"; then
32 | CFLAGS="$ssp_old_cflags"
33 | else
34 | AC_DEFINE([ENABLE_SSP_CC], 1, [Define if SSP C support is enabled.])
35 | fi
36 | fi
37 | ])
38 |
39 | AC_DEFUN([GCC_STACK_PROTECT_CXX],[
40 | ssp_cxx=yes
41 | if test "X$CXX" != "X"; then
42 | AC_MSG_CHECKING([whether ${CXX} accepts -fstack-protector])
43 | ssp_old_cxxflags="$CXXFLAGS"
44 | CXXFLAGS="$CXXFLAGS -fstack-protector"
45 | AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[],[ssp_cxx=no])
46 | echo $ssp_cxx
47 | if test "X$ssp_cxx" = "Xno"; then
48 | CXXFLAGS="$ssp_old_cxxflags"
49 | else
50 | AC_DEFINE([ENABLE_SSP_CXX], 1, [Define if SSP C++ support is enabled.])
51 | fi
52 | fi
53 | ])
54 |
--------------------------------------------------------------------------------
/m4/libcap-capabilities.m4:
--------------------------------------------------------------------------------
1 | dnl Check for POSIX.1e capabilities support with libcap
2 | AC_DEFUN([CHECK_LIBCAP],
3 | [
4 | AC_ARG_WITH(libcap,
5 | AS_HELP_STRING([--with-libcap@<:@=auto/yes/no@:>@],[Build with libcap POSIX.1e capabilities support @<:@default=auto@:>@]),,
6 | with_libcap=auto)
7 |
8 | if test "X$with_libcap" = "Xno" ; then
9 | have_libcap=no;
10 | else
11 | # Check for header file
12 | AC_CHECK_HEADER(sys/capability.h, cap_headers=yes, cap_headers=no)
13 | # Check for library
14 | AC_CHECK_LIB(cap, cap_set_proc, cap_library=yes, cap_library=no)
15 | # Check results are usable
16 | if test "X$with_libcap" = "Xyes" -a "X$cap_library" = "Xno" ; then
17 | AC_MSG_ERROR([libcap support was requested but the library was not found])
18 | fi
19 | if test "X$cap_library" = "Xyes" -a "X$cap_headers" = "Xno" ; then
20 | AC_MSG_ERROR([libcap libraries found but headers are missing])
21 | fi
22 | fi
23 | AC_MSG_CHECKING([whether to use libcap])
24 | if test "X$cap_library" = "Xyes" -a "X$cap_library" = "Xyes"; then
25 | AC_DEFINE(HAVE_LIBCAP,1,[Define to 1 if you have the libcap library])
26 | AC_DEFINE(HAVE_SYS_CAPABILITY_H,1,[Define to 1 if you have the header file])
27 | LIBS="-lcap $LIBS"
28 | AC_MSG_RESULT([yes])
29 | AC_MSG_NOTICE([Including libcap POSIX.1e capability support])
30 | else
31 | AC_MSG_RESULT([no])
32 | AC_MSG_NOTICE([POSIX.1e capabilities disabled or not supported])
33 | fi
34 | ])
35 |
--------------------------------------------------------------------------------
/mac-vendor.5:
--------------------------------------------------------------------------------
1 | '\" t
2 | .\" Copyright (C) Roy Hills
3 | .\"
4 | .\" Copying and distribution of this file, with or without modification,
5 | .\" are permitted in any medium without royalty provided the copyright
6 | .\" notice and this notice are preserved.
7 | .\"
8 | .TH MAC-VENDOR 5 "October 28, 2022"
9 | .\" Please adjust this date whenever revising the man page.
10 | .SH NAME
11 | mac-vendor \- Ethernet vendor file for arp-scan
12 | .SH SYNOPSIS
13 | .I mac-vendor.txt
14 | .SH DESCRIPTION
15 | The
16 | .I mac-vendor.txt
17 | contains Ethernet MAC to vendor string mappings for
18 | .BR arp-scan .
19 | It is used in addition to the IEEE OUI listings in
20 | .IR ieee-oui.txt .
21 | It is for MAC-vendor mappings that are not covered by the IEEE manufacturer
22 | listings.
23 | .PP
24 | Each line in the
25 | .I mac-vendor.txt
26 | file contains a MAC-vendor mapping in the form:
27 | .PP
28 | .nf
29 |
30 | .fi
31 | .PP
32 | Where is the prefix of the MAC address in hex, and
33 | is the name of the vendor. The prefix can be of any length from two hex
34 | digits (one octet) to twelve hex digits (six octets, the entire Ethernet
35 | hardware address).
36 | .PP
37 | Alphabetic hex characters [A-F] may use either upper or lower case, and
38 | seperator symbols such as ":", "-" and "." are ignored. This permits the
39 | use of standard format MAC addresses in this file.
40 | .PP
41 | For example:
42 | .TS
43 | L L .
44 | 01:23:45 matches 01:23:45:xx:xx:xx, where xx represents any value;
45 | 01:23:45:6 matches 01:23:45:6x:xx:xx; and
46 | 01:23:45:67 matches 01:23:45:67:xx:xx.
47 | .TE
48 | .PP
49 | Do not include entries from the IEEE OUI listings, as these are
50 | already in the file ieee-oui.txt, which is automatically
51 | used by arp-scan. See get-oui(1) for details of how to
52 | update the OUI listings.
53 | .PP
54 | The order of entries in the file is not important.
55 | .PP
56 | Blank lines and lines beginning with "#" are ignored.
57 | .B arp-scan
58 | will attempt to match larger prefixes before trying to match smaller ones, and
59 | will stop at the first match.
60 | .SH FILES
61 | .I /usr/local/share/arp-scan/mac-vendor.txt
62 | .SH EXAMPLE
63 | .nf
64 | # From nmap Debian bug report #369681 dated 31 May 2006
65 | 52:54:00 QEMU
66 | b0:c4:20 Bochs
67 |
68 | # From RFC 2338: 00-00-5E-00-01-{VRID}
69 | 00:00:5e:00:01 VRRP (last octet is VRID)
70 |
71 | # Microsoft WLBS (Windows NT Load Balancing Service)
72 | # http://www.microsoft.com/technet/prodtechnol/acs/reskit/acrkappb.mspx
73 | 02:bf Microsoft WLBS (last four octets are IP address)
74 |
75 | # Cisco HSRP (Hot Standby Routing Protocol)
76 | # 00-00-0c-07-ac-XX, where XX is the HSRP group number (0 to 255)
77 | 00:00:0c:07:ac HSRP (last octet is group number)
78 | .fi
79 | .SH "SEE ALSO"
80 | .TP
81 | .BR arp-scan (1)
82 | .TP
83 | .BR get-oui (1)
84 | .TP
85 | .BR arp-fingerprint (1)
86 |
--------------------------------------------------------------------------------
/mac-vendor.txt:
--------------------------------------------------------------------------------
1 | # mac-vendor.txt -- Ethernet vendor file for arp-scan
2 | #
3 | # This file contains Ethernet vendor mappings for arp-scan. These are used
4 | # to determine the vendor for a give Ethernet interface given the MAC address.
5 | #
6 | # Each line of this file contains a MAC-vendor mapping in the form:
7 | #
8 | #
9 | #
10 | # Where is the prefix of the MAC address in hex, and
11 | # is the name of the vendor. The prefix can be of any length from two hex
12 | # digits (one octet) to twelve hex digits (six octets, the entire Ethernet
13 | # hardware address).
14 | #
15 | # Alphabetic hex characters [A-F] may use either upper or lower case, and
16 | # seperator symbols such as ":", "-" and "." are ignored. This permits the
17 | # use of standard format MAC addresses in this file.
18 | #
19 | # For example:
20 | #
21 | # 01:23:45 matches 01:23:45:xx:xx:xx, where xx represents any value;
22 | # 01:23:45:6 matches 01:23:45:6x:xx:xx; and
23 | # 01:23:45:67 matches 01:23:45:67:xx:xx.
24 | #
25 | # Do not include entries from the IEEE OUI listings, as these are already in
26 | # the file ieee-oui.txt, which is automatically used by arp-scan. See
27 | # get-oui(1) for details of how to update the OUI listings.
28 | #
29 | # The order of entries in this file are not important.
30 | #
31 | # arp-scan will attempt to match larger prefixes before trying to match
32 | # smaller ones, and will stop at the first match.
33 | #
34 | # Blank lines and lines beginning with "#" are ignored.
35 | #
36 | # See the mac-vendor(5) manpage for more information.
37 | #
38 |
39 | # From nmap Debian bug report #369681 dated 31 May 2006
40 | 52:54:00 QEMU
41 | b0:c4:20 Bochs
42 |
43 | # From RFC 5798: "IPv4 case: 00-00-5E-00-01-{VRID}"
44 | # OpenBSD's CARP protocol uses VRRP's IPv4 MAC addresses.
45 | 00:00:5e:00:01 VRRP/CARP (last octet is VRID/VHID)
46 | # From RFC 5798: "IPv6 case: 00-00-5E-00-02-{VRID}"
47 | 00:00:5e:00:02 IPv6 VRRP (last octet is VRID)
48 |
49 | # OpenBSD ether_fakeaddr()
50 | fe:e1:ba:d OpenBSD randomly generated MAC address
51 |
52 | # Microsoft WLBS (Windows NT Load Balancing Service)
53 | # http://www.microsoft.com/technet/prodtechnol/acs/reskit/acrkappb.mspx
54 | 02:bf Microsoft WLBS (last four octets are IP address)
55 |
56 | # Cisco HSRP (Hot Standby Routing Protocol)
57 | # 00-00-0c-07-ac-XX, where XX is the HSRP group number (0 to 255)
58 | 00:00:0c:07:ac HSRP (last octet is group number)
59 |
60 | # Ethernet broadcast address
61 | ff:ff:ff:ff:ff:ff Broadcast
62 |
63 | # You can add local MAC address/name mappings to this file. There should be
64 | # a TAB character between the MAC address and the name.
65 | #
66 | # Put any local additions after this line.
67 |
--------------------------------------------------------------------------------
/mt19937ar-test.c:
--------------------------------------------------------------------------------
1 | /*
2 | A C-program for MT19937, with initialization improved 2002/1/26.
3 | Coded by Takuji Nishimura and Makoto Matsumoto.
4 |
5 | Before using, initialize the state by using init_genrand(seed)
6 | or init_by_array(init_key, key_length).
7 |
8 | Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
9 | All rights reserved.
10 | Copyright (C) 2005, Mutsuo Saito,
11 | All rights reserved.
12 |
13 | Redistribution and use in source and binary forms, with or without
14 | modification, are permitted provided that the following conditions
15 | are met:
16 |
17 | 1. Redistributions of source code must retain the above copyright
18 | notice, this list of conditions and the following disclaimer.
19 |
20 | 2. Redistributions in binary form must reproduce the above copyright
21 | notice, this list of conditions and the following disclaimer in the
22 | documentation and/or other materials provided with the distribution.
23 |
24 | 3. The names of its contributors may not be used to endorse or promote
25 | products derived from this software without specific prior written
26 | permission.
27 |
28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
32 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
35 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
36 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
37 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 |
40 |
41 | Any feedback is very welcome.
42 | http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
43 | email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
44 | */
45 |
46 | #include
47 | #include "mt19937ar.h"
48 |
49 | int main(void)
50 | {
51 | int i;
52 | unsigned long init[4]={0x123, 0x234, 0x345, 0x456}, length=4;
53 | init_by_array(init, length);
54 | printf("1000 outputs of genrand_int32()\n");
55 | for (i=0; i<1000; i++) {
56 | printf("%10lu ", genrand_int32());
57 | if (i%5==4) printf("\n");
58 | }
59 | printf("\n1000 outputs of genrand_real2()\n");
60 | for (i=0; i<1000; i++) {
61 | printf("%10.8f ", genrand_real2());
62 | if (i%5==4) printf("\n");
63 | }
64 | return 0;
65 | }
66 |
--------------------------------------------------------------------------------
/mt19937ar.c:
--------------------------------------------------------------------------------
1 | /*
2 | A C-program for MT19937, with initialization improved 2002/1/26.
3 | Coded by Takuji Nishimura and Makoto Matsumoto.
4 | Before using, initialize the state by using init_genrand(seed)
5 | or init_by_array(init_key, key_length).
6 | Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
7 | All rights reserved.
8 | Copyright (C) 2005, Mutsuo Saito,
9 | All rights reserved.
10 | Redistribution and use in source and binary forms, with or without
11 | modification, are permitted provided that the following conditions
12 | are met:
13 | 1. Redistributions of source code must retain the above copyright
14 | notice, this list of conditions and the following disclaimer.
15 | 2. Redistributions in binary form must reproduce the above copyright
16 | notice, this list of conditions and the following disclaimer in the
17 | documentation and/or other materials provided with the distribution.
18 | 3. The names of its contributors may not be used to endorse or promote
19 | products derived from this software without specific prior written
20 | permission.
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 | Any feedback is very welcome.
33 | http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
34 | email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
35 | */
36 |
37 | #include
38 | #include "mt19937ar.h"
39 |
40 | /* Period parameters */
41 | #define N 624
42 | #define M 397
43 | #define MATRIX_A 0x9908b0dfUL /* constant vector a */
44 | #define UPPER_MASK 0x80000000UL /* most significant w-r bits */
45 | #define LOWER_MASK 0x7fffffffUL /* least significant r bits */
46 |
47 | static unsigned long mt[N]; /* the array for the state vector */
48 | static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
49 |
50 | /* initializes mt[N] with a seed */
51 | void init_genrand(unsigned long s)
52 | {
53 | mt[0]= s & 0xffffffffUL;
54 | for (mti=1; mti> 30)) + mti);
57 | /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
58 | /* In the previous versions, MSBs of the seed affect */
59 | /* only MSBs of the array mt[]. */
60 | /* 2002/01/09 modified by Makoto Matsumoto */
61 | mt[mti] &= 0xffffffffUL;
62 | /* for >32 bit machines */
63 | }
64 | }
65 |
66 | /* initialize by an array with array-length */
67 | /* init_key is the array for initializing keys */
68 | /* key_length is its length */
69 | /* slight change for C++, 2004/2/26 */
70 | void init_by_array(unsigned long init_key[], int key_length)
71 | {
72 | int i, j, k;
73 | init_genrand(19650218UL);
74 | i=1; j=0;
75 | k = (N>key_length ? N : key_length);
76 | for (; k; k--) {
77 | mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
78 | + init_key[j] + j; /* non linear */
79 | mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
80 | i++; j++;
81 | if (i>=N) { mt[0] = mt[N-1]; i=1; }
82 | if (j>=key_length) j=0;
83 | }
84 | for (k=N-1; k; k--) {
85 | mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
86 | - i; /* non linear */
87 | mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
88 | i++;
89 | if (i>=N) { mt[0] = mt[N-1]; i=1; }
90 | }
91 |
92 | mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
93 | }
94 |
95 | /* generates a random number on [0,0xffffffff]-interval */
96 | unsigned long genrand_int32(void)
97 | {
98 | unsigned long y;
99 | static unsigned long mag01[2]={0x0UL, MATRIX_A};
100 | /* mag01[x] = x * MATRIX_A for x=0,1 */
101 |
102 | if (mti >= N) { /* generate N words at one time */
103 | int kk;
104 |
105 | if (mti == N+1) /* if init_genrand() has not been called, */
106 | init_genrand(5489UL); /* a default initial seed is used */
107 |
108 | for (kk=0;kk> 1) ^ mag01[y & 0x1UL];
111 | }
112 | for (;kk> 1) ^ mag01[y & 0x1UL];
115 | }
116 | y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
117 | mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
118 |
119 | mti = 0;
120 | }
121 |
122 | y = mt[mti++];
123 |
124 | /* Tempering */
125 | y ^= (y >> 11);
126 | y ^= (y << 7) & 0x9d2c5680UL;
127 | y ^= (y << 15) & 0xefc60000UL;
128 | y ^= (y >> 18);
129 |
130 | return y;
131 | }
132 |
133 | /* generates a random number on [0,1)-real-interval */
134 | double genrand_real2(void)
135 | {
136 | return genrand_int32()*(1.0/4294967296.0);
137 | /* divided by 2^32 */
138 | }
139 |
140 | /*
141 | * genrand_int31(), genrand_real1(), genrand_real3() and genrand_res53() have
142 | * been removed because they are not used in the arp-scan code and are not
143 | * tested by "make check".
144 | */
145 |
--------------------------------------------------------------------------------
/mt19937ar.h:
--------------------------------------------------------------------------------
1 | #ifndef MT19937AR_H
2 | #define MT19937AR_H
3 |
4 | /*
5 | A C-program for MT19937, with initialization improved 2002/1/26.
6 | Coded by Takuji Nishimura and Makoto Matsumoto.
7 | Before using, initialize the state by using init_genrand(seed)
8 | or init_by_array(init_key, key_length).
9 | Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
10 | All rights reserved.
11 | Copyright (C) 2005, Mutsuo Saito
12 | All rights reserved.
13 | Redistribution and use in source and binary forms, with or without
14 | modification, are permitted provided that the following conditions
15 | are met:
16 | 1. Redistributions of source code must retain the above copyright
17 | notice, this list of conditions and the following disclaimer.
18 | 2. Redistributions in binary form must reproduce the above copyright
19 | notice, this list of conditions and the following disclaimer in the
20 | documentation and/or other materials provided with the distribution.
21 | 3. The names of its contributors may not be used to endorse or promote
22 | products derived from this software without specific prior written
23 | permission.
24 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 | Any feedback is very welcome.
36 | http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
37 | email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
38 | */
39 |
40 | /* initializes mt[N] with a seed */
41 | void init_genrand(unsigned long s);
42 |
43 | /* initialize by an array with array-length */
44 | /* init_key is the array for initializing keys */
45 | /* key_length is its length */
46 | /* slight change for C++, 2004/2/26 */
47 | void init_by_array(unsigned long init_key[], int key_length);
48 |
49 | /* generates a random number on [0,0xffffffff]-interval */
50 | unsigned long genrand_int32(void);
51 |
52 | /* generates a random number on [0,0x7fffffff]-interval */
53 | long genrand_int31(void);
54 |
55 | /* These real versions are due to Isaku Wada, 2002/01/09 added */
56 | /* generates a random number on [0,1]-real-interval */
57 | double genrand_real1(void);
58 |
59 | /* generates a random number on [0,1)-real-interval */
60 | double genrand_real2(void);
61 |
62 | /* generates a random number on (0,1)-real-interval */
63 | double genrand_real3(void);
64 |
65 | /* generates a random number on [0,1) with 53-bit resolution*/
66 | double genrand_res53(void);
67 |
68 | #endif /* MT19937AR_H */
69 |
--------------------------------------------------------------------------------
/my_getopt.c:
--------------------------------------------------------------------------------
1 | /*
2 | * my_getopt.c - my re-implementation of getopt.
3 | * Copyright 1997, 2000, 2001, 2002, 2006, Benjamin Sittler
4 | *
5 | * Permission is hereby granted, free of charge, to any person
6 | * obtaining a copy of this software and associated documentation
7 | * files (the "Software"), to deal in the Software without
8 | * restriction, including without limitation the rights to use, copy,
9 | * modify, merge, publish, distribute, sublicense, and/or sell copies
10 | * of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be
14 | * included in all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | * DEALINGS IN THE SOFTWARE.
24 | */
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include "my_getopt.h"
31 |
32 | int my_optind=1, my_opterr=1, my_optopt=0;
33 | char *my_optarg=0;
34 |
35 | /* reset argument parser to start-up values */
36 | int my_getopt_reset(void)
37 | {
38 | my_optind = 1;
39 | my_opterr = 1;
40 | my_optopt = 0;
41 | my_optarg = 0;
42 | return 0;
43 | }
44 |
45 | /* this is the plain old UNIX getopt, with GNU-style extensions. */
46 | /* if you're porting some piece of UNIX software, this is all you need. */
47 | /* this supports GNU-style permution and optional arguments */
48 |
49 | int my_getopt(int argc, char * argv[], const char *opts)
50 | {
51 | static int charind=0;
52 | const char *s;
53 | char mode, colon_mode;
54 | int off = 0, opt = -1;
55 |
56 | if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+';
57 | else {
58 | if((colon_mode = *opts) == ':') off ++;
59 | if(((mode = opts[off]) == '+') || (mode == '-')) {
60 | off++;
61 | if((colon_mode != ':') && ((colon_mode = opts[off]) == ':'))
62 | off ++;
63 | }
64 | }
65 | my_optarg = 0;
66 | if(charind) {
67 | my_optopt = argv[my_optind][charind];
68 | for(s=opts+off; *s; s++) if(my_optopt == *s) {
69 | charind++;
70 | if((*(++s) == ':') || ((my_optopt == 'W') && (*s == ';'))) {
71 | if(argv[my_optind][charind]) {
72 | my_optarg = &(argv[my_optind++][charind]);
73 | charind = 0;
74 | } else if(*(++s) != ':') {
75 | charind = 0;
76 | if(++my_optind >= argc) {
77 | if(my_opterr) fprintf(stderr,
78 | "%s: option requires an argument -- %c\n",
79 | argv[0], my_optopt);
80 | opt = (colon_mode == ':') ? ':' : '?';
81 | goto my_getopt_ok;
82 | }
83 | my_optarg = argv[my_optind++];
84 | }
85 | }
86 | opt = my_optopt;
87 | goto my_getopt_ok;
88 | }
89 | if(my_opterr) fprintf(stderr,
90 | "%s: illegal option -- %c\n",
91 | argv[0], my_optopt);
92 | opt = '?';
93 | if(argv[my_optind][++charind] == '\0') {
94 | my_optind++;
95 | charind = 0;
96 | }
97 | my_getopt_ok:
98 | if(charind && ! argv[my_optind][charind]) {
99 | my_optind++;
100 | charind = 0;
101 | }
102 | } else if((my_optind >= argc) ||
103 | ((argv[my_optind][0] == '-') &&
104 | (argv[my_optind][1] == '-') &&
105 | (argv[my_optind][2] == '\0'))) {
106 | my_optind++;
107 | opt = -1;
108 | } else if((argv[my_optind][0] != '-') ||
109 | (argv[my_optind][1] == '\0')) {
110 | char *tmp;
111 | int i, j, k;
112 |
113 | if(mode == '+') opt = -1;
114 | else if(mode == '-') {
115 | my_optarg = argv[my_optind++];
116 | charind = 0;
117 | opt = 1;
118 | } else {
119 | for(i=j=my_optind; i j) {
124 | tmp=argv[--i];
125 | for(k=i; k+1 argc) my_optind = argc;
137 | return opt;
138 | }
139 |
140 | /* this is the extended getopt_long{,_only}, with some GNU-like
141 | * extensions. Implements _getopt_internal in case any programs
142 | * expecting GNU libc getopt call it.
143 | */
144 |
145 | int _my_getopt_internal(int argc, char * argv[], const char *shortopts,
146 | const struct option *longopts, int *longind,
147 | int long_only)
148 | {
149 | char mode, colon_mode = *shortopts;
150 | int shortoff = 0, opt = -1;
151 |
152 | if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+';
153 | else {
154 | if((colon_mode = *shortopts) == ':') shortoff ++;
155 | if(((mode = shortopts[shortoff]) == '+') || (mode == '-')) {
156 | shortoff++;
157 | if((colon_mode != ':') && ((colon_mode = shortopts[shortoff]) == ':'))
158 | shortoff ++;
159 | }
160 | }
161 | my_optarg = 0;
162 | if((my_optind >= argc) ||
163 | ((argv[my_optind][0] == '-') &&
164 | (argv[my_optind][1] == '-') &&
165 | (argv[my_optind][2] == '\0'))) {
166 | my_optind++;
167 | opt = -1;
168 | } else if((argv[my_optind][0] != '-') ||
169 | (argv[my_optind][1] == '\0')) {
170 | char *tmp;
171 | int i, j, k;
172 |
173 | opt = -1;
174 | if(mode == '+') return -1;
175 | else if(mode == '-') {
176 | my_optarg = argv[my_optind++];
177 | return 1;
178 | }
179 | for(i=j=my_optind; i j) {
186 | tmp=argv[--i];
187 | for(k=i; k+1= argc) {
240 | opt = (colon_mode == ':') ? ':' : '?';
241 | if(my_opterr) fprintf(stderr,
242 | "%s: option `--%s' requires an argument\n",
243 | argv[0], longopts[found].name);
244 | } else my_optarg = argv[my_optind];
245 | }
246 | if(!opt) {
247 | if (longind) *longind = found;
248 | if(!longopts[found].flag) opt = longopts[found].val;
249 | else *(longopts[found].flag) = longopts[found].val;
250 | }
251 | my_optind++;
252 | } else if(!hits) {
253 | if(offset == 1) opt = my_getopt(argc, argv, shortopts);
254 | else {
255 | opt = '?';
256 | if(my_opterr) fprintf(stderr,
257 | "%s: unrecognized option `%s'\n",
258 | argv[0], argv[my_optind++]);
259 | }
260 | } else {
261 | opt = '?';
262 | if(my_opterr) fprintf(stderr,
263 | "%s: option `%s' is ambiguous\n",
264 | argv[0], argv[my_optind++]);
265 | }
266 | }
267 | if (my_optind > argc) my_optind = argc;
268 | return opt;
269 | }
270 |
271 | int my_getopt_long(int argc, char * argv[], const char *shortopts,
272 | const struct option *longopts, int *longind)
273 | {
274 | return _my_getopt_internal(argc, argv, shortopts, longopts, longind, 0);
275 | }
276 |
277 | int my_getopt_long_only(int argc, char * argv[], const char *shortopts,
278 | const struct option *longopts, int *longind)
279 | {
280 | return _my_getopt_internal(argc, argv, shortopts, longopts, longind, 1);
281 | }
282 |
--------------------------------------------------------------------------------
/my_getopt.h:
--------------------------------------------------------------------------------
1 | /*
2 | * my_getopt.h - interface to my re-implementation of getopt.
3 | * Copyright 1997, 2000, 2001, 2002, 2006, Benjamin Sittler
4 | *
5 | * Permission is hereby granted, free of charge, to any person
6 | * obtaining a copy of this software and associated documentation
7 | * files (the "Software"), to deal in the Software without
8 | * restriction, including without limitation the rights to use, copy,
9 | * modify, merge, publish, distribute, sublicense, and/or sell copies
10 | * of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be
14 | * included in all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | * DEALINGS IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef MY_GETOPT_H_INCLUDED
27 | #define MY_GETOPT_H_INCLUDED
28 |
29 | #ifdef __cplusplus
30 | extern "C" {
31 | #endif
32 |
33 | /* reset argument parser to start-up values */
34 | extern int my_getopt_reset(void);
35 |
36 | /* UNIX-style short-argument parser */
37 | extern int my_getopt(int argc, char * argv[], const char *opts);
38 |
39 | extern int my_optind, my_opterr, my_optopt;
40 | extern char *my_optarg;
41 |
42 | struct option {
43 | const char *name;
44 | int has_arg;
45 | int *flag;
46 | int val;
47 | };
48 |
49 | /* human-readable values for has_arg */
50 | #undef no_argument
51 | #define no_argument 0
52 | #undef required_argument
53 | #define required_argument 1
54 | #undef optional_argument
55 | #define optional_argument 2
56 |
57 | /* GNU-style long-argument parsers */
58 | extern int my_getopt_long(int argc, char * argv[], const char *shortopts,
59 | const struct option *longopts, int *longind);
60 |
61 | extern int my_getopt_long_only(int argc, char * argv[], const char *shortopts,
62 | const struct option *longopts, int *longind);
63 |
64 | extern int _my_getopt_internal(int argc, char * argv[], const char *shortopts,
65 | const struct option *longopts, int *longind,
66 | int long_only);
67 |
68 | #undef getopt
69 | #define getopt my_getopt
70 | #undef getopt_long
71 | #define getopt_long my_getopt_long
72 | #undef getopt_long_only
73 | #define getopt_long_only my_getopt_long_only
74 | #undef _getopt_internal
75 | #define _getopt_internal _my_getopt_internal
76 | #undef opterr
77 | #define opterr my_opterr
78 | #undef optind
79 | #define optind my_optind
80 | #undef optopt
81 | #define optopt my_optopt
82 | #undef optarg
83 | #define optarg my_optarg
84 |
85 | #ifdef __cplusplus
86 | }
87 | #endif
88 |
89 | #endif /* MY_GETOPT_H_INCLUDED */
90 |
--------------------------------------------------------------------------------
/strlcpy.c:
--------------------------------------------------------------------------------
1 | /* $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $ */
2 |
3 | /*
4 | * Copyright (c) 1998, 2015 Todd C. Miller
5 | *
6 | * Permission to use, copy, modify, and distribute this software for any
7 | * purpose with or without fee is hereby granted, provided that the above
8 | * copyright notice and this permission notice appear in all copies.
9 | *
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 | */
18 |
19 | #include
20 | #include
21 | #include "strlcpy.h"
22 |
23 | /*
24 | * Copy string src to buffer dst of size dsize. At most dsize-1
25 | * chars will be copied. Always NUL terminates (unless dsize == 0).
26 | * Returns strlen(src); if retval >= dsize, truncation occurred.
27 | */
28 | size_t
29 | strlcpy(char *dst, const char *src, size_t dsize)
30 | {
31 | const char *osrc = src;
32 | size_t nleft = dsize;
33 |
34 | /* Copy as many bytes as will fit. */
35 | if (nleft != 0) {
36 | while (--nleft != 0) {
37 | if ((*dst++ = *src++) == '\0')
38 | break;
39 | }
40 | }
41 |
42 | /* Not enough room in dst, add NUL and traverse rest of src. */
43 | if (nleft == 0) {
44 | if (dsize != 0)
45 | *dst = '\0'; /* NUL-terminate dst */
46 | while (*src++)
47 | ;
48 | }
49 |
50 | return(src - osrc - 1); /* count does not include NUL */
51 | }
52 |
--------------------------------------------------------------------------------
/strlcpy.h:
--------------------------------------------------------------------------------
1 | #ifndef STRLCPY_H
2 | #define STRLCPY_H
3 |
4 | /*
5 | * Prototype for OpenBSD strlcpy() function.
6 | */
7 |
8 | size_t strlcpy(char *, const char *, size_t);
9 |
10 | #endif /* STRLCPY_H */
11 |
--------------------------------------------------------------------------------
/testdata/README.md:
--------------------------------------------------------------------------------
1 | # testdata directory
2 | This directory contains data files used by `make check` to run self tests.
3 |
4 | | Filename | Description |
5 | | --- | --- |
6 | | pkt-simple-response.pcap | Simple ARP response packet |
7 | | pkt-padding-response.pcap | ARP response followed by non-zero padding |
8 | | pkt-vlan-response.pcap | ARP response with 802.1Q VLAN tag |
9 | | pkt-llc-response.pcap | ARP response with 802.2 LLC/SNAP framing |
10 | | pkt-vlan-llc-response.pcap | ARP response with 802.2 LLC/SNAP framing and 802.1Q VLAN tag |
11 | | pkt-net1921681-response.pcap | 56 ARP responses from 192.168.1.0/24 |
12 | | pkt-trailer-response.pcap | ARP response with RFC 893 trailer encapsulation |
13 | | pkt-dup-response.pcap | ARP responses with duplicate packets |
14 | | pkt-diff-frame-addr.pcap | ARP response with Ethernet source address != ar$sha |
15 | | pkt-local-admin.pcap | ARP response with locally administered source address |
16 | | pkt-ieee-regcheck.pcap | ARP responses with source addresses in IEEE IAB, MA-M, MA-L and MA-S registries |
17 | | pkt-too-short.pcap | Truncated ARP response packet |
18 | | pkt-simple-request.dat | Raw ARP simple request packet |
19 | | pkt-custom-request.dat | Raw custom ARP request packet |
20 | | pkt-custom-request-padding.dat | Raw ARP request followed by non-zero padding |
21 | | pkt-custom-request-llc.dat | Raw ARP request with 802.2 LLC/SNAP framing |
22 | | pkt-custom-request-vlan.dat | Raw ARP request with 802.1Q VLAN tag |
23 | | pkt-custom-request-vlan-llc.dat | Raw ARP request with 802.2 LLC/SNAP framing and 802.1Q VLAN tag |
24 |
--------------------------------------------------------------------------------
/testdata/pkt-custom-request-llc.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-custom-request-llc.dat
--------------------------------------------------------------------------------
/testdata/pkt-custom-request-padding.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-custom-request-padding.dat
--------------------------------------------------------------------------------
/testdata/pkt-custom-request-vlan-llc.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-custom-request-vlan-llc.dat
--------------------------------------------------------------------------------
/testdata/pkt-custom-request-vlan.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-custom-request-vlan.dat
--------------------------------------------------------------------------------
/testdata/pkt-custom-request.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-custom-request.dat
--------------------------------------------------------------------------------
/testdata/pkt-diff-frame-addr.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-diff-frame-addr.pcap
--------------------------------------------------------------------------------
/testdata/pkt-dup-response.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-dup-response.pcap
--------------------------------------------------------------------------------
/testdata/pkt-ieee-regcheck.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-ieee-regcheck.pcap
--------------------------------------------------------------------------------
/testdata/pkt-llc-response.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-llc-response.pcap
--------------------------------------------------------------------------------
/testdata/pkt-local-admin.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-local-admin.pcap
--------------------------------------------------------------------------------
/testdata/pkt-net1921681-response.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-net1921681-response.pcap
--------------------------------------------------------------------------------
/testdata/pkt-padding-response.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-padding-response.pcap
--------------------------------------------------------------------------------
/testdata/pkt-simple-request.dat:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-simple-request.dat
--------------------------------------------------------------------------------
/testdata/pkt-simple-response.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-simple-response.pcap
--------------------------------------------------------------------------------
/testdata/pkt-too-short.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-too-short.pcap
--------------------------------------------------------------------------------
/testdata/pkt-trailer-response.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-trailer-response.pcap
--------------------------------------------------------------------------------
/testdata/pkt-vlan-llc-response.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-vlan-llc-response.pcap
--------------------------------------------------------------------------------
/testdata/pkt-vlan-response.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/royhills/arp-scan/a0466d5fc7fa8a1e5625b7aae568ffb384e3f5a5/testdata/pkt-vlan-response.pcap
--------------------------------------------------------------------------------
/utils.c:
--------------------------------------------------------------------------------
1 | /*
2 | * arp-scan is Copyright (C) 2005-2025 Roy Hills
3 | *
4 | * This file is part of arp-scan.
5 | *
6 | * arp-scan is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * arp-scan is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with arp-scan. If not, see .
18 | *
19 | * You are encouraged to send comments, improvements or suggestions
20 | * at the github repository https://github.com/royhills/arp-scan
21 | *
22 | * Author: Roy Hills
23 | * Date: 5 April 2004
24 | *
25 | * This file contains various utility functions used by arp-scan.
26 | */
27 |
28 | #include "arp-scan.h"
29 |
30 | static uid_t uid;
31 | #ifndef HAVE_LIBCAP
32 | static uid_t euid;
33 | #endif
34 |
35 | /*
36 | * timeval_diff -- Calculates the difference between two timevals
37 | * and returns this difference in a third timeval.
38 | *
39 | * Inputs:
40 | *
41 | * a = First timeval
42 | * b = Second timeval
43 | * diff = Difference between timevals (a - b).
44 | *
45 | * Returns:
46 | *
47 | * None.
48 | */
49 | void
50 | timeval_diff(const struct timeval *a, const struct timeval *b,
51 | struct timeval *diff) {
52 | diff->tv_sec = a->tv_sec - b->tv_sec;
53 | diff->tv_usec = a->tv_usec - b->tv_usec;
54 | if (diff->tv_usec < 0) {
55 | diff->tv_sec--;
56 | diff->tv_usec += 1000000;
57 | }
58 | }
59 |
60 | /*
61 | * hstr_i -- Convert two-digit hex string to unsigned integer
62 | *
63 | * Inputs:
64 | *
65 | * cptr Two-digit hex string
66 | *
67 | * Returns:
68 | *
69 | * Number corresponding to input hex value.
70 | *
71 | * An input of "0A" or "0a" would return 10.
72 | * Note that this function does no sanity checking, it's up to the
73 | * caller to ensure that *cptr points to at least two hex digits.
74 | *
75 | * This function is a modified version of hstr_i at www.snippets.org.
76 | */
77 | unsigned int
78 | hstr_i(const char *cptr) {
79 | unsigned int i;
80 | unsigned int j = 0;
81 | int k;
82 |
83 | for (k=0; k<2; k++) {
84 | i = *cptr++ - '0';
85 | if (9 < i)
86 | i -= 7;
87 | j <<= 4;
88 | j |= (i & 0x0f);
89 | }
90 | return j;
91 | }
92 |
93 | /*
94 | * hex2data -- Convert hex string to binary data
95 | *
96 | * Inputs:
97 | *
98 | * string The string to convert
99 | * data_len (output) The length of the resultant binary data
100 | *
101 | * Returns:
102 | *
103 | * Pointer to the binary data.
104 | *
105 | * The returned pointer points to malloc'ed storage which should be
106 | * free'ed by the caller when it's no longer needed. If the length of
107 | * the input string is not even, the function will return NULL and
108 | * set data_len to 0.
109 | */
110 | unsigned char *
111 | hex2data(const char *string, size_t *data_len) {
112 | unsigned char *data;
113 | unsigned char *cp;
114 | unsigned i;
115 | size_t len;
116 |
117 | assert(strlen(string) % 2 == 0); /* Length must be even */
118 |
119 | len = strlen(string) / 2;
120 | data = Malloc(len);
121 | cp = data;
122 | for (i=0; i c2)
603 | return 1;
604 | if (c1 < c2)
605 | return -1;
606 | if (c1 == 0 && c2 == 0)
607 | return 0;
608 | }
609 | }
610 |
611 | /*
612 | * my_lookupdev -- Find the default interface name
613 | *
614 | * Inputs:
615 | *
616 | * errbuf String to hold error message
617 | *
618 | * Returns:
619 | *
620 | * The name of the default network interface or NULL if an error occurs.
621 | *
622 | * This function is adapted from pcap_lookupdev() which was depreciated
623 | * in libpcap 1.9.0.
624 | */
625 | char *
626 | my_lookupdev(char *errbuf) {
627 | pcap_if_t *alldevs;
628 |
629 | #ifndef IF_NAMESIZE
630 | #define IF_NAMESIZE 8192
631 | #endif
632 |
633 | static char device[IF_NAMESIZE + 1];
634 | char *ret;
635 |
636 | if (pcap_findalldevs(&alldevs, errbuf) == -1)
637 | return NULL;
638 |
639 | if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
640 | /*
641 | * There are no devices on the list, or the first device
642 | * on the list is a loopback device, which means there
643 | * are no non-loopback devices on the list. This means
644 | * we can't return any device.
645 | */
646 | (void)strlcpy(errbuf, "no suitable device found", PCAP_ERRBUF_SIZE);
647 | ret = NULL;
648 | } else {
649 | /*
650 | * Return the name of the first device on the list.
651 | */
652 | (void)strlcpy(device, alldevs->name, sizeof(device));
653 | ret = device;
654 | }
655 |
656 | pcap_freealldevs(alldevs);
657 | return ret;
658 | }
659 |
--------------------------------------------------------------------------------
/wrappers.c:
--------------------------------------------------------------------------------
1 | /*
2 | * arp-scan is Copyright (C) 2005-2025 Roy Hills
3 | *
4 | * This file is part of arp-scan.
5 | *
6 | * arp-scan is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * arp-scan is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU General Public License
17 | * along with arp-scan. If not, see .
18 | *
19 | * Author: Roy Hills
20 | * Date: 8 November 2003
21 | *
22 | * This file contains wrapper functions for system and library calls that
23 | * are not expected to fail. If they do fail, then it calls err_sys to
24 | * print a diagnostic and terminate the program. This removed the tedious
25 | * "if ((function()) == NULL) err_sys("function");" logic thus making the
26 | * code easier to read.
27 | *
28 | * The wrapper functions have the same name as the system or library function
29 | * but with an initial capital letter. E.g. Gethostbyname(). This convention
30 | * if from Richard Steven's UNIX Network Programming book.
31 | *
32 | */
33 |
34 | #include "arp-scan.h"
35 |
36 | /*
37 | * We omit the timezone arg from this wrapper since it's obsolete and we never
38 | * use it.
39 | */
40 | int
41 | Gettimeofday(struct timeval *tv) {
42 | int result;
43 |
44 | result = gettimeofday(tv, NULL);
45 |
46 | if (result != 0)
47 | err_sys("gettimeofday");
48 |
49 | return result;
50 | }
51 |
52 | void *
53 | Malloc(size_t size) {
54 | void *result;
55 |
56 | result = malloc(size);
57 |
58 | if (result == NULL)
59 | err_sys("malloc");
60 |
61 | return result;
62 | }
63 |
64 | void *
65 | Realloc(void *ptr, size_t size) {
66 | void *result;
67 |
68 | result = realloc(ptr, size);
69 |
70 | if (result == NULL)
71 | err_sys("realloc");
72 |
73 | return result;
74 | }
75 |
76 | unsigned long int
77 | Strtoul(const char *nptr, int base) {
78 | char *endptr;
79 | unsigned long int result;
80 |
81 | result=strtoul(nptr, &endptr, base);
82 | if (endptr == nptr || (*endptr != '\0' && !isspace((unsigned char)*endptr)))
83 | err_msg("ERROR: \"%s\" is not a valid numeric value", nptr);
84 |
85 | return result;
86 | }
87 |
88 | long int
89 | Strtol(const char *nptr, int base) {
90 | char *endptr;
91 | long int result;
92 |
93 | result=strtol(nptr, &endptr, base);
94 | if (endptr == nptr || (*endptr != '\0' && !isspace((unsigned char)*endptr)))
95 | err_msg("ERROR: \"%s\" is not a valid numeric value", nptr);
96 |
97 | return result;
98 | }
99 |
--------------------------------------------------------------------------------