Listing information on all active interfaces on MacOS part 2: adding DHCP/BOOTP and routing details
Posted by jpluimers on 2021/07/27
This is a continuation of yesterdays
Listing information on all active interfaces on MacOS part 1: getting the active interface names.
It is based on ideas in these StackExchange posts:
- [WayBack] shell – Extracting ip address and interface name from ifconfig – Stack Overflow
- [WayBack] bash – Show active interfaces in terminal – Stack Overflow
I threw most of the implementation details in the ideas away, as they were way to much based on empirical trial and error, than proper research.
So I tried doing the research and came up with the things below.
Getting the IPv4 address and DHCP/BOOTP information of a NIC
By using the ipconfig
command, you can get specific details for a NIC like an IPv4 (with the getifaddr
) or DHCP (with the getpacket
option to get the latest DHCP packet):
for i in $(ifconfig -l -u); do if ifconfig $i | grep -q "status: active" ; then echo $i; fi; done | xargs -n1 -I_nic_ sh -c 'echo "_nic_: $(ipconfig getifaddr _nic_)"'
or DHCP/BOOTP:
for i in $(ifconfig -l -u); do if ifconfig $i | grep -q "status: active" ; then echo $i; fi; done | xargs -n1 -I_nic_ sh -c 'echo "_nic_: $(ipconfig getpacket _nic_)"'
The latter returns a very long list, which I wanted to shorten into a more readable format.
ipconfig syntax
You can find more information in the [Archive.is] ipconfig(8) [osx man page] / [WayBack] ipconfig Man Page – macOS – SS64.com excerpt:
NAME ipconfig -- view and control IP configuration state SYNOPSIS ... ipconfig getifaddr interface-name ... ipconfig getoption interface-name (option-name | option-code) ipconfig getpacket interface-name ... DESCRIPTION ipconfig is a utility that communicates with the IPConfiguration agent to retrieve and set IP configuration parameters. It should only be used in a test and debug context. Using it for any other purpose is strongly discouraged. Public API's in the SystemConfiguration frame- work are currently the only supported way to access and control the state of IPConfiguration. COMMANDS The ipconfig utility provides several commands: ... getifaddr interface-name Prints to standard output the IP address for the first network service associated with the given interface. The output will be empty if no service is currently configured or active on the interface. ... getoption interface-name (option-name | option-code) Prints the BOOTP/DHCP option with the given name or option code integer value. See bootpd(8) for option code names. If an option has multiple values e.g. domain_name_server, only the first value is printed. getpacket interface-name Prints to standard output the DHCP/BOOTP packet that the client accepted from the DHCP/BOOTP server. This command is useful to check what the server provided, and whether the values are sensible. This command outputs nothing if DHCP/BOOTP is not active on the interface, or the attempt to acquire an IP address was unsuccessful. ...
Filtering on the DHCP fields and options: what are their names?
You can either filter these based on the option-name
, or specify any option-name
with getoption
.
Note thet DHCP servers if supporting BOOTP (most – if not all – do), favour BOOTP responses over DHCP responses, see:
- [WayBack] Dynamic Host Configuration Protocol – Wikipedia
- [WayBack] Dynamic Host Configuration Protocol (DHCP) and Bootstrap Protocol (BOOTP) Parameters
- [WayBack] RFC 951 – Bootstrap Protocol
- [WayBack] RFC 1395 – BOOTP Vendor Information Extensions
- [WayBack] RFC 1497 – BOOTP Vendor Information Extensions
- [WayBack] RFC 1532 – Clarifications and Extensions for the Bootstrap Protocol
- [WayBack] RFC 1533 – DHCP Options and BOOTP Vendor Extensions
- [WayBack] RFC 1534 – Interoperation Between DHCP and BOOTP
- [WayBack] RFC 1542 – Clarifications and Extensions for the Bootstrap Protocol
- [WayBack] RFC 2131 – Dynamic Host Configuration Protocol
- [WayBack] RFC 2132 – DHCP Options and BOOTP Vendor Extensions
- [WayBack] RFC 2939 – Procedures and IANA Guidelines for Definition of New DHCP Options and Message Types
All options are listed with getpacket
, for example on one of my systems:
# for i in $(ifconfig -l -u); do if ifconfig $i | grep -q "status: active" ; then echo $i; fi; done | xargs -n1 -I_nic_ sh -c 'echo "Information on _nic_:" && ipconfig getpacket _nic_' Information on en0: op = BOOTREPLY htype = 1 flags = 0 hlen = 6 hops = 0 xid = 0x43a5d3ee secs = 1 ciaddr = 0.0.0.0 yiaddr = 192.168.171.47 siaddr = 192.168.171.1 giaddr = 0.0.0.0 chaddr = c4:b3:1:c5:f8:db sname = file = options: Options count is 10 dhcp_message_type (uint8): ACK 0x5 server_identifier (ip): 192.168.171.1 lease_time (uint32): 0xd2f00 renewal_t1_time_value (uint32): 0x69780 rebinding_t2_time_value (uint32): 0xb8920 subnet_mask (ip): 255.255.255.0 router (ip_mult): {192.168.171.1} domain_name_server (ip_mult): {192.168.171.1} domain_name (string): fritz.box end (none): Information on awdl0: Information on en10: op = BOOTREPLY htype = 1 flags = 0 hlen = 6 hops = 0 xid = 0x35b4bdbc secs = 0 ciaddr = 192.168.1.63 yiaddr = 192.168.1.63 siaddr = 0.0.0.0 giaddr = 0.0.0.0 chaddr = a0:ce:c8:c0:96:29 sname = file = options: Options count is 7 dhcp_message_type (uint8): ACK 0x5 server_identifier (ip): 192.168.1.1 lease_time (uint32): 0x78 subnet_mask (ip): 255.255.255.0 router (ip_mult): {192.168.1.1} domain_name_server (ip_mult): {192.168.1.1} end (none):
Filtering on meaningful fields/options
A shorter list with filtering on these fields and options:
ciaddr
: original client address (that asked for a DHCP packet)yiaddr
: your address (the DHCP assigned address for the client)chaddr
: MAC address used by the client in the DHCP requestdhcp_message_type
: the type of DHCP response from the DHCP serverserver_identifier
: IPv4 of the responding DHCP serverlease_time
: DHCP lease time in seconds (0xd2f00
is one day,0x78
is 2 minutes)subnet_mask
: network mask foryiaddr
router
: list of IP addresses to route IPv4 traffic throughdomain_name_server
: list of IP addresses for DNS requests
So filtered, the statement becomes:
# for i in $(ifconfig -l -u); do if ifconfig $i | grep -q "status: active" ; then echo $i; fi; done | xargs -n1 -I_nic_ sh -c 'echo "Information on _nic_:" && ipconfig getpacket _nic_' | grep "Information on \|ciaddr\|yiaddr\|chaddr\|subnet_mask\|server_identi;2Cfier\|lease_time\|ip_mult" Information on en0: ciaddr = 0.0.0.0 yiaddr = 192.168.171.47 chaddr = c4:b3:1:c5:f8:db lease_time (uint32): 0xd2f00 subnet_mask (ip): 255.255.255.0 router (ip_mult): {192.168.171.1} domain_name_server (ip_mult): {192.168.171.1} Information on awdl0: Information on en10: ciaddr = 192.168.1.63 yiaddr = 192.168.1.63 chaddr = a0:ce:c8:c0:96:29 lease_time (uint32): 0x78 subnet_mask (ip): 255.255.255.0 router (ip_mult): {192.168.1.1} domain_name_server (ip_mult): {192.168.1.1}
Adding routing information
Often network issues relate to routing as much as they do on address resolving, so I also use the below command in an alias that I can remember.
The below answer is based on the very dense netstat documentation, especially the [Archive.is] netstat(8) [osx man page] excerpt (note that inet
means IPv4):
NAME netstat -- show network status SYNOPSIS ... netstat -r [-Aaln] [-f address_family] DESCRIPTION The netstat command symbolically displays the contents of various network-related data structures. There are a number of output formats, depending on the options for the information presented. ... The seventh form displays routing table for the specified address family. ... -f address_family Limit statistics or address control block reports to those of the specified address family. The following address families are rec- ognized: inet, for AF_INET, inet6, for AF_INET6 and unix, for AF_UNIX. ... -n Show network addresses as numbers (normally netstat interprets addresses and attempts to display them symbolically). This option may be used with any of the display formats. ... -r Show the routing tables. Use with -a to show protocol-cloned routes. When -s is also present, show routing statistics instead. When -l is also present, netstat assumes more columns are there and the maximum transmission unit (``mtu'') are also displayed. ... The routing table display indicates the available routes and their status. Each route consists of a destination host or network and a gateway to use in forwarding packets. The flags field shows a collection of information about the route stored as binary choices. The individual flags are discussed in more detail in the route(8) and route(4) manual pages. The mapping between letters and flags is: 1 RTF_PROTO1 Protocol specific routing flag #1 2 RTF_PROTO2 Protocol specific routing flag #2 3 RTF_PROTO3 Protocol specific routing flag #3 B RTF_BLACKHOLE Just discard packets (during updates) b RTF_BROADCAST The route represents a broadcast address C RTF_CLONING Generate new routes on use c RTF_PRCLONING Protocol-specified generate new routes on use D RTF_DYNAMIC Created dynamically (by redirect) G RTF_GATEWAY Destination requires forwarding by intermediary H RTF_HOST Host entry (net otherwise) I RTF_IFSCOPE Route is associated with an interface scope i RTF_IFREF Route is holding a reference to the interface L RTF_LLINFO Valid protocol to link address translation M RTF_MODIFIED Modified dynamically (by redirect) m RTF_MULTICAST The route represents a multicast address R RTF_REJECT Host or net unreachable r RTF_ROUTER Host is a default router S RTF_STATIC Manually added U RTF_UP Route usable W RTF_WASCLONED Route was generated as a result of cloning X RTF_XRESOLVE External daemon translates proto to link address Y RTF_PROXY Proxying; cloned routes will not be scoped
[WayBack] ip – Which short command to only output the IPv4 routing table? – Ask Different by [WayBack] Pro-Backup:
$ netstat -nr -f inet Routing tables Internet: Destination Gateway Flags Refs Use Netif Expire default 192.168.1.254 UGSc 10 0 en4 default 10.0.2.1 UGScI 0 0 ppp0 10 ppp0 USc 0 0 ppp0
One problem is that in the mean time, netstat
has added a lot of information on local MAC addresses as well.
At first I tried to filter them out based on the above flags. That was way too cumbersome,.
So I now filter them out using the MAC address syntax with the opposite of [WayBack] regex – Best way to extract MAC address from ifconfig’s output? – Stack Overflow (by [WayBack] Robert Gamble):
ifconfig eth0 | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'
The
-o
will cause grep to only print the part of the line that matches the expression.[[:xdigit:]]{1,2}
will match 1 or 2 hexidecimal digits (Solaris doesn’t output leading zeros).
So I added the -v
option (negate) and kept the -E
option (extended regular expression), see [WayBack] grep – Wikipedia and [WayBack] Regular expression: POSIX basic and extended – Wikipedia.
On my system, the output is still more complex:
# netstat -r -n -f inet | grep -v -E '([[:xdigit:]]{1,2}[:-]){5}[[:xdigit:]]{1,2}' Routing tables Internet: Destination Gateway Flags Refs Use Netif Expire default 192.168.1.1 UGSc 66 0 en10 default 192.168.171.1 UGScI 4 0 en0 127 127.0.0.1 UCS 0 131 lo0 127.0.0.1 127.0.0.1 UH 2 4598 lo0 169.254 link#13 UCS 1 0 en10 169.254 link#7 UCSI 0 0 en0 192.168.1 link#13 UCS 14 0 en10 192.168.1.1/32 link#13 UCS 1 0 en10 192.168.1.63/32 link#13 UCS 0 0 en10 192.168.171 link#7 UCS 1 0 en0 192.168.171.1/32 link#7 UCS 1 0 en0 192.168.171.47/32 link#7 UCS 0 0 en0 224.0.0/4 link#13 UmCS 2 0 en10 224.0.0/4 link#7 UmCSI 1 0 en0 255.255.255.255/32 link#13 UCS 1 0 en10 255.255.255.255/32 link#7 UCSI 0 0 en0
–jeroen
Leave a Reply