Add mg_crc16(), make PPP use it

This commit is contained in:
Sergio R. Caprile committed 2026-07-29 17:57:30 -03:00
1 parent 03be16803c
commit 7821fb9ab4
7 files changed
+65 -38

No files matched your search

+3 -19
View File
@@ -169,30 +169,14 @@ uint8_t *mg_l2_pppoe_header(struct mg_tcpip_if *ifp, enum mg_l2proto proto,
s_id, src, dst, frame));
}
// Calculate FCS/CRC for PPP frames. Could be implemented faster using lookup
// tables.
static uint16_t fcs_do(uint8_t *frame, size_t len) {
uint32_t fcs = 0xffff;
unsigned int j;
for (j = 0; j < len; j++) {
unsigned int i;
uint8_t x = frame[j];
for (i = 0; i < 8; i++) {
fcs = ((fcs ^ x) & 1) ? (fcs >> 1) ^ 0x8408 : fcs >> 1;
x >>= 1;
}
}
return (uint16_t) (fcs & 0xffff);
}
size_t mg_l2_ppp_trailer(struct mg_tcpip_if *ifp, size_t len, uint8_t *cur) {
uint16_t crc;
uint8_t *frame;
len += sizeof(struct ppp) + sizeof(struct hdlc_);
frame = cur - len;
crc = fcs_do(frame, len);
*cur++ = (uint8_t) ~crc; // add CRC, note the byte order
*cur++ = (uint8_t) (~crc >> 8);
crc = mg_crc16(0, (const char *) frame, len);
*cur++ = (uint8_t) crc; // add CRC, note the byte order
*cur++ = (uint8_t) (crc >> 8);
// there is no len field in PPP
(void) ifp;
return len + 2;
+14
View File
@@ -128,6 +128,20 @@ uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len) {
return ~crc;
}
uint16_t mg_crc16(uint16_t crc, const char *buf, size_t len) {
static const uint16_t crclut[16] = {
// table for polynomial 0x8408 (reflected)
0x0000, 0x1081, 0x2102, 0x3183, 0x4204, 0x5285, 0x6306, 0x7387,
0x8408, 0x9489, 0xA50A, 0xB58B, 0xC60C, 0xD68D, 0xE70E, 0xF78F};
unsigned int c = (unsigned int) ~crc & 0xffff;
while (len--) {
uint8_t b = *(uint8_t *) buf++;
c = crclut[(c ^ b) & 0x0F] ^ (c >> 4);
c = crclut[(c ^ (b >> 4)) & 0x0F] ^ (c >> 4);
}
return (uint16_t) ~c;
}
static int isbyte(int n) {
return n >= 0 && n <= 255;
}
+4
View File
@@ -40,6 +40,10 @@ char *mg_random_str(char *buf, size_t len);
// a new checksum; pass the result of a prior call to extend over more data.
uint32_t mg_crc32(uint32_t crc, const char *buf, size_t len);
// Computes CRC16 (HDLC, polynomial 0x8408) over buf/len. Pass crc=0 to start
// a new checksum; pass the result of a prior call to extend over more data.
uint16_t mg_crc16(uint16_t crc, const char *buf, size_t len);
// Returns true if path is safe to serve from the filesystem. Rejects paths
// that start with '~' or '..', or contain a '/../' component, to prevent
// directory traversal attacks.