ADDRWATCH(8)
π ADDRWATCH β the addrwatch(8) glow-up π
okay bestie, sit down, because we're about to talk about addrwatch, the ethernet/ip address monitoring tool, and honestly? it's giving network surveillance but make it cute. this is section 8 of the manual, so it's a system admin situation. buckle up π
β¨ NAME β¨
addrwatch β ethernet/ip address monitoring tool π¦
β¨ SYNOPSIS β¨
addrwatch [-lmqv46dP?V] [-m[database]] [-o file] [-s sqlite3.db] [-b ip]
[-H size] [-r num] [-p pidfile] [-u user] [-h hostname] [--mysql-table=table]
[--sqlite3-table=table] [INTERFACE1 INTERFACE2 ...]
like yes, that's a lot of brackets, but we'll go through every single one, no skipping, periodt π
β¨ DESCRIPTION β¨
so addrwatch is basically arpwatch's cooler cousin. its whole main character purpose is to monitor the network and log ethernet/ip pairings β that's it, that's the job πΈ
want to just try it out? run it with zero arguments. when you start it with no arguments it will:
- open the first non loopback interface
- start logging events to the console
- write absolutely nothing to disk
every ethernet/ip pairing it discovers gets printed to stdout. and all the debug, warning, and err messages? those get sent to syslog</> and printed to stderr. two channels, very organized, we love a multitasker π«Ά
β¨ OPTIONS β¨
-l,--syslogβ log the discovered ethernet/ip pairings to syslog (daemon facility). log girlies rise up π- *
-o*file,--output=file β write discovered ethernet/ip pairings to a specified file. the OUTPUT section below has the tea π - *
-m[database*],--mysql=[database] β write discovered ethernet/ip pairings into a MySQL database. your default MySQL server, login info and database should live in the~/.my.cnfconfig file, in an addrwatch section. here's what that file looks like:
[addrwatch]
host=localhost
user=db_user
password=db_password
database=db_name
the pairings get written into a table with this schema:
CREATE TABLE IF NOT EXISTS `addrwatch` (
`tstamp` timestamp NOT NULL,
`hostname` varchar(256) NOT NULL,
`interface` varchar(16) NOT NULL,
`vlan_tag` int(11) NOT NULL,
`mac_address` varchar(17) NOT NULL,
`ip_address` varchar(42) NOT NULL,
`origin` varchar(8) NOT NULL,
KEY `interface` (`interface`),
KEY `vlan_tag` (`vlan_tag`),
KEY `interface_vlan_tag` (`interface`,`vlan_tag`)
)
default table name is addrwatch unless you pass --mysql-table. slay π
- *
--mysql-table=TBL* β insert the data into MySQL table TBL instead. custom naming rights, iconic β¨ - *
-s*sqlite3.db,--sqlite3=sqlite3.db β write discovered ethernet/ip pairings to a sqlite3 database in the sqlite3.db file. the database file and the tables get created during startup if they don't already exist. self-sufficient queen π
pairings go into a table with this schema:
CREATE TABLE addrwatch(
timestamp UNSIGNED BIG INT,
interface varchar(16),
vlan_tag UNSIGNED INT,
mac_address varchar(17),
ip_address varchar(42),
origin TINYINT
);
-q,--quietβ suppress any output to stdout and stderr. silence. serenity. π€«-v,--verboseβ turn on debug messages. we're nosy now π-4,--ipv4-onlyβ capture only IPv4 packets. four only π-6,--ipv6-onlyβ capture only IPv6 packets. six only π- *
-b*ip,--blacklist=ip β ignore pairings that involve the specified ip address. not on my watch π - *
-r*num,--ratelimit=num β the dupe control. here's the breakdown:- if num > 0, ratelimit duplicate ethernet/ip pairings to 1 every num seconds.
- if num = 0, ratelimiting of duplicate entries is disabled.
- if num = -1, duplicate entries are suppressed indefinitely.
- more details in the RATELIMITING section, go read it, i'll wait π§
- *
-H*size,--hashsize=size β the size of the ratelimiting hash table used to store recent ethernet/ip address pairings. minimum value is1, maximum value is65536. default value is1(which means no hash table, and all pairings are stored in a linked list instead).- bump the hash table size up in active networks with lots of nodes. a lager hash table speeds up cache lookups, but it costs you more memory usage. tradeoffs, bestie π
-d,--daemonβ become a daemon after start. this option implies the-q(--quiet) argument. it's a package deal π- *
-h*hostname,--hostname=hostname β override the system hostname. main character energy, rename yourself π - *
-p*pidfile,--pid=pidfile β write the process id to pidfile. the pidfile gets deleted when the application is terminated. this option is usually used together with the-d(--daemon) argument. heads up though: when it's used with the-u(--user) argument, the pidfile will be created before changing the active user, and in most cases addrwatch will not be able to delete the pidfile on exit. so it just... lingers. ghost pidfile π» -P,--no-promiscβ disable promisc mode on network interfaces. minding its own business, respectfully πΈ- *
-u*user,--user=user β suid to user after opening the network interfaces. -?,--helpβ show the command line arguments.--usageβ give a short usage message.-V,--versionβ print the program version. identity check β¨
β¨ OUTPUT β¨
in the output file (or stdout), each line = one ethernet/ip address pairing discovery event. every event has this format: unix timestamp, interface, vlan tag, mac address, ip address and packet type, all separated by a space. no commas, just vibes π
packets that don't have a vlan tag get represented by the tag value 0.
the possible packet types are ARP_REQ, ARP_REP, ARP_ACD, ND_ND, ND_NA, ND_DAD. the ethernet address and the IP address get pulled from different parts of the packet depending on the packet type. here's the breakdown:
ARP_REQβ ARP Request packet. the sender hardware address (from the ARP header) and the sender protocol address (from the ARP header) get saved.ARP_REPβ ARP Reply packet. the sender hardware address (from the ARP header) and the sender protocol address (from the ARP header) get saved.ARP_ACDβ ARP Address collision detection packet. the sender hardware address (from the ARP header) and the target protocol address (from the ARP header) get saved.ND_NSβ Neighbor Solicitation packet. the source link-layer address (from the NS option) and the source address (from the IPv6 header) get saved.ND_NAβ Neighbor Advertisement packet. the target link-layer address (from the NA option) and the source address (from the IPv6 header) get saved.ND_DADβ Duplicate Address Detection packet. the source MAC (from the Ethernet header) and the target address (from the NS header) get saved.
output example, look at her go π
timestamp iface vlan mac ip type
1339405924 eth0 502 e0:ca:94:30:06:8b 2001:db8:200:4202:8946:e6b7:976a:cef3 ND_NA
1339406009 eth0 257 f0:4d:a2:2e:ad:0d 169.254.227.85 ARP_ACD
1339406018 eth0 502 58:1f:aa:d0:92:7d 2001:db8:200:4202:805d:b5ae:8374:436c ND_DAD
1339406029 eth0 502 38:59:f9:3a:de:65 172.16.2.19 ARP_REP
1339406030 eth0 12 00:c0:ee:5a:89:c7 10.1.32.221 ARP_REQ
1339406030 eth0 252 00:1c:c0:79:ab:ee 2001:db8:200:2381::657b ND_NS
β¨ RATELIMITING β¨
if you run it without ratelimiting, addrwatch reports an ethernet/ip pairing every single time it gets a usable ARP or IPv6 ND packet. and in actively used networks? that generates a LOT of duplicate pairings, especially for routers and servers. it's spam. it's a group chat with no mute button π
the ratelimiting option -r num (--ratelimit=num) suppresses the output of duplicate pairings for at least NUM seconds. all non-duplicate pairings still get reported, don't worry. in other words: if addrwatch has discovered some pairing (mac,ip), it will not report that same (mac,ip) again unless NUM seconds have passed. π
but wait β there's an exception, and it exists so we can still track ethernet address changes. if addrwatch has discovered these pairings:
(mac1,ip), (mac2,ip), (mac1,ip)
all within the ratelimit time window, it will report all three pairings. this way ratelimiting doesn't lose any information about ethernet address changes. smart. iconic. ate π
so for example, if we have a stream of events like this:
time ethernet ip
01 11:22:33:44:55:66 192.168.0.1
15 11:22:33:44:55:66 192.168.0.1
20 aa:bb:cc:dd:ee:ff 192.168.0.1
25 aa:bb:cc:dd:ee:ff 192.168.0.1
30 11:22:33:44:55:66 192.168.0.1
35 11:22:33:44:55:66 192.168.0.1
40 aa:bb:cc:dd:ee:ff 192.168.0.1
65 aa:bb:cc:dd:ee:ff 192.168.0.1
with --ratelimit=100 we would get:
time ethernet ip
01 11:22:33:44:55:66 192.168.0.1
20 aa:bb:cc:dd:ee:ff 192.168.0.1
30 11:22:33:44:55:66 192.168.0.1
40 aa:bb:cc:dd:ee:ff 192.168.0.1
without that exception, the output would be:
time ethernet ip
01 11:22:33:44:55:66 192.168.0.1
20 aa:bb:cc:dd:ee:ff 192.168.0.1
and then we would lose the information that the address 192.168.0.1 was used by 11:22:33:44:55:66 between the 30th and 40th seconds. gone. deleted. not the vibe π
so to sum it all up: ratelimiting reduces the amount of duplicate information without losing any ethernet address change events. best of both worlds, we love a balanced queen β¨
the ratelimit option essentially limits the data granularity for IP address usage duration information β meaning when and for what time period a specific IP address was used. on the other hand, if you don't ratelimit at all, you wouldn't get very precise IP address usage duration info anyway, because some hosts might use an IP address without sending ARP or ND packets as often as other hosts do. it's not a you problem, it's a them problem π
- if num is set to
0, ratelimiting is disabled and all pairing discovery events are reported. - if num is set to
-1, ratelimiting is enabled with an infinitely long time window, therefore all duplicate pairings are suppressed indefinitely. in this mode addrwatch acts almost as arpwatch, with the exception that ethernet address changes are still reported. almost identical twin behavior π―
okay so it might look tempting to always run addrwatch with --ratelimit=-1, but if you do that you lose the information about when and for what period of time a specific IP address was used. there would be no difference between a temporary IPv6 address that was used once and a statically configured permanent address. and that's a loss, bestie. don't do it π
β¨ NOTES β¨
you can send the SIGHUP signal to addrwatch to force it to reopen the output file. this may be useful if you're using it in combination with logrotate(8). signal handling, so sophisticated π
β¨ EXAMPLES β¨
start monitoring the first non loopback network interface. output goes to stdout:
addrwatch
start monitoring on multiple interfaces:
addrwatch eth0 eth1 eth2
start addrwatch as a daemon, write output to a file, enable ratelimiting to 1 event per minute:
addrwatch -d -o /var/lib/addrwatch.dat -r 60 eth0
start as a daemon, save the pid file, send output to syslog, ratelimit to 1 event per hour, suid to nobody, monitor multiple interfaces:
addrwatch -d -p /var/run/addrwatch.pid -s -r 3600 -u nobody eth0 eth1 eth3
look at all those flags living their best life π
β¨ SEE ALSO β¨
logrotate(8) πΈ
and that's the whole page, bestie!! this was addrwatch version 0.3, dated 06 Jun 2012, and it's still out here monitoring ethernet/ip pairings like the icon it is. go forth and watch some addresses, i'm obsessed with you π«Άπβ¨
π¦ where this page comes from
- alpine 3.24: addrwatch-doc 1.0.2-r1 Β· GPL-3.0-only
- fedora 43: addrwatch 1.0.2-14.fc43 Β· GPL-3.0-only
- fedora 44: addrwatch 1.0.2-16.fc44 Β· GPL-3.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms