Skip to content

Commit 96d3912

Browse files
committed
DHCP6: Remove the dhcp6_pd_addr packed struct
Some compilers just don't support this. We need to manually copy this in and out. Fixes #347.
1 parent 23841dd commit 96d3912

File tree

2 files changed

+40
-36
lines changed

2 files changed

+40
-36
lines changed

src/common.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,10 @@
7070
#endif
7171

7272
#if __GNUC__ > 2 || defined(__INTEL_COMPILER)
73-
# ifndef __packed
74-
# define __packed __attribute__((__packed__))
75-
# endif
7673
# ifndef __unused
7774
# define __unused __attribute__((__unused__))
7875
# endif
7976
#else
80-
# ifndef __packed
81-
# define __packed
82-
# endif
8377
# ifndef __unused
8478
# define __unused
8579
# endif

src/dhcp6.c

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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
117118
struct 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

125133
struct 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

Comments
 (0)