Getting interface names using code

Is there a way to use code to get the interface names for a Solaris machine. I can easily see them on a command line with the "ifconfig -a" command. I could write a script that parses these out of a the ifconfig result and outputs them to a file, and then I run the script with the system command from code, and open the resulting file from code.

It seems there should be an easier way for a program to get these names. On some of the Solaris boxes I use, these names are bge0, bge1,... depending on how many ethernet cards are installed. On others the names are ce0, ce1,...

If you know how I can get these names from code directly, please let me know.
TIA,
Herb Miller
:confused:

Are you only concerned with active network interfaces?

use can use prtconf -D |grep network to see each interfaces' instances. and of course, if you need only the active interface, you can use ifconfig or the combination of both, depending on how stylish you want your script to report it out with the output:p

I'm not 100% sure what the OP means but 'code', but my foggy crystal ball tells me it's not "script", but rather some kind of the compiled language.
Maybe the OP could shed some more light....

That was my understanding also.

I may be in the wrong forum.

I was hoping to do this from code (C++ or C, most likely). I can use the ifconfig command from code and pipe the result of a file and open the file and parse it. This seems cumbersome, but it does work.

I was hoping to just make some calls (or series of calls) from software to get this information rather that relying on the "system_ command from software, and writing and reading a file. I can not be sure that the code I am writing will be run in an environment where writing a file is permitted.

Thanks,
Herb

Yes, active interfaces only.

might be better in the high level programming forum.

There is very little error checking in this, and I have not filtered out the loopback interface.

compiles as is, but required libsocket and libnsl

cc -lsocket -lnsl -o ifprint ifprint.c 

[highlight=c]
/*
ifprint.c - prints active network interfaces
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/dlpi.h>
#include <net/if.h>
#include <sys/sockio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>

#define SOCKET_AF(af) (((af) == AF_UNSPEC) ? AF_INET : (af))

int main(int argc, char *argv[])
{
struct lifreq lifr
int64_t onflags = 0;
int64_t offflags = 0;
int setaddr;
int n;
int af = AF_INET;
char *buf;
int s = socket(SOCKET_AF(af), SOCK_DGRAM, 0);
struct lifnum lifn;
struct lifconf lifc;
struct lifreq lifrp;
struct lifreq lifrl; /
Local lifreq struct */
int numifs;
unsigned bufsize;
int plumball = 0;
int save_af = af;
int64_t lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;

    lifn.lifn_family = AF_UNSPEC;
    lifn.lifn_flags = lifc_flags;
    if \(ioctl\(s, SIOCGLIFNUM, \(char *\)&lifn\) &lt; 0\) \{
            /* Could not determine number of interfaces */
            exit\(2\);
    \}
    numifs = lifn.lifn_count;

    bufsize = numifs * sizeof \(struct lifreq\);
    if \(\(buf = malloc\(bufsize\)\) == NULL\) \{
            /* out of memory */
            \(void\) close\(s\);
            exit\(1\);
    \}

    lifc.lifc_family = AF_UNSPEC;
    lifc.lifc_flags = lifc_flags;
    lifc.lifc_len = bufsize;
    lifc.lifc_buf = buf;

    if \(ioctl\(s, SIOCGLIFCONF, \(char *\)&lifc\) &lt; 0\) \{
            free\(buf\);
            exit\(1\);
    \}
    lifrp = lifc.lifc_req;

    for \(n = lifc.lifc_len / sizeof \(struct lifreq\); n &gt; 0; n--, lifrp\+\+\) \{


            \(void\) close\(s\);
            af = lifrp-&gt;lifr\_addr.ss_family;
            s = socket\(SOCKET_AF\(af\), SOCK_DGRAM, 0\);
            if \(s == -1\) \{
                    exit\(1\);
            \}
            if \(onflags || offflags\) \{
                    \(void\) memset\(&lifrl, 0, sizeof \(lifrl\)\);
                    \(void\) strncpy\(lifrl.lifr_name, lifrp-&gt;lifr_name,
                            sizeof \(lifrl.lifr_name\)\);
                    if \(ioctl\(s, SIOCGLIFFLAGS, \(caddr_t\)&lifrl\) &lt; 0\) \{
                            \(void\) strncpy\(lifr.lifr_name,
                                    lifrp-&gt;lifr_name, sizeof \(lifr.lifr_name\)\);
                            printf\("foreachinterface: SIOCGLIFFLAGS\\n"\);
                            exit\(1\);
                    \}
                    if \(\(lifrl.lifr_flags & onflags\) != onflags\)
                            continue;
                    if \(\(~lifrl.lifr_flags & offflags\) != offflags\)
                            continue;
            \}

            \(void\) strncpy\(lifrl.lifr_name, lifrp-&gt;lifr_name,
                    sizeof \(lifrl.lifr_name\)\);
            if \(ioctl\(s, SIOCGLIFADDR, \(caddr_t\)&lifrl\) &lt; 0\) \{
                    \(void\) strncpy\(lifr.lifr_name,
                    lifrp-&gt;lifr_name, sizeof \(lifr.lifr_name\)\);
                    printf\("foreachinterface: SIOCGLIFADDR\\n"\);
                    continue;
            \}
            if \(lifrl.lifr\_addr.ss_family != af\) \{
                    af = lifrl.lifr\_addr.ss_family;
                    \(void\) close\(s\);
                    s = socket\(SOCKET_AF\(af\), SOCK_DGRAM, 0\);
                    if \(s == -1\) \{
                            \(void\) strncpy\(lifr.lifr_name,
                            lifrp-&gt;lifr_name,
                                    sizeof \(lifr.lifr_name\)\);
                                    printf\("socket\\n"\);
                                    exit\(1\);
                    \}
            \}
            setaddr = 0;
            /* print the name of the interface */
            printf\("%s\\n",  lifrp-&gt;lifr_name\);
    \}
    if \(buf != NULL\)
            free\(buf\);

}

[/highlight]

Thanks. This looks like something I can use. I only have access to my linux and windows boxes until Monday. I will try it out on Solaris Monday.
Thanks again,
Herb Miller
:slight_smile:

Mine's smaller :wink:

cc -lkstat  -o knet knet.c
#include <kstat.h>
#include <string.h>
#include <stdio.h>
int main(int argc, char **argv) {
  kstat_ctl_t *kc;
  kstat_t *ksp;
  kc=kstat_open();
  for(ksp=kc->kc_chain; ksp != NULL; ksp=ksp->ks_next) {
    if((strcmp(ksp->ks_class, "net")==0) && (strcmp(ksp->ks_module, "link")==0)) {
      printf("%s\n", ksp->ks_name);
    }
  }
  kstat_close(kc);
}

Am I missing something here?

bash-3.00# cc -lkstat  -o knet knet.c
bash-3.00# ./knet
bash-3.00#

I get nothing on Sparc or x86/64, as I would expect. ksp->ks_module concatenated with ksp->ks_instance and compared with ks->ks_name might give you something, but I wouldn't expect ksp->ks_module to ever return "link" as a value it should return the module name eg. bge, hme or whatever the interface type is.

bash-3.00# ./ifprint
lo0
elxl0

You are right, my code relies on recent kstat changes.

It works fine with latest Solaris Express releases.

I thought as much, but my nevada machine is broken at the moment.