├── .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 | [![Build](https://github.com/royhills/arp-scan/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/royhills/arp-scan/actions/workflows/c-cpp.yml) 4 | [![Coverage Status](https://coveralls.io/repos/github/royhills/arp-scan/badge.svg?branch=master)](https://coveralls.io/github/royhills/arp-scan?branch=master) 5 | [![CodeQL](https://github.com/royhills/arp-scan/actions/workflows/codeql.yml/badge.svg)](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 | --------------------------------------------------------------------------------