diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 8f500b6c..68386ad1 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -54,6 +54,18 @@ jobs: - uses: actions/checkout@v4 with: { fetch-depth: 2 } - run: if [ "${{ matrix.target }}" == "mip_tap_test" ]; then ./test/setup_ga_network.sh ; fi && sudo apt -y update ; sudo apt -y install libmbedtls-dev libwolfssl-dev && make -C test ${{ matrix.target }} IPV6=0 + mip89: + runs-on: ubuntu-latest + strategy: + fail-fast: false + max-parallel: 1 # no parallel runs, to minimize MQTT errors + matrix: + target: [mip_vc98] + name: mip89 ${{ matrix.target }} + steps: + - uses: actions/checkout@v4 + with: { fetch-depth: 2 } + - run: make -C test ${{ matrix.target }} s390: runs-on: ubuntu-latest strategy: diff --git a/mongoose.c b/mongoose.c index 9ef71c48..e889ced8 100644 --- a/mongoose.c +++ b/mongoose.c @@ -4327,7 +4327,7 @@ static uint32_t csumup(uint32_t sum, const void *buf, size_t len) { static uint16_t csumfin(uint32_t sum) { while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16); - return mg_htons(~sum & 0xffff); + return mg_htons((uint16_t) (~sum & 0xffff)); } static uint16_t ipcsum(const void *buf, size_t len) { @@ -4414,12 +4414,13 @@ static bool tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src, tx_ip(ifp, mac_dst, 17, ip_src, ip_dst, len + sizeof(struct udp)); struct udp *udp = (struct udp *) (ip + 1); size_t eth_len; + uint32_t cs; // MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len)); udp->sport = sport; udp->dport = dport; udp->len = mg_htons((uint16_t) (sizeof(*udp) + len)); udp->csum = 0; - uint32_t cs = csumup(0, udp, sizeof(*udp)); + cs = csumup(0, udp, sizeof(*udp)); cs = csumup(cs, buf, len); cs = csumup(cs, &ip->src, sizeof(ip->src)); cs = csumup(cs, &ip->dst, sizeof(ip->dst)); @@ -4503,7 +4504,8 @@ static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt, break; if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport) break; if (!c->is_udp && pkt->tcp && c->loc.port == pkt->tcp->dport && - lsn == c->is_listening && (lsn || c->rem.port == pkt->tcp->sport)) + lsn == (bool) c->is_listening && + (lsn || c->rem.port == pkt->tcp->sport)) break; } return c; @@ -4558,10 +4560,12 @@ static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) { if (pkt->icmp->type == 8 && pkt->ip != NULL && pkt->ip->dst == ifp->ip) { size_t hlen = sizeof(struct eth) + sizeof(struct ip) + sizeof(struct icmp); size_t space = ifp->tx.len - hlen, plen = pkt->pay.len; + struct ip *ip; + struct icmp *icmp; if (plen > space) plen = space; - struct ip *ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src, - sizeof(struct icmp) + plen); - struct icmp *icmp = (struct icmp *) (ip + 1); + ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src, + sizeof(*icmp) + plen); + icmp = (struct icmp *) (ip + 1); memset(icmp, 0, sizeof(*icmp)); // Set csum to 0 memcpy(icmp + 1, pkt->pay.buf, plen); // Copy RX payload to TX icmp->csum = ipcsum(icmp, sizeof(*icmp) + plen); @@ -4608,13 +4612,13 @@ static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) { ifp->state = MG_TCPIP_STATE_REQ; // REQUESTING state } else if (msgtype == 5) { // DHCPACK if (ifp->state == MG_TCPIP_STATE_REQ && ip && gw && lease) { // got an IP + uint64_t rand; ifp->lease_expire = ifp->now + lease * 1000; MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000)); // assume DHCP server = router until ARP resolves memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac)); ifp->ip = ip, ifp->gw = gw, ifp->mask = mask; ifp->state = MG_TCPIP_STATE_IP; // BOUND state - uint64_t rand; mg_random(&rand, sizeof(rand)); srand((unsigned int) (rand + mg_millis())); if (ifp->enable_req_dns && dns != 0) @@ -4633,9 +4637,9 @@ static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) { static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) { uint8_t op = 0, *p = pkt->dhcp->options, *end = (uint8_t *) &pkt->raw.buf[pkt->raw.len]; - if (end < (uint8_t *) (pkt->dhcp + 1)) return; // struct dhcp *req = pkt->dhcp; struct dhcp res = {2, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}}; + if (end < (uint8_t *) (pkt->dhcp + 1)) return; res.yiaddr = ifp->ip; ((uint8_t *) (&res.yiaddr))[3]++; // Offer our IP + 1 while (p + 1 < end && p[0] != 255) { // Parse options @@ -4674,9 +4678,9 @@ static void rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) { if (c == NULL) { // No UDP listener on this port. Should send ICMP, but keep silent. } else { + struct connstate *s = (struct connstate *) (c + 1); c->rem.port = pkt->udp->sport; memcpy(c->rem.ip, &pkt->ip->src, sizeof(uint32_t)); - struct connstate *s = (struct connstate *) (c + 1); memcpy(s->mac, pkt->eth->src, sizeof(s->mac)); if (c->recv.len >= MG_MAX_RECV_SIZE) { mg_error(c, "max_recv_buf_size reached"); @@ -4697,9 +4701,9 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip, struct ip *ip; struct tcp *tcp; uint16_t opts[4 / 2]; - if (flags & TH_SYN) { // Send MSS, RFC-9293 3.7.1 - opts[0] = mg_htons(0x0204); // RFC-9293 3.2 - opts[1] = mg_htons(ifp->mtu - 40); // RFC-6691 + if (flags & TH_SYN) { // Send MSS, RFC-9293 3.7.1 + opts[0] = mg_htons(0x0204); // RFC-9293 3.2 + opts[1] = mg_htons((uint16_t) (ifp->mtu - 40)); // RFC-6691 buf = opts; len = sizeof(opts); } @@ -4715,15 +4719,16 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip, tcp->win = mg_htons(MIP_TCP_WIN); tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4); if (flags & TH_SYN) tcp->off += (uint8_t) (sizeof(opts) / 4 << 4); - - uint32_t cs = 0; - uint16_t n = (uint16_t) (sizeof(*tcp) + len); - uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)}; - cs = csumup(cs, tcp, n); - cs = csumup(cs, &ip->src, sizeof(ip->src)); - cs = csumup(cs, &ip->dst, sizeof(ip->dst)); - cs = csumup(cs, pseudo, sizeof(pseudo)); - tcp->csum = csumfin(cs); + { + uint32_t cs = 0; + uint16_t n = (uint16_t) (sizeof(*tcp) + len); + uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)}; + cs = csumup(cs, tcp, n); + cs = csumup(cs, &ip->src, sizeof(ip->src)); + cs = csumup(cs, &ip->dst, sizeof(ip->dst)); + cs = csumup(cs, pseudo, sizeof(pseudo)); + tcp->csum = csumfin(cs); + } 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)); @@ -4743,11 +4748,12 @@ static size_t tx_tcp_pkt(struct mg_tcpip_if *ifp, struct pkt *pkt, static struct mg_connection *accept_conn(struct mg_connection *lsn, struct pkt *pkt) { struct mg_connection *c = mg_alloc_conn(lsn->mgr); + struct connstate *s; if (c == NULL) { MG_ERROR(("OOM")); return NULL; } - struct connstate *s = (struct connstate *) (c + 1); + s = (struct connstate *) (c + 1); s->dmss = 536; // assume default, RFC-9293 3.7.1 s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq); memcpy(s->mac, pkt->eth->src, sizeof(s->mac)); @@ -5005,10 +5011,10 @@ static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) { static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) { 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); if (c) mg_error(c, "Received fragmented packet"); + if (pkt->ip->proto == 17) pkt->udp = (struct udp *) (pkt->ip + 1); + if (pkt->ip->proto == 6) pkt->tcp = (struct tcp *) (pkt->ip + 1); } else if (pkt->ip->proto == 1) { pkt->icmp = (struct icmp *) (pkt->ip + 1); if (pkt->pay.len < sizeof(*pkt->icmp)) return; @@ -5033,11 +5039,12 @@ static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) { rx_udp(ifp, pkt); } } else if (pkt->ip->proto == 6) { + uint16_t iplen, off; pkt->tcp = (struct tcp *) (pkt->ip + 1); if (pkt->pay.len < sizeof(*pkt->tcp)) return; mkpay(pkt, pkt->tcp + 1); - uint16_t iplen = mg_ntohs(pkt->ip->len); - uint16_t off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U)); + iplen = mg_ntohs(pkt->ip->len); + off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U)); if (iplen >= off) pkt->pay.len = (size_t) (iplen - off); MG_VERBOSE(("TCP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src, mg_ntohs(pkt->tcp->sport), mg_print_ip4, &pkt->ip->dst, @@ -5075,8 +5082,9 @@ static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) { memcmp(pkt.eth->dst, broadcast, sizeof(pkt.eth->dst)) != 0) return; if (ifp->enable_crc32_check && len > 4) { + uint32_t crc; len -= 4; // TODO(scaprile): check on bigendian - uint32_t crc = mg_crc32(0, (const char *) buf, len); + crc = mg_crc32(0, (const char *) buf, len); if (memcmp((void *) ((size_t) buf + len), &crc, sizeof(crc))) return; } if (pkt.eth->type == mg_htons(0x806)) { @@ -5185,10 +5193,10 @@ 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; struct connstate *s = (struct connstate *) (c + 1); uint32_t rem_ip; + if ((c->is_udp && !c->is_arplooking) || c->is_listening || c->is_resolving) + continue; memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); if (ifp->now > s->timer) { if (s->ttype == MIP_TTYPE_ARP) { @@ -5386,10 +5394,10 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) { if (mgr->ifp == NULL || mgr->ifp->driver == NULL) return; mg_tcpip_poll(mgr->ifp, now); for (c = mgr->conns; c != NULL; c = tmp) { - tmp = c->next; struct connstate *s = (struct connstate *) (c + 1); bool is_tls = c->is_tls && !c->is_resolving && !c->is_arplooking && !c->is_listening && !c->is_connecting; + tmp = c->next; mg_call(c, MG_EV_POLL, &now); MG_VERBOSE(("%lu .. %c%c%c%c%c %lu %lu", c->id, c->is_tls ? 'T' : 't', c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h', @@ -22062,8 +22070,8 @@ struct mg_tcpip_driver mg_tcpip_driver_imxrt = {mg_tcpip_driver_imxrt_init, #endif -enum { // ID1 ID2 - MG_PHY_KSZ8x = 0x22, // 0022 1561 - KSZ8081RNB +enum { // ID1 ID2 + MG_PHY_KSZ8x = 0x22, // 0022 1561 - KSZ8081RNB MG_PHY_DP83x = 0x2000, MG_PHY_DP83867 = 0xa231, // 2000 a231 - TI DP83867I MG_PHY_DP83825 = 0xa140, // 2000 a140 - TI DP83825I @@ -22071,7 +22079,7 @@ enum { // ID1 ID2 MG_PHY_LAN87x = 0x7, // 0007 c0fx - LAN8720 MG_PHY_RTL8201 = 0x1C, // 001c c816 - RTL8201, MG_PHY_ICS1894x = 0x15, - MG_PHY_ICS189432 = 0xf450 // 0015 f450 - ICS1894 + MG_PHY_ICS189432 = 0xf450 // 0015 f450 - ICS1894 }; enum { @@ -22144,11 +22152,13 @@ void mg_phy_init(struct mg_phy *phy, uint8_t phy_addr, uint8_t config) { phy->write_reg(phy_addr, MG_PHY_DP83x_REG_RCSR, MG_BIT(7) | MG_BIT(0)); } else if (id1 == MG_PHY_KSZ8x) { // Disable isolation (override hw, it doesn't make sense at this point) - phy->write_reg( // #2848, some NXP boards set ISO, even though - phy_addr, MG_PHY_REG_BCR, // docs say they don't - phy->read_reg(phy_addr, MG_PHY_REG_BCR) & (uint16_t) ~MG_BIT(10)); - phy->write_reg(phy_addr, MG_PHY_KSZ8x_REG_PC2R, // now do clock stuff - MG_BIT(15) | MG_BIT(8) | MG_BIT(7)); + // - #2848, some NXP boards set ISO, even though docs say they don't + phy->write_reg(phy_addr, MG_PHY_REG_BCR, + (uint16_t) (phy->read_reg(phy_addr, MG_PHY_REG_BCR) & + (uint16_t) ~MG_BIT(10))); + // now do clock stuff + phy->write_reg(phy_addr, MG_PHY_KSZ8x_REG_PC2R, + (uint16_t) (MG_BIT(15) | MG_BIT(8) | MG_BIT(7))); } else if (id1 == MG_PHY_LAN87x) { // nothing to do } else if (id1 == MG_PHY_RTL8201) { diff --git a/src/drivers/phy.c b/src/drivers/phy.c index 506f6cba..60e7d9d8 100644 --- a/src/drivers/phy.c +++ b/src/drivers/phy.c @@ -1,7 +1,7 @@ #include "phy.h" -enum { // ID1 ID2 - MG_PHY_KSZ8x = 0x22, // 0022 1561 - KSZ8081RNB +enum { // ID1 ID2 + MG_PHY_KSZ8x = 0x22, // 0022 1561 - KSZ8081RNB MG_PHY_DP83x = 0x2000, MG_PHY_DP83867 = 0xa231, // 2000 a231 - TI DP83867I MG_PHY_DP83825 = 0xa140, // 2000 a140 - TI DP83825I @@ -9,7 +9,7 @@ enum { // ID1 ID2 MG_PHY_LAN87x = 0x7, // 0007 c0fx - LAN8720 MG_PHY_RTL8201 = 0x1C, // 001c c816 - RTL8201, MG_PHY_ICS1894x = 0x15, - MG_PHY_ICS189432 = 0xf450 // 0015 f450 - ICS1894 + MG_PHY_ICS189432 = 0xf450 // 0015 f450 - ICS1894 }; enum { @@ -82,11 +82,13 @@ void mg_phy_init(struct mg_phy *phy, uint8_t phy_addr, uint8_t config) { phy->write_reg(phy_addr, MG_PHY_DP83x_REG_RCSR, MG_BIT(7) | MG_BIT(0)); } else if (id1 == MG_PHY_KSZ8x) { // Disable isolation (override hw, it doesn't make sense at this point) - phy->write_reg( // #2848, some NXP boards set ISO, even though - phy_addr, MG_PHY_REG_BCR, // docs say they don't - phy->read_reg(phy_addr, MG_PHY_REG_BCR) & (uint16_t) ~MG_BIT(10)); - phy->write_reg(phy_addr, MG_PHY_KSZ8x_REG_PC2R, // now do clock stuff - MG_BIT(15) | MG_BIT(8) | MG_BIT(7)); + // - #2848, some NXP boards set ISO, even though docs say they don't + phy->write_reg(phy_addr, MG_PHY_REG_BCR, + (uint16_t) (phy->read_reg(phy_addr, MG_PHY_REG_BCR) & + (uint16_t) ~MG_BIT(10))); + // now do clock stuff + phy->write_reg(phy_addr, MG_PHY_KSZ8x_REG_PC2R, + (uint16_t) (MG_BIT(15) | MG_BIT(8) | MG_BIT(7))); } else if (id1 == MG_PHY_LAN87x) { // nothing to do } else if (id1 == MG_PHY_RTL8201) { diff --git a/src/net_builtin.c b/src/net_builtin.c index 461a37df..75549078 100644 --- a/src/net_builtin.c +++ b/src/net_builtin.c @@ -161,7 +161,7 @@ static uint32_t csumup(uint32_t sum, const void *buf, size_t len) { static uint16_t csumfin(uint32_t sum) { while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16); - return mg_htons(~sum & 0xffff); + return mg_htons((uint16_t) ((uint16_t) ~sum & 0xffff)); } static uint16_t ipcsum(const void *buf, size_t len) { @@ -248,12 +248,13 @@ static bool tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src, tx_ip(ifp, mac_dst, 17, ip_src, ip_dst, len + sizeof(struct udp)); struct udp *udp = (struct udp *) (ip + 1); size_t eth_len; + uint32_t cs; // MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len)); udp->sport = sport; udp->dport = dport; udp->len = mg_htons((uint16_t) (sizeof(*udp) + len)); udp->csum = 0; - uint32_t cs = csumup(0, udp, sizeof(*udp)); + cs = csumup(0, udp, sizeof(*udp)); cs = csumup(cs, buf, len); cs = csumup(cs, &ip->src, sizeof(ip->src)); cs = csumup(cs, &ip->dst, sizeof(ip->dst)); @@ -337,7 +338,8 @@ static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt, break; if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport) break; if (!c->is_udp && pkt->tcp && c->loc.port == pkt->tcp->dport && - lsn == c->is_listening && (lsn || c->rem.port == pkt->tcp->sport)) + lsn == (bool) c->is_listening && + (lsn || c->rem.port == pkt->tcp->sport)) break; } return c; @@ -392,10 +394,12 @@ static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) { if (pkt->icmp->type == 8 && pkt->ip != NULL && pkt->ip->dst == ifp->ip) { size_t hlen = sizeof(struct eth) + sizeof(struct ip) + sizeof(struct icmp); size_t space = ifp->tx.len - hlen, plen = pkt->pay.len; + struct ip *ip; + struct icmp *icmp; if (plen > space) plen = space; - struct ip *ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src, - sizeof(struct icmp) + plen); - struct icmp *icmp = (struct icmp *) (ip + 1); + ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src, + sizeof(*icmp) + plen); + icmp = (struct icmp *) (ip + 1); memset(icmp, 0, sizeof(*icmp)); // Set csum to 0 memcpy(icmp + 1, pkt->pay.buf, plen); // Copy RX payload to TX icmp->csum = ipcsum(icmp, sizeof(*icmp) + plen); @@ -442,13 +446,13 @@ static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) { ifp->state = MG_TCPIP_STATE_REQ; // REQUESTING state } else if (msgtype == 5) { // DHCPACK if (ifp->state == MG_TCPIP_STATE_REQ && ip && gw && lease) { // got an IP + uint64_t rand; ifp->lease_expire = ifp->now + lease * 1000; MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000)); // assume DHCP server = router until ARP resolves memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac)); ifp->ip = ip, ifp->gw = gw, ifp->mask = mask; ifp->state = MG_TCPIP_STATE_IP; // BOUND state - uint64_t rand; mg_random(&rand, sizeof(rand)); srand((unsigned int) (rand + mg_millis())); if (ifp->enable_req_dns && dns != 0) @@ -467,9 +471,9 @@ static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) { static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) { uint8_t op = 0, *p = pkt->dhcp->options, *end = (uint8_t *) &pkt->raw.buf[pkt->raw.len]; - if (end < (uint8_t *) (pkt->dhcp + 1)) return; // struct dhcp *req = pkt->dhcp; struct dhcp res = {2, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}}; + if (end < (uint8_t *) (pkt->dhcp + 1)) return; res.yiaddr = ifp->ip; ((uint8_t *) (&res.yiaddr))[3]++; // Offer our IP + 1 while (p + 1 < end && p[0] != 255) { // Parse options @@ -508,9 +512,9 @@ static void rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) { if (c == NULL) { // No UDP listener on this port. Should send ICMP, but keep silent. } else { + struct connstate *s = (struct connstate *) (c + 1); c->rem.port = pkt->udp->sport; memcpy(c->rem.ip, &pkt->ip->src, sizeof(uint32_t)); - struct connstate *s = (struct connstate *) (c + 1); memcpy(s->mac, pkt->eth->src, sizeof(s->mac)); if (c->recv.len >= MG_MAX_RECV_SIZE) { mg_error(c, "max_recv_buf_size reached"); @@ -531,9 +535,9 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip, struct ip *ip; struct tcp *tcp; uint16_t opts[4 / 2]; - if (flags & TH_SYN) { // Send MSS, RFC-9293 3.7.1 - opts[0] = mg_htons(0x0204); // RFC-9293 3.2 - opts[1] = mg_htons(ifp->mtu - 40); // RFC-6691 + if (flags & TH_SYN) { // Send MSS, RFC-9293 3.7.1 + opts[0] = mg_htons(0x0204); // RFC-9293 3.2 + opts[1] = mg_htons((uint16_t) (ifp->mtu - 40)); // RFC-6691 buf = opts; len = sizeof(opts); } @@ -549,15 +553,16 @@ static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip, tcp->win = mg_htons(MIP_TCP_WIN); tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4); if (flags & TH_SYN) tcp->off += (uint8_t) (sizeof(opts) / 4 << 4); - - uint32_t cs = 0; - uint16_t n = (uint16_t) (sizeof(*tcp) + len); - uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)}; - cs = csumup(cs, tcp, n); - cs = csumup(cs, &ip->src, sizeof(ip->src)); - cs = csumup(cs, &ip->dst, sizeof(ip->dst)); - cs = csumup(cs, pseudo, sizeof(pseudo)); - tcp->csum = csumfin(cs); + { + uint32_t cs = 0; + uint16_t n = (uint16_t) (sizeof(*tcp) + len); + uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)}; + cs = csumup(cs, tcp, n); + cs = csumup(cs, &ip->src, sizeof(ip->src)); + cs = csumup(cs, &ip->dst, sizeof(ip->dst)); + cs = csumup(cs, pseudo, sizeof(pseudo)); + tcp->csum = csumfin(cs); + } 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)); @@ -577,11 +582,12 @@ static size_t tx_tcp_pkt(struct mg_tcpip_if *ifp, struct pkt *pkt, static struct mg_connection *accept_conn(struct mg_connection *lsn, struct pkt *pkt) { struct mg_connection *c = mg_alloc_conn(lsn->mgr); + struct connstate *s; if (c == NULL) { MG_ERROR(("OOM")); return NULL; } - struct connstate *s = (struct connstate *) (c + 1); + s = (struct connstate *) (c + 1); s->dmss = 536; // assume default, RFC-9293 3.7.1 s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq); memcpy(s->mac, pkt->eth->src, sizeof(s->mac)); @@ -839,10 +845,10 @@ static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) { static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) { 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); if (c) mg_error(c, "Received fragmented packet"); + if (pkt->ip->proto == 17) pkt->udp = (struct udp *) (pkt->ip + 1); + if (pkt->ip->proto == 6) pkt->tcp = (struct tcp *) (pkt->ip + 1); } else if (pkt->ip->proto == 1) { pkt->icmp = (struct icmp *) (pkt->ip + 1); if (pkt->pay.len < sizeof(*pkt->icmp)) return; @@ -867,11 +873,12 @@ static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) { rx_udp(ifp, pkt); } } else if (pkt->ip->proto == 6) { + uint16_t iplen, off; pkt->tcp = (struct tcp *) (pkt->ip + 1); if (pkt->pay.len < sizeof(*pkt->tcp)) return; mkpay(pkt, pkt->tcp + 1); - uint16_t iplen = mg_ntohs(pkt->ip->len); - uint16_t off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U)); + iplen = mg_ntohs(pkt->ip->len); + off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U)); if (iplen >= off) pkt->pay.len = (size_t) (iplen - off); MG_VERBOSE(("TCP %M:%hu -> %M:%hu len %u", mg_print_ip4, &pkt->ip->src, mg_ntohs(pkt->tcp->sport), mg_print_ip4, &pkt->ip->dst, @@ -909,8 +916,9 @@ static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) { memcmp(pkt.eth->dst, broadcast, sizeof(pkt.eth->dst)) != 0) return; if (ifp->enable_crc32_check && len > 4) { + uint32_t crc; len -= 4; // TODO(scaprile): check on bigendian - uint32_t crc = mg_crc32(0, (const char *) buf, len); + crc = mg_crc32(0, (const char *) buf, len); if (memcmp((void *) ((size_t) buf + len), &crc, sizeof(crc))) return; } if (pkt.eth->type == mg_htons(0x806)) { @@ -1019,10 +1027,10 @@ 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; struct connstate *s = (struct connstate *) (c + 1); uint32_t rem_ip; + if ((c->is_udp && !c->is_arplooking) || c->is_listening || c->is_resolving) + continue; memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t)); if (ifp->now > s->timer) { if (s->ttype == MIP_TTYPE_ARP) { @@ -1220,10 +1228,10 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) { if (mgr->ifp == NULL || mgr->ifp->driver == NULL) return; mg_tcpip_poll(mgr->ifp, now); for (c = mgr->conns; c != NULL; c = tmp) { - tmp = c->next; struct connstate *s = (struct connstate *) (c + 1); bool is_tls = c->is_tls && !c->is_resolving && !c->is_arplooking && !c->is_listening && !c->is_connecting; + tmp = c->next; mg_call(c, MG_EV_POLL, &now); MG_VERBOSE(("%lu .. %c%c%c%c%c %lu %lu", c->id, c->is_tls ? 'T' : 't', c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h', diff --git a/test/Makefile b/test/Makefile index eb316cc0..cc4d04db 100644 --- a/test/Makefile +++ b/test/Makefile @@ -91,6 +91,10 @@ mip_tap_test: mip_tap_test.c mongoose.c mongoose.h packed_fs.c Makefile tls_mult $(CC) mip_tap_test.c packed_fs.c $(CFLAGS) $(LDFLAGS) -o $@ ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@ +mip_vc98: mip_test.c mongoose.c mongoose.h packed_fs.c Makefile + $(DOCKER) mdashnet/vc98 wine cl mip_test.c packed_fs.c $(VCFLAGS) $(DEFS) $(TFLAGS) /Fe$@.exe + $(DOCKER) mdashnet/vc98 wine $@.exe + packed_fs.c: Makefile data/ssi.h fuzz.c data/a.txt data/ca.pem certs/ca.crt certs/server.crt certs/server.key $(CC) $(CFLAGS) pack.c -o pack $(RUN) ./pack Makefile data/ssi.h fuzz.c data/a.txt data/range.txt data/ca.pem certs/ca.crt certs/server.crt certs/server.key certs/client.key certs/client.crt > $@ diff --git a/test/mip_test.c b/test/mip_test.c index 8e4904bd..251c1385 100644 --- a/test/mip_test.c +++ b/test/mip_test.c @@ -74,9 +74,9 @@ static void frag_send_fn(struct mg_connection *c, int ev, void *ev_data) { static void test_poll(void) { int count = 0, i; + struct mg_tcpip_if mif; struct mg_mgr mgr; mg_mgr_init(&mgr); - struct mg_tcpip_if mif; memset(&mif, 0, sizeof(mif)); mif.driver = &mg_tcpip_driver_mock; mg_tcpip_init(&mgr, &mif); @@ -295,6 +295,7 @@ static void test_frag_send_path(void) { struct mg_mgr mgr; struct mg_tcpip_driver driver; struct mg_tcpip_if mif; + unsigned int i; mg_mgr_init(&mgr); memset(&mif, 0, sizeof(mif)); @@ -307,7 +308,7 @@ static void test_frag_send_path(void) { mif.mtu = 500; // force ad hoc small MTU to fragment IP mg_http_listen(&mgr, "http://0.0.0.0:0", frag_send_fn, NULL); mgr.conns->pfn = NULL; - for (int i = 0; i < 10; i++) mg_mgr_poll(&mgr, 0); + for (i = 0; i < 10; i++) mg_mgr_poll(&mgr, 0); ASSERT(s_seg_sent == 3); s_driver_data.len = 0; mg_mgr_free(&mgr);