xref: /original-bsd/usr.sbin/amd/amd/wire.c (revision 95a66346)
1 /*
2  * $Id: wire.c,v 5.2.1.1 91/03/17 17:42:58 jsp Alpha $
3  *
4  * Copyright (c) 1990 Jan-Simon Pendry
5  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
6  * Copyright (c) 1990 The Regents of the University of California.
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to Berkeley by
10  * Jan-Simon Pendry at Imperial College, London.
11  *
12  * %sccs.include.redist.c%
13  *
14  *	@(#)wire.c	5.2 (Berkeley) 03/17/91
15  */
16 
17 /*
18  * This routine returns the subnet (address&netmask) for the primary network
19  * interface.  If the resulting address has an entry in the hosts file, the
20  * corresponding name is retuned, otherwise the address is returned in
21  * standard internet format.
22  *
23  * From: Paul Anderson (23/4/90)
24  */
25 
26 #include "am.h"
27 
28 #include <sys/ioctl.h>
29 
30 #define NO_SUBNET "notknown"
31 
32 #ifdef SIOCGIFFLAGS
33 #include <net/if.h>
34 #include <netdb.h>
35 
36 #if defined(IFF_LOCAL_LOOPBACK) && !defined(IFF_LOOPBACK)
37 #define IFF_LOOPBACK IFF_LOCAL_LOOPBACK
38 #endif
39 
40 #define GFBUFLEN 1024
41 #define clist (ifc.ifc_ifcu.ifcu_req)
42 #define count (ifc.ifc_len/sizeof(struct ifreq))
43 
44 char *getwire P((void));
45 char *getwire()
46 {
47 	struct hostent *hp;
48 	struct netent *np;
49 	struct ifconf ifc;
50 	struct ifreq *ifr;
51 	caddr_t cp, cplim;
52 	unsigned long address, netmask, subnet;
53 	char buf[GFBUFLEN], *s;
54 	int sk = -1;
55 
56 	/*
57 	 * Get suitable socket
58 	 */
59 	if ((sk = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
60 		goto out;
61 
62 	/*
63 	 * Fill in ifconf details
64 	 */
65 	ifc.ifc_len = sizeof buf;
66 	ifc.ifc_buf = buf;
67 
68 	/*
69 	 * Get network interface configurations
70 	 */
71 	if (ioctl(sk, SIOCGIFCONF, (caddr_t) &ifc) < 0)
72 		goto out;
73 
74 	/*
75 	 * Upper bound on array
76 	 */
77 	cplim = buf + ifc.ifc_len;
78 
79 	/*
80 	 * This is some magic to cope with both "traditional" and the
81 	 * new 4.4BSD-style struct sockaddrs.  The new structure has
82 	 * variable length and a size field to support longer addresses.
83 	 * AF_LINK is a new definition for 4.4BSD.
84 	 */
85 #ifdef AF_LINK
86 #define max(a, b) ((a) > (b) ? (a) : (b))
87 #define size(p) max((p).sa_len, sizeof(p))
88 #else
89 #define size(p) sizeof(p)
90 #endif
91 	/*
92 	 * Scan the list looking for a suitable interface
93 	 */
94 	for (cp = buf; cp < cplim; cp += sizeof(ifr->ifr_name) + size(ifr->ifr_addr)) {
95 		ifr = (struct ifreq *) cp;
96 
97 		if (ifr->ifr_addr.sa_family != AF_INET)
98 			continue;
99 		else
100 			address = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
101 
102 		/*
103 		 * Get interface flags
104 		 */
105 		if (ioctl(sk, SIOCGIFFLAGS, (caddr_t) ifr) < 0)
106 			goto out;
107 
108 		/*
109 		 * If the interface is a loopback, or its not running
110 		 * then ignore it.
111 		 */
112 		if ((ifr->ifr_flags & IFF_LOOPBACK) != 0)
113 			continue;
114 		if ((ifr->ifr_flags & IFF_RUNNING) == 0)
115 			continue;
116 
117 		/*
118 		 * Get the netmask of this interface
119 		 */
120 		if (ioctl(sk, SIOCGIFNETMASK, (caddr_t) ifr) < 0)
121 			goto out;
122 
123 		netmask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
124 
125 		(void) close(sk);
126 
127 		/*
128 		 * Figure out the subnet's network address
129 		 */
130 		subnet = address & netmask;
131 		/*
132 		 * Now get a usable name.
133 		 * First use the network database,
134 		 * then the host database,
135 		 * and finally just make a dotted quad.
136 		 */
137 		np = getnetbyaddr(subnet, AF_INET);
138 		if (np)
139 			s = np->n_name;
140 		else {
141 			hp = gethostbyaddr((char *) &subnet, 4, AF_INET);
142 			if (hp)
143 				s = hp->h_name;
144 			else
145 				s = inet_dquad(buf, subnet);
146 		}
147 
148 		return strdup(s);
149 	}
150 
151 out:
152 	if (sk >= 0)
153 		(void) close(sk);
154 	return strdup(NO_SUBNET);
155 }
156 
157 #else
158 
159 char *getwire P((void));
160 char *getwire()
161 {
162 	return strdup(NO_SUBNET);
163 }
164  * %sccs.include.redist.c%
165 #endif /* SIOCGIFFLAGS */
166