# ifconfig: Proper usage of <name> and <description>



## Snurg (Dec 10, 2017)

Usually interfaces seem to be referenced by their id.

However, there are two more fields, <name> and <description>.
I was unable to find any documentation about their intended use.

Now I am unsure what information these are supposed to contain.

Thus my question:
Is it correct that the <name> field is intended to contain a short clear-text interface description, and the <description> field a detailed description, and both fields are of pure human-informational purpose?


----------



## tobik@ (Dec 10, 2017)

Snurg said:


> Is it correct that the <name> field is intended to contain a short clear-text interface description


No, you can give interfaces another name (or id as you call it) i.e. `ifconfig re0 name eth0` will rename re0 and afterwards it will show up as eth0. <description> is just for humans.


----------



## Snurg (Dec 12, 2017)

Thank you very much for clarification, tobik@!
I obviously got that wrong. 

May I ask in that context, is it legal to use the description field in the rc.conf this way?

```
ifconfig_exampleinterface0="inet 11.11.11.11 netmask 0xffffff00 description 'that is a stupid example interface #0'"
```


----------



## obsigna (Dec 12, 2017)

In the ifconfig directives in /etc/rc.conf, I place in the description fields the interface designators WAN, LAN, etc. By this way, I can identify the WAN and LAN interfaces without needing to rely on the device ID of the interface, which might change when I change a NIC.

For example in my ipfw.conf I got the following preamble:

```
for iface in `/sbin/ifconfig -l` ; do
   desc=`/sbin/ifconfig $iface | /usr/bin/sed -n '/.description: /{s///;s/ .*//;p;}'`
   if [ "$desc" == "WAN" ] ; then
      WAN=$iface
   elif [ "$desc" == "LAN" ] ; then
      LAN=$iface
   fi
done
...
...
```
The following ipfw(8) rules refer to $WAN instead of a hard coded device ID of the respective NIC.

In my dyndns-update.sh I put the same preamble in order to find out the public IP of the WAN NIC as follows:

```
...
if [ "$WAN" != "" ] ; then
   newIP=`/sbin/ifconfig $WAN | /usr/bin/sed -n '/.inet /{s///;s/ .*//;p;}'`
fi
...
```
Perhaps, I could have used the renaming facility of ifconfig(8), however, my feeling tells me that the description field is more appropriate for this usage case.


----------



## Snurg (Dec 13, 2017)

obsigna,
although the original intention behind the post was the thought of using the description field for easy association of the loopback interfaces to their particular jail, your examples hit the spot in some manner.

I have been thinking much about the same problem you are telling about.
Because, I need an auto-detection functionality.
My jail admin script should do the PF configuration thing automatically for the user.

However, I do not know an "official" way to tell what is the WAN port.
So my approach is to use the "defaultrouter" entry in
/etc/rc.conf.
And then look which network interfaces match the defaultrouter address with their IP/netmask.
If there is only one match, I guess it is safe to assume that this is the WAN network device.

However, I think there are exceptions like multiple WAN-connected IPs etc. But I have no experience with such, so I have no idea how to handle such things.
And, I don't know how big the percentage of users is who actually have such installations with more than one network connection to the internet.
I do not know, what is correct?
Using one of these addresses or all of them? As this potentially affects the design of the pf.conf templates much, I wish I knew more about that.

Anyway, if you want to take a look:
I have attached the test script for my WAN device autodetection Perl subroutine.
That subroutine gethostipnicgate()...
  ... returns the WAN network device, IP and netmask if it is unambiguous
  ... if there are more than one interface that match with their to the defaultrouter IP,
      then the user gets a list and can choose one of these to use, which then gets returned
  ... or returns "fail" if that method didn't succeed

I have packed that subroutine together with a test stub, so it can be easily tried out interactively.

Here is the script:

