@@ -112,15 +112,23 @@ struct dhcp6_ia_addr {
112112};
113113__CTASSERT (sizeof (struct dhcp6_ia_addr ) == 16 + 8 );
114114
115- /* XXX FIXME: This is the only packed structure and it does not align.
116- * Maybe manually decode it? */
115+ /* Some compilers do not support packed structures.
116+ * We manually decode this. */
117+ #if 0
117118struct dhcp6_pd_addr {
118119 uint32_t pltime ;
119120 uint32_t vltime ;
120121 uint8_t prefix_len ;
121122 struct in6_addr prefix ;
122123} __packed ;
123124__CTASSERT (sizeof (struct dhcp6_pd_addr ) == 8 + 1 + 16 );
125+ #endif
126+
127+ #define DHCP6_PD_ADDR_SIZE (8 + 1 + 16)
128+ #define DHCP6_PD_ADDR_PLTIME 0
129+ #define DHCP6_PD_ADDR_VLTIME 4
130+ #define DHCP6_PD_ADDR_PLEN 8
131+ #define DHCP6_PD_ADDR_PREFIX 9
124132
125133struct dhcp6_op {
126134 uint16_t type ;
@@ -838,7 +846,7 @@ dhcp6_makemessage(struct interface *ifp)
838846 continue ;
839847 if (ap -> ia_type == D6_OPTION_IA_PD ) {
840848#ifndef SMALL
841- len += sizeof (o ) + sizeof ( struct dhcp6_pd_addr ) ;
849+ len += sizeof (o ) + DHCP6_PD_ADDR_SIZE ;
842850 if (ap -> prefix_exclude_len )
843851 len += sizeof (o ) + 1 +
844852 (uint8_t )((ap -> prefix_exclude_len -
@@ -989,19 +997,14 @@ dhcp6_makemessage(struct interface *ifp)
989997 continue ;
990998 if (ap -> ia_type == D6_OPTION_IA_PD ) {
991999#ifndef SMALL
992- struct dhcp6_pd_addr pdp = {
993- .prefix_len = ap -> prefix_len ,
994- /*
995- * RFC 8415 21.22 states that the
996- * valid and preferred lifetimes sent by
997- * the client SHOULD be zero and MUST
998- * be ignored by the server.
999- */
1000- };
1000+ uint8_t pdp [DHCP6_PD_ADDR_SIZE ];
1001+
1002+ memset (pdp , 0 , DHCP6_PD_ADDR_PLEN );
1003+ pdp [DHCP6_PD_ADDR_PLEN ] = (uint8_t )ap -> prefix_len ;
1004+ memcpy (pdp + DHCP6_PD_ADDR_PREFIX , & ap -> prefix ,
1005+ DHCP6_PD_ADDR_SIZE - DHCP6_PD_ADDR_PREFIX );
1006+ COPYIN (D6_OPTION_IAPREFIX , pdp , sizeof (pdp ));
10011007
1002- /* pdp.prefix is not aligned, so copy it in. */
1003- memcpy (& pdp .prefix , & ap -> prefix , sizeof (pdp .prefix ));
1004- COPYIN (D6_OPTION_IAPREFIX , & pdp , sizeof (pdp ));
10051008 ia_na_len = (uint16_t )
10061009 (ia_na_len + sizeof (o ) + sizeof (pdp ));
10071010
@@ -2224,7 +2227,8 @@ dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
22242227 int i ;
22252228 uint8_t nb , * pw ;
22262229 uint16_t ol ;
2227- struct dhcp6_pd_addr pdp ;
2230+ uint32_t pdp_vltime , pdp_pltime ;
2231+ uint8_t pdp_plen ;
22282232 struct in6_addr pdp_prefix ;
22292233
22302234 i = 0 ;
@@ -2234,36 +2238,42 @@ dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
22342238 nd = o + ol ;
22352239 l -= (size_t )(nd - d );
22362240 d = nd ;
2237- if (ol < sizeof ( pdp ) ) {
2241+ if (ol < DHCP6_PD_ADDR_SIZE ) {
22382242 errno = EINVAL ;
22392243 logerrx ("%s: IA Prefix option truncated" , ifp -> name );
22402244 continue ;
22412245 }
22422246
2243- memcpy (& pdp , o , sizeof (pdp ));
2244- pdp .pltime = ntohl (pdp .pltime );
2245- pdp .vltime = ntohl (pdp .vltime );
2247+ memcpy (& pdp_pltime , o , sizeof (pdp_pltime ));
2248+ o += sizeof (pdp_pltime );
2249+ memcpy (& pdp_vltime , o , sizeof (pdp_vltime ));
2250+ o += sizeof (pdp_vltime );
2251+ memcpy (& pdp_plen , o , sizeof (pdp_plen ));
2252+ o += sizeof (pdp_plen );
2253+
2254+ pdp_pltime = (uint16_t )ntohl (pdp_pltime );
2255+ pdp_vltime = (uint16_t )ntohl (pdp_vltime );
22462256 /* RFC 3315 22.6 */
2247- if (pdp . pltime > pdp . vltime ) {
2257+ if (pdp_pltime > pdp_vltime ) {
22482258 errno = EINVAL ;
22492259 logerrx ("%s: IA Prefix pltime %" PRIu32
22502260 " > vltime %" PRIu32 ,
2251- ifp -> name , pdp . pltime , pdp . vltime );
2261+ ifp -> name , pdp_pltime , pdp_vltime );
22522262 continue ;
22532263 }
22542264
2255- o += sizeof (pdp );
2256- ol = (uint16_t )(ol - sizeof (pdp ));
2265+ memcpy (& pdp_prefix , o , sizeof (pdp_prefix ));
2266+ o += sizeof (pdp_prefix );
2267+ ol = (uint16_t )(ol - sizeof (pdp_pltime ) - sizeof (pdp_vltime ) -
2268+ sizeof (pdp_plen ) - sizeof (pdp_prefix ));
22572269
2258- /* pdp.prefix is not aligned so copy it out. */
2259- memcpy (& pdp_prefix , & pdp .prefix , sizeof (pdp_prefix ));
22602270 TAILQ_FOREACH (a , & state -> addrs , next ) {
22612271 if (IN6_ARE_ADDR_EQUAL (& a -> prefix , & pdp_prefix ))
22622272 break ;
22632273 }
22642274
22652275 if (a == NULL ) {
2266- a = ipv6_newaddr (ifp , & pdp_prefix , pdp . prefix_len ,
2276+ a = ipv6_newaddr (ifp , & pdp_prefix , pdp_plen ,
22672277 IPV6_AF_DELEGATEDPFX );
22682278 if (a == NULL )
22692279 break ;
@@ -2276,13 +2286,13 @@ dhcp6_findpd(struct interface *ifp, const uint8_t *iaid,
22762286 if (!(a -> flags & IPV6_AF_DELEGATEDPFX ))
22772287 a -> flags |= IPV6_AF_NEW | IPV6_AF_DELEGATEDPFX ;
22782288 a -> flags &= ~(IPV6_AF_STALE | IPV6_AF_EXTENDED );
2279- if (a -> prefix_vltime != pdp . vltime )
2289+ if (a -> prefix_vltime != pdp_vltime )
22802290 a -> flags |= IPV6_AF_NEW ;
22812291 }
22822292
22832293 a -> acquired = * acquired ;
2284- a -> prefix_pltime = pdp . pltime ;
2285- a -> prefix_vltime = pdp . vltime ;
2294+ a -> prefix_pltime = pdp_pltime ;
2295+ a -> prefix_vltime = pdp_vltime ;
22862296
22872297 if (a -> prefix_pltime && a -> prefix_pltime < state -> lowpl )
22882298 state -> lowpl = a -> prefix_pltime ;
0 commit comments