diff options
| author | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-09-01 09:08:47 +0300 |
|---|---|---|
| committer | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-09-01 09:08:47 +0300 |
| commit | 7d4f8524f57ba0ac77e47171bebfc0370df667b1 (patch) | |
| tree | b3020b4e2aac0deac02721b7ebfe96c5ca4519b9 | |
| parent | c12e1242c0ab98255661f84be3eb37148c00cb38 (diff) | |
| download | accel-ppp-7d4f8524f57ba0ac77e47171bebfc0370df667b1.tar.gz accel-ppp-7d4f8524f57ba0ac77e47171bebfc0370df667b1.zip | |
utils: centralize unaligned integer accessors
| -rw-r--r-- | accel-pppd/ctrl/l2tp/packet.c | 68 | ||||
| -rw-r--r-- | accel-pppd/ctrl/l2tp/packet_test.c | 2 | ||||
| -rw-r--r-- | accel-pppd/ctrl/pppoe/pppoe.c | 26 | ||||
| -rw-r--r-- | accel-pppd/ctrl/pppoe/tr101.c | 37 | ||||
| -rw-r--r-- | accel-pppd/ipv6/dhcpv6.c | 4 | ||||
| -rw-r--r-- | accel-pppd/ipv6/dhcpv6_packet.c | 18 | ||||
| -rw-r--r-- | accel-pppd/ppp/ccp_mppe.c | 4 | ||||
| -rw-r--r-- | accel-pppd/ppp/ppp_lcp.c | 26 | ||||
| -rw-r--r-- | accel-pppd/radius/backup.c | 39 | ||||
| -rw-r--r-- | accel-pppd/radius/packet.c | 51 | ||||
| -rw-r--r-- | accel-pppd/utils.h | 73 |
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); |
