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