Subject: Re: Implementing interface media type autodetection?
To: Chris G Demetriou <Chris_G_Demetriou@ux2.sp.cs.cmu.edu>
From: Matt Thomas <matt@lkg.dec.com>
List: tech-net
Date: 06/09/1996 12:01:08
I agrree with Chris that this should go into struct ifnet.
if_media is fine with me.  Note that a SIOCGIFTYPE is also
needed as well since the media definitions are interface type
specific.  If you happen to get ifconfig to support this,
ifconfig will need to be able to obtain the iftype.  Maybe a
SIOC{GS]IFSPEED as well.  And SIOC[GS]MTU too.

The definitions (IFM_*) should really go in0 either
<netinet/if_ether.h>, <net/if_fddi.h>, etc. since they are type
specific or <net/if_medias.h> (ie. like <net/if_types.h>).

What about things like dual attach FDDI controllers?  They could
have two different medias in use.

/* IEEE 802.3 (aka Ethernet) */
#define	IFM_UNKNOWN		0
#define	IFM_AUTOSENSE		1
#define	IFM_10BASET		2
#define	IFM_BNC			3
#define	IFM_AUI			4
#define	IFM_100BASETX_STP	5
#define	IFM_100BASETX_UTP	6
#define	IFM_100BASET4		7
#define	IFM_100BASEFX		8
#define	IFM_100BASET2		9

/* FDDI */
#define	IFM_TPPMD		1
#define	IFM_MMF			2
#define	IFM_SMF			3

/* Token Ring */
#define	IFM_4MB			1
#define	IFM_16MB		2

What do you do about media with full-duplex support?  (Note
that you can do full-duplex on FDDI too if you use the DEC
FDDI adapters).

Should that be a IFF_LINKx option?  (I hope not).  

BTW, at the same time we probably should increase if_flags from
a short to an int.


*** WARNING *** Radical idea follows.

Another problem is that ifreq is too limiting and lead to a proliferation
of ioctls.

struct  ifreq {
        char    ifr_name[IFNAMSIZ];             /* if name, e.g. "en0" */
        union {
                struct  sockaddr ifru_addr;
                struct  sockaddr ifru_dstaddr;
                struct  sockaddr ifru_broadaddr;
                short   ifru_flags;
                int     ifru_metric;
                caddr_t ifru_data;
        } ifr_ifru;
#define ifr_addr        ifr_ifru.ifru_addr      /* address */
#define ifr_dstaddr     ifr_ifru.ifru_dstaddr   /* other end of p-to-p link */
#define ifr_broadaddr   ifr_ifru.ifru_broadaddr /* broadcast address */
#define ifr_flags       ifr_ifru.ifru_flags     /* flags */
#define ifr_metric      ifr_ifru.ifru_metric    /* metric */
#define ifr_data        ifr_ifru.ifru_data      /* for use by interface */
};

ifru_flags should be changed to an int.
it would be very useful if struct ifreq was larger (so that you could
use it with protocol whose sockaddr > 16 bytes long like IPv6).
Change ifru_metric to ifru_values[4];

#define	ifr_metric	ifr_ifru.ifru_values[0]
#define	ifr_flags	ifr_ifru.ifru_values[0]

You could then use value[0] as an option id and value[1] as the data:

#define	ifr_attr_id	ifr_ifru.ifru_values[0]
#define	ifr_attr_value	ifr_ifru.ifru_values[2]

	strcpy(ifr.ifr_name, "fpa0");
	ifr.ifr_attr_id = FDDI_ATTR_TVX;
	ifr.ifr_attr_value = tvx;
	ioctl(s, SIOCSIFATTR, &ifr);

or

	ifr.ifr_attr_id = ETHER_ATTR_FULLDUPLEX;
	ifr.ifr_attr_value = 1;
	...

This also allows us to avoid defining lots of ioctls.  

Hopefully some of that made some sense.  Maybe.
-- 
Matt Thomas               Internet:   matt@3am-software.com
3am Software Foundry      WWW URL:    http://www.3am-software.com/bio/matt.html
Westford, MA              Disclaimer: I disavow all knowledge of this message