addrwatch - Man Page

ethernet/ip address monitoring tool


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 ...]


addrwatch is a similar software to arpwatch. It main purpose is to monitor  network and log ethernet/ip pairings.

To simply try out addrwatch start it without any arguments. When started without arguments it will open  first non loopback interface and start logging events to the console without  writing anything to disk. All discovered ethernet/ip address pairings will be printed to stdout. All debug, warning, and err messages will be sent to syslog  and printed to stderr.


-l,  --syslog

Log discovered ethernet/ip address pairings to syslog (daemon facility).

-o file, --output=file

Write discovered ethernet/ip address pairings to a specified file. See Output section for more details.

-m[database], --mysql=[database]

Write discovered ethernet/ip address pairings to MySQL database. Default MySQL server, login information and database should be specified in ~/.my.cnf configuration file in addrwatch section. Example of ~/.my.cnf configuration file:


Pairings are written in a table having such schema:

`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 option --mysql-table is specified.


Insert data to MySQL table TBL.

-s sqlite3.db, --sqlite3=sqlite3.db

Write discovered ethernet/ip address pairings to sqlite3 database in sqlite3.db file. Database file and tables are created during startup if does not exists.

Pairings are written in a table having such schema:

CREATE TABLE addrwatch(
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.

-v,  --verbose

Enable debug messages.

-4,  --ipv4-only

Capture only IPv4 packets.

-6,  --ipv6-only

Capture only IPv6 packets.

-b ip, --blacklist=ip

Ignore pairings with specified ip address.

-r num, --ratelimit=num

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. See Ratelimiting section for more details.

-H size, --hashsize=size

Size of ratelimiting hash table used to store recent ethernet/ip address pairings. Minimum value is 1, maximum value is 65536. Default value is 1 (no hash table), all pairings are stored in a linked list.

The size of hash table should be increased in active networks with many nodes. Lager hash table speeds up cache lookups at the cost of increased memory usage.

-d,  --daemon

Become a daemon after start. This option implies -q (--quiet) argument.

-h hostname, --hostname=hostname

Override system hostname.

-p pidfile, --pid=pidfile

Write process id to pidfile. Pidfile is deleted when application is terminated. This option is usually used with -d (--daemon) argument. When used with -u (--user) argument pidfle will be created before changing active user and in most cases addrwatch will not be able to delete pidfile on exit.

-P,  --no-promisc

Disable promisc mode on network interfaces.

-u user, --user=user

Suid to user after opening network interfaces.

-?,  --help

Show command line arguments.


Give a short usage message.

-V,  --version

Print program version.


In output file or stdout each line represents one ethernet/ip address pairing discovery event. Event has following format unix timestamp, interface, vlan tag, mac address, ip address and packet type separated by a space.

Packets without vlan tag is represented by tag value 0.

Possible packet types are ARP_REQ, ARP_REP, ARP_ACD, ND_ND, ND_NA, ND_DAD. Ethernet address and IP address are extracted from different parts of the packet based on packet type.


ARP Request packet. Sender hardware address (from ARP header) and sender protocol address (from ARP header) is saved.


ARP Reply packet. Sender hardware address (from ARP header) and sender protocol address (from ARP header) is saved.


ARP Address collision detection packet. Sender hardware address (from ARP header) and target protocol address (from ARP header) is saved.


Neighbor Solicitation packet. Source link-layer address (from NS option) and source address (from IPv6 header) is saved.


Neighbor Advertisement packet. Target link-layer address (from NA option) and source address (from IPv6 header) is saved.


Duplicate Address Detection packet. Source MAC (from Ethernet header) and target address (from NS header) is saved.

Output example:

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 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 ARP_REP
1339406030 eth0 12 00:c0:ee:5a:89:c7 ARP_REQ
1339406030 eth0 252 00:1c:c0:79:ab:ee 2001:db8:200:2381::657b ND_NS


If used without ratelimiting addrwatch reports etherment/ip pairing every time it gets usable ARP or IPv6 ND packet. In actively used networks it generates many duplicate pairings especially for routers and servers.

Ratelimiting option -r num ( --ratelimit=num ) suppress output of duplicate pairings for at least NUM seconds (all non duplicate pairings will be reported). In other words if addrwatch have discovered some pairing (mac,ip) it will not report (mac,ip) again unless NUM seconds have passed.

There is an exception to this rule to allow tracking ethernet address changes. If addrwatch have discovered pairings: (mac1,ip),(mac2,ip),(mac1,ip) within ratelimit time window it will report all three pairings. By doing so ratelimiting will not loose any information about ethernet address changes.

For example if we have a stream of events:

time   ethernet          ip
01     11:22:33:44:55:66
15     11:22:33:44:55:66
20     aa:bb:cc:dd:ee:ff
25     aa:bb:cc:dd:ee:ff
30     11:22:33:44:55:66
35     11:22:33:44:55:66
40     aa:bb:cc:dd:ee:ff
65     aa:bb:cc:dd:ee:ff

With --ratelimit=100 we would get:

time   ethernet          ip
01     11:22:33:44:55:66
20     aa:bb:cc:dd:ee:ff
30     11:22:33:44:55:66
40     aa:bb:cc:dd:ee:ff

Without the exception output would be:

time   ethernet          ip
01     11:22:33:44:55:66
20     aa:bb:cc:dd:ee:ff

And we would loose information that address was used by 11:22:33:44:55:66 between 30-40th seconds.

To sum up ratelimiting reduces amount of duplicate information without loosing any ethernet address change events.

Ratelimit option essentially limits data granularity for IP address usage duration information (when and for what time period specific IP address was used). On the other hand without ratelimiting at all you would not get very precise IP address usage duration information anyways because some hosts might use IP address without sending ARP or ND packets as often as others do.

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 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.

It might look tempting to always use addrwatch with --ratelimit=-1 however by doing so you loose the information about when and for what period of time specific IP address was used. There will be no difference between temporary IPv6 addressed which was used once and statically configured permanent addresses.


You can send SIGHUP signal to addrwatch to force it reopen output file. It may be useful if used in combination with logrotate(8).


Start monitoring first non loopback network interface. Output will be send to stdout:


Start monitoring on multiple interfaces:

addrwatch eth0 eth1 eth2

Start addrwatch as a daemon, write output to file, enable ratelimiting to 1 event per minute:

addrwatch -d -o /var/lib/addrwatch.dat -r 60 eth0

Start as a daemon, save pid file, send output to syslog, ratelimit to 1 event per hour, suid to nobody, monitor multiple interfaces:

addrwatch -d -p /var/run/ -s -r 3600 -u nobody eth0 eth1 eth3

See Also



06 Jun 2012 addrwatch 0.3 addrwatch man page