```
#!/usr/bin/env perl
use strict;
use warnings;
use POSIX;

my $external_interface;
my $external_ip_bin;
my $external_netmask_bin;
my $file_etc_rc_conf = '/etc/rc.conf';

# string read_a_file( string filename)
sub read_a_file
{
  my $fn = shift;
  local $/ = undef;
  open FILE, $fn or return undef;
  my $text = <FILE>;
  close FILE or return undef;
  return $text;
}

# string sub getipstr( num)
sub getipstr
{
  my $num = shift;
  $num &= 0x00000000ffffffff;    # if i do not mask them out, 255.255.255.0 appears as 511.255.255.0 ?!?
  my $n1 = $num >> 24;
  my $n2 = ($num >> 16) & 255;
  my $n3 = ($num >> 8) & 255;
  my $n4 = $num & 255;
  return "$n1.$n2.$n3.$n4";
}

# num sub getstrip( string)
sub getstrip
{
  my $str = shift;
  (my $d1, my $d2, my $d3, my $d4) = $str =~ /(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3})/;
#  my $num = (int($d1) << 24) & (int($d2) << 16) & (int($d3) << 8) & int($d4);  # why doesnt this work?
  my $num = (($d1 * 256 + $d2) * 256 + $d3) * 256 + $d4;
  return $num;
}

# string sub askvalue (string itemdesc, string defaultvalue, string sanityregexp, string repeatmsg)
sub askvalue
{
  my $itemdesc = shift;
  my $defvalue = shift;
  my $sanityregexp = shift;
  my $repeatmsg = shift;
  my $prompt = (defined $defvalue)
                  ? "$itemdesc   \[$defvalue\] "
                  : "$itemdesc ";

  print( $prompt);
  my $ts;
  for (my $sane = 0; !$sane ;) {
    $ts = <STDIN>;
    chomp $ts;
    $sane = ( (defined $defvalue and $ts eq '') or ($ts =~ m/$sanityregexp/) );
    (print( $repeatmsg)) if !$sane;
  }
  return ($ts =~ /^\S+$/) ? $ts : $defvalue;
}

  # possibly useful info to find out the host ip/NIC:
  # rc.conf:
  #   defaultrouter="xx.xx.xx.xx"
  #   ifconfig_wwwwddd="inet xx.xx.xx.xx netmask 0xxxxxxxxx"
  # -> find interfaces that match defaultrouter with netmask:
  #    -> if there is one, there is no ambiguity, take it
  #    -> if there are more, ask user
# int sub gethostipnicgate()
sub gethostipnicgate
{
  my $defr;
  my $rc_conf = read_a_file( $file_etc_rc_conf );
  my $r = ! defined $rc_conf;
 
  if (!$r) {
    $r = !defined (($defr) = $rc_conf =~ /^defaultrouter\s*?=\s*?\"(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\"\s*?$/ms);
  }
  if (!$r) {
    # get the defaultrouter IP as number
    my $defrip = getstrip( $defr);
    # find the network interface(s) that match it with their netmask
    # does it make sense to counter-check with rc.conf pattern ifconfig_ data?
    my $ifc = qx/ifconfig/;
    my @ifclines = split( /\n/, $ifc);
    my $intfs = -1;
    my @intf_name;
    my @intf_ip;
    my @intf_netmask;
    my @intf_match;
    foreach my $l ( @ifclines) {
      if ( $l =~ /^[a-z]{2,}\d{1,3}.*$/ ) {        # new interface section
        ++$intfs;
        ($intf_name[ $intfs]) = $l =~ /^([a-z]{2,}\d{1,3})\: .*$/;
      } elsif ( $l =~ /^\s+?inet\s\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}\snetmask.*$/ ) {
        (my $tip, my $tnm) = $l =~ /^\s+inet\s(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\snetmask\s([x0-9a-f]{10}).*$/;
        $intf_ip[ $intfs] = getstrip( $tip);
        $intf_netmask[ $intfs] = hex( $tnm);
    } }
    # now we should have three arrays
    # walk through every entry and count the matches of their subnets with default gateway
    print "Interfaces found:";
    my $n = scalar @intf_name;
    for ( my $i = 0; $i < $n; ++$i) {
      print "\n  $intf_name[ $i] ";
      if (!defined $intf_ip[ $i]) {
        print "has no IP";
        next;
      }
      print 'has IP: ' . getipstr( $intf_ip[ $i]) . ' and netmask: ' . getipstr( $intf_netmask[ $i]);
      if ( (int($defrip) & int($intf_netmask[ $i])) == (int($intf_ip[ $i]) & int($intf_netmask[ $i])) ) {
        push @intf_match, $i;      # match
        print ', which matches';
    } }
    print "\n\n";
    my $matchcnt = scalar @intf_match;
    if ($matchcnt != 1) {
      if ($matchcnt == 0 ) {
        $r = 1;
        print "I seem unable to find a WAN interface.\n";
      } else {
        print "Choose one of these interfaces, please.\n";
        my $ilistre = '';
        for ( my $i = 0; $i < $matchcnt; ++$i) {
          my $iname = $intf_name[ $intf_match[ $i]];
          $ilistre .= (length( $ilistre)) ? "|$iname" : $iname;
          print "  Interface: <$iname>  " .
                "IP: <" . getipstr( $intf_ip[ $intf_match[ $i]]) . ">  " .
                "netmask: <" . getipstr( $intf_netmask[ $intf_match[ $i]]) . ">\n";
        }
        my $sel = askvalue("Enter <$ilistre>", undef, $ilistre, "Please enter one of those <$ilistre>");
        for ( my $i = 0; $i < $n; ++$i) {
          if ($sel eq $intf_name[ $i]) {
            $external_interface = $intf_name[ $i];
            $external_ip_bin = $intf_ip[ $i];
            $external_netmask_bin = $intf_netmask[ $i];
            last;
    } } } } else {
      my $match = $intf_match[ 0];
      $external_interface = $intf_name[ $match];
      $external_ip_bin = $intf_ip[ $match];
      $external_netmask_bin = $intf_netmask[ $match];
  } }
  return $r;
}

# main part
my $r = gethostipnicgate();
if (!$r) {
  print "WAN interface: <$external_interface>\n";
  print "External IP:   <" . getipstr( $external_ip_bin) . ">\n";
  print "Ext. netmask:  <" . getipstr( $external_netmask_bin) . ">\n";
}
```

(Maybe it could be easy to modify that scripts' output so it can be used from shell scripts, like for your needs?)


----------



## tobik@ (Dec 13, 2017)

obsigna said:


> In the ifconfig directives in /etc/rc.conf, I place in the description fields the interface designators WAN, LAN, etc. By this way, I can identify the WAN and LAN interfaces without needing to rely on the device ID of the interface, which might change when I change a NIC.


I would assign the interfaces to groups instead i.e. `ifconfig re0 group WAN`. Once done you can easily look up interfaces belonging to a group with `ifconfig -g WAN`.
In pf.conf you can use group names in place of interfaces as well. Not sure if that works with IPFW.


----------



## Snurg (Dec 13, 2017)

Wow, that's cool! Thank you tobik@ for pointing at the grouping feature!
A WAN group could be helpful to find out with more certainty which one of these is active.
Jail group(s) could help managing multiple jails at once.
For example, if you work on a site that is composed of several webservers jailed separately, you could start/stop the whole thing easily, and do other things, like reconfiguring the access settings for them all at once (PF).

That's great food for thinking  Thanks to you all again!


----------

