xref: /freebsd/libexec/bootpd/getether.c (revision 07ee9f80d73118450375bd991c5cabb8c85bd7a2)
144099b7bSPaul Traina /*
244099b7bSPaul Traina  * getether.c : get the ethernet address of an interface
344099b7bSPaul Traina  *
444099b7bSPaul Traina  * All of this code is quite system-specific.  As you may well
544099b7bSPaul Traina  * guess, it took a good bit of detective work to figure out!
644099b7bSPaul Traina  *
744099b7bSPaul Traina  * If you figure out how to do this on another system,
844099b7bSPaul Traina  * please let me know.  <gwr@mc.com>
9148531efSWolfram Schneider  *
107f3dea24SPeter Wemm  * $FreeBSD$
1144099b7bSPaul Traina  */
1244099b7bSPaul Traina 
1344099b7bSPaul Traina #include <sys/types.h>
1444099b7bSPaul Traina #include <sys/socket.h>
1544099b7bSPaul Traina 
16e08ac58bSPaul Traina #ifndef	NO_UNISTD
17e08ac58bSPaul Traina #include <unistd.h>
18e08ac58bSPaul Traina #endif
19e08ac58bSPaul Traina 
2044099b7bSPaul Traina #include <ctype.h>
211a37aa56SDavid E. O'Brien #include <paths.h>
227fe354baSIan Dowse #include <string.h>
2344099b7bSPaul Traina #include <syslog.h>
2444099b7bSPaul Traina 
25e08ac58bSPaul Traina #include "getether.h"
2644099b7bSPaul Traina #include "report.h"
2744099b7bSPaul Traina #define EALEN 6
2844099b7bSPaul Traina 
2944099b7bSPaul Traina #if defined(ultrix) || (defined(__osf__) && defined(__alpha))
3044099b7bSPaul Traina /*
3144099b7bSPaul Traina  * This is really easy on Ultrix!  Thanks to
3244099b7bSPaul Traina  * Harald Lundberg <hl@tekla.fi> for this code.
3344099b7bSPaul Traina  *
3444099b7bSPaul Traina  * The code here is not specific to the Alpha, but that was the
3544099b7bSPaul Traina  * only symbol we could find to identify DEC's version of OSF.
3644099b7bSPaul Traina  * (Perhaps we should just define DEC in the Makefile... -gwr)
3744099b7bSPaul Traina  */
3844099b7bSPaul Traina 
3944099b7bSPaul Traina #include <sys/ioctl.h>
4044099b7bSPaul Traina #include <net/if.h>				/* struct ifdevea */
4144099b7bSPaul Traina 
4244099b7bSPaul Traina getether(ifname, eap)
4344099b7bSPaul Traina 	char *ifname, *eap;
4444099b7bSPaul Traina {
4544099b7bSPaul Traina 	int rc = -1;
4644099b7bSPaul Traina 	int fd;
4744099b7bSPaul Traina 	struct ifdevea phys;
4844099b7bSPaul Traina 	bzero(&phys, sizeof(phys));
4944099b7bSPaul Traina 	strcpy(phys.ifr_name, ifname);
5044099b7bSPaul Traina 	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
5144099b7bSPaul Traina 		report(LOG_ERR, "getether: socket(INET,DGRAM) failed");
5244099b7bSPaul Traina 		return -1;
5344099b7bSPaul Traina 	}
5444099b7bSPaul Traina 	if (ioctl(fd, SIOCRPHYSADDR, &phys) < 0) {
5544099b7bSPaul Traina 		report(LOG_ERR, "getether: ioctl SIOCRPHYSADDR failed");
5644099b7bSPaul Traina 	} else {
5744099b7bSPaul Traina 		bcopy(&phys.current_pa[0], eap, EALEN);
5844099b7bSPaul Traina 		rc = 0;
5944099b7bSPaul Traina 	}
6044099b7bSPaul Traina 	close(fd);
6144099b7bSPaul Traina 	return rc;
6244099b7bSPaul Traina }
6344099b7bSPaul Traina 
6444099b7bSPaul Traina #define	GETETHER
6544099b7bSPaul Traina #endif /* ultrix|osf1 */
6644099b7bSPaul Traina 
6744099b7bSPaul Traina 
6844099b7bSPaul Traina #ifdef	SUNOS
6944099b7bSPaul Traina 
7044099b7bSPaul Traina #include <sys/sockio.h>
7144099b7bSPaul Traina #include <sys/time.h>			/* needed by net_if.h */
7244099b7bSPaul Traina #include <net/nit_if.h>			/* for NIOCBIND */
7344099b7bSPaul Traina #include <net/if.h>				/* for struct ifreq */
7444099b7bSPaul Traina 
7544099b7bSPaul Traina getether(ifname, eap)
7644099b7bSPaul Traina 	char *ifname;				/* interface name from ifconfig structure */
7744099b7bSPaul Traina 	char *eap;					/* Ether address (output) */
7844099b7bSPaul Traina {
7944099b7bSPaul Traina 	int rc = -1;
8044099b7bSPaul Traina 
8144099b7bSPaul Traina 	struct ifreq ifrnit;
8244099b7bSPaul Traina 	int nit;
8344099b7bSPaul Traina 
8444099b7bSPaul Traina 	bzero((char *) &ifrnit, sizeof(ifrnit));
852386a44fSKris Kennaway 	strlcpy(&ifrnit.ifr_name[0], ifname, IFNAMSIZ);
8644099b7bSPaul Traina 
8744099b7bSPaul Traina 	nit = open("/dev/nit", 0);
8844099b7bSPaul Traina 	if (nit < 0) {
8944099b7bSPaul Traina 		report(LOG_ERR, "getether: open /dev/nit: %s",
9044099b7bSPaul Traina 			   get_errmsg());
9144099b7bSPaul Traina 		return rc;
9244099b7bSPaul Traina 	}
9344099b7bSPaul Traina 	do {
9444099b7bSPaul Traina 		if (ioctl(nit, NIOCBIND, &ifrnit) < 0) {
9544099b7bSPaul Traina 			report(LOG_ERR, "getether: NIOCBIND on nit");
9644099b7bSPaul Traina 			break;
9744099b7bSPaul Traina 		}
9844099b7bSPaul Traina 		if (ioctl(nit, SIOCGIFADDR, &ifrnit) < 0) {
9944099b7bSPaul Traina 			report(LOG_ERR, "getether: SIOCGIFADDR on nit");
10044099b7bSPaul Traina 			break;
10144099b7bSPaul Traina 		}
10244099b7bSPaul Traina 		bcopy(&ifrnit.ifr_addr.sa_data[0], eap, EALEN);
10344099b7bSPaul Traina 		rc = 0;
10444099b7bSPaul Traina 	} while (0);
10544099b7bSPaul Traina 	close(nit);
10644099b7bSPaul Traina 	return rc;
10744099b7bSPaul Traina }
10844099b7bSPaul Traina 
10944099b7bSPaul Traina #define	GETETHER
11044099b7bSPaul Traina #endif /* SUNOS */
11144099b7bSPaul Traina 
11244099b7bSPaul Traina 
113d1c0e759SPaul Traina #if defined(__FreeBSD__) || defined(__NetBSD__)
11444099b7bSPaul Traina /* Thanks to John Brezak <brezak@ch.hp.com> for this code. */
11544099b7bSPaul Traina #include <sys/ioctl.h>
116628d2ac1SGarrett Wollman #include <sys/time.h>
11744099b7bSPaul Traina #include <net/if.h>
11844099b7bSPaul Traina #include <net/if_dl.h>
11944099b7bSPaul Traina #include <net/if_types.h>
12044099b7bSPaul Traina 
1217fe354baSIan Dowse int
12244099b7bSPaul Traina getether(ifname, eap)
12344099b7bSPaul Traina 	char *ifname;				/* interface name from ifconfig structure */
12444099b7bSPaul Traina 	char *eap;					/* Ether address (output) */
12544099b7bSPaul Traina {
12644099b7bSPaul Traina 	int fd, rc = -1;
127*07ee9f80SPedro F. Giffuni 	int n;
1287fe354baSIan Dowse 	struct ifreq ibuf[16];
12944099b7bSPaul Traina 	struct ifconf ifc;
130*07ee9f80SPedro F. Giffuni 	struct ifreq *ifrp, *ifend;
13144099b7bSPaul Traina 
13244099b7bSPaul Traina 	/* Fetch the interface configuration */
13344099b7bSPaul Traina 	fd = socket(AF_INET, SOCK_DGRAM, 0);
13444099b7bSPaul Traina 	if (fd < 0) {
13544099b7bSPaul Traina 		report(LOG_ERR, "getether: socket %s: %s", ifname, get_errmsg());
13644099b7bSPaul Traina 		return (fd);
13744099b7bSPaul Traina 	}
13844099b7bSPaul Traina 	ifc.ifc_len = sizeof(ibuf);
13944099b7bSPaul Traina 	ifc.ifc_buf = (caddr_t) ibuf;
14044099b7bSPaul Traina 	if (ioctl(fd, SIOCGIFCONF, (char *) &ifc) < 0 ||
14144099b7bSPaul Traina 		ifc.ifc_len < sizeof(struct ifreq)) {
142be9efd56SKris Kennaway 		report(LOG_ERR, "getether: SIOCGIFCONF: %s", get_errmsg());
14344099b7bSPaul Traina 		goto out;
14444099b7bSPaul Traina 	}
14544099b7bSPaul Traina 	/* Search interface configuration list for link layer address. */
14644099b7bSPaul Traina 	ifrp = ibuf;
14744099b7bSPaul Traina 	ifend = (struct ifreq *) ((char *) ibuf + ifc.ifc_len);
14844099b7bSPaul Traina 	while (ifrp < ifend) {
14944099b7bSPaul Traina 		/* Look for interface */
15044099b7bSPaul Traina 		if (strcmp(ifname, ifrp->ifr_name) == 0 &&
15144099b7bSPaul Traina 			ifrp->ifr_addr.sa_family == AF_LINK &&
15244099b7bSPaul Traina 		((struct sockaddr_dl *) &ifrp->ifr_addr)->sdl_type == IFT_ETHER) {
15344099b7bSPaul Traina 			bcopy(LLADDR((struct sockaddr_dl *) &ifrp->ifr_addr), eap, EALEN);
15444099b7bSPaul Traina 			rc = 0;
15544099b7bSPaul Traina 			break;
15644099b7bSPaul Traina 		}
15744099b7bSPaul Traina 		/* Bump interface config pointer */
15844099b7bSPaul Traina 		n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
15944099b7bSPaul Traina 		if (n < sizeof(*ifrp))
16044099b7bSPaul Traina 			n = sizeof(*ifrp);
16144099b7bSPaul Traina 		ifrp = (struct ifreq *) ((char *) ifrp + n);
16244099b7bSPaul Traina 	}
16344099b7bSPaul Traina 
16444099b7bSPaul Traina   out:
16544099b7bSPaul Traina 	close(fd);
16644099b7bSPaul Traina 	return (rc);
16744099b7bSPaul Traina }
16844099b7bSPaul Traina 
16944099b7bSPaul Traina #define	GETETHER
17044099b7bSPaul Traina #endif /* __NetBSD__ */
17144099b7bSPaul Traina 
17244099b7bSPaul Traina 
17344099b7bSPaul Traina #ifdef	SVR4
17444099b7bSPaul Traina /*
17544099b7bSPaul Traina  * This is for "Streams TCP/IP" by Lachman Associates.
17644099b7bSPaul Traina  * They sure made this cumbersome!  -gwr
17744099b7bSPaul Traina  */
17844099b7bSPaul Traina 
17944099b7bSPaul Traina #include <sys/sockio.h>
18044099b7bSPaul Traina #include <sys/dlpi.h>
18144099b7bSPaul Traina #include <stropts.h>
182e08ac58bSPaul Traina #include <string.h>
18344099b7bSPaul Traina #ifndef NULL
18444099b7bSPaul Traina #define NULL 0
18544099b7bSPaul Traina #endif
18644099b7bSPaul Traina 
187e08ac58bSPaul Traina int
18844099b7bSPaul Traina getether(ifname, eap)
18944099b7bSPaul Traina 	char *ifname;				/* interface name from ifconfig structure */
19044099b7bSPaul Traina 	char *eap;					/* Ether address (output) */
19144099b7bSPaul Traina {
19244099b7bSPaul Traina 	int rc = -1;
19344099b7bSPaul Traina 	char devname[32];
19444099b7bSPaul Traina 	char tmpbuf[sizeof(union DL_primitives) + 16];
19544099b7bSPaul Traina 	struct strbuf cbuf;
19644099b7bSPaul Traina 	int fd, flags;
19744099b7bSPaul Traina 	union DL_primitives *dlp;
19844099b7bSPaul Traina 	char *enaddr;
19944099b7bSPaul Traina 	int unit = -1;				/* which unit to attach */
20044099b7bSPaul Traina 
2011a37aa56SDavid E. O'Brien 	snprintf(devname, sizeof(devname), "%s%s", _PATH_DEV, ifname);
20244099b7bSPaul Traina 	fd = open(devname, 2);
20344099b7bSPaul Traina 	if (fd < 0) {
20444099b7bSPaul Traina 		/* Try without the trailing digit. */
20544099b7bSPaul Traina 		char *p = devname + 5;
20644099b7bSPaul Traina 		while (isalpha(*p))
20744099b7bSPaul Traina 			p++;
20844099b7bSPaul Traina 		if (isdigit(*p)) {
20944099b7bSPaul Traina 			unit = *p - '0';
21044099b7bSPaul Traina 			*p = '\0';
21144099b7bSPaul Traina 		}
21244099b7bSPaul Traina 		fd = open(devname, 2);
21344099b7bSPaul Traina 		if (fd < 0) {
21444099b7bSPaul Traina 			report(LOG_ERR, "getether: open %s: %s",
21544099b7bSPaul Traina 				   devname, get_errmsg());
21644099b7bSPaul Traina 			return rc;
21744099b7bSPaul Traina 		}
21844099b7bSPaul Traina 	}
21944099b7bSPaul Traina #ifdef	DL_ATTACH_REQ
22044099b7bSPaul Traina 	/*
22144099b7bSPaul Traina 	 * If this is a "Style 2" DLPI, then we must "attach" first
22244099b7bSPaul Traina 	 * to tell the driver which unit (board, port) we want.
22344099b7bSPaul Traina 	 * For now, decide this based on the device name.
22444099b7bSPaul Traina 	 * (Should do "info_req" and check dl_provider_style ...)
22544099b7bSPaul Traina 	 */
22644099b7bSPaul Traina 	if (unit >= 0) {
22744099b7bSPaul Traina 		memset(tmpbuf, 0, sizeof(tmpbuf));
22844099b7bSPaul Traina 		dlp = (union DL_primitives *) tmpbuf;
22944099b7bSPaul Traina 		dlp->dl_primitive = DL_ATTACH_REQ;
23044099b7bSPaul Traina 		dlp->attach_req.dl_ppa = unit;
23144099b7bSPaul Traina 		cbuf.buf = tmpbuf;
23244099b7bSPaul Traina 		cbuf.len = DL_ATTACH_REQ_SIZE;
23344099b7bSPaul Traina 		if (putmsg(fd, &cbuf, NULL, 0) < 0) {
23444099b7bSPaul Traina 			report(LOG_ERR, "getether: attach: putmsg: %s", get_errmsg());
23544099b7bSPaul Traina 			goto out;
23644099b7bSPaul Traina 		}
23744099b7bSPaul Traina 		/* Recv the ack. */
23844099b7bSPaul Traina 		cbuf.buf = tmpbuf;
23944099b7bSPaul Traina 		cbuf.maxlen = sizeof(tmpbuf);
24044099b7bSPaul Traina 		flags = 0;
24144099b7bSPaul Traina 		if (getmsg(fd, &cbuf, NULL, &flags) < 0) {
24244099b7bSPaul Traina 			report(LOG_ERR, "getether: attach: getmsg: %s", get_errmsg());
24344099b7bSPaul Traina 			goto out;
24444099b7bSPaul Traina 		}
24544099b7bSPaul Traina 		/*
24644099b7bSPaul Traina 		 * Check the type, etc.
24744099b7bSPaul Traina 		 */
24844099b7bSPaul Traina 		if (dlp->dl_primitive == DL_ERROR_ACK) {
24944099b7bSPaul Traina 			report(LOG_ERR, "getether: attach: dlpi_errno=%d, unix_errno=%d",
25044099b7bSPaul Traina 				   dlp->error_ack.dl_errno,
25144099b7bSPaul Traina 				   dlp->error_ack.dl_unix_errno);
25244099b7bSPaul Traina 			goto out;
25344099b7bSPaul Traina 		}
25444099b7bSPaul Traina 		if (dlp->dl_primitive != DL_OK_ACK) {
25544099b7bSPaul Traina 			report(LOG_ERR, "getether: attach: not OK or ERROR");
25644099b7bSPaul Traina 			goto out;
25744099b7bSPaul Traina 		}
25844099b7bSPaul Traina 	} /* unit >= 0 */
25944099b7bSPaul Traina #endif	/* DL_ATTACH_REQ */
26044099b7bSPaul Traina 
26144099b7bSPaul Traina 	/*
26244099b7bSPaul Traina 	 * Get the Ethernet address the same way the ARP module
26344099b7bSPaul Traina 	 * does when it is pushed onto a new stream (bind).
264d64ada50SJens Schweikhardt 	 * One should instead be able just do a dl_info_req
26544099b7bSPaul Traina 	 * but many drivers do not supply the hardware address
26644099b7bSPaul Traina 	 * in the response to dl_info_req (they MUST supply it
26744099b7bSPaul Traina 	 * for dl_bind_ack because the ARP module requires it).
26844099b7bSPaul Traina 	 */
26944099b7bSPaul Traina 	memset(tmpbuf, 0, sizeof(tmpbuf));
27044099b7bSPaul Traina 	dlp = (union DL_primitives *) tmpbuf;
27144099b7bSPaul Traina 	dlp->dl_primitive = DL_BIND_REQ;
27244099b7bSPaul Traina 	dlp->bind_req.dl_sap = 0x8FF;	/* XXX - Unused SAP */
27344099b7bSPaul Traina 	cbuf.buf = tmpbuf;
27444099b7bSPaul Traina 	cbuf.len = DL_BIND_REQ_SIZE;
27544099b7bSPaul Traina 	if (putmsg(fd, &cbuf, NULL, 0) < 0) {
27644099b7bSPaul Traina 		report(LOG_ERR, "getether: bind: putmsg: %s", get_errmsg());
27744099b7bSPaul Traina 		goto out;
27844099b7bSPaul Traina 	}
27944099b7bSPaul Traina 	/* Recv the ack. */
28044099b7bSPaul Traina 	cbuf.buf = tmpbuf;
28144099b7bSPaul Traina 	cbuf.maxlen = sizeof(tmpbuf);
28244099b7bSPaul Traina 	flags = 0;
28344099b7bSPaul Traina 	if (getmsg(fd, &cbuf, NULL, &flags) < 0) {
28444099b7bSPaul Traina 		report(LOG_ERR, "getether: bind: getmsg: %s", get_errmsg());
28544099b7bSPaul Traina 		goto out;
28644099b7bSPaul Traina 	}
28744099b7bSPaul Traina 	/*
28844099b7bSPaul Traina 	 * Check the type, etc.
28944099b7bSPaul Traina 	 */
29044099b7bSPaul Traina 	if (dlp->dl_primitive == DL_ERROR_ACK) {
29144099b7bSPaul Traina 		report(LOG_ERR, "getether: bind: dlpi_errno=%d, unix_errno=%d",
29244099b7bSPaul Traina 			   dlp->error_ack.dl_errno,
29344099b7bSPaul Traina 			   dlp->error_ack.dl_unix_errno);
29444099b7bSPaul Traina 		goto out;
29544099b7bSPaul Traina 	}
29644099b7bSPaul Traina 	if (dlp->dl_primitive != DL_BIND_ACK) {
29744099b7bSPaul Traina 		report(LOG_ERR, "getether: bind: not OK or ERROR");
29844099b7bSPaul Traina 		goto out;
29944099b7bSPaul Traina 	}
30044099b7bSPaul Traina 	if (dlp->bind_ack.dl_addr_offset == 0) {
30144099b7bSPaul Traina 		report(LOG_ERR, "getether: bind: ack has no address");
30244099b7bSPaul Traina 		goto out;
30344099b7bSPaul Traina 	}
30444099b7bSPaul Traina 	if (dlp->bind_ack.dl_addr_length < EALEN) {
30544099b7bSPaul Traina 		report(LOG_ERR, "getether: bind: ack address truncated");
30644099b7bSPaul Traina 		goto out;
30744099b7bSPaul Traina 	}
30844099b7bSPaul Traina 	/*
30944099b7bSPaul Traina 	 * Copy the Ethernet address out of the message.
31044099b7bSPaul Traina 	 */
31144099b7bSPaul Traina 	enaddr = tmpbuf + dlp->bind_ack.dl_addr_offset;
31244099b7bSPaul Traina 	memcpy(eap, enaddr, EALEN);
31344099b7bSPaul Traina 	rc = 0;
31444099b7bSPaul Traina 
31544099b7bSPaul Traina   out:
31644099b7bSPaul Traina 	close(fd);
31744099b7bSPaul Traina 	return rc;
31844099b7bSPaul Traina }
31944099b7bSPaul Traina 
32044099b7bSPaul Traina #define	GETETHER
32144099b7bSPaul Traina #endif /* SVR4 */
32244099b7bSPaul Traina 
32344099b7bSPaul Traina 
324e08ac58bSPaul Traina #ifdef	__linux__
32544099b7bSPaul Traina /*
32644099b7bSPaul Traina  * This is really easy on Linux!  This version (for linux)
327e08ac58bSPaul Traina  * written by Nigel Metheringham <nigelm@ohm.york.ac.uk> and
328e08ac58bSPaul Traina  * updated by Pauline Middelink <middelin@polyware.iaf.nl>
32944099b7bSPaul Traina  *
33044099b7bSPaul Traina  * The code is almost identical to the Ultrix code - however
33144099b7bSPaul Traina  * the names are different to confuse the innocent :-)
33244099b7bSPaul Traina  * Most of this code was stolen from the Ultrix bit above.
33344099b7bSPaul Traina  */
33444099b7bSPaul Traina 
335e08ac58bSPaul Traina #include <memory.h>
33644099b7bSPaul Traina #include <sys/ioctl.h>
33744099b7bSPaul Traina #include <net/if.h>	       	/* struct ifreq */
338e08ac58bSPaul Traina #include <sys/socketio.h>	/* Needed for IOCTL defs */
33944099b7bSPaul Traina 
340e08ac58bSPaul Traina int
34144099b7bSPaul Traina getether(ifname, eap)
34244099b7bSPaul Traina 	char *ifname, *eap;
34344099b7bSPaul Traina {
34444099b7bSPaul Traina 	int rc = -1;
34544099b7bSPaul Traina 	int fd;
34644099b7bSPaul Traina 	struct ifreq phys;
347e08ac58bSPaul Traina 
348e08ac58bSPaul Traina 	memset(&phys, 0, sizeof(phys));
34944099b7bSPaul Traina 	strcpy(phys.ifr_name, ifname);
35044099b7bSPaul Traina 	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
35144099b7bSPaul Traina 		report(LOG_ERR, "getether: socket(INET,DGRAM) failed");
35244099b7bSPaul Traina 		return -1;
35344099b7bSPaul Traina 	}
35444099b7bSPaul Traina 	if (ioctl(fd, SIOCGIFHWADDR, &phys) < 0) {
35544099b7bSPaul Traina 		report(LOG_ERR, "getether: ioctl SIOCGIFHWADDR failed");
35644099b7bSPaul Traina 	} else {
357e08ac58bSPaul Traina 		memcpy(eap, &phys.ifr_hwaddr.sa_data, EALEN);
35844099b7bSPaul Traina 		rc = 0;
35944099b7bSPaul Traina 	}
36044099b7bSPaul Traina 	close(fd);
36144099b7bSPaul Traina 	return rc;
36244099b7bSPaul Traina }
36344099b7bSPaul Traina 
36444099b7bSPaul Traina #define	GETETHER
365e08ac58bSPaul Traina #endif	/* __linux__ */
36644099b7bSPaul Traina 
36744099b7bSPaul Traina 
36844099b7bSPaul Traina /* If we don't know how on this system, just return an error. */
36944099b7bSPaul Traina #ifndef	GETETHER
370e08ac58bSPaul Traina int
37144099b7bSPaul Traina getether(ifname, eap)
37244099b7bSPaul Traina 	char *ifname, *eap;
37344099b7bSPaul Traina {
37444099b7bSPaul Traina 	return -1;
37544099b7bSPaul Traina }
37644099b7bSPaul Traina 
37744099b7bSPaul Traina #endif /* !GETETHER */
37844099b7bSPaul Traina 
37944099b7bSPaul Traina /*
38044099b7bSPaul Traina  * Local Variables:
38144099b7bSPaul Traina  * tab-width: 4
38244099b7bSPaul Traina  * c-indent-level: 4
38344099b7bSPaul Traina  * c-argdecl-indent: 4
38444099b7bSPaul Traina  * c-continued-statement-offset: 4
38544099b7bSPaul Traina  * c-continued-brace-offset: -4
38644099b7bSPaul Traina  * c-label-offset: -4
38744099b7bSPaul Traina  * c-brace-offset: 0
38844099b7bSPaul Traina  * End:
38944099b7bSPaul Traina  */
390