xref: /dflybsd-src/sbin/ifconfig/af_inet.c (revision 0989c651fdc5dd328ce52881604350b1bd44978a)
1ca74a0a2SSepherosa Ziehau /*
2ca74a0a2SSepherosa Ziehau  * Copyright (c) 1983, 1993
3ca74a0a2SSepherosa Ziehau  *	The Regents of the University of California.  All rights reserved.
4ca74a0a2SSepherosa Ziehau  *
5ca74a0a2SSepherosa Ziehau  * Redistribution and use in source and binary forms, with or without
6ca74a0a2SSepherosa Ziehau  * modification, are permitted provided that the following conditions
7ca74a0a2SSepherosa Ziehau  * are met:
8ca74a0a2SSepherosa Ziehau  * 1. Redistributions of source code must retain the above copyright
9ca74a0a2SSepherosa Ziehau  *    notice, this list of conditions and the following disclaimer.
10ca74a0a2SSepherosa Ziehau  * 2. Redistributions in binary form must reproduce the above copyright
11ca74a0a2SSepherosa Ziehau  *    notice, this list of conditions and the following disclaimer in the
12ca74a0a2SSepherosa Ziehau  *    documentation and/or other materials provided with the distribution.
13dc71b7abSJustin C. Sherrill  * 3. Neither the name of the University nor the names of its contributors
14ca74a0a2SSepherosa Ziehau  *    may be used to endorse or promote products derived from this software
15ca74a0a2SSepherosa Ziehau  *    without specific prior written permission.
16ca74a0a2SSepherosa Ziehau  *
17ca74a0a2SSepherosa Ziehau  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18ca74a0a2SSepherosa Ziehau  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19ca74a0a2SSepherosa Ziehau  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20ca74a0a2SSepherosa Ziehau  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21ca74a0a2SSepherosa Ziehau  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22ca74a0a2SSepherosa Ziehau  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23ca74a0a2SSepherosa Ziehau  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24ca74a0a2SSepherosa Ziehau  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25ca74a0a2SSepherosa Ziehau  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26ca74a0a2SSepherosa Ziehau  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27ca74a0a2SSepherosa Ziehau  * SUCH DAMAGE.
28ca74a0a2SSepherosa Ziehau  *
29ca74a0a2SSepherosa Ziehau  * $FreeBSD: src/sbin/ifconfig/af_inet.c,v 1.2 2005/06/16 19:37:09 ume Exp $
30ca74a0a2SSepherosa Ziehau  */
31ca74a0a2SSepherosa Ziehau 
325ecbd701SAaron LI #include <sys/param.h>
33ca74a0a2SSepherosa Ziehau #include <sys/types.h>
34ca74a0a2SSepherosa Ziehau #include <sys/ioctl.h>
35ca74a0a2SSepherosa Ziehau #include <sys/socket.h>
36ca74a0a2SSepherosa Ziehau #include <net/if.h>
3746158ff5SAaron LI #include <net/if_var.h>		/* for struct ifaddr */
3846158ff5SAaron LI #include <netinet/in.h>
3946158ff5SAaron LI #include <netinet/in_var.h>
4046158ff5SAaron LI #include <arpa/inet.h>
4146158ff5SAaron LI #include <netdb.h>
42ca74a0a2SSepherosa Ziehau 
43ca74a0a2SSepherosa Ziehau #include <err.h>
445ecbd701SAaron LI #include <ifaddrs.h>
45ca74a0a2SSepherosa Ziehau #include <stdio.h>
46ca74a0a2SSepherosa Ziehau #include <stdlib.h>
47ca74a0a2SSepherosa Ziehau #include <string.h>
48ca74a0a2SSepherosa Ziehau #include <unistd.h>
49ca74a0a2SSepherosa Ziehau 
50ca74a0a2SSepherosa Ziehau #include "ifconfig.h"
51ca74a0a2SSepherosa Ziehau 
52ca74a0a2SSepherosa Ziehau static struct ifaliasreq in_addreq;
53ca74a0a2SSepherosa Ziehau static struct ifreq in_ridreq;
5451a3d09eSAaron LI static char addr_buf[NI_MAXHOST];  /* for getnameinfo() */
55ca74a0a2SSepherosa Ziehau 
56ca74a0a2SSepherosa Ziehau static void
in_status(int s __unused,const struct ifaddrs * ifa)575ecbd701SAaron LI in_status(int s __unused, const struct ifaddrs *ifa)
58ca74a0a2SSepherosa Ziehau {
59ca74a0a2SSepherosa Ziehau 	struct sockaddr_in *sin, null_sin;
6051a3d09eSAaron LI 	int error, n_flags;
61ca74a0a2SSepherosa Ziehau 
62ca74a0a2SSepherosa Ziehau 	memset(&null_sin, 0, sizeof(null_sin));
63ca74a0a2SSepherosa Ziehau 
645ecbd701SAaron LI 	sin = (struct sockaddr_in *)ifa->ifa_addr;
65ca74a0a2SSepherosa Ziehau 	if (sin == NULL)
66ca74a0a2SSepherosa Ziehau 		return;
67ca74a0a2SSepherosa Ziehau 
6851a3d09eSAaron LI 	if (f_addr != NULL && strcmp(f_addr, "fqdn") == 0)
6951a3d09eSAaron LI 		n_flags = 0;
7051a3d09eSAaron LI 	else if (f_addr != NULL && strcmp(f_addr, "host") == 0)
7151a3d09eSAaron LI 		n_flags = NI_NOFQDN;
7251a3d09eSAaron LI 	else
7351a3d09eSAaron LI 		n_flags = NI_NUMERICHOST;
7451a3d09eSAaron LI 
7551a3d09eSAaron LI 	error = getnameinfo((struct sockaddr *)sin, sin->sin_len, addr_buf,
7651a3d09eSAaron LI 			    sizeof(addr_buf), NULL, 0, n_flags);
7751a3d09eSAaron LI 	if (error != 0)
7851a3d09eSAaron LI 		inet_ntop(AF_INET, &sin->sin_addr, addr_buf, sizeof(addr_buf));
7951a3d09eSAaron LI 
8051a3d09eSAaron LI 	printf("\tinet %s", addr_buf);
81ca74a0a2SSepherosa Ziehau 
825ecbd701SAaron LI 	if (ifa->ifa_flags & IFF_POINTOPOINT) {
835ecbd701SAaron LI 		sin = (struct sockaddr_in *)ifa->ifa_dstaddr;
845ecbd701SAaron LI 		if (sin == NULL)
85ca74a0a2SSepherosa Ziehau 			sin = &null_sin;
86ca74a0a2SSepherosa Ziehau 		printf(" --> %s", inet_ntoa(sin->sin_addr));
87ca74a0a2SSepherosa Ziehau 	}
88ca74a0a2SSepherosa Ziehau 
895ecbd701SAaron LI 	sin = (struct sockaddr_in *)ifa->ifa_netmask;
905ecbd701SAaron LI 	if (sin == NULL)
91ca74a0a2SSepherosa Ziehau 		sin = &null_sin;
9251a3d09eSAaron LI 	if (f_inet != NULL && strcmp(f_inet, "cidr") == 0) {
9351a3d09eSAaron LI 		int cidr = 32;
9451a3d09eSAaron LI 		unsigned long smask = ntohl(sin->sin_addr.s_addr);
9551a3d09eSAaron LI 
9651a3d09eSAaron LI 		while ((smask & 1) == 0) {
9751a3d09eSAaron LI 			smask >>= 1;
9851a3d09eSAaron LI 			cidr--;
9951a3d09eSAaron LI 			if (cidr == 0)
10051a3d09eSAaron LI 				break;
10151a3d09eSAaron LI 		}
10251a3d09eSAaron LI 		printf("/%d", cidr);
10351a3d09eSAaron LI 	} else if (f_inet != NULL && strcmp(f_inet, "dotted") == 0) {
10451a3d09eSAaron LI 		printf(" netmask %s", inet_ntoa(sin->sin_addr));
10551a3d09eSAaron LI 	} else {
10651a3d09eSAaron LI 		printf(" netmask 0x%lx",
10751a3d09eSAaron LI 			(unsigned long)ntohl(sin->sin_addr.s_addr));
10851a3d09eSAaron LI 	}
109ca74a0a2SSepherosa Ziehau 
1105ecbd701SAaron LI 	if (ifa->ifa_flags & IFF_BROADCAST) {
1115ecbd701SAaron LI 		sin = (struct sockaddr_in *)ifa->ifa_broadaddr;
1125ecbd701SAaron LI 		if (sin != NULL && sin->sin_addr.s_addr != 0)
113ca74a0a2SSepherosa Ziehau 			printf(" broadcast %s", inet_ntoa(sin->sin_addr));
114ca74a0a2SSepherosa Ziehau 	}
115ca74a0a2SSepherosa Ziehau 	putchar('\n');
116ca74a0a2SSepherosa Ziehau }
117ca74a0a2SSepherosa Ziehau 
118ca74a0a2SSepherosa Ziehau #define SIN(x) ((struct sockaddr_in *) &(x))
119ca74a0a2SSepherosa Ziehau static struct sockaddr_in *sintab[] = {
120ca74a0a2SSepherosa Ziehau 	SIN(in_ridreq.ifr_addr), SIN(in_addreq.ifra_addr),
121ca74a0a2SSepherosa Ziehau 	SIN(in_addreq.ifra_mask), SIN(in_addreq.ifra_broadaddr)
122ca74a0a2SSepherosa Ziehau };
123ca74a0a2SSepherosa Ziehau 
124ca74a0a2SSepherosa Ziehau static void
in_getaddr(const char * s,int which)125ca74a0a2SSepherosa Ziehau in_getaddr(const char *s, int which)
126ca74a0a2SSepherosa Ziehau {
127ca74a0a2SSepherosa Ziehau 	struct sockaddr_in *sin = sintab[which];
128ca74a0a2SSepherosa Ziehau 	struct hostent *hp;
129ca74a0a2SSepherosa Ziehau 	struct netent *np;
130ca74a0a2SSepherosa Ziehau 
131ca74a0a2SSepherosa Ziehau 	sin->sin_len = sizeof(*sin);
132ca74a0a2SSepherosa Ziehau 	if (which != MASK)
133ca74a0a2SSepherosa Ziehau 		sin->sin_family = AF_INET;
134ca74a0a2SSepherosa Ziehau 
135ca74a0a2SSepherosa Ziehau 	if (which == ADDR) {
136ca74a0a2SSepherosa Ziehau 		char *p = NULL;
137ca74a0a2SSepherosa Ziehau 
138ca74a0a2SSepherosa Ziehau 		if ((p = strrchr(s, '/')) != NULL) {
139ca74a0a2SSepherosa Ziehau 			/* address is `name/masklen' */
14093b0f758SAaron LI 			int masklen, ret;
141ca74a0a2SSepherosa Ziehau 			struct sockaddr_in *min = sintab[MASK];
14293b0f758SAaron LI 
143ca74a0a2SSepherosa Ziehau 			*p = '\0';
144ca74a0a2SSepherosa Ziehau 			ret = sscanf(p+1, "%u", &masklen);
145ca74a0a2SSepherosa Ziehau 			if (ret != 1 || (masklen < 0 || masklen > 32)) {
146ca74a0a2SSepherosa Ziehau 				*p = '/';
147ca74a0a2SSepherosa Ziehau 				errx(1, "%s: bad value", s);
148ca74a0a2SSepherosa Ziehau 			}
149ca74a0a2SSepherosa Ziehau 			min->sin_len = sizeof(*min);
15093b0f758SAaron LI 			min->sin_addr.s_addr =
15193b0f758SAaron LI 			    htonl(rounddown2(0xffffffff, 1LL << (32 - masklen)));
152ca74a0a2SSepherosa Ziehau 		}
153ca74a0a2SSepherosa Ziehau 	}
154ca74a0a2SSepherosa Ziehau 
155ca74a0a2SSepherosa Ziehau 	if (inet_aton(s, &sin->sin_addr))
156ca74a0a2SSepherosa Ziehau 		return;
157678e8cc6SSascha Wildner 	if ((hp = gethostbyname(s)) != NULL)
158*0989c651SAaron LI 		memcpy(&sin->sin_addr, hp->h_addr,
15946158ff5SAaron LI 		       MIN((size_t)hp->h_length, sizeof(sin->sin_addr)));
160678e8cc6SSascha Wildner 	else if ((np = getnetbyname(s)) != NULL)
161ca74a0a2SSepherosa Ziehau 		sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
162ca74a0a2SSepherosa Ziehau 	else
163ca74a0a2SSepherosa Ziehau 		errx(1, "%s: bad value", s);
164ca74a0a2SSepherosa Ziehau }
165ca74a0a2SSepherosa Ziehau 
166ca74a0a2SSepherosa Ziehau static void
in_status_tunnel(int s)167ca74a0a2SSepherosa Ziehau in_status_tunnel(int s)
168ca74a0a2SSepherosa Ziehau {
169ca74a0a2SSepherosa Ziehau 	char src[NI_MAXHOST];
170ca74a0a2SSepherosa Ziehau 	char dst[NI_MAXHOST];
171ca74a0a2SSepherosa Ziehau 	struct ifreq ifr;
172ca74a0a2SSepherosa Ziehau 	const struct sockaddr *sa = (const struct sockaddr *) &ifr.ifr_addr;
173ca74a0a2SSepherosa Ziehau 
174ca74a0a2SSepherosa Ziehau 	memset(&ifr, 0, sizeof(ifr));
1757203d4e3SAaron LI 	strlcpy(ifr.ifr_name, IfName, sizeof(ifr.ifr_name));
176ca74a0a2SSepherosa Ziehau 
1770b22c3cfSAaron LI 	if (ioctl(s, SIOCGIFPSRCADDR, &ifr) < 0)
178ca74a0a2SSepherosa Ziehau 		return;
179ca74a0a2SSepherosa Ziehau 	if (sa->sa_family != AF_INET)
180ca74a0a2SSepherosa Ziehau 		return;
18193b0f758SAaron LI 	if (getnameinfo(sa, sa->sa_len, src, sizeof(src), 0, 0,
18293b0f758SAaron LI 			NI_NUMERICHOST) != 0)
183ca74a0a2SSepherosa Ziehau 		src[0] = '\0';
184ca74a0a2SSepherosa Ziehau 
1850b22c3cfSAaron LI 	if (ioctl(s, SIOCGIFPDSTADDR, &ifr) < 0)
186ca74a0a2SSepherosa Ziehau 		return;
187ca74a0a2SSepherosa Ziehau 	if (sa->sa_family != AF_INET)
188ca74a0a2SSepherosa Ziehau 		return;
18993b0f758SAaron LI 	if (getnameinfo(sa, sa->sa_len, dst, sizeof(dst), 0, 0,
19093b0f758SAaron LI 			NI_NUMERICHOST) != 0)
191ca74a0a2SSepherosa Ziehau 		dst[0] = '\0';
192ca74a0a2SSepherosa Ziehau 
193ca74a0a2SSepherosa Ziehau 	printf("\ttunnel inet %s --> %s\n", src, dst);
194ca74a0a2SSepherosa Ziehau }
195ca74a0a2SSepherosa Ziehau 
196ca74a0a2SSepherosa Ziehau static void
in_set_tunnel(int s,struct addrinfo * srcres,struct addrinfo * dstres)197ca74a0a2SSepherosa Ziehau in_set_tunnel(int s, struct addrinfo *srcres, struct addrinfo *dstres)
198ca74a0a2SSepherosa Ziehau {
199ca74a0a2SSepherosa Ziehau 	struct ifaliasreq addreq;
200ca74a0a2SSepherosa Ziehau 
201ca74a0a2SSepherosa Ziehau 	memset(&addreq, 0, sizeof(addreq));
2027203d4e3SAaron LI 	strlcpy(addreq.ifra_name, IfName, sizeof(addreq.ifra_name));
203ca74a0a2SSepherosa Ziehau 	memcpy(&addreq.ifra_addr, srcres->ai_addr, srcres->ai_addr->sa_len);
204ca74a0a2SSepherosa Ziehau 	memcpy(&addreq.ifra_dstaddr, dstres->ai_addr, dstres->ai_addr->sa_len);
205ca74a0a2SSepherosa Ziehau 
206ca74a0a2SSepherosa Ziehau 	if (ioctl(s, SIOCSIFPHYADDR, &addreq) < 0)
207ca74a0a2SSepherosa Ziehau 		warn("SIOCSIFPHYADDR");
208ca74a0a2SSepherosa Ziehau }
209ca74a0a2SSepherosa Ziehau 
210ca74a0a2SSepherosa Ziehau static struct afswtch af_inet = {
211ca74a0a2SSepherosa Ziehau 	.af_name	= "inet",
212ca74a0a2SSepherosa Ziehau 	.af_af		= AF_INET,
213ca74a0a2SSepherosa Ziehau 	.af_status	= in_status,
214ca74a0a2SSepherosa Ziehau 	.af_getaddr	= in_getaddr,
215ca74a0a2SSepherosa Ziehau 	.af_status_tunnel = in_status_tunnel,
216ca74a0a2SSepherosa Ziehau 	.af_settunnel	= in_set_tunnel,
217ca74a0a2SSepherosa Ziehau 	.af_difaddr	= SIOCDIFADDR,
218ca74a0a2SSepherosa Ziehau 	.af_aifaddr	= SIOCAIFADDR,
219ca74a0a2SSepherosa Ziehau 	.af_ridreq	= &in_ridreq,
220ca74a0a2SSepherosa Ziehau 	.af_addreq	= &in_addreq,
221ca74a0a2SSepherosa Ziehau };
222ca74a0a2SSepherosa Ziehau 
223ec7e0eebSAaron LI __constructor(112)
224ec7e0eebSAaron LI static void
inet_ctor(void)225ca74a0a2SSepherosa Ziehau inet_ctor(void)
226ca74a0a2SSepherosa Ziehau {
227ca74a0a2SSepherosa Ziehau 	af_register(&af_inet);
228ca74a0a2SSepherosa Ziehau }
229