Exploring Network Cards

Exploring Network Cards

Post by Jeffrey Oegem » Fri, 01 Aug 1997 04:00:00



I am attempting to write a script which determines the following
        1) What Network Cards are installed in a machine
        2) and which of these are configured.

        as well as gather some peripheral data.

At this point the script is to run on multiple Solaris 2.5.1
machines.

To get information regarding configured cards, I am using ifconfig -a.
To get information regarding installed, but not configured cards it had
been suggested to me to use prtdiag -v.  While this is somewhat useful
it is very inconvient and produces little data.  Does anyone have a
better idea of how to go about this?

Thanks in advance,

        Jeff Oegema    

 
 
 

Exploring Network Cards

Post by Dan Razze » Fri, 01 Aug 1997 04:00:00



> I am attempting to write a script which determines the following
>    1) What Network Cards are installed in a machine
>    2) and which of these are configured.

>    as well as gather some peripheral data.

> At this point the script is to run on multiple Solaris 2.5.1
> machines.

> To get information regarding configured cards, I am using ifconfig -a.
> To get information regarding installed, but not configured cards it had
> been suggested to me to use prtdiag -v.  While this is somewhat useful
> it is very inconvient and produces little data.  Does anyone have a
> better idea of how to go about this?

You can traverse the system device tree using openprom ioctls, documented
in openprom(7) and available in /usr/include/sys/openpromio.h.  These are
used internally by prtconf and prtdiag.

There is an undocumented system function in libc called modctl which can
be used to report modules loaded into the kernel.  It gets used by
modinfo, modload and modunload and carries about the same amount of
information apparent in these commands, which may not be sufficient for
your needs.  See /usr/include/sys/modctl.h for more information.

Another undocumented system function called devfs_find lives in
libdevinfo.  It can be used to get network devices from the kernel
devinfo tree.  The data then has to be translated into an ifreq
structure as described in if_tcp(7) and found in /usr/include/net/if.h.
Finally the device can be queried by passing this structure to a socket
ioctl such as SIOCGIFFLAGS described in if_tcp(7) and elaborated in
/usr/include/sys/sockio.h.  The socket is opened using:

  socket(AF_INET, SOCK_DGRAM, O_RDONLY)

Essentially this is the internal behavior of ifconfig and certainly provides
many hours of reading pleasure in the best style of network and driver code.

The devfs_find function takes the following arguments:

  char *                        [In your case use DDI_NT_NET for networks]
  void (*)()                    [Callback described below]
  int                           [Use nonzero to check device aliases]

The callback presumably get called once for each matching device and receives
the following arguments:

  const char *                  [Name]
  const char *                  [Type]
  dev_info_t *                  [Devinfo]
  struct ddi_minor_data *       [Device data]
  struct ddi_minor_data *       [Alias data]

By the way, I've never used any of this code and only happened to be
browsing it when I read your message.  Please don't ask me for help
because it will not be informed help.

I'm not aware of any simpler command interfaces suited for use by
scripts.  Such a command would save some of the more arcane uses of
ifconfig, such as is found when deciding whether to enable routing in
/etc/init.d/inetinit.

--

    . o o .     Laboratory for Computational Intelligence
    . >v< .     University of British Columbia
_____mm.mm_____ http://www.cs.ubc.ca/nest/lci

 
 
 

Exploring Network Cards

Post by Dan Razze » Sat, 02 Aug 1997 04:00:00




> Another undocumented system function called devfs_find lives in
> libdevinfo.  It can be used to get network devices from the kernel
> devinfo tree.  The data then has to be translated into an ifreq
> structure as described in if_tcp(7) and found in /usr/include/net/if.h.
> Finally the device can be queried by passing this structure to a socket
> ioctl such as SIOCGIFCONF described in if_tcp(7) and elaborated in
> /usr/include/sys/sockio.h.

Of course I had to take it out for a spin.  It turns out not so bad if
you only want to traverse the configured interfaces.  Those can be found
using well documented ioctls as in the first example below.  The
trickier part is finding interfaces that are present but not configured.
For that you do need to call devfs_find as in the second example.  Left
as an exercise is to then ferret out all the aliases and finally remove
any configured interfaces to find the remainder.

------------------------------------------------------------------------

Example 1: Use of SIOCGIFCONF and friends:

#include <stdio.h>
#include <fcntl.h>

#include <sys/socket.h>
#include <sys/sockio.h>
#include <netinet/in.h>
#include <net/if.h>

#define FALSE           0
#define TRUE            1

#define SYS_ERROR       -1
#define SYS_SUCCESS     0
#define SYS_FAILURE     1

#define IP_DEV_NAME     "/dev/ip"
#define IP_MOD_NAME     "ip"

#define IA(arg) \
  inet_ntoa(((struct sockaddr_in *) &(arg))->sin_addr)

