diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/Makefile.am ./radvd/radvd/Makefile.am --- ../tools/radvd-0.7.2/Makefile.am Thu Nov 15 06:58:10 2001 +++ ./radvd/radvd/Makefile.am Fri May 23 12:45:41 2003 @@ -28,7 +28,8 @@ sbin_PROGRAMS = radvd radvdump radvd_SOURCES = $(COMMON_SRC) radvd.c timer.c send.c process.c interface.c \ - device.c device-common.c gram.y gram.h scanner.l + device.c device-common.c gram.y gram.h scanner.l \ + maptable.c list.c radvd_LDADD = -lfl EXTRA_radvd_SOURCES = device-linux.c device-bsd44.c YFLAGS = -d @@ -41,7 +42,7 @@ BUILT_SOURCES = device.c CLEANFILES = radvd.8 radvdump.8 radvd.conf.5 -DISTCLEANFILES = device.c +DISTCLEANFILES = device.c gram.c gram.h scanner.c SUFFIXES = .man diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/Makefile.in ./radvd/radvd/Makefile.in --- ../tools/radvd-0.7.2/Makefile.in Tue Oct 29 04:42:32 2002 +++ ./radvd/radvd/Makefile.in Mon Jun 23 13:23:36 2003 @@ -1,6 +1,6 @@ -# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am +# Makefile.in generated automatically by automake 1.4 from Makefile.am -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -95,23 +95,18 @@ AUTOMAKE_OPTIONS = 1.2 foreign -DEFS = -DPATH_RADVD_CONF=\"$(PATH_RADVD_CONF)\" \ - -DPATH_RADVD_LOG=\"$(PATH_RADVD_LOG)\" -DLOG_FACILITY=$(LOG_FACILITY) \ - -DPATH_RADVD_PID=\"$(PATH_RADVD_PID)\" \ - -DVERSION=\"$(VERSION)\" -DINET6=1 +DEFS = -DPATH_RADVD_CONF=\"$(PATH_RADVD_CONF)\" -DPATH_RADVD_LOG=\"$(PATH_RADVD_LOG)\" -DLOG_FACILITY=$(LOG_FACILITY) -DPATH_RADVD_PID=\"$(PATH_RADVD_PID)\" -DVERSION=\"$(VERSION)\" -DINET6=1 INCLUDES = -I$(srcdir) -I. ######################################################################## -COMMON_SRC = log.c socket.c recv.c util.c radvd.h defaults.h pathnames.h \ - includes.h +COMMON_SRC = log.c socket.c recv.c util.c radvd.h defaults.h pathnames.h includes.h sbin_PROGRAMS = radvd radvdump -radvd_SOURCES = $(COMMON_SRC) radvd.c timer.c send.c process.c interface.c \ - device.c device-common.c gram.y gram.h scanner.l +radvd_SOURCES = $(COMMON_SRC) radvd.c timer.c send.c process.c interface.c device.c device-common.c gram.y gram.h scanner.l maptable.c list.c radvd_LDADD = -lfl EXTRA_radvd_SOURCES = device-linux.c device-bsd44.c @@ -120,13 +115,12 @@ radvdump_SOURCES = $(COMMON_SRC) radvdump.c man_MANS = radvd.8 radvdump.8 radvd.conf.5 -EXTRA_DIST = radvd.8.man radvdump.8.man radvd.conf.5.man VERSION CHANGES \ - COPYRIGHT INTRO.html copyright.blurb radvd.conf.example +EXTRA_DIST = radvd.8.man radvdump.8.man radvd.conf.5.man VERSION CHANGES COPYRIGHT INTRO.html copyright.blurb radvd.conf.example BUILT_SOURCES = device.c CLEANFILES = radvd.8 radvdump.8 radvd.conf.5 -DISTCLEANFILES = device.c +DISTCLEANFILES = device.c gram.c gram.h scanner.c SUFFIXES = .man ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -139,7 +133,8 @@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ radvd_OBJECTS = log.o socket.o recv.o util.o radvd.o timer.o send.o \ -process.o interface.o device.o device-common.o gram.o scanner.o +process.o interface.o device.o device-common.o gram.o scanner.o \ +maptable.o list.o radvd_DEPENDENCIES = radvd_LDFLAGS = radvdump_OBJECTS = log.o socket.o recv.o util.o radvdump.o @@ -165,6 +160,11 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) GZIP_ENV = --best +DEP_FILES = .deps/device-bsd44.P .deps/device-common.P \ +.deps/device-linux.P .deps/device.P .deps/gram.P .deps/interface.P \ +.deps/list.P .deps/log.P .deps/maptable.P .deps/process.P .deps/radvd.P \ +.deps/radvdump.P .deps/recv.P .deps/scanner.P .deps/send.P \ +.deps/socket.P .deps/timer.P .deps/util.P SOURCES = $(radvd_SOURCES) $(EXTRA_radvd_SOURCES) $(radvdump_SOURCES) OBJECTS = $(radvd_OBJECTS) $(radvdump_OBJECTS) @@ -172,9 +172,9 @@ .SUFFIXES: .SUFFIXES: .S .c .l .man .o .s .y $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps Makefile + cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) cd $(top_builddir) \ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status @@ -239,9 +239,6 @@ rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ done -.c.o: - $(COMPILE) -c $< - .s.o: $(COMPILE) -c $< @@ -414,6 +411,11 @@ -rm -rf $(distdir) mkdir $(distdir) -chmod 777 $(distdir) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ @@ -426,6 +428,37 @@ done $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp info-am: info: info-am dvi-am: @@ -470,25 +503,27 @@ maintainer-clean-generic: -test -z "scannerlgramhgramc$(BUILT_SOURCES)" || rm -f scannerl gramh gramc $(BUILT_SOURCES) mostlyclean-am: mostlyclean-hdr mostlyclean-sbinPROGRAMS \ - mostlyclean-compile mostlyclean-tags \ + mostlyclean-compile mostlyclean-tags mostlyclean-depend \ mostlyclean-generic mostlyclean: mostlyclean-am clean-am: clean-hdr clean-sbinPROGRAMS clean-compile clean-tags \ - clean-generic mostlyclean-am + clean-depend clean-generic mostlyclean-am clean: clean-am distclean-am: distclean-hdr distclean-sbinPROGRAMS distclean-compile \ - distclean-tags distclean-generic clean-am + distclean-tags distclean-depend distclean-generic \ + clean-am distclean: distclean-am -rm -f config.status maintainer-clean-am: maintainer-clean-hdr maintainer-clean-sbinPROGRAMS \ maintainer-clean-compile maintainer-clean-tags \ - maintainer-clean-generic distclean-am + maintainer-clean-depend maintainer-clean-generic \ + distclean-am @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." @@ -502,12 +537,13 @@ clean-compile maintainer-clean-compile install-man5 uninstall-man5 \ install-man8 uninstall-man8 install-man uninstall-man tags \ mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \ -distdir info-am info dvi-am dvi check check-am installcheck-am \ -installcheck all-recursive-am install-exec-am install-exec \ -install-data-am install-data install-am install uninstall-am uninstall \ -all-redirect all-am all installdirs mostlyclean-generic \ -distclean-generic clean-generic maintainer-clean-generic clean \ -mostlyclean distclean maintainer-clean +distdir mostlyclean-depend distclean-depend clean-depend \ +maintainer-clean-depend info-am info dvi-am dvi check check-am \ +installcheck-am installcheck all-recursive-am install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean .man: diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/aclocal.m4 ./radvd/radvd/aclocal.m4 --- ../tools/radvd-0.7.2/aclocal.m4 Tue Oct 29 04:02:33 2002 +++ ./radvd/radvd/aclocal.m4 Wed Mar 12 14:03:18 2003 @@ -1,6 +1,6 @@ -dnl aclocal.m4 generated automatically by aclocal 1.4-p5 +dnl aclocal.m4 generated automatically by aclocal 1.4 -dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -19,7 +19,7 @@ dnl Usage: dnl AM_INIT_AUTOMAKE(package,version, [no-define]) -AC_DEFUN([AM_INIT_AUTOMAKE], +AC_DEFUN(AM_INIT_AUTOMAKE, [AC_REQUIRE([AC_PROG_INSTALL]) PACKAGE=[$1] AC_SUBST(PACKAGE) @@ -47,7 +47,7 @@ # Check to make sure that the build environment is sane. # -AC_DEFUN([AM_SANITY_CHECK], +AC_DEFUN(AM_SANITY_CHECK, [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 @@ -88,7 +88,7 @@ dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) dnl The program must properly implement --version. -AC_DEFUN([AM_MISSING_PROG], +AC_DEFUN(AM_MISSING_PROG, [AC_MSG_CHECKING(for working $2) # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. @@ -105,7 +105,7 @@ dnl AM_PROG_LEX dnl Look for flex, lex or missing, then run AC_PROG_LEX and AC_DECL_YYTEXT -AC_DEFUN([AM_PROG_LEX], +AC_DEFUN(AM_PROG_LEX, [missing_dir=ifelse([$1],,`cd $ac_aux_dir && pwd`,$1) AC_CHECK_PROGS(LEX, flex lex, "$missing_dir/missing flex") AC_PROG_LEX @@ -113,7 +113,7 @@ # Like AC_CONFIG_HEADER, but automatically create stamp file. -AC_DEFUN([AM_CONFIG_HEADER], +AC_DEFUN(AM_CONFIG_HEADER, [AC_PREREQ([2.12]) AC_CONFIG_HEADER([$1]) dnl When config.status generates a header, we must update the stamp-h file. diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/defaults.h ./radvd/radvd/defaults.h --- ../tools/radvd-0.7.2/defaults.h Fri Dec 28 18:38:44 2001 +++ ./radvd/radvd/defaults.h Fri Nov 28 15:31:36 2003 @@ -24,11 +24,15 @@ #define MSG_SIZE 4096 +#define EPSILON (1.0/10000.0) + /* Router Configuration Variables: */ /* For each multicast interface: */ +#define MAX2(X,Y) ( (( X ) >= ( Y )) ? ( X ) : ( Y )) + #define DFLT_AdvSendAdv 0 #define DFLT_MaxRtrAdvInterval 600 #define DFLT_MinRtrAdvInterval(iface) ((int)(0.33 * (double)(iface)->MaxRtrAdvInterval)) @@ -39,12 +43,20 @@ #define DFLT_AdvRetransTimer 0 #define DFLT_AdvCurHopLimit 64 /* as per RFC 1700 or the next incarnation of it :) */ -#define DFLT_AdvDefaultLifetime(iface) (3 * (iface)->MaxRtrAdvInterval) +#define DFLT_AdvDefaultLifetime(iface) MAX2(1, ((int)((3.0 * (iface)->MaxRtrAdvInterval) + 0.9999)) ) +#define DFLT_MinDelayBetweenRAs MIN_DELAY_BETWEEN_RAS +/* don't care bit for advertising if Iface is down*/ +#define DFLT_AdvIfDown 0 /* Options sent with RA */ #define DFLT_AdvSourceLLAddress 1 +/* Link Identifier advertisement */ +#define DFLT_AdvLinkID 0 +#define DFLT_LinkID 0 +#define DFLT_LinkIDAmbiguity 0 + /* Each prefix has an associated: */ #define DFLT_AdvValidLifetime 2592000 /* seconds */ @@ -61,6 +73,7 @@ #define MAX_INITIAL_RTR_ADVERTISEMENTS 3 #define MAX_FINAL_RTR_ADVERTISEMENTS 3 #define MIN_DELAY_BETWEEN_RAS 3 +#define MIN_DELAY_BETWEEN_RAS_MIPv6 (30.0/1000.0) #define MAX_RA_DELAY_TIME (1000.0/2.0) /* milliseconds */ /* Host constants: */ @@ -87,7 +100,7 @@ #define MAX_MaxRtrAdvInterval 1800 #define MIN_MinRtrAdvInterval 3 -#define MAX_MinRtrAdvInterval(iface) ((int)(0.75 * (double)(iface)->MaxRtrAdvInterval)) +#define MAX_MinRtrAdvInterval(iface) ((double)(0.75 * (double)(iface)->MaxRtrAdvInterval)) #define MIN_AdvDefaultLifetime(iface) ((iface)->MaxRtrAdvInterval) #define MAX_AdvDefaultLifetime 9000 @@ -108,6 +121,9 @@ #define DFLT_AdvHomeAgentFlag 0 #define DFLT_AdvIntervalOpt 0 #define DFLT_AdvHomeAgentInfo 0 +#define DFLT_FastRSResponse 0 +#define DFLT_NumFastRSReq 0 +#define DFLT_MaxFastRS 10 /* Option types (defined also at least in glibc 2.2's netinet/icmp6.h) */ @@ -136,14 +152,69 @@ #define AdvertisementInterval(iface) ((iface)->MaxRtrAdvInterval)) -#define MIN_MinRtrAdvInterval_MIPv6 (1.0/20.0) -#define MIN_MaxRtrAdvInterval_MIPv6 (3.0/2.0) +#define MIN_MinRtrAdvInterval_MIPv6 ((3.0/100.0) - EPSILON ) +#define MIN_MaxRtrAdvInterval_MIPv6 ((7.0/100.0) - EPSILON ) #define RTR_SOLICITATION_INTERVAL_MIPv6 1 /* Recommended value by MIPv6 */ +#define Cautious_MaxRtrAdvInterval (2.0/10.0) +#define Cautious_MaxRtrAdvInterval_Leeway (2.0/100.0) + #define MIN_HomeAgentLifetime 1 /* 0 must NOT be used */ #define MAX_HomeAgentLifetime 65520 /* 18.2 hours in secs */ /* #define MAX_RTR_SOLICITATIONS This MAY be ignored by MIPv6 */ +/* Hierarchical MobileIPv6 extensions, off by default */ + +#define DFLT_ReAdvHmip6MapInfo 0 +#define DFLT_RecvHmip6MapInfo 0 +#define DFLT_AdvHmip6MapInfo 0 + +/* Flags */ + +#ifndef ND_OPT_MAP +#define ND_OPT_MAP 201 /* temporary value for testing */ +/* Ref (2001-06-08) : http://www.iana.org/assignments/icmpv6-parameters */ +#endif + +#ifndef ND_OPT_MAP_FLAG_R /* Use Prefix for RCoA (R) */ +#define ND_OPT_MAP_FLAG_R 0x80 +#endif +#ifndef ND_OPT_MAP_FLAG_M /* Extended Mode (M) */ +#define ND_OPT_MAP_FLAG_M 0x40 +#endif +#ifndef ND_OPT_MAP_FLAG_I /* Privacy (I) */ +#define ND_OPT_MAP_FLAG_I 0x20 +#endif +#ifndef ND_OPT_MAP_FLAG_T /* Incorrect Topology (T) */ +#define ND_OPT_MAP_FLAG_T 0x10 +#endif +#ifndef ND_OPT_MAP_FLAG_P /* Packet Source Address (P)*/ +#define ND_OPT_MAP_FLAG_P 0x08 +#endif +#ifndef ND_OPT_MAP_FLAG_V /* Reverse Tunnel (V) */ +#define ND_OPT_MAP_FLAG_V 0x04 +#endif + + /* HMIPv6 MAP FLAGS */ +#define DFLT_MAP_RcoaPrefix 1 +#define DFLT_MAP_ExtendedMode ( ! ( DFLT_MAP_RcoaPrefix ) ) +#define DFLT_MAP_Privacy ( 0 && ( DFLT_MAP_RcoaPrefix ) ) +#define DFLT_MAP_Topology ( 0 && ( DFLT_MAP_ExtendedMode ) ) +#define DFLT_MAP_PacketSource 0 +#define DFLT_MAP_ReverseTunnel 0 +#define DFLT_MAP_Distance 1 +#define DFLT_MAP_Preference 7 +#define DFLT_MAP_ValidLifetime ( DFLT_AdvValidLifetime ) + +#define DFLT_MAP_lastUpdate ( (time_t) 0 ) +#define DFLT_MAP_srcIfIndex (-1) + + + /* MAP Propagation Table defaults */ + +#define DFLT_MAP_Table_looseStatic 0 +#define DFLT_MAP_Table_splitHorizon 0 +#define DFLT_MAP_Table_Nearest() ( time(NULL) + 5 ) /* 5 seconds time */ #endif diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/device-bsd44.c ./radvd/radvd/device-bsd44.c --- ../tools/radvd-0.7.2/device-bsd44.c Fri Jul 12 07:23:10 2002 +++ ./radvd/radvd/device-bsd44.c Mon Jun 23 13:23:36 2003 @@ -239,4 +239,13 @@ close( fd ); return 0; +} + +int init_netlink_sock(){ + return 0; +} + + +int neigh_add(int ifi, unsigned char *linkaddr, int len, struct in6_addr *addr){ + return 0; } diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/device-common.c ./radvd/radvd/device-common.c --- ../tools/radvd-0.7.2/device-common.c Wed Jan 2 22:01:11 2002 +++ ./radvd/radvd/device-common.c Mon Aug 12 15:21:16 2002 @@ -33,7 +33,7 @@ return (-1); } - if (!(ifr.ifr_flags & IFF_UP)) + if (!iface->AdvIfDown && !(ifr.ifr_flags & IFF_UP)) { log(LOG_ERR, "interface %s is not UP", iface->Name); return (-1); diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/device-linux.c ./radvd/radvd/device-linux.c --- ../tools/radvd-0.7.2/device-linux.c Fri Jul 12 07:23:10 2002 +++ ./radvd/radvd/device-linux.c Mon Jun 23 13:23:36 2003 @@ -19,10 +19,19 @@ #include #include /* for PATH_PROC_NET_IF_INET6 */ +/* rtnetlink */ +#include +#include +#include +#include +/* end rtnetlink */ + #ifndef IPV6_ADDR_LINKLOCAL #define IPV6_ADDR_LINKLOCAL 0x0020U #endif + +static int netlink_sock = -1; /* * this function gets the hardware type and address of an interface, * determines the link layer token length and checks it against @@ -122,11 +131,18 @@ str_addr, &if_idx, &plen, &scope, &dad_status, devname) != EOF) { - if (scope == IPV6_ADDR_LINKLOCAL && - strcmp(devname, iface->Name) == 0) + if(!strcmp(devname, iface->Name)){ + iface->if_index = if_idx; + if(ntohs(iface->if_addr.s6_addr32[0]) == 0xfe80){ + log(LOG_WARNING, + "linklocal address pre-configured for %s", + iface->Name); + return 0; + } + if (scope == IPV6_ADDR_LINKLOCAL) { struct in6_addr addr; - unsigned int ap; + unsigned int ap ; int i; for (i=0; i<16; i++) @@ -134,15 +150,14 @@ sscanf(str_addr + i * 2, "%02x", &ap); addr.s6_addr[i] = (unsigned char)ap; } - memcpy(&iface->if_addr, &addr, sizeof(addr)); - - iface->if_index = if_idx; + memcpy(&iface->if_addr, &addr, sizeof(struct in6_addr)); + /* iface->if_index = if_idx; */ fclose(fp); return 0; } } - - log(LOG_ERR, "no linklocal address configured for %s", iface->Name); + } + log(LOG_WARNING,"no linklocal address configured for %s",iface->Name); fclose(fp); return (-1); } @@ -239,4 +254,58 @@ close( fd ); return 0; +} + + +int init_netlink_socket(void){ + netlink_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); + + return netlink_sock; + +} + +int neigh_add(int ifi, unsigned char *linkaddr, int len, struct in6_addr *addr){ + static int sequence_number = 1; + struct nlmsghdr mh; + struct { + struct nlmsghdr nh; + struct ndmsg ndm; + char attrbuf[512]; + } req; + struct rtattr *rta; + unsigned int mtu = 1000; + int rval; + + memset(&req, 0, sizeof(req)); + + req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); + req.nh.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE/*|NLM_F_REPLACE*/; + req.nh.nlmsg_type = RTM_NEWNEIGH; + req.ndm.ndm_family = AF_INET6; + req.ndm.ndm_ifindex = ifi; + req.ndm.ndm_flags = 0; + req.ndm.ndm_state = NUD_STALE; + req.ndm.ndm_type = 0; /* ???*/ + + rta = (struct rtattr *)(((char *) &req) + + NLMSG_ALIGN(req.nh.nlmsg_len)); + rta->rta_type = NDA_DST; + rta->rta_len = RTA_LENGTH(sizeof(struct in6_addr)); + req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + + RTA_LENGTH(sizeof(struct in6_addr)); + memcpy(RTA_DATA(rta), &addr, sizeof (struct in6_addr)); + + rta = (struct rtattr *)(((char*) &req) + + NLMSG_ALIGN(req.nh.nlmsg_len)); + rta->rta_type = NDA_LLADDR; + rta->rta_len = RTA_LENGTH(len); + req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + + RTA_LENGTH(len); + memcpy(RTA_DATA(rta), linkaddr, len); + /* NDA_LLADDR */ + rval = send(netlink_sock, &req, req.nh.nlmsg_len,0); + + dlog(LOG_DEBUG,4,"RVAL = %d",rval); + + return (rval >= 0); } diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/gram.y ./radvd/radvd/gram.y --- ../tools/radvd-0.7.2/gram.y Wed Jan 2 22:01:11 2002 +++ ./radvd/radvd/gram.y Mon Jun 23 13:23:36 2003 @@ -22,6 +22,8 @@ extern struct Interface *IfaceList; struct Interface *iface = NULL; struct AdvPrefix *prefix = NULL; +struct MobilityAccessPoint *map = NULL; +struct in6_addr *linklocal = NULL; extern char *conf_file; extern int num_lines; @@ -46,6 +48,8 @@ %token T_INTERFACE %token T_PREFIX +%token T_MAP +%token T_LLADDR %token STRING %token NUMBER @@ -58,6 +62,7 @@ %token T_AdvSendAdvert %token T_MaxRtrAdvInterval %token T_MinRtrAdvInterval +%token T_MinDelayBetweenRAs %token T_AdvManagedFlag %token T_AdvOtherConfigFlag %token T_AdvLinkMTU @@ -66,6 +71,7 @@ %token T_AdvCurHopLimit %token T_AdvDefaultLifetime %token T_AdvSourceLLAddress +%token T_AdvIfDown %token T_AdvOnLink %token T_AdvAutonomous @@ -77,16 +83,37 @@ %token T_AdvIntervalOpt %token T_AdvHomeAgentInfo +%token T_FastRSResponse +%token T_MaxFastRS + +%token T_RecvHmip6MapInfo +%token T_AdvHmip6MapInfo +%token T_ReAdvHmip6MapInfo + %token T_Base6to4Interface %token T_UnicastOnly +%token T_HackAdvLinkID + %token T_HomeAgentPreference %token T_HomeAgentLifetime +%token T_MapDistance +%token T_MapPreference +%token T_MapExtendedMode +%token T_MapTopology +%token T_MapPrivacy +%token T_MapPacketSource +%token T_MapReverseTunnel +%token T_MapValidLifetime + %token T_BAD_TOKEN %type name %type prefixdef prefixlist +%type optionlist +%type mapdef maplist +%type lladdr %type number_or_infinity %union { @@ -97,6 +124,8 @@ struct in6_addr *addr; char *str; struct AdvPrefix *pinfo; + struct InterfaceOptions intfoptions; + struct MobilityAccessPoint *mapinfo; }; %% @@ -128,10 +157,14 @@ ABORT; if (check_iface(iface) < 0) ABORT; - if (setup_linklocal_addr(sock, iface) < 0) - ABORT; + if (setup_linklocal_addr(sock, iface) < 0){ + log(LOG_ERR,"NO link local/ifindex for interface"); + /* ABORT; */ + } if (setup_allrouters_membership(sock, iface) < 0) ABORT; + if (setup_hmipv6_iface(iface) < 0) + ABORT; iface->next = IfaceList; IfaceList = iface; @@ -163,9 +196,19 @@ } ; -ifaceparams : optional_ifacevlist prefixlist +ifaceparams : optional_ifacevlist + | optional_ifacevlist optionlist { - iface->AdvPrefixList = $2; + iface->AdvPrefixList = $2.plist; + + dlog(LOG_DEBUG, 4, "Setting AdvPrefixList %p %p :%p", + $2.plist, ($2.plist?$2.plist->next: 0), + iface->AdvPrefixList); + iface->Hmip6MapList = $2.mlist; + if($2.llocal){ + memcpy(&iface->if_addr, $2.llocal, + sizeof(struct in6_addr)); + } } ; @@ -185,6 +228,10 @@ { iface->MaxRtrAdvInterval = $2; } + | T_MinDelayBetweenRAs NUMBER ';' + { + iface->MinDelayBetweenRAs = $2; + } | T_MinRtrAdvInterval DECIMAL ';' { iface->MinRtrAdvInterval = $2; @@ -193,6 +240,10 @@ { iface->MaxRtrAdvInterval = $2; } + | T_MinDelayBetweenRAs DECIMAL ';' + { + iface->MinDelayBetweenRAs = $2; + } | T_AdvSendAdvert SWITCH ';' { iface->AdvSendAdvert = $2; @@ -229,6 +280,10 @@ { iface->AdvSourceLLAddress = $2; } + | T_AdvIfDown SWITCH ';' + { + iface->AdvIfDown = $2; + } | T_AdvIntervalOpt SWITCH ';' { iface->AdvIntervalOpt = $2; @@ -237,6 +292,18 @@ { iface->AdvHomeAgentInfo = $2; } + | T_RecvHmip6MapInfo SWITCH ';' + { + iface->RecvHmip6MapInfo = $2; + } + | T_AdvHmip6MapInfo SWITCH ';' + { + iface->AdvHmip6MapInfo = $2; + } + | T_ReAdvHmip6MapInfo SWITCH ';' + { + iface->ReAdvHmip6MapInfo = $2; + } | T_AdvHomeAgentFlag SWITCH ';' { iface->AdvHomeAgentFlag = $2; @@ -257,11 +324,81 @@ { iface->UnicastOnly = $2; } + | T_FastRSResponse SWITCH ';' + { + iface->FastRSResponse = $2; + } + | T_MaxFastRS NUMBER ';' + { + iface->MaxFastRS = $2; + } + | T_HackAdvLinkID NUMBER ';' + { + iface->AdvLinkID = 1; + iface->LinkID = $2; + iface->LinkIDAmbiguity = 0; + } + ; + +optionlist : prefixlist + { + $$.plist = $1; + $$.mlist = NULL; + $$.llocal = NULL; + prefix = NULL; + } + | maplist + { + $$.mlist = $1; + $$.plist = NULL; + $$.llocal = NULL; + map = NULL; + } + | lladdr + { + $$.mlist = NULL; + $$.plist = NULL; + $$.llocal = $1; + linklocal = NULL; + } + | optionlist prefixlist + { + $$.plist = prefixlist_combine($2, $1.plist); + dlog(LOG_DEBUG, 4, "Setting plist %p %p", $$.plist, + ($$.plist? $$.plist->next : 0 )); + $$.mlist = $1.mlist; + $$.llocal = $1.llocal; + prefix = NULL; + } + | optionlist maplist + { + $$.mlist = maplist_combine($2, $1.mlist); + $$.plist = $1.plist; + dlog(LOG_DEBUG, 4, "Setting plist %p %p", $$.plist, + ($$.plist? $$.plist->next : 0 )); + $$.llocal = $1.llocal; + map = NULL; + } + | optionlist lladdr + { + if($1.llocal){ + log(LOG_ERR, + "only one link local address per interface"); + ABORT; + } + $$.mlist = $1.mlist; + $$.plist = $1.plist; + dlog(LOG_DEBUG, 4, "Setting plist %p %p", $$.plist, + ($$.plist? $$.plist->next : 0 )); + $$.llocal = $2; + linklocal = NULL; + } ; prefixlist : prefixdef { $$ = $1; + $$->next = NULL; } | prefixlist prefixdef { @@ -359,6 +496,166 @@ } ; +maplist : mapdef + { + $$ = $1; + } + | maplist mapdef + { + $2->next = $1; + $$ = $2; + } + ; + +mapdef : maphead '{' optional_mapplist '}' ';' + { + + $$ = map; + map = NULL; + + /* check parameters as received from option list */ + + if(!$$->distance || ($$->distance > 15)){ + /* Invalid distance (Draft 5 HMIPv6) */ + log(LOG_ERR, "MapDistance must be in range [1,15]" + " in %s, line %d", + conf_file, num_lines); + ABORT; + } + if($$->preference > 15){ + /* Invalid Preference (Draft 5 HMIPv6) */ + log(LOG_ERR, "MapPreference must be in range [0,15]" + " in %s, line %d", + conf_file, num_lines); + ABORT; + } + if($$->ExtendedMode){ + /* check that only valid flags are set */ + if($$->Privacy){ + log(LOG_ERR, "MapPrivacy must not be set" + " in MapExtendedMode in %s, line %d", + conf_file, num_lines); + ABORT; + } + if($$->PacketSource){ + log(LOG_ERR, "MapPacketSource must not be set" + " in MapExtendedMode in %s, line %d", + conf_file, num_lines); + ABORT; + } + + } + else{ /* Basic Mode */ + /* Set RcoaPrefix */ + /* check that only valid flags are set */ + if($$->Topology){ + log(LOG_ERR, "MapTopology must not be set " + " unless MapExtendedMode is on in %s, line %d", + conf_file, num_lines); + ABORT; + } + } + + } + ; + +maphead : T_MAP IPV6ADDR /* '/' NUMBER */ + { + map = malloc(sizeof(struct MobilityAccessPoint)); + + if (map == NULL) { + log(LOG_CRIT, "malloc failed: %s", strerror(errno)); + ABORT; + } + + local_map_init_defaults(map); + + /*if ($4 > MAX_PrefixLen) + { + log(LOG_ERR, "invalid prefix length in %s, line %d", conf_file, num_lines); + ABORT; + } + + map->prefixLen = $4; */ + + memcpy(&map->globalAddress, $2, sizeof(struct in6_addr)); + } + ; + +optional_mapplist: /* empty */ + | mapplist + +mapplist : mapplist mapparms + | mapparms + ; + +mapparms : T_MapDistance NUMBER ';' + { + if(!$2 || ($2 > 15)){ + /* Invalid distance (Draft 5 HMIPv6) */ + log(LOG_ERR, "MapDistance must be in range [1,15]" + " in %s, line %d", + conf_file, num_lines); + ABORT; + } + map->distance = $2; + } + | T_MapPreference NUMBER ';' + { + if($2 > 15){ + /* Invalid Preference (Draft 5 HMIPv6) */ + log(LOG_ERR, "MapPreference must be in range [0,15]" + " in %s, line %d", + conf_file, num_lines); + ABORT; + } + map->preference = $2; + } + | T_MapExtendedMode SWITCH ';' + { + map->ExtendedMode = $2; + map->RcoaPrefix = ! ($2); + } + | T_MapTopology SWITCH ';' + { + /* Topology (T) IFF ExtendedMode (M) */ + map->Topology = $2; + } + | T_MapPrivacy SWITCH ';' + { + /* Privacy (I) IFF RcoaPrefix (R) */ + map->Privacy = $2; + } + | T_MapPacketSource SWITCH ';' + { + /* PacketSource (P) IF !ExtendedMode (!M) */ + map->PacketSource = $2; + } + | T_MapReverseTunnel SWITCH ';' + { + /* ReverseTunnel (V) IF ExtendedMode (M) */ + map->ReverseTunnel = $2; + } + | T_MapValidLifetime NUMBER ';' + { + map->validLifetime = $2; + } + ; + +lladdr : T_LLADDR IPV6ADDR /* '/' NUMBER */ ';' + { + linklocal = malloc(sizeof(struct in6_addr)); + + if (linklocal == NULL) { + log(LOG_CRIT,"malloc failed: %s", + strerror(errno)); + ABORT; + } + + memcpy(linklocal, $2, sizeof(struct in6_addr)); + $$ = linklocal; + } + ; number_or_infinity : NUMBER { $$ = $1; @@ -379,6 +676,8 @@ if (prefix) free(prefix); + if (map) + free(map); } static void diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/greg.notes ./radvd/radvd/greg.notes --- ../tools/radvd-0.7.2/greg.notes Thu Jan 1 10:00:00 1970 +++ ./radvd/radvd/greg.notes Tue Apr 9 14:44:05 2002 @@ -0,0 +1,108 @@ + + + + Created 3 HMIPv6 options for radvd.conf + +# +# Hierarchical MobileIPv6 +# + AdvHmip6MapInfo off; # Advertise Local MAP options? + RecvHmip6MapInfo off; # Receive MAP options from Neighbours + ReAdvHmip6MapInfo off; # Send Readvertised MAP options? + + AdvHmip6MapFlag: + + States: off/on + + Default: off + + When the AdvHmip6MapFlag is set 'on', advertisements of (local) interface + configured MAP information are advertised. + + This is the static MAP definitions indicated in the Hierarchical Draft. + + Multiple MAPs may be configured on each interface. + These each have a set of parameters and defaults. + + + In this fashion, Access Routers may advertise a static list of + maps, Each with their own options. unspecified parameters will + receive default values as follows: + + + MapDistance 2; #(Range:1-15, Default:1) + MapPreference 3; #(Range:0-15 (15=notavail), Default:7) + MapExtendedMode off ;#(Default:off) + # MapRcoaPrefix is same as (!MapExtendedMode) + MapTopology off; #(Default: off, requires MapExtendedMode) + MapPrivacy on; #(Default: off, requires !MapExtendedMode) + MapPacketSource off; #(Default: off, requires !MapExtendedMode) + MapValidLifetime 1200;#(Default: 2592000 seconds) + MapReverseTunnel off; + + sends MAPs out an interface without resorting to Authentication and + extension of trust. + + The MAP need not be on this host nor on the local link, and + the distance and preference parameters may be set to indicate this. + + ?? At threshold/load value degrade map preference ?? + + + RecvHmip6MapFlag: + + States: off/on + + Default: off + + This option allows this interface to accept advertised map options + from neighbouring routers (suitably authenticated) + + This will be sent out all other interfaces (split-horizon by default!?) + ?? do we need a MAP split horizon option? (Default on)?? + + + ?? Also, since we may receive the same MAP option from ourselves + how do we determine this? ?? + + ?? What happens if there is a change in routing topology and the metric goes + up?? do we still advertise at the old metric?? + + ?? Advertisement changes: change preference --> modify cache + with (significantly increased) lifetime --> update + + + ?? if not one interface is configured to readvertise, do not collect info? + (reset when reloading config)?? + + It is recommended that on wireless/mobile access interfaces + that this option is set to 'off' to prevent MAP spoofing. + + + ?? RecvMAP filters set to list of valid/invalidated prefixes?? + + ReAdvHmip6Info + + States: off/on + + Default: off + + Determines if the interface will readvertise dynamically learnt MAP + information. The MAP advertisement will have a higher distance metric + (by one) than that received originally + + ?? if not one interface is configured to receive, no readvertisig done + (reset when reloading config)?? + + ?? ReadvMAP filters set to list of valid/invalidated prefixes on + per interface basis?? + + order for implementation: + + Static local advertisement (Done: 23/10/2001) + + Reception of Dynamic MAP options + + Readvertisement of Dynamic MAP options. + + Router Renumbering With MAP/Propagate?? diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/icmp6.h.diff ./radvd/radvd/icmp6.h.diff --- ../tools/radvd-0.7.2/icmp6.h.diff Thu Jan 1 10:00:00 1970 +++ ./radvd/radvd/icmp6.h.diff Tue Feb 26 16:57:10 2002 @@ -0,0 +1,35 @@ +--- /usr/include/netinet/icmp6.h.orig Thu Oct 18 16:25:53 2001 ++++ /usr/include/netinet/icmp6.h Mon Feb 11 12:48:40 2002 +@@ -198,6 +198,8 @@ + #define ND_OPT_MTU 5 + #define ND_OPT_RTR_ADV_INTERVAL 7 + #define ND_OPT_HOME_AGENT_INFO 8 ++ /* Temporary for HMIPv6 */ ++#define ND_OPT_MAP 201 + + struct nd_opt_prefix_info /* prefix information */ + { +@@ -250,5 +252,23 @@ + int16_t nd_opt_home_agent_info_preference; + uint16_t nd_opt_home_agent_info_lifetime; + }; ++ ++/* Mobile IPv6 extension: Home Agent Info. */ ++struct nd_opt_map ++ { ++ uint8_t nd_opt_map_type; ++ uint8_t nd_opt_map_length; ++ uint8_t nd_opt_map_dist_pref; ++ uint8_t nd_opt_map_flags_reserved; ++ uint32_t nd_opt_map_valid_time; ++ struct in6_addr nd_opt_map_globaladdr; ++ }; ++ ++#define ND_OPT_MAP_FLAG_R 0x80 ++#define ND_OPT_MAP_FLAG_M 0x40 ++#define ND_OPT_MAP_FLAG_I 0x20 ++#define ND_OPT_MAP_FLAG_T 0x10 ++#define ND_OPT_MAP_FLAG_P 0x08 ++#define ND_OPT_MAP_FLAG_V 0x04 + + #endif /* netinet/icmpv6.h */ diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/interface.c ./radvd/radvd/interface.c --- ../tools/radvd-0.7.2/interface.c Fri Dec 28 18:38:44 2001 +++ ./radvd/radvd/interface.c Mon Jun 23 13:23:36 2003 @@ -28,6 +28,7 @@ iface->AdvSourceLLAddress = DFLT_AdvSourceLLAddress; iface->AdvReachableTime = DFLT_AdvReachableTime; iface->AdvRetransTimer = DFLT_AdvRetransTimer; + iface->AdvIfDown = DFLT_AdvIfDown; iface->AdvLinkMTU = DFLT_AdvLinkMTU; iface->AdvCurHopLimit = DFLT_AdvCurHopLimit; iface->AdvIntervalOpt = DFLT_AdvIntervalOpt; @@ -35,6 +36,20 @@ iface->AdvHomeAgentFlag = DFLT_AdvHomeAgentFlag; iface->HomeAgentPreference = DFLT_HomeAgentPreference; + iface->ReAdvHmip6MapInfo = DFLT_ReAdvHmip6MapInfo; + iface->AdvHmip6MapInfo = DFLT_AdvHmip6MapInfo; + iface->RecvHmip6MapInfo = DFLT_RecvHmip6MapInfo; + + iface->FastRSResponse = DFLT_FastRSResponse; + iface->NumFastRSReq = DFLT_NumFastRSReq; + iface->MaxFastRS = DFLT_MaxFastRS; + + iface->MinDelayBetweenRAs = DFLT_MinDelayBetweenRAs; + + iface->AdvLinkID = DFLT_AdvLinkID; + iface->LinkID = DFLT_LinkID; + iface->LinkIDAmbiguity = DFLT_LinkIDAmbiguity; + iface->MinRtrAdvInterval = -1; iface->AdvDefaultLifetime = -1; iface->HomeAgentLifetime = 0; @@ -54,6 +69,29 @@ prefix->enabled = 1; } +void +local_map_init_defaults(struct MobilityAccessPoint *map) +{ + memset(map, 0, sizeof(struct MobilityAccessPoint)); + + map->PacketSource = DFLT_MAP_PacketSource; + map->Topology = DFLT_MAP_Topology; + map->Privacy = DFLT_MAP_Privacy; + map->ExtendedMode = DFLT_MAP_ExtendedMode; + map->RcoaPrefix = DFLT_MAP_RcoaPrefix; + map->distance = DFLT_MAP_Distance; + map->preference = DFLT_MAP_Preference; + + map->validLifetime = DFLT_MAP_ValidLifetime; + map->enabled=1; /* enable all listed maps by default */ + map->next = NULL; + + map->dynamic = MAP_INTERFACE_STATIC; + map->lastUpdate = DFLT_MAP_lastUpdate; + map->srcIfIndex = DFLT_MAP_srcIfIndex; +} + + int check_iface(struct Interface *iface) { @@ -63,12 +101,17 @@ /* Check if we use Mobile IPv6 extensions */ if (iface->AdvHomeAgentFlag || iface->AdvHomeAgentInfo || - iface->AdvIntervalOpt) + iface->AdvIntervalOpt|| iface->ReAdvHmip6MapInfo || + iface->AdvHmip6MapInfo ) { MIPv6 = 1; } prefix = iface->AdvPrefixList; + + dlog(LOG_DEBUG, 4, "check prefix list %p %p", prefix, + iface->AdvPrefixList); + while (!MIPv6 && prefix) { if (prefix->AdvRouterAddr) @@ -93,6 +136,7 @@ (iface->MinRtrAdvInterval > MAX_MinRtrAdvInterval(iface))) { double limit = (double) MAX_MinRtrAdvInterval(iface); + if (limit < MIN_MinRtrAdvInterval_MIPv6) limit = MIN_MinRtrAdvInterval_MIPv6; log(LOG_ERR, @@ -105,11 +149,11 @@ else { if ((iface->MinRtrAdvInterval < MIN_MinRtrAdvInterval) || - (iface->MinRtrAdvInterval > MAX_MinRtrAdvInterval(iface))) + (iface->MinRtrAdvInterval > (int)MAX_MinRtrAdvInterval(iface))) { log(LOG_ERR, "MinRtrAdvInterval must be between %d and %d for %s", - MIN_MinRtrAdvInterval, MAX_MinRtrAdvInterval(iface), + MIN_MinRtrAdvInterval, (int)MAX_MinRtrAdvInterval(iface), iface->Name); res = -1; } @@ -140,6 +184,28 @@ } } + /* Mobile IPv6 ext */ + if (MIPv6) + { + if (iface->MinDelayBetweenRAs < MIN_DELAY_BETWEEN_RAS_MIPv6) + { + log(LOG_ERR, + "MinDelayBetweenRAs for %s must be greater than %.2f", + iface->Name, MIN_DELAY_BETWEEN_RAS_MIPv6); + res = -1; + } + } + else + { + if (iface->MinDelayBetweenRAs < MIN_DELAY_BETWEEN_RAS) + { + log(LOG_ERR, + "MinDelayBetweenRAs for %s must be greater than %.2f", + iface->Name, (double) MIN_DELAY_BETWEEN_RAS); + res = -1; + } + } + if (iface->if_maxmtu != -1) { if ((iface->AdvLinkMTU != 0) && @@ -244,4 +310,24 @@ } return res; +} + + +int setup_hmipv6_iface(struct Interface *iface){ + struct MobilityAccessPoint *map; + if(!iface) + return -1; + + log(LOG_ERR, "Ifindex %s: %d ", iface->Name, iface->if_index); + + + if(iface && (map =iface->Hmip6MapList)){ + while(map){ + map->srcIfIndex = iface->if_index; + install_map_local(map); + map=map->next; + } + } + + } diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/linkid.h ./radvd/radvd/linkid.h --- ../tools/radvd-0.7.2/linkid.h Thu Jan 1 10:00:00 1970 +++ ./radvd/radvd/linkid.h Wed May 28 14:47:21 2003 @@ -0,0 +1,71 @@ +#ifndef _LINKID_H +#define _LINKID_H 1 + +#include +#include + +#define ND_DELEGATION_CHAIN_SOLICIT 143 +#define ND_DELEGATION_CHAIN_ADVERT 144 + +#define ND_OPT_LINKID 203 + +/* + * + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Type | Code | Checksum | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Identifier |M| Component | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Reserved | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Options ... ++-+-+-+-+-+-+-+-+-+-+-+- + */ + +struct nd_del_chain_adv{ + struct icmp6_hdr nd_dca_hdr; + uint32_t nd_dca_reserved; +}; +#define nd_dca_type nd_dca_hdr.icmp6_type +#define nd_dca_code nd_dca_hdr.icmp6_code +#define nd_dca_cksum nd_dca_hdr.icmp6_cksum +#define nd_dca_identifier nd_dca_hdr.icmp6_data16[0] +#define nd_dca_flag_component nd_dca_hdr.icmp6_data16[1] +#define ND_DCA_FLAG_MORE 0x8000 + + +/* + * Delegation Chain Solicitation ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Type | Code | Checksum | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Identifier | Reserved | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Options ... ++-+-+-+-+-+-+-+-+-+-+-+- + */ + +struct nd_del_chain_sol{ + struct icmp6_hdr nd_dcs_hdr; +}; +#define nd_dcs_type nd_dcs_hdr.icmp6_type +#define nd_dcs_code nd_dcs_hdr.icmp6_code +#define nd_dcs_cksum nd_dcs_hdr.icmp6_cksum +#define nd_dcs_identifier nd_dcs_hdr.icmp6_data16[0] +#define nd_dcs_reserved nd_dcs_hdr.icmp6_data16[1] + +struct nd_opt_linkid /* Link Identifier */ + { + uint8_t nd_opt_lid_type; + uint8_t nd_opt_lid_len; /* 1 (<<3) */ + uint8_t nd_opt_lid_flags_reserved; + uint8_t nd_opt_lid_reserved2; + uint32_t nd_opt_lid_linkid; + }; + +#define ND_OPT_LID_FLAG_AMBIGUOUS 0x80 + + +#endif /* netinet/icmpv6.h */ diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/list.c ./radvd/radvd/list.c --- ../tools/radvd-0.7.2/list.c Thu Jan 1 10:00:00 1970 +++ ./radvd/radvd/list.c Mon Aug 12 15:21:16 2002 @@ -0,0 +1,118 @@ +/* + * $Id: list.c,v 1.2 2002/08/12 05:21:16 gdaley Exp $ + * + * Authors: + * Greg Daley + * + * This software is Copyright 2002 by the above mentioned author(s), + * All Rights Reserved. + * + * The license which is distributed with this software in the file COPYRIGHT + * applies to this software. If your distribution is missing this file, you + * may request it from . + * + */ + +#include +#include +#include +#include + + +/* +* Simple Lists module for collecting non-contiguous lists +*/ + + +/* Using list combination, order not mattering yet */ + + + +void *combine(void *list1, void *list2, + void *(*getnext)(const void *), + void *(*setnext)(const void *,const void *)){ + + void * head, *next2 ; + + if (list1 == NULL ){ + return list2; + } + if (list2 == NULL){ + return list1; + } + + while(list2 != NULL){ + /* collect list starting at second entry of list 2 */ + next2 = getnext(list2); + /* put list2's first entry at the front of list1 */ + head = setnext(list2, list1); + + /* Index list positions */ + list2 = next2; + list1 = head; + } +} + + /* Hmip6 Map list functions */ + +void *map_getnext(const void *list){ + struct MobilityAccessPoint *tmpMap; + + tmpMap = ( struct MobilityAccessPoint *)list; + + return (void *)(tmpMap->next); +} + + +void *map_setnext (const void *entry, const void *list){ + struct MobilityAccessPoint *tmpMap; + + tmpMap = (struct MobilityAccessPoint *)entry; + + tmpMap->next = (struct MobilityAccessPoint *)list; + + return (void *)tmpMap; +} + +struct MobilityAccessPoint *maplist_combine(struct MobilityAccessPoint *list1, + struct MobilityAccessPoint *list2){ + + struct MobilityAccessPoint *tmpMap; + + tmpMap = (struct MobilityAccessPoint *)combine( list1, + list2, map_getnext, map_setnext); + + return tmpMap; +} + + /* Prefix list functions */ + +void *prefix_getnext(const void *list){ + struct AdvPrefix *tmpPrefix; + + tmpPrefix = ( struct AdvPrefix *)list; + + return (void *)(tmpPrefix->next); +} + +void *prefix_setnext (const void *entry, const void *list){ + struct AdvPrefix *tmpPrefix; + + tmpPrefix = (struct AdvPrefix *)entry; + + tmpPrefix->next = (struct AdvPrefix *)list; + + return (void *)tmpPrefix; +} + + +struct AdvPrefix *prefixlist_combine(struct AdvPrefix *list1, + struct AdvPrefix *list2){ + + struct AdvPrefix *tmpPrefix; + + tmpPrefix = (struct AdvPrefix *)combine( list1, + list2, prefix_getnext, prefix_setnext); + + return tmpPrefix; +} diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/maptable.c ./radvd/radvd/maptable.c --- ../tools/radvd-0.7.2/maptable.c Thu Jan 1 10:00:00 1970 +++ ./radvd/radvd/maptable.c Mon Aug 12 15:21:16 2002 @@ -0,0 +1,265 @@ +/* + * $Id: maptable.c,v 1.2 2002/08/12 05:21:16 gdaley Exp $ + * + * Authors: + * Greg Daley + * + * This software is Copyright 2002 by the above mentioned author(s), + * All Rights Reserved. + * + * The license which is distributed with this software in the file COPYRIGHT + * applies to this software. If your distribution is missing this file, you + * may request it from . + * + */ + +#include +#include "radvd.h" +#include "maptable.h" + + +struct MapTable{ + + struct MobilityAccessPoint head; + int looseStatic; + int splitHorizon; + int poisonReverse; + sigset_t oldmask; +}; + +struct MapTable maptable; + +void init_maptable(void){ + dlog(LOG_DEBUG, 4,"init_maptable()"); + memset(&maptable.head, 0 , sizeof (struct MobilityAccessPoint)); + maptable.looseStatic = 1; + maptable.splitHorizon = 1; + maptable.poisonReverse= 0; +} + +void clear_maptable(void){ + struct MobilityAccessPoint *tmpmap, *nextmap; + dlog(LOG_DEBUG, 4,"clear_maptable()"); + + tmpmap = maptable.head.next; + + maptable.head.next=NULL; + + while(tmpmap != NULL){ + nextmap = tmpmap->next; + tmpmap->next = NULL; + free(tmpmap); + tmpmap=nextmap; + } +} + +void maptable_lock(void){ + sigset_t bmask; + dlog(LOG_DEBUG, 4,"maptable_lock()"); + + sigemptyset(&bmask); + sigaddset(&bmask, SIGALRM); + sigprocmask(SIG_BLOCK, &bmask, &maptable.oldmask); + + return; +} + + +void maptable_unlock(void){ + + sigprocmask(SIG_SETMASK, &maptable.oldmask, NULL); + dlog(LOG_DEBUG, 4,"maptable_unlock()"); + return; +} + + + +int maptable_looseStatic(void){ + dlog(LOG_DEBUG, 4,"maptable_looseStatic()"); + /* use copy-return for atomicity */ + return maptable.looseStatic; +} + +int maptable_splitHorizon(void){ + dlog(LOG_DEBUG, 4,"maptable_splitHorizon()"); + /* use copy-return for atomicity */ + return maptable.splitHorizon; +} +void maptable_cleanup_unsafe(void){ + struct MobilityAccessPoint *currentmap,*tmpmap; + time_t now; + dlog(LOG_DEBUG, 4,"maptable_cleanup_unsafe()"); + + now = time(NULL); + currentmap=&maptable.head; + + while(currentmap->next != NULL){ + if(currentmap->next->dynamic){ + if(currentmap->next->validLifetime == 0){ + + if((currentmap->next->lastUpdate + + ( 2*currentmap->next->dynInterval ))< now){ + /* remove old entries with zero lifetime */ + /* including those entries without intervals */ + tmpmap = currentmap->next; + currentmap->next = tmpmap->next; + tmpmap->next = NULL; + free(tmpmap); + dlog(LOG_DEBUG, 4,"maptable_cleanup_unsafe(): remove expired (interval)"); + continue; + } + } + else if((currentmap->next->validLifetime + + currentmap->next->lastUpdate) < now ){ + tmpmap = currentmap->next; + currentmap->next = tmpmap->next; + tmpmap->next = NULL; + free(tmpmap); + dlog(LOG_DEBUG, 4,"maptable_cleanup_unsafe(): remove expired (lifetime)"); + continue; + } + else if(currentmap->next->dynInterval &&(( + 2*currentmap->next->dynInterval + + currentmap->next->lastUpdate) < now )){ + /* mark the entries as invalid */ + currentmap->next->lastUpdate = now; + currentmap->next->validLifetime = (uint32_t)0; + dlog(LOG_DEBUG, 4,"maptable_cleanup_unsafe(): interval expired, lifetime zeroed"); + + } + } + currentmap = currentmap->next; + } + +} + +struct MobilityAccessPoint *get_maptable_unsafe(void){ + dlog(LOG_DEBUG, 4,"get_maptable_unsafe()"); + return maptable.head.next; +} + + +struct MobilityAccessPoint *maptable_insert_unsafe( + struct MobilityAccessPoint *map){ + int val; + struct MobilityAccessPoint *currentmap, *tmpmap; + + dlog(LOG_DEBUG, 4,"maptable_insert_unsafe()"); + currentmap=&maptable.head; + + while(currentmap->next){ + if((val = memcmp(&map->globalAddress,¤tmap->next->globalAddress, + sizeof(struct in6_addr))) <0){ + break; + } + if(!val){ + if(!currentmap->next->dynamic){ + if(!(maptable.looseStatic|| + (map->srcIfIndex == currentmap->next->srcIfIndex))){ + /* don't learn about statically configured locals */ + return map; + } + /* else, skip static entry; */ + } + else if((map->srcIfIndex == currentmap->next->srcIfIndex)&& + !memcmp(&map->srcAddress,¤tmap->next->srcAddress, + sizeof(struct in6_addr))){ + /* we have an update for a dynamic entry */ + currentmap->next->lastUpdate = time(NULL); + /* TODO: check if this is ok .... */ + /* removing update if valid lifetime is already 0 */ + if(currentmap->next->validLifetime || map->validLifetime){ + currentmap->next->lastUpdate = time(NULL); + currentmap->next->validLifetime = map->validLifetime; + currentmap->next->validLifetime = map->validLifetime; + } + currentmap->next->dynInterval = map->dynInterval; + currentmap->next->distance = map->distance; + currentmap->next->preference = map->preference; + return; + } + else if(!currentmap->next->next || memcmp(&map->globalAddress, + ¤tmap->next->next->globalAddress, sizeof(struct in6_addr))){ + /* we're at the last of the entries for this map */ + break; + } + } + + currentmap=currentmap->next; + } + if((tmpmap = (struct MobilityAccessPoint *)malloc(sizeof(struct + MobilityAccessPoint))) == NULL){ + return NULL; + } + memcpy(tmpmap, map, sizeof (struct MobilityAccessPoint)); + tmpmap->lastUpdate = time(NULL); + tmpmap->dynamic = 1; + tmpmap->next = currentmap->next; + currentmap->next = tmpmap; + + + return map; +} + + + +static struct MobilityAccessPoint *install_map_local_unsafe( + struct MobilityAccessPoint *map){ + struct MobilityAccessPoint *currentmap, *tmpmap; + + dlog(LOG_DEBUG, 4,"install_map_local_unsafe()"); + currentmap=&maptable.head; + + while(currentmap->next){ + if(memcmp(&map->globalAddress,¤tmap->next->globalAddress, + sizeof(struct in6_addr)) <0){ + break; + } + currentmap=currentmap->next; + } + if((tmpmap = (struct MobilityAccessPoint *)malloc(sizeof(struct + MobilityAccessPoint))) == NULL){ + return NULL; + } + memcpy(tmpmap, map, sizeof (struct MobilityAccessPoint)); + tmpmap->dynamic = 0; + tmpmap->next = currentmap->next; + currentmap->next = tmpmap; + + return map; +} + + + + +struct MobilityAccessPoint *maptable_insert(struct MobilityAccessPoint *map){ + struct MobilityAccessPoint *ret; + + dlog(LOG_DEBUG, 4,"maptable_insert()"); + maptable_lock(); + + ret = maptable_insert_unsafe(map); + + maptable_unlock(); + + return ret; +} + + + +struct MobilityAccessPoint *install_map_local(struct MobilityAccessPoint *map){ + /* install_map_local inserts maps which are static into maptable */ + struct MobilityAccessPoint *ret; + dlog(LOG_DEBUG, 4,"install_map_local()"); + + maptable_lock(); + ret = install_map_local_unsafe(map); + maptable_unlock(); + return ret; +} + + + + + + diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/maptable.h ./radvd/radvd/maptable.h --- ../tools/radvd-0.7.2/maptable.h Thu Jan 1 10:00:00 1970 +++ ./radvd/radvd/maptable.h Mon Aug 12 15:21:16 2002 @@ -0,0 +1,38 @@ +/* + * $Id: maptable.h,v 1.2 2002/08/12 05:21:16 gdaley Exp $ + * + * Authors: + * Greg Daley + * + * This software is Copyright 2002 by the above mentioned author(s), + * All Rights Reserved. + * + * The license which is distributed with this software in the file COPYRIGHT + * applies to this software. If your distribution is missing this file, you + * may request it from . + * + */ + +#include "radvd.h" + + + + +void init_maptable(void); +void clear_maptable(void); + +void maptable_lock(void); +void maptable_unlock(void); + +int maptable_looseStatic(void); +int maptable_splitHorizon(void); +void maptable_cleanup_unsafe(void); + +struct MobilityAccessPoint *get_maptable_unsafe(void); +struct MobilityAccessPoint *maptable_insert(struct MobilityAccessPoint *map); +struct MobilityAccessPoint *install_map_local(struct MobilityAccessPoint *map); + + + + + diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/netinet/icmp6.h ./radvd/radvd/netinet/icmp6.h --- ../tools/radvd-0.7.2/netinet/icmp6.h Thu Jan 1 10:00:00 1970 +++ ./radvd/radvd/netinet/icmp6.h Mon May 13 16:24:00 2002 @@ -0,0 +1,274 @@ +/* Copyright (C) 1991,92,93,94,95,96,97,2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _NETINET_ICMP6_H +#define _NETINET_ICMP6_H 1 + +#include +#include +#include +#include + +#define ICMP6_FILTER 1 + +#define ICMP6_FILTER_BLOCK 1 +#define ICMP6_FILTER_PASS 2 +#define ICMP6_FILTER_BLOCKOTHERS 3 +#define ICMP6_FILTER_PASSONLY 4 + +struct icmp6_filter + { + uint32_t data[8]; + }; + +struct icmp6_hdr + { + uint8_t icmp6_type; /* type field */ + uint8_t icmp6_code; /* code field */ + uint16_t icmp6_cksum; /* checksum field */ + union + { + uint32_t icmp6_un_data32[1]; /* type-specific field */ + uint16_t icmp6_un_data16[2]; /* type-specific field */ + uint8_t icmp6_un_data8[4]; /* type-specific field */ + } icmp6_dataun; + }; + +#define icmp6_data32 icmp6_dataun.icmp6_un_data32 +#define icmp6_data16 icmp6_dataun.icmp6_un_data16 +#define icmp6_data8 icmp6_dataun.icmp6_un_data8 +#define icmp6_pptr icmp6_data32[0] /* parameter prob */ +#define icmp6_mtu icmp6_data32[0] /* packet too big */ +#define icmp6_id icmp6_data16[0] /* echo request/reply */ +#define icmp6_seq icmp6_data16[1] /* echo request/reply */ +#define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */ + +#define ICMP6_DST_UNREACH 1 +#define ICMP6_PACKET_TOO_BIG 2 +#define ICMP6_TIME_EXCEEDED 3 +#define ICMP6_PARAM_PROB 4 + +#define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */ + +#define ICMP6_ECHO_REQUEST 128 +#define ICMP6_ECHO_REPLY 129 +#define ICMP6_MEMBERSHIP_QUERY 130 +#define ICMP6_MEMBERSHIP_REPORT 131 +#define ICMP6_MEMBERSHIP_REDUCTION 132 + +#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ +#define ICMP6_DST_UNREACH_ADMIN 1 /* communication with destination */ + /* administratively prohibited */ +#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor */ +#define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ +#define ICMP6_DST_UNREACH_NOPORT 4 /* bad port */ + +#define ICMP6_TIME_EXCEED_TRANSIT 0 /* Hop Limit == 0 in transit */ +#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* Reassembly time out */ + +#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */ +#define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized Next Header */ +#define ICMP6_PARAMPROB_OPTION 2 /* unrecognized IPv6 option */ + +#define ICMP6_FILTER_WILLPASS(type, filterp) \ + ((((filterp)->data[(type) >> 5]) & (1 << ((type) & 31))) == 0) + +#define ICMP6_FILTER_WILLBLOCK(type, filterp) \ + ((((filterp)->data[(type) >> 5]) & (1 << ((type) & 31))) != 0) + +#define ICMP6_FILTER_SETPASS(type, filterp) \ + ((((filterp)->data[(type) >> 5]) &= ~(1 << ((type) & 31)))) + +#define ICMP6_FILTER_SETBLOCK(type, filterp) \ + ((((filterp)->data[(type) >> 5]) |= (1 << ((type) & 31)))) + +#define ICMP6_FILTER_SETPASSALL(filterp) \ + memset (filterp, 0, sizeof (struct icmp6_filter)); + +#define ICMP6_FILTER_SETBLOCKALL(filterp) \ + memset (filterp, 0xFF, sizeof (struct icmp6_filter)); + +#define ND_ROUTER_SOLICIT 133 +#define ND_ROUTER_ADVERT 134 +#define ND_NEIGHBOR_SOLICIT 135 +#define ND_NEIGHBOR_ADVERT 136 +#define ND_REDIRECT 137 + +struct nd_router_solicit /* router solicitation */ + { + struct icmp6_hdr nd_rs_hdr; + /* could be followed by options */ + }; + +#define nd_rs_type nd_rs_hdr.icmp6_type +#define nd_rs_code nd_rs_hdr.icmp6_code +#define nd_rs_cksum nd_rs_hdr.icmp6_cksum +#define nd_rs_reserved nd_rs_hdr.icmp6_data32[0] + +struct nd_router_advert /* router advertisement */ + { + struct icmp6_hdr nd_ra_hdr; + uint32_t nd_ra_reachable; /* reachable time */ + uint32_t nd_ra_retransmit; /* retransmit timer */ + /* could be followed by options */ + }; + +#define nd_ra_type nd_ra_hdr.icmp6_type +#define nd_ra_code nd_ra_hdr.icmp6_code +#define nd_ra_cksum nd_ra_hdr.icmp6_cksum +#define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0] +#define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1] +#define ND_RA_FLAG_MANAGED 0x80 +#define ND_RA_FLAG_OTHER 0x40 +#define ND_RA_FLAG_HOME_AGENT 0x20 +#define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1] + +struct nd_neighbor_solicit /* neighbor solicitation */ + { + struct icmp6_hdr nd_ns_hdr; + struct in6_addr nd_ns_target; /* target address */ + /* could be followed by options */ + }; + +#define nd_ns_type nd_ns_hdr.icmp6_type +#define nd_ns_code nd_ns_hdr.icmp6_code +#define nd_ns_cksum nd_ns_hdr.icmp6_cksum +#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0] + +struct nd_neighbor_advert /* neighbor advertisement */ + { + struct icmp6_hdr nd_na_hdr; + struct in6_addr nd_na_target; /* target address */ + /* could be followed by options */ + }; + +#define nd_na_type nd_na_hdr.icmp6_type +#define nd_na_code nd_na_hdr.icmp6_code +#define nd_na_cksum nd_na_hdr.icmp6_cksum +#define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0] +#if BYTE_ORDER == BIG_ENDIAN +#define ND_NA_FLAG_ROUTER 0x80000000 +#define ND_NA_FLAG_SOLICITED 0x40000000 +#define ND_NA_FLAG_OVERRIDE 0x20000000 +#else /* BYTE_ORDER == LITTLE_ENDIAN */ +#define ND_NA_FLAG_ROUTER 0x00000080 +#define ND_NA_FLAG_SOLICITED 0x00000040 +#define ND_NA_FLAG_OVERRIDE 0x00000020 +#endif + +struct nd_redirect /* redirect */ + { + struct icmp6_hdr nd_rd_hdr; + struct in6_addr nd_rd_target; /* target address */ + struct in6_addr nd_rd_dst; /* destination address */ + /* could be followed by options */ + }; + +#define nd_rd_type nd_rd_hdr.icmp6_type +#define nd_rd_code nd_rd_hdr.icmp6_code +#define nd_rd_cksum nd_rd_hdr.icmp6_cksum +#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0] + +struct nd_opt_hdr /* Neighbor discovery option header */ + { + uint8_t nd_opt_type; + uint8_t nd_opt_len; /* in units of 8 octets */ + /* followed by option specific data */ + }; + +#define ND_OPT_SOURCE_LINKADDR 1 +#define ND_OPT_TARGET_LINKADDR 2 +#define ND_OPT_PREFIX_INFORMATION 3 +#define ND_OPT_REDIRECTED_HEADER 4 +#define ND_OPT_MTU 5 +#define ND_OPT_RTR_ADV_INTERVAL 7 +#define ND_OPT_HOME_AGENT_INFO 8 + /* Temporary for HMIPv6 */ +#define ND_OPT_MAP 201 + +struct nd_opt_prefix_info /* prefix information */ + { + uint8_t nd_opt_pi_type; + uint8_t nd_opt_pi_len; + uint8_t nd_opt_pi_prefix_len; + uint8_t nd_opt_pi_flags_reserved; + uint32_t nd_opt_pi_valid_time; + uint32_t nd_opt_pi_preferred_time; + uint32_t nd_opt_pi_reserved2; + struct in6_addr nd_opt_pi_prefix; + }; + +#define ND_OPT_PI_FLAG_ONLINK 0x80 +#define ND_OPT_PI_FLAG_AUTO 0x40 +#define ND_OPT_PI_FLAG_RADDR 0x20 + +struct nd_opt_rd_hdr /* redirected header */ + { + uint8_t nd_opt_rh_type; + uint8_t nd_opt_rh_len; + uint16_t nd_opt_rh_reserved1; + uint32_t nd_opt_rh_reserved2; + /* followed by IP header and data */ + }; + +struct nd_opt_mtu /* MTU option */ + { + uint8_t nd_opt_mtu_type; + uint8_t nd_opt_mtu_len; + uint16_t nd_opt_mtu_reserved; + uint32_t nd_opt_mtu_mtu; + }; + +/* Mobile IPv6 extension: Advertisement Interval. */ +struct nd_opt_adv_interval + { + uint8_t nd_opt_adv_interval_type; + uint8_t nd_opt_adv_interval_len; + uint16_t nd_opt_adv_interval_reserved; + uint32_t nd_opt_adv_interval_ival; + }; + +/* Mobile IPv6 extension: Home Agent Info. */ +struct nd_opt_home_agent_info + { + uint8_t nd_opt_home_agent_info_type; + uint8_t nd_opt_home_agent_info_len; + uint16_t nd_opt_home_agent_info_reserved; + int16_t nd_opt_home_agent_info_preference; + uint16_t nd_opt_home_agent_info_lifetime; + }; + +/* Mobile IPv6 extension: Home Agent Info. */ +struct nd_opt_map + { + uint8_t nd_opt_map_type; + uint8_t nd_opt_map_length; + uint8_t nd_opt_map_dist_pref; + uint8_t nd_opt_map_flags_reserved; + uint32_t nd_opt_map_valid_time; + struct in6_addr nd_opt_map_globaladdr; + }; + +#define ND_OPT_MAP_FLAG_R 0x80 +#define ND_OPT_MAP_FLAG_M 0x40 +#define ND_OPT_MAP_FLAG_I 0x20 +#define ND_OPT_MAP_FLAG_T 0x10 +#define ND_OPT_MAP_FLAG_P 0x08 +#define ND_OPT_MAP_FLAG_V 0x04 + +#endif /* netinet/icmpv6.h */ diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/process.c ./radvd/radvd/process.c --- ../tools/radvd-0.7.2/process.c Thu Nov 15 06:58:11 2001 +++ ./radvd/radvd/process.c Mon Jun 23 13:23:36 2003 @@ -17,12 +17,109 @@ #include #include #include +#include "linkid.h" /* Delegation chain definitions */ +static int process_rs_opt( struct Interface *iface, unsigned char *msg, int len, + struct sockaddr_in6 *addr); static void process_rs(int, struct Interface *, struct sockaddr_in6 *); +static void process_dcs(int, struct Interface *, + struct in6_addr *, struct in6_addr *, uint16_t); + static void process_ra(struct Interface *, unsigned char *msg, int len, struct sockaddr_in6 *); static int addr_match(struct in6_addr *a1, struct in6_addr *a2, int prefixlen); +static int check_map_flags(unsigned char flags); +static int check_map_address(struct in6_addr *mapaddr); + +static struct MobilityAccessPoint *process_map_opt(struct nd_opt_map *mapinfo); + + + +static int check_map_flags(unsigned char flags){ + unsigned char ext_opts; + unsigned char bas_opts; + + dlog(LOG_DEBUG, 3, "check_map_flags(%x)", flags); + bas_opts = ((ND_OPT_MAP_FLAG_I | ND_OPT_MAP_FLAG_P | + ND_OPT_MAP_FLAG_R) & flags); + + ext_opts = ((ND_OPT_MAP_FLAG_T | ND_OPT_MAP_FLAG_V | + ND_OPT_MAP_FLAG_M) & flags); + + dlog(LOG_DEBUG, 3, "check_map_flags(%x) %x %x",flags, bas_opts , ext_opts); + if( bas_opts && ext_opts) + return 0; + + return 1; +} + + /* TODO: proper map address testing */ + +static int check_map_address(struct in6_addr *mapaddr){ + /* reject if ll_addr, site scoped may be OK */ + + dlog(LOG_DEBUG, 3, "check_map_address(%hx)", + htons(mapaddr->s6_addr16[0])); + if (htons(mapaddr->s6_addr16[0]) == 0xfe80){ + return 0; + } + + return 1; +} + + + +static struct MobilityAccessPoint *process_map_opt(struct nd_opt_map *mapinfo){ + struct MobilityAccessPoint *tmpmap; + dlog(LOG_DEBUG, 3, "check_map_address()"); + + if((tmpmap = (struct MobilityAccessPoint *) + malloc(sizeof (struct MobilityAccessPoint) ))== NULL){ + log(LOG_ERR, "Unable to allocate MAP in process.c"); + return NULL; + } + + memset(tmpmap, 0, sizeof(struct MobilityAccessPoint)); + tmpmap->dynamic=1; + /* set parameters from packet */ + tmpmap->preference = 0xf & + mapinfo->nd_opt_map_dist_pref; + tmpmap->distance = 0xf & + (mapinfo->nd_opt_map_dist_pref >>4); + + /* increment distance */ + tmpmap->distance = (tmpmap->distance + && (tmpmap->distance < 15))? + tmpmap->distance+1: 0; + + tmpmap->validLifetime = ntohl( mapinfo->nd_opt_map_valid_time); + + memcpy(&(tmpmap->globalAddress), + &mapinfo->nd_opt_map_globaladdr, sizeof( struct in6_addr)); + + /* Set flags from packet */ + tmpmap->Privacy =!!(ND_OPT_MAP_FLAG_I& + mapinfo->nd_opt_map_flags_reserved); + + tmpmap->Topology =!!(ND_OPT_MAP_FLAG_T& + mapinfo->nd_opt_map_flags_reserved); + + tmpmap->RcoaPrefix =!!(ND_OPT_MAP_FLAG_R& + mapinfo->nd_opt_map_flags_reserved); + + tmpmap->ExtendedMode =!!(ND_OPT_MAP_FLAG_M& + mapinfo->nd_opt_map_flags_reserved); + + tmpmap->PacketSource =!!(ND_OPT_MAP_FLAG_P& + mapinfo->nd_opt_map_flags_reserved); + + tmpmap->ReverseTunnel =!!(ND_OPT_MAP_FLAG_V& + mapinfo->nd_opt_map_flags_reserved); + + return tmpmap; +} + void process(int sock, struct Interface *ifacel, unsigned char *msg, int len, @@ -30,6 +127,7 @@ { struct Interface *iface; struct icmp6_hdr *icmph; + uint16_t dcsid; char addr_str[INET6_ADDRSTRLEN]; if ( ! pkt_info ) @@ -51,8 +149,9 @@ icmph = (struct icmp6_hdr *) msg; - if (icmph->icmp6_type != ND_ROUTER_SOLICIT && - icmph->icmp6_type != ND_ROUTER_ADVERT) + if (!(icmph->icmp6_type == ND_ROUTER_SOLICIT || + icmph->icmp6_type == ND_ROUTER_ADVERT || + icmph->icmp6_type == ND_DELEGATION_CHAIN_SOLICIT)) { /* * We just want to listen to RSs and RAs @@ -98,6 +197,15 @@ } dlog(LOG_DEBUG, 4, "if_index %d", pkt_info->ipi6_ifindex); + dlog(LOG_DEBUG, 4, "ipi6_addr %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", + ntohs(pkt_info->ipi6_addr.s6_addr16[0]), + ntohs(pkt_info->ipi6_addr.s6_addr16[1]), + ntohs(pkt_info->ipi6_addr.s6_addr16[2]), + ntohs(pkt_info->ipi6_addr.s6_addr16[3]), + ntohs(pkt_info->ipi6_addr.s6_addr16[4]), + ntohs(pkt_info->ipi6_addr.s6_addr16[5]), + ntohs(pkt_info->ipi6_addr.s6_addr16[6]), + ntohs(pkt_info->ipi6_addr.s6_addr16[7])); /* get iface by received if_index */ @@ -132,16 +240,109 @@ dlog(LOG_DEBUG, 4, "found Interface: %s", iface->Name); + + if (icmph->icmp6_type == ND_DELEGATION_CHAIN_SOLICIT) + { + dcsid = ntohs(((struct nd_del_chain_sol *)icmph)-> + nd_dcs_identifier); + process_dcs(sock, iface, &pkt_info->ipi6_addr, + &addr->sin6_addr, dcsid); + } + else if (icmph->icmp6_type == ND_ROUTER_SOLICIT) { + print_addr(&addr->sin6_addr, addr_str); + log(LOG_WARNING, "received RS on %s from %s", + iface->Name, addr_str); + if(!process_rs_opt(iface, msg,len,addr)){ process_rs(sock, iface, addr); } + } else if (icmph->icmp6_type == ND_ROUTER_ADVERT) { process_ra(iface, msg, len, addr); } } +static int +process_rs_opt( struct Interface *iface, unsigned char *msg, int len, + struct sockaddr_in6 *addr) +{ + char addr_str[INET6_ADDRSTRLEN]; + char linkaddr[INET6_ADDRSTRLEN]; + uint8_t *opt_str; + struct in6_addr unspec; + + memset(&unspec, 0, sizeof(unspec)); + print_addr(&addr->sin6_addr, addr_str); + len -= sizeof(struct nd_router_solicit); + + if (len == 0) + return; + + opt_str = (uint8_t *)(msg + sizeof(struct nd_router_solicit)); + + while (len > 0) + { + int optlen; + + if (len < 2) + { + log(LOG_ERR, "trailing garbage in RS on %s from %s", + iface->Name, addr_str); + break; + } + + optlen = (opt_str[1] << 3); + + dlog(LOG_DEBUG, 5, "option %hhd length: %hhd",*opt_str, optlen); + if (optlen == 0) + { + log(LOG_ERR, "zero length option in RS on %s from %s", + iface->Name, addr_str); + return -1; + break; + } + else if (optlen > len) + { + log(LOG_ERR, "option length greater than total" + " length in RS on %s from %s", + iface->Name, addr_str); + break; + } + + switch (*opt_str){ + case ND_OPT_SOURCE_LINKADDR: + if(!memcmp(&unspec, &addr->sin6_addr, sizeof (unspec))){ + log(LOG_WARNING, "RS with unspec addr"); + /* early return, invalid packet */ + return -1; + } + dlog(LOG_DEBUG, 5, "SLLAO received in RS"); + memcpy(&opt_str[2],linkaddr, (optlen-2 > + sizeof(linkaddr))?optlen-2:sizeof(linkaddr)); + + + if (neigh_add(iface->if_index,linkaddr, optlen-2, + &addr->sin6_addr)) + log(LOG_WARNING, + "Added NC entry for SLLAO in RS\n"); + else + log(LOG_WARNING, + "Unable to add NC entry for SLLAO\n"); + break; + default: + log(LOG_WARNING, + "unknown option type %hhd in RS\n", + *opt_str); + break; + } + opt_str = (uint8_t *)(opt_str + optlen); + len -= optlen; + } + return 0; +} + static void process_rs(int sock, struct Interface *iface, struct sockaddr_in6 *addr) { @@ -151,12 +352,40 @@ gettimeofday(&tv, NULL); + + if(iface->FastRSResponse){ + if(iface->NumFastRSReq < iface->MaxFastRS){ + dlog(LOG_DEBUG, 3, "Sending Fast RS response"); + send_ra(sock, iface, &addr->sin6_addr); + iface->NumFastRSReq++; + } + else if((iface->NumFastRSReq++ == iface->MaxFastRS) && + !iface->UnicastOnly ){ + /* schedule nearest Multicast RA */ + clear_timer(&iface->tm); + if (( next = ( iface->MinDelayBetweenRAs - + (tv.tv_sec - iface->last_multicast))) >0 ) { + send_ra(sock, iface, &addr->sin6_addr); + } + else{ + send_ra(sock, iface, NULL); + next = rand_between(iface->MinRtrAdvInterval, + iface->MaxRtrAdvInterval); + } + set_timer(&iface->tm, next); + } + /* else discard the RS */ + return; + } + + else{ delay = (int) (MAX_RA_DELAY_TIME*rand()/(RAND_MAX+1.0)); dlog(LOG_DEBUG, 3, "random mdelay for %s: %d", iface->Name, delay); mdelay(delay); + } if (iface->UnicastOnly - || tv.tv_sec - iface->last_multicast < MIN_DELAY_BETWEEN_RAS) + || tv.tv_sec - iface->last_multicast < iface->MinDelayBetweenRAs) { /* * unicast reply @@ -169,15 +398,48 @@ /* * multicast reply */ - - clear_timer(&iface->tm); send_ra(sock, iface, NULL); + } +} - next = rand_between(iface->MinRtrAdvInterval, iface->MaxRtrAdvInterval); - set_timer(&iface->tm, next); +/* + * Process Delegation Chain Solicitation. + */ + +static void +process_dcs(int sock, struct Interface *iface, + struct in6_addr *src, struct in6_addr *addr, uint16_t id) +{ + int delay; + double next; + struct timeval tv; + + dlog(LOG_DEBUG, 4, "processing Delegation Chain Solicit on %s", + iface->Name); + gettimeofday(&tv, NULL); + + delay = (int) (MAX_RA_DELAY_TIME*rand()/(RAND_MAX+1.0)); + dlog(LOG_DEBUG, 3, "random mdelay for %s: %d", iface->Name, delay); + mdelay(delay); + + if (iface->UnicastOnly || + tv.tv_sec - iface->last_multicast < iface->MinDelayBetweenRAs) + { + /* + * unicast reply + */ + send_dca(sock, iface, src, addr, id); + } + else + { + /* + * multicast reply + */ + send_dca(sock, iface, src, NULL, id); } } + /* * check router advertisements according to RFC 2461, 6.2.7 */ @@ -187,10 +449,22 @@ { struct nd_router_advert *radvert; char addr_str[INET6_ADDRSTRLEN]; + char intaddr_str[INET6_ADDRSTRLEN]; + char prefix_str[INET6_ADDRSTRLEN]; + struct MobilityAccessPoint *map, *tmpmap , *maplist=NULL; + time_t interval = 0; uint8_t *opt_str; print_addr(&addr->sin6_addr, addr_str); + print_addr(&(iface->if_addr), intaddr_str); + dlog(LOG_DEBUG, 4, "Received RA from: %s",addr_str); + dlog(LOG_DEBUG, 4, "on If with addr : %s",intaddr_str); + /* gets rid of issue only when one interface per subnet */ + if(addr_match(&(iface->if_addr), &(addr->sin6_addr), 128)){ + dlog(LOG_DEBUG, 4, "ignore RA , comes from ourself"); + return; + } radvert = (struct nd_router_advert *) msg; if ((radvert->nd_ra_curhoplimit && iface->AdvCurHopLimit) && @@ -239,7 +513,8 @@ struct nd_opt_prefix_info *pinfo; struct nd_opt_mtu *mtu; struct AdvPrefix *prefix; - char prefix_str[INET6_ADDRSTRLEN]; + struct nd_opt_map *mapinfo; + struct nd_opt_adv_interval *ivalinfo = NULL; uint32_t preferred, valid; if (len < 2) @@ -251,6 +526,7 @@ optlen = (opt_str[1] << 3); + dlog(LOG_DEBUG, 5, "option %hhd length: %hhd",*opt_str, optlen); if (optlen == 0) { log(LOG_ERR, "zero length option in RA on %s from %s", @@ -270,6 +546,7 @@ case ND_OPT_MTU: mtu = (struct nd_opt_mtu *)opt_str; + dlog(LOG_DEBUG, 4, "option %hhd (MTU) length: %hhd",*opt_str, optlen); if (iface->AdvLinkMTU && (ntohl(mtu->nd_opt_mtu_mtu) != iface->AdvLinkMTU)) { log(LOG_WARNING, "our AdvLinkMTU on %s doesn't agree with %s", @@ -281,6 +558,7 @@ preferred = ntohl(pinfo->nd_opt_pi_preferred_time); valid = ntohl(pinfo->nd_opt_pi_valid_time); + dlog(LOG_DEBUG, 4, "option %hhd (PREFIX) length: %hhd",*opt_str, optlen); prefix = iface->AdvPrefixList; while (prefix) { @@ -315,6 +593,7 @@ } break; case ND_OPT_SOURCE_LINKADDR: + dlog(LOG_DEBUG, 4, "option %hhd (SOURCELINK) length: %hhd",*opt_str, optlen); /* not checked */ break; case ND_OPT_TARGET_LINKADDR: @@ -324,8 +603,59 @@ break; /* Mobile IPv6 extensions */ case ND_OPT_RTR_ADV_INTERVAL: + ivalinfo = (struct nd_opt_adv_interval *) opt_str; + + /* round up received Adv interval to next second */ + /* granularity not so fine for advertising */ + interval = (time_t)(( ((unsigned long)htonl( + ivalinfo->nd_opt_adv_interval_ival)) + +1000)/1000); + + dlog(LOG_DEBUG, 4, "option %hhd (Interval opt) " + "length: %hhd",*opt_str, optlen); + dlog(LOG_DEBUG, 4, " interval (s): %lu", + interval); + break; case ND_OPT_HOME_AGENT_INFO: /* not checked */ + dlog(LOG_DEBUG, 4, "option %hhd (MIP6options) length: %hhd",*opt_str, optlen); + break; + /* HMIPv6 extensions */ + case ND_OPT_MAP: + /* Only if Accepting MAP options */ + /* (RecvHmip6MapInfo on) */ + /* should we process further */ + if( iface->RecvHmip6MapInfo){ + mapinfo = (struct nd_opt_map *) opt_str; + + dlog(LOG_DEBUG, 4, "option %hhd (HMIP6_MAP) length: %hhd",*opt_str, optlen); + + /* check map parameters, and allocate MAP */ + + if(!(check_map_address(&mapinfo->nd_opt_map_globaladdr) && + check_map_flags(mapinfo->nd_opt_map_flags_reserved))){ + print_addr( &mapinfo->nd_opt_map_globaladdr, prefix_str); + dlog(LOG_DEBUG, 4, "invalid map %s",prefix_str); + break; + } + + /* allocate and initialise MAP */ + if((tmpmap = process_map_opt(mapinfo)) == NULL){ + log(LOG_ERR, "Unable to process MAP option"); + return; + } + + tmpmap->srcIfIndex = iface->if_index; + memcpy(&(tmpmap->srcAddress), &addr->sin6_addr, + sizeof( struct in6_addr)); + + tmpmap->next=maplist; + maplist=tmpmap; + } + else{ + /* Skip Option */ + dlog(LOG_DEBUG, 4, "discarding Hierarchical MIPv6 MAP option, interface set to ignore"); + } break; default: dlog(LOG_DEBUG, 1, "unknown option %d in RA on %s from %s", @@ -336,6 +666,25 @@ len -= optlen; opt_str += optlen; } + /* process MAP options after receiving all option headers */ + + while(maplist != NULL){ + tmpmap = maplist; + maplist = maplist->next; + + /* set interval timer if available */ + if(interval) + tmpmap->dynInterval = interval; + + print_addr(&tmpmap->globalAddress, prefix_str); + dlog(LOG_DEBUG, 4, "receive unknown mapadv from: %s %d %s", + iface->Name, iface->if_index, addr_str); + dlog(LOG_DEBUG, 4, "mapaddr: %s", prefix_str); + + maptable_insert(tmpmap); + tmpmap->next= NULL; + free(tmpmap); + } } static int Binary files ../tools/radvd-0.7.2/radvd and ./radvd/radvd/radvd differ diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/radvd.c ./radvd/radvd/radvd.c --- ../tools/radvd-0.7.2/radvd.c Fri Dec 28 19:39:54 2001 +++ ./radvd/radvd/radvd.c Mon Jun 23 13:23:36 2003 @@ -18,6 +18,7 @@ #include #include #include +#include struct Interface *IfaceList = NULL; @@ -182,6 +183,12 @@ if (sock < 0) exit(1); + /* Linux only*/ +#if 0 + if(init_netlink_socket()<0) + exit(1); + +#endif /* 0 */ /* drop root privileges if requested. */ if (username) { if (drop_root_privileges(username) < 0) @@ -208,6 +215,10 @@ log(LOG_WARNING, "IPv6 forwarding seems to be disabled, but continuing anyway."); } + /* initialise map propagation */ + + init_maptable(); + /* parse config file */ if (readin_config(conf_file) < 0) exit(1); @@ -289,6 +300,8 @@ dlog(LOG_DEBUG, 4, "timer_handler called for %s", iface->Name); + iface->NumFastRSReq=0; + send_ra(sock, iface, NULL); next = rand_between(iface->MinRtrAdvInterval, iface->MaxRtrAdvInterval); @@ -314,6 +327,7 @@ /* send an initial advertisement */ send_ra(sock, iface, NULL); + /* TODO: need to update for DCS/DCA */ set_timer(&iface->tm, iface->MaxRtrAdvInterval); } } @@ -336,6 +350,11 @@ dlog(LOG_DEBUG, 4, "disabling timer for %s", iface->Name); clear_timer(&iface->tm); } + + /* clear the MAP table */ + + + clear_maptable(); iface=IfaceList; while(iface) diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/radvd.conf.5.man ./radvd/radvd/radvd.conf.5.man --- ../tools/radvd-0.7.2/radvd.conf.5.man Fri Jun 21 21:57:15 2002 +++ ./radvd/radvd/radvd.conf.5.man Fri Nov 28 15:50:28 2003 @@ -27,7 +27,7 @@ .nf .BR "interface " "name " { list of interface specific options - list of prefix definitions + list of prefix and HMIPv6 map definitions .B }; .fi @@ -49,6 +49,21 @@ All the possible prefix specific options are described below. Each option has to be terminated by a semicolon. +MAP definitions for Hierarchical Mobile IPv6 (HMIPv6) are of the form: + +.nf +.BR "map " map-address " " { + list of map specific options +.B }; +.fi + +The map-address must be a globally scoped (or very rarely site-scoped) +address for the MAP. This address may be on the RA advertising router +or may be one a remote device. + +All the possible map specific options are described below. Each +option has to be terminated by a semicolon. + Decimal values are allowed only for MaxRtrAdvInterval and MinRtrAdvInterval. Decimal values should be used only when using Mobile IPv6 extensions. @@ -88,7 +103,7 @@ Must be no less than 4 seconds and no greater than 1800 seconds. -Minimum when using Mobile IPv6 extensions: 1.5. +Minimum when using Mobile IPv6 extensions: 0.07. Default: 600 seconds @@ -101,11 +116,25 @@ Must be no less than 3 seconds and no greater than 0.75 * MaxRtrAdvInterval. -Minimum when using Mobile IPv6 extensions: 0.05. +Minimum when using Mobile IPv6 extensions: 0.03. Default: 0.33 * MaxRtrAdvInterval .TP +.BR "MinDelayBetweenRAs " seconds + +The minimum time allowed between sending multicast +router advertisements from the interface, in seconds. + +This applies to solicited multicast RAs. +This is defined as the protocol constant MIN_DELAY_BETWEEN_RAS in RFC2461. +MIPv6 redefines this parameter to have a minimum of 0.03s + +Minimum when using Mobile IPv6 extensions: 0.03. + +Default: 3 + +.TP .BR AdvManagedFlag " " on | off When set, hosts use the administered (stateful) protocol for address @@ -183,7 +212,7 @@ Must be either zero or between MaxRtrAdvInterval and 9000 seconds. -Default: 3 * MaxRtrAdvInterval +Default: 3 * MaxRtrAdvInterval (Minimum 1 second). .TP .BR AdvSourceLLAddress " " on | off @@ -239,6 +268,29 @@ Default: 0 .TP +.BR FastRSResponse " " on | off + +When set, this flag removes the RFC2461 specified delay before +sending an RA after an RS is received. This works for Unicast and +and multicast request packets. + +This works for MaxFastRS packets per Multicast Advertisement Interval, in +compliance to draft-mkhalil-ipv6-fastra-01.txt (june 2002) + +Default: off + +.TP +.BR MaxFastRS " " integer + +Modifies the number of Fast Responses to Router Solicitation per +Multicast Advertisement Interval. +If more packets than this value are received, a Multicast RA will be +scheduled (At the earliest possible time). Further Router Solicitations +will be ignored until this Multicast RA is performed. + +Default: 10 + +.TP .BR AdvIntervalOpt " " on | off When set, Advertisement Interval Option (specified by Mobile IPv6) @@ -248,6 +300,46 @@ Default: off +.TP +.BR AdvIfDown " " on | off + +Determines if the Interface may be in Down state when radvd starts. +By default radvd will terminate if a configured interface is down at +initialization time. + +Setting this to "on" ensures that if an interface is down, it will +not affect initialization and that when the interface comes up, packets +will be start being sent. + +Default: off + + +.TP +.BR AdvHmip6MapInfo " " on | off + +Determines if MAPs configured locally on this interface will be +advertised as MAP options. + +Default: off + +.TP +.BR RecvHmip6MapInfo " " on | off + +Determines if MAP options received on this interface will be processed. +If this is switched on, MAP option information will be stored in a +central table for re-advertisement out eligible interfaces. + +Default: off + +.TP +.BR ReAdvHmip6MapInfo " " on | off + +Determines if MAP options received on other interfaces will be +retransmitted from this one. The re-advertised options have their +distance increased by one prior to transmission. + +Default: off + .SH PREFIX SPECIFIC OPTIONS .TP @@ -341,6 +433,123 @@ Default: 6to4 is not used +.SH MAP SPECIFIC OPTIONS + +.TP +.BR "MapDistance " integer + +A number from 1 to 15 indicating the distance away of the MAP. +This is not meant to be a strict hop-count indication, except in +the case where the MAP is on this Access Router, in which it should +be set to one. + +a Zero Value must not be set. + +This distance value is incremented in RA Propagated MAP discovery, +by each router passing along the MAP Option, if Map option re-advertising +is on. + +Default: 1 + +.TP +.BR "MapPreference " integer + +A number from 0-15 which indicates the relative preference of +this MAP amongst others. O is the most preferred, 15 is the least +and indicates that this MAP is not to be selected (this value may +be present for MN's with existing MAP bindings). + +Default:7 + +.TP +.BR MapExtendedMode " " on | off + +Sets the 'M' bit in the MAP option. + +This bit indicates that the MAP is in Extended mode. + +If only one of MapRcoaPrefix and MapExtendedMode is set, then the +other will be set to the inverse. + +Default: off + +Requires: MapRcoaPrefix off + +.TP +.BR MapRcoaPrefix " " on | off + +Sets the 'R' bit in the MAP option. + +This bit indicates that the MAP is in Basic mode and that MN's +should choose an RCoA in the 64 bit prefix associated +with the MAP's address. + +If only one of MapRcoaPrefix and MapExtendedMode is set, then the +other will be set to the inverse. + +Default : on + +Requires: MapExtendedMode off + +.TP +.BR MapTopology " " on | off + +Sets the 'T' bit in the MAP option. + +This bit indicates that the Prefix of the link care-of-address +is not topologically correct on the Internet, and that the MN +must use the MAP's Global Address as a packet source address. +This bit may only be set if in HMIPv6 Extended Mode. + +Default: off + +Requires: MapExtendedMode on + +.TP +.BR MapPrivacy " " on | off + +Sets the 'I' bit in the MAP option. + +This bit allows the MN to set the RCoA as the source address of +outgoing packets in order to provide location privacy from +devices on the Internet. + +Default: off + +Requires: MapRcoaPrefix on + +.TP +.BR MapPacketSource " " on | off + +sets the 'P' bit in the MAP option. + +This bit forces the MNs to hide the LCoA by putting the RCoA +in the packet as source address. + +Default: off + +Requires: MapRcoaPrefix on + +.TP +.BR MapReverseTunnel " " on | off + +Sets the 'V' bit in the MAP option. + +This bit forces the MN to reverse tunnel outgoing Packets to +the MAP address. + +Default: off + +Requires: MapExtendedMode on + +.TP +.BR "MapValidLifetime " integer + +Maximum Valid lifetime for advertisement of the MAP prefix +and also for HMIPv6 binding updates to the MAP. + +Default: 2592000 seconds (30 days) + .SH EXAMPLES .nf @@ -409,6 +618,48 @@ ppp0 at configuration time. (IPv6 addresses are written in hexadecimal whereas IPv4 addresses are written in decimal, so the IPv4 address WW.XX.YY.ZZ in the 6to4 prefix will be represented in hex.) + + +For HMIPv6 MAP advertisement, include the address of the MAP +in a +.B map +section, and set +.B AdvHmip6MapInfo on +: + + +.nf +interface eth0 +{ + AdvSendAdvert on; + + AdvIntervalOpt; + + AdvHmip6MapInfo on; + + map fec0:0:0:8::ff + { + MapRcoaPrefix on; + MapPreference 2; + MapValidLifetime 1200; + } + + prefix fec0:0:0:1::4/64 + { + AdvOnLink on; + AdvAutonomous on; + AdvRouterAddr on; + }; +}; +.fi + +The MAP option's parameters may be set by setting variables in the MAP section. +unspecified options will be set to their default values, except in the case of +.B MapRcoaPrefix +and +.B MapExtendedMode +which will assume inverse values of one another. In the above example, +MapExtendedMode would be turned off. .SH FILES diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/radvd.h ./radvd/radvd/radvd.h --- ../tools/radvd-0.7.2/radvd.h Thu Nov 15 06:58:11 2001 +++ ./radvd/radvd/radvd.h Mon Jun 23 13:23:36 2003 @@ -57,6 +57,7 @@ int AdvSendAdvert; double MaxRtrAdvInterval; double MinRtrAdvInterval; + double MinDelayBetweenRAs; int AdvManagedFlag; int AdvOtherConfigFlag; int AdvLinkMTU; @@ -65,6 +66,7 @@ int AdvCurHopLimit; int AdvDefaultLifetime; int AdvSourceLLAddress; + int AdvIfDown; int UnicastOnly; /* Mobile IPv6 extensions */ @@ -73,9 +75,26 @@ int AdvHomeAgentFlag; int16_t HomeAgentPreference; uint16_t HomeAgentLifetime; + int FastRSResponse; + int NumFastRSReq; + int MaxFastRS; + + /* Hierarchical MobileIPv6 extensions */ + + int RecvHmip6MapInfo; + int AdvHmip6MapInfo; + int ReAdvHmip6MapInfo; + + /* Link ID advertisement */ + int AdvLinkID; + uint32_t LinkID; + uint8_t LinkIDAmbiguity; struct AdvPrefix *AdvPrefixList; + struct MobilityAccessPoint *Hmip6MapList; struct timer_lst tm; + struct timeval ra_callbacktime; + struct timeval dca_callbacktime; unsigned long last_multicast; struct Interface *next; @@ -117,6 +136,41 @@ uint16_t lifetime; }; +/* Hierarchical MobileIPv6 extensions */ + +#define MAP_DYNAMIC_LEARN ( 1 ) +#define MAP_INTERFACE_STATIC ( 0 ) + +struct MobilityAccessPoint { + uint8_t type; + uint8_t length; + uint8_t distance:4; + uint8_t preference:4; + /*uint8_t prefixLen; */ + u_int8_t RcoaPrefix:1; /* Form an RCoA from the prefix */ + u_int8_t ExtendedMode:1; /* Use Hmip6 Extended Mode */ + u_int8_t Privacy:1; /* MN may use RCoA as source addr */ + u_int8_t Topology:1; /* Topologically Incorrect Prefix */ + u_int8_t PacketSource:1; /* Use Rcoa in Packet Source Addr */ + u_int8_t ReverseTunnel:1;/* Reverse Tunnel Packets to MAP */ + u_int8_t reserved2:2; + uint32_t validLifetime; + struct in6_addr globalAddress; + int enabled; /* on or off flag...*/ + struct MobilityAccessPoint *next; + int dynamic; /* on or off flag...*/ + int srcIfIndex; /* origin of packet (st/dyn) */ + struct in6_addr srcAddress; /* origin of packet (dyn)*/ + time_t lastUpdate; + time_t dynInterval; +}; + + +struct InterfaceOptions{ + struct AdvPrefix *plist; + struct MobilityAccessPoint *mlist; + struct in6_addr *llocal; +}; /* gram.y */ int yyparse(void); @@ -145,9 +199,12 @@ int setup_allrouters_membership(int, struct Interface *); int check_allrouters_membership(int, struct Interface *); int get_v4addr(const char *, unsigned int *); +int init_netlink_socket(void); /* interface.c */ void iface_init_defaults(struct Interface *); +void local_map_init_defaults(struct MobilityAccessPoint *); +int setup_hmipv6_iface(struct Interface *); void prefix_init_defaults(struct AdvPrefix *); int check_iface(struct Interface *); @@ -168,5 +225,9 @@ void mdelay(int); double rand_between(double, double); void print_addr(struct in6_addr *, char *); + +/* list.c */ +extern struct AdvPrefix *prefixlist_combine(struct AdvPrefix *, struct AdvPrefix *); +extern struct MobilityAccessPoint *maplist_combine(struct MobilityAccessPoint *, struct MobilityAccessPoint *); #endif Binary files ../tools/radvd-0.7.2/radvdump and ./radvd/radvd/radvdump differ diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/radvdump.c ./radvd/radvd/radvdump.c --- ../tools/radvd-0.7.2/radvdump.c Mon Dec 31 22:40:56 2001 +++ ./radvd/radvd/radvdump.c Mon Aug 12 15:21:16 2002 @@ -223,6 +223,7 @@ struct nd_opt_mtu *mtu; struct AdvInterval *a_ival; struct HomeAgentInfo *ha_info; + struct nd_opt_map *mapinfo; char prefix_str[INET6_ADDRSTRLEN]; if (len < 2) @@ -320,6 +321,34 @@ printf("\t\tHomeAgentLifetime: %hu", (unsigned short)ntohs(ha_info->lifetime)); printf("\n"); break; + case ND_OPT_MAP: + mapinfo = (struct nd_opt_map *) opt_str; + print_addr(&(mapinfo->nd_opt_map_globaladdr), prefix_str); + printf("\tMAP %s\n", prefix_str); + printf("\t\tMapDistance: %hhu\n", + (unsigned char) ((mapinfo->nd_opt_map_dist_pref) >>4) & 0x0f); + printf("\t\tMapPreference: %hhd\n", + (unsigned char) (mapinfo->nd_opt_map_dist_pref & + 0x0f)); + printf("\t\tMapRcoaPrefix: %s\n", + ((mapinfo->nd_opt_map_flags_reserved + & ND_OPT_MAP_FLAG_R) ? "on" : "off")); + printf("\t\tMapExtendedMode: %s\n", + ((mapinfo->nd_opt_map_flags_reserved + & ND_OPT_MAP_FLAG_M) ? "on" : "off")); + printf("\t\tMapTopology: %s\n", + ((mapinfo->nd_opt_map_flags_reserved + & ND_OPT_MAP_FLAG_T) ? "on" : "off")); + printf("\t\tMapPrivacy: %s\n", + ((mapinfo->nd_opt_map_flags_reserved + & ND_OPT_MAP_FLAG_I) ? "on" : "off")); + printf("\t\tMapPacketSource: %s\n", + ((mapinfo->nd_opt_map_flags_reserved + & ND_OPT_MAP_FLAG_P) ? "on" : "off")); + + printf("\t\tMapValidLifetime: %lu\n", + ntohl(mapinfo->nd_opt_map_valid_time)); + break; case ND_OPT_TARGET_LINKADDR: case ND_OPT_REDIRECTED_HEADER: log(LOG_ERR, "invalid option %d in RA", (int)*opt_str); @@ -477,6 +506,7 @@ { int optlen; struct nd_opt_prefix_info *pinfo; + struct nd_opt_map *mapinfo; char prefix_str[INET6_ADDRSTRLEN]; if (orig_len < 2) @@ -545,6 +575,39 @@ (pinfo->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_RADDR)?"on":"off"); printf("\t}; # End of prefix definition\n\n"); + break; + case ND_OPT_MAP : + mapinfo = (struct nd_opt_map *) opt_str; + print_addr(&(mapinfo->nd_opt_map_globaladdr), prefix_str); + printf("\tmap %s\n", prefix_str); + printf("\t{\n"); + printf("\t\tMapDistance %hhu;\n", + (unsigned char) ((mapinfo->nd_opt_map_dist_pref + >>4)& 0x0f)); + printf("\t\tMapPreference %hhd;\n", + (unsigned char) (mapinfo->nd_opt_map_dist_pref & + 0x0f)); + /* in file do not print MapRcoaPrefix, */ + /* use !MapExtendedMode */ + printf("\t\tMapExtendedMode %s;\n", + ((mapinfo->nd_opt_map_flags_reserved + & ND_OPT_MAP_FLAG_M) ? "on" : "off")); + printf("\t\tMapTopology %s;\n", + ((mapinfo->nd_opt_map_flags_reserved + & ND_OPT_MAP_FLAG_T) ? "on" : "off")); + printf("\t\tMapPrivacy %s;\n", + ((mapinfo->nd_opt_map_flags_reserved + & ND_OPT_MAP_FLAG_I) ? "on" : "off")); + printf("\t\tMapPacketSource %s;\n", + ((mapinfo->nd_opt_map_flags_reserved + & ND_OPT_MAP_FLAG_P) ? "on" : "off")); + + printf("\t\tMapValidLifetime %lu;\n", + ntohl(mapinfo->nd_opt_map_valid_time)); + printf("\t};\n"); + break; + case ND_OPT_TARGET_LINKADDR: + break; default: break; diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/scanner.l ./radvd/radvd/scanner.l --- ../tools/radvd-0.7.2/scanner.l Fri Jul 12 07:26:16 2002 +++ ./radvd/radvd/scanner.l Mon Jun 23 13:23:36 2003 @@ -43,6 +43,8 @@ interface { return T_INTERFACE; } prefix { return T_PREFIX; } +map { return T_MAP; } +lladdr { return T_LLADDR; } AdvSendAdvert { return T_AdvSendAdvert; } MaxRtrAdvInterval { return T_MaxRtrAdvInterval; } @@ -55,6 +57,7 @@ AdvCurHopLimit { return T_AdvCurHopLimit; } AdvDefaultLifetime { return T_AdvDefaultLifetime; } AdvSourceLLAddress { return T_AdvSourceLLAddress; } +AdvIfDown { return T_AdvIfDown; } AdvOnLink { return T_AdvOnLink; } AdvAutonomous { return T_AdvAutonomous; } @@ -67,10 +70,30 @@ AdvHomeAgentInfo { return T_AdvHomeAgentInfo; } UnicastOnly { return T_UnicastOnly; } +HackAdvLinkID { return T_HackAdvLinkID; } + +FastRSResponse { return T_FastRSResponse; } +MaxFastRS { return T_MaxFastRS; } + +RecvHmip6MapInfo { return T_RecvHmip6MapInfo; } +AdvHmip6MapInfo { return T_AdvHmip6MapInfo; } +ReAdvHmip6MapInfo { return T_ReAdvHmip6MapInfo; } + Base6to4Interface { return T_Base6to4Interface; } HomeAgentPreference { return T_HomeAgentPreference; } HomeAgentLifetime { return T_HomeAgentLifetime; } + +MapDistance { return T_MapDistance; } +MapPreference { return T_MapPreference; } +MapExtendedMode { return T_MapExtendedMode; } +MapTopology { return T_MapTopology; } +MapPrivacy { return T_MapPrivacy; } +MapPacketSource { return T_MapPacketSource; } +MapReverseTunnel { return T_MapReverseTunnel; } +MapValidLifetime { return T_MapValidLifetime; } + +MinDelayBetweenRAs { return T_MinDelayBetweenRAs; } {addr} { static struct in6_addr addr; diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/send.c ./radvd/radvd/send.c --- ../tools/radvd-0.7.2/send.c Tue Oct 29 04:41:27 2002 +++ ./radvd/radvd/send.c Mon Jun 23 13:23:36 2003 @@ -17,6 +17,58 @@ #include #include #include +#include "linkid.h" +#include "maptable.h" + + +time_t dynlifetime(struct MobilityAccessPoint *map ){ + + time_t move_interval; + time_t valid_left; + +#include "linkid.h" + if(!map->validLifetime){ + return 0; + } + dlog(LOG_DEBUG, 3, "dynlifetime() "); + if(map->dynInterval) + move_interval = (time_t) ((2 * map->dynInterval)) ; + + + dlog(LOG_DEBUG, 3, "interval %lu 2 * = %lu ", + map->dynInterval, move_interval); + + valid_left = (time_t) map->validLifetime - + (time(NULL) - map->lastUpdate); + dlog(LOG_DEBUG, 3, "valid_left %lu lastUp %lu", + valid_left,map->lastUpdate); + if(map->dynInterval && ((time(NULL) - (2 * map->dynInterval)) + > map->lastUpdate)) + valid_left = 0; + + return valid_left; +} + +int map_better(struct MobilityAccessPoint *map, struct MobilityAccessPoint *best,int ifindex){ + /* do not select a map which is unupdated */ + if(map->dynInterval && ((time(NULL) - (2 * map->dynInterval)) + > map->lastUpdate)) + return 0; + + /* if the first map was unupdated, move off it */ + if(best->dynInterval && ((time(NULL) - (2 * best->dynInterval)) + > best->lastUpdate)) + return 1; + + if(map->distance < best->distance) + return 1; + + if((map->distance == best->distance) + && (map->srcIfIndex == ifindex )) + return 1; + + return 0; +} void send_ra(int sock, struct Interface *iface, struct in6_addr *dest) @@ -29,11 +81,17 @@ struct iovec iov; char chdr[CMSG_SPACE(sizeof(struct in6_pktinfo))]; struct nd_router_advert *radvert; - struct AdvPrefix *prefix; + struct AdvPrefix *prefix=NULL; + struct MobilityAccessPoint *map = NULL; unsigned char buff[MSG_SIZE]; + char addr_str[INET6_ADDRSTRLEN]; int len = 0; - int err; + int err,fd = 0; + if(!iface->if_index && (setup_linklocal_addr(fd,iface)<0)){ + log(LOG_WARNING, "unable to send on interface %s",iface->Name); + return; + } /* Make sure that we've joined the all-routers multicast group */ if (check_allrouters_membership(sock, iface) < 0) log(LOG_WARNING, "problem checking all-routers membership on %s", iface->Name); @@ -79,12 +137,15 @@ prefix = iface->AdvPrefixList; + dlog(LOG_DEBUG, 3, "preentry prefix %p", prefix); /* * add prefix options */ while(prefix) { + dlog(LOG_DEBUG, 3, "Adding prefix on %p", prefix); + if( prefix->enabled ) { struct nd_opt_prefix_info *pinfo; @@ -158,11 +219,18 @@ * Mobile IPv6 ext: Advertisement Interval Option to support * movement detection of mobile nodes */ - if(iface->AdvIntervalOpt) { struct AdvInterval a_ival; - uint32_t ival = (iface->MaxRtrAdvInterval * 1000); + uint32_t ival; + if(iface->MaxRtrAdvInterval < Cautious_MaxRtrAdvInterval){ + ival = ((iface->MaxRtrAdvInterval + + Cautious_MaxRtrAdvInterval_Leeway ) * 1000); + + } + else { + ival = (iface->MaxRtrAdvInterval * 1000); + } a_ival.type = ND_OPT_RTR_ADV_INTERVAL; a_ival.length = 1; a_ival.reserved = 0; @@ -171,12 +239,10 @@ memcpy(buff + len, &a_ival, sizeof(a_ival)); len += sizeof(a_ival); } - /* * Mobile IPv6 ext: Home Agent Information Option to support * Dynamic Home Agent Address Discovery */ - if(iface->AdvHomeAgentInfo && (iface->HomeAgentPreference != 0 || iface->HomeAgentLifetime != iface->AdvDefaultLifetime)) { @@ -190,7 +256,202 @@ memcpy(buff + len, &ha_info, sizeof(ha_info)); len += sizeof(ha_info); } + /* + * LinkID option advertisement + * TODO: check if we have a LinkID: + * check if ambiguous: if so, only send on RAs to All-Routers. + * else, all RAs have LinkID. + */ + if(iface->AdvLinkID && /*(*/iface->LinkID /* || conflict) && + dst == All routers || ! + ambiguous */){ + struct nd_opt_linkid linkid; + memset(&linkid, 0, sizeof(struct nd_opt_linkid)); + linkid.nd_opt_lid_type = ND_OPT_LINKID; + linkid.nd_opt_lid_len = 1; + linkid.nd_opt_lid_linkid = htonl(iface->LinkID); + linkid.nd_opt_lid_flags_reserved |= + ( iface->LinkIDAmbiguity ? + ND_OPT_LID_FLAG_AMBIGUOUS :0 ) ; + memcpy(buff + len, &linkid, sizeof(linkid)); + len += sizeof(linkid); + } + + /* + * add map options + */ + + dlog(LOG_DEBUG, 4, "len before MAP: %d", len); + if(iface->AdvHmip6MapInfo) + { + map = iface->Hmip6MapList; + dlog(LOG_DEBUG, 4, "MAP Advertising allowed on this interface: %s", iface->Name); + } + else{ + dlog(LOG_DEBUG, 4, "MAP advertising disallowed on interface: %s", iface->Name); + } + + while(map) + { + if( map->enabled ) + { + struct nd_opt_map *mapinfo; + + print_addr(&map->globalAddress, addr_str); + dlog(LOG_DEBUG, 4, "MAP enabled: %s", addr_str); + + mapinfo = (struct nd_opt_map *) (buff + len); + + mapinfo->nd_opt_map_type = ND_OPT_MAP; + mapinfo->nd_opt_map_length = 3; + + mapinfo->nd_opt_map_dist_pref = + (((uint8_t) (map->distance) )<< 4) | + ((uint8_t) map->preference); + + mapinfo->nd_opt_map_flags_reserved = + (map->RcoaPrefix)? ND_OPT_MAP_FLAG_R:0; + mapinfo->nd_opt_map_flags_reserved |= + (map->ExtendedMode)?ND_OPT_MAP_FLAG_M:0; + mapinfo->nd_opt_map_flags_reserved |= + (map->Privacy)? ND_OPT_MAP_FLAG_I:0; + mapinfo->nd_opt_map_flags_reserved |= + (map->Topology)? ND_OPT_MAP_FLAG_T:0; + mapinfo->nd_opt_map_flags_reserved |= + (map->PacketSource)?ND_OPT_MAP_FLAG_P:0; + mapinfo->nd_opt_map_flags_reserved |= + (map->ReverseTunnel)?ND_OPT_MAP_FLAG_V:0; + + mapinfo->nd_opt_map_valid_time = + htonl(map->validLifetime); + + memcpy(&mapinfo->nd_opt_map_globaladdr, + &map->globalAddress, sizeof(struct in6_addr)); + + len += (mapinfo->nd_opt_map_length <<3); + } + else + { + dlog(LOG_DEBUG, 4, "MAP disabled: %d", map); + } + map = map->next; + } + if(iface->ReAdvHmip6MapInfo){ + int looseStatic,splitHorizon; + dlog(LOG_DEBUG, 4, "MAP ReAdvertising allowed: %s", iface->Name); + + + maptable_lock(); + + dlog(LOG_DEBUG, 4, "MAP cleanup"); + maptable_cleanup_unsafe(); + dlog(LOG_DEBUG, 4, "MAP maptable get"); + + looseStatic = maptable_looseStatic(); + splitHorizon = maptable_splitHorizon(); + map = get_maptable_unsafe(); + while(map){ + print_addr(&map->globalAddress, addr_str); + dlog(LOG_DEBUG, 4, "MAP ??????: %s", addr_str); + map=map->next; + } + map = get_maptable_unsafe(); + while(map){ + + if(map->dynamic){ + struct MobilityAccessPoint *best; + /* have passed all static entries */ + /* pick best dynamic entry */ + print_addr(&map->globalAddress, addr_str); + dlog(LOG_DEBUG, 4, "MAP dynamic: %s", addr_str); + best = map; + map=map->next; + while(map && !memcmp(&map->globalAddress, + &best->globalAddress, + sizeof (struct in6_addr))){ + /* TODO: what about lifetimes ?? */ + + if(map_better(map, best,iface->if_index)){ + /* (map->distance < best->distance) || best-> + ((map->distance == best->distance) + && (map->srcIfIndex == iface->if_index ))){ */ + /* make sure that best metric is saved */ + /* if equal cost best metric, make sure*/ + /* we save the adv with came from this */ + /* interface, if present(split-horizon)*/ + best = map; + } + map = map->next; + } + /* include the best entry for this MAP */ + if(!(splitHorizon &&(iface->if_index == best->srcIfIndex))){ + struct nd_opt_map *mapinfo; + /* split-horizon: may send packet */ + + mapinfo = (struct nd_opt_map *) (buff + len); + + mapinfo->nd_opt_map_type = ND_OPT_MAP; + mapinfo->nd_opt_map_length = 3; + + mapinfo->nd_opt_map_dist_pref = + (((uint8_t) (best->distance) )<< 4) | + ((uint8_t) best->preference); + + mapinfo->nd_opt_map_flags_reserved = + (best->RcoaPrefix)? ND_OPT_MAP_FLAG_R:0; + mapinfo->nd_opt_map_flags_reserved |= + (best->ExtendedMode)?ND_OPT_MAP_FLAG_M:0; + mapinfo->nd_opt_map_flags_reserved |= + (best->Privacy)? ND_OPT_MAP_FLAG_I:0; + mapinfo->nd_opt_map_flags_reserved |= + (best->Topology)? ND_OPT_MAP_FLAG_T:0; + mapinfo->nd_opt_map_flags_reserved |= + (best->PacketSource)?ND_OPT_MAP_FLAG_P:0; + mapinfo->nd_opt_map_flags_reserved |= + (best->ReverseTunnel)?ND_OPT_MAP_FLAG_V:0; + + /* check if valid lifetime is less than */ + /* 2*adv int if so, mark it as ZERO */ + mapinfo->nd_opt_map_valid_time = + htonl(dynlifetime(best)); + + memcpy(&mapinfo->nd_opt_map_globaladdr, + &best->globalAddress, sizeof(struct in6_addr)); + + len += (mapinfo->nd_opt_map_length <<3); + } + } + else if(!looseStatic ||(map->srcIfIndex==iface->if_index)){ + struct MobilityAccessPoint *current; + /* redistribution of statics restricted */ + /* or interface has this map as static */ + + print_addr(&map->globalAddress, addr_str); + dlog(LOG_DEBUG, 4, "MAP strict/if: %s", addr_str); + + current = map; + map = map->next; + if(map){ + print_addr(&map->globalAddress, addr_str); + dlog(LOG_DEBUG, 4, "MAP next strict/if: %s", addr_str); + } + while(map && !memcmp(&map->globalAddress, + ¤t->globalAddress, + sizeof (struct in6_addr))){ + /* skip all entries for this map */ + map = map->next; + } + } + else{ /* ignore static entry */ + print_addr(&map->globalAddress, addr_str); + dlog(LOG_DEBUG, 4, "MAP unstrict: %s", addr_str); + map=map->next; + } + } + maptable_unlock(); + } + dlog(LOG_DEBUG, 4, "len after MAP: %d", len); iov.iov_len = len; iov.iov_base = (caddr_t) buff; @@ -204,6 +465,99 @@ pkt_info = (struct in6_pktinfo *)CMSG_DATA(cmsg); pkt_info->ipi6_ifindex = iface->if_index; memcpy(&pkt_info->ipi6_addr, &iface->if_addr, sizeof(struct in6_addr)); + +#ifdef HAVE_SIN6_SCOPE_ID + if (IN6_IS_ADDR_LINKLOCAL(&addr.sin6_addr) || + IN6_IS_ADDR_MC_LINKLOCAL(&addr.sin6_addr)) + addr.sin6_scope_id = iface->if_index; +#endif + + mhdr.msg_name = (caddr_t)&addr; + mhdr.msg_namelen = sizeof(struct sockaddr_in6); + mhdr.msg_iov = &iov; + mhdr.msg_iovlen = 1; + mhdr.msg_control = (void *) cmsg; + mhdr.msg_controllen = sizeof(chdr); + + err = sendmsg(sock, &mhdr, 0); + + if (err < 0) { + log(LOG_WARNING, "sendmsg: %s", strerror(errno)); + } +} + +void +send_dca(int sock, struct Interface *iface, struct in6_addr *src, + struct in6_addr *dest, uint16_t id) +{ + uint8_t all_hosts_addr[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; + struct sockaddr_in6 addr; + struct in6_pktinfo *pkt_info; + struct msghdr mhdr; + struct cmsghdr *cmsg; + struct iovec iov; + char chdr[CMSG_SPACE(sizeof(struct in6_pktinfo))]; + struct nd_del_chain_adv *chainadvert; + unsigned char buff[MSG_SIZE]; + char addr_str[INET6_ADDRSTRLEN]; + int len = 0; + int err,fd = 0; + + if(!iface->if_index && (setup_linklocal_addr(fd,iface)<0)){ + log(LOG_WARNING, "unable to send on interface %s",iface->Name); + return; + } + + /* Make sure that we've joined the all-routers multicast group */ + if (check_allrouters_membership(sock, iface) < 0) + log(LOG_WARNING, "problem checking all-routers membership on %s", iface->Name); + + dlog(LOG_DEBUG, 3, "sending DCA on %s", iface->Name); + + if (dest == NULL) + { + struct timeval tv; + + dest = (struct in6_addr *)all_hosts_addr; + gettimeofday(&tv, NULL); + + iface->last_multicast = tv.tv_sec; + } + + memset((void *)&addr, 0, sizeof(addr)); + addr.sin6_family = AF_INET6; + addr.sin6_port = htons(IPPROTO_ICMPV6); + memcpy(&addr.sin6_addr, dest, sizeof(struct in6_addr)); + + chainadvert = (struct nd_del_chain_adv *) buff; + + chainadvert->nd_dca_type = ND_DELEGATION_CHAIN_ADVERT; + chainadvert->nd_dca_code = 0; + chainadvert->nd_dca_cksum = 0; + chainadvert->nd_dca_identifier = htons(id); + /* currently no fragmentation */ + chainadvert->nd_dca_flag_component = htons(0 & (!ND_DCA_FLAG_MORE)) ; + chainadvert->nd_dca_reserved = 0; + + + len = sizeof(struct nd_del_chain_adv); + + /* add options here */ + + iov.iov_len = len; + iov.iov_base = (caddr_t) buff; + + memset(chdr, 0, sizeof(chdr)); + cmsg = (struct cmsghdr *) chdr; + + cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); + cmsg->cmsg_level = IPPROTO_IPV6; + cmsg->cmsg_type = IPV6_PKTINFO; + + pkt_info = (struct in6_pktinfo *)CMSG_DATA(cmsg); + pkt_info->ipi6_ifindex = iface->if_index; + /* XXX: HACK source address MUST be link-local */ + memcpy(&pkt_info->ipi6_addr, src, sizeof(struct in6_addr)); #ifdef HAVE_SIN6_SCOPE_ID if (IN6_IS_ADDR_LINKLOCAL(&addr.sin6_addr) || diff -rub --exclude=CVS --exclude=*~ --exclude=*.o --exclude=.deps --exclude=config.* --exclude=device.c --exclude=scanner.c --exclude=gram.[ch] --exclude=stamp-h --exclude=*.5 --exclude=*.8 --ignore-matching-lines=$Id: --exclude=Makefile --new-file ../tools/radvd-0.7.2/socket.c ./radvd/radvd/socket.c --- ../tools/radvd-0.7.2/socket.c Fri Jul 12 07:23:10 2002 +++ ./radvd/radvd/socket.c Mon Jun 23 13:23:36 2003 @@ -17,6 +17,7 @@ #include #include #include +#include "linkid.h" /* Note: these are applicable to receiving sockopts only */ #if defined IPV6_HOPLIMIT && !defined IPV6_RECVHOPLIMIT @@ -94,6 +95,7 @@ ICMP6_FILTER_SETBLOCKALL(&filter); ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter); ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter); + ICMP6_FILTER_SETPASS(ND_DELEGATION_CHAIN_SOLICIT, &filter); err = setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, sizeof(filter));