├── .gitignore ├── CHANGES ├── COPYRIGHT ├── Makefile.in ├── README ├── addrconf.c ├── addrconf.h ├── auth.c ├── auth.h ├── base64.c ├── base64.h ├── cfparse.y ├── cftoken.l ├── common.c ├── common.h ├── config.c ├── config.guess ├── config.h ├── config.sub ├── configure ├── configure.ac ├── dhcp6.h ├── dhcp6c.8 ├── dhcp6c.c ├── dhcp6c.conf.5 ├── dhcp6c.conf.sample ├── dhcp6c.h ├── dhcp6c_ia.c ├── dhcp6c_ia.h ├── dhcp6c_script.c ├── if.c ├── install-sh ├── lease.c ├── lease.h ├── missing ├── daemon.c ├── err.h ├── getifaddrs.c ├── ifaddrs.h ├── strlcat.c ├── strlcpy.c ├── sys │ └── queue.h └── warnx.c ├── prefixconf.c ├── prefixconf.h ├── timer.c └── timer.h /.gitignore: -------------------------------------------------------------------------------- 1 | config.cache 2 | config.log 3 | config.status 4 | Makefile 5 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | 2008-07-30 SUZUKI, Shinsuke 2 | * dhcp6[cs].conf.sample: added several comments/examples. 3 | (contributed by Stefan Sperling) 4 | 5 | --- 20080615 tar ball released --- 6 | 2008-05-01 SUZUKI, Shinsuke 7 | * common.c: fixed a memory leak (Bug-ID: 1847587) 8 | * dhcp6s.c: fixed a potential NULL pointer access (Bug-ID: 1848304). 9 | used a val_statefuladdr, instead of val_prefix, to access 10 | an address in IA in DHCP DECLINE handling. 11 | * config.c: fixed a possible memory leak. (Bug-ID 1847588) 12 | * dhcp6s.c: fixed a lifetime calculation failure in RENEW/REBIND 13 | process for stateful-address. (Bug-ID: 1850457) 14 | * common.c: fixed a improper handling of a domain-name ending with '.'. 15 | (Bug-ID: 1852869) 16 | 17 | 2007-12-06 SUZUKI, Shinsuke 18 | * common.c: fixed a possible memory leak. (Bug-ID 1844676) 19 | * common.c: fixed a possible double free. (Bug-ID 1844683) 20 | * dhcp6s.c: fixed a bugthat dhcp6s cannot accept a relayed 21 | request message with authentication option. (Bug-ID 1814287) 22 | 23 | 2007-07-25 SUZUKI, Shinsuke 24 | * config.c, lease.h, common.c: removed compilation warnings 25 | 26 | 2007-07-24 SUZUKI, Shinsuke 27 | * dhcp6s.c, dhcp6c.c, dhcp6relay.c, configure*: use sig_atomic_t for 28 | a signal-handler variable (Bug-ID 1678874) 29 | * common.c: fixed a buffer overrun in sprint_uint64() 30 | (Bug-ID 1714648) 31 | 32 | 2007-07-10 SUZUKI, Shinsuke 33 | * common.c: fixed a singular-point detection failure in replay check. 34 | (Bug-ID 1714644) 35 | 36 | 2007-06-28 SUZUKI, Shinsuke 37 | * dhcp6s.8: fixed a typo in a manual (program name "dhcp6sctl" should 38 | be "dhcp6ctl") 39 | 40 | --- 20070507 tar ball released --- 41 | 2007-05-03 SUZUKI, Shinsuke 42 | * dhcp6relay.c: changes the destination port of a relayed DHCP packet 43 | from 546 to 547, when it is supposed to be bound for a relay, 44 | instead of a client. (the situation occurs when DHCPv6-relays are 45 | cascased in a row) 46 | * dhcp6s.c: fixed a Solicitation message validation error (introduced 47 | on Mar 21 2007) 48 | 49 | 2007-03-23 SUZUKI, Shinsuke 50 | * dhcp6relay.c,dhcp6.c: in signal-receiving procedure, not uses 51 | a function that is not always designed to be signal-safe 52 | (Bug-ID 1678874) 53 | 54 | 2007-03-21 SUZUKI, Shinsuke 55 | fixed several bugs found in IPv6-Ready-Logo DHCPv6 Self-Test script. 56 | * dhcp6s.c, config.h, if.c: implemented DHCPv6 Confirm message processing 57 | on DHCPv6 server. 58 | * dhcp6s.c, lease.c: implemented DHCPv6 Decline message processing on DHCPv6 server. 59 | * dhcp6s.c: fixed a Solicitation message validation as stated in RFC3315 15.2. 60 | * dhcp6s.c: fixed a bug that Rebind does not work for IA-NA. 61 | * config.c: supported an address pool that has only one entry. 62 | 63 | 2007-03-20 SUZUKI, Shinsuke 64 | * common.c: fixed a bug that IA-PD/IA-NA cannot coexist in one DHCP message 65 | when they have the same IA-ID. 66 | 67 | 2007-02-28 SUZUKI, Shinsuke 68 | * config.c: fixed a typo. 69 | 70 | 2007-02-27 SUZUKI, Shinsuke 71 | * dhcp6relay.c, dhcp6relay_script.c, common.[ch], dhcp6c_script.c, 72 | Makefile.in, dhcp6relay.8: 73 | supported script execution for dhcp6relay (contributed by Bruno STEVANT) 74 | 75 | * Makefile.in, configure.in, configure, auth.h, common.c, control.h, dhcp6.h, 76 | dhcp6s.c, missing/{arc4random.h, daemon.c, err.h, getifaddrs.c, ifaddrs.h, 77 | sys/queue.h, warnx.c} 78 | supported compilation on Solaris (contributed by James Carlson) 79 | 80 | 2007-02-12 SUZUKI, Shinsuke 81 | * cftoken.l: accepts interface names, such as eth0.100(Linux VLAN interface) 82 | or foobar (named by "ifconfig name" command). (Bug-ID 1644637) 83 | * configure.in, Makefile.in: allows a user to specify the owner/group for the 84 | installed files. (suggested by Tsuyoshi MOMOSE and Tomofumi Hayashi) 85 | 86 | 2007-01-11 SUZUKI, Shinsuke 87 | * dhcp6s.conf.5: fixed an incorrect descrption regarding NTP option. 88 | 2006-12-04 SUZUKI, Shinsuke 89 | * dhcp6c.8: clarified the behavior of the Info-req mode. 90 | * addrconf.c, common.[ch], configure, configure.in, dhcp6relay.c, 91 | prefixconf.c: introduced a HAVE_SA_LEN macro to support OSes 92 | (other than linux) without length field in sockaddr_* 93 | 94 | 2006-11-15 SUZUKI, Shinsuke 95 | * dhcp6s.c: fixed an IA allocation failure from pool when it doubly 96 | requested by the same client. (patch submitted by Hajimu UMEMOTO) 97 | * Makefile.in: creates man/man[58] in "make install" 98 | (suggested by Masahide NAKAMURA) 99 | 100 | 2006-11-05 SUZUKI, Shinsuke 101 | * dhcp6s.c: dhcp6s recognizes "-P" option. 102 | (patch submitted by Masahide NAKAMURA) 103 | 104 | * dhcp6relay.c: accepts ULA (Bug-ID 1584704) 105 | 106 | * Makefile.in: fixed a compilation error on SuSE and Debian Linux. 107 | (patch submitted by Masahide NAKAMURA) 108 | 109 | --- 20061016 tar ball released --- 110 | 2006-10-13 SUZUKI, Shinsuke 111 | * Makefile.in: creates the target directory in "make install" 112 | (suggested by Masahide NAKAMURA) 113 | 114 | 2006-10-08 SUZUKI, Shinsuke 115 | * dhcp6s.conf.sample: corrected a misleading comment (pointed out by 116 | Hajimu UMEMOTO) 117 | 118 | 2006-10-04 SUZUKI, Shinsuke 119 | * config.c: fixed a improper memory access when there is no free 120 | address in an address pool. (Bug-ID 1563232) 121 | 122 | fixed a bug that a pooled address will never be reused even when 123 | it is released. 124 | 125 | 2006-10-03 SUZUKI, Shinsuke 126 | * config.c: dhcp6s does not include a 0 refresh-time option in 127 | ADVERTISE/REPLY message, when "option refreshtime" configuration does 128 | not exist in its configuration. (patch submitted by Jun-ya Kato) 129 | 130 | * cftoken.l, cfparse.y: fixed a compilation failure by flex 2.5.4 131 | (patch submitted by Jun-ya Kato) 132 | 133 | 2006-10-01 SUZUKI, Shinsuke 134 | * cftoken.l, dhcp6[cs].conf.5: accepted "nis-domain-name" and "nisp- 135 | domain-name" as a configuration keyword for NIS/NIS+ domain name, 136 | as well as nis/nisp-server-domain-name. (Bug-ID 1566494) 137 | 138 | * cftoken.l: supported a declaration name (hostname, poolname, 139 | keyname, authname) including "-". (Bug-ID 1566476) 140 | 141 | 2006-09-20 SUZUKI, Shinsuke 142 | * common.c: fixed a bug that dhcp6s inserts SIP server addresses into 143 | DNS server address option (Bug-ID 1561202). (degrade from 2006-07-30) 144 | * common.c: fixed a bug that status-code option might include a unexpected 145 | garbage value. (Bug-ID 1561202) 146 | * dhcp6s.conf.5, dhcp6s.conf.sample: you need to provide a preferred-lifetime 147 | for each address-prefix. (Bug-ID 1558811) 148 | 149 | 2006-09-20 STEVANT, Bruno 150 | * lease.c: Fix a memory violation in lease management. 151 | 152 | --- 20060902 tar ball released --- 153 | 2006-09-02 SUZUKI, Shinsuke 154 | * added a configure check routine to automatically detect a 155 | difference in TAILQ_FOREACH_REVERSE macros (Suggested by Brute 156 | STEVANT) 157 | * fixed a bug that dhcp6c cannot advertise an Option-Request-Option. 158 | * fixed a compilation failure in freebsd4 159 | 160 | 2006-07-30 SUZUKI, Shinsuke 161 | * supported the following options: 162 | NIS server option, NIS domain option (RFC3898) 163 | NIS+ server option, NIS+ domain option (RFC3898) 164 | BCMCS server option, BCMCS domain option (RFC4280) 165 | * changed the name of the enviromental variable for SIP server 166 | address (new_sip_servers). 167 | * removed a configure option to control the NTP option number. 168 | (since one year has been passed since its official assignment) 169 | 170 | 2006-07-29 SUZUKI, Shinsuke 171 | * dhcp6s and dhcp6relay dumps process-id file, like dhcp6c 172 | 173 | 2006-05-05 SUZUKI, Shinsuke 174 | * fixed a compilation error on netbsd 175 | * updated the list of the supported RFCs 176 | * NTP option number has been already assigned by IANA 177 | * added other official option numbers for future implementors 178 | 179 | 2006-04-26 SUZUKI, Shinsuke 180 | * supported 'include' statement 181 | (contributed by Bruno STEVANT) 182 | 183 | 2006-04-11 SUZUKI, Shinsuke 184 | * removed 'ifdef USE_POOL' macros, since it is always ON 185 | * rename some pool-related variables to prepare for the support of prefix-pool 186 | 187 | --- 20060322 tar ball released --- 188 | 2006-03-20 SUZUKI, Shinsuke 189 | * fixed a bug that dhcp6c cannot receive a DHCPv6 packet on linux. 190 | (Request ID=1435976, and a patch proposed by Yasuyuki KOZAKAI) 191 | 192 | 2006-03-08 SUZUKI, Shinsuke 193 | * added some missing queue-management macros to make it compilable on linux 194 | 195 | --- 20060214 tar ball released --- 196 | 2006-01-26 SUZUKI, Shinsuke 197 | * supported IA-NA address-pool (contributed by: WIDE Project Secure6-WG) 198 | ToDo: IA-PD prefix-pool, write a manual 199 | 200 | 2006-01-19 SUZUKI, Shinsuke 201 | * corrected the condition for detecting unwanted incoming messages 202 | * missing initialization in dhcp6c 203 | --- 20060114 tar ball released --- 204 | --- 20051211 tar ball released --- 205 | 2005-12-11 SUZUKI, Shinsuke 206 | * locate every files in /usr/local/xxx, instead of /usr/local/v6/xxx 207 | * Assign an official option number for Information Refresh Timer 208 | * Removed old prefix delegation options, since these options numbers 209 | coinsides with Information Refresh Timer. 210 | --- 20050723a tar ball released --- 211 | 212 | 2005-07-22 JINMEI, Tatuya 213 | * kame/kame/dhcp6: fixed memory leak for renew/rebind event data. 214 | (KAME PR 872 reported by Meng Huan Hsieh) 215 | 216 | 2005-05-03 JINMEI, Tatuya 217 | * kame/kame/dhcp6/dhcp6c_ia.c (ia_timo): kept the latest server's 218 | DUID even in the REBIND state in case of sending a Release message 219 | in that state. 220 | 221 | 2005-05-03 JINMEI, Tatuya 222 | * kame/kame/dhcp6/cfparse.y: corrected "address parameters" so 223 | that we don't have to specify the meaningless (but mandatory) 224 | prefix length in the context of IA_NA. 225 | 226 | 2005-05-03 JINMEI, Tatuya 227 | * kame/kame/dhcp6/config.c (configure_commit): made sure that 228 | interface parameters are initialized with the default values even 229 | if the interface is not explicitly configured in the configuration 230 | file. This particularly made sure that the preference option is 231 | not included unless explicitly specified. A memory leakage for 232 | the client when specifying a script file was also fixed. 233 | 234 | 2005-04-29 JINMEI, Tatuya 235 | * kame/kame/dhcp6/dhcp6c.c (client6_mainloop): corrected error 236 | handling for select(2) in order to avoid unexpected blocking when 237 | receiving a signal. 238 | 239 | 2005-04-27 JINMEI, Tatuya 240 | * kame/sys/netinet6/in6.c (in6_update_ifa): always updated 241 | ia6_updatetime regardless of whether the address is created or 242 | updated. This is necessary so that the expiration times will be 243 | updated correctly when the lifetiems of an existing address are 244 | modified by hand or by a process such as a DHCPv6 client. 245 | 246 | 2005-04-26 JINMEI, Tatuya 247 | * kame/kame/dhcp6/addrconf.c (na_ifaddrconf): corrected lifetime 248 | arguments to ifaddrconf(). 249 | 250 | 2005-03-30 JINMEI, Tatuya 251 | * kame/kame/dhcp6/addrconf.c (update_address): make sure that 252 | the lifetimes of addresses are updated when the client receives a 253 | Reply in response to Renew or Rebind. 254 | 255 | 2005-03-02 SUZUKI, Shinsuke 256 | * kame/kame/dhcp6/dhcp6.c: fixed a DHCPv6-client 257 | initialization failure when a node has no IPv6 global address. 258 | 259 | 2005-03-02 SUZUKI, Shinsuke 260 | * kame/kame/dhcp6/dhcp6relay.[c8]: supports multiple client-side 261 | interfaces 262 | 263 | 2005-01-12 suz@crl.hitachi.co.jp 264 | * kame/kame/dhcp6: implemented stateful non-temporary address 265 | assignment. 266 | 267 | 2004-12-03 JINMEI, Tatuya 268 | * kame/kame/dhcp6/common.c: silenced strict-aliasing warnings. 269 | Otherwise dhcp6 could not be built with -O2 on FreeBSD 5.3. 270 | (KAME-PR 851) 271 | 272 | 2004-12-02 JINMEI, Tatuya 273 | * kame/kame/dhcp6/config.c (configure_commit): corrected list 274 | management operation. (mostly harmless, but it was incorrect.) 275 | From: Nicolas Dichtel 276 | 277 | 2004-11-28 JINMEI, Tatuya 278 | * kame/kame/dhcp6: catch up draft-ietf-dhc-lifetime-02. 279 | Specifically, 280 | - renamed "lifetime" to "refreshtime". Note that configuration 281 | compatibility was lost 282 | - implemented the default and minimum timer values 283 | - clarified that the refresh time option can only be available for 284 | Information-request and reply exchanges 285 | 286 | 2004-09-07 JINMEI, Tatuya 287 | * kame/kame/dhcp6: provided a new command "dhcp6ctl", deprecating 288 | dhcp6sctl. This new command controls the client as well as the 289 | server. For the client, the "start" and "stop" (which can specify 290 | a particular interface) commands are available. 291 | 292 | 2004-09-04 JINMEI, Tatuya 293 | * kame/kame/dhcp6: added the ability of dhcp6c to work on multiple 294 | interfaces simultaneously. 295 | 296 | --- 20040903a tar ball released --- 297 | 298 | --- 20040816a tar ball released --- 299 | 300 | 2004-08-01 SUZUKI, Shinsuke 301 | * kame/freebsd5/usr.sbin/dhcp6: builds DHCPv6 in FreeBSD5 302 | 303 | --- 20040731a tar ball released --- 304 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | $KAME: COPYRIGHT,v 1.2 2004/07/29 19:02:18 jinmei Exp $ 2 | 3 | Copyright (C) 1998-2004 WIDE Project. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions 8 | are met: 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 3. Neither the name of the project nor the names of its contributors 15 | may be used to endorse or promote products derived from this software 16 | without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 | SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /Makefile.in: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2004 WIDE Project. All rights reserved. 2 | # 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions 5 | # are met: 6 | # 1. Redistributions of source code must retain the above copyright 7 | # notice, this list of conditions and the following disclaimer. 8 | # 2. Redistributions in binary form must reproduce the above copyright 9 | # notice, this list of conditions and the following disclaimer in the 10 | # documentation and/or other materials provided with the distribution. 11 | # 3. Neither the name of the project nor the names of its contributors 12 | # may be used to endorse or promote products derived from this software 13 | # without specific prior written permission. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 16 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | # ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 19 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 | # SUCH DAMAGE. 26 | 27 | # 28 | # $Id$ 29 | # $KAME: Makefile.in,v 1.45 2005/10/16 16:25:38 suz Exp $ 30 | # 31 | 32 | prefix= @prefix@ 33 | srcdir= @srcdir@ 34 | sysconfdir= @sysconfdir@ 35 | localdbdir= @localdbdir@ 36 | user= @user@ 37 | group= @group@ 38 | 39 | CFLAGS= @CFLAGS@ @DEFS@ -DSYSCONFDIR=\"${sysconfdir}\" \ 40 | -DLOCALDBDIR=\"${localdbdir}\" 41 | LDFLAGS=@LDFLAGS@ 42 | LIBOBJS=@LIBOBJS@ 43 | LIBS= @LIBS@ @LEXLIB@ 44 | CC= @CC@ 45 | TARGET= dhcp6c 46 | 47 | INSTALL=@INSTALL@ 48 | INSTALL_PROGRAM=@INSTALL_PROGRAM@ 49 | INSTALL_DATA=@INSTALL_DATA@ 50 | prefix= @prefix@ 51 | exec_prefix= @exec_prefix@ 52 | bindir= @bindir@ 53 | sbindir=@sbindir@ 54 | mandir= @mandir@ 55 | 56 | GENSRCS=cfparse.c cftoken.c 57 | CLIENTOBJS= dhcp6c.o common.o config.o prefixconf.o dhcp6c_ia.o timer.o \ 58 | dhcp6c_script.o if.o base64.o auth.o addrconf.o lease.o \ 59 | $(GENSRCS:%.c=%.o) 60 | CLEANFILES+= y.tab.h 61 | 62 | all: $(TARGET) 63 | dhcp6c: $(CLIENTOBJS) $(LIBOBJS) 64 | $(CC) $(LDFLAGS) -o dhcp6c $(CLIENTOBJS) $(LIBOBJS) $(LIBS) 65 | 66 | y.tab.c y.tab.h: cfparse.y 67 | @YACC@ -d cfparse.y 68 | cfparse.c: y.tab.c 69 | mv y.tab.c $@ 70 | lex.yy.c: cftoken.l y.tab.h 71 | @LEX@ cftoken.l 72 | cftoken.c: lex.yy.c 73 | mv lex.yy.c $@ 74 | 75 | getaddrinfo.o: $(srcdir)/missing/getaddrinfo.c 76 | $(CC) -c $(srcdir)/missing/$*.c 77 | getnameinfo.o: $(srcdir)/missing/getnameinfo.c 78 | $(CC) -c $(srcdir)/missing/$*.c 79 | strlcat.o: $(srcdir)/missing/strlcat.c 80 | $(CC) -c $(srcdir)/missing/$*.c 81 | strlcpy.o: $(srcdir)/missing/strlcpy.c 82 | $(CC) -c $(srcdir)/missing/$*.c 83 | getifaddrs.o: $(srcdir)/missing/getifaddrs.c 84 | $(CC) -c $(srcdir)/missing/$*.c 85 | daemon.o: $(srcdir)/missing/daemon.c 86 | $(CC) -c $(srcdir)/missing/$*.c 87 | warnx.o: $(srcdir)/missing/warnx.c 88 | $(CC) -c $(srcdir)/missing/$*.c 89 | 90 | $(srcdir)/ianaopts.h: gentab.pl bootp-dhcp-parameters 91 | expand bootp-dhcp-parameters | perl gentab.pl > ianaopts.h 92 | 93 | install:: 94 | -mkdir -p $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man5 $(DESTDIR)$(mandir)/man8 95 | $(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(sbindir) 96 | $(INSTALL_DATA) dhcp6c.8 $(DESTDIR)$(mandir)/man8 97 | $(INSTALL_DATA) dhcp6c.conf.5 $(DESTDIR)$(mandir)/man5 98 | 99 | includes:: 100 | 101 | clean:: 102 | /bin/rm -f *.o $(TARGET) $(CLEANFILES) $(GENSRCS) 103 | 104 | distclean:: clean 105 | /bin/rm -f Makefile config.cache config.log config.status .depend 106 | 107 | depend: 108 | mkdep ${CFLAGS:M-[ID]*} $(srcdir)/*.c 109 | 110 | package: 111 | tar -zcvf wide-dhcpv6.tar.gz $(srcdir)/*.[chyl1-8] $(srcdir)/Makefile.in \ 112 | $(srcdir)/README $(srcdir)/COPYRIGHT $(srcdir)/CHANGES \ 113 | $(srcdir)/configure $(srcdir)/configure.in \ 114 | $(srcdir)/install-sh $(srcdir)/*.sample \ 115 | $(srcdir)/missing/strlcpy.c $(srcdir)/missing/daemon.c \ 116 | $(srcdir)/missing/err.h $(srcdir)/missing/warnx.c \ 117 | $(srcdir)/missing/ifaddrs.h $(srcdir)/missing/getifaddrs.c \ 118 | $(srcdir)/missing/sys/queue.h 119 | 120 | upgrade: all install clean 121 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is the WIDE-DHCPv6 client maintained by the OPNsense project. 2 | 3 | Improvements include the following: 4 | 5 | - Reload the client configuration on SIGHUP 6 | - Removed all unused binaries except dhcp6c 7 | - Raw option send and receive support 8 | - PDINFO delegated prefixes environment variable 9 | - Accept interfaces from the configuration file 10 | - Allow assigning the prefix to the WAN interface 11 | - Several relevant patches from Debian 12 | - Extended prefix-interface ifid options 13 | 14 | It is based on a patched version of WIDE-DHCPv6 maintained by hrs@FreeBSD.org. 15 | 16 | Improvements include the following: 17 | 18 | - Increased log verbosity. 19 | - Fix socket leakage by setting FD_CLOEXEC. 20 | - Call a configuration script after addresses and prefixes are set 21 | on an interface. 22 | - Update ifid on interface restart, it may have changed. 23 | - "-n" flag to prevent address release from being sent to the DHCP server 24 | upon restart. 25 | 26 | Original README: 27 | 28 | $KAME: README,v 1.3 2005/01/12 06:06:10 suz Exp $ 29 | 30 | WIDE-DHCPv6 31 | 32 | WIDE-DHCPv6 is an open-source implementation of Dynamic Host 33 | Configuration Protocol for IPv6 (DHCPv6) developed by the KAME 34 | project. 35 | 36 | The implementation mainly conforms to the following standards: 37 | 38 | - RFC3315: Dynamic Host Configuration Protocol for IPv6 (DHCPv6) 39 | - RFC3319: Dynamic Host Configuration Protocol (DHCPv6) Options 40 | for Session Initiation Protocol (SIP) Servers 41 | - RFC3633: IPv6 Prefix Options for Dynamic Host Configuration 42 | Protocol (DHCP) 43 | - RFC3646: DNS Configuration options for Dynamic Host 44 | Configuration Protocol for IPv6 (DHCPv6) 45 | - RFC4075: Simple Network Time Protocol (SNTP) Configuration 46 | Option for DHCPv6 47 | - RFC4242: Information Refresh Time Option for Dynamic Host 48 | Configuration Protocol for IPv6 (DHCPv6) 49 | 50 | All the components of the main protocol are provided, i.e., 51 | DHCPv6 clients, servers, and relay agents. 52 | 53 | Supported message types are as follows: 54 | Solicit, Advertise, Request, Renew, Rebind, Release, Reply, 55 | Information-request, Relay-forward and Relay-reply. 56 | 57 | Note that the current implementation does not support IPv6 58 | temporary address allocation by DHCPv6, and there is no plan to 59 | implement that feature at the moment. 60 | 61 | Bug Reports and Mailing Lists 62 | 63 | Bugs reports should be put to the Bug Tracking System at 64 | sourceforge.net 65 | http://sourceforge.net/projects/wide-dhcpv6/ 66 | 67 | Information on the mailing list, including how to subscribe 68 | and browse archives, is available at the following URL: 69 | 70 | http://sourceforge.net/mail/?group_id=153668 71 | -------------------------------------------------------------------------------- /addrconf.c: -------------------------------------------------------------------------------- 1 | /* $KAME: addrconf.c,v 1.8 2005/09/16 11:30:13 suz Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2002 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | #ifdef __FreeBSD__ 39 | #include 40 | #endif 41 | 42 | #include 43 | 44 | #ifdef __KAME__ 45 | #include 46 | #include 47 | #endif 48 | 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include "dhcp6.h" 57 | #include "config.h" 58 | #include "common.h" 59 | #include "timer.h" 60 | #include "dhcp6c.h" 61 | #include "dhcp6c_ia.h" 62 | #include "prefixconf.h" 63 | #include "addrconf.h" 64 | 65 | TAILQ_HEAD(statefuladdr_list, statefuladdr); 66 | struct iactl_na { 67 | struct iactl common; 68 | struct statefuladdr_list statefuladdr_head; 69 | }; 70 | #define iacna_ia common.iactl_ia 71 | #define iacna_callback common.callback 72 | #define iacna_isvalid common.isvalid 73 | #define iacna_duration common.duration 74 | #define iacna_renew_data common.renew_data 75 | #define iacna_rebind_data common.rebind_data 76 | #define iacna_reestablish_data common.reestablish_data 77 | #define iacna_release_data common.release_data 78 | #define iacna_cleanup common.cleanup 79 | 80 | struct statefuladdr { 81 | TAILQ_ENTRY (statefuladdr) link; 82 | 83 | struct dhcp6_statefuladdr addr; 84 | time_t updatetime; 85 | struct dhcp6_timer *timer; 86 | struct iactl_na *ctl; 87 | struct dhcp6_if *dhcpif; 88 | }; 89 | 90 | static struct statefuladdr *find_addr(struct statefuladdr_list *, 91 | struct dhcp6_statefuladdr *); 92 | static int remove_addr(struct statefuladdr *); 93 | static int isvalid_addr(struct iactl *); 94 | static uint32_t duration_addr(struct iactl *); 95 | static void cleanup_addr(struct iactl *); 96 | static int renew_addr(struct iactl *, struct dhcp6_ia *, 97 | struct dhcp6_eventdata **, struct dhcp6_eventdata *); 98 | static void na_renew_data_free(struct dhcp6_eventdata *); 99 | 100 | static struct dhcp6_timer *addr_timo(void *); 101 | 102 | static int na_ifaddrconf(ifaddrconf_cmd_t, struct statefuladdr *); 103 | 104 | int 105 | update_address(struct ia *ia, struct dhcp6_statefuladdr *addr, 106 | struct dhcp6_if *dhcpifp, struct iactl **ctlp, 107 | void (*callback)(struct ia *)) 108 | { 109 | struct iactl_na *iac_na = (struct iactl_na *)*ctlp; 110 | struct statefuladdr *sa; 111 | int sacreate = 0; 112 | struct timeval timo; 113 | 114 | /* 115 | * A client discards any addresses for which the preferred 116 | * lifetime is greater than the valid lifetime. 117 | * [RFC3315 22.6] 118 | */ 119 | if (addr->vltime != DHCP6_DURATION_INFINITE && 120 | (addr->pltime == DHCP6_DURATION_INFINITE || 121 | addr->pltime > addr->vltime)) { 122 | d_printf(LOG_INFO, FNAME, "invalid address %s: " 123 | "pltime (%lu) is larger than vltime (%lu)", 124 | in6addr2str(&addr->addr, 0), 125 | addr->pltime, addr->vltime); 126 | return (-1); 127 | } 128 | 129 | if (iac_na == NULL) { 130 | if ((iac_na = malloc(sizeof(*iac_na))) == NULL) { 131 | d_printf(LOG_NOTICE, FNAME, "memory allocation failed"); 132 | return (-1); 133 | } 134 | memset(iac_na, 0, sizeof(*iac_na)); 135 | iac_na->iacna_ia = ia; 136 | iac_na->iacna_callback = callback; 137 | iac_na->iacna_isvalid = isvalid_addr; 138 | iac_na->iacna_duration = duration_addr; 139 | iac_na->iacna_cleanup = cleanup_addr; 140 | iac_na->iacna_renew_data = 141 | iac_na->iacna_rebind_data = 142 | iac_na->iacna_release_data = 143 | iac_na->iacna_reestablish_data = renew_addr; 144 | 145 | TAILQ_INIT(&iac_na->statefuladdr_head); 146 | *ctlp = (struct iactl *)iac_na; 147 | } 148 | 149 | /* search for the given address, and make a new one if it fails */ 150 | if ((sa = find_addr(&iac_na->statefuladdr_head, addr)) == NULL) { 151 | if ((sa = malloc(sizeof(*sa))) == NULL) { 152 | d_printf(LOG_NOTICE, FNAME, "memory allocation failed"); 153 | return (-1); 154 | } 155 | memset(sa, 0, sizeof(*sa)); 156 | sa->addr.addr = addr->addr; 157 | sa->ctl = iac_na; 158 | TAILQ_INSERT_TAIL(&iac_na->statefuladdr_head, sa, link); 159 | sacreate = 1; 160 | } 161 | 162 | /* update the timestamp of update */ 163 | sa->updatetime = time(NULL); 164 | 165 | /* update the prefix according to addr */ 166 | sa->addr.pltime = addr->pltime; 167 | sa->addr.vltime = addr->vltime; 168 | sa->dhcpif = dhcpifp; 169 | d_printf(LOG_DEBUG, FNAME, "%s an address %s pltime=%u, vltime=%u", 170 | sacreate ? "create" : "update", 171 | in6addr2str(&addr->addr, 0), (unsigned int)addr->pltime, 172 | (unsigned int)addr->vltime); 173 | 174 | if (sa->addr.vltime != 0) 175 | if (na_ifaddrconf(IFADDRCONF_ADD, sa) < 0) 176 | return (-1); 177 | 178 | /* 179 | * If the new vltime is 0, this address immediately expires. 180 | * Otherwise, set up or update the associated timer. 181 | */ 182 | switch (sa->addr.vltime) { 183 | case 0: 184 | if (remove_addr(sa) < 0) 185 | return (-1); 186 | break; 187 | case DHCP6_DURATION_INFINITE: 188 | if (sa->timer) 189 | dhcp6_remove_timer(&sa->timer); 190 | break; 191 | default: 192 | if (sa->timer == NULL) { 193 | sa->timer = dhcp6_add_timer(addr_timo, sa); 194 | if (sa->timer == NULL) { 195 | d_printf(LOG_NOTICE, FNAME, 196 | "failed to add stateful addr timer"); 197 | remove_addr(sa); /* XXX */ 198 | return (-1); 199 | } 200 | } 201 | /* update the timer */ 202 | timo.tv_sec = sa->addr.vltime; 203 | timo.tv_usec = 0; 204 | 205 | dhcp6_set_timer(&timo, sa->timer); 206 | break; 207 | } 208 | 209 | return (0); 210 | } 211 | 212 | static struct statefuladdr * 213 | find_addr(struct statefuladdr_list *head, struct dhcp6_statefuladdr *addr) 214 | { 215 | struct statefuladdr *sa; 216 | 217 | for (sa = TAILQ_FIRST(head); sa; sa = TAILQ_NEXT(sa, link)) { 218 | if (!IN6_ARE_ADDR_EQUAL(&sa->addr.addr, &addr->addr)) 219 | continue; 220 | return (sa); 221 | } 222 | 223 | return (NULL); 224 | } 225 | 226 | static int 227 | remove_addr(struct statefuladdr *sa) 228 | { 229 | int ret; 230 | 231 | d_printf(LOG_DEBUG, FNAME, "remove an address %s", 232 | in6addr2str(&sa->addr.addr, 0)); 233 | 234 | if (sa->timer) 235 | dhcp6_remove_timer(&sa->timer); 236 | 237 | TAILQ_REMOVE(&sa->ctl->statefuladdr_head, sa, link); 238 | ret = na_ifaddrconf(IFADDRCONF_REMOVE, sa); 239 | free(sa); 240 | 241 | return (ret); 242 | } 243 | 244 | static int 245 | isvalid_addr(struct iactl *iac) 246 | { 247 | struct iactl_na *iac_na = (struct iactl_na *)iac; 248 | 249 | if (TAILQ_EMPTY(&iac_na->statefuladdr_head)) 250 | return (0); /* this IA is invalid */ 251 | return (1); 252 | } 253 | 254 | static uint32_t 255 | duration_addr(struct iactl *iac) 256 | { 257 | struct iactl_na *iac_na = (struct iactl_na *)iac; 258 | struct statefuladdr *sa; 259 | uint32_t base = DHCP6_DURATION_INFINITE, pltime, passed; 260 | time_t now; 261 | 262 | /* Determine the smallest period until pltime expires. */ 263 | now = time(NULL); 264 | for (sa = TAILQ_FIRST(&iac_na->statefuladdr_head); sa; 265 | sa = TAILQ_NEXT(sa, link)) { 266 | passed = now > sa->updatetime ? 267 | (uint32_t)(now - sa->updatetime) : 0; 268 | pltime = sa->addr.pltime > passed ? 269 | sa->addr.pltime - passed : 0; 270 | 271 | if (base == DHCP6_DURATION_INFINITE || pltime < base) 272 | base = pltime; 273 | } 274 | 275 | return (base); 276 | } 277 | 278 | static void 279 | cleanup_addr(struct iactl *iac) 280 | { 281 | struct iactl_na *iac_na = (struct iactl_na *)iac; 282 | struct statefuladdr *sa; 283 | 284 | while ((sa = TAILQ_FIRST(&iac_na->statefuladdr_head)) != NULL) { 285 | TAILQ_REMOVE(&iac_na->statefuladdr_head, sa, link); 286 | remove_addr(sa); 287 | } 288 | 289 | free(iac); 290 | } 291 | 292 | static int 293 | renew_addr(struct iactl *iac, struct dhcp6_ia *iaparam, 294 | struct dhcp6_eventdata **evdp, struct dhcp6_eventdata *evd) 295 | { 296 | struct iactl_na *iac_na = (struct iactl_na *)iac; 297 | struct statefuladdr *sa; 298 | struct dhcp6_list *ial = NULL, pl; 299 | 300 | TAILQ_INIT(&pl); 301 | for (sa = TAILQ_FIRST(&iac_na->statefuladdr_head); sa; 302 | sa = TAILQ_NEXT(sa, link)) { 303 | if (dhcp6_add_listval(&pl, DHCP6_LISTVAL_STATEFULADDR6, 304 | &sa->addr, NULL) == NULL) 305 | goto fail; 306 | } 307 | 308 | if ((ial = malloc(sizeof(*ial))) == NULL) 309 | goto fail; 310 | TAILQ_INIT(ial); 311 | if (dhcp6_add_listval(ial, DHCP6_LISTVAL_IANA, iaparam, &pl) == NULL) 312 | goto fail; 313 | dhcp6_clear_list(&pl); 314 | 315 | evd->type = DHCP6_EVDATA_IANA; 316 | evd->data = (void *)ial; 317 | evd->privdata = (void *)evdp; 318 | evd->destructor = na_renew_data_free; 319 | 320 | return (0); 321 | 322 | fail: 323 | dhcp6_clear_list(&pl); 324 | if (ial) 325 | free(ial); 326 | return (-1); 327 | } 328 | 329 | static void 330 | na_renew_data_free(struct dhcp6_eventdata *evd) 331 | { 332 | struct dhcp6_list *ial; 333 | 334 | if (evd->type != DHCP6_EVDATA_IANA) { 335 | d_printf(LOG_ERR, FNAME, "assumption failure"); 336 | exit(1); 337 | } 338 | 339 | if (evd->privdata) 340 | *(struct dhcp6_eventdata **)evd->privdata = NULL; 341 | ial = (struct dhcp6_list *)evd->data; 342 | dhcp6_clear_list(ial); 343 | free(ial); 344 | } 345 | 346 | static struct dhcp6_timer * 347 | addr_timo(void *arg) 348 | { 349 | struct statefuladdr *sa = (struct statefuladdr *)arg; 350 | struct ia *ia; 351 | void (*callback)(struct ia *); 352 | 353 | d_printf(LOG_DEBUG, FNAME, "address timeout for %s", 354 | in6addr2str(&sa->addr.addr, 0)); 355 | 356 | ia = sa->ctl->iacna_ia; 357 | callback = sa->ctl->iacna_callback; 358 | 359 | if (sa->timer) 360 | dhcp6_remove_timer(&sa->timer); 361 | 362 | remove_addr(sa); 363 | 364 | (*callback)(ia); 365 | 366 | return (NULL); 367 | } 368 | 369 | static int 370 | na_ifaddrconf(ifaddrconf_cmd_t cmd, struct statefuladdr *sa) 371 | { 372 | struct dhcp6_statefuladdr *addr; 373 | struct sockaddr_in6 sin6; 374 | 375 | addr = &sa->addr; 376 | memset(&sin6, 0, sizeof(sin6)); 377 | sin6.sin6_family = AF_INET6; 378 | #ifdef HAVE_SA_LEN 379 | sin6.sin6_len = sizeof(sin6); 380 | #endif 381 | sin6.sin6_addr = addr->addr; 382 | 383 | return (ifaddrconf(cmd, sa->dhcpif->ifname, &sin6, 128, 384 | addr->pltime, addr->vltime)); 385 | } 386 | -------------------------------------------------------------------------------- /addrconf.h: -------------------------------------------------------------------------------- 1 | /* $KAME: addrconf.h,v 1.1 2005/03/02 07:20:13 suz Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2002 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | 32 | #ifndef _ADDRCONF_H_ 33 | #define _ADDRCONF_H_ 34 | 35 | typedef enum { ADDR6S_ACTIVE, ADDR6S_RENEW, ADDR6S_REBIND} addr6state_t; 36 | 37 | int update_address(struct ia *, struct dhcp6_statefuladdr *, 38 | struct dhcp6_if *, struct iactl **, void (*)(struct ia *)); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /auth.c: -------------------------------------------------------------------------------- 1 | /* $KAME: auth.c,v 1.4 2004/09/07 05:03:02 jinmei Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2004 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | 32 | /* 33 | * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") 34 | * Copyright (C) 2000, 2001 Internet Software Consortium. 35 | * 36 | * Permission to use, copy, modify, and distribute this software for any 37 | * purpose with or without fee is hereby granted, provided that the above 38 | * copyright notice and this permission notice appear in all copies. 39 | * 40 | * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 41 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 42 | * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 43 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 44 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 45 | * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 46 | * PERFORMANCE OF THIS SOFTWARE. 47 | */ 48 | #include 49 | #include 50 | #include 51 | #include 52 | #if TIME_WITH_SYS_TIME 53 | # include 54 | # include 55 | #else 56 | # if HAVE_SYS_TIME_H 57 | # include 58 | # else 59 | # include 60 | # endif 61 | #endif 62 | 63 | #include 64 | 65 | #include 66 | #include 67 | #include 68 | 69 | #include "dhcp6.h" 70 | #include "config.h" 71 | #include "common.h" 72 | #include "auth.h" 73 | 74 | #define PADLEN 64 75 | #define IPAD 0x36 76 | #define OPAD 0x5C 77 | 78 | #define HMACMD5_KEYLENGTH 64 79 | 80 | typedef struct { 81 | uint32_t buf[4]; 82 | uint32_t bytes[2]; 83 | uint32_t in[16]; 84 | } md5_t; 85 | 86 | typedef struct { 87 | md5_t md5ctx; 88 | unsigned char key[HMACMD5_KEYLENGTH]; 89 | } hmacmd5_t; 90 | 91 | static void hmacmd5_init(hmacmd5_t *, const unsigned char *, 92 | unsigned int); 93 | static void hmacmd5_invalidate(hmacmd5_t *); 94 | static void hmacmd5_update(hmacmd5_t *, const unsigned char *, 95 | unsigned int); 96 | static void hmacmd5_sign(hmacmd5_t *, unsigned char *); 97 | static int hmacmd5_verify(hmacmd5_t *, unsigned char *); 98 | 99 | static void md5_init(md5_t *); 100 | static void md5_invalidate(md5_t *); 101 | static void md5_final(md5_t *, unsigned char *); 102 | static void md5_update(md5_t *, const unsigned char *, unsigned int); 103 | 104 | int 105 | dhcp6_validate_key(struct keyinfo *key) 106 | { 107 | time_t now; 108 | 109 | if (key->expire == 0) /* never expire */ 110 | return (0); 111 | 112 | if (time(&now) == -1) 113 | return (-1); /* treat it as expiration (XXX) */ 114 | 115 | if (now > key->expire) 116 | return (-1); 117 | 118 | return (0); 119 | } 120 | 121 | int 122 | dhcp6_calc_mac(unsigned char *buf, size_t len, int proto __attribute__((__unused__)), int alg, 123 | size_t off, struct keyinfo *key) 124 | { 125 | hmacmd5_t ctx; 126 | unsigned char digest[MD5_DIGESTLENGTH]; 127 | 128 | /* right now, we don't care about the protocol */ 129 | 130 | if (alg != DHCP6_AUTHALG_HMACMD5) 131 | return (-1); 132 | 133 | if (off + MD5_DIGESTLENGTH > len) { 134 | /* 135 | * this should be assured by the caller, but check it here 136 | * for safety. 137 | */ 138 | return (-1); 139 | } 140 | 141 | hmacmd5_init(&ctx, key->secret, key->secretlen); 142 | hmacmd5_update(&ctx, buf, len); 143 | hmacmd5_sign(&ctx, digest); 144 | 145 | memcpy(buf + off, digest, MD5_DIGESTLENGTH); 146 | 147 | return (0); 148 | } 149 | 150 | int 151 | dhcp6_verify_mac(unsigned char *buf, ssize_t len, int proto __attribute__((__unused__)), 152 | int alg, size_t off, struct keyinfo *key) 153 | { 154 | hmacmd5_t ctx; 155 | unsigned char digest[MD5_DIGESTLENGTH]; 156 | int result; 157 | 158 | /* right now, we don't care about the protocol */ 159 | 160 | if (alg != DHCP6_AUTHALG_HMACMD5) 161 | return (-1); 162 | 163 | if (off + MD5_DIGESTLENGTH > (size_t)len) 164 | return (-1); 165 | 166 | /* 167 | * Copy the MAC value and clear the field. 168 | * XXX: should we make a local working copy? 169 | */ 170 | memcpy(digest, buf + off, sizeof(digest)); 171 | memset(buf + off, 0, sizeof(digest)); 172 | 173 | hmacmd5_init(&ctx, key->secret, key->secretlen); 174 | hmacmd5_update(&ctx, buf, len); 175 | result = hmacmd5_verify(&ctx, digest); 176 | 177 | /* copy back the digest value (XXX) */ 178 | memcpy(buf + off, digest, sizeof(digest)); 179 | 180 | return (result); 181 | } 182 | 183 | /* 184 | * This code implements the HMAC-MD5 keyed hash algorithm 185 | * described in RFC 2104. 186 | */ 187 | /* 188 | * Start HMAC-MD5 process. Initialize an md5 context and digest the key. 189 | */ 190 | static void 191 | hmacmd5_init(hmacmd5_t *ctx, const unsigned char *key, unsigned int len) 192 | { 193 | unsigned char ipad[PADLEN]; 194 | int i; 195 | 196 | memset(ctx->key, 0, sizeof(ctx->key)); 197 | if (len > sizeof(ctx->key)) { 198 | md5_t md5ctx; 199 | md5_init(&md5ctx); 200 | md5_update(&md5ctx, key, len); 201 | md5_final(&md5ctx, ctx->key); 202 | } else 203 | memcpy(ctx->key, key, len); 204 | 205 | md5_init(&ctx->md5ctx); 206 | memset(ipad, IPAD, sizeof(ipad)); 207 | for (i = 0; i < PADLEN; i++) 208 | ipad[i] ^= ctx->key[i]; 209 | md5_update(&ctx->md5ctx, ipad, sizeof(ipad)); 210 | } 211 | 212 | static void 213 | hmacmd5_invalidate(hmacmd5_t *ctx) 214 | { 215 | md5_invalidate(&ctx->md5ctx); 216 | memset(ctx->key, 0, sizeof(ctx->key)); 217 | memset(ctx, 0, sizeof(*ctx)); 218 | } 219 | 220 | /* 221 | * Update context to reflect the concatenation of another buffer full 222 | * of bytes. 223 | */ 224 | static void 225 | hmacmd5_update(hmacmd5_t *ctx, const unsigned char *buf, unsigned int len) 226 | { 227 | md5_update(&ctx->md5ctx, buf, len); 228 | } 229 | 230 | /* 231 | * Compute signature - finalize MD5 operation and reapply MD5. 232 | */ 233 | static void 234 | hmacmd5_sign(hmacmd5_t *ctx, unsigned char *digest) 235 | { 236 | unsigned char opad[PADLEN]; 237 | int i; 238 | 239 | md5_final(&ctx->md5ctx, digest); 240 | 241 | memset(opad, OPAD, sizeof(opad)); 242 | for (i = 0; i < PADLEN; i++) 243 | opad[i] ^= ctx->key[i]; 244 | 245 | md5_init(&ctx->md5ctx); 246 | md5_update(&ctx->md5ctx, opad, sizeof(opad)); 247 | md5_update(&ctx->md5ctx, digest, MD5_DIGESTLENGTH); 248 | md5_final(&ctx->md5ctx, digest); 249 | hmacmd5_invalidate(ctx); 250 | } 251 | 252 | /* 253 | * Verify signature - finalize MD5 operation and reapply MD5, then 254 | * compare to the supplied digest. 255 | */ 256 | static int 257 | hmacmd5_verify(hmacmd5_t *ctx, unsigned char *digest) { 258 | unsigned char newdigest[MD5_DIGESTLENGTH]; 259 | 260 | hmacmd5_sign(ctx, newdigest); 261 | return (memcmp(digest, newdigest, MD5_DIGESTLENGTH)); 262 | } 263 | 264 | /* 265 | * This code implements the MD5 message-digest algorithm. 266 | * The algorithm is due to Ron Rivest. This code was 267 | * written by Colin Plumb in 1993, no copyright is claimed. 268 | * This code is in the public domain; do with it what you wish. 269 | * 270 | * Equivalent code is available from RSA Data Security, Inc. 271 | * This code has been tested against that, and is equivalent, 272 | * except that you don't need to include two pages of legalese 273 | * with every copy. 274 | * 275 | * To compute the message digest of a chunk of bytes, declare an 276 | * MD5Context structure, pass it to MD5Init, call MD5Update as 277 | * needed on buffers full of bytes, and then call MD5Final, which 278 | * will fill a supplied 16-byte array with the digest. 279 | */ 280 | 281 | static void 282 | byteSwap(uint32_t *buf, unsigned words) 283 | { 284 | unsigned char *p = (unsigned char *)buf; 285 | 286 | do { 287 | *buf++ = (uint32_t)((unsigned)p[3] << 8 | p[2]) << 16 | 288 | ((unsigned)p[1] << 8 | p[0]); 289 | p += 4; 290 | } while (--words); 291 | } 292 | 293 | /* 294 | * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 295 | * initialization constants. 296 | */ 297 | static void 298 | md5_init(md5_t *ctx) 299 | { 300 | ctx->buf[0] = 0x67452301; 301 | ctx->buf[1] = 0xefcdab89; 302 | ctx->buf[2] = 0x98badcfe; 303 | ctx->buf[3] = 0x10325476; 304 | 305 | ctx->bytes[0] = 0; 306 | ctx->bytes[1] = 0; 307 | } 308 | 309 | static void 310 | md5_invalidate(md5_t *ctx) 311 | { 312 | memset(ctx, 0, sizeof(md5_t)); 313 | } 314 | 315 | /* The four core functions - F1 is optimized somewhat */ 316 | 317 | /* #define F1(x, y, z) (x & y | ~x & z) */ 318 | #define F1(x, y, z) (z ^ (x & (y ^ z))) 319 | #define F2(x, y, z) F1(z, x, y) 320 | #define F3(x, y, z) (x ^ y ^ z) 321 | #define F4(x, y, z) (y ^ (x | ~z)) 322 | 323 | /* This is the central step in the MD5 algorithm. */ 324 | #define MD5STEP(f,w,x,y,z,in,s) \ 325 | (w += f(x,y,z) + in, w = (w<>(32-s)) + x) 326 | 327 | /* 328 | * The core of the MD5 algorithm, this alters an existing MD5 hash to 329 | * reflect the addition of 16 longwords of new data. MD5Update blocks 330 | * the data and converts bytes into longwords for this routine. 331 | */ 332 | static void 333 | transform(uint32_t buf[4], uint32_t const in[16]) { 334 | register uint32_t a, b, c, d; 335 | 336 | a = buf[0]; 337 | b = buf[1]; 338 | c = buf[2]; 339 | d = buf[3]; 340 | 341 | MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); 342 | MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); 343 | MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); 344 | MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); 345 | MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); 346 | MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); 347 | MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); 348 | MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); 349 | MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); 350 | MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); 351 | MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 352 | MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 353 | MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 354 | MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 355 | MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 356 | MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 357 | 358 | MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); 359 | MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); 360 | MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 361 | MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); 362 | MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); 363 | MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 364 | MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 365 | MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); 366 | MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); 367 | MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 368 | MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); 369 | MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); 370 | MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 371 | MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); 372 | MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); 373 | MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 374 | 375 | MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); 376 | MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); 377 | MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 378 | MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 379 | MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); 380 | MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); 381 | MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); 382 | MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 383 | MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 384 | MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); 385 | MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); 386 | MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); 387 | MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); 388 | MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 389 | MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 390 | MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); 391 | 392 | MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); 393 | MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); 394 | MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 395 | MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); 396 | MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 397 | MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); 398 | MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 399 | MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); 400 | MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); 401 | MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 402 | MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); 403 | MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 404 | MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); 405 | MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 406 | MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); 407 | MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); 408 | 409 | buf[0] += a; 410 | buf[1] += b; 411 | buf[2] += c; 412 | buf[3] += d; 413 | } 414 | 415 | /* 416 | * Update context to reflect the concatenation of another buffer full 417 | * of bytes. 418 | */ 419 | static void 420 | md5_update(md5_t *ctx, const unsigned char *buf, unsigned int len) 421 | { 422 | uint32_t t; 423 | 424 | /* Update byte count */ 425 | 426 | t = ctx->bytes[0]; 427 | if ((ctx->bytes[0] = t + len) < t) 428 | ctx->bytes[1]++; /* Carry from low to high */ 429 | 430 | t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ 431 | if (t > len) { 432 | memcpy((unsigned char *)ctx->in + 64 - t, buf, len); 433 | return; 434 | } 435 | /* First chunk is an odd size */ 436 | memcpy((unsigned char *)ctx->in + 64 - t, buf, t); 437 | byteSwap(ctx->in, 16); 438 | transform(ctx->buf, ctx->in); 439 | buf += t; 440 | len -= t; 441 | 442 | /* Process data in 64-byte chunks */ 443 | while (len >= 64) { 444 | memcpy(ctx->in, buf, 64); 445 | byteSwap(ctx->in, 16); 446 | transform(ctx->buf, ctx->in); 447 | buf += 64; 448 | len -= 64; 449 | } 450 | 451 | /* Handle any remaining bytes of data. */ 452 | memcpy(ctx->in, buf, len); 453 | } 454 | 455 | /* 456 | * Final wrapup - pad to 64-byte boundary with the bit pattern 457 | * 1 0* (64-bit count of bits processed, MSB-first) 458 | */ 459 | static void 460 | md5_final(md5_t *ctx, unsigned char *digest) 461 | { 462 | int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ 463 | unsigned char *p = (unsigned char *)ctx->in + count; 464 | 465 | /* Set the first char of padding to 0x80. There is always room. */ 466 | *p++ = 0x80; 467 | 468 | /* Bytes of padding needed to make 56 bytes (-8..55) */ 469 | count = 56 - 1 - count; 470 | 471 | if (count < 0) { /* Padding forces an extra block */ 472 | memset(p, 0, count + 8); 473 | byteSwap(ctx->in, 16); 474 | transform(ctx->buf, ctx->in); 475 | p = (unsigned char *)ctx->in; 476 | count = 56; 477 | } 478 | memset(p, 0, count); 479 | byteSwap(ctx->in, 14); 480 | 481 | /* Append length in bits and transform */ 482 | ctx->in[14] = ctx->bytes[0] << 3; 483 | ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; 484 | transform(ctx->buf, ctx->in); 485 | 486 | byteSwap(ctx->buf, 4); 487 | memcpy(digest, ctx->buf, 16); 488 | memset(ctx, 0, sizeof(md5_t)); /* In case it's sensitive */ 489 | } 490 | -------------------------------------------------------------------------------- /auth.h: -------------------------------------------------------------------------------- 1 | /* $KAME: auth.h,v 1.3 2004/09/07 05:03:02 jinmei Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2004 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | #ifndef _AUTH_H_ 32 | #define _AUTH_H_ 33 | 34 | #define MD5_DIGESTLENGTH 16 35 | 36 | /* secret key information for delayed authentication */ 37 | struct keyinfo { 38 | struct keyinfo *next; 39 | 40 | char *name; /* key name */ 41 | 42 | char *realm; /* DHCP realm */ 43 | size_t realmlen; /* length of realm */ 44 | u_int32_t keyid; /* key ID */ 45 | unsigned char *secret; /* binary key */ 46 | size_t secretlen; /* length of the key */ 47 | time_t expire; /* expiration time (0 means forever) */ 48 | }; 49 | 50 | int dhcp6_validate_key(struct keyinfo *); 51 | int dhcp6_calc_mac(unsigned char *, size_t, int, int, size_t, 52 | struct keyinfo *); 53 | int dhcp6_verify_mac(unsigned char *, ssize_t, int, int, size_t, 54 | struct keyinfo *); 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /base64.c: -------------------------------------------------------------------------------- 1 | /* $KAME: base64.c,v 1.1 2004/06/08 07:26:56 jinmei Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2004 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | 32 | /* 33 | * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") 34 | * Copyright (C) 1998-2001, 2003 Internet Software Consortium. 35 | * 36 | * Permission to use, copy, modify, and distribute this software for any 37 | * purpose with or without fee is hereby granted, provided that the above 38 | * copyright notice and this permission notice appear in all copies. 39 | * 40 | * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 41 | * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 42 | * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 43 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 44 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 45 | * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 46 | * PERFORMANCE OF THIS SOFTWARE. 47 | */ 48 | 49 | #include 50 | 51 | typedef enum { FALSE = 0, TRUE = 1 } boolean_t; 52 | 53 | static const char base64[] = 54 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 55 | 56 | /* 57 | * State of a base64 decoding process in progress. 58 | */ 59 | typedef struct { 60 | int length; /* Desired length of binary data or -1 */ 61 | int digits; /* Number of buffered base64 digits */ 62 | boolean_t seen_end; /* True if "=" end marker seen */ 63 | int val[4]; 64 | 65 | char *dst; /* Head of the available space for resulting 66 | * binary data */ 67 | char *dstend; /* End of the buffer */ 68 | } base64_decode_ctx_t; 69 | 70 | int base64_decodestring(const char *, char *, size_t); 71 | 72 | static int 73 | mem_tobuffer(base64_decode_ctx_t *ctx, void *base, unsigned int length) 74 | { 75 | if (ctx->dst + length >= ctx->dstend) 76 | return (-1); 77 | memcpy(ctx->dst, base, length); 78 | ctx->dst += length; 79 | return (0); 80 | } 81 | 82 | static inline void 83 | base64_decode_init(base64_decode_ctx_t *ctx, int length, 84 | char *result, size_t resultlen) 85 | { 86 | ctx->digits = 0; 87 | ctx->seen_end = FALSE; 88 | ctx->length = length; 89 | ctx->dst = result; 90 | ctx->dstend = result + resultlen; 91 | } 92 | 93 | static inline int 94 | base64_decode_char(base64_decode_ctx_t *ctx, int c) 95 | { 96 | char *s; 97 | 98 | if (ctx->seen_end == TRUE) 99 | return (-1); 100 | if ((s = strchr(base64, c)) == NULL) 101 | return (-1); 102 | ctx->val[ctx->digits++] = s - base64; 103 | if (ctx->digits == 4) { 104 | int n; 105 | unsigned char buf[3]; 106 | if (ctx->val[0] == 64 || ctx->val[1] == 64) 107 | return (-1); 108 | if (ctx->val[2] == 64 && ctx->val[3] != 64) 109 | return (-1); 110 | /* 111 | * Check that bits that should be zero are. 112 | */ 113 | if (ctx->val[2] == 64 && (ctx->val[1] & 0xf) != 0) 114 | return (-1); 115 | /* 116 | * We don't need to test for ctx->val[2] != 64 as 117 | * the bottom two bits of 64 are zero. 118 | */ 119 | if (ctx->val[3] == 64 && (ctx->val[2] & 0x3) != 0) 120 | return (-1); 121 | n = (ctx->val[2] == 64) ? 1 : 122 | (ctx->val[3] == 64) ? 2 : 3; 123 | if (n != 3) { 124 | ctx->seen_end = TRUE; 125 | if (ctx->val[2] == 64) 126 | ctx->val[2] = 0; 127 | if (ctx->val[3] == 64) 128 | ctx->val[3] = 0; 129 | } 130 | buf[0] = (ctx->val[0]<<2)|(ctx->val[1]>>4); 131 | buf[1] = (ctx->val[1]<<4)|(ctx->val[2]>>2); 132 | buf[2] = (ctx->val[2]<<6)|(ctx->val[3]); 133 | if (mem_tobuffer(ctx, buf, n)) 134 | return (-1); 135 | if (ctx->length >= 0) { 136 | if (n > ctx->length) 137 | return (-1); 138 | else 139 | ctx->length -= n; 140 | } 141 | ctx->digits = 0; 142 | } 143 | return (0); 144 | } 145 | 146 | static inline int 147 | base64_decode_finish(base64_decode_ctx_t *ctx) 148 | { 149 | if (ctx->length > 0) 150 | return (-1); 151 | if (ctx->digits != 0) 152 | return (-1); 153 | return (0); 154 | } 155 | 156 | int 157 | base64_decodestring(const char *cstr, char *result, size_t resultlen) 158 | { 159 | base64_decode_ctx_t ctx; 160 | 161 | base64_decode_init(&ctx, -1, result, resultlen); 162 | for (;;) { 163 | int c = *cstr++; 164 | if (c == '\0') 165 | break; 166 | if (c == ' ' || c == '\t' || c == '\n' || c== '\r') 167 | continue; 168 | if (base64_decode_char(&ctx, c)) 169 | return (-1); 170 | } 171 | if (base64_decode_finish(&ctx)) 172 | return (-1); 173 | return (ctx.dst - result); 174 | } 175 | -------------------------------------------------------------------------------- /base64.h: -------------------------------------------------------------------------------- 1 | /* $KAME: base64.h,v 1.1 2004/06/17 12:25:18 jinmei Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2004 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | 32 | #ifndef _BASE64_H_ 33 | #define _BASE64_H_ 34 | 35 | int base64_decodestring(const char *, char *, size_t); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /cftoken.l: -------------------------------------------------------------------------------- 1 | /* $KAME: cftoken.l,v 1.35 2005/01/12 06:06:11 suz Exp $ */ 2 | 3 | %option noyywrap 4 | %option noinput 5 | %{ 6 | /* 7 | * Copyright (C) 2002 WIDE Project. 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 1. Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * 2. Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 3. Neither the name of the project nor the names of its contributors 19 | * may be used to endorse or promote products derived from this software 20 | * without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 23 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 26 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 | * SUCH DAMAGE. 33 | */ 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #ifdef HAVE_STDARG_H 46 | #include 47 | #else 48 | #include 49 | #endif 50 | 51 | #include "dhcp6.h" 52 | #include "config.h" 53 | #include "common.h" 54 | #include "y.tab.h" 55 | 56 | #define YY_NO_UNPUT 1 57 | 58 | extern char *configfilename; 59 | extern int lineno; 60 | extern void cf_init(void); 61 | 62 | char *configfilename; 63 | int lineno = 1; 64 | 65 | 66 | /* Recursion limit for includes */ 67 | #define MAX_INCLUDE_DEPTH 10 68 | 69 | static struct include_stack { 70 | char *path; 71 | YY_BUFFER_STATE state; 72 | int lineno; 73 | } incstack[MAX_INCLUDE_DEPTH]; 74 | static int incstackp = 0; 75 | 76 | 77 | static int yy_first_time = 1; 78 | static int yyerrorcount = 0; 79 | 80 | #ifndef NOCONFIG_DEBUG 81 | #ifndef YYDEBUG 82 | #define YYDEBUG 1 83 | #endif 84 | static int cfdebug = 1; 85 | #else 86 | static int cfdebug = 0; 87 | #endif 88 | 89 | extern int yyparse(void); 90 | extern int cf_post_config(void); 91 | 92 | static void cfdebug_print(const char *, const char *, int); 93 | void yyerror(const char *, ...); 94 | void yywarn(char *, ...); 95 | int cfswitch_buffer(char *); 96 | 97 | #define DP(str) if (cfdebug) cfdebug_print(str, yytext, yyleng) 98 | #define DECHO if (cfdebug) cfdebug_print(NULL, yytext, yyleng); 99 | #define DNOECHO if (cfdebug) cfdebug_print(NULL, "****", yyleng); 100 | %} 101 | 102 | /* abbreviations */ 103 | nl \n 104 | ws [ \t]+ 105 | comma , 106 | comment \#.* 107 | semi \; 108 | quotedstring \"[^\"]*\" 109 | string [a-zA-Z0-9:\._\-][a-zA-Z0-9:\._\-]* 110 | digit [0-9] 111 | integer {digit}+ 112 | number {integer}|({digit}*\.{integer}) 113 | hexdigit [0-9A-Fa-f] 114 | hexpair {hexdigit}{hexdigit} 115 | hexstring 0[xX]{hexpair}+ 116 | /* XXX */ 117 | hexdata {hexpair}(:{hexpair})* 118 | ifname {string} 119 | slash \/ 120 | bcl \{ 121 | ecl \} 122 | 123 | 124 | %s S_CNF 125 | %s S_IFACE 126 | %s S_PREF 127 | %s S_HOST 128 | %s S_DUID 129 | %s S_IA 130 | %s S_AUTH 131 | %s S_KEY 132 | %s S_SECRET 133 | %s S_ADDRPOOL 134 | %s S_INCL 135 | %s S_RAW 136 | 137 | %% 138 | %{ 139 | if (yy_first_time) { 140 | BEGIN S_CNF; 141 | yy_first_time = 0; 142 | } 143 | %} 144 | /* interface configuration */ 145 | interface { DECHO; BEGIN S_IFACE; return (INTERFACE); } 146 | {ifname} { 147 | DECHO; 148 | yylval.str = strdup(yytext); 149 | BEGIN S_CNF; 150 | return (IFNAME); 151 | } 152 | 153 | /* host configuration */ 154 | host { DECHO; BEGIN S_HOST; return (HOST); } 155 | {string} { 156 | DECHO; 157 | yylval.str = strdup(yytext); 158 | BEGIN S_CNF; 159 | return (HOSTNAME); 160 | } 161 | 162 | /* address pool configuration */ 163 | pool { DECHO; BEGIN S_ADDRPOOL; return (ADDRPOOL); } 164 | 165 | {string} { 166 | DECHO; 167 | yylval.str = strdup(yytext); 168 | BEGIN S_CNF; 169 | return (POOLNAME); 170 | } 171 | 172 | duid { DECHO; BEGIN S_DUID; return (DUID); } 173 | {hexdata} { 174 | DECHO; 175 | yylval.str = strdup(yytext); 176 | BEGIN S_CNF; 177 | return (DUID_ID); 178 | } 179 | 180 | address { DECHO; return (ADDRESS); } 181 | 182 | prefix { DECHO; return (PREFIX); } 183 | 184 | preference { DECHO; return (PREFERENCE); } 185 | 186 | script { DECHO; return (SCRIPT); } 187 | 188 | delayedkey { DECHO; return (DELAYEDKEY); } 189 | 190 | /* request */ 191 | request { DECHO; return (REQUEST); } 192 | 193 | /* send */ 194 | send { DECHO; return (SEND); } 195 | 196 | /* range */ 197 | range { DECHO; return (RANGE); } 198 | to { DECHO; return (TO); } 199 | 200 | /* address-pool */ 201 | address-pool { DECHO; return (ADDRESS_POOL); } 202 | 203 | /* DHCP options */ 204 | option { DECHO; return (OPTION); } 205 | 206 | rapid-commit { DECHO; return (RAPID_COMMIT); } 207 | ia-pd { DECHO; return (IA_PD); } 208 | ia-na { DECHO; return (IA_NA); } 209 | domain-name-servers { DECHO; return (DNS_SERVERS); } 210 | domain-name { DECHO; return (DNS_NAME); } 211 | sip-server-address { DECHO; return (SIP_SERVERS); } 212 | sip-server-domain-name { DECHO; return (SIP_NAME); } 213 | ntp-servers { DECHO; return (NTP_SERVERS); } 214 | nis-server-address { DECHO; return (NIS_SERVERS); } 215 | nis-domain-name { DECHO; return (NIS_NAME); } 216 | nisp-server-address { DECHO; return (NISP_SERVERS); } 217 | nisp-domain-name { DECHO; return (NISP_NAME); } 218 | bcmcs-server-address { DECHO; return (BCMCS_SERVERS); } 219 | bcmcs-server-domain-name { DECHO; return (BCMCS_NAME); } 220 | refreshtime { DECHO; return (REFRESHTIME); } 221 | raw-option { DECHO; BEGIN S_RAW; return (RAW); } 222 | {integer} { 223 | DECHO; 224 | yylval.num = strtoull(yytext, NULL, 10); 225 | return (NUMBER); 226 | } 227 | {hexdata} { 228 | DECHO; 229 | yylval.str = strdup(yytext); 230 | BEGIN S_CNF; 231 | return (STRING); 232 | } 233 | 234 | /* provided for a backward compatibility to WIDE-DHCPv6 before Oct 1 2006 */ 235 | nis-server-domain-name { DECHO; return (NIS_NAME); } 236 | nisp-server-domain-name { DECHO; return (NISP_NAME); } 237 | 238 | /* generic options */ 239 | information-only { DECHO; return (INFO_ONLY); } 240 | 241 | allow { DECHO; return (ALLOW); } 242 | 243 | /* identity association */ 244 | id-assoc { DECHO; BEGIN S_IA; return(ID_ASSOC); } 245 | pd { DECHO; return(IA_PD); } 246 | na { DECHO; return(IA_NA); } 247 | {number} { DECHO; yylval.str = strdup(yytext); return(IAID); } 248 | {bcl} { DP("begin of closure"); BEGIN S_CNF; return (BCL); } 249 | 250 | /* 251 | * interface parameters for delegated prefix configuration. 252 | * when lex reads an interface name, the state will be back to 253 | * S_CNF. 254 | */ 255 | prefix-interface { DECHO; BEGIN S_IFACE; return (PREFIX_INTERFACE); } 256 | sla-id { DECHO; return (SLA_ID); } 257 | sla-len { DECHO; return (SLA_LEN); } 258 | ifid { DECHO; return (IFID); } 259 | random { DECHO; return (RANDOM); } 260 | eui-64 { DECHO; return (EUI64); } 261 | 262 | /* duration */ 263 | infinity { DECHO; return (INFINITY); } 264 | 265 | /* authentication option */ 266 | authentication { DECHO; BEGIN S_AUTH; return (AUTHENTICATION); } 267 | {string} { 268 | DECHO; 269 | yylval.str = strdup(yytext); 270 | BEGIN S_CNF; 271 | return (AUTHNAME); 272 | } 273 | 274 | /* authentication parameters */ 275 | protocol { DECHO; return (PROTOCOL); }; 276 | algorithm { DECHO; return (ALGORITHM); }; 277 | rdm { DECHO; return (RDM); }; 278 | key { DECHO; return (KEY); }; 279 | 280 | /* authentication protocols */ 281 | delayed { DECHO; return (DELAYED); }; 282 | reconfig { DECHO; return (RECONFIG); }; 283 | 284 | /* authentication algorithms */ 285 | hmac-md5 { DECHO; return (HMACMD5); }; 286 | HMAC-MD5 { DECHO; return (HMACMD5); }; 287 | hmacmd5 { DECHO; return (HMACMD5); }; 288 | HMACMD5 { DECHO; return (HMACMD5); }; 289 | 290 | /* authentication RDM */ 291 | monocounter { DECHO; return (MONOCOUNTER); }; 292 | 293 | /* secret keys */ 294 | keyinfo { DECHO; BEGIN S_KEY; return (KEYINFO); } 295 | {string} { 296 | DECHO; 297 | yylval.str = strdup(yytext); 298 | BEGIN S_CNF; 299 | return (KEYNAME); 300 | } 301 | 302 | /* key parameters */ 303 | realm { DECHO; return (REALM); } 304 | keyid { DECHO; return (KEYID); } 305 | secret { DECHO; BEGIN S_SECRET; return (SECRET); } 306 | {quotedstring} { 307 | DNOECHO; 308 | yylval.str = strdup(yytext); 309 | BEGIN S_CNF; 310 | return (QSTRING); 311 | } 312 | expire { DECHO; return (EXPIRE); } 313 | 314 | /* include */ 315 | include { DECHO; BEGIN S_INCL; return (INCLUDE); } 316 | {quotedstring} { 317 | DECHO; 318 | yylval.str = strdup(yytext); 319 | BEGIN S_CNF; 320 | return (QSTRING); 321 | } 322 | 323 | /* quoted string */ 324 | {quotedstring} { 325 | DECHO; 326 | yylval.str = strdup(yytext); 327 | return (QSTRING); 328 | } 329 | 330 | /* misc */ 331 | {ws} { ; } 332 | {nl} { lineno++; } 333 | {comment} { DP("comment"); } 334 | {number} { 335 | DECHO; 336 | yylval.num = strtoull(yytext, NULL, 10); 337 | return (NUMBER); 338 | } 339 | {slash} { DECHO; return (SLASH); } 340 | {comma} { DECHO; return (COMMA); } 341 | {semi} { DP("end of sentence"); return (EOS); } 342 | {bcl} { DP("begin of closure"); return (BCL); } 343 | {ecl} { DP("end of closure"); return (ECL); } 344 | 345 | /* generic string */ 346 | {string} { 347 | DECHO; 348 | yylval.str = strdup(yytext); 349 | return (STRING); 350 | } 351 | 352 | <> { 353 | if (--incstackp < 0) 354 | yyterminate(); 355 | else { 356 | yy_delete_buffer(YY_CURRENT_BUFFER); 357 | free(incstack[incstackp + 1].path); 358 | configfilename = incstack[incstackp].path; 359 | lineno = incstack[incstackp].lineno; 360 | yy_switch_to_buffer(incstack[incstackp].state); 361 | } 362 | } 363 | 364 | %% 365 | static void 366 | cfdebug_print(const char *w, const char *t, int l) 367 | { 368 | if (w) { 369 | d_printf(LOG_DEBUG, FNAME, 370 | "<%d>%s [%s] (%d)", yy_start, w, t, l); 371 | } else { 372 | d_printf(LOG_DEBUG, FNAME, 373 | "<%d>[%s] (%d)", yy_start, t, l); 374 | } 375 | } 376 | 377 | static void 378 | yyerror0(int level, const char *s, va_list ap) 379 | { 380 | char ebuf[BUFSIZ], *bp, *ep; 381 | 382 | bp = ebuf; 383 | ep = ebuf + sizeof(ebuf); 384 | bp += snprintf(bp, ep - bp, "%s %d: ", configfilename, lineno); 385 | if (bp < ep) 386 | bp += vsnprintf(bp, ep - bp, s, ap); 387 | 388 | d_printf(level, FNAME, ebuf); 389 | } 390 | 391 | void 392 | yyerror(const char *s, ...) 393 | { 394 | va_list ap; 395 | #ifdef HAVE_STDARG_H 396 | va_start(ap, s); 397 | #else 398 | va_start(ap); 399 | #endif 400 | yyerror0(LOG_ERR, s, ap); 401 | va_end(ap); 402 | yyerrorcount++; 403 | } 404 | 405 | void 406 | yywarn(char *s, ...) 407 | { 408 | va_list ap; 409 | #ifdef HAVE_STDARG_H 410 | va_start(ap, s); 411 | #else 412 | va_start(ap); 413 | #endif 414 | yyerror0(LOG_WARNING, s, ap); 415 | va_end(ap); 416 | } 417 | 418 | int 419 | cfswitch_buffer(char *incl) 420 | { 421 | char *path = qstrdup(incl); 422 | FILE *fp; 423 | 424 | if (incstackp >= MAX_INCLUDE_DEPTH) { 425 | d_printf(LOG_ERR, FNAME, "cfparse: includes nested too deeply"); 426 | return (-1); 427 | } 428 | incstack[incstackp].path = configfilename; 429 | incstack[incstackp].state = YY_CURRENT_BUFFER; 430 | incstack[incstackp].lineno = lineno; 431 | 432 | fp = fopen(path, "r"); 433 | if (fp == NULL) { 434 | d_printf(LOG_ERR, FNAME, "cfparse: fopen(%s): %s", 435 | path, strerror(errno)); 436 | if (errno == ENOENT) 437 | return (0); 438 | return (-1); 439 | } 440 | incstackp++; 441 | configfilename = path; 442 | lineno = 1; 443 | yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE)); 444 | 445 | BEGIN(S_CNF); 446 | 447 | return (0); 448 | } 449 | 450 | int 451 | cfparse(const char *conf) 452 | { 453 | 454 | free(configfilename); 455 | configfilename = strdup(conf); 456 | 457 | lineno = 1; 458 | cf_init(); 459 | if ((yyin = fopen(configfilename, "r")) == NULL) { 460 | d_printf(LOG_ERR, FNAME, "cfparse: fopen(%s): %s", 461 | configfilename, strerror(errno)); 462 | if (errno == ENOENT) 463 | return (0); 464 | return (-1); 465 | } 466 | 467 | if (yyparse() || yyerrorcount) { 468 | if (yyerrorcount) { 469 | yyerror("fatal parse failure: exiting (%d errors)", 470 | yyerrorcount); 471 | } else 472 | yyerror("fatal parse failure: exiting"); 473 | return (-1); 474 | } 475 | 476 | return (cf_post_config()); 477 | } 478 | -------------------------------------------------------------------------------- /common.h: -------------------------------------------------------------------------------- 1 | /* $KAME: common.h,v 1.42 2005/09/16 11:30:13 suz Exp $ */ 2 | /* 3 | * Copyright (C) 1998 and 1999 WIDE Project. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. Neither the name of the project nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software 16 | * without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 | * SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef _COMMON_H_ 32 | #define _COMMON_H_ 33 | 34 | #ifdef __KAME__ 35 | #define IN6_IFF_INVALID (IN6_IFF_ANYCAST|IN6_IFF_TENTATIVE|\ 36 | IN6_IFF_DUPLICATED|IN6_IFF_DETACHED) 37 | #else 38 | #define IN6_IFF_INVALID (0) 39 | #endif 40 | 41 | #ifdef HAVE_ANSI_FUNC 42 | #define FNAME __func__ 43 | #elif defined (HAVE_GCC_FUNCTION) 44 | #define FNAME __FUNCTION__ 45 | #else 46 | #define FNAME "" 47 | #endif 48 | 49 | /* XXX: bsdi4 does not have TAILQ_EMPTY */ 50 | #ifndef TAILQ_EMPTY 51 | #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) 52 | #endif 53 | 54 | /* and linux *_FIRST and *_NEXT */ 55 | #ifndef LIST_EMPTY 56 | #define LIST_EMPTY(head) ((head)->lh_first == NULL) 57 | #endif 58 | #ifndef LIST_FIRST 59 | #define LIST_FIRST(head) ((head)->lh_first) 60 | #endif 61 | #ifndef LIST_NEXT 62 | #define LIST_NEXT(elm, field) ((elm)->field.le_next) 63 | #endif 64 | #ifndef LIST_FOREACH 65 | #define LIST_FOREACH(var, head, field) \ 66 | for ((var) = LIST_FIRST((head)); \ 67 | (var); \ 68 | (var) = LIST_NEXT((var), field)) 69 | #endif 70 | #ifndef TAILQ_FIRST 71 | #define TAILQ_FIRST(head) ((head)->tqh_first) 72 | #endif 73 | #ifndef TAILQ_LAST 74 | #define TAILQ_LAST(head, headname) \ 75 | (*(((struct headname *)((head)->tqh_last))->tqh_last)) 76 | #endif 77 | #ifndef TAILQ_PREV 78 | #define TAILQ_PREV(elm, headname, field) \ 79 | (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) 80 | #endif 81 | #ifndef TAILQ_NEXT 82 | #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) 83 | #endif 84 | #ifndef TAILQ_FOREACH 85 | #define TAILQ_FOREACH(var, head, field) \ 86 | for ((var) = TAILQ_FIRST((head)); \ 87 | (var); \ 88 | (var) = TAILQ_NEXT((var), field)) 89 | #endif 90 | #ifdef HAVE_TAILQ_FOREACH_REVERSE_OLD 91 | #undef TAILQ_FOREACH_REVERSE 92 | #endif 93 | #ifndef TAILQ_FOREACH_REVERSE 94 | #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ 95 | for ((var) = TAILQ_LAST((head), headname); \ 96 | (var); \ 97 | (var) = TAILQ_PREV((var), headname, field)) 98 | #endif 99 | 100 | 101 | #ifndef SO_REUSEPORT 102 | #define SO_REUSEPORT SO_REUSEADDR 103 | #endif 104 | 105 | /* s*_len stuff */ 106 | static __inline uint8_t 107 | sysdep_sa_len (const struct sockaddr *sa) 108 | { 109 | #ifndef HAVE_SA_LEN 110 | switch (sa->sa_family) 111 | { 112 | case AF_INET: 113 | return sizeof (struct sockaddr_in); 114 | case AF_INET6: 115 | return sizeof (struct sockaddr_in6); 116 | } 117 | return sizeof (struct sockaddr_in); 118 | #else 119 | return sa->sa_len; 120 | #endif 121 | } 122 | 123 | extern int foreground; 124 | extern int debug_thresh; 125 | extern char *device; 126 | extern int opt_norelease; 127 | 128 | /* search option for dhcp6_find_listval() */ 129 | #define MATCHLIST_PREFIXLEN 0x1 130 | 131 | /* common.c */ 132 | typedef enum { IFADDRCONF_ADD, IFADDRCONF_REMOVE } ifaddrconf_cmd_t; 133 | int rawop_copy_list(struct rawop_list *, struct rawop_list *); 134 | void rawop_clear_list(struct rawop_list *); 135 | int dhcp6_copy_list(struct dhcp6_list *, struct dhcp6_list *); 136 | void dhcp6_move_list(struct dhcp6_list *, struct dhcp6_list *); 137 | void dhcp6_clear_list(struct dhcp6_list *); 138 | void dhcp6_clear_listval(struct dhcp6_listval *); 139 | struct dhcp6_listval *dhcp6_find_listval(struct dhcp6_list *, 140 | dhcp6_listval_type_t, void *, int); 141 | struct dhcp6_listval *dhcp6_add_listval(struct dhcp6_list *, 142 | dhcp6_listval_type_t, void *, struct dhcp6_list *); 143 | int dhcp6_vbuf_copy(struct dhcp6_vbuf *, struct dhcp6_vbuf *); 144 | void dhcp6_vbuf_free(struct dhcp6_vbuf *); 145 | int dhcp6_vbuf_cmp(struct dhcp6_vbuf *, struct dhcp6_vbuf *); 146 | struct dhcp6_event *dhcp6_create_event(struct dhcp6_if *, int); 147 | void dhcp6_remove_event(struct dhcp6_event *); 148 | void dhcp6_remove_evdata(struct dhcp6_event *); 149 | struct authparam *new_authparam(int, int, int); 150 | struct authparam *copy_authparam(struct authparam *); 151 | int dhcp6_auth_replaycheck(int, uint64_t, uint64_t); 152 | int getifaddr(struct in6_addr *, char *, struct in6_addr *, 153 | int, int, int); 154 | int getifidfromaddr(struct in6_addr *, unsigned int *); 155 | int transmit_sa(int, struct sockaddr *, char *, size_t); 156 | int prefix6_mask(struct in6_addr *, int); 157 | int sa6_plen2mask(struct sockaddr_in6 *, int); 158 | char *addr2str(struct sockaddr *); 159 | char *in6addr2str(struct in6_addr *, int); 160 | int in6_addrscopebyif(struct in6_addr *, char *); 161 | int in6_scope(struct in6_addr *); 162 | void setloglevel(int); 163 | void d_printf(int, const char *, const char *, ...); 164 | int get_duid(const char *, struct duid *); 165 | void dhcp6_init_options(struct dhcp6_optinfo *); 166 | void dhcp6_clear_options(struct dhcp6_optinfo *); 167 | int dhcp6_copy_options(struct dhcp6_optinfo *, 168 | struct dhcp6_optinfo *); 169 | int dhcp6_get_options(struct dhcp6opt *, struct dhcp6opt *, 170 | struct dhcp6_optinfo *); 171 | int dhcp6_set_options(int, struct dhcp6opt *, struct dhcp6opt *, 172 | struct dhcp6_optinfo *); 173 | void dhcp6_set_timeoparam(struct dhcp6_event *); 174 | void dhcp6_reset_timer(struct dhcp6_event *); 175 | const char *dhcp6optstr(int); 176 | const char *dhcp6msgstr(int); 177 | const char *dhcp6_stcodestr(uint16_t); 178 | char *duidstr(struct duid *); 179 | const char *dhcp6_event_statestr(struct dhcp6_event *); 180 | int get_rdvalue(int, void *, size_t); 181 | int duidcpy(struct duid *, struct duid *); 182 | int duidcmp(struct duid *, struct duid *); 183 | void duidfree(struct duid *); 184 | int ifaddrconf(ifaddrconf_cmd_t, char *, struct sockaddr_in6 *, 185 | int, int, int); 186 | int safefile(const char *); 187 | 188 | /* missing */ 189 | #ifndef HAVE_STRLCAT 190 | size_t strlcat(char *, const char *, size_t); 191 | #endif 192 | #ifndef HAVE_STRLCPY 193 | size_t strlcpy(char *, const char *, size_t); 194 | #endif 195 | 196 | int get_val32(char **bpp, int *lenp, uint32_t *valp); 197 | int get_val(char **bpp, int *lenp, void *valp, size_t vallen); 198 | 199 | #endif 200 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | /* $KAME: config.h,v 1.39 2005/04/01 12:43:36 jinmei Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2002 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | 32 | #ifndef _CONFIG_H_ 33 | #define _CONFIG_H_ 34 | 35 | /* definitions of tail-queue types */ 36 | TAILQ_HEAD(ia_conflist, ia_conf); 37 | TAILQ_HEAD(pifc_list, prefix_ifconf); 38 | 39 | struct dhcp6_poolspec { 40 | char* name; 41 | uint32_t pltime; 42 | uint32_t vltime; 43 | }; 44 | 45 | struct dhcp6_range { 46 | struct in6_addr min; 47 | struct in6_addr max; 48 | }; 49 | 50 | struct pool_conf { 51 | struct pool_conf *next; 52 | 53 | char* name; 54 | 55 | struct in6_addr min; 56 | struct in6_addr max; 57 | }; 58 | 59 | /* per-interface information */ 60 | struct dhcp6_if { 61 | struct dhcp6_if *next; 62 | 63 | /* timer for the interface */ 64 | struct dhcp6_timer *timer; 65 | 66 | /* event queue */ 67 | TAILQ_HEAD(, dhcp6_event) event_list; 68 | 69 | /* static parameters of the interface */ 70 | char *ifname; 71 | unsigned int ifid; 72 | uint32_t linkid; /* to send link-local packets */ 73 | /* multiple global address configuration is not supported now */ 74 | struct in6_addr addr; /* global address */ 75 | 76 | /* configuration parameters */ 77 | u_long send_flags; 78 | u_long allow_flags; 79 | #define DHCIFF_INFO_ONLY 0x1 80 | #define DHCIFF_RAPID_COMMIT 0x2 81 | 82 | int server_pref; /* server preference (server only) */ 83 | struct dhcp6_poolspec pool; /* address pool (server only) */ 84 | char *scriptpath; /* path to config script (client only) */ 85 | 86 | /* XXX */ 87 | struct duid duid; 88 | struct rawop_list rawops; 89 | 90 | struct dhcp6_list reqopt_list; 91 | struct ia_conflist iaconf_list; 92 | 93 | /* authentication information */ 94 | int authproto; /* protocol */ 95 | /* the followings are valid only if authproto is not UNDEF */ 96 | int authalgorithm; /* algorithm */ 97 | int authrdm; /* replay attack detection method */ 98 | }; 99 | 100 | /* run-time authentication parameters */ 101 | struct authparam { 102 | int authproto; 103 | int authalgorithm; 104 | int authrdm; 105 | struct keyinfo *key; 106 | int flags; 107 | #define AUTHPARAM_FLAGS_NOPREVRD 0x1 108 | 109 | uint64_t prevrd; /* previous RD value provided by the peer */ 110 | }; 111 | 112 | struct dhcp6_event { 113 | TAILQ_ENTRY(dhcp6_event) link; 114 | 115 | struct dhcp6_if *ifp; 116 | struct dhcp6_timer *timer; 117 | 118 | struct duid serverid; 119 | 120 | struct timeval tv_start; /* timestamp when the 1st msg is sent */ 121 | 122 | /* internal timer parameters */ 123 | long retrans; 124 | long init_retrans; 125 | long max_retrans_cnt; 126 | long max_retrans_time; 127 | long max_retrans_dur; 128 | int timeouts; /* number of timeouts */ 129 | 130 | uint32_t xid; /* current transaction ID */ 131 | int state; 132 | 133 | /* list of known servers */ 134 | struct dhcp6_serverinfo *current_server; 135 | struct dhcp6_serverinfo *servers; 136 | 137 | /* authentication parameters */ 138 | struct authparam *authparam; 139 | 140 | TAILQ_HEAD(, dhcp6_eventdata) data_list; 141 | }; 142 | 143 | typedef enum { DHCP6_EVDATA_IAPD, DHCP6_EVDATA_IANA } dhcp6_eventdata_t; 144 | 145 | struct dhcp6_eventdata { 146 | TAILQ_ENTRY(dhcp6_eventdata) link; 147 | 148 | struct dhcp6_event *event; 149 | dhcp6_eventdata_t type; 150 | void *data; 151 | 152 | void (*destructor)(struct dhcp6_eventdata *); 153 | void *privdata; 154 | }; 155 | 156 | struct dhcp6_serverinfo { 157 | struct dhcp6_serverinfo *next; 158 | 159 | /* option information provided in the advertisement */ 160 | struct dhcp6_optinfo optinfo; 161 | 162 | int pref; /* preference */ 163 | int active; /* bool; if this server is active or not */ 164 | 165 | struct authparam *authparam; /* authentication parameters */ 166 | 167 | /* TODO: remember available information from the server */ 168 | }; 169 | 170 | /* client status code */ 171 | enum {DHCP6S_INIT, DHCP6S_SOLICIT, DHCP6S_INFOREQ, DHCP6S_REQUEST, 172 | DHCP6S_RENEW, DHCP6S_REBIND, DHCP6S_RELEASE, DHCP6S_IDLE, 173 | DHCP6S_EXIT}; 174 | 175 | struct prefix_ifconf { 176 | TAILQ_ENTRY(prefix_ifconf) link; 177 | 178 | char *ifname; /* interface name such as ne0 */ 179 | int sla_len; /* SLA ID length in bits */ 180 | uint32_t sla_id; /* need more than 32bits? */ 181 | int ifid_len; /* interface ID length in bits */ 182 | int ifid_type; /* EUI-64 and manual (unused?) */ 183 | char ifid[16]; /* Interface ID, up to 128bits */ 184 | }; 185 | #define IFID_LEN_DEFAULT 64 186 | #define SLA_LEN_DEFAULT 16 187 | 188 | typedef enum { IATYPE_PD, IATYPE_NA } iatype_t; 189 | struct ia_conf { 190 | TAILQ_ENTRY(ia_conf) link; 191 | /*struct ia_conf *next;*/ 192 | iatype_t type; 193 | uint32_t iaid; 194 | 195 | TAILQ_HEAD(, ia) iadata; /* struct ia is an opaque type */ 196 | 197 | /* type dependent values follow */ 198 | }; 199 | 200 | struct iapd_conf { 201 | struct ia_conf iapd_ia; 202 | 203 | /* type dependent values follow */ 204 | struct dhcp6_list iapd_prefix_list; 205 | struct pifc_list iapd_pif_list; 206 | }; 207 | #define iapd_next iapd_ia.next 208 | #define iapd_type iapd_ia.type 209 | #define iapd_id iapd_ia.iaid 210 | 211 | struct iana_conf { 212 | struct ia_conf iana_ia; 213 | 214 | /* type dependent values follow */ 215 | struct dhcp6_list iana_address_list; 216 | }; 217 | #define iana_next iana_ia.next 218 | 219 | /* per-host configuration */ 220 | struct host_conf { 221 | struct host_conf *next; 222 | 223 | char *name; /* host name to identify the host */ 224 | struct duid duid; /* DUID for the host */ 225 | 226 | /* prefixes to be delegated to the host */ 227 | struct dhcp6_list prefix_list; 228 | /* address to be assigned for the host */ 229 | struct dhcp6_list addr_list; 230 | /* address pool from which addresses are assigned for the host */ 231 | struct dhcp6_poolspec pool; 232 | 233 | /* secret key shared with the client for delayed authentication */ 234 | struct keyinfo *delayedkey; 235 | /* previous replay detection value from the client */ 236 | int saw_previous_rd; /* if we remember the previous value */ 237 | uint64_t previous_rd; 238 | }; 239 | 240 | /* DHCPv6 authentication information */ 241 | struct authinfo { 242 | struct authinfo *next; 243 | 244 | char *name; /* auth info name */ 245 | 246 | int protocol; /* authentication protocol */ 247 | int algorithm; /* authentication algorithm */ 248 | int rdm; /* random attack detection method */ 249 | 250 | /* keys specific to this info? */ 251 | }; 252 | 253 | /* structures and definitions used in the config file parser */ 254 | struct cf_namelist { 255 | struct cf_namelist *next; 256 | char *name; 257 | int line; /* the line number of the config file */ 258 | struct cf_list *params; 259 | }; 260 | 261 | struct cf_list { 262 | struct cf_list *next; 263 | struct cf_list *tail; 264 | int type; 265 | int line; /* the line number of the config file */ 266 | 267 | /* type dependent values: */ 268 | long long num; 269 | struct cf_list *list; 270 | void *ptr; 271 | }; 272 | 273 | enum { DECL_SEND, DECL_ALLOW, DECL_INFO_ONLY, DECL_REQUEST, DECL_DUID, 274 | DECL_PREFIX, DECL_PREFERENCE, DECL_SCRIPT, DECL_DELAYEDKEY, 275 | DECL_ADDRESS, 276 | DECL_RANGE, DECL_ADDRESSPOOL, 277 | IFPARAM_SLA_ID, IFPARAM_SLA_LEN, 278 | IFPARAM_IFID, IFPARAM_IFID_RAND, IFPARAM_IFID_EUI64, 279 | DHCPOPT_RAPID_COMMIT, DHCPOPT_AUTHINFO, 280 | DHCPOPT_DNS, DHCPOPT_DNSNAME, 281 | DHCPOPT_IA_PD, DHCPOPT_IA_NA, DHCPOPT_NTP, 282 | DHCPOPT_REFRESHTIME, 283 | DHCPOPT_NIS, DHCPOPT_NISNAME, 284 | DHCPOPT_NISP, DHCPOPT_NISPNAME, 285 | DHCPOPT_BCMCS, DHCPOPT_BCMCSNAME, 286 | CFLISTENT_GENERIC, 287 | IACONF_PIF, IACONF_PREFIX, IACONF_ADDR, 288 | DHCPOPT_SIP, DHCPOPT_SIPNAME, 289 | AUTHPARAM_PROTO, AUTHPARAM_ALG, AUTHPARAM_RDM, AUTHPARAM_KEY, 290 | KEYPARAM_REALM, KEYPARAM_KEYID, KEYPARAM_SECRET, KEYPARAM_EXPIRE, 291 | DHCPOPT_RAW }; 292 | 293 | typedef enum {DHCP6_MODE_SERVER, DHCP6_MODE_CLIENT, DHCP6_MODE_RELAY } 294 | dhcp6_mode_t; 295 | 296 | extern const dhcp6_mode_t dhcp6_mode; 297 | 298 | extern struct dhcp6_if *dhcp6_if; 299 | extern struct dhcp6_ifconf *dhcp6_iflist; 300 | extern struct prefix_ifconf *prefix_ifconflist; 301 | extern struct dhcp6_list siplist; 302 | extern struct dhcp6_list sipnamelist; 303 | extern struct dhcp6_list dnslist; 304 | extern struct dhcp6_list dnsnamelist; 305 | extern struct dhcp6_list ntplist; 306 | extern struct dhcp6_list nislist; 307 | extern struct dhcp6_list nisnamelist; 308 | extern struct dhcp6_list nisplist; 309 | extern struct dhcp6_list nispnamelist; 310 | extern struct dhcp6_list bcmcslist; 311 | extern struct dhcp6_list bcmcsnamelist; 312 | extern long long optrefreshtime; 313 | extern int use_all_config_if; 314 | 315 | struct dhcp6_if *ifinit(char *); 316 | int ifreset(struct dhcp6_if *); 317 | int configure_interface(struct cf_namelist *); 318 | int configure_host(struct cf_namelist *); 319 | int configure_keys(struct cf_namelist *); 320 | int configure_authinfo(struct cf_namelist *); 321 | int configure_ia(struct cf_namelist *, iatype_t); 322 | int configure_global_option(void); 323 | void configure_cleanup(void); 324 | void configure_commit(void); 325 | int cfparse(const char *); 326 | struct dhcp6_if *find_ifconfbyname(char *); 327 | struct dhcp6_if *find_ifconfbyid(unsigned int); 328 | struct prefix_ifconf *find_prefixifconf(char *); 329 | struct host_conf *find_hostconf(struct duid *); 330 | struct authinfo *find_authinfo(struct authinfo *, char *); 331 | struct dhcp6_prefix *find_prefix6(struct dhcp6_list *, 332 | struct dhcp6_prefix *); 333 | struct ia_conf *find_iaconf(struct ia_conflist *, int, uint32_t); 334 | struct keyinfo *find_key(char *, size_t, uint32_t); 335 | int configure_pool(struct cf_namelist *); 336 | struct pool_conf *find_pool(const char *); 337 | int is_available_in_pool(struct pool_conf *, struct in6_addr *); 338 | int get_free_address_from_pool(struct pool_conf *, 339 | struct in6_addr *); 340 | struct host_conf *create_dynamic_hostconf(struct duid *, 341 | struct dhcp6_poolspec *); 342 | char *qstrdup(char *); 343 | 344 | #endif 345 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | dnl Process this file with autoconf to produce a configure script. 2 | AC_INIT([wide-dhcpv6],[20080615]) 3 | 4 | dnl Checks for programs. 5 | AC_PROG_INSTALL 6 | AC_PROG_MAKE_SET 7 | AC_PROG_CC 8 | AC_PROG_CPP 9 | AC_PROG_YACC 10 | AC_PROG_LEX 11 | 12 | dnl Checks for libraries. 13 | dnl AC_CHECK_LIB(c, kvm_open, [], [AC_CHECK_LIB(kvm, kvm_open)]) 14 | dnl AC_CHECK_LIB(mld, nlist) 15 | 16 | dnl pcap library 17 | dnl CFLAGS="-I. $CFLAGS" 18 | dnl AC_MSG_CHECKING(for pcap library/header) 19 | dnl for dir in /usr/local/libpcap /usr/local/v6 /usr/local \ 20 | dnl ../libpcap* ../../libpcap*; do 21 | dnl ac_cv_pcap_lib=no 22 | dnl ac_cv_pcap_include=no 23 | dnl if test -d $dir -a -f $dir/libpcap.a; then 24 | dnl ac_cv_pcap_lib="$dir" 25 | dnl elif test -d $dir/lib -a -f $dir/lib/libpcap.a; then 26 | dnl ac_cv_pcap_lib="$dir/lib" 27 | dnl fi 28 | dnl if test -d $dir -a -f $dir/pcap.h; then 29 | dnl ac_cv_pcap_include="$dir" 30 | dnl elif test -d $dir/include -a -f $dir/include/pcap.h; then 31 | dnl ac_cv_pcap_include="$dir/include" 32 | dnl fi 33 | dnl if test "$ac_cv_pcap_lib" != "no" -a "$ac_cv_pcap_include" != "no"; then 34 | dnl LIBS="-L$ac_cv_pcap_lib $LIBS" 35 | dnl CFLAGS="-I$ac_cv_pcap_include $CFLAGS" 36 | dnl break 37 | dnl fi 38 | dnl done 39 | dnl if test "$ac_cv_pcap_lib" = "no" -a "$ac_cv_pcap_include" = "no"; then 40 | dnl AC_MSG_RESULT(no) 41 | dnl else 42 | dnl AC_MSG_RESULT($ac_cv_pcap_lib and $ac_cv_pcap_include) 43 | dnl fi 44 | dnl AC_CHECK_LIB(pcap, pcap_lookupdev, [], 45 | dnl [echo "Fatal: libpcap.a not found" 46 | dnl exit 1]) 47 | dnl AC_TRY_COMPILE([#include ], [], [], [dnl 48 | dnl echo "Fatal: pcap.h not found" 49 | dnl exit 1]) 50 | 51 | CFLAGS="$CFLAGS -I\$(srcdir)" 52 | 53 | dnl On Sun systems, we need to use the standards-compliant 3XNET functions 54 | if test -x /usr/bin/sun && /usr/bin/sun; then 55 | CFLAGS="$CFLAGS -D_XOPEN_SOURCE=500 -D__EXTENSIONS__" 56 | LDFLAGS="-lxnet -ldevinfo -lnsl -lsocket -lrt" 57 | fi 58 | 59 | AC_MSG_CHECKING(for sys/queue.h) 60 | AC_TRY_COMPILE([#include ], 61 | [TAILQ_HEAD(test, none);], 62 | [AC_MSG_RESULT(yes)], 63 | [AC_MSG_RESULT(no) 64 | CFLAGS="$CFLAGS -I\$(srcdir)/missing"]) 65 | 66 | AC_EGREP_CPP(yes, 67 | [#include 68 | #ifdef __KAME__ 69 | yes 70 | #endif], [result=kame], [result=regular]) 71 | AC_MSG_CHECKING(for getaddrinfo/getnameinfo library) 72 | AC_MSG_RESULT($result) 73 | case $result in 74 | kame) AC_DEFINE(INET6) 75 | o_LIBS="$LIBS" 76 | LIBS="$LIBS -L/usr/local/v6/lib" 77 | AC_CHECK_LIB(inet6, getaddrinfo, [], [LIBS="$o_LIBS"]) 78 | ;; 79 | *) ;; 80 | esac 81 | 82 | AC_REPLACE_FUNCS(getaddrinfo) 83 | AC_REPLACE_FUNCS(getnameinfo) 84 | AC_REPLACE_FUNCS(getifaddrs) 85 | AC_CHECK_FUNCS(if_nametoindex) 86 | AC_REPLACE_FUNCS(strlcpy strlcat) 87 | AC_REPLACE_FUNCS(daemon) 88 | AC_REPLACE_FUNCS(warnx) 89 | 90 | dnl Checks for header files. 91 | AC_HEADER_STDC 92 | AC_CHECK_HEADERS(fcntl.h sys/ioctl.h sys/time.h syslog.h unistd.h ifaddrs.h) 93 | AC_MSG_CHECKING(for socklen_t) 94 | AC_TRY_COMPILE([#include 95 | #include ], 96 | [socklen_t x; x = 1; return x;], 97 | [AC_MSG_RESULT(yes)], 98 | [AC_MSG_RESULT(no) 99 | AC_CHECK_TYPE(socklen_t, int)]) 100 | 101 | dnl Checks for typedefs, structures, and compiler characteristics. 102 | AC_C_CONST 103 | AC_TYPE_SIZE_T 104 | AC_HEADER_TIME 105 | AC_STRUCT_TM 106 | AC_STRUCT_TIMEZONE 107 | AC_CHECK_TYPES([sig_atomic_t], , [AC_DEFINE(sig_atomic_t, u_long)], [#include 108 | #include ]) 109 | 110 | 111 | dnl Checks for library functions. 112 | AC_FUNC_GETPGRP 113 | AC_PROG_GCC_TRADITIONAL 114 | AC_FUNC_SETPGRP 115 | AC_TYPE_SIGNAL 116 | AC_CHECK_FUNCS(mktime select socket) 117 | AC_CHECK_FUNCS(clock_gettime) 118 | 119 | dnl configure local DB directory 120 | AC_MSG_CHECKING(for local DB directory) 121 | AC_ARG_WITH(localdbdir, 122 | [ --with-localdbdir=VALUE where to put local DB files], 123 | localdbdir="$withval", localdbdir="/var/db") 124 | AC_MSG_RESULT($localdbdir) 125 | AC_SUBST(localdbdir) 126 | 127 | AC_MSG_CHECKING(if --enable-pedant option is specified) 128 | AC_ARG_ENABLE(pedant, [ --enable-pedant pedantic compilation], 129 | [if test "$enableval" = "yes"; then 130 | CFLAGS="-Wall -Werror $CFLAGS" 131 | fi], [enableval=no]) 132 | AC_MSG_RESULT($enableval); 133 | 134 | dnl Checks predeclared identifers of function names 135 | AC_MSG_CHECKING(ANSI predeclared __func__) 136 | AC_TRY_COMPILE([], 137 | [void func(void) {printf("%s\n", __func__);}], 138 | [AC_MSG_RESULT(yes) 139 | pred_func_id=ansi], 140 | [AC_MSG_RESULT(no) 141 | pred_func_id=no]) 142 | if test $pred_func_id = no; then 143 | AC_MSG_CHECKING(gcc predelcared __FUNCTION__) 144 | AC_TRY_COMPILE([], 145 | [void func(void) {printf("%s\n", __FUNCTION__);}], 146 | [AC_MSG_RESULT(yes) 147 | pred_func_id=gcc], 148 | [AC_MSG_RESULT(no) 149 | pred_func_id=no]) 150 | fi 151 | case $pred_func_id in 152 | ansi) 153 | AC_DEFINE(HAVE_ANSI_FUNC) 154 | ;; 155 | gcc) 156 | AC_DEFINE(HAVE_GCC_FUNCTION) 157 | ;; 158 | esac 159 | 160 | dnl DHCP option type values not officially defined 161 | dnl (no such option now) 162 | 163 | dnl Checks the existence of TAILQ_FOREACH_REVERSE 164 | AC_MSG_CHECKING(checking the existence TAILQ_FOREACH_REVERSE) 165 | AC_EGREP_CPP(yes, 166 | [#include 167 | #ifdef TAILQ_FOREACH_REVERSE 168 | yes 169 | #endif], [result=yes], [result=no]) 170 | AC_MSG_RESULT($result) 171 | case $result in 172 | yes) tailq_foreach=yes 173 | ;; 174 | *) tailq_foreach=no 175 | ;; 176 | esac 177 | 178 | dnl Checks the argument order of TAILQ_FOREACH_REVERSE if it exists 179 | if test $tailq_foreach = yes ; then 180 | AC_MSG_CHECKING(argument order of TAILQ_FOREACH_REVERSE) 181 | AC_TRY_COMPILE([], 182 | [ 183 | #include 184 | #include 185 | 186 | TAILQ_HEAD(tailhead, entry) head = TAILQ_HEAD_INITIALIZER(head); 187 | struct entry { 188 | TAILQ_ENTRY(entry) entries; 189 | } *p; 190 | 191 | int i; 192 | struct tailhead *headp; 193 | 194 | TAILQ_FOREACH_REVERSE(p, headp, tailhead, entries) { 195 | } 196 | ], 197 | [AC_MSG_RESULT(new) 198 | AC_DEFINE(HAVE_TAILQ_FOREACH_REVERSE)], 199 | [AC_MSG_RESULT(old) 200 | AC_DEFINE(HAVE_TAILQ_FOREACH_REVERSE_OLD)]); 201 | fi 202 | 203 | dnl Checks for other features 204 | AC_MSG_CHECKING(if you have a length field in struct sockaddr*) 205 | AC_CACHE_VAL(ts_cv_sa_len, [dnl 206 | AC_TRY_COMPILE([ 207 | #include 208 | #include 209 | ], [ 210 | struct sockaddr a; 211 | a.sa_len = 1; 212 | ], [ts_cv_sa_len="yes"], [ts_cv_sa_len="no"])]) 213 | AC_MSG_RESULT($ts_cv_sa_len); 214 | if test "$ts_cv_sa_len" = yes; then 215 | AC_DEFINE([HAVE_SA_LEN], 1, [Define to 1 if you have a length field in struct sockaddr]) 216 | fi 217 | 218 | dnl configure the ownership of the programs 219 | AC_MSG_CHECKING(the owner of the programs) 220 | AC_ARG_WITH(user, 221 | [ --with-user=USER set the owner of the programs], 222 | user="$withval", user="bin") 223 | AC_MSG_RESULT($user) 224 | AC_SUBST(user) 225 | 226 | dnl configure the group ownership of the programs 227 | AC_MSG_CHECKING(the group owner of the programs) 228 | AC_ARG_WITH(group, 229 | [ --with-group=GROUP set the group owner of the programs], 230 | group="$withval", group="bin") 231 | AC_MSG_RESULT($group) 232 | AC_SUBST(group) 233 | 234 | AC_CHECK_HEADERS(stdarg.h) 235 | 236 | AC_OUTPUT(Makefile) 237 | -------------------------------------------------------------------------------- /dhcp6.h: -------------------------------------------------------------------------------- 1 | /* $KAME: dhcp6.h,v 1.56 2005/03/20 06:46:09 jinmei Exp $ */ 2 | /* 3 | * Copyright (C) 1998 and 1999 WIDE Project. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. Neither the name of the project nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software 16 | * without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 | * SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef _DHCP6_H_ 32 | #define _DHCP6_H_ 33 | 34 | #ifndef CMSG_SPACE 35 | #define CMSG_SPACE(l) \ 36 | ((unsigned int)_CMSG_HDR_ALIGN(sizeof (struct cmsghdr) + (l))) 37 | #endif 38 | #ifndef CMSG_LEN 39 | #define CMSG_LEN(l) \ 40 | ((unsigned int)_CMSG_DATA_ALIGN(sizeof (struct cmsghdr)) + (l)) 41 | #endif 42 | 43 | /* Error Values */ 44 | #define DH6ERR_FAILURE 16 45 | #define DH6ERR_AUTHFAIL 17 46 | #define DH6ERR_POORLYFORMED 18 47 | #define DH6ERR_UNAVAIL 19 48 | #define DH6ERR_OPTUNAVAIL 20 49 | 50 | /* Message type */ 51 | #define DH6_SOLICIT 1 52 | #define DH6_ADVERTISE 2 53 | #define DH6_REQUEST 3 54 | #define DH6_CONFIRM 4 55 | #define DH6_RENEW 5 56 | #define DH6_REBIND 6 57 | #define DH6_REPLY 7 58 | #define DH6_RELEASE 8 59 | #define DH6_DECLINE 9 60 | #define DH6_RECONFIGURE 10 61 | #define DH6_INFORM_REQ 11 62 | #define DH6_RELAY_FORW 12 63 | #define DH6_RELAY_REPLY 13 64 | 65 | /* Predefined addresses */ 66 | #define DH6ADDR_ALLAGENT "ff02::1:2" 67 | #define DH6ADDR_ALLSERVER "ff05::1:3" 68 | #define DH6PORT_DOWNSTREAM "546" 69 | #define DH6PORT_UPSTREAM "547" 70 | 71 | /* Protocol constants */ 72 | 73 | /* timer parameters (msec, unless explicitly commented) */ 74 | #define SOL_MAX_DELAY 1000 75 | #define SOL_TIMEOUT 1000 76 | #define SOL_MAX_RT 3600000 77 | #define INF_MAX_DELAY 1000 78 | #define INF_TIMEOUT 1000 79 | #define INF_MAX_RT 3600000 80 | #define REQ_TIMEOUT 1000 81 | #define REQ_MAX_RT 30000 82 | #define REQ_MAX_RC 10 /* Max Request retry attempts */ 83 | #define REN_TIMEOUT 10000 84 | #define REN_MAX_RT 600000 85 | #define REB_TIMEOUT 10000 86 | #define REB_MAX_RT 600000 87 | #define REL_TIMEOUT 1000 88 | #define REL_MAX_RC 4 /* Max Release retry attempts */ 89 | 90 | #define DHCP6_DURATION_INFINITE 0xffffffff 91 | #define DHCP6_DURATION_MIN 30 92 | 93 | #define DHCP6_RELAY_MULTICAST_HOPS 32 94 | #define DHCP6_RELAY_HOP_COUNT_LIMIT 32 95 | 96 | #define DHCP6_IRT_DEFAULT 86400 /* 1 day */ 97 | #define DHCP6_IRT_MINIMUM 600 98 | 99 | TAILQ_HEAD(rawop_list, rawoption); 100 | struct rawoption { 101 | TAILQ_ENTRY(rawoption) link; 102 | 103 | int opnum; 104 | char *data; 105 | int datalen; 106 | }; 107 | 108 | 109 | /* DUID: DHCP unique Identifier */ 110 | struct duid { 111 | size_t duid_len; /* length */ 112 | char *duid_id; /* variable length ID value (must be opaque) */ 113 | }; 114 | 115 | struct dhcp6_vbuf { /* generic variable length buffer */ 116 | int dv_len; 117 | caddr_t dv_buf; 118 | }; 119 | 120 | /* option information */ 121 | struct dhcp6_ia { /* identity association */ 122 | uint32_t iaid; 123 | uint32_t t1; 124 | uint32_t t2; 125 | }; 126 | 127 | struct dhcp6_prefix { /* IA_PA */ 128 | uint32_t pltime; 129 | uint32_t vltime; 130 | struct in6_addr addr; 131 | int plen; 132 | }; 133 | 134 | struct dhcp6_statefuladdr { /* IA_NA */ 135 | uint32_t pltime; 136 | uint32_t vltime; 137 | struct in6_addr addr; 138 | }; 139 | 140 | /* Internal data structure */ 141 | typedef enum { DHCP6_LISTVAL_NUM = 1, 142 | DHCP6_LISTVAL_STCODE, DHCP6_LISTVAL_ADDR6, 143 | DHCP6_LISTVAL_IAPD, DHCP6_LISTVAL_PREFIX6, 144 | DHCP6_LISTVAL_IANA, DHCP6_LISTVAL_STATEFULADDR6, 145 | DHCP6_LISTVAL_VBUF 146 | } dhcp6_listval_type_t; 147 | TAILQ_HEAD(dhcp6_list, dhcp6_listval); 148 | struct dhcp6_listval { 149 | TAILQ_ENTRY(dhcp6_listval) link; 150 | 151 | dhcp6_listval_type_t type; 152 | 153 | union { 154 | int uv_num; 155 | uint16_t uv_num16; 156 | struct in6_addr uv_addr6; 157 | struct dhcp6_prefix uv_prefix6; 158 | struct dhcp6_statefuladdr uv_statefuladdr6; 159 | struct dhcp6_ia uv_ia; 160 | struct dhcp6_vbuf uv_vbuf; 161 | } uv; 162 | 163 | struct dhcp6_list sublist; 164 | }; 165 | #define val_num uv.uv_num 166 | #define val_num16 uv.uv_num16 167 | #define val_addr6 uv.uv_addr6 168 | #define val_ia uv.uv_ia 169 | #define val_prefix6 uv.uv_prefix6 170 | #define val_statefuladdr6 uv.uv_statefuladdr6 171 | #define val_vbuf uv.uv_vbuf 172 | 173 | struct dhcp6_optinfo { 174 | struct duid clientID; /* DUID */ 175 | struct duid serverID; /* DUID */ 176 | 177 | int rapidcommit; /* bool */ 178 | int pref; /* server preference */ 179 | int32_t elapsed_time; /* elapsed time (from client to server only) */ 180 | int64_t refreshtime; /* info refresh time for stateless options */ 181 | 182 | struct dhcp6_list iapd_list; /* list of IA_PD */ 183 | struct dhcp6_list iana_list; /* list of IA_NA */ 184 | struct dhcp6_list reqopt_list; /* options in option request */ 185 | struct dhcp6_list stcode_list; /* status code */ 186 | struct dhcp6_list sip_list; /* SIP server list */ 187 | struct dhcp6_list sipname_list; /* SIP domain list */ 188 | struct dhcp6_list dns_list; /* DNS server list */ 189 | struct dhcp6_list dnsname_list; /* Domain Search list */ 190 | struct dhcp6_list ntp_list; /* NTP server list */ 191 | struct dhcp6_list prefix_list; /* prefix list */ 192 | struct dhcp6_list nis_list; /* NIS server list */ 193 | struct dhcp6_list nisname_list; /* NIS domain list */ 194 | struct dhcp6_list nisp_list; /* NIS+ server list */ 195 | struct dhcp6_list nispname_list; /* NIS+ domain list */ 196 | struct dhcp6_list bcmcs_list; /* BCMC server list */ 197 | struct dhcp6_list bcmcsname_list; /* BCMC domain list */ 198 | struct rawop_list rawops; /* Raw option list */ 199 | 200 | struct dhcp6_vbuf relay_msg; /* relay message */ 201 | #define relaymsg_len relay_msg.dv_len 202 | #define relaymsg_msg relay_msg.dv_buf 203 | 204 | struct dhcp6_vbuf ifidopt; /* Interface-id */ 205 | #define ifidopt_len ifidopt.dv_len 206 | #define ifidopt_id ifidopt.dv_buf 207 | 208 | u_int authflags; 209 | #define DHCP6OPT_AUTHFLAG_NOINFO 0x1 210 | int authproto; 211 | int authalgorithm; 212 | int authrdm; 213 | /* the followings are effective only when NOINFO is unset */ 214 | uint64_t authrd; 215 | union { 216 | struct { 217 | uint32_t keyid; 218 | struct dhcp6_vbuf realm; 219 | int offset; /* offset to the HMAC field */ 220 | } aiu_delayed; 221 | struct { 222 | int type; 223 | int offset; /* offset to the HMAC field */ 224 | char val[16]; /* key value */ 225 | } aiu_reconfig; 226 | } authinfo; 227 | #define delayedauth_keyid authinfo.aiu_delayed.keyid 228 | #define delayedauth_realmlen authinfo.aiu_delayed.realm.dv_len 229 | #define delayedauth_realmval authinfo.aiu_delayed.realm.dv_buf 230 | #define delayedauth_offset authinfo.aiu_delayed.offset 231 | #define reconfigauth_type authinfo.aiu_reconfig.type 232 | #define reconfigauth_offset authinfo.aiu_reconfig.offset 233 | #define reconfigauth_val authinfo.aiu_reconfig.val 234 | }; 235 | 236 | /* DHCP6 base packet format */ 237 | struct dhcp6 { 238 | union { 239 | uint8_t m; 240 | uint32_t x; 241 | } dh6_msgtypexid; 242 | /* options follow */ 243 | } __attribute__ ((__packed__)); 244 | #define dh6_msgtype dh6_msgtypexid.m 245 | #define dh6_xid dh6_msgtypexid.x 246 | #define DH6_XIDMASK 0x00ffffff 247 | 248 | /* DHCPv6 relay messages */ 249 | struct dhcp6_relay { 250 | uint8_t dh6relay_msgtype; 251 | uint8_t dh6relay_hcnt; 252 | struct in6_addr dh6relay_linkaddr; /* XXX: badly aligned */ 253 | struct in6_addr dh6relay_peeraddr; /* ditto */ 254 | /* options follow */ 255 | } __attribute__ ((__packed__)); 256 | 257 | /* options */ 258 | #define DH6OPT_CLIENTID 1 259 | #define DH6OPT_SERVERID 2 260 | #define DH6OPT_IA_NA 3 261 | #define DH6OPT_IA_TA 4 262 | #define DH6OPT_IAADDR 5 263 | #define DH6OPT_ORO 6 264 | #define DH6OPT_PREFERENCE 7 265 | # define DH6OPT_PREF_UNDEF -1 266 | # define DH6OPT_PREF_MAX 255 267 | #define DH6OPT_ELAPSED_TIME 8 268 | # define DH6OPT_ELAPSED_TIME_UNDEF -1 269 | #define DH6OPT_RELAY_MSG 9 270 | /* #define DH6OPT_SERVER_MSG 10: deprecated */ 271 | #define DH6OPT_AUTH 11 272 | # define DH6OPT_AUTH_PROTO_DELAYED 2 273 | # define DH6OPT_AUTH_RRECONFIGURE 3 274 | # define DH6OPT_AUTH_ALG_HMACMD5 1 275 | #define DH6OPT_UNICAST 12 276 | #define DH6OPT_STATUS_CODE 13 277 | # define DH6OPT_STCODE_SUCCESS 0 278 | # define DH6OPT_STCODE_UNSPECFAIL 1 279 | # define DH6OPT_STCODE_NOADDRSAVAIL 2 280 | # define DH6OPT_STCODE_NOBINDING 3 281 | # define DH6OPT_STCODE_NOTONLINK 4 282 | # define DH6OPT_STCODE_USEMULTICAST 5 283 | # define DH6OPT_STCODE_NOPREFIXAVAIL 6 284 | 285 | #define DH6OPT_RAPID_COMMIT 14 286 | #define DH6OPT_USER_CLASS 15 287 | #define DH6OPT_VENDOR_CLASS 16 288 | #define DH6OPT_VENDOR_OPTS 17 289 | #define DH6OPT_INTERFACE_ID 18 290 | #define DH6OPT_RECONF_MSG 19 291 | #define DH6OPT_RECONF_ACCEPT 20 292 | #define DH6OPT_SIP_SERVER_D 21 293 | #define DH6OPT_SIP_SERVER_A 22 294 | #define DH6OPT_DNS 23 295 | #define DH6OPT_DNSNAME 24 296 | #define DH6OPT_IA_PD 25 297 | #define DH6OPT_IA_PD_PREFIX 26 298 | #define DH6OPT_NIS_SERVERS 27 299 | #define DH6OPT_NISP_SERVERS 28 300 | #define DH6OPT_NIS_DOMAIN_NAME 29 301 | #define DH6OPT_NISP_DOMAIN_NAME 30 302 | #define DH6OPT_NTP 31 303 | #define DH6OPT_REFRESHTIME 32 304 | #define DH6OPT_REFRESHTIME_UNDEF -1 305 | #define DH6OPT_BCMCS_SERVER_D 33 306 | #define DH6OPT_BCMCS_SERVER_A 34 307 | #define DH6OPT_GEOCONF_CIVIC 36 308 | #define DH6OPT_REMOTE_ID 37 309 | #define DH6OPT_SUBSCRIBER_ID 38 310 | #define DH6OPT_CLIENT_FQDN 39 311 | 312 | /* The followings are KAME specific. */ 313 | 314 | struct dhcp6opt { 315 | uint16_t dh6opt_type; 316 | uint16_t dh6opt_len; 317 | /* type-dependent data follows */ 318 | } __attribute__ ((__packed__)); 319 | 320 | /* DUID type 1 */ 321 | struct dhcp6opt_duid_type1 { 322 | uint16_t dh6_duid1_type; 323 | uint16_t dh6_duid1_hwtype; 324 | uint32_t dh6_duid1_time; 325 | /* link-layer address follows */ 326 | } __attribute__ ((__packed__)); 327 | 328 | /* Status Code */ 329 | struct dhcp6opt_stcode { 330 | uint16_t dh6_stcode_type; 331 | uint16_t dh6_stcode_len; 332 | uint16_t dh6_stcode_code; 333 | } __attribute__ ((__packed__)); 334 | 335 | /* 336 | * General format of Identity Association. 337 | * This format applies to Prefix Delegation (IA_PD) and Non-temporary Addresses 338 | * (IA_NA) 339 | */ 340 | struct dhcp6opt_ia { 341 | uint16_t dh6_ia_type; 342 | uint16_t dh6_ia_len; 343 | uint32_t dh6_ia_iaid; 344 | uint32_t dh6_ia_t1; 345 | uint32_t dh6_ia_t2; 346 | /* sub options follow */ 347 | } __attribute__ ((__packed__)); 348 | 349 | /* IA Addr */ 350 | struct dhcp6opt_ia_addr { 351 | uint16_t dh6_ia_addr_type; 352 | uint16_t dh6_ia_addr_len; 353 | struct in6_addr dh6_ia_addr_addr; 354 | uint32_t dh6_ia_addr_preferred_time; 355 | uint32_t dh6_ia_addr_valid_time; 356 | } __attribute__ ((__packed__)); 357 | 358 | /* IA_PD Prefix */ 359 | struct dhcp6opt_ia_pd_prefix { 360 | uint16_t dh6_iapd_prefix_type; 361 | uint16_t dh6_iapd_prefix_len; 362 | uint32_t dh6_iapd_prefix_preferred_time; 363 | uint32_t dh6_iapd_prefix_valid_time; 364 | uint8_t dh6_iapd_prefix_prefix_len; 365 | struct in6_addr dh6_iapd_prefix_prefix_addr; 366 | } __attribute__ ((__packed__)); 367 | 368 | /* Authentication */ 369 | struct dhcp6opt_auth { 370 | uint16_t dh6_auth_type; 371 | uint16_t dh6_auth_len; 372 | uint8_t dh6_auth_proto; 373 | uint8_t dh6_auth_alg; 374 | uint8_t dh6_auth_rdm; 375 | uint8_t dh6_auth_rdinfo[8]; 376 | /* authentication information follows */ 377 | } __attribute__ ((__packed__)); 378 | 379 | enum { DHCP6_AUTHPROTO_UNDEF = -1, DHCP6_AUTHPROTO_DELAYED = 2, 380 | DHCP6_AUTHPROTO_RECONFIG = 3 }; 381 | enum { DHCP6_AUTHALG_UNDEF = -1, DHCP6_AUTHALG_HMACMD5 = 1 }; 382 | enum { DHCP6_AUTHRDM_UNDEF = -1, DHCP6_AUTHRDM_MONOCOUNTER = 0 }; 383 | 384 | #endif 385 | -------------------------------------------------------------------------------- /dhcp6c.8: -------------------------------------------------------------------------------- 1 | .\" $KAME: dhcp6c.8,v 1.36 2005/03/17 05:27:01 suz Exp $ 2 | .\" 3 | .\" Copyright (C) 1998 and 1999 WIDE Project. 4 | .\" All rights reserved. 5 | .\" 6 | .\" Redistribution and use in source and binary forms, with or without 7 | .\" modification, are permitted provided that the following conditions 8 | .\" are met: 9 | .\" 1. Redistributions of source code must retain the above copyright 10 | .\" notice, this list of conditions and the following disclaimer. 11 | .\" 2. Redistributions in binary form must reproduce the above copyright 12 | .\" notice, this list of conditions and the following disclaimer in the 13 | .\" documentation and/or other materials provided with the distribution. 14 | .\" 3. Neither the name of the project nor the names of its contributors 15 | .\" may be used to endorse or promote products derived from this software 16 | .\" without specific prior written permission. 17 | .\" 18 | .\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 19 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 22 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 | .\" SUCH DAMAGE. 29 | .\" 30 | .Dd June 7, 2024 31 | .Dt DHCP6C 8 32 | .Os KAME 33 | .Sh NAME 34 | .Nm dhcp6c 35 | .Nd DHCPv6 client daemon 36 | .\" 37 | .Sh SYNOPSIS 38 | .Nm 39 | .Op Fl c Ar configfile 40 | .Op Fl Ddfint 41 | .Op Fl p Ar pid-file 42 | .Op Ar interfaces... 43 | .\" 44 | .Sh DESCRIPTION 45 | .Nm 46 | works as a DHCPv6 client and gets information from DHCPv6 servers 47 | to configure the specified 48 | .Ar interface . 49 | Multiple 50 | .Ar interfaces 51 | can be specified separated by spaces or tabs, 52 | in which case 53 | .Nm 54 | will work on all the interfaces simultaneously. 55 | .Pp 56 | The command line options are: 57 | .Bl -tag -width indent 58 | .\" 59 | .It Fl c Ar configfile 60 | Use 61 | .Ar configfile 62 | as the configuration file. 63 | .It Fl d 64 | Print debugging messages. 65 | .It Fl D 66 | Even more debugging information is printed. 67 | .It Fl f 68 | Foreground mode (useful when debugging). 69 | Although 70 | .Nm 71 | usually prints warning, debugging, or error messages to 72 | .Xr syslog 8 , 73 | it prints the messages to standard error if this option is 74 | specified. 75 | .It Fl i 76 | Info-req mode. 77 | In this mode, stateless DHCPv6 is executed with the following configuration, 78 | and the obtained info is written to stdout. 79 | After this output, 80 | .Nm 81 | is terminated. (suits for a use in shell-script etc). 82 | .Bd -literal -offset 83 | interface (interface given in the argument) { 84 | information-only; 85 | script (a script which displays the received information to stdout); 86 | }; 87 | .Ed 88 | .Pp 89 | Since the configuration is internally generated, you cannot provide a configuration in this mode. If you want to have different actions for the stateless DHCPv6 information, you should write an appropriate configuration and invoke 90 | .Nm 91 | without this option. 92 | .It Fl n 93 | Prevent Release message from being sent to DHCPv6 server when 94 | .Nm 95 | stops. 96 | This is useful for preventing a new address from being configured by 97 | the DHCPv6 server when restarting the DHCPv6 client. 98 | .It Fl p Ar pid-file 99 | Use 100 | .Ar pid-file 101 | to dump the process ID of 102 | .Nm . 103 | .It Fl t 104 | Only parse the configuration and exit. 105 | .El 106 | .Pp 107 | The program will daemonize itself on invocation unless the 108 | .Fl f , 109 | .Fl i , 110 | or 111 | .Fl t 112 | option is specified. 113 | .Pp 114 | Upon receipt of a 115 | .Dv SIGHUP , 116 | .Dv SIGINT , 117 | .Dv SIGTERM , 118 | or 119 | .Dv SIGUSR1 120 | signal, 121 | .Nm 122 | will remove all stateful resources from the system. 123 | After that, 124 | .Dv SIGHUP 125 | reinitializes the daemon, 126 | and both 127 | .DV SIGINT 128 | or 129 | .Dv SIGTERM 130 | stop the daemon. 131 | In these cases, 132 | DHCPv6 Release message will be sent to release resources 133 | assigned from servers. 134 | .Dv SIGUSR1 135 | stops the daemon as 136 | .Dv SIGINT 137 | or 138 | .Dv SIGTERM 139 | does though DHCPv6 Release message will not be sent. 140 | .\" 141 | .Sh FILES 142 | .Bl -tag -width /usr/local/etc/dhcp6c.conf -compact 143 | .It Pa /var/run/dhcp6c.pid 144 | is the default file that contains pid of the currently running 145 | .Nm dhcp6c . 146 | .It Pa /usr/local/etc/dhcp6c.conf 147 | is the default configuration file. 148 | .It Pa /var/db/dhcp6c_duid 149 | is the file to store the client's DUID. 150 | .El 151 | .Sh Configuration Script 152 | When 153 | .Nm 154 | receives a reply message, 155 | it will invoke a supplementary configuration script specified in the 156 | .Xr dhcp6c.conf 5 157 | file. 158 | The daemon will provide the script with configuration parameters as 159 | environment variables, 160 | which include: 161 | .Pp 162 | .Bl -tag -width Ds -compact 163 | .It Li PDINFO 164 | The delegated prefix for the interface. 165 | Make sure to use a separate script for each interface when using 166 | multiple interfaces at once. 167 | .It Li REASON 168 | The reason why the script is invoked. 169 | One of the following values is set based on a message 170 | which the client sent before the 171 | .Li REPLY 172 | message arrives: 173 | .Bl -tag -width "INFOREQ" -compact -offset indent 174 | .It Li INFOREQ 175 | The client sent an 176 | .Li INFORMATION REQUEST 177 | message. 178 | .It Li REQUEST 179 | The client sent a 180 | .Li REQUEST 181 | message. 182 | .It Li RENEW 183 | The client sent a 184 | .Li RENEW 185 | message. 186 | .It Li REBIND 187 | The client sent a 188 | .Li REBIND 189 | message. 190 | .It Li RELEASE 191 | The client sent a 192 | .Li RELEASE 193 | message. 194 | .It Li EXIT 195 | This happens when 196 | .Nm 197 | exits. 198 | .El 199 | .It Ic new_domain_name_servers 200 | A list of available DNS servers, 201 | each of which is an IPv6 numeric address and is separated by a white 202 | space character. 203 | .It Ic new_domain_name 204 | A list of DNS names, 205 | which provides DNS name search path. 206 | .It Ic new_ntp_servers 207 | A list of available NTP servers, 208 | each of which is an IPv6 numeric address and is separated by a white 209 | space character. 210 | .It Ic new_sip_servers 211 | A list of available SIP server addresses, 212 | each of which is an IPv6 numeric address and is separated by a white 213 | space character. 214 | .It Ic new_sip_name 215 | A list of SIP server domain names. 216 | .It Ic new_nis_servers 217 | A list of available NIS server addresses, 218 | each of which is an IPv6 numeric address and is separated by a white 219 | space character. 220 | .It Ic new_nis_name 221 | A list of NIS domain names. 222 | .It Ic new_nisp_servers 223 | A list of available NIS+ server addresses, 224 | each of which is an IPv6 numeric address and is separated by a white 225 | space character. 226 | .It Ic new_nisp_name 227 | A list of NIS+ domain names. 228 | .It Ic new_bcmcs_servers 229 | A list of available BCMCS server addresses, 230 | each of which is an IPv6 numeric address and is separated by a white 231 | space character. 232 | .It Ic new_bcmcs_name 233 | A list of BCMCS server domain names. 234 | .El 235 | .Pp 236 | Note that the daemon does not always provide all the parameters. 237 | It sets an environment variable only when the corresponding 238 | configuration parameter is provided by the DHCPv6 server. 239 | .\" 240 | .Sh SEE ALSO 241 | .Xr daemon 3 , 242 | .Xr dhcp6c.conf 5 . 243 | .Rs 244 | .%A Ralph Droms, Editor 245 | .%D 2003 246 | .%T Dynamic Host Configuration Protocol for IPv6 (DHCPv6) 247 | .%R RFC 3315 248 | .Re 249 | .\" 250 | .Sh HISTORY 251 | The 252 | .Nm 253 | command first appeared in WIDE/KAME IPv6 protocol stack kit. 254 | .\" 255 | .Sh BUGS 256 | .Nm 257 | is incomplete and violates DHCPv6 protocol spec, in several aspects. 258 | In particular, temporary address assignment is intentionally omitted. 259 | .Pp 260 | Information Refresh Time Option is not recognied in Info-req mode, since 261 | .Nm 262 | terminates after it receives a REPLY message. 263 | -------------------------------------------------------------------------------- /dhcp6c.conf.sample: -------------------------------------------------------------------------------- 1 | # The following is an example for use with IPv6 auto-configuration. 2 | # The "information-only" statement makes dhcp6c exchange informational 3 | # configuration parameters with servers. A list of DNS server addresses 4 | # is an example of such parameters. This statement is useful when the 5 | # client does not need stateful configuration parameters such as IPv6 6 | # addresses or prefixes. 7 | 8 | interface ne0 { 9 | information-only; 10 | }; 11 | 12 | 13 | # The following is a sample configuration for a client on a LAN 14 | # where IPv6 addresses are assigned via DHCPv6 ("stateful address 15 | # assignment"). Use this if you want the client to query the 16 | # DHCPv6 server for an IPv6 address and for DNS servers, as in 17 | # traditional IPv4 DHCP. 18 | 19 | interface em0 { 20 | send ia-na 0; 21 | send rapid-commit; 22 | send domain-name-servers; 23 | }; 24 | 25 | id-assoc na { 26 | }; 27 | 28 | # The following is an example configuration for delegation of an IPv6 prefix 29 | # from an upstream service provider. With this configuration dhcp6c will 30 | # send solicit messages containing an IA_PD option, with an IAID 0, on to 31 | # an upstream PPP link, ppp0. After receiving some prefixes from a server, 32 | # dhcp6c will then configure derived IPv6 prefixes with the SLA ID 1 on a 33 | # local ethernet interface, ne0. Note that the IAID for the id-assoc 34 | # statement is 0 according to the default. 35 | 36 | interface ppp0 { 37 | send ia-pd 0; 38 | }; 39 | 40 | id-assoc pd { 41 | prefix-interface ne0 { 42 | sla-id 1; 43 | }; 44 | }; 45 | 46 | # If a shared secret was to be configured in both the client and the server 47 | # for DHCPv6 authentication, it would be specified in this file as follows: 48 | 49 | keyinfo kame-key { 50 | realm "kame.net"; 51 | keyid 1; 52 | secret "5pvW2g48OHPvkYMJSw0vZA=="; 53 | }; 54 | 55 | # And the interface statement would be modified as follows: 56 | 57 | interface ppp0 { 58 | send ia-pd 0; 59 | send authentication kame; 60 | }; 61 | 62 | -------------------------------------------------------------------------------- /dhcp6c.h: -------------------------------------------------------------------------------- 1 | /* $KAME: dhcp6c.h,v 1.6 2004/09/04 09:26:38 jinmei Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2003 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | #ifndef _DHCP6C_H_ 32 | #define _DHCP6C_H_ 33 | 34 | #define DHCP6C_CONF SYSCONFDIR "/dhcp6c.conf" 35 | #define DHCP6C_PIDFILE "/var/run/dhcp6c.pid" 36 | #define DUID_FILE LOCALDBDIR "/dhcp6c_duid" 37 | 38 | struct dhcp6_timer *client6_timo(void *); 39 | int client6_start(struct dhcp6_if *); 40 | void client6_send(struct dhcp6_event *); 41 | 42 | int client6_script(char *, int, struct dhcp6_optinfo *); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /dhcp6c_ia.h: -------------------------------------------------------------------------------- 1 | /* $KAME: dhcp6c_ia.h,v 1.6 2004/06/10 07:28:29 jinmei Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2003 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | #ifndef _DHCP6C_IA_H_ 32 | #define _DHCP6C_IA_H_ 33 | 34 | struct ia; /* this is an opaque type */ 35 | 36 | struct iactl { 37 | struct ia *iactl_ia; /* back pointer to IA */ 38 | 39 | /* callback function called when something may happen on the IA */ 40 | void (*callback)(struct ia *); 41 | 42 | /* common methods: */ 43 | int (*isvalid)(struct iactl *); 44 | uint32_t (*duration)(struct iactl *); 45 | int (*renew_data)(struct iactl *, struct dhcp6_ia *, 46 | struct dhcp6_eventdata **, struct dhcp6_eventdata *); 47 | int (*rebind_data)(struct iactl *, struct dhcp6_ia *, 48 | struct dhcp6_eventdata **, struct dhcp6_eventdata *); 49 | int (*release_data)(struct iactl *, struct dhcp6_ia *, 50 | struct dhcp6_eventdata **, struct dhcp6_eventdata *); 51 | int (*reestablish_data)(struct iactl *, struct dhcp6_ia *, 52 | struct dhcp6_eventdata **, struct dhcp6_eventdata *); 53 | void (*cleanup)(struct iactl *); 54 | }; 55 | 56 | void update_ia(iatype_t, struct dhcp6_list *, 57 | struct dhcp6_if *, struct duid *, struct authparam *); 58 | void release_all_ia(struct dhcp6_if *); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /dhcp6c_script.c: -------------------------------------------------------------------------------- 1 | /* $KAME: dhcp6c_script.c,v 1.11 2004/11/28 10:48:38 jinmei Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2003 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #if TIME_WITH_SYS_TIME 39 | # include 40 | # include 41 | #else 42 | # if HAVE_SYS_TIME_H 43 | # include 44 | # else 45 | # include 46 | # endif 47 | #endif 48 | 49 | #include 50 | 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | 59 | #include "dhcp6.h" 60 | #include "config.h" 61 | #include "dhcp6c.h" 62 | #include "common.h" 63 | 64 | static char sipserver_str[] = "new_sip_servers"; 65 | static char sipname_str[] = "new_sip_name"; 66 | static char dnsserver_str[] = "new_domain_name_servers"; 67 | static char dnsname_str[] = "new_domain_name"; 68 | static char ntpserver_str[] = "new_ntp_servers"; 69 | static char nisserver_str[] = "new_nis_servers"; 70 | static char nisname_str[] = "new_nis_name"; 71 | static char nispserver_str[] = "new_nisp_servers"; 72 | static char nispname_str[] = "new_nisp_name"; 73 | static char bcmcsserver_str[] = "new_bcmcs_servers"; 74 | static char bcmcsname_str[] = "new_bcmcs_name"; 75 | static char raw_dhcp_option_str[] = "raw_dhcp_option"; 76 | 77 | int client6_script(char *, int, struct dhcp6_optinfo *); 78 | 79 | int 80 | client6_script(char *scriptpath, int state, struct dhcp6_optinfo *optinfo) 81 | { 82 | int i, dnsservers, ntpservers, dnsnamelen, envc, elen, ret = 0; 83 | int sipservers, sipnamelen; 84 | int nisservers, nisnamelen; 85 | int nispservers, nispnamelen; 86 | int bcmcsservers, bcmcsnamelen; 87 | int prefixes; 88 | char **envp, *s; 89 | char reason[32]; 90 | char prefixinfo[32] = "\0"; 91 | struct dhcp6_listval *v; 92 | struct dhcp6_event ev; 93 | struct rawoption *rawop; 94 | pid_t pid, wpid; 95 | struct dhcp6_listval *iav, *siav; 96 | 97 | /* if a script is not specified, do nothing */ 98 | if (scriptpath == NULL || strlen(scriptpath) == 0) 99 | return -1; 100 | d_printf(LOG_DEBUG, FNAME, "executes %s", scriptpath); 101 | 102 | ev.state = state; 103 | 104 | /* initialize counters */ 105 | dnsservers = 0; 106 | ntpservers = 0; 107 | dnsnamelen = 0; 108 | sipservers = 0; 109 | sipnamelen = 0; 110 | nisservers = 0; 111 | nisnamelen = 0; 112 | nispservers = 0; 113 | nispnamelen = 0; 114 | bcmcsservers = 0; 115 | bcmcsnamelen = 0; 116 | prefixes = 0; 117 | envc = 2; /* we at least include the reason and the terminator */ 118 | if (state == DHCP6S_EXIT) 119 | goto setenv; 120 | 121 | /* count the number of variables */ 122 | for (v = TAILQ_FIRST(&optinfo->dns_list); v; v = TAILQ_NEXT(v, link)) 123 | dnsservers++; 124 | envc += dnsservers ? 1 : 0; 125 | for (v = TAILQ_FIRST(&optinfo->dnsname_list); v; 126 | v = TAILQ_NEXT(v, link)) { 127 | dnsnamelen += v->val_vbuf.dv_len; 128 | } 129 | envc += dnsnamelen ? 1 : 0; 130 | for (v = TAILQ_FIRST(&optinfo->ntp_list); v; v = TAILQ_NEXT(v, link)) 131 | ntpservers++; 132 | envc += ntpservers ? 1 : 0; 133 | for (v = TAILQ_FIRST(&optinfo->sip_list); v; v = TAILQ_NEXT(v, link)) 134 | sipservers++; 135 | envc += sipservers ? 1 : 0; 136 | for (v = TAILQ_FIRST(&optinfo->sipname_list); v; 137 | v = TAILQ_NEXT(v, link)) { 138 | sipnamelen += v->val_vbuf.dv_len; 139 | } 140 | envc += sipnamelen ? 1 : 0; 141 | 142 | for (v = TAILQ_FIRST(&optinfo->nis_list); v; v = TAILQ_NEXT(v, link)) 143 | nisservers++; 144 | envc += nisservers ? 1 : 0; 145 | for (v = TAILQ_FIRST(&optinfo->nisname_list); v; 146 | v = TAILQ_NEXT(v, link)) { 147 | nisnamelen += v->val_vbuf.dv_len; 148 | } 149 | envc += nisnamelen ? 1 : 0; 150 | 151 | for (v = TAILQ_FIRST(&optinfo->nisp_list); v; v = TAILQ_NEXT(v, link)) 152 | nispservers++; 153 | envc += nispservers ? 1 : 0; 154 | for (v = TAILQ_FIRST(&optinfo->nispname_list); v; 155 | v = TAILQ_NEXT(v, link)) { 156 | nispnamelen += v->val_vbuf.dv_len; 157 | } 158 | envc += nispnamelen ? 1 : 0; 159 | 160 | for (v = TAILQ_FIRST(&optinfo->bcmcs_list); v; v = TAILQ_NEXT(v, link)) 161 | bcmcsservers++; 162 | envc += bcmcsservers ? 1 : 0; 163 | for (v = TAILQ_FIRST(&optinfo->bcmcsname_list); v; 164 | v = TAILQ_NEXT(v, link)) { 165 | bcmcsnamelen += v->val_vbuf.dv_len; 166 | } 167 | envc += bcmcsnamelen ? 1 : 0; 168 | 169 | for (iav = TAILQ_FIRST(&optinfo->iapd_list); iav; iav = TAILQ_NEXT(iav, link)) { 170 | for (siav = TAILQ_FIRST(&iav->sublist); siav; siav = TAILQ_NEXT(siav, link)) { 171 | if (siav->type == DHCP6_LISTVAL_PREFIX6) { 172 | prefixes += 1; 173 | } 174 | } 175 | } 176 | envc += prefixes ? 1 : 0; 177 | 178 | setenv: 179 | /* allocate an environments array */ 180 | if ((envp = malloc(sizeof (char *) * envc)) == NULL) { 181 | d_printf(LOG_NOTICE, FNAME, 182 | "failed to allocate environment buffer"); 183 | return -1; 184 | } 185 | memset(envp, 0, sizeof (char *) * envc); 186 | 187 | /* 188 | * Copy the parameters as environment variables 189 | */ 190 | snprintf(reason, sizeof(reason), "REASON=%s", 191 | dhcp6_event_statestr(&ev)); 192 | i = 0; 193 | /* reason */ 194 | if ((envp[i++] = strdup(reason)) == NULL) { 195 | d_printf(LOG_NOTICE, FNAME, 196 | "failed to allocate reason strings"); 197 | ret = -1; 198 | goto clean; 199 | } 200 | if (state == DHCP6S_EXIT) 201 | goto launch; 202 | 203 | /* "var=addr1 addr2 ... addrN" + null char for termination */ 204 | if (dnsservers) { 205 | elen = sizeof (dnsserver_str) + 206 | (INET6_ADDRSTRLEN + 1) * dnsservers + 1; 207 | if ((s = envp[i++] = malloc(elen)) == NULL) { 208 | d_printf(LOG_NOTICE, FNAME, 209 | "failed to allocate strings for DNS servers"); 210 | ret = -1; 211 | goto clean; 212 | } 213 | memset(s, 0, elen); 214 | snprintf(s, elen, "%s=", dnsserver_str); 215 | for (v = TAILQ_FIRST(&optinfo->dns_list); v; 216 | v = TAILQ_NEXT(v, link)) { 217 | char *addr; 218 | 219 | addr = in6addr2str(&v->val_addr6, 0); 220 | strlcat(s, addr, elen); 221 | strlcat(s, " ", elen); 222 | } 223 | } 224 | if (ntpservers) { 225 | elen = sizeof (ntpserver_str) + 226 | (INET6_ADDRSTRLEN + 1) * ntpservers + 1; 227 | if ((s = envp[i++] = malloc(elen)) == NULL) { 228 | d_printf(LOG_NOTICE, FNAME, 229 | "failed to allocate strings for NTP servers"); 230 | ret = -1; 231 | goto clean; 232 | } 233 | memset(s, 0, elen); 234 | snprintf(s, elen, "%s=", ntpserver_str); 235 | for (v = TAILQ_FIRST(&optinfo->ntp_list); v; 236 | v = TAILQ_NEXT(v, link)) { 237 | char *addr; 238 | 239 | addr = in6addr2str(&v->val_addr6, 0); 240 | strlcat(s, addr, elen); 241 | strlcat(s, " ", elen); 242 | } 243 | } 244 | 245 | if (dnsnamelen) { 246 | elen = sizeof (dnsname_str) + dnsnamelen + 1; 247 | if ((s = envp[i++] = malloc(elen)) == NULL) { 248 | d_printf(LOG_NOTICE, FNAME, 249 | "failed to allocate strings for DNS name"); 250 | ret = -1; 251 | goto clean; 252 | } 253 | memset(s, 0, elen); 254 | snprintf(s, elen, "%s=", dnsname_str); 255 | for (v = TAILQ_FIRST(&optinfo->dnsname_list); v; 256 | v = TAILQ_NEXT(v, link)) { 257 | strlcat(s, v->val_vbuf.dv_buf, elen); 258 | strlcat(s, " ", elen); 259 | } 260 | } 261 | 262 | if (sipservers) { 263 | elen = sizeof (sipserver_str) + 264 | (INET6_ADDRSTRLEN + 1) * sipservers + 1; 265 | if ((s = envp[i++] = malloc(elen)) == NULL) { 266 | d_printf(LOG_NOTICE, FNAME, 267 | "failed to allocate strings for SIP servers"); 268 | ret = -1; 269 | goto clean; 270 | } 271 | memset(s, 0, elen); 272 | snprintf(s, elen, "%s=", sipserver_str); 273 | for (v = TAILQ_FIRST(&optinfo->sip_list); v; 274 | v = TAILQ_NEXT(v, link)) { 275 | char *addr; 276 | 277 | addr = in6addr2str(&v->val_addr6, 0); 278 | strlcat(s, addr, elen); 279 | strlcat(s, " ", elen); 280 | } 281 | } 282 | if (sipnamelen) { 283 | elen = sizeof (sipname_str) + sipnamelen + 1; 284 | if ((s = envp[i++] = malloc(elen)) == NULL) { 285 | d_printf(LOG_NOTICE, FNAME, 286 | "failed to allocate strings for SIP domain name"); 287 | ret = -1; 288 | goto clean; 289 | } 290 | memset(s, 0, elen); 291 | snprintf(s, elen, "%s=", sipname_str); 292 | for (v = TAILQ_FIRST(&optinfo->sipname_list); v; 293 | v = TAILQ_NEXT(v, link)) { 294 | strlcat(s, v->val_vbuf.dv_buf, elen); 295 | strlcat(s, " ", elen); 296 | } 297 | } 298 | 299 | if (nisservers) { 300 | elen = sizeof (nisserver_str) + 301 | (INET6_ADDRSTRLEN + 1) * nisservers + 1; 302 | if ((s = envp[i++] = malloc(elen)) == NULL) { 303 | d_printf(LOG_NOTICE, FNAME, 304 | "failed to allocate strings for NIS servers"); 305 | ret = -1; 306 | goto clean; 307 | } 308 | memset(s, 0, elen); 309 | snprintf(s, elen, "%s=", nisserver_str); 310 | for (v = TAILQ_FIRST(&optinfo->nis_list); v; 311 | v = TAILQ_NEXT(v, link)) { 312 | char *addr; 313 | 314 | addr = in6addr2str(&v->val_addr6, 0); 315 | strlcat(s, addr, elen); 316 | strlcat(s, " ", elen); 317 | } 318 | } 319 | if (nisnamelen) { 320 | elen = sizeof (nisname_str) + nisnamelen + 1; 321 | if ((s = envp[i++] = malloc(elen)) == NULL) { 322 | d_printf(LOG_NOTICE, FNAME, 323 | "failed to allocate strings for NIS domain name"); 324 | ret = -1; 325 | goto clean; 326 | } 327 | memset(s, 0, elen); 328 | snprintf(s, elen, "%s=", nisname_str); 329 | for (v = TAILQ_FIRST(&optinfo->nisname_list); v; 330 | v = TAILQ_NEXT(v, link)) { 331 | strlcat(s, v->val_vbuf.dv_buf, elen); 332 | strlcat(s, " ", elen); 333 | } 334 | } 335 | 336 | if (nispservers) { 337 | elen = sizeof (nispserver_str) + 338 | (INET6_ADDRSTRLEN + 1) * nispservers + 1; 339 | if ((s = envp[i++] = malloc(elen)) == NULL) { 340 | d_printf(LOG_NOTICE, FNAME, 341 | "failed to allocate strings for NIS+ servers"); 342 | ret = -1; 343 | goto clean; 344 | } 345 | memset(s, 0, elen); 346 | snprintf(s, elen, "%s=", nispserver_str); 347 | for (v = TAILQ_FIRST(&optinfo->nisp_list); v; 348 | v = TAILQ_NEXT(v, link)) { 349 | char *addr; 350 | 351 | addr = in6addr2str(&v->val_addr6, 0); 352 | strlcat(s, addr, elen); 353 | strlcat(s, " ", elen); 354 | } 355 | } 356 | if (nispnamelen) { 357 | elen = sizeof (nispname_str) + nispnamelen + 1; 358 | if ((s = envp[i++] = malloc(elen)) == NULL) { 359 | d_printf(LOG_NOTICE, FNAME, 360 | "failed to allocate strings for NIS+ domain name"); 361 | ret = -1; 362 | goto clean; 363 | } 364 | memset(s, 0, elen); 365 | snprintf(s, elen, "%s=", nispname_str); 366 | for (v = TAILQ_FIRST(&optinfo->nispname_list); v; 367 | v = TAILQ_NEXT(v, link)) { 368 | strlcat(s, v->val_vbuf.dv_buf, elen); 369 | strlcat(s, " ", elen); 370 | } 371 | } 372 | 373 | if (bcmcsservers) { 374 | elen = sizeof (bcmcsserver_str) + 375 | (INET6_ADDRSTRLEN + 1) * bcmcsservers + 1; 376 | if ((s = envp[i++] = malloc(elen)) == NULL) { 377 | d_printf(LOG_NOTICE, FNAME, 378 | "failed to allocate strings for BCMC servers"); 379 | ret = -1; 380 | goto clean; 381 | } 382 | memset(s, 0, elen); 383 | snprintf(s, elen, "%s=", bcmcsserver_str); 384 | for (v = TAILQ_FIRST(&optinfo->bcmcs_list); v; 385 | v = TAILQ_NEXT(v, link)) { 386 | char *addr; 387 | 388 | addr = in6addr2str(&v->val_addr6, 0); 389 | strlcat(s, addr, elen); 390 | strlcat(s, " ", elen); 391 | } 392 | } 393 | if (bcmcsnamelen) { 394 | elen = sizeof (bcmcsname_str) + bcmcsnamelen + 1; 395 | if ((s = envp[i++] = malloc(elen)) == NULL) { 396 | d_printf(LOG_NOTICE, FNAME, 397 | "failed to allocate strings for BCMC domain name"); 398 | ret = -1; 399 | goto clean; 400 | } 401 | memset(s, 0, elen); 402 | snprintf(s, elen, "%s=", bcmcsname_str); 403 | for (v = TAILQ_FIRST(&optinfo->bcmcsname_list); v; 404 | v = TAILQ_NEXT(v, link)) { 405 | strlcat(s, v->val_vbuf.dv_buf, elen); 406 | strlcat(s, " ", elen); 407 | } 408 | } 409 | 410 | if (prefixes) { 411 | #define PDINFO_MAX 64 412 | char *str = "PDINFO"; 413 | elen = sizeof (str) + PDINFO_MAX * prefixes + 1; 414 | if ((s = envp[i++] = malloc(elen)) == NULL) { 415 | d_printf(LOG_NOTICE, FNAME, 416 | "failed to allocate prefixinfo strings"); 417 | ret = -1; 418 | goto clean; 419 | } 420 | memset(s, 0, elen); 421 | snprintf(s, elen, "%s=", str); 422 | for (iav = TAILQ_FIRST(&optinfo->iapd_list); iav; iav = TAILQ_NEXT(iav, link)) { 423 | for (siav = TAILQ_FIRST(&iav->sublist); siav; siav = TAILQ_NEXT(siav, link)) { 424 | if (siav->type == DHCP6_LISTVAL_PREFIX6) { 425 | char prefixinfo[PDINFO_MAX]; 426 | 427 | snprintf(prefixinfo, sizeof(prefixinfo), 428 | "%s/%d", in6addr2str(&siav->val_prefix6.addr, 0), 429 | siav->val_prefix6.plen); 430 | 431 | strlcat(s, prefixinfo, elen); 432 | strlcat(s, " ", elen); 433 | } 434 | } 435 | } 436 | } 437 | 438 | /* XXX */ 439 | for (rawop = TAILQ_FIRST(&optinfo->rawops); rawop; rawop = TAILQ_NEXT(rawop, link)) { 440 | // max of 5 numbers after last underscore (seems like max DHCPv6 option could be 65535) 441 | elen = sizeof(raw_dhcp_option_str) + 1 /* underscore */ + 1 /* equals sign */ + 5; 442 | elen += rawop->datalen * 2; 443 | if ((s = envp[i++] = malloc(elen)) == NULL) { 444 | d_printf(LOG_NOTICE, FNAME, 445 | "failed to allocate string for DHCPv6 option %d", 446 | rawop->opnum); 447 | ret = -1; 448 | goto clean; 449 | } 450 | 451 | // make raw options available as raw_dhcp_option_xyz=hexresponse 452 | snprintf(s, elen, "%s_%d=", raw_dhcp_option_str, rawop->opnum); 453 | const char * hex = "0123456789abcdef"; 454 | char * val = (char*)malloc(3); 455 | for (int o = 0; o < rawop->datalen; o++) { 456 | val[0] = hex[(rawop->data[o]>>4) & 0x0F]; 457 | val[1] = hex[(rawop->data[o] ) & 0x0F]; 458 | val[2] = 0x00; 459 | strlcat(s, val, 1); 460 | } 461 | free(val); 462 | } 463 | launch: 464 | /* launch the script */ 465 | pid = fork(); 466 | if (pid < 0) { 467 | d_printf(LOG_ERR, FNAME, "failed to fork: %s", strerror(errno)); 468 | ret = -1; 469 | goto clean; 470 | } else if (pid) { 471 | int wstatus; 472 | 473 | do { 474 | wpid = wait(&wstatus); 475 | } while (wpid != pid && wpid > 0); 476 | 477 | if (wpid < 0) 478 | d_printf(LOG_ERR, FNAME, "wait: %s", strerror(errno)); 479 | else { 480 | d_printf(LOG_DEBUG, FNAME, 481 | "script \"%s\" terminated", scriptpath); 482 | } 483 | } else { 484 | char *argv[2]; 485 | int fd; 486 | 487 | argv[0] = scriptpath; 488 | argv[1] = NULL; 489 | 490 | if (safefile(scriptpath)) { 491 | d_printf(LOG_ERR, FNAME, 492 | "script \"%s\" cannot be executed safely", 493 | scriptpath); 494 | exit(1); 495 | } 496 | 497 | if (foreground == 0 && (fd = open("/dev/null", O_RDWR)) != -1) { 498 | dup2(fd, STDIN_FILENO); 499 | dup2(fd, STDOUT_FILENO); 500 | dup2(fd, STDERR_FILENO); 501 | if (fd > STDERR_FILENO) 502 | close(fd); 503 | } 504 | 505 | execve(scriptpath, argv, envp); 506 | 507 | d_printf(LOG_ERR, FNAME, "child: exec failed: %s", 508 | strerror(errno)); 509 | exit(0); 510 | } 511 | 512 | clean: 513 | for (i = 0; i < envc; i++) 514 | free(envp[i]); 515 | free(envp); 516 | 517 | return ret; 518 | } 519 | -------------------------------------------------------------------------------- /if.c: -------------------------------------------------------------------------------- 1 | /* $KAME: if.c,v 1.6 2005/09/16 11:30:15 suz Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2002 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | #ifdef __KAME__ 38 | #include 39 | #endif 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | #include "dhcp6.h" 49 | #include "config.h" 50 | #include "common.h" 51 | 52 | struct dhcp6_if *dhcp6_if; 53 | 54 | struct dhcp6_if * 55 | ifinit(char *ifname) 56 | { 57 | struct dhcp6_if *ifp; 58 | 59 | if ((ifp = find_ifconfbyname(ifname)) != NULL) { 60 | d_printf(LOG_NOTICE, FNAME, "duplicated interface: %s", ifname); 61 | return (ifp); 62 | } 63 | 64 | if ((ifp = malloc(sizeof(*ifp))) == NULL) { 65 | d_printf(LOG_ERR, FNAME, "malloc failed"); 66 | goto fail; 67 | } 68 | memset(ifp, 0, sizeof(*ifp)); 69 | 70 | TAILQ_INIT(&ifp->event_list); 71 | 72 | if ((ifp->ifname = strdup(ifname)) == NULL) { 73 | d_printf(LOG_ERR, FNAME, "failed to copy ifname"); 74 | goto fail; 75 | } 76 | 77 | if (ifreset(ifp)) 78 | goto fail; 79 | 80 | TAILQ_INIT(&ifp->reqopt_list); 81 | TAILQ_INIT(&ifp->iaconf_list); 82 | TAILQ_INIT(&ifp->rawops); 83 | 84 | ifp->authproto = DHCP6_AUTHPROTO_UNDEF; 85 | ifp->authalgorithm = DHCP6_AUTHALG_UNDEF; 86 | ifp->authrdm = DHCP6_AUTHRDM_UNDEF; 87 | 88 | { 89 | struct ifaddrs *ifa, *ifap; 90 | struct sockaddr_in6 *sin6; 91 | 92 | if (getifaddrs(&ifap) < 0) { 93 | d_printf(LOG_ERR, FNAME, "getifaddrs failed: %s", 94 | strerror(errno)); 95 | goto fail; 96 | } 97 | 98 | for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 99 | if (strcmp(ifa->ifa_name, ifname) != 0) 100 | continue; 101 | if (ifa->ifa_addr == NULL) 102 | continue; 103 | if (ifa->ifa_addr->sa_family != AF_INET6) 104 | continue; 105 | 106 | sin6 = (struct sockaddr_in6 *)(void *)ifa->ifa_addr; 107 | if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) 108 | continue; 109 | 110 | ifp->addr = sin6->sin6_addr; 111 | } 112 | 113 | freeifaddrs(ifap); 114 | } 115 | 116 | ifp->next = dhcp6_if; 117 | dhcp6_if = ifp; 118 | return (ifp); 119 | 120 | fail: 121 | if (ifp->ifname != NULL) 122 | free(ifp->ifname); 123 | free(ifp); 124 | return (NULL); 125 | } 126 | 127 | int 128 | ifreset(struct dhcp6_if *ifp) 129 | { 130 | unsigned int ifid; 131 | uint32_t linkid; 132 | 133 | if ((ifid = if_nametoindex(ifp->ifname)) == 0) { 134 | d_printf(LOG_ERR, FNAME, "invalid interface(%s): %s", 135 | ifp->ifname, strerror(errno)); 136 | return (-1); 137 | } 138 | 139 | #ifdef HAVE_SCOPELIB 140 | if (inet_zoneid(AF_INET6, 2, ifname, &linkid)) { 141 | d_printf(LOG_ERR, FNAME, "failed to get link ID for %s", 142 | ifname); 143 | return (-1); 144 | } 145 | #else 146 | linkid = ifid; /* XXX: assume 1to1 mapping IFs and links */ 147 | #endif 148 | 149 | ifp->ifid = ifid; 150 | ifp->linkid = linkid; 151 | 152 | return (0); 153 | } 154 | 155 | struct dhcp6_if * 156 | find_ifconfbyname(char *ifname) 157 | { 158 | struct dhcp6_if *ifp; 159 | 160 | for (ifp = dhcp6_if; ifp; ifp = ifp->next) { 161 | if (strcmp(ifp->ifname, ifname) == 0) 162 | return (ifp); 163 | } 164 | 165 | return (NULL); 166 | } 167 | 168 | struct dhcp6_if * 169 | find_ifconfbyid(unsigned int id) 170 | { 171 | struct dhcp6_if *ifp; 172 | 173 | for (ifp = dhcp6_if; ifp; ifp = ifp->next) { 174 | if (ifp->ifid == id) 175 | return (ifp); 176 | } 177 | 178 | return (NULL); 179 | } 180 | -------------------------------------------------------------------------------- /install-sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # install - install a program, script, or datafile 4 | # This comes from X11R5 (mit/util/scripts/install.sh). 5 | # 6 | # Copyright 1991 by the Massachusetts Institute of Technology 7 | # 8 | # Permission to use, copy, modify, distribute, and sell this software and its 9 | # documentation for any purpose is hereby granted without fee, provided that 10 | # the above copyright notice appear in all copies and that both that 11 | # copyright notice and this permission notice appear in supporting 12 | # documentation, and that the name of M.I.T. not be used in advertising or 13 | # publicity pertaining to distribution of the software without specific, 14 | # written prior permission. M.I.T. makes no representations about the 15 | # suitability of this software for any purpose. It is provided "as is" 16 | # without express or implied warranty. 17 | # 18 | # Calling this script install-sh is preferred over install.sh, to prevent 19 | # `make' implicit rules from creating a file called install from it 20 | # when there is no Makefile. 21 | # 22 | # This script is compatible with the BSD install script, but was written 23 | # from scratch. It can only install one file at a time, a restriction 24 | # shared with many OS's install programs. 25 | 26 | 27 | # set DOITPROG to echo to test this script 28 | 29 | # Don't use :- since 4.3BSD and earlier shells don't like it. 30 | doit="${DOITPROG-}" 31 | 32 | 33 | # put in absolute paths if you don't have them in your path; or use env. vars. 34 | 35 | mvprog="${MVPROG-mv}" 36 | cpprog="${CPPROG-cp}" 37 | chmodprog="${CHMODPROG-chmod}" 38 | chownprog="${CHOWNPROG-chown}" 39 | chgrpprog="${CHGRPPROG-chgrp}" 40 | stripprog="${STRIPPROG-strip}" 41 | rmprog="${RMPROG-rm}" 42 | mkdirprog="${MKDIRPROG-mkdir}" 43 | 44 | transformbasename="" 45 | transform_arg="" 46 | instcmd="$mvprog" 47 | chmodcmd="$chmodprog 0755" 48 | chowncmd="" 49 | chgrpcmd="" 50 | stripcmd="" 51 | rmcmd="$rmprog -f" 52 | mvcmd="$mvprog" 53 | src="" 54 | dst="" 55 | dir_arg="" 56 | 57 | while [ x"$1" != x ]; do 58 | case $1 in 59 | -c) instcmd="$cpprog" 60 | shift 61 | continue;; 62 | 63 | -d) dir_arg=true 64 | shift 65 | continue;; 66 | 67 | -m) chmodcmd="$chmodprog $2" 68 | shift 69 | shift 70 | continue;; 71 | 72 | -o) chowncmd="$chownprog $2" 73 | shift 74 | shift 75 | continue;; 76 | 77 | -g) chgrpcmd="$chgrpprog $2" 78 | shift 79 | shift 80 | continue;; 81 | 82 | -s) stripcmd="$stripprog" 83 | shift 84 | continue;; 85 | 86 | -t=*) transformarg=`echo $1 | sed 's/-t=//'` 87 | shift 88 | continue;; 89 | 90 | -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 91 | shift 92 | continue;; 93 | 94 | *) if [ x"$src" = x ] 95 | then 96 | src=$1 97 | else 98 | # this colon is to work around a 386BSD /bin/sh bug 99 | : 100 | dst=$1 101 | fi 102 | shift 103 | continue;; 104 | esac 105 | done 106 | 107 | if [ x"$src" = x ] 108 | then 109 | echo "install: no input file specified" 110 | exit 1 111 | else 112 | true 113 | fi 114 | 115 | if [ x"$dir_arg" != x ]; then 116 | dst=$src 117 | src="" 118 | 119 | if [ -d $dst ]; then 120 | instcmd=: 121 | else 122 | instcmd=mkdir 123 | fi 124 | else 125 | 126 | # Waiting for this to be detected by the "$instcmd $src $dsttmp" command 127 | # might cause directories to be created, which would be especially bad 128 | # if $src (and thus $dsttmp) contains '*'. 129 | 130 | if [ -f $src -o -d $src ] 131 | then 132 | true 133 | else 134 | echo "install: $src does not exist" 135 | exit 1 136 | fi 137 | 138 | if [ x"$dst" = x ] 139 | then 140 | echo "install: no destination specified" 141 | exit 1 142 | else 143 | true 144 | fi 145 | 146 | # If destination is a directory, append the input filename; if your system 147 | # does not like double slashes in filenames, you may need to add some logic 148 | 149 | if [ -d $dst ] 150 | then 151 | dst="$dst"/`basename $src` 152 | else 153 | true 154 | fi 155 | fi 156 | 157 | ## this sed command emulates the dirname command 158 | dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 159 | 160 | # Make sure that the destination directory exists. 161 | # this part is taken from Noah Friedman's mkinstalldirs script 162 | 163 | # Skip lots of stat calls in the usual case. 164 | if [ ! -d "$dstdir" ]; then 165 | defaultIFS=' 166 | ' 167 | IFS="${IFS-${defaultIFS}}" 168 | 169 | oIFS="${IFS}" 170 | # Some sh's can't handle IFS=/ for some reason. 171 | IFS='%' 172 | set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` 173 | IFS="${oIFS}" 174 | 175 | pathcomp='' 176 | 177 | while [ $# -ne 0 ] ; do 178 | pathcomp="${pathcomp}${1}" 179 | shift 180 | 181 | if [ ! -d "${pathcomp}" ] ; 182 | then 183 | $mkdirprog "${pathcomp}" 184 | else 185 | true 186 | fi 187 | 188 | pathcomp="${pathcomp}/" 189 | done 190 | fi 191 | 192 | if [ x"$dir_arg" != x ] 193 | then 194 | $doit $instcmd $dst && 195 | 196 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && 197 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && 198 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && 199 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi 200 | else 201 | 202 | # If we're going to rename the final executable, determine the name now. 203 | 204 | if [ x"$transformarg" = x ] 205 | then 206 | dstfile=`basename $dst` 207 | else 208 | dstfile=`basename $dst $transformbasename | 209 | sed $transformarg`$transformbasename 210 | fi 211 | 212 | # don't allow the sed command to completely eliminate the filename 213 | 214 | if [ x"$dstfile" = x ] 215 | then 216 | dstfile=`basename $dst` 217 | else 218 | true 219 | fi 220 | 221 | # Make a temp file name in the proper directory. 222 | 223 | dsttmp=$dstdir/#inst.$$# 224 | 225 | # Move or copy the file name to the temp name 226 | 227 | $doit $instcmd $src $dsttmp && 228 | 229 | trap "rm -f ${dsttmp}" 0 && 230 | 231 | # and set any options; do chmod last to preserve setuid bits 232 | 233 | # If any of these fail, we abort the whole thing. If we want to 234 | # ignore errors from any of these, just make sure not to ignore 235 | # errors from the above "$doit $instcmd $src $dsttmp" command. 236 | 237 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && 238 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && 239 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && 240 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && 241 | 242 | # Now rename the file to the real destination. 243 | 244 | $doit $rmcmd -f $dstdir/$dstfile && 245 | $doit $mvcmd $dsttmp $dstdir/$dstfile 246 | 247 | fi && 248 | 249 | 250 | exit 0 251 | -------------------------------------------------------------------------------- /lease.c: -------------------------------------------------------------------------------- 1 | #include 2 | /* 3 | * Copyright (C) 1998 and 1999 WIDE Project. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. Neither the name of the project nor the names of its contributors 15 | * may be used to endorse or promote products derived from this software 16 | * without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 | * SUCH DAMAGE. 29 | */ 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #if TIME_WITH_SYS_TIME 37 | # include 38 | # include 39 | #else 40 | # if HAVE_SYS_TIME_H 41 | # include 42 | # else 43 | # include 44 | # endif 45 | #endif 46 | #include 47 | #include "dhcp6.h" 48 | #include "config.h" 49 | #include "common.h" 50 | #include "lease.h" 51 | 52 | #ifndef FALSE 53 | #define FALSE 0 54 | #define TRUE !FALSE 55 | #endif 56 | 57 | struct hash_entry { 58 | LIST_ENTRY(hash_entry) list; 59 | char *val; 60 | char flag; /* 0x01: DHCP6_LEASE_DECLINED */ 61 | }; 62 | 63 | /* marked as declined (e.g. someone has been using the same address) */ 64 | #define DHCP6_LEASE_DECLINED 0x01 65 | 66 | LIST_HEAD(hash_head, hash_entry); 67 | 68 | typedef unsigned int (*pfn_hash_t)(void *val) ; 69 | typedef int (*pfh_hash_match_t)(void *val1, void *val2); 70 | 71 | struct hash_table { 72 | struct hash_head *table; 73 | unsigned int size; 74 | pfn_hash_t hash; 75 | pfh_hash_match_t match; 76 | }; 77 | 78 | #ifndef DHCP6_LEASE_TABLE_SIZE 79 | #define DHCP6_LEASE_TABLE_SIZE 256 80 | #endif 81 | 82 | static struct hash_table dhcp6_lease_table; 83 | 84 | static unsigned int in6_addr_hash(void *); 85 | static int in6_addr_match(void *, void *); 86 | 87 | static int hash_table_init(struct hash_table *, unsigned int, 88 | pfn_hash_t, pfh_hash_match_t); 89 | static void hash_table_cleanup(struct hash_table *); 90 | static int hash_table_add(struct hash_table *, void *, unsigned int); 91 | static int hash_table_remove(struct hash_table *, void *); 92 | static struct hash_entry * hash_table_find(struct hash_table *, void *); 93 | 94 | int 95 | lease_init(void) 96 | { 97 | d_printf(LOG_DEBUG, FNAME, "called"); 98 | 99 | if (hash_table_init(&dhcp6_lease_table, DHCP6_LEASE_TABLE_SIZE, 100 | in6_addr_hash, in6_addr_match) != 0) { 101 | return (-1); 102 | } 103 | 104 | return (0); 105 | } 106 | 107 | void 108 | lease_cleanup(void) 109 | { 110 | hash_table_cleanup(&dhcp6_lease_table); 111 | } 112 | 113 | int 114 | lease_address(struct in6_addr *addr) 115 | { 116 | if (!addr) 117 | return (FALSE); 118 | 119 | d_printf(LOG_DEBUG, FNAME, "addr=%s", in6addr2str(addr, 0)); 120 | 121 | if (hash_table_find(&dhcp6_lease_table, addr)) { 122 | d_printf(LOG_WARNING, FNAME, "already leased: %s", 123 | in6addr2str(addr, 0)); 124 | return (FALSE); 125 | } 126 | 127 | if (hash_table_add(&dhcp6_lease_table, addr, sizeof(*addr)) != 0) { 128 | return (FALSE); 129 | } 130 | 131 | return (TRUE); 132 | } 133 | 134 | void 135 | release_address(struct in6_addr *addr) 136 | { 137 | if (!addr) 138 | return; 139 | 140 | d_printf(LOG_DEBUG, FNAME, "addr=%s", in6addr2str(addr, 0)); 141 | 142 | if (hash_table_remove(&dhcp6_lease_table, addr) != 0) { 143 | d_printf(LOG_WARNING, FNAME, "not found: %s", in6addr2str(addr, 0)); 144 | } 145 | } 146 | 147 | void 148 | decline_address(struct in6_addr *addr) 149 | { 150 | struct hash_entry *entry; 151 | 152 | if (!addr) 153 | return; 154 | 155 | d_printf(LOG_DEBUG, FNAME, "addr=%s", in6addr2str(addr, 0)); 156 | 157 | entry = hash_table_find(&dhcp6_lease_table, addr); 158 | if (entry == NULL) { 159 | d_printf(LOG_WARNING, FNAME, "not found: %s", 160 | in6addr2str(addr, 0)); 161 | return; 162 | } 163 | 164 | entry->flag |= DHCP6_LEASE_DECLINED; 165 | } 166 | 167 | int 168 | is_leased(struct in6_addr *addr) 169 | { 170 | return (hash_table_find(&dhcp6_lease_table, addr) != NULL); 171 | } 172 | 173 | static unsigned int 174 | in6_addr_hash(void *val) 175 | { 176 | uint8_t *addr = ((struct in6_addr *)val)->s6_addr; 177 | unsigned int hash = 0; 178 | int i; 179 | 180 | for (i = 0; i < 16; i++) { 181 | hash += addr[i]; 182 | } 183 | 184 | return (hash); 185 | } 186 | 187 | static int 188 | in6_addr_match(void *val1, void *val2) 189 | { 190 | struct in6_addr * addr1 = val1; 191 | struct in6_addr * addr2 = val2; 192 | 193 | return (memcmp(addr1->s6_addr, addr2->s6_addr, 16) == 0); 194 | } 195 | 196 | /* 197 | * hash table 198 | */ 199 | static int 200 | hash_table_init(struct hash_table *table, unsigned int size, 201 | pfn_hash_t hash, pfh_hash_match_t match) 202 | { 203 | size_t i; 204 | 205 | if (!table || !hash || !match) { 206 | return (-1); 207 | } 208 | 209 | if ((table->table = malloc(sizeof(*table->table) * size)) == NULL) { 210 | return (-1); 211 | } 212 | 213 | for (i = 0; i < size; i++) 214 | LIST_INIT(&table->table[i]); 215 | 216 | table->size = size; 217 | table->hash = hash; 218 | table->match = match; 219 | 220 | return (0); 221 | } 222 | 223 | static void 224 | hash_table_cleanup(struct hash_table *table) 225 | { 226 | size_t i; 227 | 228 | if (!table) { 229 | return; 230 | } 231 | 232 | for (i = 0; i < table->size; i++) { 233 | while (!LIST_EMPTY(&table->table[i])) { 234 | struct hash_entry *entry = LIST_FIRST(&table->table[i]); 235 | LIST_REMOVE(entry, list); 236 | if (entry->val) 237 | free(entry->val); 238 | free(entry); 239 | } 240 | } 241 | free(table->table); 242 | memset(table, 0, sizeof(*table)); 243 | } 244 | 245 | static int 246 | hash_table_add(struct hash_table *table, void *val, unsigned int size) 247 | { 248 | struct hash_entry *entry = NULL; 249 | int i = 0; 250 | 251 | if (!table || !val) { 252 | return (-1); 253 | } 254 | 255 | if ((entry = malloc(sizeof(*entry))) == NULL) { 256 | return (-1); 257 | } 258 | memset(entry, 0, sizeof(*entry)); 259 | 260 | if ((entry->val = malloc(size)) == NULL) { 261 | return (-1); 262 | } 263 | memcpy(entry->val, val, size); 264 | 265 | i = table->hash(val) % table->size; 266 | LIST_INSERT_HEAD(&table->table[i], entry, list); 267 | 268 | return (0); 269 | } 270 | 271 | static int 272 | hash_table_remove(struct hash_table *table, void *val) 273 | { 274 | struct hash_entry *entry; 275 | 276 | if (!table || !val) { 277 | return (-1); 278 | } 279 | 280 | if ((entry = hash_table_find(table, val)) == NULL) { 281 | return (-1); 282 | } 283 | 284 | LIST_REMOVE(entry, list); 285 | if (entry->val) 286 | free(entry->val); 287 | free(entry); 288 | 289 | return (0); 290 | } 291 | 292 | static struct hash_entry * 293 | hash_table_find(struct hash_table *table, void *val) 294 | { 295 | struct hash_entry *entry; 296 | int i; 297 | 298 | if (!table || !val) { 299 | return (NULL); 300 | } 301 | 302 | i = table->hash(val) % table->size; 303 | LIST_FOREACH(entry, &table->table[i], list) 304 | { 305 | if (table->match(val, entry->val)) { 306 | return (entry); 307 | } 308 | } 309 | 310 | return (NULL); 311 | } 312 | 313 | -------------------------------------------------------------------------------- /lease.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 1998 and 1999 WIDE Project. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. Neither the name of the project nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef _LEASE_H_ 31 | #define _LEASE_H_ 32 | 33 | int lease_init(void); 34 | void lease_cleanup(void); 35 | int lease_address(struct in6_addr *); 36 | void release_address(struct in6_addr *); 37 | void decline_address(struct in6_addr *); 38 | int is_leased(struct in6_addr *); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /missing/daemon.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006 WIDE Project. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 3. Neither the name of the project nor the names of its contributors 13 | * may be used to endorse or promote products derived from this software 14 | * without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | int 34 | daemon(int nochdir, int noclose) 35 | { 36 | if (fork() != 0) 37 | _exit(0); 38 | if (nochdir == 0) 39 | (void) chdir("/"); 40 | if (noclose == 0) { 41 | (void) close(0); 42 | (void) open("/dev/null", O_RDWR); 43 | (void) dup2(0, 1); 44 | (void) dup2(0, 2); 45 | } 46 | (void) setsid(); 47 | if (fork() != 0) 48 | _exit(0); 49 | return (0); 50 | } 51 | -------------------------------------------------------------------------------- /missing/err.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006 WIDE Project. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 3. Neither the name of the project nor the names of its contributors 13 | * may be used to endorse or promote products derived from this software 14 | * without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | extern void err(int, const char *); 30 | /* PRINTFLIKE2 */ 31 | extern void errx(int, const char *, ...); 32 | /* PRINTFLIKE1 */ 33 | extern void warnx(const char *, ...); 34 | #define warn warnx 35 | -------------------------------------------------------------------------------- /missing/getifaddrs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006 WIDE Project. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 3. Neither the name of the project nor the names of its contributors 13 | * may be used to endorse or promote products derived from this software 14 | * without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include "ifaddrs.h" 38 | 39 | static int 40 | get_lifreq(int fd, struct lifreq **ifr_ret) 41 | { 42 | struct lifnum lifn; 43 | struct lifconf lifc; 44 | struct lifreq *lifrp; 45 | 46 | lifn.lifn_family = AF_UNSPEC; 47 | lifn.lifn_flags = 0; 48 | if (ioctl(fd, SIOCGLIFNUM, &lifn) == -1) 49 | lifn.lifn_count = 16; 50 | else 51 | lifn.lifn_count += 16; 52 | 53 | for (;;) { 54 | lifc.lifc_len = lifn.lifn_count * sizeof (*lifrp); 55 | lifrp = malloc(lifc.lifc_len); 56 | if (lifrp == NULL) 57 | return (-1); 58 | 59 | lifc.lifc_family = AF_UNSPEC; 60 | lifc.lifc_flags = 0; 61 | lifc.lifc_buf = (char *)lifrp; 62 | if (ioctl(fd, SIOCGLIFCONF, &lifc) == -1) { 63 | free(lifrp); 64 | if (errno == EINVAL) { 65 | lifn.lifn_count <<= 1; 66 | continue; 67 | } 68 | (void) close(fd); 69 | return (-1); 70 | } 71 | if (lifc.lifc_len < (lifn.lifn_count - 1) * sizeof (*lifrp)) 72 | break; 73 | free(lifrp); 74 | lifn.lifn_count <<= 1; 75 | } 76 | (void) close(fd); 77 | 78 | *ifr_ret = lifrp; 79 | 80 | return (lifc.lifc_len / sizeof (*lifrp)); 81 | } 82 | 83 | static size_t 84 | nbytes(const struct lifreq *lifrp, int nlif, size_t socklen) 85 | { 86 | size_t len = 0; 87 | size_t slen; 88 | 89 | while (nlif > 0) { 90 | slen = strlen(lifrp->lifr_name) + 1; 91 | len += sizeof (struct ifaddrs) + ((slen + 3) & ~3); 92 | len += 3 * socklen; 93 | lifrp++; 94 | nlif--; 95 | } 96 | return (len); 97 | } 98 | 99 | static struct sockaddr * 100 | addrcpy(struct sockaddr_storage *addr, char **bufp) 101 | { 102 | char *buf = *bufp; 103 | size_t len; 104 | 105 | len = addr->ss_family == AF_INET ? sizeof (struct sockaddr_in) : 106 | sizeof (struct sockaddr_in6); 107 | (void) memcpy(buf, addr, len); 108 | *bufp = buf + len; 109 | return ((struct sockaddr *)buf); 110 | } 111 | 112 | static int 113 | populate(struct ifaddrs *ifa, int fd, struct lifreq *lifrp, int nlif, int af, 114 | char **bufp) 115 | { 116 | char *buf = *bufp; 117 | size_t slen; 118 | 119 | while (nlif > 0) { 120 | ifa->ifa_next = (nlif > 1) ? ifa + 1 : NULL; 121 | (void) strcpy(ifa->ifa_name = buf, lifrp->lifr_name); 122 | slen = strlen(lifrp->lifr_name) + 1; 123 | buf += (slen + 3) & ~3; 124 | if (ioctl(fd, SIOCGLIFFLAGS, lifrp) == -1) 125 | ifa->ifa_flags = 0; 126 | else 127 | ifa->ifa_flags = lifrp->lifr_flags; 128 | if (ioctl(fd, SIOCGLIFADDR, lifrp) == -1) 129 | ifa->ifa_addr = NULL; 130 | else 131 | ifa->ifa_addr = addrcpy(&lifrp->lifr_addr, &buf); 132 | if (ioctl(fd, SIOCGLIFNETMASK, lifrp) == -1) 133 | ifa->ifa_netmask = NULL; 134 | else 135 | ifa->ifa_netmask = addrcpy(&lifrp->lifr_addr, &buf); 136 | if (ifa->ifa_flags & IFF_POINTOPOINT) { 137 | if (ioctl(fd, SIOCGLIFDSTADDR, lifrp) == -1) 138 | ifa->ifa_dstaddr = NULL; 139 | else 140 | ifa->ifa_dstaddr = 141 | addrcpy(&lifrp->lifr_dstaddr, &buf); 142 | } else if (ifa->ifa_flags & IFF_BROADCAST) { 143 | if (ioctl(fd, SIOCGLIFBRDADDR, lifrp) == -1) 144 | ifa->ifa_broadaddr = NULL; 145 | else 146 | ifa->ifa_broadaddr = 147 | addrcpy(&lifrp->lifr_broadaddr, &buf); 148 | } else { 149 | ifa->ifa_dstaddr = NULL; 150 | } 151 | 152 | ifa++; 153 | nlif--; 154 | lifrp++; 155 | } 156 | *bufp = buf; 157 | return (0); 158 | } 159 | 160 | int 161 | getifaddrs(struct ifaddrs **ifap) 162 | { 163 | int fd4, fd6; 164 | int nif4, nif6 = 0; 165 | struct lifreq *ifr4 = NULL; 166 | struct lifreq *ifr6 = NULL; 167 | struct ifaddrs *ifa = NULL; 168 | char *buf; 169 | 170 | if ((fd4 = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 171 | return (-1); 172 | if ((fd6 = socket(AF_INET6, SOCK_DGRAM, 0)) == -1 && 173 | errno != EAFNOSUPPORT) { 174 | (void) close(fd4); 175 | return (-1); 176 | } 177 | 178 | if ((nif4 = get_lifreq(fd4, &ifr4)) == -1 || 179 | (fd6 != -1 && (nif6 = get_lifreq(fd6, &ifr6)) == -1)) 180 | goto failure; 181 | 182 | if (nif4 == 0 && nif6 == 0) { 183 | *ifap = NULL; 184 | return (0); 185 | } 186 | 187 | ifa = malloc(nbytes(ifr4, nif4, sizeof (struct sockaddr_in)) + 188 | nbytes(ifr6, nif6, sizeof (struct sockaddr_in6))); 189 | if (ifa == NULL) 190 | goto failure; 191 | 192 | buf = (char *)(ifa + nif4 + nif6); 193 | 194 | if (populate(ifa, fd4, ifr4, nif4, AF_INET, &buf) == -1) 195 | goto failure; 196 | if (nif4 > 0 && nif6 > 0) 197 | ifa[nif4 - 1].ifa_next = ifa + nif4; 198 | if (populate(ifa + nif4, fd6, ifr6, nif6, AF_INET6, &buf) == -1) 199 | goto failure; 200 | 201 | return (0); 202 | 203 | failure: 204 | free(ifa); 205 | (void) close(fd4); 206 | if (fd6 != -1) 207 | (void) close(fd6); 208 | free(ifr4); 209 | free(ifr6); 210 | return (-1); 211 | } 212 | 213 | void 214 | freeifaddrs(struct ifaddrs *ifa) 215 | { 216 | free(ifa); 217 | } 218 | -------------------------------------------------------------------------------- /missing/ifaddrs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006 WIDE Project. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 3. Neither the name of the project nor the names of its contributors 13 | * may be used to endorse or promote products derived from this software 14 | * without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | 31 | #undef ifa_broadaddr 32 | #undef ifa_dstaddr 33 | struct ifaddrs { 34 | struct ifaddrs *ifa_next; /* Pointer to next struct */ 35 | char *ifa_name; /* Interface name */ 36 | uint64_t ifa_flags; /* Interface flags */ 37 | struct sockaddr *ifa_addr; /* Interface address */ 38 | struct sockaddr *ifa_netmask; /* Interface netmask */ 39 | struct sockaddr *ifa_dstaddr; /* P2P interface destination */ 40 | }; 41 | #define ifa_broadaddr ifa_dstaddr 42 | 43 | extern int getifaddrs(struct ifaddrs **); 44 | extern void freeifaddrs(struct ifaddrs *); 45 | -------------------------------------------------------------------------------- /missing/strlcat.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: strlcat.c,v 1.5 1999/09/20 04:39:47 lukem Exp $ */ 2 | /* from OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp */ 3 | 4 | /* 5 | * Copyright (c) 1998 Todd C. Miller 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 21 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 25 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 28 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #if defined(LIBC_SCCS) && !defined(lint) 33 | __RCSID("$NetBSD: strlcat.c,v 1.5 1999/09/20 04:39:47 lukem Exp $"); 34 | #endif /* LIBC_SCCS and not lint */ 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | /* 41 | * Appends src to string dst of size siz (unlike strncat, siz is the 42 | * full size of dst, not space left). At most siz-1 characters 43 | * will be copied. Always NUL terminates (unless siz == 0). 44 | * Returns strlen(src); if retval >= siz, truncation occurred. 45 | */ 46 | size_t 47 | strlcat(dst, src, siz) 48 | char *dst; 49 | const char *src; 50 | size_t siz; 51 | { 52 | register char *d = dst; 53 | register const char *s = src; 54 | register size_t n = siz; 55 | size_t dlen; 56 | 57 | /* Find the end of dst and adjust bytes left but don't go past end */ 58 | while (*d != '\0' && n-- != 0) 59 | d++; 60 | dlen = d - dst; 61 | n = siz - dlen; 62 | 63 | if (n == 0) 64 | return(dlen + strlen(s)); 65 | while (*s != '\0') { 66 | if (n != 1) { 67 | *d++ = *s; 68 | n--; 69 | } 70 | s++; 71 | } 72 | *d = '\0'; 73 | 74 | return(dlen + (s - src)); /* count does not include NUL */ 75 | } 76 | -------------------------------------------------------------------------------- /missing/strlcpy.c: -------------------------------------------------------------------------------- 1 | /* $NetBSD: strlcpy.c,v 1.5 1999/09/20 04:39:47 lukem Exp $ */ 2 | /* from OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp */ 3 | 4 | /* 5 | * Copyright (c) 1998 Todd C. Miller 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 21 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 25 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 28 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | #if defined(LIBC_SCCS) && !defined(lint) 33 | __RCSID("$NetBSD: strlcpy.c,v 1.5 1999/09/20 04:39:47 lukem Exp $"); 34 | #endif /* LIBC_SCCS and not lint */ 35 | 36 | #include 37 | #include 38 | #include 39 | 40 | /* 41 | * Copy src to string dst of size siz. At most siz-1 characters 42 | * will be copied. Always NUL terminates (unless siz == 0). 43 | * Returns strlen(src); if retval >= siz, truncation occurred. 44 | */ 45 | size_t 46 | strlcpy(dst, src, siz) 47 | char *dst; 48 | const char *src; 49 | size_t siz; 50 | { 51 | register char *d = dst; 52 | register const char *s = src; 53 | register size_t n = siz; 54 | 55 | /* Copy as many bytes as will fit */ 56 | if (n != 0 && --n != 0) { 57 | do { 58 | if ((*d++ = *s++) == 0) 59 | break; 60 | } while (--n != 0); 61 | } 62 | 63 | /* Not enough room in dst, add NUL and traverse rest of src */ 64 | if (n == 0) { 65 | if (siz != 0) 66 | *d = '\0'; /* NUL-terminate dst */ 67 | while (*s++) 68 | ; 69 | } 70 | 71 | return(s - src - 1); /* count does not include NUL */ 72 | } 73 | -------------------------------------------------------------------------------- /missing/sys/queue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1991, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. All advertising materials mentioning features or use of this software 14 | * must display the following acknowledgement: 15 | * This product includes software developed by the University of 16 | * California, Berkeley and its contributors. 17 | * 4. Neither the name of the University nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | * SUCH DAMAGE. 32 | * 33 | * Adapted from FreeBSD sys/queue.h by James Carlson 34 | * 35 | * @(#)queue.h 8.5 (Berkeley) 8/20/94 36 | * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.6 2001/12/18 10:09:02 ru Exp $ 37 | */ 38 | 39 | /* 40 | * Tail queue declarations. 41 | */ 42 | #define TAILQ_HEAD(name, type) \ 43 | struct name { \ 44 | struct type *tqh_first; /* first element */ \ 45 | struct type **tqh_last; /* addr of last next element */ \ 46 | } 47 | 48 | #define TAILQ_ENTRY(type) \ 49 | struct { \ 50 | struct type *tqe_next; /* next element */ \ 51 | struct type **tqe_prev; /* address of previous next element */ \ 52 | } 53 | 54 | /* 55 | * Tail queue functions. 56 | */ 57 | #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) 58 | 59 | #define TAILQ_FIRST(head) ((head)->tqh_first) 60 | 61 | #define TAILQ_INIT(head) do { \ 62 | TAILQ_FIRST((head)) = NULL; \ 63 | (head)->tqh_last = &TAILQ_FIRST((head)); \ 64 | } while (0) 65 | 66 | #define TAILQ_INSERT_HEAD(head, elm, field) do { \ 67 | if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ 68 | TAILQ_FIRST((head))->field.tqe_prev = \ 69 | &TAILQ_NEXT((elm), field); \ 70 | else \ 71 | (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 72 | TAILQ_FIRST((head)) = (elm); \ 73 | (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ 74 | } while (0) 75 | 76 | #define TAILQ_INSERT_TAIL(head, elm, field) do { \ 77 | TAILQ_NEXT((elm), field) = NULL; \ 78 | (elm)->field.tqe_prev = (head)->tqh_last; \ 79 | *(head)->tqh_last = (elm); \ 80 | (head)->tqh_last = &TAILQ_NEXT((elm), field); \ 81 | } while (0) 82 | 83 | #define TAILQ_LAST(head, headname) \ 84 | (*(((struct headname *)((head)->tqh_last))->tqh_last)) 85 | 86 | #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) 87 | 88 | #define TAILQ_REMOVE(head, elm, field) do { \ 89 | if ((TAILQ_NEXT((elm), field)) != NULL) \ 90 | TAILQ_NEXT((elm), field)->field.tqe_prev = \ 91 | (elm)->field.tqe_prev; \ 92 | else \ 93 | (head)->tqh_last = (elm)->field.tqe_prev; \ 94 | *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ 95 | } while (0) 96 | 97 | /* 98 | * List declarations. 99 | */ 100 | #define LIST_HEAD(name, type) \ 101 | struct name { \ 102 | struct type *lh_first; /* first element */ \ 103 | } 104 | 105 | #define LIST_ENTRY(type) \ 106 | struct { \ 107 | struct type *le_next; /* next element */ \ 108 | struct type **le_prev; /* address of previous next element */ \ 109 | } 110 | 111 | /* 112 | * List functions. 113 | */ 114 | 115 | #define LIST_EMPTY(head) ((head)->lh_first == NULL) 116 | 117 | #define LIST_FIRST(head) ((head)->lh_first) 118 | 119 | #define LIST_INIT(head) do { \ 120 | LIST_FIRST((head)) = NULL; \ 121 | } while (0) 122 | 123 | #define LIST_INSERT_HEAD(head, elm, field) do { \ 124 | if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ 125 | LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ 126 | LIST_FIRST((head)) = (elm); \ 127 | (elm)->field.le_prev = &LIST_FIRST((head)); \ 128 | } while (0) 129 | 130 | #define LIST_NEXT(elm, field) ((elm)->field.le_next) 131 | 132 | #define LIST_REMOVE(elm, field) do { \ 133 | if (LIST_NEXT((elm), field) != NULL) \ 134 | LIST_NEXT((elm), field)->field.le_prev = \ 135 | (elm)->field.le_prev; \ 136 | *(elm)->field.le_prev = LIST_NEXT((elm), field); \ 137 | } while (0) 138 | -------------------------------------------------------------------------------- /missing/warnx.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006 WIDE Project. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 3. Neither the name of the project nor the names of its contributors 13 | * may be used to endorse or promote products derived from this software 14 | * without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 | * SUCH DAMAGE. 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | void 34 | err(int retv, const char *str) 35 | { 36 | (void) fprintf(stderr, "%s\n", str); 37 | exit(retv); 38 | } 39 | 40 | void 41 | errx(int retv, const char *fmt, ...) 42 | { 43 | va_list args; 44 | 45 | va_start(args, fmt); 46 | (void) vfprintf(stderr, fmt, args); 47 | va_end(args); 48 | exit(retv); 49 | } 50 | 51 | void 52 | warnx(const char *fmt, ...) 53 | { 54 | va_list args; 55 | 56 | va_start(args, fmt); 57 | (void) vfprintf(stderr, fmt, args); 58 | va_end(args); 59 | } 60 | -------------------------------------------------------------------------------- /prefixconf.c: -------------------------------------------------------------------------------- 1 | /* $KAME: prefixconf.c,v 1.33 2005/09/16 11:30:15 suz Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2002 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | #ifdef __FreeBSD__ 39 | #include 40 | #endif 41 | 42 | #include 43 | 44 | #ifdef __KAME__ 45 | #include 46 | #include 47 | #endif 48 | 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | 56 | #include "dhcp6.h" 57 | #include "config.h" 58 | #include "common.h" 59 | #include "timer.h" 60 | #include "dhcp6c.h" 61 | #include "dhcp6c_ia.h" 62 | #include "prefixconf.h" 63 | 64 | TAILQ_HEAD(siteprefix_list, siteprefix); 65 | struct iactl_pd { 66 | struct iactl common; 67 | struct pifc_list *pifc_head; 68 | struct siteprefix_list siteprefix_head; 69 | }; 70 | #define iacpd_ia common.iactl_ia 71 | #define iacpd_callback common.callback 72 | #define iacpd_isvalid common.isvalid 73 | #define iacpd_duration common.duration 74 | #define iacpd_renew_data common.renew_data 75 | #define iacpd_rebind_data common.rebind_data 76 | #define iacpd_reestablish_data common.reestablish_data 77 | #define iacpd_release_data common.release_data 78 | #define iacpd_cleanup common.cleanup 79 | 80 | struct siteprefix { 81 | TAILQ_ENTRY (siteprefix) link; 82 | 83 | struct dhcp6_prefix prefix; 84 | time_t updatetime; 85 | struct dhcp6_timer *timer; 86 | struct iactl_pd *ctl; 87 | TAILQ_HEAD(, dhcp6_ifprefix) ifprefix_list; /* interface prefixes */ 88 | }; 89 | 90 | struct dhcp6_ifprefix { 91 | TAILQ_ENTRY(dhcp6_ifprefix) plink; 92 | 93 | /* interface configuration */ 94 | struct prefix_ifconf *ifconf; 95 | 96 | /* interface prefix parameters */ 97 | struct sockaddr_in6 paddr; 98 | int plen; 99 | 100 | /* address assigned on the interface based on the prefix */ 101 | struct sockaddr_in6 ifaddr; 102 | }; 103 | 104 | static struct siteprefix *find_siteprefix(struct siteprefix_list *, 105 | struct dhcp6_prefix *, int); 106 | static void remove_siteprefix(struct siteprefix *); 107 | static int isvalid(struct iactl *); 108 | static uint32_t duration(struct iactl *); 109 | static void cleanup(struct iactl *); 110 | static int renew_prefix(struct iactl *, struct dhcp6_ia *, 111 | struct dhcp6_eventdata **, struct dhcp6_eventdata *); 112 | static void renew_data_free(struct dhcp6_eventdata *); 113 | 114 | static struct dhcp6_timer *siteprefix_timo(void *); 115 | 116 | static int add_ifprefix(struct siteprefix *, 117 | struct dhcp6_prefix *, struct prefix_ifconf *); 118 | 119 | static int pd_ifaddrconf(ifaddrconf_cmd_t, struct dhcp6_ifprefix *ifpfx); 120 | 121 | int 122 | update_prefix(struct ia *ia, struct dhcp6_prefix *pinfo, 123 | struct pifc_list *pifc, struct dhcp6_if *dhcpifp, 124 | struct iactl **ctlp, void (*callback)(struct ia *)) 125 | { 126 | struct iactl_pd *iac_pd = (struct iactl_pd *)*ctlp; 127 | struct siteprefix *sp; 128 | struct prefix_ifconf *pif; 129 | int spcreate = 0; 130 | struct timeval timo; 131 | 132 | /* 133 | * A client discards any addresses for which the preferred 134 | * lifetime is greater than the valid lifetime. 135 | * [RFC3315 22.6] 136 | */ 137 | if (pinfo->vltime != DHCP6_DURATION_INFINITE && 138 | (pinfo->pltime == DHCP6_DURATION_INFINITE || 139 | pinfo->pltime > pinfo->vltime)) { 140 | d_printf(LOG_INFO, FNAME, "invalid prefix %s/%d: " 141 | "pltime (%lu) is larger than vltime (%lu)", 142 | in6addr2str(&pinfo->addr, 0), pinfo->plen, 143 | pinfo->pltime, pinfo->vltime); 144 | return (-1); 145 | } 146 | 147 | if (iac_pd == NULL) { 148 | if ((iac_pd = malloc(sizeof(*iac_pd))) == NULL) { 149 | d_printf(LOG_NOTICE, FNAME, "memory allocation failed"); 150 | return (-1); 151 | } 152 | memset(iac_pd, 0, sizeof(*iac_pd)); 153 | iac_pd->iacpd_ia = ia; 154 | iac_pd->iacpd_callback = callback; 155 | iac_pd->iacpd_isvalid = isvalid; 156 | iac_pd->iacpd_duration = duration; 157 | iac_pd->iacpd_cleanup = cleanup; 158 | iac_pd->iacpd_renew_data = 159 | iac_pd->iacpd_rebind_data = 160 | iac_pd->iacpd_release_data = 161 | iac_pd->iacpd_reestablish_data = renew_prefix; 162 | 163 | iac_pd->pifc_head = pifc; 164 | TAILQ_INIT(&iac_pd->siteprefix_head); 165 | *ctlp = (struct iactl *)iac_pd; 166 | } 167 | 168 | /* search for the given prefix, and make a new one if it fails */ 169 | if ((sp = find_siteprefix(&iac_pd->siteprefix_head, pinfo, 1)) == NULL) { 170 | if ((sp = malloc(sizeof(*sp))) == NULL) { 171 | d_printf(LOG_NOTICE, FNAME, "memory allocation failed"); 172 | return (-1); 173 | } 174 | memset(sp, 0, sizeof(*sp)); 175 | sp->prefix.addr = pinfo->addr; 176 | sp->prefix.plen = pinfo->plen; 177 | sp->ctl = iac_pd; 178 | TAILQ_INIT(&sp->ifprefix_list); 179 | 180 | TAILQ_INSERT_TAIL(&iac_pd->siteprefix_head, sp, link); 181 | 182 | spcreate = 1; 183 | } 184 | 185 | /* update the timestamp of update */ 186 | sp->updatetime = time(NULL); 187 | 188 | /* update the prefix according to pinfo */ 189 | sp->prefix.pltime = pinfo->pltime; 190 | sp->prefix.vltime = pinfo->vltime; 191 | d_printf(LOG_DEBUG, FNAME, "%s a prefix %s/%d pltime=%lu, vltime=%lu", 192 | spcreate ? "create" : "update", 193 | in6addr2str(&pinfo->addr, 0), pinfo->plen, 194 | pinfo->pltime, pinfo->vltime); 195 | 196 | /* update prefix interfaces if necessary */ 197 | if (sp->prefix.vltime != 0 && spcreate) { 198 | for (pif = TAILQ_FIRST(iac_pd->pifc_head); pif; 199 | pif = TAILQ_NEXT(pif, link)) { 200 | add_ifprefix(sp, pinfo, pif); 201 | } 202 | } 203 | 204 | /* 205 | * If the new vltime is 0, this prefix immediately expires. 206 | * Otherwise, set up or update the associated timer. 207 | */ 208 | switch (sp->prefix.vltime) { 209 | case 0: 210 | remove_siteprefix(sp); 211 | break; 212 | case DHCP6_DURATION_INFINITE: 213 | if (sp->timer) 214 | dhcp6_remove_timer(&sp->timer); 215 | break; 216 | default: 217 | if (sp->timer == NULL) { 218 | sp->timer = dhcp6_add_timer(siteprefix_timo, sp); 219 | if (sp->timer == NULL) { 220 | d_printf(LOG_NOTICE, FNAME, 221 | "failed to add prefix timer"); 222 | remove_siteprefix(sp); /* XXX */ 223 | return (-1); 224 | } 225 | } 226 | /* update the timer */ 227 | timo.tv_sec = sp->prefix.vltime; 228 | timo.tv_usec = 0; 229 | 230 | dhcp6_set_timer(&timo, sp->timer); 231 | break; 232 | } 233 | 234 | return (0); 235 | } 236 | 237 | static struct siteprefix * 238 | find_siteprefix(struct siteprefix_list *head, struct dhcp6_prefix *prefix, 239 | int match_plen) 240 | { 241 | struct siteprefix *sp; 242 | 243 | for (sp = TAILQ_FIRST(head); sp; sp = TAILQ_NEXT(sp, link)) { 244 | if (!IN6_ARE_ADDR_EQUAL(&sp->prefix.addr, &prefix->addr)) 245 | continue; 246 | if (match_plen == 0 || sp->prefix.plen == prefix->plen) 247 | return (sp); 248 | } 249 | 250 | return (NULL); 251 | } 252 | 253 | static void 254 | remove_siteprefix(struct siteprefix *sp) 255 | { 256 | struct dhcp6_ifprefix *ip; 257 | 258 | d_printf(LOG_DEBUG, FNAME, "remove a site prefix %s/%d", 259 | in6addr2str(&sp->prefix.addr, 0), sp->prefix.plen); 260 | 261 | if (sp->timer) 262 | dhcp6_remove_timer(&sp->timer); 263 | 264 | /* remove all interface prefixes */ 265 | while ((ip = TAILQ_FIRST(&sp->ifprefix_list)) != NULL) { 266 | TAILQ_REMOVE(&sp->ifprefix_list, ip, plink); 267 | pd_ifaddrconf(IFADDRCONF_REMOVE, ip); 268 | free(ip); 269 | } 270 | 271 | TAILQ_REMOVE(&sp->ctl->siteprefix_head, sp, link); 272 | free(sp); 273 | } 274 | 275 | static int 276 | isvalid(struct iactl *iac) 277 | { 278 | struct iactl_pd *iac_pd = (struct iactl_pd *)iac; 279 | 280 | if (TAILQ_EMPTY(&iac_pd->siteprefix_head)) 281 | return (0); /* this IA is invalid */ 282 | return (1); 283 | } 284 | 285 | static uint32_t 286 | duration(struct iactl *iac) 287 | { 288 | struct iactl_pd *iac_pd = (struct iactl_pd *)iac; 289 | struct siteprefix *sp; 290 | uint32_t base = DHCP6_DURATION_INFINITE, pltime, passed; 291 | time_t now; 292 | 293 | /* Determine the smallest period until pltime expires. */ 294 | now = time(NULL); 295 | for (sp = TAILQ_FIRST(&iac_pd->siteprefix_head); sp; 296 | sp = TAILQ_NEXT(sp, link)) { 297 | passed = now > sp->updatetime ? 298 | (uint32_t)(now - sp->updatetime) : 0; 299 | pltime = sp->prefix.pltime > passed ? 300 | sp->prefix.pltime - passed : 0; 301 | 302 | if (base == DHCP6_DURATION_INFINITE || pltime < base) 303 | base = pltime; 304 | } 305 | 306 | return (base); 307 | } 308 | 309 | static void 310 | cleanup(struct iactl *iac) 311 | { 312 | struct iactl_pd *iac_pd = (struct iactl_pd *)iac; 313 | struct siteprefix *sp; 314 | 315 | while ((sp = TAILQ_FIRST(&iac_pd->siteprefix_head)) != NULL) { 316 | TAILQ_REMOVE(&iac_pd->siteprefix_head, sp, link); 317 | remove_siteprefix(sp); 318 | } 319 | 320 | free(iac); 321 | } 322 | 323 | static int 324 | renew_prefix(struct iactl *iac, struct dhcp6_ia *iaparam, 325 | struct dhcp6_eventdata **evdp, struct dhcp6_eventdata *evd) 326 | { 327 | struct iactl_pd *iac_pd = (struct iactl_pd *)iac; 328 | struct siteprefix *sp; 329 | struct dhcp6_list *ial = NULL, pl; 330 | 331 | TAILQ_INIT(&pl); 332 | for (sp = TAILQ_FIRST(&iac_pd->siteprefix_head); sp; 333 | sp = TAILQ_NEXT(sp, link)) { 334 | if (dhcp6_add_listval(&pl, DHCP6_LISTVAL_PREFIX6, 335 | &sp->prefix, NULL) == NULL) 336 | goto fail; 337 | } 338 | 339 | if ((ial = malloc(sizeof(*ial))) == NULL) 340 | goto fail; 341 | TAILQ_INIT(ial); 342 | if (dhcp6_add_listval(ial, DHCP6_LISTVAL_IAPD, iaparam, &pl) == NULL) 343 | goto fail; 344 | dhcp6_clear_list(&pl); 345 | 346 | evd->type = DHCP6_EVDATA_IAPD; 347 | evd->data = (void *)ial; 348 | evd->privdata = (void *)evdp; 349 | evd->destructor = renew_data_free; 350 | 351 | return (0); 352 | 353 | fail: 354 | dhcp6_clear_list(&pl); 355 | if (ial) 356 | free(ial); 357 | return (-1); 358 | } 359 | 360 | static void 361 | renew_data_free(struct dhcp6_eventdata *evd) 362 | { 363 | struct dhcp6_list *ial; 364 | 365 | if (evd->type != DHCP6_EVDATA_IAPD) { 366 | d_printf(LOG_ERR, FNAME, "assumption failure"); 367 | exit(1); 368 | } 369 | 370 | if (evd->privdata) 371 | *(struct dhcp6_eventdata **)evd->privdata = NULL; 372 | ial = (struct dhcp6_list *)evd->data; 373 | dhcp6_clear_list(ial); 374 | free(ial); 375 | } 376 | 377 | static struct dhcp6_timer * 378 | siteprefix_timo(void *arg) 379 | { 380 | struct siteprefix *sp = (struct siteprefix *)arg; 381 | struct ia *ia; 382 | void (*callback)(struct ia *); 383 | 384 | d_printf(LOG_DEBUG, FNAME, "prefix timeout for %s/%d", 385 | in6addr2str(&sp->prefix.addr, 0), sp->prefix.plen); 386 | 387 | ia = sp->ctl->iacpd_ia; 388 | callback = sp->ctl->iacpd_callback; 389 | 390 | if (sp->timer) 391 | dhcp6_remove_timer(&sp->timer); 392 | 393 | remove_siteprefix(sp); 394 | 395 | (*callback)(ia); 396 | 397 | return (NULL); 398 | } 399 | 400 | static int 401 | add_ifprefix(struct siteprefix *siteprefix, struct dhcp6_prefix *prefix, 402 | struct prefix_ifconf *pconf) 403 | { 404 | struct dhcp6_ifprefix *ifpfx = NULL; 405 | struct in6_addr *a; 406 | u_long sla_id; 407 | char *sp; 408 | int b, i; 409 | 410 | if ((ifpfx = malloc(sizeof(*ifpfx))) == NULL) { 411 | d_printf(LOG_NOTICE, FNAME, 412 | "failed to allocate memory for ifprefix"); 413 | return (-1); 414 | } 415 | memset(ifpfx, 0, sizeof(*ifpfx)); 416 | 417 | ifpfx->ifconf = pconf; 418 | 419 | ifpfx->paddr.sin6_family = AF_INET6; 420 | #ifdef HAVE_SA_LEN 421 | ifpfx->paddr.sin6_len = sizeof(struct sockaddr_in6); 422 | #endif 423 | ifpfx->paddr.sin6_addr = prefix->addr; 424 | 425 | /* 426 | * dave (bevhost) thinks this should fix it rather than 427 | * generare the error below "invalid prefix length" 428 | * this way the sla-len can be left out of the config file 429 | * and calculated when the prefix is received 430 | */ 431 | if (prefix->plen + pconf->ifid_len + pconf->sla_len > 128) { 432 | pconf->sla_len = 128 - pconf->ifid_len - prefix->plen; 433 | } 434 | 435 | ifpfx->plen = prefix->plen + pconf->sla_len; 436 | /* 437 | * XXX: our current implementation assumes ifid len is a multiple of 8 438 | */ 439 | if ((pconf->ifid_len % 8) != 0) { 440 | d_printf(LOG_ERR, FNAME, 441 | "assumption failure on the length of interface ID"); 442 | goto bad; 443 | } 444 | if (ifpfx->plen + pconf->ifid_len < 0 || 445 | ifpfx->plen + pconf->ifid_len > 128) { 446 | d_printf(LOG_INFO, FNAME, 447 | "invalid prefix length %d + %d + %d", 448 | prefix->plen, pconf->sla_len, pconf->ifid_len); 449 | goto bad; 450 | } 451 | 452 | /* copy prefix and SLA ID */ 453 | a = &ifpfx->paddr.sin6_addr; 454 | b = prefix->plen; 455 | for (i = 0, b = prefix->plen; b > 0; b -= 8, i++) 456 | a->s6_addr[i] = prefix->addr.s6_addr[i]; 457 | sla_id = htonl(pconf->sla_id); 458 | sp = ((char *)&sla_id + 3); 459 | i = (128 - pconf->ifid_len) / 8; 460 | for (b = pconf->sla_len; b > 7; b -= 8, sp--) 461 | a->s6_addr[--i] = *sp; 462 | if (b) 463 | a->s6_addr[--i] |= *sp; 464 | 465 | /* configure the corresponding address */ 466 | ifpfx->ifaddr = ifpfx->paddr; 467 | for (i = 15; i >= pconf->ifid_len / 8; i--) 468 | ifpfx->ifaddr.sin6_addr.s6_addr[i] = pconf->ifid[i]; 469 | if (pd_ifaddrconf(IFADDRCONF_ADD, ifpfx)) 470 | goto bad; 471 | 472 | /* TODO: send a control message for other processes */ 473 | 474 | TAILQ_INSERT_TAIL(&siteprefix->ifprefix_list, ifpfx, plink); 475 | 476 | return (0); 477 | 478 | bad: 479 | if (ifpfx) 480 | free(ifpfx); 481 | return (-1); 482 | } 483 | 484 | #ifndef ND6_INFINITE_LIFETIME 485 | #define ND6_INFINITE_LIFETIME 0xffffffff 486 | #endif 487 | 488 | static int 489 | pd_ifaddrconf(ifaddrconf_cmd_t cmd, struct dhcp6_ifprefix *ifpfx) 490 | { 491 | struct prefix_ifconf *pconf; 492 | 493 | pconf = ifpfx->ifconf; 494 | return (ifaddrconf(cmd, pconf->ifname, &ifpfx->ifaddr, ifpfx->plen, 495 | ND6_INFINITE_LIFETIME, ND6_INFINITE_LIFETIME)); 496 | } 497 | -------------------------------------------------------------------------------- /prefixconf.h: -------------------------------------------------------------------------------- 1 | /* $KAME: prefixconf.h,v 1.6 2005/03/02 07:20:14 suz Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2002 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | #ifndef _PREFIXCONF_H_ 32 | #define _PREFIXCONF_H_ 33 | 34 | typedef enum { PREFIX6S_ACTIVE, PREFIX6S_RENEW, 35 | PREFIX6S_REBIND} prefix6state_t; 36 | 37 | int update_prefix(struct ia *, struct dhcp6_prefix *, 38 | struct pifc_list *, struct dhcp6_if *, struct iactl **, 39 | void (*)(struct ia *)); 40 | int prefix6_add(struct dhcp6_if *, struct dhcp6_prefix *, 41 | struct duid *); 42 | int prefix6_update(struct dhcp6_event *, struct dhcp6_list *, 43 | struct duid *); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /timer.c: -------------------------------------------------------------------------------- 1 | /* $KAME: timer.c,v 1.6 2003/07/31 23:25:59 jinmei Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2002 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | #if defined(__NetBSD__) || defined(__OpenBSD__) 43 | #include 44 | #endif 45 | #include "dhcp6.h" 46 | #include "config.h" 47 | #include "common.h" 48 | #include "timer.h" 49 | 50 | #define MILLION 1000000 51 | 52 | static LIST_HEAD(, dhcp6_timer) timer_head; 53 | static struct timeval tm_sentinel; 54 | static struct timeval tm_max = {0x7fffffff, 0x7fffffff}; 55 | 56 | static void timeval_add(struct timeval *, struct timeval *, 57 | struct timeval *); 58 | 59 | void 60 | dhcp6_timer_init(void) 61 | { 62 | LIST_INIT(&timer_head); 63 | tm_sentinel = tm_max; 64 | } 65 | 66 | struct dhcp6_timer * 67 | dhcp6_add_timer(struct dhcp6_timer *(*timeout)(void *), void *timeodata) 68 | { 69 | struct dhcp6_timer *newtimer; 70 | 71 | if ((newtimer = malloc(sizeof(*newtimer))) == NULL) { 72 | d_printf(LOG_ERR, FNAME, "can't allocate memory"); 73 | return (NULL); 74 | } 75 | 76 | memset(newtimer, 0, sizeof(*newtimer)); 77 | 78 | if (timeout == NULL) { 79 | d_printf(LOG_ERR, FNAME, "timeout function unspecified"); 80 | exit(1); 81 | } 82 | newtimer->expire = timeout; 83 | newtimer->expire_data = timeodata; 84 | newtimer->tm = tm_max; 85 | 86 | LIST_INSERT_HEAD(&timer_head, newtimer, link); 87 | 88 | return (newtimer); 89 | } 90 | 91 | void 92 | dhcp6_remove_timer(struct dhcp6_timer **timer) 93 | { 94 | LIST_REMOVE(*timer, link); 95 | free(*timer); 96 | *timer = NULL; 97 | } 98 | 99 | void 100 | dhcp6_set_timer(struct timeval *tm, struct dhcp6_timer *timer) 101 | { 102 | struct timeval now; 103 | 104 | /* reset the timer */ 105 | gettimeofday(&now, NULL); 106 | 107 | timeval_add(&now, tm, &timer->tm); 108 | 109 | /* update the next expiration time */ 110 | if (TIMEVAL_LT(timer->tm, tm_sentinel)) 111 | tm_sentinel = timer->tm; 112 | 113 | return; 114 | } 115 | 116 | /* 117 | * Check expiration for each timer. If a timer is expired, 118 | * call the expire function for the timer and update the timer. 119 | * Return the next interval for select() call. 120 | */ 121 | struct timeval * 122 | dhcp6_check_timer(void) 123 | { 124 | static struct timeval returnval; 125 | struct timeval now; 126 | struct dhcp6_timer *tm, *tm_next; 127 | 128 | gettimeofday(&now, NULL); 129 | 130 | tm_sentinel = tm_max; 131 | for (tm = LIST_FIRST(&timer_head); tm; tm = tm_next) { 132 | tm_next = LIST_NEXT(tm, link); 133 | 134 | if (TIMEVAL_LEQ(tm->tm, now)) { 135 | if ((*tm->expire)(tm->expire_data) == NULL) 136 | continue; /* timer has been freed */ 137 | } 138 | 139 | if (TIMEVAL_LT(tm->tm, tm_sentinel)) 140 | tm_sentinel = tm->tm; 141 | } 142 | 143 | if (TIMEVAL_EQUAL(tm_max, tm_sentinel)) { 144 | /* no need to timeout */ 145 | return (NULL); 146 | } else if (TIMEVAL_LT(tm_sentinel, now)) { 147 | /* this may occur when the interval is too small */ 148 | returnval.tv_sec = returnval.tv_usec = 0; 149 | } else 150 | timeval_sub(&tm_sentinel, &now, &returnval); 151 | return (&returnval); 152 | } 153 | 154 | struct timeval * 155 | dhcp6_timer_rest(struct dhcp6_timer *timer) 156 | { 157 | struct timeval now; 158 | static struct timeval returnval; /* XXX */ 159 | 160 | gettimeofday(&now, NULL); 161 | if (TIMEVAL_LEQ(timer->tm, now)) { 162 | d_printf(LOG_DEBUG, FNAME, 163 | "a timer must be expired, but not yet"); 164 | returnval.tv_sec = returnval.tv_usec = 0; 165 | } else 166 | timeval_sub(&timer->tm, &now, &returnval); 167 | 168 | return (&returnval); 169 | } 170 | 171 | /* result = a + b */ 172 | static void 173 | timeval_add(struct timeval *a, struct timeval *b, struct timeval *result) 174 | { 175 | long l; 176 | 177 | if ((l = a->tv_usec + b->tv_usec) < MILLION) { 178 | result->tv_usec = l; 179 | result->tv_sec = a->tv_sec + b->tv_sec; 180 | } 181 | else { 182 | result->tv_usec = l - MILLION; 183 | result->tv_sec = a->tv_sec + b->tv_sec + 1; 184 | } 185 | } 186 | 187 | /* 188 | * result = a - b 189 | * XXX: this function assumes that a >= b. 190 | */ 191 | void 192 | timeval_sub(struct timeval *a, struct timeval *b, struct timeval *result) 193 | { 194 | long l; 195 | 196 | if ((l = a->tv_usec - b->tv_usec) >= 0) { 197 | result->tv_usec = l; 198 | result->tv_sec = a->tv_sec - b->tv_sec; 199 | } 200 | else { 201 | result->tv_usec = MILLION + l; 202 | result->tv_sec = a->tv_sec - b->tv_sec - 1; 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /timer.h: -------------------------------------------------------------------------------- 1 | /* $KAME: timer.h,v 1.1 2002/05/16 06:04:08 jinmei Exp $ */ 2 | 3 | /* 4 | * Copyright (C) 2002 WIDE Project. 5 | * All rights reserved. 6 | * 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. 18 | * 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. 30 | */ 31 | #ifndef _TIMER_H_ 32 | #define _TIMER_H_ 33 | 34 | /* a < b */ 35 | #define TIMEVAL_LT(a, b) (((a).tv_sec < (b).tv_sec) ||\ 36 | (((a).tv_sec == (b).tv_sec) && \ 37 | ((a).tv_usec < (b).tv_usec))) 38 | /* a <= b */ 39 | #define TIMEVAL_LEQ(a, b) (((a).tv_sec < (b).tv_sec) ||\ 40 | (((a).tv_sec == (b).tv_sec) &&\ 41 | ((a).tv_usec <= (b).tv_usec))) 42 | /* a == b */ 43 | #define TIMEVAL_EQUAL(a, b) ((a).tv_sec == (b).tv_sec &&\ 44 | (a).tv_usec == (b).tv_usec) 45 | 46 | struct dhcp6_timer { 47 | LIST_ENTRY(dhcp6_timer) link; 48 | 49 | struct timeval tm; 50 | 51 | struct dhcp6_timer *(*expire)(void *); 52 | void *expire_data; 53 | }; 54 | 55 | void dhcp6_timer_init(void); 56 | struct dhcp6_timer *dhcp6_add_timer(struct dhcp6_timer *(*)(void *), 57 | void *); 58 | void dhcp6_set_timer(struct timeval *, struct dhcp6_timer *); 59 | void dhcp6_remove_timer(struct dhcp6_timer **); 60 | struct timeval *dhcp6_check_timer(void); 61 | struct timeval *dhcp6_timer_rest(struct dhcp6_timer *); 62 | 63 | void timeval_sub(struct timeval *, struct timeval *, struct timeval *); 64 | 65 | #endif 66 | --------------------------------------------------------------------------------