#define EA(arg) \
  ((arg) & 0xFF)

main(int argc, char *argv[])
  {
    int fd, i, n, buflen;
    void *buf;
    struct ifconf ifc;
    struct ifreq *ifr;

    if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) == SYS_ERROR)
      {
        perror("socket");
        exit(SYS_FAILURE);
      }

    if (ioctl(fd, SIOCGIFNUM, &n) == SYS_ERROR)
      {
        perror("ioctl SIOCGIFNUM");
        exit(SYS_FAILURE);
      }

    printf("interfaces: %d\n", n);

    buflen = n * sizeof(struct ifreq);

    if (!(buf = (void *) malloc(buflen)))
      {
        fprintf(stderr, "memory\n");
        exit(SYS_FAILURE);
      }

    ifc.ifc_buf = buf;
    ifc.ifc_len = buflen;

    if (ioctl(fd, SIOCGIFCONF, &ifc) == SYS_ERROR)
      {
        perror("ioctl SIOCGIFCONF");
        exit(SYS_FAILURE);
      }

    ifr = ifc.ifc_req;

    for (i = 0; i < n; i++)
      {
        printf("%2d:\t name: %-6s\n",
          i,
          ifr->ifr_name);
        printf("\t addr: %-16s broadcast: %-16s\n",
          IA(ifr->ifr_addr),
          IA(ifr->ifr_broadaddr));
        printf("\t ether: %0.2x:%0.2x:%0.2x:%0.2x:%0.2x:%0.2x:\n",
          EA(ifr->ifr_enaddr[0]),
          EA(ifr->ifr_enaddr[1]),
          EA(ifr->ifr_enaddr[2]),
          EA(ifr->ifr_enaddr[3]),
          EA(ifr->ifr_enaddr[4]),
          EA(ifr->ifr_enaddr[5]));
        printf("\t flags: 0x%X metric: %3d\n",
          ifr->ifr_flags,
          ifr->ifr_metric);

        ifr++;
      }

    devfs_find(CLASS, devfs_entry, TRUE);

    close(fd);

    exit(SYS_SUCCESS);
  }

------------------------------------------------------------------------

Example 2: Use of devfs_find:

#include <stdio.h>
#include <fcntl.h>

#include <sys/sunddi.h>
#include <sys/ddi_impldefs.h>

#define FALSE           0
#define TRUE            1

#define SYS_ERROR       -1
#define SYS_SUCCESS     0
#define SYS_FAILURE     1

#define CLASS           DDI_NT_NET

static void devfs_entry(const char *devfsname,
  const char *devfstype,
  const dev_info_t *dip,
  struct ddi_minor_data *minor,
  struct ddi_minor_data *alias)
  {
    char *name = NULL;

    printf("name: [%s] type: [%s] code: [%d]\n",
      devfsname, devfstype, minor->type);

    switch (minor->type)
      {
        case DDM_ALIAS:
          printf("type: alias\n");
          name = (char *) local_addr(alias->ddm_name);
          break;
        case DDM_MINOR:
          printf("type: minor\n");
          name = (char *) (local_addr(DEVI(dip)->devi_name));
          break;
        default:
          printf("(unknown type)\n");
          break;
      }
  }

main(int argc, char *argv[])
  {
    devfs_find(CLASS, devfs_entry, TRUE);

    exit(SYS_SUCCESS);
  }

------------------------------------------------------------------------

--

    . o o .     Laboratory for Computational Intelligence
    . >v< .     University of British Columbia
_____mm.mm_____ http://www.cs.ubc.ca/nest/lci

 
 
 

1. 3C905 Network Card detected as a Vortex Network Card (3c59X series)

    I have a problem in connecting my Linux Server. I already had a
linux server working and
was planning to add a newer machine to replace it. In the new machine, I
had a 3c905
network card (Boomerang Series) but RedHat detects it as a Vortex Series
Network card
(3c59x). I continued on with the installation and  connected the 2 Linux
machines in a hub.
However, when I tried to check the connection using the ping command,
time-out error
occurred. Is it because of wrong detection of network or something else?
Any help would be
greatly appreciated.

Thanks

PS. Please reply to my e-mail address if possible. I might not be able
to get the answer on
time if posted in the Usenet.

2. rdist under Solaris 2.3

3. How do I explore the possbile speed for an interface from C code?

4. monitor won't power off after screensaver timeout?

5. Oops Msg exploring

6. Become a programmer: study sources

7. Question of a newbie like to explore the code of opensource project

8. IBM 8515 Monitor?

9. Best way to explore Linux ?

10. Internet Explore

11. Crash utility (how to explore dump file?)

12. NEWBIE: exploring Linux + win/lin modem

13. I can't explore a log file generated from a batch with ksh