summaryrefslogtreecommitdiff
path: root/accel-pppd
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2026-09-01 09:08:47 +0300
committerDenys Fedoryshchenko <denys.f@collabora.com>2026-09-01 09:08:47 +0300
commit7d4f8524f57ba0ac77e47171bebfc0370df667b1 (patch)
treeb3020b4e2aac0deac02721b7ebfe96c5ca4519b9 /accel-pppd
parentc12e1242c0ab98255661f84be3eb37148c00cb38 (diff)
downloadaccel-ppp-7d4f8524f57ba0ac77e47171bebfc0370df667b1.tar.gz
accel-ppp-7d4f8524f57ba0ac77e47171bebfc0370df667b1.zip
utils: centralize unaligned integer accessors
Diffstat (limited to 'accel-pppd')
-rw-r--r--accel-pppd/ctrl/l2tp/packet.c68
-rw-r--r--accel-pppd/ctrl/l2tp/packet_test.c2
-rw-r--r--accel-pppd/ctrl/pppoe/pppoe.c26
-rw-r--r--accel-pppd/ctrl/pppoe/tr101.c37
-rw-r--r--accel-pppd/ipv6/dhcpv6.c4
-rw-r--r--accel-pppd/ipv6/dhcpv6_packet.c18
-rw-r--r--accel-pppd/ppp/ccp_mppe.c4
-rw-r--r--accel-pppd/ppp/ppp_lcp.c26
-rw-r--r--accel-pppd/radius/backup.c39
-rw-r--r--accel-pppd/radius/packet.c51
-rw-r--r--accel-pppd/utils.h73
11 files changed, 137 insertions, 211 deletions
diff --git a/accel-pppd/ctrl/l2tp/packet.c b/accel-pppd/ctrl/l2tp/packet.c
index 0a4113a0..f134666d 100644
--- a/accel-pppd/ctrl/l2tp/packet.c
+++ b/accel-pppd/ctrl/l2tp/packet.c
@@ -111,58 +111,6 @@ void l2tp_packet_free(struct l2tp_packet_t *pack)
mempool_free(pack);
}
-/*
- * AVPs are not aligned in any way inside the packet buffer: their offset
- * depends on the length of every preceding AVP, which is peer chosen.
- * Always go through memcpy() to read multi-byte fields out of them, both to
- * stay portable on strict alignment architectures and to avoid tripping
- * -fsanitize=alignment.
- */
-static uint16_t unaligned_ntohs(const void *ptr)
-{
- uint16_t val;
-
- memcpy(&val, ptr, sizeof(val));
-
- return ntohs(val);
-}
-
-static uint32_t unaligned_ntohl(const void *ptr)
-{
- uint32_t val;
-
- memcpy(&val, ptr, sizeof(val));
-
- return ntohl(val);
-}
-
-static uint64_t unaligned_be64toh(const void *ptr)
-{
- uint64_t val;
-
- memcpy(&val, ptr, sizeof(val));
-
- return be64toh(val);
-}
-
-static void unaligned_htons(void *ptr, uint16_t val)
-{
- val = htons(val);
- memcpy(ptr, &val, sizeof(val));
-}
-
-static void unaligned_htonl(void *ptr, uint32_t val)
-{
- val = htonl(val);
- memcpy(ptr, &val, sizeof(val));
-}
-
-static void unaligned_htobe64(void *ptr, uint64_t val)
-{
- val = htobe64(val);
- memcpy(ptr, &val, sizeof(val));
-}
-
static void memxor(uint8_t *dst, const uint8_t *src, size_t sz)
{
size_t indx;
@@ -223,7 +171,7 @@ static int decode_avp(struct l2tp_avp_t *avp, const struct l2tp_attr_t *RV,
}
memxor(p1, avp->val, MD5_DIGEST_LENGTH);
- orig_attr_len = unaligned_ntohs(p1);
+ orig_attr_len = u_read_be16(p1);
if (orig_attr_len <= MD5_DIGEST_LENGTH - sizeof(uint16_t)) {
/* Enough bytes decoded already, no need to decode padding */
@@ -271,7 +219,7 @@ out:
trustworthy as the peer's knowledge of the shared secret. Bound it
against the room actually available in the received AVP before
letting it drive any read of the attribute value */
- orig_attr_len = unaligned_ntohs(avp->val);
+ orig_attr_len = u_read_be16(avp->val);
if (orig_attr_len > attr_len - sizeof(uint16_t)) {
log_warn("l2tp: incorrect hidden avp received (type %hu):"
" deciphered attribute length too big (ciphered"
@@ -502,17 +450,17 @@ int l2tp_recv(int fd, struct l2tp_packet_t **p, struct in_pktinfo *pkt_info,
case ATTR_TYPE_INT16:
if (orig_avp_len != sizeof(*avp) + 2)
goto out_err_len;
- attr->val.uint16 = unaligned_ntohs(orig_avp_val);
+ attr->val.uint16 = u_read_be16(orig_avp_val);
break;
case ATTR_TYPE_INT32:
if (orig_avp_len != sizeof(*avp) + 4)
goto out_err_len;
- attr->val.uint32 = unaligned_ntohl(orig_avp_val);
+ attr->val.uint32 = u_read_be32(orig_avp_val);
break;
case ATTR_TYPE_INT64:
if (orig_avp_len != sizeof(*avp) + 8)
goto out_err_len;
- attr->val.uint64 = unaligned_be64toh(orig_avp_val);
+ attr->val.uint64 = u_read_be64(orig_avp_val);
break;
case ATTR_TYPE_OCTETS:
attr->val.octets = _malloc(attr->length);
@@ -589,13 +537,13 @@ int l2tp_packet_send(int sock, struct l2tp_packet_t *pack)
else
switch (attr->attr->type) {
case ATTR_TYPE_INT16:
- unaligned_htons(avp->val, attr->val.int16);
+ u_write_be16(avp->val, attr->val.int16);
break;
case ATTR_TYPE_INT32:
- unaligned_htonl(avp->val, attr->val.int32);
+ u_write_be32(avp->val, attr->val.int32);
break;
case ATTR_TYPE_INT64:
- unaligned_htobe64(avp->val, attr->val.uint64);
+ u_write_be64(avp->val, attr->val.uint64);
break;
case ATTR_TYPE_STRING:
case ATTR_TYPE_OCTETS:
diff --git a/accel-pppd/ctrl/l2tp/packet_test.c b/accel-pppd/ctrl/l2tp/packet_test.c
index 9f962407..a6c9a182 100644
--- a/accel-pppd/ctrl/l2tp/packet_test.c
+++ b/accel-pppd/ctrl/l2tp/packet_test.c
@@ -4,7 +4,7 @@
* Not part of the cmake build. Compile and run with:
* gcc -O1 -g -Wall -fno-strict-aliasing -D_GNU_SOURCE \
* -fsanitize=address,undefined -fno-sanitize-recover=all \
- * -I accel-pppd/include -I accel-pppd/ctrl/l2tp \
+ * -I accel-pppd -I accel-pppd/include -I accel-pppd/ctrl/l2tp \
* -o /tmp/l2tp_packet_test \
* accel-pppd/ctrl/l2tp/packet_test.c accel-pppd/ctrl/l2tp/packet.c \
* -lcrypto && /tmp/l2tp_packet_test
diff --git a/accel-pppd/ctrl/pppoe/pppoe.c b/accel-pppd/ctrl/pppoe/pppoe.c
index 00f962af..bd92cbf8 100644
--- a/accel-pppd/ctrl/pppoe/pppoe.c
+++ b/accel-pppd/ctrl/pppoe/pppoe.c
@@ -554,22 +554,6 @@ static void print_tag_octets(struct pppoe_tag *tag)
log_info2("%02x", (uint8_t)tag->tag_data[i]);
}
-static uint16_t pppoe_read_u16(const void *ptr)
-{
- uint16_t value;
-
- memcpy(&value, ptr, sizeof(value));
- return ntohs(value);
-}
-
-static uint32_t pppoe_read_u32(const void *ptr)
-{
- uint32_t value;
-
- memcpy(&value, ptr, sizeof(value));
- return ntohl(value);
-}
-
static void print_tag_u16(struct pppoe_tag *tag)
{
if (ntohs(tag->tag_len) != sizeof(uint16_t)) {
@@ -577,7 +561,7 @@ static void print_tag_u16(struct pppoe_tag *tag)
return;
}
- log_info2("%i", pppoe_read_u16(tag->tag_data));
+ log_info2("%i", u_read_be16(tag->tag_data));
}
static void print_packet(const char *ifname, const char *op, uint8_t *pack)
@@ -654,7 +638,7 @@ static void print_packet(const char *ifname, const char *op, uint8_t *pack)
if (ntohs(tag->tag_len) < 4)
log_info2(" <Vendor-Specific invalid>");
else
- log_info2(" <Vendor-Specific %x>", pppoe_read_u32(tag->tag_data));
+ log_info2(" <Vendor-Specific %x>", u_read_be32(tag->tag_data));
break;
case TAG_RELAY_SESSION_ID:
log_info2(" <Relay-Session-Id ");
@@ -1101,7 +1085,7 @@ static void pppoe_recv_PADI(struct pppoe_serv_t *serv, uint8_t *pack, int size)
break;
case TAG_PPP_MAX_PAYLOAD:
if (ntohs(tag->tag_len) == 2)
- ppp_max_payload = pppoe_read_u16(tag->tag_data);
+ ppp_max_payload = u_read_be16(tag->tag_data);
break;
}
}
@@ -1248,14 +1232,14 @@ static void pppoe_recv_PADR(struct pppoe_serv_t *serv, uint8_t *pack, int size)
case TAG_VENDOR_SPECIFIC:
if (ntohs(tag->tag_len) < 4)
continue;
- vendor_id = pppoe_read_u32(tag->tag_data);
+ vendor_id = u_read_be32(tag->tag_data);
if (vendor_id == VENDOR_ADSL_FORUM)
if (conf_tr101)
tr101_tag = tag;
break;
case TAG_PPP_MAX_PAYLOAD:
if (ntohs(tag->tag_len) == 2)
- ppp_max_payload = pppoe_read_u16(tag->tag_data);
+ ppp_max_payload = u_read_be16(tag->tag_data);
break;
}
}
diff --git a/accel-pppd/ctrl/pppoe/tr101.c b/accel-pppd/ctrl/pppoe/tr101.c
index e7aa96dc..06aeff86 100644
--- a/accel-pppd/ctrl/pppoe/tr101.c
+++ b/accel-pppd/ctrl/pppoe/tr101.c
@@ -8,6 +8,7 @@
#include "log.h"
#include "radius.h"
#include "memdebug.h"
+#include "utils.h"
#include "pppoe.h"
@@ -30,14 +31,6 @@
#define ACCESS_LOOP_ENCAP 0x90
#define IFW_SESSION 0xFE
-static uint32_t tr101_read_u32(const void *ptr)
-{
- uint32_t value;
-
- memcpy(&value, ptr, sizeof(value));
- return ntohl(value);
-}
-
static int tr101_send_request(struct pppoe_tag *tr101, struct rad_packet_t *pack, int type)
{
uint8_t *ptr = (uint8_t *)tr101->tag_data + 4;
@@ -83,85 +76,85 @@ static int tr101_send_request(struct pppoe_tag *tr101, struct rad_packet_t *pack
case OPT_ACTUAL_DATA_RATE_UP:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Data-Rate-Upstream", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Data-Rate-Upstream", u_read_be32(ptr)))
return -1;
break;
case OPT_ACTUAL_DATA_RATE_DOWN:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Data-Rate-Downstream", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Data-Rate-Downstream", u_read_be32(ptr)))
return -1;
break;
case OPT_MIN_DATA_RATE_UP:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Upstream", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Upstream", u_read_be32(ptr)))
return -1;
break;
case OPT_MIN_DATA_RATE_DOWN:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Downstream", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Downstream", u_read_be32(ptr)))
return -1;
break;
case OPT_ATT_DATA_RATE_UP:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Attainable-Data-Rate-Upstream", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Attainable-Data-Rate-Upstream", u_read_be32(ptr)))
return -1;
break;
case OPT_ATT_DATA_RATE_DOWN:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Attainable-Data-Rate-Downstream", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Attainable-Data-Rate-Downstream", u_read_be32(ptr)))
return -1;
break;
case OPT_MAX_DATA_RATE_UP:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Data-Rate-Upstream", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Data-Rate-Upstream", u_read_be32(ptr)))
return -1;
break;
case OPT_MAX_DATA_RATE_DOWN:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Data-Rate-Downstream", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Data-Rate-Downstream", u_read_be32(ptr)))
return -1;
break;
case OPT_MIN_DATA_RATE_UP_LP:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Upstream-Low-Power", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Upstream-Low-Power", u_read_be32(ptr)))
return -1;
break;
case OPT_MIN_DATA_RATE_DOWN_LP:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Downstream-Low-Power", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Minimum-Data-Rate-Downstream-Low-Power", u_read_be32(ptr)))
return -1;
break;
case OPT_MAX_INTERL_DELAY_UP:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Interleaving-Delay-Upstream", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Interleaving-Delay-Upstream", u_read_be32(ptr)))
return -1;
break;
case OPT_ACTUAL_INTERL_DELAY_UP:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Interleaving-Delay-Upstream", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Interleaving-Delay-Upstream", u_read_be32(ptr)))
return -1;
break;
case OPT_MAX_INTER_DELAY_DOWN:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Interleaving-Delay-Downstream", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Maximum-Interleaving-Delay-Downstream", u_read_be32(ptr)))
return -1;
break;
case OPT_ACTUAL_INTER_DELAY_DOWN:
if (len != 4)
goto inval;
- if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Interleaving-Delay-Downstream", tr101_read_u32(ptr)))
+ if (rad_packet_add_int(pack, "ADSL-Forum", "Actual-Interleaving-Delay-Downstream", u_read_be32(ptr)))
return -1;
break;
case ACCESS_LOOP_ENCAP:
diff --git a/accel-pppd/ipv6/dhcpv6.c b/accel-pppd/ipv6/dhcpv6.c
index 1d565a76..a0b159cf 100644
--- a/accel-pppd/ipv6/dhcpv6.c
+++ b/accel-pppd/ipv6/dhcpv6.c
@@ -23,6 +23,7 @@
#include "ipv6_dns.h"
#include "events.h"
#include "iputils.h"
+#include "utils.h"
#include "dhcpv6.h"
@@ -229,8 +230,7 @@ static void insert_oro(struct dhcpv6_packet *reply, struct dhcpv6_option *opt)
struct in6_addr dns[MAX_DNS_COUNT];
for (i = ntohs(opt->hdr->len) / 2, ptr = opt->hdr->data; i; i--, ptr += sizeof(code)) {
- memcpy(&code, ptr, sizeof(code));
- code = ntohs(code);
+ code = u_read_be16(ptr);
if (code == D6_OPTION_DNS_SERVERS) {
dns_count = ipv6_dns_get(reply->ses, conf_dns, conf_dns_count,
dns, MAX_DNS_COUNT);
diff --git a/accel-pppd/ipv6/dhcpv6_packet.c b/accel-pppd/ipv6/dhcpv6_packet.c
index 1bf297af..f1c168b6 100644
--- a/accel-pppd/ipv6/dhcpv6_packet.c
+++ b/accel-pppd/ipv6/dhcpv6_packet.c
@@ -4,6 +4,7 @@
#include "log.h"
#include "memdebug.h"
+#include "utils.h"
#include "dhcpv6.h"
@@ -34,14 +35,6 @@ static void print_dnssl(struct dhcpv6_option *opt, void (*print)(const char *fmt
static void print_ia_prefix(struct dhcpv6_option *opt, void (*print)(const char *fmt, ...));
static void print_aftr_gw(struct dhcpv6_option *opt, void (*print)(const char *fmt, ...));
-static uint16_t dhcpv6_read_u16(const void *ptr)
-{
- uint16_t value;
-
- memcpy(&value, ptr, sizeof(value));
- return ntohs(value);
-}
-
static struct dict_option known_options[] = {
{ D6_OPTION_CLIENTID, "Client-ID", 1, sizeof(uint16_t), 0, print_clientid },
{ D6_OPTION_SERVERID, "Server-ID", 0, sizeof(uint16_t), 0, print_clientid },
@@ -497,7 +490,7 @@ static void print_oro(struct dhcpv6_option *opt, void (*print)(const char *fmt,
else
print(" ");
- code = dhcpv6_read_u16(ptr);
+ code = u_read_be16(ptr);
for (dopt = known_options; dopt->code; dopt++) {
if (code == dopt->code)
break;
@@ -531,13 +524,10 @@ static void print_uint8(struct dhcpv6_option *opt, void (*print)(const char *fmt
static void print_time(struct dhcpv6_option *opt, void (*print)(const char *fmt, ...))
{
- uint16_t val;
-
- if (ntohs(opt->hdr->len) < sizeof(val))
+ if (ntohs(opt->hdr->len) < sizeof(uint16_t))
return;
- memcpy(&val, opt->hdr->data, sizeof(val));
- print(" %u", ntohs(val));
+ print(" %u", u_read_be16(opt->hdr->data));
}
static void print_ipv6addr(struct dhcpv6_option *opt, void (*print)(const char *fmt, ...))
diff --git a/accel-pppd/ppp/ccp_mppe.c b/accel-pppd/ppp/ccp_mppe.c
index c2ffd9a0..5042c8a0 100644
--- a/accel-pppd/ppp/ccp_mppe.c
+++ b/accel-pppd/ppp/ccp_mppe.c
@@ -10,6 +10,7 @@
#include "ppp_ccp.h"
#include "log.h"
#include "events.h"
+#include "utils.h"
#include "memdebug.h"
@@ -102,12 +103,11 @@ static int setup_mppe_key(int fd, int transmit, uint8_t *key)
{
struct ppp_option_data data;
uint8_t buf[6 + 16];
- uint32_t bits = htonl(MPPE_S | MPPE_H);
memset(buf, 0, sizeof(buf));
buf[0] = CI_MPPE;
buf[1] = 6;
- memcpy(buf + 2, &bits, sizeof(bits));
+ u_write_be32(buf + 2, MPPE_S | MPPE_H);
if (key)
memcpy(buf + 6, key, 16);
diff --git a/accel-pppd/ppp/ppp_lcp.c b/accel-pppd/ppp/ppp_lcp.c
index fb0bb8bb..b44674f4 100644
--- a/accel-pppd/ppp/ppp_lcp.c
+++ b/accel-pppd/ppp/ppp_lcp.c
@@ -47,22 +47,6 @@ static void send_term_req(struct ppp_fsm_t *fsm);
static void send_term_ack(struct ppp_fsm_t *fsm);
static void lcp_recv(struct ppp_handler_t*);
-static uint16_t lcp_read_u16(const void *ptr)
-{
- uint16_t value;
-
- memcpy(&value, ptr, sizeof(value));
- return ntohs(value);
-}
-
-static uint32_t lcp_read_u32(const void *ptr)
-{
- uint32_t value;
-
- memcpy(&value, ptr, sizeof(value));
- return ntohl(value);
-}
-
static void lcp_options_init(struct ppp_lcp_t *lcp)
{
struct lcp_option_t *lopt;
@@ -627,7 +611,7 @@ static void lcp_recv_echo_repl(struct ppp_lcp_t *lcp, uint8_t *data, int size)
if (conf_ppp_verbose)
log_ppp_debug("recv [LCP EchoRep id=%x]\n", lcp->fsm.recv_id);
} else {
- magic = lcp_read_u32(data);
+ magic = u_read_be32(data);
if (conf_ppp_verbose)
log_ppp_debug("recv [LCP EchoRep id=%x <magic %08x>]\n", lcp->fsm.recv_id, magic);
@@ -881,7 +865,7 @@ static void lcp_recv(struct ppp_handler_t*h)
break;
}
if (conf_ppp_verbose)
- log_ppp_debug("recv [LCP EchoReq id=%x <magic %08x>]\n", hdr->id, lcp_read_u32(hdr + 1));
+ log_ppp_debug("recv [LCP EchoReq id=%x <magic %08x>]\n", hdr->id, u_read_be32(hdr + 1));
send_echo_reply(lcp);
break;
case ECHOREP:
@@ -897,11 +881,11 @@ static void lcp_recv(struct ppp_handler_t*h)
log_ppp_warn("LCP: short ProtoRej received\n");
break;
}
- log_ppp_info2("recv [LCP ProtoRej id=%x <%04x>]\n", hdr->id, lcp_read_u16(hdr + 1));
+ log_ppp_info2("recv [LCP ProtoRej id=%x <%04x>]\n", hdr->id, u_read_be16(hdr + 1));
}
if (len < PPP_HDRLEN + 2 || buf_len < (int)(sizeof(*hdr) + 2))
break;
- ppp_recv_proto_rej(lcp->ppp, lcp_read_u16(hdr + 1));
+ ppp_recv_proto_rej(lcp->ppp, u_read_be16(hdr + 1));
break;
case DISCARDREQ:
if (conf_ppp_verbose) {
@@ -909,7 +893,7 @@ static void lcp_recv(struct ppp_handler_t*h)
log_ppp_warn("LCP: short DiscardReq received\n");
break;
}
- log_ppp_info2("recv [LCP DiscardReq id=%x <magic %08x>]\n", hdr->id, lcp_read_u32(hdr + 1));
+ log_ppp_info2("recv [LCP DiscardReq id=%x <magic %08x>]\n", hdr->id, u_read_be32(hdr + 1));
}
break;
case IDENT:
diff --git a/accel-pppd/radius/backup.c b/accel-pppd/radius/backup.c
index 73825336..bfca0e49 100644
--- a/accel-pppd/radius/backup.c
+++ b/accel-pppd/radius/backup.c
@@ -6,6 +6,7 @@
#include "log.h"
#include "memdebug.h"
+#include "utils.h"
#include "backup.h"
#include "ap_session_backup.h"
@@ -23,26 +24,6 @@
#define RAD_TAG_ACCT_SERVER_PORT 10
#define RAD_TAG_IDLE_TIMEOUT 11
-static uint16_t backup_read_u16(const void *ptr)
-{
- uint16_t value;
- memcpy(&value, ptr, sizeof(value));
- return value;
-}
-
-static uint32_t backup_read_u32(const void *ptr)
-{
- uint32_t value;
- memcpy(&value, ptr, sizeof(value));
- return value;
-}
-
-static uint64_t backup_read_u64(const void *ptr)
-{
- uint64_t value;
- memcpy(&value, ptr, sizeof(value));
- return value;
-}
#define RAD_TAG_ACCT_USERNAME 12
@@ -115,10 +96,10 @@ static void restore_ipv4_addr(struct ap_session *ses)
list_for_each_entry(tag, &m->tag_list, entry) {
switch (tag->id) {
case SES_TAG_IPV4_ADDR:
- ses->ipv4->addr = backup_read_u32(tag->data);
+ ses->ipv4->addr = u_read_native32(tag->data);
break;
case SES_TAG_IPV4_PEER_ADDR:
- ses->ipv4->peer_addr = backup_read_u32(tag->data);
+ ses->ipv4->peer_addr = u_read_native32(tag->data);
break;
}
}
@@ -142,16 +123,16 @@ void radius_restore_session(struct ap_session *ses, struct radius_pd_t *rpd)
list_for_each_entry(tag, &m->tag_list, entry) {
switch (tag->id) {
case RAD_TAG_INTERIM_INTERVAL:
- rpd->acct_interim_interval = backup_read_u32(tag->data);
+ rpd->acct_interim_interval = u_read_native32(tag->data);
break;
case RAD_TAG_INTERIM_JITTER:
- rpd->acct_interim_jitter = backup_read_u32(tag->data);
+ rpd->acct_interim_jitter = u_read_native32(tag->data);
break;
case RAD_TAG_SESSION_TIMEOUT:
- rpd->session_timeout.expire_tv.tv_sec = backup_read_u64(tag->data) - ses->start_time;
+ rpd->session_timeout.expire_tv.tv_sec = u_read_native64(tag->data) - ses->start_time;
break;
case RAD_TAG_IDLE_TIMEOUT:
- rpd->idle_timeout.period = backup_read_u32(tag->data) * 1000;
+ rpd->idle_timeout.period = u_read_native32(tag->data) * 1000;
break;
case RAD_TAG_IPV4_ADDR:
ses->ipv4 = &rpd->ipv4_addr;
@@ -171,16 +152,16 @@ void radius_restore_session(struct ap_session *ses, struct radius_pd_t *rpd)
rpd->attr_state_len = tag->size;
break;
case RAD_TAG_TERMINATION_ACTION:
- rpd->termination_action = backup_read_u32(tag->data);
+ rpd->termination_action = u_read_native32(tag->data);
break;
case RAD_TAG_ACCT_USERNAME:
rpd->acct_username = _strndup(tag->data, tag->size);
break;
case RAD_TAG_ACCT_SERVER_ADDR:
- acct_addr = backup_read_u32(tag->data);
+ acct_addr = u_read_native32(tag->data);
break;
case RAD_TAG_ACCT_SERVER_PORT:
- acct_port = backup_read_u16(tag->data);
+ acct_port = u_read_native16(tag->data);
break;
}
}
diff --git a/accel-pppd/radius/packet.c b/accel-pppd/radius/packet.c
index 782ecffe..4a0ab244 100644
--- a/accel-pppd/radius/packet.c
+++ b/accel-pppd/radius/packet.c
@@ -24,6 +24,7 @@
#include "mempool.h"
#include "radius_p.h"
#include "attr_defs.h"
+#include "utils.h"
#include "memdebug.h"
@@ -35,34 +36,6 @@ static mempool_t packet_pool;
static mempool_t attr_pool;
static mempool_t buf_pool;
-static uint16_t radius_read_u16(const void *ptr)
-{
- uint16_t value;
-
- memcpy(&value, ptr, sizeof(value));
- return ntohs(value);
-}
-
-static uint32_t radius_read_u32(const void *ptr)
-{
- uint32_t value;
-
- memcpy(&value, ptr, sizeof(value));
- return ntohl(value);
-}
-
-static void radius_write_u16(void *ptr, uint16_t value)
-{
- value = htons(value);
- memcpy(ptr, &value, sizeof(value));
-}
-
-static void radius_write_u32(void *ptr, uint32_t value)
-{
- value = htonl(value);
- memcpy(ptr, &value, sizeof(value));
-}
-
struct rad_packet_t *rad_packet_alloc(int code)
{
struct rad_packet_t *pack;
@@ -139,20 +112,20 @@ int rad_packet_build(struct rad_packet_t *pack, uint8_t *RA)
*ptr = pack->code; ptr++;
*ptr = pack->id; ptr++;
- radius_write_u16(ptr, pack->len); ptr += 2;
+ u_write_be16(ptr, pack->len); ptr += 2;
memcpy(ptr, RA, 16); ptr+=16;
list_for_each_entry(attr, &pack->attrs, entry) {
if (attr->vendor) {
*ptr = 26; ptr++;
*ptr = attr->len + 2 + 6; ptr++;
- radius_write_u32(ptr, attr->vendor->id); ptr += 4;
+ u_write_be32(ptr, attr->vendor->id); ptr += 4;
}
*ptr = attr->attr->id; ptr++;
*ptr = attr->len + 2; ptr++;
switch(attr->attr->type) {
case ATTR_TYPE_INTEGER:
- radius_write_u32(ptr, attr->val.integer);
+ u_write_be32(ptr, attr->val.integer);
break;
case ATTR_TYPE_OCTETS:
case ATTR_TYPE_STRING:
@@ -164,7 +137,7 @@ int rad_packet_build(struct rad_packet_t *pack, uint8_t *RA)
memcpy(ptr, &attr->val, attr->len);
break;
case ATTR_TYPE_DATE:
- radius_write_u32(ptr, attr->val.date);
+ u_write_be32(ptr, attr->val.date);
break;
case ATTR_TYPE_IPV6PREFIX:
ptr[0] = 0;
@@ -232,7 +205,7 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr)
pack->code = *ptr; ptr++;
pack->id = *ptr; ptr++;
- pack->len = radius_read_u16(ptr); ptr += 2;
+ pack->len = u_read_be16(ptr); ptr += 2;
if (pack->len < 20 || pack->len > n) {
log_ppp_warn("radius:packet: short packet received %i, expected %i\n", pack->len, n);
@@ -263,7 +236,7 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr)
log_ppp_warn("radius:packet: vendor attribute too short (%i)\n", len);
goto out_err;
}
- vendor_id = radius_read_u32(ptr);
+ vendor_id = u_read_be32(ptr);
vendor = rad_dict_find_vendor_id(vendor_id);
if (vendor) {
if (len < 4 + vendor->tag + vendor->len) {
@@ -273,14 +246,14 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr)
ptr += 4;
if (vendor->tag == 2)
- id = radius_read_u16(ptr);
+ id = u_read_be16(ptr);
else
id = *ptr;
ptr += vendor->tag;
if (vendor->len == 2)
- len = radius_read_u16(ptr);
+ len = u_read_be16(ptr);
else
len = *ptr;
@@ -333,15 +306,15 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr)
break;
}
if (len == 4)
- attr->val.integer = radius_read_u32(ptr);
+ attr->val.integer = u_read_be32(ptr);
else if (len == 2)
- attr->val.integer = radius_read_u16(ptr);
+ attr->val.integer = u_read_be16(ptr);
else if (len == 1)
attr->val.integer = *ptr;
break;
case ATTR_TYPE_DATE:
if (len == 4)
- attr->val.integer = radius_read_u32(ptr);
+ attr->val.integer = u_read_be32(ptr);
else
log_ppp_warn("radius:packet: attribute %s has invalid length %i (must be 4)\n", da->name, len);
break;
diff --git a/accel-pppd/utils.h b/accel-pppd/utils.h
index 63c1db0d..7c62422c 100644
--- a/accel-pppd/utils.h
+++ b/accel-pppd/utils.h
@@ -1,13 +1,86 @@
#ifndef __UTILS_H
#define __UTILS_H
+#include <endian.h>
#include <netinet/in.h>
#include <stdint.h>
+#include <string.h>
#ifndef min
#define min(x, y) ((x) < (y) ? (x) : (y))
#endif
+/*
+ * Fixed-size memcpy() lets the compiler emit efficient unaligned accesses on
+ * architectures that support them without imposing alignment or aliasing
+ * requirements on callers.
+ */
+static inline uint16_t u_read_be16(const void *ptr)
+{
+ uint16_t value;
+
+ memcpy(&value, ptr, sizeof(value));
+ return ntohs(value);
+}
+
+static inline uint32_t u_read_be32(const void *ptr)
+{
+ uint32_t value;
+
+ memcpy(&value, ptr, sizeof(value));
+ return ntohl(value);
+}
+
+static inline uint64_t u_read_be64(const void *ptr)
+{
+ uint64_t value;
+
+ memcpy(&value, ptr, sizeof(value));
+ return be64toh(value);
+}
+
+static inline void u_write_be16(void *ptr, uint16_t value)
+{
+ value = htons(value);
+ memcpy(ptr, &value, sizeof(value));
+}
+
+static inline void u_write_be32(void *ptr, uint32_t value)
+{
+ value = htonl(value);
+ memcpy(ptr, &value, sizeof(value));
+}
+
+static inline void u_write_be64(void *ptr, uint64_t value)
+{
+ value = htobe64(value);
+ memcpy(ptr, &value, sizeof(value));
+}
+
+static inline uint16_t u_read_native16(const void *ptr)
+{
+ uint16_t value;
+
+ memcpy(&value, ptr, sizeof(value));
+ return value;
+}
+
+static inline uint32_t u_read_native32(const void *ptr)
+{
+ uint32_t value;
+
+ memcpy(&value, ptr, sizeof(value));
+ return value;
+}
+
+static inline uint64_t u_read_native64(const void *ptr)
+{
+ uint64_t value;
+
+ memcpy(&value, ptr, sizeof(value));
+ return value;
+}
+
char *u_ip6str(const struct in6_addr *addr, char *buf);
char *u_ip4str(const struct in_addr *addr, char *buf);