Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Oct 1997 17:58:06 -0700
From:      Julian Elischer <julian@whistle.com>
To:        Darren Reed <darrenr@cyber.com.au>
Cc:        hackers@freebsd.org
Subject:   Re: Freebsd 3.0 current fails ipfilter 3.2b8 build (fwd)
Message-ID:  <3446B81E.4DAA423A@whistle.com>
References:  <199710170037.KAA24115@plum.cyber.com.au>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.

--------------6F5992E1773C244864880EEB
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Darren Reed wrote:
> 
> In some mail I received from Julian Elischer, sie wrote
> >
> > > In if.h, "struct ifnet" is gone, but if_var.h is included if KERNEL is
> > > defined.  However, all the #define's for the if_flags are still in if.h.
> > I think that's because they are needed externally.
> > the flags word is passed around independantly of the
> > ifnet.  (e.g. through the API)
> 
> okay, this is the second time you're referred to the API.
> 
> Where can it be found ? Who is responsible for it ?


It's a slow thing. Just a general consencus that lookingin the kernel vm
for information is notthe way to go in general.

That's why I asked what you needed to look at or change?
take ifconfig for example. it doesn't access the ifnet structure at all.

Netstat still does, but that is hoped to go away as we make
more API methods to allow this to be changed.

the aim is to stop anything from needing to do 'kread()' calls
to get status.


I enclose a little program that dumps out all the 
interface addresses and flags without reading the kernel.

I find it very hard to believe you don't know about this.. as I 
know you are very knowledgeable on the networking, and I guess we
are somehow talking on cross purposes (porpoises?).

julian

--------------6F5992E1773C244864880EEB
Content-Type: text/plain; charset=us-ascii; name="dumpifs.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="dumpifs.c"

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/syslog.h>
#include <sys/param.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>



void showbytes(unsigned char *cptr,int len)
{
	int i,j;
	for (j = 0 ;len > 0 ;j++) {
		for ( i = 0; i < 16; i++) {
			printf("0x%x ",*cptr++);
			if (--len == 0) break;
		}
		printf("\n");
	}
}
void print_sa (struct sockaddr *sap)
{
	char	buf[128];

	printf("len=%d,",sap->sa_len);
	switch(sap->sa_family) {
		
	case	AF_LINK:
		printf(" family=LINK\n");
		{
			char 	*cptr;
			struct sockaddr_dl *sdl = (struct sockaddr_dl *)sap;
			cptr = sdl->sdl_data;
			printf("index=%u, type=%u ",
				sdl->sdl_index,
        			sdl->sdl_type);
			printf("nlen=%u, alen=%u, slen=%u\n",
				sdl->sdl_nlen,
				sdl->sdl_alen,
        			sdl->sdl_slen);
			if(sdl->sdl_nlen) {
				bcopy(cptr,buf,sdl->sdl_nlen);
				buf[sdl->sdl_nlen] = 0;
				printf(" name = %s\n",buf);
				cptr += sdl->sdl_nlen;
			}
			if(sdl->sdl_alen) {
				printf(" address = ");
				showbytes(cptr,sdl->sdl_alen);
				cptr += sdl->sdl_alen;
			}
			if(sdl->sdl_slen) {
				printf(" selector = ");
				showbytes(cptr,sdl->sdl_slen);
				cptr += sdl->sdl_slen;
			}
		}
		break;
	case	AF_INET:
	printf(" family=INET\n");
		printf("[%s]",
		   inet_ntoa(((struct sockaddr_in *)sap)->sin_addr));
		printf(".%hu\n",((struct sockaddr_in *)sap)->sin_port);
		break;
	default:
		printf(" family=%d\n",sap->sa_family);
		showbytes(sap->sa_data,sap->sa_len-2);
	}
}

/*
 * Get the configuration from the kernel. Only called if there's no
 * configuration.
 */

void getifconf( void )
{
    struct ifconf	ifc;
    struct ifreq	ifrs[ 64 ], *ifr, *nextifr;
    struct interface	*iface, *niface;
    int			s;
    struct sockaddr 	*sa_p;
    int	ifrsize = 0;

    bzero(&ifc,sizeof(struct ifconf));
    bzero(ifrs,sizeof(struct ifreq) * 64);
    if (( s = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
	perror( "socket" );
	exit( 1 );
    }

    ifc.ifc_len = sizeof( ifrs );
    ifc.ifc_buf = (caddr_t)ifrs;
    if ( ioctl( s, SIOCGIFCONF, &ifc ) < 0 ) {
	perror( "getifconf" );
	exit( 1 );
    }

    for ( ifr = ifc.ifc_req; ifc.ifc_len >= sizeof( struct ifreq );
			ifr = nextifr, ifc.ifc_len -= ifrsize) {
	/*
	 * in BSD4.4, this returns an entry for every address
	 * Associated with the if. including physical.. they
	 * include a sockaddr which is VARIABLE LENGTH!
	 * 
	 * Calculate the length of this entry.
	 */
	sa_p = &(ifr->ifr_addr);
	print_sa(&(ifr->ifr_addr));
/*	print_sa(&(ifr->ifr_dstaddr));
	print_sa(&(ifr->ifr_broadaddr)); */
	ifrsize =  IFNAMSIZ + sa_p->sa_len;
	nextifr = (struct ifreq *)((caddr_t)ifr + ifrsize);
	
	/*
	 * Now get it's flags
	 */
	if ( ioctl( s, SIOCGIFFLAGS, ifr ) < 0 ) {
	    perror( ifr->ifr_name );
	    exit( 1 );
	}
	printf("FLAGS = 0x%x\n",(unsigned short)ifr->ifr_flags);

	printf("\n");

    }
    if ( ifc.ifc_len != 0 ) {
	fprintf( stderr, "Funky gifconf return.\n" );
	exit( 1 );
    }

    (void)close( s );
    return;
}

main()
{
	getifconf();
	exit(0);
}

--------------6F5992E1773C244864880EEB--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3446B81E.4DAA423A>