summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2026-08-10 08:43:17 +0300
committerDenys Fedoryshchenko <denys.f@collabora.com>2026-08-10 08:43:17 +0300
commit0dd152a83012764a77ef2a7ae7bf7c20c3d43c35 (patch)
treeeb5a02c5a74b655afa219f3dd44a115d49cbd3c4
parent52a01730fd02c2579f474c01ebf72a312f737825 (diff)
downloadaccel-ppp-0dd152a83012764a77ef2a7ae7bf7c20c3d43c35.tar.gz
accel-ppp-0dd152a83012764a77ef2a7ae7bf7c20c3d43c35.zip
ipoe: fix netmask computation for classless routes
The netmask was built with a loop shifting 1 into place, which was wrong in three ways. At i == 0 it evaluated 1 << 32, undefined for a 32 bit int, and at i == 1 it shifted into the sign bit of a signed value. The shift amount was off by one, so a /24 produced 0xfffffe00 rather than 0xffffff00. And mask1 was initialized once before the loop over the routes and only ever OR'ed into, so the mask of every route accumulated into the routes that followed it. A well formed option carrying 10.0.1.0/24 via 1.1.1.1 and 172.16.0.0/12 via 2.2.2.2 printed as 10.0.0.1/24 and 172.16.2.0/12. Compute the mask directly instead, and reject a prefix length above 32 rather than shifting by a negative amount.
-rw-r--r--accel-pppd/ctrl/ipoe/dhcpv4_options.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/accel-pppd/ctrl/ipoe/dhcpv4_options.c b/accel-pppd/ctrl/ipoe/dhcpv4_options.c
index bffcfa5c..57999995 100644
--- a/accel-pppd/ctrl/ipoe/dhcpv4_options.c
+++ b/accel-pppd/ctrl/ipoe/dhcpv4_options.c
@@ -265,7 +265,8 @@ static void print_classless_route(const struct dhcpv4_option *opt, int elem_size
{
const uint8_t *ptr = opt->data;
const uint8_t *endptr = ptr + opt->len;
- int mask, i, mask1 = 0;
+ int mask;
+ uint32_t mask1;
uint32_t ip;
uint32_t gw;
@@ -274,9 +275,11 @@ static void print_classless_route(const struct dhcpv4_option *opt, int elem_size
print(",");
mask = *ptr++;
+ if (mask > 32)
+ return;
+
ip = ntohl(*(uint32_t *)ptr);
- for (i = 0; i < mask; i++)
- mask1 |= (1 << (32 - i));
+ mask1 = mask ? UINT32_MAX << (32 - mask) : 0;
ip &= mask1;
if (mask <= 8)
ptr++;