diff -rub --new-file radvd-0.7.1/Makefile.am radvd-0.7.1.hmipv6/Makefile.am --- radvd-0.7.1/Makefile.am Thu Nov 15 06:58:10 2001 +++ radvd-0.7.1.hmipv6/Makefile.am Tue Jul 23 15:51:48 2002 @@ -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 --new-file radvd-0.7.1/Makefile.in radvd-0.7.1.hmipv6/Makefile.in --- radvd-0.7.1/Makefile.in Wed Jan 16 03:51:26 2002 +++ radvd-0.7.1.hmipv6/Makefile.in Tue Jul 23 15:51:48 2002 @@ -106,7 +106,7 @@ 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 list.c maptable.c gram.y gram.h scanner.l radvd_LDADD = -lfl EXTRA_radvd_SOURCES = device-linux.c device-bsd44.c @@ -120,7 +120,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 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -133,12 +133,15 @@ 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 -radvd_DEPENDENCIES = +process.o interface.o device.o device-common.o gram.o scanner.o \ +maptable.o list.o +radvd_DEPENDENCIES = acconfig.h config.h defaults.h gram.h includes.h \ +pathnames.h maptable.h radvd.h radvd_LDFLAGS = radvdump_OBJECTS = log.o socket.o recv.o util.o radvdump.o radvdump_LDADD = $(LDADD) -radvdump_DEPENDENCIES = +radvdump_DEPENDENCIES = acconfig.h config.h defaults.h gram.h includes.h \ +pathnames.h radvd.h radvdump_LDFLAGS = LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LEXLIB = @LEXLIB@ diff -rub --new-file radvd-0.7.1/defaults.h radvd-0.7.1.hmipv6/defaults.h --- radvd-0.7.1/defaults.h Wed Jan 16 01:51:42 2002 +++ radvd-0.7.1.hmipv6/defaults.h Tue Jul 23 15:51:48 2002 @@ -41,6 +41,8 @@ next incarnation of it :) */ #define DFLT_AdvDefaultLifetime(iface) (3 * (iface)->MaxRtrAdvInterval) +/* don't care bit for advertising if Iface is down*/ +#define DFLT_AdvIfDown 0 /* Options sent with RA */ #define DFLT_AdvSourceLLAddress 1 @@ -108,6 +110,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) */ @@ -145,5 +150,57 @@ /* #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 --new-file radvd-0.7.1/device-common.c radvd-0.7.1.hmipv6/device-common.c --- radvd-0.7.1/device-common.c Wed Jan 16 01:51:42 2002 +++ radvd-0.7.1.hmipv6/device-common.c Tue Jul 23 15:51:48 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 --new-file radvd-0.7.1/device-linux.c radvd-0.7.1.hmipv6/device-linux.c --- radvd-0.7.1/device-linux.c Wed Jan 16 01:51:42 2002 +++ radvd-0.7.1.hmipv6/device-linux.c Tue Jul 23 15:51:48 2002 @@ -122,11 +122,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++) @@ -136,14 +143,13 @@ } memcpy(&iface->if_addr, &addr, sizeof(struct in6_addr)); - - iface->if_index = if_idx; + /* 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); } diff -rub --new-file radvd-0.7.1/gram.y radvd-0.7.1.hmipv6/gram.y --- radvd-0.7.1/gram.y Wed Jan 16 01:51:42 2002 +++ radvd-0.7.1.hmipv6/gram.y Tue Jul 23 16:01:59 2002 @@ -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 @@ -66,6 +70,7 @@ %token T_AdvCurHopLimit %token T_AdvDefaultLifetime %token T_AdvSourceLLAddress +%token T_AdvIfDown %token T_AdvOnLink %token T_AdvAutonomous @@ -77,16 +82,35 @@ %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_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 +121,8 @@ struct in6_addr *addr; char *str; struct AdvPrefix *pinfo; + struct InterfaceOptions intfoptions; + struct MobilityAccessPoint *mapinfo; }; %% @@ -128,10 +154,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 +193,15 @@ } ; -ifaceparams : optional_ifacevlist prefixlist +ifaceparams : optional_ifacevlist + | optional_ifacevlist optionlist { - iface->AdvPrefixList = $2; + iface->AdvPrefixList = $2.plist; + iface->Hmip6MapList = $2.mlist; + if($2.llocal){ + memcpy(&iface->if_addr, $2.llocal, + sizeof(struct in6_addr)); + } } ; @@ -229,6 +265,10 @@ { iface->AdvSourceLLAddress = $2; } + | T_AdvIfDown SWITCH ';' + { + iface->AdvIfDown = $2; + } | T_AdvIntervalOpt SWITCH ';' { iface->AdvIntervalOpt = $2; @@ -237,6 +277,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,6 +309,64 @@ { iface->UnicastOnly = $2; } + | T_FastRSResponse SWITCH ';' + { + iface->FastRSResponse = $2; + } + | T_MaxFastRS NUMBER ';' + { + iface->MaxFastRS = $2; + } + ; + +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); + $$.mlist = $1.mlist; + $$.llocal = $1.llocal; + prefix = NULL; + } + | optionlist maplist + { + $$.mlist = maplist_combine($2, $1.mlist); + $$.plist = $1.plist; + $$.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; + + $$.llocal = $2; + linklocal = NULL; + } ; prefixlist : prefixdef @@ -359,6 +469,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 +649,8 @@ if (prefix) free(prefix); + if (map) + free(map); } static void diff -rub --new-file radvd-0.7.1/icmp6.h.diff radvd-0.7.1.hmipv6/icmp6.h.diff --- radvd-0.7.1/icmp6.h.diff Thu Jan 1 10:00:00 1970 +++ radvd-0.7.1.hmipv6/icmp6.h.diff Tue Jul 23 16:14:42 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 --new-file radvd-0.7.1/interface.c radvd-0.7.1.hmipv6/interface.c --- radvd-0.7.1/interface.c Wed Jan 16 01:51:42 2002 +++ radvd-0.7.1.hmipv6/interface.c Tue Jul 23 15:51:48 2002 @@ -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,14 @@ 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->MinRtrAdvInterval = -1; iface->AdvDefaultLifetime = -1; iface->HomeAgentLifetime = 0; @@ -54,6 +63,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,7 +95,8 @@ /* Check if we use Mobile IPv6 extensions */ if (iface->AdvHomeAgentFlag || iface->AdvHomeAgentInfo || - iface->AdvIntervalOpt) + iface->AdvIntervalOpt|| iface->ReAdvHmip6MapInfo || + iface->AdvHmip6MapInfo ) { MIPv6 = 1; } @@ -244,4 +277,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 --new-file radvd-0.7.1/list.c radvd-0.7.1.hmipv6/list.c --- radvd-0.7.1/list.c Thu Jan 1 10:00:00 1970 +++ radvd-0.7.1.hmipv6/list.c Tue Jul 23 16:45:31 2002 @@ -0,0 +1,118 @@ +/* + * $Id: list.c,v 1.1.1.1 2002/02/26 05:57:10 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 --new-file radvd-0.7.1/list.c~ radvd-0.7.1.hmipv6/list.c~ --- radvd-0.7.1/list.c~ Thu Jan 1 10:00:00 1970 +++ radvd-0.7.1.hmipv6/list.c~ Tue Jul 23 16:41:36 2002 @@ -0,0 +1,118 @@ +/* + * $Id: list.c,v 1.1.1.1 2002/02/26 05:57:10 gdaley Exp $ + * + * Authors: + * Greg Daley + * + * This software is Copyright 2001 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 --new-file radvd-0.7.1/maptable.c radvd-0.7.1.hmipv6/maptable.c --- radvd-0.7.1/maptable.c Thu Jan 1 10:00:00 1970 +++ radvd-0.7.1.hmipv6/maptable.c Tue Jul 23 16:45:13 2002 @@ -0,0 +1,265 @@ +/* + * $Id: maptable.c,v 1.1.1.1 2002/02/26 05:57:10 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 --new-file radvd-0.7.1/maptable.c~ radvd-0.7.1.hmipv6/maptable.c~ --- radvd-0.7.1/maptable.c~ Thu Jan 1 10:00:00 1970 +++ radvd-0.7.1.hmipv6/maptable.c~ Tue Jul 23 16:42:03 2002 @@ -0,0 +1,265 @@ +/* + * $Id: maptable.c,v 1.1.1.1 2002/02/26 05:57:10 gdaley Exp $ + * + * Authors: + * Greg Daley + * + * This software is Copyright 2001 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 --new-file radvd-0.7.1/maptable.h radvd-0.7.1.hmipv6/maptable.h --- radvd-0.7.1/maptable.h Thu Jan 1 10:00:00 1970 +++ radvd-0.7.1.hmipv6/maptable.h Tue Jul 23 16:45:06 2002 @@ -0,0 +1,38 @@ +/* + * $Id: maptable.h,v 1.1.1.1 2002/02/26 05:57:10 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 --new-file radvd-0.7.1/maptable.h~ radvd-0.7.1.hmipv6/maptable.h~ --- radvd-0.7.1/maptable.h~ Thu Jan 1 10:00:00 1970 +++ radvd-0.7.1.hmipv6/maptable.h~ Tue Jul 23 16:42:30 2002 @@ -0,0 +1,38 @@ +/* + * $Id: maptable.h,v 1.1.1.1 2002/02/26 05:57:10 gdaley Exp $ + * + * Authors: + * Greg Daley + * + * This software is Copyright 2001 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 --new-file radvd-0.7.1/process.c radvd-0.7.1.hmipv6/process.c --- radvd-0.7.1/process.c Thu Nov 15 06:58:11 2001 +++ radvd-0.7.1.hmipv6/process.c Tue Jul 23 16:11:27 2002 @@ -23,6 +23,97 @@ 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, @@ -151,10 +242,37 @@ 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 = ( MIN_DELAY_BETWEEN_RAS - + (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) { @@ -187,10 +305,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 +369,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 +382,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 +402,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 +414,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 +449,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 +459,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 +522,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 diff -rub --new-file radvd-0.7.1/radvd.c radvd-0.7.1.hmipv6/radvd.c --- radvd-0.7.1/radvd.c Wed Jan 16 01:51:42 2002 +++ radvd-0.7.1.hmipv6/radvd.c Tue Jul 23 16:05:14 2002 @@ -18,6 +18,7 @@ #include #include #include +#include struct Interface *IfaceList = NULL; @@ -208,6 +209,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 +294,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); @@ -336,6 +343,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 --new-file radvd-0.7.1/radvd.conf.5.man radvd-0.7.1.hmipv6/radvd.conf.5.man --- radvd-0.7.1/radvd.conf.5.man Wed Jan 16 01:51:42 2002 +++ radvd-0.7.1.hmipv6/radvd.conf.5.man Tue Jul 23 16:26:06 2002 @@ -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. @@ -239,6 +254,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 +286,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 +419,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 +604,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 --new-file radvd-0.7.1/radvd.h radvd-0.7.1.hmipv6/radvd.h --- radvd-0.7.1/radvd.h Thu Nov 15 06:58:11 2001 +++ radvd-0.7.1.hmipv6/radvd.h Tue Jul 23 16:03:54 2002 @@ -65,6 +65,7 @@ int AdvCurHopLimit; int AdvDefaultLifetime; int AdvSourceLLAddress; + int AdvIfDown; int UnicastOnly; /* Mobile IPv6 extensions */ @@ -73,8 +74,18 @@ int AdvHomeAgentFlag; int16_t HomeAgentPreference; uint16_t HomeAgentLifetime; + int FastRSResponse; + int NumFastRSReq; + int MaxFastRS; + + /* Hierarchical MobileIPv6 extensions */ + + int RecvHmip6MapInfo; + int AdvHmip6MapInfo; + int ReAdvHmip6MapInfo; struct AdvPrefix *AdvPrefixList; + struct MobilityAccessPoint *Hmip6MapList; struct timer_lst tm; unsigned long last_multicast; struct Interface *next; @@ -117,6 +128,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); @@ -148,6 +194,8 @@ /* 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 +216,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 diff -rub --new-file radvd-0.7.1/radvdump.c radvd-0.7.1.hmipv6/radvdump.c --- radvd-0.7.1/radvdump.c Wed Jan 16 01:51:42 2002 +++ radvd-0.7.1.hmipv6/radvdump.c Tue Jul 23 15:51:48 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 --new-file radvd-0.7.1/rr.h radvd-0.7.1.hmipv6/rr.h --- radvd-0.7.1/rr.h Thu Jan 1 10:00:00 1970 +++ radvd-0.7.1.hmipv6/rr.h Tue Jul 23 16:13:44 2002 @@ -0,0 +1,8 @@ + /* Router Renumbering Header Formats */ + +#ifndef __IPV6_ROUTER_RENUM_H +#define __IPV6_ROUTER_RENUM_H + + + +#endif /* __IPV6_ROUTER_RENUM_H */ diff -rub --new-file radvd-0.7.1/scanner.l radvd-0.7.1.hmipv6/scanner.l --- radvd-0.7.1/scanner.l Wed Jan 16 01:51:42 2002 +++ radvd-0.7.1.hmipv6/scanner.l Tue Jul 23 15:58:51 2002 @@ -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,27 @@ AdvHomeAgentInfo { return T_AdvHomeAgentInfo; } UnicastOnly { return T_UnicastOnly; } +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; } + {addr} { static struct in6_addr addr; diff -rub --new-file radvd-0.7.1/send.c radvd-0.7.1.hmipv6/send.c --- radvd-0.7.1/send.c Thu Nov 15 06:58:11 2001 +++ radvd-0.7.1.hmipv6/send.c Tue Jul 23 15:51:48 2002 @@ -17,6 +17,56 @@ #include #include #include +#include "maptable.h" + + +time_t dynlifetime(struct MobilityAccessPoint *map ){ + + time_t move_interval; + time_t valid_left; + + 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) @@ -30,10 +80,16 @@ char chdr[CMSG_SPACE(sizeof(struct in6_pktinfo))]; struct nd_router_advert *radvert; struct AdvPrefix *prefix; + 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); @@ -191,6 +247,181 @@ len += sizeof(struct HomeAgentInfo); } + /* + * 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;