Column sorting fixes, thanks to Tony550
[tomato.git] / release / src / router / dhcpv6 / if.c
blob61a7fd6551f3946e91fb27a8b04358b18664657b
1 /* $KAME: if.c,v 1.6 2005/09/16 11:30:15 suz Exp $ */
3 /*
4 * Copyright (C) 2002 WIDE Project.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <sys/queue.h>
35 #include <net/if.h>
36 #include <netinet/in.h>
37 #ifdef __KAME__
38 #include <net/if_dl.h>
39 #endif
41 #include <syslog.h>
42 #include <stdlib.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <ifaddrs.h>
46 #include <errno.h>
48 #include <dhcp6.h>
49 #include <config.h>
50 #include <common.h>
52 extern int errno;
54 struct dhcp6_if *dhcp6_if;
56 struct dhcp6_if *
57 ifinit(ifname)
58 char *ifname;
60 struct dhcp6_if *ifp;
62 if ((ifp = find_ifconfbyname(ifname)) != NULL) {
63 dprintf(LOG_NOTICE, FNAME, "duplicated interface: %s", ifname);
64 return (NULL);
67 if ((ifp = malloc(sizeof(*ifp))) == NULL) {
68 dprintf(LOG_ERR, FNAME, "malloc failed");
69 goto fail;
71 memset(ifp, 0, sizeof(*ifp));
73 TAILQ_INIT(&ifp->event_list);
75 if ((ifp->ifname = strdup(ifname)) == NULL) {
76 dprintf(LOG_ERR, FNAME, "failed to copy ifname");
77 goto fail;
80 if (ifreset(ifp))
81 goto fail;
83 TAILQ_INIT(&ifp->reqopt_list);
84 TAILQ_INIT(&ifp->iaconf_list);
86 ifp->authproto = DHCP6_AUTHPROTO_UNDEF;
87 ifp->authalgorithm = DHCP6_AUTHALG_UNDEF;
88 ifp->authrdm = DHCP6_AUTHRDM_UNDEF;
91 struct ifaddrs *ifa, *ifap;
92 struct sockaddr_in6 *sin6;
94 if (getifaddrs(&ifap) < 0) {
95 dprintf(LOG_ERR, FNAME, "getifaddrs failed: %s",
96 strerror(errno));
97 goto fail;
100 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
101 if (strcmp(ifa->ifa_name, ifname) != 0)
102 continue;
103 if (ifa->ifa_addr == NULL)
104 continue;
105 if (ifa->ifa_addr->sa_family != AF_INET6)
106 continue;
108 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
109 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
110 continue;
112 ifp->addr = sin6->sin6_addr;
115 freeifaddrs(ifap);
118 ifp->next = dhcp6_if;
119 dhcp6_if = ifp;
120 return (ifp);
122 fail:
123 if (ifp->ifname != NULL)
124 free(ifp->ifname);
125 free(ifp);
126 return (NULL);
130 ifreset(ifp)
131 struct dhcp6_if *ifp;
133 unsigned int ifid;
134 u_int32_t linkid;
136 if ((ifid = if_nametoindex(ifp->ifname)) == 0) {
137 dprintf(LOG_ERR, FNAME, "invalid interface(%s): %s",
138 ifp->ifname, strerror(errno));
139 return (-1);
142 #ifdef HAVE_SCOPELIB
143 if (inet_zoneid(AF_INET6, 2, ifname, &linkid)) {
144 dprintf(LOG_ERR, FNAME, "failed to get link ID for %s",
145 ifname);
146 return (-1);
148 #else
149 linkid = ifid; /* XXX: assume 1to1 mapping IFs and links */
150 #endif
152 ifp->ifid = ifid;
153 ifp->linkid = linkid;
155 return (0);
158 struct dhcp6_if *
159 find_ifconfbyname(ifname)
160 char *ifname;
162 struct dhcp6_if *ifp;
164 for (ifp = dhcp6_if; ifp; ifp = ifp->next) {
165 if (strcmp(ifp->ifname, ifname) == 0)
166 return (ifp);
169 return (NULL);
172 struct dhcp6_if *
173 find_ifconfbyid(id)
174 unsigned int id;
176 struct dhcp6_if *ifp;
178 for (ifp = dhcp6_if; ifp; ifp = ifp->next) {
179 if (ifp->ifid == id)
180 return (ifp);
183 return (NULL);