Add support for Windriver's Diab v4 (stricter C89)

This commit is contained in:
Sergio R. Caprile
2025-12-04 13:58:49 -03:00
parent 4717a15c17
commit 5b023cb85b
19 changed files with 347 additions and 215 deletions
+145 -85
View File
@@ -257,12 +257,12 @@ bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
if (rr.alen == 4 && rr.atype == 1 && rr.aclass == 1) {
dm->addr.is_ip6 = false;
memcpy(&dm->addr.ip, &buf[ofs - 4], 4);
memcpy(&dm->addr.addr.ip, &buf[ofs - 4], 4);
dm->resolved = true;
break; // Return success
} else if (rr.alen == 16 && rr.atype == 28 && rr.aclass == 1) {
dm->addr.is_ip6 = true;
memcpy(&dm->addr.ip, &buf[ofs - 16], 16);
memcpy(&dm->addr.addr.ip, &buf[ofs - 16], 16);
dm->resolved = true;
break; // Return success
}
@@ -787,7 +787,8 @@ static int xisinf(double x) {
union {
double f;
uint64_t u;
} ieee754 = {x};
} ieee754;
ieee754.f = x;
return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
((unsigned) ieee754.u == 0);
}
@@ -796,7 +797,8 @@ static int xisnan(double x) {
union {
double f;
uint64_t u;
} ieee754 = {x};
} ieee754;
ieee754.f = x;
return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) +
((unsigned) ieee754.u != 0) >
0x7ff00000;
@@ -864,7 +866,7 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) {
}
while (tz && n > 0 && buf[s + n - 1] == '0') n--; // Trim trailing zeroes
if (tz && n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot
if (tz && n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot
n += s;
if (n >= (int) sizeof(buf)) n = (int) sizeof(buf) - 1;
buf[n] = '\0';
@@ -894,7 +896,7 @@ static size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex) {
}
static size_t scpy(void (*out)(char, void *), void *ptr, char *buf,
size_t len) {
size_t len) {
size_t i = 0;
while (i < len && buf[i] != '\0') out(buf[i++], ptr);
return i;
@@ -1088,7 +1090,8 @@ static void mg_fs_ls_fn(const char *filename, void *param) {
}
bool mg_fs_ls(struct mg_fs *fs, const char *path, char *buf, size_t len) {
struct mg_str s = {buf, len};
struct mg_str s;
s.buf = buf, s.len = len;
fs->ls(path, mg_fs_ls_fn, &s);
return buf[0] != '\0';
}
@@ -3749,7 +3752,8 @@ void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) {
char client_id[21];
struct mg_str cid = opts->client_id;
size_t total_len = 7 + 1 + 2 + 2;
uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', opts->version, 0};
uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', 0, 0};
hdr[6] = opts->version;
if (cid.len == 0) {
mg_random_str(client_id, sizeof(client_id) - 1);
@@ -4107,14 +4111,14 @@ size_t mg_printf(struct mg_connection *c, const char *fmt, ...) {
static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
uint32_t localhost = mg_htonl(0x7f000001);
if (mg_strcasecmp(str, mg_str("localhost")) != 0) return false;
memcpy(addr->ip, &localhost, sizeof(uint32_t));
memcpy(addr->addr.ip, &localhost, sizeof(uint32_t));
addr->is_ip6 = false;
return true;
}
static bool mg_atone(struct mg_str str, struct mg_addr *addr) {
if (str.len > 0) return false;
memset(addr->ip, 0, sizeof(addr->ip));
memset(addr->addr.ip, 0, sizeof(addr->addr.ip));
addr->is_ip6 = false;
return true;
}
@@ -4135,7 +4139,7 @@ static bool mg_aton4(struct mg_str str, struct mg_addr *addr) {
}
}
if (num_dots != 3 || str.buf[i - 1] == '.') return false;
memcpy(&addr->ip, data, sizeof(data));
memcpy(&addr->addr.ip, data, sizeof(data));
addr->is_ip6 = false;
return true;
}
@@ -4150,10 +4154,10 @@ static bool mg_v4mapped(struct mg_str str, struct mg_addr *addr) {
}
// struct mg_str s = mg_str_n(&str.buf[7], str.len - 7);
if (!mg_aton4(mg_str_n(&str.buf[7], str.len - 7), addr)) return false;
memcpy(&ipv4, addr->ip, sizeof(ipv4));
memset(addr->ip, 0, sizeof(addr->ip));
addr->ip[10] = addr->ip[11] = 255;
memcpy(&addr->ip[12], &ipv4, 4);
memcpy(&ipv4, addr->addr.ip, sizeof(ipv4));
memset(addr->addr.ip, 0, sizeof(addr->addr.ip));
addr->addr.ip[10] = addr->addr.ip[11] = 255;
memcpy(&addr->addr.ip[12], &ipv4, 4);
addr->is_ip6 = true;
return true;
}
@@ -4171,8 +4175,8 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
if (i > j + 3) return false;
// MG_DEBUG(("%lu %lu [%.*s]", i, j, (int) (i - j + 1), &str.buf[j]));
mg_str_to_num(mg_str_n(&str.buf[j], i - j + 1), 16, &val, sizeof(val));
addr->ip[n] = (uint8_t) ((val >> 8) & 255);
addr->ip[n + 1] = (uint8_t) (val & 255);
addr->addr.ip[n] = (uint8_t) ((val >> 8) & 255);
addr->addr.ip[n + 1] = (uint8_t) (val & 255);
} else if (str.buf[i] == ':') {
j = i + 1;
if (i > 0 && str.buf[i - 1] == ':') {
@@ -4182,8 +4186,8 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
n += 2;
}
if (n > 14) return false;
addr->ip[n] = addr->ip[n + 1] = 0; // For trailing ::
} else if (str.buf[i] == '%') { // Scope ID, last in string
addr->addr.ip[n] = addr->addr.ip[n + 1] = 0; // For trailing ::
} else if (str.buf[i] == '%') { // Scope ID, last in string
if (mg_str_to_num(mg_str_n(&str.buf[i + 1], str.len - i - 1), 10,
&addr->scope_id, sizeof(uint8_t))) {
addr->is_ip6 = true;
@@ -4197,8 +4201,8 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
}
if (n < 14 && dc == 42) return false;
if (n < 14) {
memmove(&addr->ip[dc + (14 - n)], &addr->ip[dc], n - dc + 2);
memset(&addr->ip[dc], 0, 14 - n);
memmove(&addr->addr.ip[dc + (14 - n)], &addr->addr.ip[dc], n - dc + 2);
memset(&addr->addr.ip[dc], 0, 14 - n);
}
addr->is_ip6 = true;
@@ -4422,7 +4426,11 @@ struct connstate {
bool twclosure; // 3-way closure done
};
#if defined(__DCC__)
#pragma pack(1)
#else
#pragma pack(push, 1)
#endif
struct lcp {
uint8_t addr, ctrl, proto[2], code, id, len[2];
@@ -4541,7 +4549,11 @@ struct dhcp6 {
uint8_t options[30 + sizeof(((struct mg_tcpip_if *) 0)->dhcp_name)];
};
#if defined(__DCC__)
#pragma pack(0)
#else
#pragma pack(pop)
#endif
// pkt is 8-bit aligned, pointers to headers hint compilers to generate
// byte-copy code for micros with alignment constraints
@@ -4744,14 +4756,14 @@ static bool tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
#if MG_ENABLE_IPV6
struct ip6 *ip6 = NULL;
if (ip_dst->is_ip6) {
ip6 = tx_ip6(ifp, mac_dst, 17, ip_src->ip6, ip_dst->ip6,
ip6 = tx_ip6(ifp, mac_dst, 17, ip_src->addr.ip6, ip_dst->addr.ip6,
len + sizeof(struct udp));
udp = (struct udp *) (ip6 + 1);
eth_len = sizeof(struct eth) + sizeof(*ip6) + sizeof(*udp) + len;
} else
#endif
{
ip = tx_ip(ifp, mac_dst, 17, ip_src->ip4, ip_dst->ip4,
ip = tx_ip(ifp, mac_dst, 17, ip_src->addr.ip4, ip_dst->addr.ip4,
len + sizeof(struct udp));
udp = (struct udp *) (ip + 1);
eth_len = sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len;
@@ -4783,10 +4795,10 @@ static bool tx_udp4(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
const void *buf, size_t len) {
struct mg_addr ips, ipd;
memset(&ips, 0, sizeof(ips));
ips.ip4 = ip_src;
ips.addr.ip4 = ip_src;
ips.port = sport;
memset(&ipd, 0, sizeof(ipd));
ipd.ip4 = ip_dst;
ipd.addr.ip4 = ip_dst;
ipd.port = dport;
return tx_udp(ifp, mac_dst, &ips, &ipd, buf, len);
}
@@ -4858,11 +4870,11 @@ static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt,
bool lsn) {
struct mg_connection *c = NULL;
for (c = mgr->conns; c != NULL; c = c->next) {
if (c->is_arplooking && pkt->arp && pkt->arp->spa == c->rem.ip4) break;
if (c->is_arplooking && pkt->arp && pkt->arp->spa == c->rem.addr.ip4) break;
#if MG_ENABLE_IPV6
if (c->is_arplooking && pkt->icmp6 && pkt->icmp6->type == 136) {
struct ndp_na *na = (struct ndp_na *) (pkt->icmp6 + 1);
if (MG_IP6MATCH(na->addr, c->rem.ip6)) break;
if (MG_IP6MATCH(na->addr, c->rem.addr.ip6)) break;
}
#endif
if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport &&
@@ -4914,8 +4926,8 @@ static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
if (c != NULL && c->is_arplooking) {
struct connstate *s = (struct connstate *) (c + 1);
memcpy(s->mac, pkt->arp->sha, sizeof(s->mac));
MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4, c->rem.ip,
mg_print_mac, s->mac));
MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4,
c->rem.addr.ip, mg_print_mac, s->mac));
c->is_arplooking = 0;
mac_resolved(c);
}
@@ -4930,7 +4942,7 @@ static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
struct ip *ip;
struct icmp *icmp;
struct mg_addr ips;
ips.ip4 = pkt->ip->src;
ips.addr.ip4 = pkt->ip->src;
ips.is_ip6 = false;
if (get_return_mac(ifp, &ips, false, pkt) == NULL)
return; // safety net for lousy networks
@@ -5028,13 +5040,14 @@ static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) {
if (op == 1 || op == 3) { // DHCP Discover or DHCP Request
uint8_t msg = op == 1 ? 2 : 5; // Message type: DHCP OFFER or DHCP ACK
uint8_t opts[] = {
53, 1, msg, // Message type
53, 1, 0, // Message type
1, 4, 0, 0, 0, 0, // Subnet mask
54, 4, 0, 0, 0, 0, // Server ID
12, 3, 'm', 'i', 'p', // Host name: "mip"
51, 4, 255, 255, 255, 255, // Lease time
255 // End of options
};
opts[2] = msg;
memcpy(&res.hwaddr, pkt->dhcp->hwaddr, 6);
memcpy(opts + 5, &ifp->mask, sizeof(ifp->mask));
memcpy(opts + 11, &ifp->ip, sizeof(ifp->ip));
@@ -5130,8 +5143,8 @@ static void rx_ndp_na(struct mg_tcpip_if *ifp, struct pkt *pkt) {
if (c != NULL && c->is_arplooking) {
struct connstate *s = (struct connstate *) (c + 1);
memcpy(s->mac, opts, sizeof(s->mac));
MG_DEBUG(("%lu NDP resolved %M -> %M", c->id, mg_print_ip6, c->rem.ip,
mg_print_mac, s->mac));
MG_DEBUG(("%lu NDP resolved %M -> %M", c->id, mg_print_ip6,
c->rem.addr.ip, mg_print_mac, s->mac));
c->is_arplooking = 0;
mac_resolved(c);
}
@@ -5343,7 +5356,7 @@ static uint8_t *get_return_mac(struct mg_tcpip_if *ifp, struct mg_addr *rem,
} else
#endif
{
uint32_t rem_ip = rem->ip4;
uint32_t rem_ip = rem->addr.ip4;
if (is_udp && (rem_ip == 0xffffffff || rem_ip == (ifp->ip | ~ifp->mask)))
return (uint8_t *) broadcast; // global or local broadcast
if (ifp->ip != 0 && ((rem_ip & ifp->mask) == (ifp->ip & ifp->mask)))
@@ -5369,12 +5382,12 @@ static bool rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
c->rem.port = pkt->udp->sport;
#if MG_ENABLE_IPV6
if (c->loc.is_ip6) {
c->rem.ip6[0] = pkt->ip6->src[0], c->rem.ip6[1] = pkt->ip6->src[1],
c->rem.is_ip6 = true;
c->rem.addr.ip6[0] = pkt->ip6->src[0],
c->rem.addr.ip6[1] = pkt->ip6->src[1], c->rem.is_ip6 = true;
} else
#endif
{
c->rem.ip4 = pkt->ip->src;
c->rem.addr.ip4 = pkt->ip->src;
}
if ((mac = get_return_mac(ifp, &c->rem, true, pkt)) == NULL)
return false; // safety net for lousy networks
@@ -5413,13 +5426,13 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
}
#if MG_ENABLE_IPV6
if (ip_dst->is_ip6) {
ip6 = tx_ip6(ifp, mac_dst, 6, ip_src->ip6, ip_dst->ip6,
ip6 = tx_ip6(ifp, mac_dst, 6, ip_src->addr.ip6, ip_dst->addr.ip6,
sizeof(struct tcp) + len);
tcp = (struct tcp *) (ip6 + 1);
} else
#endif
{
ip = tx_ip(ifp, mac_dst, 6, ip_src->ip4, ip_dst->ip4,
ip = tx_ip(ifp, mac_dst, 6, ip_src->addr.ip4, ip_dst->addr.ip4,
sizeof(struct tcp) + len);
tcp = (struct tcp *) (ip + 1);
}
@@ -5442,9 +5455,6 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
cs = csumup(cs, &ip6->src, sizeof(ip6->src));
cs = csumup(cs, &ip6->dst, sizeof(ip6->dst));
cs += (uint32_t) (6 + n);
MG_VERBOSE(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip6, &ip6->src,
mg_ntohs(tcp->sport), mg_print_ip6, &ip6->dst,
mg_ntohs(tcp->dport), tcp->flags, len));
} else
#endif
{
@@ -5453,12 +5463,11 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
cs = csumup(cs, &ip->src, sizeof(ip->src));
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
cs = csumup(cs, pseudo, sizeof(pseudo));
MG_VERBOSE(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip4, &ip->src,
mg_ntohs(tcp->sport), mg_print_ip4, &ip->dst,
mg_ntohs(tcp->dport), tcp->flags, len));
}
tcp->csum = csumfin(cs);
}
MG_VERBOSE(("TCP %M -> %M fl %x len %u", mg_print_ip_port, ip_src,
mg_print_ip_port, ip_dst, tcp->flags, len));
return ether_output(ifp, PDIFF(ifp->tx.buf, tcp + 1) + len);
}
@@ -5471,11 +5480,11 @@ static size_t tx_tcp_ctrlresp(struct mg_tcpip_if *ifp, struct pkt *pkt,
memset(&ips, 0, sizeof(ips));
memset(&ipd, 0, sizeof(ipd));
if (pkt->ip != NULL) {
ips.ip4 = pkt->ip->dst;
ipd.ip4 = pkt->ip->src;
ips.addr.ip4 = pkt->ip->dst;
ipd.addr.ip4 = pkt->ip->src;
} else {
ips.ip6[0] = pkt->ip6->dst[0], ips.ip6[1] = pkt->ip6->dst[1];
ipd.ip6[0] = pkt->ip6->src[0], ipd.ip6[1] = pkt->ip6->src[1];
ips.addr.ip6[0] = pkt->ip6->dst[0], ips.addr.ip6[1] = pkt->ip6->dst[1];
ipd.addr.ip6[0] = pkt->ip6->src[0], ipd.addr.ip6[1] = pkt->ip6->src[1];
ips.is_ip6 = true;
ipd.is_ip6 = true;
}
@@ -5505,16 +5514,16 @@ static struct mg_connection *accept_conn(struct mg_connection *lsn,
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
#if MG_ENABLE_IPV6
if (lsn->loc.is_ip6) {
c->rem.ip6[0] = pkt->ip6->src[0], c->rem.ip6[1] = pkt->ip6->src[1],
c->rem.is_ip6 = true;
c->loc.ip6[0] = c->mgr->ifp->ip6[0], c->loc.ip6[1] = c->mgr->ifp->ip6[1],
c->loc.is_ip6 = true;
c->rem.addr.ip6[0] = pkt->ip6->src[0],
c->rem.addr.ip6[1] = pkt->ip6->src[1], c->rem.is_ip6 = true;
c->loc.addr.ip6[0] = c->mgr->ifp->ip6[0],
c->loc.addr.ip6[1] = c->mgr->ifp->ip6[1], c->loc.is_ip6 = true;
// TODO(): compare lsn to link-local, or rem as link-local: use ll instead
} else
#endif
{
c->rem.ip4 = pkt->ip->src;
c->loc.ip4 = c->mgr->ifp->ip;
c->rem.addr.ip4 = pkt->ip->src;
c->loc.addr.ip4 = c->mgr->ifp->ip;
}
c->rem.port = pkt->tcp->sport;
c->loc.port = lsn->loc.port;
@@ -5576,12 +5585,13 @@ static bool udp_send(struct mg_connection *c, const void *buf, size_t len) {
memset(&ips, 0, sizeof(ips));
#if MG_ENABLE_IPV6
if (c->loc.is_ip6) {
ips.ip6[0] = ifp->ip6[0], ips.ip6[1] = ifp->ip6[1], ips.is_ip6 = true;
ips.addr.ip6[0] = ifp->ip6[0], ips.addr.ip6[1] = ifp->ip6[1],
ips.is_ip6 = true;
// TODO(): detect link-local (c->rem) and use it
} else
#endif
{
ips.ip4 = ifp->ip;
ips.addr.ip4 = ifp->ip;
}
ips.port = c->loc.port;
return tx_udp(ifp, s->mac, &ips, &c->rem, buf, len);
@@ -6319,12 +6329,12 @@ void mg_connect_resolved(struct mg_connection *c) {
c->loc.port = mg_htons(ifp->eport++);
#if MG_ENABLE_IPV6
if (c->rem.is_ip6) {
c->loc.ip6[0] = ifp->ip6[0], c->loc.ip6[1] = ifp->ip6[1],
c->loc.addr.ip6[0] = ifp->ip6[0], c->loc.addr.ip6[1] = ifp->ip6[1],
c->loc.is_ip6 = true;
} else
#endif
{
c->loc.ip4 = ifp->ip;
c->loc.addr.ip4 = ifp->ip;
}
MG_DEBUG(("%lu %M -> %M", c->id, mg_print_ip_port, &c->loc, mg_print_ip_port,
&c->rem));
@@ -6333,21 +6343,21 @@ void mg_connect_resolved(struct mg_connection *c) {
#if MG_ENABLE_IPV6
if (c->rem.is_ip6) {
if (c->is_udp &&
MG_IP6MATCH(c->rem.ip6, ip6_allnodes.u)) { // local broadcast
MG_IP6MATCH(c->rem.addr.ip6, ip6_allnodes.u)) { // local broadcast
struct connstate *s = (struct connstate *) (c + 1);
memcpy(s->mac, ip6mac_allnodes, sizeof(s->mac));
mac_resolved(c);
} else if (c->rem.ip6[0] == ifp->ip6[0] && // TODO(): HANDLE PREFIX ***
!MG_IP6MATCH(c->rem.ip6,
} else if (c->rem.addr.ip6[0] == ifp->ip6[0] && // TODO(): HANDLE PREFIX ***
!MG_IP6MATCH(c->rem.addr.ip6,
ifp->gw6)) { // skip if gw (onstate6change -> NS)
// If we're in the same LAN, fire a Neighbor Solicitation
MG_DEBUG(("%lu NS lookup...", c->id));
tx_ndp_ns(ifp, c->rem.ip6, ifp->mac);
tx_ndp_ns(ifp, c->rem.addr.ip6, ifp->mac);
settmout(c, MIP_TTYPE_ARP);
c->is_arplooking = 1;
} else if (c->is_udp && *((uint8_t *) c->rem.ip6) == 0xFF) { // multicast
} else if (c->is_udp && *((uint8_t *) c->rem.addr.ip6) == 0xFF) { // multicast
struct connstate *s = (struct connstate *) (c + 1);
ip6_mcastmac(s->mac, c->rem.ip6);
ip6_mcastmac(s->mac, c->rem.addr.ip6);
mac_resolved(c);
} else if (ifp->gw6_ready) {
struct connstate *s = (struct connstate *) (c + 1);
@@ -6359,7 +6369,7 @@ void mg_connect_resolved(struct mg_connection *c) {
} else
#endif
{
uint32_t rem_ip = c->rem.ip4;
uint32_t rem_ip = c->rem.addr.ip4;
if (c->is_udp &&
(rem_ip == 0xffffffff || rem_ip == (ifp->ip | ~ifp->mask))) {
struct connstate *s = (struct connstate *) (c + 1);
@@ -8711,8 +8721,10 @@ void mg_pfn_iobuf(char ch, void *param) {
}
size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap) {
struct mg_iobuf io = {(uint8_t *) buf, len, 0, 0};
size_t n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap);
struct mg_iobuf io = {0, 0, 0, 0};
size_t n;
io.buf = (uint8_t *) buf, io.size = len;
n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap);
if (n < len) buf[n] = '\0';
return n;
}
@@ -8769,8 +8781,8 @@ size_t mg_print_ip6(void (*out)(char, void *), void *arg, va_list *ap) {
size_t mg_print_ip(void (*out)(char, void *), void *arg, va_list *ap) {
struct mg_addr *addr = va_arg(*ap, struct mg_addr *);
if (addr->is_ip6) return print_ip6(out, arg, (uint16_t *) addr->ip);
return print_ip4(out, arg, (uint8_t *) &addr->ip);
if (addr->is_ip6) return print_ip6(out, arg, (uint16_t *) addr->addr.ip);
return print_ip4(out, arg, (uint8_t *) &addr->addr.ip);
}
size_t mg_print_ip_port(void (*out)(char, void *), void *arg, va_list *ap) {
@@ -8818,7 +8830,8 @@ static size_t bcpy(void (*out)(char, void *), void *arg, uint8_t *buf,
for (i = 0; i < len; i += 3) {
uint8_t c1 = buf[i], c2 = i + 1 < len ? buf[i + 1] : 0,
c3 = i + 2 < len ? buf[i + 2] : 0;
char tmp[4] = {t[c1 >> 2], t[(c1 & 3) << 4 | (c2 >> 4)], '=', '='};
char tmp[4] = {0, 0, '=', '='};
tmp[0] = t[c1 >> 2], tmp[1] = t[(c1 & 3) << 4 | (c2 >> 4)];
if (i + 1 < len) tmp[2] = t[(c2 & 15) << 2 | (c3 >> 6)];
if (i + 2 < len) tmp[3] = t[c3 & 63];
for (j = 0; j < sizeof(tmp) && tmp[j] != '\0'; j++) out(tmp[j], arg);
@@ -9444,6 +9457,35 @@ void mg_hmac_sha256(uint8_t dst[32], uint8_t *key, size_t keysz, uint8_t *data,
#define sig164(x) (rotr64(x, 19) ^ rotr64(x, 61) ^ ((x) >> 6))
static const uint64_t mg_sha256_k2[80] = {
#if defined(__DCC__)
0x428a2f98d728ae22ull, 0x7137449123ef65cdull, 0xb5c0fbcfec4d3b2full,
0xe9b5dba58189dbbcull, 0x3956c25bf348b538ull, 0x59f111f1b605d019ull,
0x923f82a4af194f9bull, 0xab1c5ed5da6d8118ull, 0xd807aa98a3030242ull,
0x12835b0145706fbeull, 0x243185be4ee4b28cull, 0x550c7dc3d5ffb4e2ull,
0x72be5d74f27b896full, 0x80deb1fe3b1696b1ull, 0x9bdc06a725c71235ull,
0xc19bf174cf692694ull, 0xe49b69c19ef14ad2ull, 0xefbe4786384f25e3ull,
0x0fc19dc68b8cd5b5ull, 0x240ca1cc77ac9c65ull, 0x2de92c6f592b0275ull,
0x4a7484aa6ea6e483ull, 0x5cb0a9dcbd41fbd4ull, 0x76f988da831153b5ull,
0x983e5152ee66dfabull, 0xa831c66d2db43210ull, 0xb00327c898fb213full,
0xbf597fc7beef0ee4ull, 0xc6e00bf33da88fc2ull, 0xd5a79147930aa725ull,
0x06ca6351e003826full, 0x142929670a0e6e70ull, 0x27b70a8546d22ffcull,
0x2e1b21385c26c926ull, 0x4d2c6dfc5ac42aedull, 0x53380d139d95b3dfull,
0x650a73548baf63deull, 0x766a0abb3c77b2a8ull, 0x81c2c92e47edaee6ull,
0x92722c851482353bull, 0xa2bfe8a14cf10364ull, 0xa81a664bbc423001ull,
0xc24b8b70d0f89791ull, 0xc76c51a30654be30ull, 0xd192e819d6ef5218ull,
0xd69906245565a910ull, 0xf40e35855771202aull, 0x106aa07032bbd1b8ull,
0x19a4c116b8d2d0c8ull, 0x1e376c085141ab53ull, 0x2748774cdf8eeb99ull,
0x34b0bcb5e19b48a8ull, 0x391c0cb3c5c95a63ull, 0x4ed8aa4ae3418acbull,
0x5b9cca4f7763e373ull, 0x682e6ff3d6b2b8a3ull, 0x748f82ee5defb2fcull,
0x78a5636f43172f60ull, 0x84c87814a1f0ab72ull, 0x8cc702081a6439ecull,
0x90befffa23631e28ull, 0xa4506cebde82bde9ull, 0xbef9a3f7b2c67915ull,
0xc67178f2e372532bull, 0xca273eceea26619cull, 0xd186b8c721c0c207ull,
0xeada7dd6cde0eb1eull, 0xf57d4f7fee6ed178ull, 0x06f067aa72176fbaull,
0x0a637dc5a2c898a6ull, 0x113f9804bef90daeull, 0x1b710b35131c471bull,
0x28db77f523047d84ull, 0x32caab7b40c72493ull, 0x3c9ebe0a15c9bebcull,
0x431d67c49c100d4cull, 0x4cc5d4becb3e42b6ull, 0x597f299cfc657e2aull,
0x5fcb6fab3ad6faecull, 0x6c44198c4a475817ull
#else
0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
@@ -9470,7 +9512,9 @@ static const uint64_t mg_sha256_k2[80] = {
0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
0x5fcb6fab3ad6faec, 0x6c44198c4a475817};
0x5fcb6fab3ad6faec, 0x6c44198c4a475817
#endif
};
static void mg_sha384_transform(mg_sha384_ctx *ctx, const uint8_t data[]) {
uint64_t m[80];
@@ -9521,6 +9565,16 @@ void mg_sha384_init(mg_sha384_ctx *ctx) {
ctx->datalen = 0;
ctx->bitlen[0] = 0;
ctx->bitlen[1] = 0;
#if defined(__DCC__)
ctx->state[0] = 0xcbbb9d5dc1059ed8ull;
ctx->state[1] = 0x629a292a367cd507ull;
ctx->state[2] = 0x9159015a3070dd17ull;
ctx->state[3] = 0x152fecd8f70e5939ull;
ctx->state[4] = 0x67332667ffc00b31ull;
ctx->state[5] = 0x8eb44a8768581511ull;
ctx->state[6] = 0xdb0c2e0d64f98fa7ull;
ctx->state[7] = 0x47b5481dbefa4fa4ull;
#else
ctx->state[0] = 0xcbbb9d5dc1059ed8;
ctx->state[1] = 0x629a292a367cd507;
ctx->state[2] = 0x9159015a3070dd17;
@@ -9529,6 +9583,7 @@ void mg_sha384_init(mg_sha384_ctx *ctx) {
ctx->state[5] = 0x8eb44a8768581511;
ctx->state[6] = 0xdb0c2e0d64f98fa7;
ctx->state[7] = 0x47b5481dbefa4fa4;
#endif
}
void mg_sha384_update(mg_sha384_ctx *ctx, const uint8_t *data, size_t len) {
@@ -9751,13 +9806,13 @@ static socklen_t tousa(struct mg_addr *a, union usa *usa) {
memset(usa, 0, sizeof(*usa));
usa->sin.sin_family = AF_INET;
usa->sin.sin_port = a->port;
memcpy(&usa->sin.sin_addr, a->ip, sizeof(uint32_t));
memcpy(&usa->sin.sin_addr, a->addr.ip, sizeof(uint32_t));
#if MG_ENABLE_IPV6
if (a->is_ip6) {
usa->sin.sin_family = AF_INET6;
usa->sin6.sin6_port = a->port;
usa->sin6.sin6_scope_id = a->scope_id;
memcpy(&usa->sin6.sin6_addr, a->ip, sizeof(a->ip));
memcpy(&usa->sin6.sin6_addr, a->addr.ip, sizeof(a->addr.ip));
len = sizeof(usa->sin6);
}
#endif
@@ -9767,10 +9822,10 @@ static socklen_t tousa(struct mg_addr *a, union usa *usa) {
static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) {
a->is_ip6 = is_ip6;
a->port = usa->sin.sin_port;
memcpy(&a->ip, &usa->sin.sin_addr, sizeof(uint32_t));
memcpy(&a->addr.ip, &usa->sin.sin_addr, sizeof(uint32_t));
#if MG_ENABLE_IPV6
if (is_ip6) {
memcpy(a->ip, &usa->sin6.sin6_addr, sizeof(a->ip));
memcpy(a->addr.ip, &usa->sin6.sin6_addr, sizeof(a->addr.ip));
a->port = usa->sin6.sin6_port;
a->scope_id = (uint8_t) usa->sin6.sin6_scope_id;
}
@@ -10582,12 +10637,14 @@ void mg_http_serve_ssi(struct mg_connection *c, const char *root,
struct mg_str mg_str_s(const char *s) {
struct mg_str str = {(char *) s, s == NULL ? 0 : strlen(s)};
struct mg_str str;
str.buf = (char *) s, str.len = (s == NULL) ? 0 : strlen(s);
return str;
}
struct mg_str mg_str_n(const char *s, size_t n) {
struct mg_str str = {(char *) s, n};
struct mg_str str;
str.buf = (char *) s, str.len = n;
return str;
}
@@ -13161,7 +13218,7 @@ static int mg_tls_verify_cert_san(const uint8_t *der, size_t dersz,
while (mg_der_next(&field, &name) > 0) {
if (name.type == 0x87 && name.len == 4) { // this is an IPv4 address
MG_DEBUG(("Found SAN, IP: %M", mg_print_ip4, name.value));
if (!server_ip->is_ip6 && *((uint32_t *) name.value) == server_ip->ip4)
if (!server_ip->is_ip6 && *((uint32_t *) name.value) == server_ip->addr.ip4)
return 1; // and matches the one we're connected to
} else { // this is a text SAN
MG_DEBUG(("Found SAN, (%u): %.*s", name.type, name.len, name.value));
@@ -21038,7 +21095,7 @@ int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip) {
if (remote_ip->is_ip6) {
return -1; // TODO(): handle IPv6 ACL and addresses
} else { // IPv4
memcpy((void *) &remote_ip4, remote_ip->ip, sizeof(remote_ip4));
memcpy((void *) &remote_ip4, remote_ip->addr.ip, sizeof(remote_ip4));
while (mg_span(acl, &entry, &acl, ',')) {
uint32_t net, mask;
if (entry.buf[0] != '+' && entry.buf[0] != '-') return -1;
@@ -21052,7 +21109,7 @@ int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip) {
bool mg_path_is_sane(const struct mg_str path) {
const char *s = path.buf;
size_t n = path.len;
if (path.buf[0] == '~') return false; // Starts with ~
if (path.buf[0] == '~') return false; // Starts with ~
if (path.buf[0] == '.' && path.buf[1] == '.') return false; // Starts with ..
for (; s[0] != '\0' && n > 0; s++, n--) {
if ((s[0] == '/' || s[0] == '\\') && n >= 2) { // Subdir?
@@ -21131,7 +21188,6 @@ void mg_delayms(unsigned int ms) {
while (mg_millis() < to) (void) 0;
}
#if MG_ENABLE_CUSTOM_CALLOC
#else
void *mg_calloc(size_t count, size_t size) {
@@ -21357,9 +21413,13 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data) {
while (ws_process(c->recv.buf + ofs, c->recv.len - ofs, &msg) > 0) {
char *s = (char *) c->recv.buf + ofs + msg.header_len;
struct mg_ws_message m = {{s, msg.data_len}, msg.flags};
size_t len = msg.header_len + msg.data_len;
uint8_t final = msg.flags & 128, op = msg.flags & 15;
struct mg_ws_message m;
size_t len;
uint8_t final, op;
m.data.buf = s, m.data.len = msg.data_len, m.flags = msg.flags;
len = msg.header_len + msg.data_len;
final = msg.flags & 128;
op = msg.flags & 15;
// MG_VERBOSE ("fin %d op %d len %d [%.*s]", final, op,
// (int) m.data.len, (int) m.data.len, m.data.buf));
switch (op) {
+19 -13
View File
@@ -1267,12 +1267,18 @@ void mg_log_set_fn(mg_pfn_t fn, void *param);
#define mg_log_set(level_) mg_log_level = (level_)
#if MG_ENABLE_LOG
#define MG_LOG(level, args) \
do { \
if ((level) <= mg_log_level) { \
mg_log_prefix((level), __FILE__, __LINE__, __func__); \
mg_log args; \
} \
#if !defined(_MSC_VER) && \
(!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
#define MG___FUNC__ ""
#else
#define MG___FUNC__ __func__ // introduced in C99
#endif
#define MG_LOG(level, args) \
do { \
if ((level) <= mg_log_level) { \
mg_log_prefix((level), __FILE__, __LINE__, MG___FUNC__); \
mg_log args; \
} \
} while (0)
#else
#define MG_LOG(level, args) \
@@ -1663,11 +1669,11 @@ struct mg_dns {
};
struct mg_addr {
union { // Holds IPv4 or IPv6 address, in network byte order
union { // Holds IPv4 or IPv6 address, in network byte order
uint8_t ip[16];
uint32_t ip4;
uint64_t ip6[2];
};
} addr;
uint16_t port; // TCP or UDP port in network byte order
uint8_t scope_id; // IPv6 scope ID
bool is_ip6; // True when address is IPv6 address
@@ -2954,7 +2960,6 @@ struct mg_dns_rr {
uint16_t alen; // Address length
};
// DNS-SD response record
struct mg_dnssd_record {
struct mg_str srvcproto; // service.proto, service name
@@ -2966,8 +2971,8 @@ struct mg_dnssd_record {
struct mg_mdns_req {
struct mg_dns_rr *rr;
struct mg_dnssd_record *r;
struct mg_str reqname; // requested name in RR
struct mg_str respname; // actual name in response
struct mg_str reqname; // requested name in RR
struct mg_str respname; // actual name in response
struct mg_addr addr;
bool is_listing;
bool is_resp;
@@ -2979,8 +2984,9 @@ void mg_resolve_cancel(struct mg_connection *);
bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *);
size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
bool is_question, struct mg_dns_rr *);
struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, mg_event_handler_t fn, void *fn_data);
struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, mg_event_handler_t fn,
void *fn_data);
+2 -2
View File
@@ -136,12 +136,12 @@ bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
if (rr.alen == 4 && rr.atype == 1 && rr.aclass == 1) {
dm->addr.is_ip6 = false;
memcpy(&dm->addr.ip, &buf[ofs - 4], 4);
memcpy(&dm->addr.addr.ip, &buf[ofs - 4], 4);
dm->resolved = true;
break; // Return success
} else if (rr.alen == 16 && rr.atype == 28 && rr.aclass == 1) {
dm->addr.is_ip6 = true;
memcpy(&dm->addr.ip, &buf[ofs - 16], 16);
memcpy(&dm->addr.addr.ip, &buf[ofs - 16], 16);
dm->resolved = true;
break; // Return success
}
+5 -5
View File
@@ -31,7 +31,6 @@ struct mg_dns_rr {
uint16_t alen; // Address length
};
// DNS-SD response record
struct mg_dnssd_record {
struct mg_str srvcproto; // service.proto, service name
@@ -43,8 +42,8 @@ struct mg_dnssd_record {
struct mg_mdns_req {
struct mg_dns_rr *rr;
struct mg_dnssd_record *r;
struct mg_str reqname; // requested name in RR
struct mg_str respname; // actual name in response
struct mg_str reqname; // requested name in RR
struct mg_str respname; // actual name in response
struct mg_addr addr;
bool is_listing;
bool is_resp;
@@ -56,5 +55,6 @@ void mg_resolve_cancel(struct mg_connection *);
bool mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *);
size_t mg_dns_parse_rr(const uint8_t *buf, size_t len, size_t ofs,
bool is_question, struct mg_dns_rr *);
struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, mg_event_handler_t fn, void *fn_data);
struct mg_connection *mg_mdns_listen(struct mg_mgr *mgr, mg_event_handler_t fn,
void *fn_data);
+6 -4
View File
@@ -22,7 +22,8 @@ static int xisinf(double x) {
union {
double f;
uint64_t u;
} ieee754 = {x};
} ieee754;
ieee754.f = x;
return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
((unsigned) ieee754.u == 0);
}
@@ -31,7 +32,8 @@ static int xisnan(double x) {
union {
double f;
uint64_t u;
} ieee754 = {x};
} ieee754;
ieee754.f = x;
return ((unsigned) (ieee754.u >> 32) & 0x7fffffff) +
((unsigned) ieee754.u != 0) >
0x7ff00000;
@@ -99,7 +101,7 @@ static size_t mg_dtoa(char *dst, size_t dstlen, double d, int width, bool tz) {
}
while (tz && n > 0 && buf[s + n - 1] == '0') n--; // Trim trailing zeroes
if (tz && n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot
if (tz && n > 0 && buf[s + n - 1] == '.') n--; // Trim trailing dot
n += s;
if (n >= (int) sizeof(buf)) n = (int) sizeof(buf) - 1;
buf[n] = '\0';
@@ -129,7 +131,7 @@ static size_t mg_lld(char *buf, int64_t val, bool is_signed, bool is_hex) {
}
static size_t scpy(void (*out)(char, void *), void *ptr, char *buf,
size_t len) {
size_t len) {
size_t i = 0;
while (i < len && buf[i] != '\0') out(buf[i++], ptr);
return i;
+2 -1
View File
@@ -86,7 +86,8 @@ static void mg_fs_ls_fn(const char *filename, void *param) {
}
bool mg_fs_ls(struct mg_fs *fs, const char *path, char *buf, size_t len) {
struct mg_str s = {buf, len};
struct mg_str s;
s.buf = buf, s.len = len;
fs->ls(path, mg_fs_ls_fn, &s);
return buf[0] != '\0';
}
+12 -6
View File
@@ -16,12 +16,18 @@ void mg_log_set_fn(mg_pfn_t fn, void *param);
#define mg_log_set(level_) mg_log_level = (level_)
#if MG_ENABLE_LOG
#define MG_LOG(level, args) \
do { \
if ((level) <= mg_log_level) { \
mg_log_prefix((level), __FILE__, __LINE__, __func__); \
mg_log args; \
} \
#if !defined(_MSC_VER) && \
(!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
#define MG___FUNC__ ""
#else
#define MG___FUNC__ __func__ // introduced in C99
#endif
#define MG_LOG(level, args) \
do { \
if ((level) <= mg_log_level) { \
mg_log_prefix((level), __FILE__, __LINE__, MG___FUNC__); \
mg_log args; \
} \
} while (0)
#else
#define MG_LOG(level, args) \
+2 -1
View File
@@ -266,7 +266,8 @@ void mg_mqtt_login(struct mg_connection *c, const struct mg_mqtt_opts *opts) {
char client_id[21];
struct mg_str cid = opts->client_id;
size_t total_len = 7 + 1 + 2 + 2;
uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', opts->version, 0};
uint8_t hdr[8] = {0, 4, 'M', 'Q', 'T', 'T', 0, 0};
hdr[6] = opts->version;
if (cid.len == 0) {
mg_random_str(client_id, sizeof(client_id) - 1);
+13 -13
View File
@@ -31,14 +31,14 @@ size_t mg_printf(struct mg_connection *c, const char *fmt, ...) {
static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
uint32_t localhost = mg_htonl(0x7f000001);
if (mg_strcasecmp(str, mg_str("localhost")) != 0) return false;
memcpy(addr->ip, &localhost, sizeof(uint32_t));
memcpy(addr->addr.ip, &localhost, sizeof(uint32_t));
addr->is_ip6 = false;
return true;
}
static bool mg_atone(struct mg_str str, struct mg_addr *addr) {
if (str.len > 0) return false;
memset(addr->ip, 0, sizeof(addr->ip));
memset(addr->addr.ip, 0, sizeof(addr->addr.ip));
addr->is_ip6 = false;
return true;
}
@@ -59,7 +59,7 @@ static bool mg_aton4(struct mg_str str, struct mg_addr *addr) {
}
}
if (num_dots != 3 || str.buf[i - 1] == '.') return false;
memcpy(&addr->ip, data, sizeof(data));
memcpy(&addr->addr.ip, data, sizeof(data));
addr->is_ip6 = false;
return true;
}
@@ -74,10 +74,10 @@ static bool mg_v4mapped(struct mg_str str, struct mg_addr *addr) {
}
// struct mg_str s = mg_str_n(&str.buf[7], str.len - 7);
if (!mg_aton4(mg_str_n(&str.buf[7], str.len - 7), addr)) return false;
memcpy(&ipv4, addr->ip, sizeof(ipv4));
memset(addr->ip, 0, sizeof(addr->ip));
addr->ip[10] = addr->ip[11] = 255;
memcpy(&addr->ip[12], &ipv4, 4);
memcpy(&ipv4, addr->addr.ip, sizeof(ipv4));
memset(addr->addr.ip, 0, sizeof(addr->addr.ip));
addr->addr.ip[10] = addr->addr.ip[11] = 255;
memcpy(&addr->addr.ip[12], &ipv4, 4);
addr->is_ip6 = true;
return true;
}
@@ -95,8 +95,8 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
if (i > j + 3) return false;
// MG_DEBUG(("%lu %lu [%.*s]", i, j, (int) (i - j + 1), &str.buf[j]));
mg_str_to_num(mg_str_n(&str.buf[j], i - j + 1), 16, &val, sizeof(val));
addr->ip[n] = (uint8_t) ((val >> 8) & 255);
addr->ip[n + 1] = (uint8_t) (val & 255);
addr->addr.ip[n] = (uint8_t) ((val >> 8) & 255);
addr->addr.ip[n + 1] = (uint8_t) (val & 255);
} else if (str.buf[i] == ':') {
j = i + 1;
if (i > 0 && str.buf[i - 1] == ':') {
@@ -106,8 +106,8 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
n += 2;
}
if (n > 14) return false;
addr->ip[n] = addr->ip[n + 1] = 0; // For trailing ::
} else if (str.buf[i] == '%') { // Scope ID, last in string
addr->addr.ip[n] = addr->addr.ip[n + 1] = 0; // For trailing ::
} else if (str.buf[i] == '%') { // Scope ID, last in string
if (mg_str_to_num(mg_str_n(&str.buf[i + 1], str.len - i - 1), 10,
&addr->scope_id, sizeof(uint8_t))) {
addr->is_ip6 = true;
@@ -121,8 +121,8 @@ static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
}
if (n < 14 && dc == 42) return false;
if (n < 14) {
memmove(&addr->ip[dc + (14 - n)], &addr->ip[dc], n - dc + 2);
memset(&addr->ip[dc], 0, 14 - n);
memmove(&addr->addr.ip[dc + (14 - n)], &addr->addr.ip[dc], n - dc + 2);
memset(&addr->addr.ip[dc], 0, 14 - n);
}
addr->is_ip6 = true;
+2 -2
View File
@@ -14,11 +14,11 @@ struct mg_dns {
};
struct mg_addr {
union { // Holds IPv4 or IPv6 address, in network byte order
union { // Holds IPv4 or IPv6 address, in network byte order
uint8_t ip[16];
uint32_t ip4;
uint64_t ip6[2];
};
} addr;
uint16_t port; // TCP or UDP port in network byte order
uint8_t scope_id; // IPv6 scope ID
bool is_ip6; // True when address is IPv6 address
+51 -45
View File
@@ -34,7 +34,11 @@ struct connstate {
bool twclosure; // 3-way closure done
};
#if defined(__DCC__)
#pragma pack(1)
#else
#pragma pack(push, 1)
#endif
struct lcp {
uint8_t addr, ctrl, proto[2], code, id, len[2];
@@ -153,7 +157,11 @@ struct dhcp6 {
uint8_t options[30 + sizeof(((struct mg_tcpip_if *) 0)->dhcp_name)];
};
#if defined(__DCC__)
#pragma pack(0)
#else
#pragma pack(pop)
#endif
// pkt is 8-bit aligned, pointers to headers hint compilers to generate
// byte-copy code for micros with alignment constraints
@@ -356,14 +364,14 @@ static bool tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
#if MG_ENABLE_IPV6
struct ip6 *ip6 = NULL;
if (ip_dst->is_ip6) {
ip6 = tx_ip6(ifp, mac_dst, 17, ip_src->ip6, ip_dst->ip6,
ip6 = tx_ip6(ifp, mac_dst, 17, ip_src->addr.ip6, ip_dst->addr.ip6,
len + sizeof(struct udp));
udp = (struct udp *) (ip6 + 1);
eth_len = sizeof(struct eth) + sizeof(*ip6) + sizeof(*udp) + len;
} else
#endif
{
ip = tx_ip(ifp, mac_dst, 17, ip_src->ip4, ip_dst->ip4,
ip = tx_ip(ifp, mac_dst, 17, ip_src->addr.ip4, ip_dst->addr.ip4,
len + sizeof(struct udp));
udp = (struct udp *) (ip + 1);
eth_len = sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len;
@@ -395,10 +403,10 @@ static bool tx_udp4(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
const void *buf, size_t len) {
struct mg_addr ips, ipd;
memset(&ips, 0, sizeof(ips));
ips.ip4 = ip_src;
ips.addr.ip4 = ip_src;
ips.port = sport;
memset(&ipd, 0, sizeof(ipd));
ipd.ip4 = ip_dst;
ipd.addr.ip4 = ip_dst;
ipd.port = dport;
return tx_udp(ifp, mac_dst, &ips, &ipd, buf, len);
}
@@ -470,11 +478,11 @@ static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt,
bool lsn) {
struct mg_connection *c = NULL;
for (c = mgr->conns; c != NULL; c = c->next) {
if (c->is_arplooking && pkt->arp && pkt->arp->spa == c->rem.ip4) break;
if (c->is_arplooking && pkt->arp && pkt->arp->spa == c->rem.addr.ip4) break;
#if MG_ENABLE_IPV6
if (c->is_arplooking && pkt->icmp6 && pkt->icmp6->type == 136) {
struct ndp_na *na = (struct ndp_na *) (pkt->icmp6 + 1);
if (MG_IP6MATCH(na->addr, c->rem.ip6)) break;
if (MG_IP6MATCH(na->addr, c->rem.addr.ip6)) break;
}
#endif
if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport &&
@@ -526,8 +534,8 @@ static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
if (c != NULL && c->is_arplooking) {
struct connstate *s = (struct connstate *) (c + 1);
memcpy(s->mac, pkt->arp->sha, sizeof(s->mac));
MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4, c->rem.ip,
mg_print_mac, s->mac));
MG_DEBUG(("%lu ARP resolved %M -> %M", c->id, mg_print_ip4,
c->rem.addr.ip, mg_print_mac, s->mac));
c->is_arplooking = 0;
mac_resolved(c);
}
@@ -542,7 +550,7 @@ static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
struct ip *ip;
struct icmp *icmp;
struct mg_addr ips;
ips.ip4 = pkt->ip->src;
ips.addr.ip4 = pkt->ip->src;
ips.is_ip6 = false;
if (get_return_mac(ifp, &ips, false, pkt) == NULL)
return; // safety net for lousy networks
@@ -640,13 +648,14 @@ static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) {
if (op == 1 || op == 3) { // DHCP Discover or DHCP Request
uint8_t msg = op == 1 ? 2 : 5; // Message type: DHCP OFFER or DHCP ACK
uint8_t opts[] = {
53, 1, msg, // Message type
53, 1, 0, // Message type
1, 4, 0, 0, 0, 0, // Subnet mask
54, 4, 0, 0, 0, 0, // Server ID
12, 3, 'm', 'i', 'p', // Host name: "mip"
51, 4, 255, 255, 255, 255, // Lease time
255 // End of options
};
opts[2] = msg;
memcpy(&res.hwaddr, pkt->dhcp->hwaddr, 6);
memcpy(opts + 5, &ifp->mask, sizeof(ifp->mask));
memcpy(opts + 11, &ifp->ip, sizeof(ifp->ip));
@@ -742,8 +751,8 @@ static void rx_ndp_na(struct mg_tcpip_if *ifp, struct pkt *pkt) {
if (c != NULL && c->is_arplooking) {
struct connstate *s = (struct connstate *) (c + 1);
memcpy(s->mac, opts, sizeof(s->mac));
MG_DEBUG(("%lu NDP resolved %M -> %M", c->id, mg_print_ip6, c->rem.ip,
mg_print_mac, s->mac));
MG_DEBUG(("%lu NDP resolved %M -> %M", c->id, mg_print_ip6,
c->rem.addr.ip, mg_print_mac, s->mac));
c->is_arplooking = 0;
mac_resolved(c);
}
@@ -955,7 +964,7 @@ static uint8_t *get_return_mac(struct mg_tcpip_if *ifp, struct mg_addr *rem,
} else
#endif
{
uint32_t rem_ip = rem->ip4;
uint32_t rem_ip = rem->addr.ip4;
if (is_udp && (rem_ip == 0xffffffff || rem_ip == (ifp->ip | ~ifp->mask)))
return (uint8_t *) broadcast; // global or local broadcast
if (ifp->ip != 0 && ((rem_ip & ifp->mask) == (ifp->ip & ifp->mask)))
@@ -981,12 +990,12 @@ static bool rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
c->rem.port = pkt->udp->sport;
#if MG_ENABLE_IPV6
if (c->loc.is_ip6) {
c->rem.ip6[0] = pkt->ip6->src[0], c->rem.ip6[1] = pkt->ip6->src[1],
c->rem.is_ip6 = true;
c->rem.addr.ip6[0] = pkt->ip6->src[0],
c->rem.addr.ip6[1] = pkt->ip6->src[1], c->rem.is_ip6 = true;
} else
#endif
{
c->rem.ip4 = pkt->ip->src;
c->rem.addr.ip4 = pkt->ip->src;
}
if ((mac = get_return_mac(ifp, &c->rem, true, pkt)) == NULL)
return false; // safety net for lousy networks
@@ -1025,13 +1034,13 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
}
#if MG_ENABLE_IPV6
if (ip_dst->is_ip6) {
ip6 = tx_ip6(ifp, mac_dst, 6, ip_src->ip6, ip_dst->ip6,
ip6 = tx_ip6(ifp, mac_dst, 6, ip_src->addr.ip6, ip_dst->addr.ip6,
sizeof(struct tcp) + len);
tcp = (struct tcp *) (ip6 + 1);
} else
#endif
{
ip = tx_ip(ifp, mac_dst, 6, ip_src->ip4, ip_dst->ip4,
ip = tx_ip(ifp, mac_dst, 6, ip_src->addr.ip4, ip_dst->addr.ip4,
sizeof(struct tcp) + len);
tcp = (struct tcp *) (ip + 1);
}
@@ -1054,9 +1063,6 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
cs = csumup(cs, &ip6->src, sizeof(ip6->src));
cs = csumup(cs, &ip6->dst, sizeof(ip6->dst));
cs += (uint32_t) (6 + n);
MG_VERBOSE(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip6, &ip6->src,
mg_ntohs(tcp->sport), mg_print_ip6, &ip6->dst,
mg_ntohs(tcp->dport), tcp->flags, len));
} else
#endif
{
@@ -1065,12 +1071,11 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
cs = csumup(cs, &ip->src, sizeof(ip->src));
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
cs = csumup(cs, pseudo, sizeof(pseudo));
MG_VERBOSE(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip4, &ip->src,
mg_ntohs(tcp->sport), mg_print_ip4, &ip->dst,
mg_ntohs(tcp->dport), tcp->flags, len));
}
tcp->csum = csumfin(cs);
}
MG_VERBOSE(("TCP %M -> %M fl %x len %u", mg_print_ip_port, ip_src,
mg_print_ip_port, ip_dst, tcp->flags, len));
return ether_output(ifp, PDIFF(ifp->tx.buf, tcp + 1) + len);
}
@@ -1083,11 +1088,11 @@ static size_t tx_tcp_ctrlresp(struct mg_tcpip_if *ifp, struct pkt *pkt,
memset(&ips, 0, sizeof(ips));
memset(&ipd, 0, sizeof(ipd));
if (pkt->ip != NULL) {
ips.ip4 = pkt->ip->dst;
ipd.ip4 = pkt->ip->src;
ips.addr.ip4 = pkt->ip->dst;
ipd.addr.ip4 = pkt->ip->src;
} else {
ips.ip6[0] = pkt->ip6->dst[0], ips.ip6[1] = pkt->ip6->dst[1];
ipd.ip6[0] = pkt->ip6->src[0], ipd.ip6[1] = pkt->ip6->src[1];
ips.addr.ip6[0] = pkt->ip6->dst[0], ips.addr.ip6[1] = pkt->ip6->dst[1];
ipd.addr.ip6[0] = pkt->ip6->src[0], ipd.addr.ip6[1] = pkt->ip6->src[1];
ips.is_ip6 = true;
ipd.is_ip6 = true;
}
@@ -1117,16 +1122,16 @@ static struct mg_connection *accept_conn(struct mg_connection *lsn,
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
#if MG_ENABLE_IPV6
if (lsn->loc.is_ip6) {
c->rem.ip6[0] = pkt->ip6->src[0], c->rem.ip6[1] = pkt->ip6->src[1],
c->rem.is_ip6 = true;
c->loc.ip6[0] = c->mgr->ifp->ip6[0], c->loc.ip6[1] = c->mgr->ifp->ip6[1],
c->loc.is_ip6 = true;
c->rem.addr.ip6[0] = pkt->ip6->src[0],
c->rem.addr.ip6[1] = pkt->ip6->src[1], c->rem.is_ip6 = true;
c->loc.addr.ip6[0] = c->mgr->ifp->ip6[0],
c->loc.addr.ip6[1] = c->mgr->ifp->ip6[1], c->loc.is_ip6 = true;
// TODO(): compare lsn to link-local, or rem as link-local: use ll instead
} else
#endif
{
c->rem.ip4 = pkt->ip->src;
c->loc.ip4 = c->mgr->ifp->ip;
c->rem.addr.ip4 = pkt->ip->src;
c->loc.addr.ip4 = c->mgr->ifp->ip;
}
c->rem.port = pkt->tcp->sport;
c->loc.port = lsn->loc.port;
@@ -1188,12 +1193,13 @@ static bool udp_send(struct mg_connection *c, const void *buf, size_t len) {
memset(&ips, 0, sizeof(ips));
#if MG_ENABLE_IPV6
if (c->loc.is_ip6) {
ips.ip6[0] = ifp->ip6[0], ips.ip6[1] = ifp->ip6[1], ips.is_ip6 = true;
ips.addr.ip6[0] = ifp->ip6[0], ips.addr.ip6[1] = ifp->ip6[1],
ips.is_ip6 = true;
// TODO(): detect link-local (c->rem) and use it
} else
#endif
{
ips.ip4 = ifp->ip;
ips.addr.ip4 = ifp->ip;
}
ips.port = c->loc.port;
return tx_udp(ifp, s->mac, &ips, &c->rem, buf, len);
@@ -1931,12 +1937,12 @@ void mg_connect_resolved(struct mg_connection *c) {
c->loc.port = mg_htons(ifp->eport++);
#if MG_ENABLE_IPV6
if (c->rem.is_ip6) {
c->loc.ip6[0] = ifp->ip6[0], c->loc.ip6[1] = ifp->ip6[1],
c->loc.addr.ip6[0] = ifp->ip6[0], c->loc.addr.ip6[1] = ifp->ip6[1],
c->loc.is_ip6 = true;
} else
#endif
{
c->loc.ip4 = ifp->ip;
c->loc.addr.ip4 = ifp->ip;
}
MG_DEBUG(("%lu %M -> %M", c->id, mg_print_ip_port, &c->loc, mg_print_ip_port,
&c->rem));
@@ -1945,21 +1951,21 @@ void mg_connect_resolved(struct mg_connection *c) {
#if MG_ENABLE_IPV6
if (c->rem.is_ip6) {
if (c->is_udp &&
MG_IP6MATCH(c->rem.ip6, ip6_allnodes.u)) { // local broadcast
MG_IP6MATCH(c->rem.addr.ip6, ip6_allnodes.u)) { // local broadcast
struct connstate *s = (struct connstate *) (c + 1);
memcpy(s->mac, ip6mac_allnodes, sizeof(s->mac));
mac_resolved(c);
} else if (c->rem.ip6[0] == ifp->ip6[0] && // TODO(): HANDLE PREFIX ***
!MG_IP6MATCH(c->rem.ip6,
} else if (c->rem.addr.ip6[0] == ifp->ip6[0] && // TODO(): HANDLE PREFIX ***
!MG_IP6MATCH(c->rem.addr.ip6,
ifp->gw6)) { // skip if gw (onstate6change -> NS)
// If we're in the same LAN, fire a Neighbor Solicitation
MG_DEBUG(("%lu NS lookup...", c->id));
tx_ndp_ns(ifp, c->rem.ip6, ifp->mac);
tx_ndp_ns(ifp, c->rem.addr.ip6, ifp->mac);
settmout(c, MIP_TTYPE_ARP);
c->is_arplooking = 1;
} else if (c->is_udp && *((uint8_t *) c->rem.ip6) == 0xFF) { // multicast
} else if (c->is_udp && *((uint8_t *) c->rem.addr.ip6) == 0xFF) { // multicast
struct connstate *s = (struct connstate *) (c + 1);
ip6_mcastmac(s->mac, c->rem.ip6);
ip6_mcastmac(s->mac, c->rem.addr.ip6);
mac_resolved(c);
} else if (ifp->gw6_ready) {
struct connstate *s = (struct connstate *) (c + 1);
@@ -1971,7 +1977,7 @@ void mg_connect_resolved(struct mg_connection *c) {
} else
#endif
{
uint32_t rem_ip = c->rem.ip4;
uint32_t rem_ip = c->rem.addr.ip4;
if (c->is_udp &&
(rem_ip == 0xffffffff || rem_ip == (ifp->ip | ~ifp->mask))) {
struct connstate *s = (struct connstate *) (c + 1);
+8 -5
View File
@@ -38,8 +38,10 @@ void mg_pfn_iobuf(char ch, void *param) {
}
size_t mg_vsnprintf(char *buf, size_t len, const char *fmt, va_list *ap) {
struct mg_iobuf io = {(uint8_t *) buf, len, 0, 0};
size_t n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap);
struct mg_iobuf io = {0, 0, 0, 0};
size_t n;
io.buf = (uint8_t *) buf, io.size = len;
n = mg_vxprintf(mg_putchar_iobuf_static, &io, fmt, ap);
if (n < len) buf[n] = '\0';
return n;
}
@@ -96,8 +98,8 @@ size_t mg_print_ip6(void (*out)(char, void *), void *arg, va_list *ap) {
size_t mg_print_ip(void (*out)(char, void *), void *arg, va_list *ap) {
struct mg_addr *addr = va_arg(*ap, struct mg_addr *);
if (addr->is_ip6) return print_ip6(out, arg, (uint16_t *) addr->ip);
return print_ip4(out, arg, (uint8_t *) &addr->ip);
if (addr->is_ip6) return print_ip6(out, arg, (uint16_t *) addr->addr.ip);
return print_ip4(out, arg, (uint8_t *) &addr->addr.ip);
}
size_t mg_print_ip_port(void (*out)(char, void *), void *arg, va_list *ap) {
@@ -145,7 +147,8 @@ static size_t bcpy(void (*out)(char, void *), void *arg, uint8_t *buf,
for (i = 0; i < len; i += 3) {
uint8_t c1 = buf[i], c2 = i + 1 < len ? buf[i + 1] : 0,
c3 = i + 2 < len ? buf[i + 2] : 0;
char tmp[4] = {t[c1 >> 2], t[(c1 & 3) << 4 | (c2 >> 4)], '=', '='};
char tmp[4] = {0, 0, '=', '='};
tmp[0] = t[c1 >> 2], tmp[1] = t[(c1 & 3) << 4 | (c2 >> 4)];
if (i + 1 < len) tmp[2] = t[(c2 & 15) << 2 | (c3 >> 6)];
if (i + 2 < len) tmp[3] = t[c3 & 63];
for (j = 0; j < sizeof(tmp) && tmp[j] != '\0'; j++) out(tmp[j], arg);
+43 -1
View File
@@ -180,6 +180,35 @@ void mg_hmac_sha256(uint8_t dst[32], uint8_t *key, size_t keysz, uint8_t *data,
#define sig164(x) (rotr64(x, 19) ^ rotr64(x, 61) ^ ((x) >> 6))
static const uint64_t mg_sha256_k2[80] = {
#if defined(__DCC__)
0x428a2f98d728ae22ull, 0x7137449123ef65cdull, 0xb5c0fbcfec4d3b2full,
0xe9b5dba58189dbbcull, 0x3956c25bf348b538ull, 0x59f111f1b605d019ull,
0x923f82a4af194f9bull, 0xab1c5ed5da6d8118ull, 0xd807aa98a3030242ull,
0x12835b0145706fbeull, 0x243185be4ee4b28cull, 0x550c7dc3d5ffb4e2ull,
0x72be5d74f27b896full, 0x80deb1fe3b1696b1ull, 0x9bdc06a725c71235ull,
0xc19bf174cf692694ull, 0xe49b69c19ef14ad2ull, 0xefbe4786384f25e3ull,
0x0fc19dc68b8cd5b5ull, 0x240ca1cc77ac9c65ull, 0x2de92c6f592b0275ull,
0x4a7484aa6ea6e483ull, 0x5cb0a9dcbd41fbd4ull, 0x76f988da831153b5ull,
0x983e5152ee66dfabull, 0xa831c66d2db43210ull, 0xb00327c898fb213full,
0xbf597fc7beef0ee4ull, 0xc6e00bf33da88fc2ull, 0xd5a79147930aa725ull,
0x06ca6351e003826full, 0x142929670a0e6e70ull, 0x27b70a8546d22ffcull,
0x2e1b21385c26c926ull, 0x4d2c6dfc5ac42aedull, 0x53380d139d95b3dfull,
0x650a73548baf63deull, 0x766a0abb3c77b2a8ull, 0x81c2c92e47edaee6ull,
0x92722c851482353bull, 0xa2bfe8a14cf10364ull, 0xa81a664bbc423001ull,
0xc24b8b70d0f89791ull, 0xc76c51a30654be30ull, 0xd192e819d6ef5218ull,
0xd69906245565a910ull, 0xf40e35855771202aull, 0x106aa07032bbd1b8ull,
0x19a4c116b8d2d0c8ull, 0x1e376c085141ab53ull, 0x2748774cdf8eeb99ull,
0x34b0bcb5e19b48a8ull, 0x391c0cb3c5c95a63ull, 0x4ed8aa4ae3418acbull,
0x5b9cca4f7763e373ull, 0x682e6ff3d6b2b8a3ull, 0x748f82ee5defb2fcull,
0x78a5636f43172f60ull, 0x84c87814a1f0ab72ull, 0x8cc702081a6439ecull,
0x90befffa23631e28ull, 0xa4506cebde82bde9ull, 0xbef9a3f7b2c67915ull,
0xc67178f2e372532bull, 0xca273eceea26619cull, 0xd186b8c721c0c207ull,
0xeada7dd6cde0eb1eull, 0xf57d4f7fee6ed178ull, 0x06f067aa72176fbaull,
0x0a637dc5a2c898a6ull, 0x113f9804bef90daeull, 0x1b710b35131c471bull,
0x28db77f523047d84ull, 0x32caab7b40c72493ull, 0x3c9ebe0a15c9bebcull,
0x431d67c49c100d4cull, 0x4cc5d4becb3e42b6ull, 0x597f299cfc657e2aull,
0x5fcb6fab3ad6faecull, 0x6c44198c4a475817ull
#else
0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
@@ -206,7 +235,9 @@ static const uint64_t mg_sha256_k2[80] = {
0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
0x5fcb6fab3ad6faec, 0x6c44198c4a475817};
0x5fcb6fab3ad6faec, 0x6c44198c4a475817
#endif
};
static void mg_sha384_transform(mg_sha384_ctx *ctx, const uint8_t data[]) {
uint64_t m[80];
@@ -257,6 +288,16 @@ void mg_sha384_init(mg_sha384_ctx *ctx) {
ctx->datalen = 0;
ctx->bitlen[0] = 0;
ctx->bitlen[1] = 0;
#if defined(__DCC__)
ctx->state[0] = 0xcbbb9d5dc1059ed8ull;
ctx->state[1] = 0x629a292a367cd507ull;
ctx->state[2] = 0x9159015a3070dd17ull;
ctx->state[3] = 0x152fecd8f70e5939ull;
ctx->state[4] = 0x67332667ffc00b31ull;
ctx->state[5] = 0x8eb44a8768581511ull;
ctx->state[6] = 0xdb0c2e0d64f98fa7ull;
ctx->state[7] = 0x47b5481dbefa4fa4ull;
#else
ctx->state[0] = 0xcbbb9d5dc1059ed8;
ctx->state[1] = 0x629a292a367cd507;
ctx->state[2] = 0x9159015a3070dd17;
@@ -265,6 +306,7 @@ void mg_sha384_init(mg_sha384_ctx *ctx) {
ctx->state[5] = 0x8eb44a8768581511;
ctx->state[6] = 0xdb0c2e0d64f98fa7;
ctx->state[7] = 0x47b5481dbefa4fa4;
#endif
}
void mg_sha384_update(mg_sha384_ctx *ctx, const uint8_t *data, size_t len) {
+4 -4
View File
@@ -57,13 +57,13 @@ static socklen_t tousa(struct mg_addr *a, union usa *usa) {
memset(usa, 0, sizeof(*usa));
usa->sin.sin_family = AF_INET;
usa->sin.sin_port = a->port;
memcpy(&usa->sin.sin_addr, a->ip, sizeof(uint32_t));
memcpy(&usa->sin.sin_addr, a->addr.ip, sizeof(uint32_t));
#if MG_ENABLE_IPV6
if (a->is_ip6) {
usa->sin.sin_family = AF_INET6;
usa->sin6.sin6_port = a->port;
usa->sin6.sin6_scope_id = a->scope_id;
memcpy(&usa->sin6.sin6_addr, a->ip, sizeof(a->ip));
memcpy(&usa->sin6.sin6_addr, a->addr.ip, sizeof(a->addr.ip));
len = sizeof(usa->sin6);
}
#endif
@@ -73,10 +73,10 @@ static socklen_t tousa(struct mg_addr *a, union usa *usa) {
static void tomgaddr(union usa *usa, struct mg_addr *a, bool is_ip6) {
a->is_ip6 = is_ip6;
a->port = usa->sin.sin_port;
memcpy(&a->ip, &usa->sin.sin_addr, sizeof(uint32_t));
memcpy(&a->addr.ip, &usa->sin.sin_addr, sizeof(uint32_t));
#if MG_ENABLE_IPV6
if (is_ip6) {
memcpy(a->ip, &usa->sin6.sin6_addr, sizeof(a->ip));
memcpy(a->addr.ip, &usa->sin6.sin6_addr, sizeof(a->addr.ip));
a->port = usa->sin6.sin6_port;
a->scope_id = (uint8_t) usa->sin6.sin6_scope_id;
}
+4 -2
View File
@@ -2,12 +2,14 @@
#include "util.h"
struct mg_str mg_str_s(const char *s) {
struct mg_str str = {(char *) s, s == NULL ? 0 : strlen(s)};
struct mg_str str;
str.buf = (char *) s, str.len = (s == NULL) ? 0 : strlen(s);
return str;
}
struct mg_str mg_str_n(const char *s, size_t n) {
struct mg_str str = {(char *) s, n};
struct mg_str str;
str.buf = (char *) s, str.len = n;
return str;
}
+1 -1
View File
@@ -1215,7 +1215,7 @@ static int mg_tls_verify_cert_san(const uint8_t *der, size_t dersz,
while (mg_der_next(&field, &name) > 0) {
if (name.type == 0x87 && name.len == 4) { // this is an IPv4 address
MG_DEBUG(("Found SAN, IP: %M", mg_print_ip4, name.value));
if (!server_ip->is_ip6 && *((uint32_t *) name.value) == server_ip->ip4)
if (!server_ip->is_ip6 && *((uint32_t *) name.value) == server_ip->addr.ip4)
return 1; // and matches the one we're connected to
} else { // this is a text SAN
MG_DEBUG(("Found SAN, (%u): %.*s", name.type, name.len, name.value));
+2 -3
View File
@@ -120,7 +120,7 @@ int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip) {
if (remote_ip->is_ip6) {
return -1; // TODO(): handle IPv6 ACL and addresses
} else { // IPv4
memcpy((void *) &remote_ip4, remote_ip->ip, sizeof(remote_ip4));
memcpy((void *) &remote_ip4, remote_ip->addr.ip, sizeof(remote_ip4));
while (mg_span(acl, &entry, &acl, ',')) {
uint32_t net, mask;
if (entry.buf[0] != '+' && entry.buf[0] != '-') return -1;
@@ -134,7 +134,7 @@ int mg_check_ip_acl(struct mg_str acl, struct mg_addr *remote_ip) {
bool mg_path_is_sane(const struct mg_str path) {
const char *s = path.buf;
size_t n = path.len;
if (path.buf[0] == '~') return false; // Starts with ~
if (path.buf[0] == '~') return false; // Starts with ~
if (path.buf[0] == '.' && path.buf[1] == '.') return false; // Starts with ..
for (; s[0] != '\0' && n > 0; s++, n--) {
if ((s[0] == '/' || s[0] == '\\') && n >= 2) { // Subdir?
@@ -213,7 +213,6 @@ void mg_delayms(unsigned int ms) {
while (mg_millis() < to) (void) 0;
}
#if MG_ENABLE_CUSTOM_CALLOC
#else
void *mg_calloc(size_t count, size_t size) {
+7 -3
View File
@@ -173,9 +173,13 @@ static void mg_ws_cb(struct mg_connection *c, int ev, void *ev_data) {
while (ws_process(c->recv.buf + ofs, c->recv.len - ofs, &msg) > 0) {
char *s = (char *) c->recv.buf + ofs + msg.header_len;
struct mg_ws_message m = {{s, msg.data_len}, msg.flags};
size_t len = msg.header_len + msg.data_len;
uint8_t final = msg.flags & 128, op = msg.flags & 15;
struct mg_ws_message m;
size_t len;
uint8_t final, op;
m.data.buf = s, m.data.len = msg.data_len, m.flags = msg.flags;
len = msg.header_len + msg.data_len;
final = msg.flags & 128;
op = msg.flags & 15;
// MG_VERBOSE ("fin %d op %d len %d [%.*s]", final, op,
// (int) m.data.len, (int) m.data.len, m.data.buf));
switch (op) {
+19 -19
View File
@@ -1496,7 +1496,7 @@ static void f3(struct mg_connection *c, int ev, void *ev_data) {
// MG_INFO(("%d", ev));
if (ev == MG_EV_CONNECT) {
// c->is_hexdumping = 1;
ASSERT((c->loc.ip[0] != 0)); // Make sure that c->loc address is populated
ASSERT((c->loc.addr.ip[0] != 0)); // Make sure that c->loc address is populated
mg_printf(c, "GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n",
c->rem.is_ip6 ? "" : "/robots.txt",
c->rem.is_ip6 ? "ipv6.google.com" : "cesanta.com");
@@ -2478,7 +2478,7 @@ static void test_str(void) {
char buf[100];
struct mg_addr a;
uint32_t addr = mg_htonl(0x2000001);
memcpy(a.ip, &addr, sizeof(uint32_t));
memcpy(a.addr.ip, &addr, sizeof(uint32_t));
a.port = mg_htons(3);
a.is_ip6 = false;
@@ -2488,8 +2488,8 @@ static void test_str(void) {
11);
ASSERT(strcmp(buf, "2.0.0.1:3 7") == 0);
memset(a.ip, 0, sizeof(a.ip));
a.ip[0] = 1, a.ip[1] = 100, a.ip[2] = 33;
memset(a.addr.ip, 0, sizeof(a.addr.ip));
a.addr.ip[0] = 1, a.addr.ip[1] = 100, a.addr.ip[2] = 33;
a.is_ip6 = true;
ASSERT(mg_snprintf(buf, sizeof(buf), "%M %d", mg_print_ip, &a, 7) == 24);
ASSERT(strcmp(buf, "[164:2100:0:0:0:0:0:0] 7") == 0);
@@ -2636,7 +2636,7 @@ static void test_util(void) {
ASSERT(mg_aton(mg_str("0.0.0.-1"), &a) == false);
ASSERT(mg_aton(mg_str("127.0.0.1"), &a) == true);
ASSERT(a.is_ip6 == false);
memcpy(&ipv4, a.ip, sizeof(ipv4));
memcpy(&ipv4, &a.addr.ip4, sizeof(ipv4));
ASSERT(ipv4 == mg_htonl(0x7f000001));
ASSERT(mg_ntohl(ipv4) == 0x7f000001);
MG_STORE_BE32(&ipv4, 0x5678abcd);
@@ -2667,48 +2667,48 @@ static void test_util(void) {
((uint8_t *) &ipv3)[6] == 0x9e && ((uint8_t *) &ipv3)[7] == 0xf0);
ASSERT(MG_LOAD_BE64(&ipv3) == 0x5678abcd12349ef0);
memset(a.ip, 0xa5, sizeof(a.ip));
memset(a.addr.ip, 0xa5, sizeof(a.addr.ip)), a.is_ip6 = false;
ASSERT(mg_aton(mg_str("1:2:3:4:5:6:7:8"), &a) == true);
ASSERT(a.is_ip6 == true);
e = "\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08";
ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0);
ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0);
memset(a.ip, 0xa5, sizeof(a.ip));
memset(a.addr.ip, 0xa5, sizeof(a.addr.ip)), a.is_ip6 = false;
ASSERT(mg_aton(mg_str("1:2::3"), &a) == true);
ASSERT(a.is_ip6 == true);
e = "\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03";
ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0);
ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0);
memset(a.ip, 0xaa, sizeof(a.ip));
memset(a.addr.ip, 0xaa, sizeof(a.addr.ip)), a.is_ip6 = false;
ASSERT(mg_aton(mg_str("1::1"), &a) == true);
ASSERT(a.is_ip6 == true);
e = "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01";
ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0);
ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0);
memset(a.ip, 0xaa, sizeof(a.ip));
memset(a.addr.ip, 0xaa, sizeof(a.addr.ip)), a.is_ip6 = false;
ASSERT(mg_aton(mg_str("::fFff:1.2.3.4"), &a) == true);
ASSERT(a.is_ip6 == true);
e = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x01\x02\x03\x04";
ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0);
ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0);
memset(a.ip, 0xaa, sizeof(a.ip));
memset(a.addr.ip, 0xaa, sizeof(a.addr.ip)), a.is_ip6 = false;
ASSERT(mg_aton(mg_str("::1"), &a) == true);
ASSERT(a.is_ip6 == true);
ASSERT(a.scope_id == 0);
e = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01";
ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0);
ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0);
memset(a.ip, 0xaa, sizeof(a.ip));
memset(a.addr.ip, 0xaa, sizeof(a.addr.ip)), a.is_ip6 = false;
ASSERT(mg_aton(mg_str("1::"), &a) == true);
ASSERT(a.is_ip6 == true);
e = "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0);
ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0);
memset(a.ip, 0xaa, sizeof(a.ip));
memset(a.addr.ip, 0xaa, sizeof(a.addr.ip)), a.is_ip6 = false;
ASSERT(mg_aton(mg_str("2001:4860:4860::8888"), &a) == true);
ASSERT(a.is_ip6 == true);
e = "\x20\x01\x48\x60\x48\x60\x00\x00\x00\x00\x00\x00\x00\x00\x88\x88";
ASSERT(memcmp(a.ip, e, sizeof(a.ip)) == 0);
ASSERT(memcmp(&a.addr.ip6, e, sizeof(a.addr.ip6)) == 0);
ASSERT(mg_url_decode("a=%", 3, buf, sizeof(buf), 0) < 0);
ASSERT(mg_url_decode("&&&a=%", 6, buf, sizeof(buf), 0) < 0);