Skip to content

Commit

Permalink
Merge pull request #2919 from cesanta/frag
Browse files Browse the repository at this point in the history
Fix IP fragmentation checks for big-endian CPUs
  • Loading branch information
scaprile authored Oct 4, 2024
2 parents 5af2de6 + 93dd7a8 commit 4be8aa0
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 55 deletions.
24 changes: 9 additions & 15 deletions mongoose.c
Original file line number Diff line number Diff line change
Expand Up @@ -4970,8 +4970,8 @@ struct ip {
uint16_t len; // Length
uint16_t id; // Unused
uint16_t frag; // Fragmentation
#define IP_FRAG_OFFSET_MSK 0xFF1F
#define IP_MORE_FRAGS_MSK 0x20
#define IP_FRAG_OFFSET_MSK 0x1fff
#define IP_MORE_FRAGS_MSK 0x2000
uint8_t ttl; // Time to live
uint8_t proto; // Upper level protocol
uint16_t csum; // Checksum
Expand Down Expand Up @@ -5145,8 +5145,8 @@ static struct ip *tx_ip(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
memcpy(eth->src, ifp->mac, sizeof(eth->src)); // Use our MAC
eth->type = mg_htons(0x800);
memset(ip, 0, sizeof(*ip));
ip->ver = 0x45; // Version 4, header length 5 words
ip->frag = 0x40; // Don't fragment
ip->ver = 0x45; // Version 4, header length 5 words
ip->frag = mg_htons(0x4000); // Don't fragment
ip->len = mg_htons((uint16_t) (sizeof(*ip) + plen));
ip->ttl = 64;
ip->proto = proto;
Expand Down Expand Up @@ -5706,7 +5706,8 @@ static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
}

static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
if (pkt->ip->frag & IP_MORE_FRAGS_MSK || pkt->ip->frag & IP_FRAG_OFFSET_MSK) {
uint16_t frag = mg_ntohs(pkt->ip->frag);
if (frag & IP_MORE_FRAGS_MSK || frag & IP_FRAG_OFFSET_MSK) {
if (pkt->ip->proto == 17) pkt->udp = (struct udp *) (pkt->ip + 1);
if (pkt->ip->proto == 6) pkt->tcp = (struct tcp *) (pkt->ip + 1);
struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
Expand Down Expand Up @@ -5870,7 +5871,8 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) {

// Process timeouts
for (c = ifp->mgr->conns; c != NULL; c = c->next) {
if ((c->is_udp && !c->is_arplooking) || c->is_listening || c->is_resolving) continue;
if ((c->is_udp && !c->is_arplooking) || c->is_listening || c->is_resolving)
continue;
struct connstate *s = (struct connstate *) (c + 1);
uint32_t rem_ip;
memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
Expand Down Expand Up @@ -9475,6 +9477,7 @@ int mg_aes_gcm_decrypt(unsigned char *output, const unsigned char *input,




#if MG_TLS == MG_TLS_BUILTIN

#define CHACHA20 1
Expand Down Expand Up @@ -9557,15 +9560,6 @@ struct tls_data {
struct tls_enc enc;
};

#define MG_LOAD_BE16(p) ((uint16_t) ((MG_U8P(p)[0] << 8U) | MG_U8P(p)[1]))
#define MG_LOAD_BE24(p) \
((uint32_t) ((MG_U8P(p)[0] << 16U) | (MG_U8P(p)[1] << 8U) | MG_U8P(p)[2]))
#define MG_STORE_BE16(p, n) \
do { \
MG_U8P(p)[0] = ((n) >> 8U) & 255; \
MG_U8P(p)[1] = (n) &255; \
} while (0)

#define TLS_RECHDR_SIZE 5 // 1 byte type, 2 bytes version, 2 bytes length
#define TLS_MSGHDR_SIZE 4 // 1 byte type, 3 bytes length

Expand Down
11 changes: 10 additions & 1 deletion mongoose.h
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ typedef enum { false = 0, true = 1 } bool;
#pragma comment(lib, "advapi32.lib")
#else
#include <bcrypt.h>
#if defined(_MSC_VER)
#if defined(_MSC_VER)
#pragma comment(lib, "bcrypt.lib")
#endif
#endif
Expand Down Expand Up @@ -1112,6 +1112,15 @@ bool mg_path_is_sane(const struct mg_str path);
#define MG_IPADDR_PARTS(ADDR) \
MG_U8P(ADDR)[0], MG_U8P(ADDR)[1], MG_U8P(ADDR)[2], MG_U8P(ADDR)[3]

#define MG_LOAD_BE16(p) ((uint16_t) ((MG_U8P(p)[0] << 8U) | MG_U8P(p)[1]))
#define MG_LOAD_BE24(p) \
((uint32_t) ((MG_U8P(p)[0] << 16U) | (MG_U8P(p)[1] << 8U) | MG_U8P(p)[2]))
#define MG_STORE_BE16(p, n) \
do { \
MG_U8P(p)[0] = ((n) >> 8U) & 255; \
MG_U8P(p)[1] = (n) &255; \
} while (0)

#define MG_REG(x) ((volatile uint32_t *) (x))[0]
#define MG_BIT(x) (((uint32_t) 1U) << (x))
#define MG_SET_BITS(R, CLRMASK, SETMASK) (R) = ((R) & ~(CLRMASK)) | (SETMASK)
Expand Down
48 changes: 24 additions & 24 deletions src/arch_rtthread.h
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
#pragma once

#if MG_ARCH == MG_ARCH_RTTHREAD

#include <rtthread.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>

#ifndef MG_IO_SIZE
#define MG_IO_SIZE 1460
#endif

#endif // MG_ARCH == MG_ARCH_RTTHREAD
#pragma once

#if MG_ARCH == MG_ARCH_RTTHREAD

#include <rtthread.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>

#ifndef MG_IO_SIZE
#define MG_IO_SIZE 1460
#endif

#endif // MG_ARCH == MG_ARCH_RTTHREAD
14 changes: 8 additions & 6 deletions src/net_builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ struct ip {
uint16_t len; // Length
uint16_t id; // Unused
uint16_t frag; // Fragmentation
#define IP_FRAG_OFFSET_MSK 0xFF1F
#define IP_MORE_FRAGS_MSK 0x20
#define IP_FRAG_OFFSET_MSK 0x1fff
#define IP_MORE_FRAGS_MSK 0x2000
uint8_t ttl; // Time to live
uint8_t proto; // Upper level protocol
uint16_t csum; // Checksum
Expand Down Expand Up @@ -223,8 +223,8 @@ static struct ip *tx_ip(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
memcpy(eth->src, ifp->mac, sizeof(eth->src)); // Use our MAC
eth->type = mg_htons(0x800);
memset(ip, 0, sizeof(*ip));
ip->ver = 0x45; // Version 4, header length 5 words
ip->frag = 0x40; // Don't fragment
ip->ver = 0x45; // Version 4, header length 5 words
ip->frag = mg_htons(0x4000); // Don't fragment
ip->len = mg_htons((uint16_t) (sizeof(*ip) + plen));
ip->ttl = 64;
ip->proto = proto;
Expand Down Expand Up @@ -784,7 +784,8 @@ static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
}

static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
if (pkt->ip->frag & IP_MORE_FRAGS_MSK || pkt->ip->frag & IP_FRAG_OFFSET_MSK) {
uint16_t frag = mg_ntohs(pkt->ip->frag);
if (frag & IP_MORE_FRAGS_MSK || frag & IP_FRAG_OFFSET_MSK) {
if (pkt->ip->proto == 17) pkt->udp = (struct udp *) (pkt->ip + 1);
if (pkt->ip->proto == 6) pkt->tcp = (struct tcp *) (pkt->ip + 1);
struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
Expand Down Expand Up @@ -948,7 +949,8 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t now) {

// Process timeouts
for (c = ifp->mgr->conns; c != NULL; c = c->next) {
if ((c->is_udp && !c->is_arplooking) || c->is_listening || c->is_resolving) continue;
if ((c->is_udp && !c->is_arplooking) || c->is_listening || c->is_resolving)
continue;
struct connstate *s = (struct connstate *) (c + 1);
uint32_t rem_ip;
memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
Expand Down
10 changes: 1 addition & 9 deletions src/tls_builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "tls_chacha20.h"
#include "tls_uecc.h"
#include "tls_x25519.h"
#include "util.h"

#if MG_TLS == MG_TLS_BUILTIN

Expand Down Expand Up @@ -90,15 +91,6 @@ struct tls_data {
struct tls_enc enc;
};

#define MG_LOAD_BE16(p) ((uint16_t) ((MG_U8P(p)[0] << 8U) | MG_U8P(p)[1]))
#define MG_LOAD_BE24(p) \
((uint32_t) ((MG_U8P(p)[0] << 16U) | (MG_U8P(p)[1] << 8U) | MG_U8P(p)[2]))
#define MG_STORE_BE16(p, n) \
do { \
MG_U8P(p)[0] = ((n) >> 8U) & 255; \
MG_U8P(p)[1] = (n) &255; \
} while (0)

#define TLS_RECHDR_SIZE 5 // 1 byte type, 2 bytes version, 2 bytes length
#define TLS_MSGHDR_SIZE 4 // 1 byte type, 3 bytes length

Expand Down
9 changes: 9 additions & 0 deletions src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ bool mg_path_is_sane(const struct mg_str path);
#define MG_IPADDR_PARTS(ADDR) \
MG_U8P(ADDR)[0], MG_U8P(ADDR)[1], MG_U8P(ADDR)[2], MG_U8P(ADDR)[3]

#define MG_LOAD_BE16(p) ((uint16_t) ((MG_U8P(p)[0] << 8U) | MG_U8P(p)[1]))
#define MG_LOAD_BE24(p) \
((uint32_t) ((MG_U8P(p)[0] << 16U) | (MG_U8P(p)[1] << 8U) | MG_U8P(p)[2]))
#define MG_STORE_BE16(p, n) \
do { \
MG_U8P(p)[0] = ((n) >> 8U) & 255; \
MG_U8P(p)[1] = (n) &255; \
} while (0)

#define MG_REG(x) ((volatile uint32_t *) (x))[0]
#define MG_BIT(x) (((uint32_t) 1U) << (x))
#define MG_SET_BITS(R, CLRMASK, SETMASK) (R) = ((R) & ~(CLRMASK)) | (SETMASK)
Expand Down

0 comments on commit 4be8aa0

Please sign in to comment.