The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 2,466 other followers

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:

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:

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 request
  • dhcp_message_type: the type of DHCP response from the DHCP server
  • server_identifier: IPv4 of the responding DHCP server
  • lease_time: DHCP lease time in seconds (0xd2f00 is one day, 0x78 is 2 minutes)
  • subnet_mask: network mask for yiaddr
  • router: list of IP addresses to route IPv4 traffic through
  • domain_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

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

 
%d bloggers like this: