Provided by: libnet-interface-perl_1.016-2ubuntu3_amd64 bug

NAME

       Net::Interface::Developer - api, notes, hints

DESCRIPTION

       This contains development notes and API documentation for the Net::Interface module. It is hoped that
       others will help fill in the missing pieces for OS's and address families that are currently unsupported.

ARCHITECTURE

       Net::Interface gathers information about the network interfaces in an OS independent fashion by first
       attempting to use "getifaddrs" if "getifaddrs" is not supported on the OS it falls back to using system
       "ioctl's" and the "ifreq, in6_ifreq, lifreq" structures defined on the local host. Linux differs somewhat
       since ipV6 information is available only directly from the kernel on older versions where "getifaddrs" is
       not available. The "ifreq" and friends information is used to generate a "getifaddrs" response.

       Herein lies the need for continued development by the opensource community.  Many OS's have peculiar
       "ioctl" variants and SIOC's variants that require unique code solutions. I'm sure that all of them are
       not presently included.

       Net::Interface is built in 5 layers, listed below from the base up.

   description:   files          code
   1) AF_xxx families: ni_af_inetcommon.c  (C)
       Code modules for AF families. Currently supported are AF_INET, AF_INET6. There is partial support for
       AF_LINK and AF_PACKET for retrieval of MAC address from the interface where it is needed. Where the code
       is reasonably universal for a particular address family and the methods used to retrieve the information
       from the OS, it resides in an af_xxxx.c file.

   2) IFREQ families: ni_xx_ifreq.c   (C)
       Code modules for IFREQ families. Currently supported are:

       • "ifreq" ni_ifreq.c

         Provides support for retrieval of ipV4 information. The structure "ifreq" does not provide enough space
         to return data about socket address families larger than "struct sockaddr". All known operating systems
         support this flavor of data retrieval. ni_ifreq.c makes use of calls to ni_af_inet.c

       • "in6_ifreq" ni_in6_ifreq.c

         Provides  support  for  retrieval  of  both  ipV4  and  ipV6  information.   "in6_ifreq"  uses  "struct
         sockaddr_storage" rather than the smaller "struct sockaddr" that is used in "ifreq". This code  modules
         support  variants  of  the  BSD  operating  system and a few others. ni_in6_ifreq makes use of calls to
         ni_af_inetcommon.c

       • "lifreq" ni_lifreq.c

         Provides support for retrieval of both ipV4 and ipV6 information. "lifreq" has a custom  format  unique
         to  the  SUN  operating  systems.  Pretty much everything in it, while similar to the two previous code
         modules, is custom.

       • "linuxproc" ni_linuxproc.c

         Provides support for  retrieval  of  both  ipV4  and  ipV6  information.   "linuxproc"  uses  calls  to
         ni_af_inet.c  to  get  ipV4  information  int  "getifaddrs" format and custom code to collect similarly
         formatted ipV6 information directly from the /proc file system. It then performs a merge on  these  two
         data  sets  to  put  them  into  proper  order  and  add  fake  AF_LINK or AF_PACKET records to provide
         "getifaddrs" compatiable access to the MAC address through the returned "struct ifaddrs" array.

   3) "getifaddrs" ni_getifaddrs.c    (C)
       The "getifaddrs" code module contains the decision mechanism for how data is retrieved for  a  particular
       build  of  Net::Interface.  At  build  time,  portions  of  the code are #ifdef'd in/out depending on the
       availabiltiy of resource from the underlying OS. In addition, at run time, if the system  does  not  have
       native  "getifaddrs"  then  a  decision  tree  is used depending on the response to calls for data to the
       various code modules described in section 2).

   4) Sub-system Interface.xs    (PERLXS)
       This file asks for the data about the interfaces with a generic call to "getifaddrs". The  data  returned
       resides in memory allocated by the OS and must be freed or a memory leak will result as it is not tracked
       by  Perl's  garbage  collector.  "Interface.xs"  moves  the  interface data from allocated memory to Perl
       managed memory where it can be reclaimed by the garbage  collection  mechanism  if/when  the  user  space
       program  turns  it  loose.  This  eliminates  the need for a "close" operation to free the OS's allocated
       memory.

   5) User space Interface.pm    (Perl)

DATA FLOW BLOCK DIAGRAM

       The pure perl portion of this module performs most of the presentation operations for the user  that  are
       published in the API for Net::Interface.

               *\  \  \    |    /  /  /*
               *      user space       *
               *************************
                           ^                                Net::Interface
                           |                           Architecture Block Diagram
                           v
               *************************
               *      Interface.pm     *
               *************************
                           |
               *************************
               *      Interface.xs     *
               *************************
                           |
               *************************               *************************
               *   system getifaddrs   *               *      ni_getifreqs     *
               *          via          *<-if missing ->*           via         *
               *   (ni_getifaddrer.c)  *               *    (ni_ifreq.c)       *
               *************************               *    (ni_lifreq.c)      *
                                                       *    (ni_in6_ifreq.c)   *
                                                       *    (ni_linuxproc.c)   *
                                                       *************************
                                                                   |
                                                       *************************
                                                       *  (ni_af_inetcommon.c) *
                                                       *************************

DEVELOPER API

       Access  to  the  pieces  of  code in the block diagram above are available through a developer API. These
       codes snippets from Interfaces.xs describe the access.

        void
        __developer(ref)
               SV *ref
           ALIAS:
               d_ni_ifreq      = NI_IFREQ
               d_ni_lifreq     = NI_LIFREQ
               d_ni_in6_ifreq  = NI_IN6_IFREQ
               d_ni_linuxproc  = NI_LINUXPROC
           PREINIT:
               char * process;
               int er = ni_developer(ix);

       and.....

        void
        gifaddrs_base(ref)
               SV * ref
           ALIAS:
        #      base            = 0
               gifa_ifreq      = NI_IFREQ
               gifa_lifreq     = NI_LIFREQ
               gifa_in6_ifreq  = NI_IN6_IFREQ
               gifa_linuxproc  = NI_LINUXPROC
           PREINIT:
               struct ifaddrs * ifap;
               int rv;
           CODE:
               if ((rv = ni_getifaddrs(&ifap,ix)) == -1) {
                   printf("failed PUNT!\n");
                   XSRETURN_EMPTY;

       Both function sets result in a printed description to the terminal window to facilitate code creation and
       debug. Currently the ref is unused. It is expected that future development will modify or add to function
       access.

         # test.pl for developer
         #
         use strict;
         use Net::Interface;

         # to call OS native getifaddrs if present
         print "\nifreq\n";  gifaddrs_base Net::Interface();

         # to call ni_linuxproc fallback getifaddrs
         print "\nlxp\n";    gifa_linuxproc Net::Interface();

         # to call ni_linuxproc ifreq emulation
         print "\nglxp\n";   d_ni_linuxproc Net::Interface();

       See: test.pl.developer

DEVELOPER API DESCRIPTION

       If you have gotten this far, it is time to read some of  the  code.  AF_familes  and  IFREQ_families  are
       accessed  through constructor structs found at the bottom of each of the ni_af_xxx and ni_xx_ifreq source
       files. Their vectoring components are described in "ni_func.h" near the bottom and in "ni_util.c" in  the
       section labeled constructor registration the essence of which is described here.

         struct ni_ifconf_flavor * ni_ifcf_get(enum ni_FLAVOR type)
         struct ni_ifconf_flavor * ni_safe_ifcf_get(enum ni_FLAVOR type);

         nifp = ni_ifcf_get(NI_IFREQ);

       Returns a pointer "nifp" to the structure for a particular flavor of ifreq. If a flavor is unsupported on
       a  particular  architecture  a  NULL  is  returned  by  the  first invocation and NI_IFREQ by the second.
       Currently supported flavors are:

         enum ni_FLAVOR {
               NI_NULL,        reserved for the getifaddrs base system call
               NI_IFREQ,
               NI_LIFREQ,
               NI_IN6_IFREQ,
               NI_LINUXPROC
         };

         struct ni_ifconf_flavor {
           enum ni_FLAVOR              ni_type;
           int                         (*gifaddrs)
           int                         siocgifindex;
           int                         siocsifaddr;
           int                         siocgifaddr;
           int                         siocdifaddr;
           int                         siocaifaddr;
           int                         siocsifdstaddr;
           int                         siocgifdstaddr;
           int                         siocsifflags;
           int                         siocgifflags;
           int                         siocsifmtu;
           int                         siocgifmtu;
           int                         siocsifbrdaddr;
           int                         siocgifbrdaddr;
           int                         siocsifnetmask;
           int                         siocgifnetmask;
           int                         siocsifmetric;
           int                         siocgifmetric;
           int                         ifr_offset;
           void                        (*fifaddrs)      howto free ifaddrs
           int                         (*refreshifr)    howto refresh ifreq
           void *                      (*getifreqs)     howto get ifreq
           int                         (*developer)     developer access
           struct ni_ifconf_flavor *   ni_ifcf_next;
         };

MACROS

       NI_PRINT_MAC(u_char * hex_mac_string);
             printf statement for terminal output of the form

                   XX:XX:XX:XX:XX:XX:XX:XX

       NI_MAC_NOT_ZERO(u_char * hex_mac_string)
             if( NI_MAC_NOT_ZERO(macp))
                   do something

       NI_PRINT_IPV6(struct sin6_addr);
             Takes an argument of the form sockaddr_in6.sin6_addr and prints

                   XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX

FUNCTIONS

       int ni_clos_reopn_dgrm(int fd, int af)
           Closes and then opens an "ioctl" socket of type SOCK_DGRAM and  returns  the  socket  value.  If  the
           socket value is NEGATIVE, no close is attempted an the call is equivalent to:

             socket(af,SOCK_DGRAM,0)

       void ni_gifa_free(struct ifaddrs * ifap, int flavor)
           Use the appropriate free memory function call depending on the flavor of the getifaddrs function that
           returned the ifaddrs structure list.

       int nifreq_gifaddrs(struct ifaddrs **ifap, struct ni_ifconf_flavor *nifp)
           Our semi-standard version of "getifaddrs" used by OS's that provide "ifreq" and "in6_ifreq".

           NOTE:  all  calls  to  "getifaddrs"  return  -1  on failure and and the FLAVOR as enumerated above on
           success.

             i.e. NI_NULL for the native getifaddrs, NI_IFREQ, NI_LINUXPROC, etc...

       uint32_t ni_ipv6addr_gettype(struct in6_addr * in6p)
           Extracts information about the type of ipV6 address. The returned value may be  passed  to  the  NEXT
           function call to print.

       int ni_lx_map2scope(int lscope)
           This function maps Linux style scope bits to their RFC-2373 equivalent.

               scope flags rfc-2373
                   0       reserved
                   1    node-local (aka loopback, interface-local)
                   2    link-local
                   3       unassigned
                   4       unassigned
                   5    site-local
                   6       unassigned
                   7       unassigned
                   8    organization-local
                   9       unassigned
                   A       unassigned
                   B       unassigned
                   C       unassigned
                   D       unassigned
                   E    global scope
                   F       reserved

                 Linux   rfc-2372
                0x0000     0xe     GLOBAL
                0x0010u    0x1     NODELOCAL, LOOPBACK, INTERFACELOCAL
                0x0020u    0x2     LINKLOCAL
                0x0040u    0x5     SITELOCAL

       void ni_linux_scope2txt(uint32_t type)
           Print information about an ipV6 address for each bit present in "type".

             const ni_iff_t ni_lx_type2txt[] = {
                   { IPV6_ADDR_ANY,                "unknown" },
                   { IPV6_ADDR_UNICAST,            "unicast" },
                   { IPV6_ADDR_MULTICAST,          "multicast" },
                   { IPV6_ADDR_ANYCAST,            "anycast" },
                   { IPV6_ADDR_LOOPBACK,           "loopback" },
                   { IPV6_ADDR_LINKLOCAL,          "link-local" },
                   { IPV6_ADDR_SITELOCAL,          "site-local" },
                   { IPV6_ADDR_COMPATv4,           "compat-v4" },
                   { IPV6_ADDR_SCOPE_MASK,         "scope-mask" },
                   { IPV6_ADDR_MAPPED,             "mapped" },
                   { IPV6_ADDR_RESERVED,           "reserved" },
                   { IPV6_ADDR_ULUA,               "uniq-lcl-unicast" },
                   { IPV6_ADDR_6TO4,               "6to4" },
                   { IPV6_ADDR_6BONE,              "6bone" },
                   { IPV6_ADDR_AGU,                "global-unicast" },
                   { IPV6_ADDR_UNSPECIFIED,        "unspecified" },
                   { IPV6_ADDR_SOLICITED_NODE,     "solicited-node" },
                   { IPV6_ADDR_ISATAP,             "ISATAP" },
                   { IPV6_ADDR_PRODUCTIVE,         "productive" },
                   { IPV6_ADDR_6TO4_MICROSOFT,     "6to4-ms" },
                   { IPV6_ADDR_TEREDO,             "teredo" },
                   { IPV6_ADDR_ORCHID,             "orchid" },
                   { IPV6_ADDR_NON_ROUTE_DOC,      "non-routeable-doc" }
             };

       int ni_sizeof_type2txt()
           Returns the size of the above table.

       u_int ni_get_scopeid(struct sockaddr_in6 * sin6)
           On  systems using KAME, this function extracts and returns the scope from field 2 of the ipV6 address
           and sets fields 2,3 to zero. On all other systems it returns

                   sin6->sin6_scopeid

              scope flags     rfc-2373

                   0         reserved
                   1       node-local
                   2       link-local
                   3         unassigned
                   4         unassigned
                   5       site-local
                   6         unassigned
                   7         unassigned
                   8       organization-local
                   9         unassigned
                   A         unassigned
                   B         unassigned
                   C         unassigned
                   D         unassigned
                   E       global scope
                   F         reserved

       void * ni_memdup(void *memp, int size)
           Allocate memory of for size and copy contents from memp. Returns NULL on  error  and  sets  errno  to
           ENOMEM.

       void ni_plen2mask(void * in_addr, int plen, int sizeofaddr)
           Create a NETMASK string from a prefix length

           For ipV4: ni_plen2mask(&in_addr, cidr, sizeof(struct in_addr));

           For ipV6: ni_plen2mask(&in6_addr, cidr, sizeof(struct in6_addr));

       int ni_prefix(void * ap, int len, int size)
           Calculated  the  prefix  length  for  a  NETMASK where *ap points to the binary representation of the
           NETMASK and size is the number of bytes in the mask.

           For ipV4: ni_prefix(&in_addr,sizeof(struct in_addr));

           For ipV6: ni_prefix(&in6_addr,sizeof(struct(in6_addr));

       int ni_refresh_ifreq(int fd, struct ifconf *ifc, void **oifr, void **olifr, struct ni_ifconf_flavor *
       nifp)
           Some OS lose scope on the particular device/addr handle when  certain  ioctl's  are  performed.  This
           function  refreshs  the  ifconf  chain  and  positions the pointers in the exact same spot with fresh
           scope.

           See ni_in6_ifreq.c and ni_af_net6.c for usage. Search for the string refreshifr. Code  snippit  looks
           like:

                   nifp->refreshir

COPYRIGHT

               Copyright 2008-2009 - Michael Robinton

       This  program  is  free  software;  you  can  redistribute it and/or modify it under the terms of the GNU
       General Public License as published by the Free Software  Foundation;  either  version  2,  or  (at  your
       option) any later version.

       This  program  is  distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
       the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General  Public
       License in the file named "Copying" for more details.

       You  should  also  have  received a copy of the GNU General Public License along with this program in the
       file named "Copying". If not, write to the

               Free Software Foundation, Inc.
               59 Temple Place, Suite 330
               Boston, MA  02111-1307, USA

       or visit their web page on the internet at:

               http://www.gnu.org/copyleft/gpl.html.

perl v5.38.2                                       2024-03-31                     Net::Interface::Developer(3pm)