mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-10 16:31:44 +00:00
make TCP/IP C89-friendly
This commit is contained in:
1 parent
52ab6bc499
commit
b3ee71acbe
6 files changed
+115
-78
No files matched your search
@@ -54,6 +54,18 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
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
|
- 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:
|
s390:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
|
|||||||
+48
-38
@@ -4327,7 +4327,7 @@ static uint32_t csumup(uint32_t sum, const void *buf, size_t len) {
|
|||||||
|
|
||||||
static uint16_t csumfin(uint32_t sum) {
|
static uint16_t csumfin(uint32_t sum) {
|
||||||
while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16);
|
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) {
|
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));
|
tx_ip(ifp, mac_dst, 17, ip_src, ip_dst, len + sizeof(struct udp));
|
||||||
struct udp *udp = (struct udp *) (ip + 1);
|
struct udp *udp = (struct udp *) (ip + 1);
|
||||||
size_t eth_len;
|
size_t eth_len;
|
||||||
|
uint32_t cs;
|
||||||
// MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len));
|
// MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len));
|
||||||
udp->sport = sport;
|
udp->sport = sport;
|
||||||
udp->dport = dport;
|
udp->dport = dport;
|
||||||
udp->len = mg_htons((uint16_t) (sizeof(*udp) + len));
|
udp->len = mg_htons((uint16_t) (sizeof(*udp) + len));
|
||||||
udp->csum = 0;
|
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, buf, len);
|
||||||
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
||||||
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
|
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;
|
break;
|
||||||
if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport) 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 &&
|
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;
|
break;
|
||||||
}
|
}
|
||||||
return c;
|
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) {
|
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 hlen = sizeof(struct eth) + sizeof(struct ip) + sizeof(struct icmp);
|
||||||
size_t space = ifp->tx.len - hlen, plen = pkt->pay.len;
|
size_t space = ifp->tx.len - hlen, plen = pkt->pay.len;
|
||||||
|
struct ip *ip;
|
||||||
|
struct icmp *icmp;
|
||||||
if (plen > space) plen = space;
|
if (plen > space) plen = space;
|
||||||
struct ip *ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src,
|
ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src,
|
||||||
sizeof(struct icmp) + plen);
|
sizeof(*icmp) + plen);
|
||||||
struct icmp *icmp = (struct icmp *) (ip + 1);
|
icmp = (struct icmp *) (ip + 1);
|
||||||
memset(icmp, 0, sizeof(*icmp)); // Set csum to 0
|
memset(icmp, 0, sizeof(*icmp)); // Set csum to 0
|
||||||
memcpy(icmp + 1, pkt->pay.buf, plen); // Copy RX payload to TX
|
memcpy(icmp + 1, pkt->pay.buf, plen); // Copy RX payload to TX
|
||||||
icmp->csum = ipcsum(icmp, sizeof(*icmp) + plen);
|
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
|
ifp->state = MG_TCPIP_STATE_REQ; // REQUESTING state
|
||||||
} else if (msgtype == 5) { // DHCPACK
|
} else if (msgtype == 5) { // DHCPACK
|
||||||
if (ifp->state == MG_TCPIP_STATE_REQ && ip && gw && lease) { // got an IP
|
if (ifp->state == MG_TCPIP_STATE_REQ && ip && gw && lease) { // got an IP
|
||||||
|
uint64_t rand;
|
||||||
ifp->lease_expire = ifp->now + lease * 1000;
|
ifp->lease_expire = ifp->now + lease * 1000;
|
||||||
MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000));
|
MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000));
|
||||||
// assume DHCP server = router until ARP resolves
|
// assume DHCP server = router until ARP resolves
|
||||||
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
||||||
ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
|
ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
|
||||||
ifp->state = MG_TCPIP_STATE_IP; // BOUND state
|
ifp->state = MG_TCPIP_STATE_IP; // BOUND state
|
||||||
uint64_t rand;
|
|
||||||
mg_random(&rand, sizeof(rand));
|
mg_random(&rand, sizeof(rand));
|
||||||
srand((unsigned int) (rand + mg_millis()));
|
srand((unsigned int) (rand + mg_millis()));
|
||||||
if (ifp->enable_req_dns && dns != 0)
|
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) {
|
static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||||
uint8_t op = 0, *p = pkt->dhcp->options,
|
uint8_t op = 0, *p = pkt->dhcp->options,
|
||||||
*end = (uint8_t *) &pkt->raw.buf[pkt->raw.len];
|
*end = (uint8_t *) &pkt->raw.buf[pkt->raw.len];
|
||||||
if (end < (uint8_t *) (pkt->dhcp + 1)) return;
|
|
||||||
// struct dhcp *req = pkt->dhcp;
|
// struct dhcp *req = pkt->dhcp;
|
||||||
struct dhcp res = {2, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}};
|
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;
|
res.yiaddr = ifp->ip;
|
||||||
((uint8_t *) (&res.yiaddr))[3]++; // Offer our IP + 1
|
((uint8_t *) (&res.yiaddr))[3]++; // Offer our IP + 1
|
||||||
while (p + 1 < end && p[0] != 255) { // Parse options
|
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) {
|
if (c == NULL) {
|
||||||
// No UDP listener on this port. Should send ICMP, but keep silent.
|
// No UDP listener on this port. Should send ICMP, but keep silent.
|
||||||
} else {
|
} else {
|
||||||
|
struct connstate *s = (struct connstate *) (c + 1);
|
||||||
c->rem.port = pkt->udp->sport;
|
c->rem.port = pkt->udp->sport;
|
||||||
memcpy(c->rem.ip, &pkt->ip->src, sizeof(uint32_t));
|
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));
|
memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
|
||||||
if (c->recv.len >= MG_MAX_RECV_SIZE) {
|
if (c->recv.len >= MG_MAX_RECV_SIZE) {
|
||||||
mg_error(c, "max_recv_buf_size reached");
|
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 ip *ip;
|
||||||
struct tcp *tcp;
|
struct tcp *tcp;
|
||||||
uint16_t opts[4 / 2];
|
uint16_t opts[4 / 2];
|
||||||
if (flags & TH_SYN) { // Send MSS, RFC-9293 3.7.1
|
if (flags & TH_SYN) { // Send MSS, RFC-9293 3.7.1
|
||||||
opts[0] = mg_htons(0x0204); // RFC-9293 3.2
|
opts[0] = mg_htons(0x0204); // RFC-9293 3.2
|
||||||
opts[1] = mg_htons(ifp->mtu - 40); // RFC-6691
|
opts[1] = mg_htons((uint16_t) (ifp->mtu - 40)); // RFC-6691
|
||||||
buf = opts;
|
buf = opts;
|
||||||
len = sizeof(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->win = mg_htons(MIP_TCP_WIN);
|
||||||
tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4);
|
tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4);
|
||||||
if (flags & TH_SYN) tcp->off += (uint8_t) (sizeof(opts) / 4 << 4);
|
if (flags & TH_SYN) tcp->off += (uint8_t) (sizeof(opts) / 4 << 4);
|
||||||
|
{
|
||||||
uint32_t cs = 0;
|
uint32_t cs = 0;
|
||||||
uint16_t n = (uint16_t) (sizeof(*tcp) + len);
|
uint16_t n = (uint16_t) (sizeof(*tcp) + len);
|
||||||
uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)};
|
uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)};
|
||||||
cs = csumup(cs, tcp, n);
|
cs = csumup(cs, tcp, n);
|
||||||
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
||||||
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
|
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
|
||||||
cs = csumup(cs, pseudo, sizeof(pseudo));
|
cs = csumup(cs, pseudo, sizeof(pseudo));
|
||||||
tcp->csum = csumfin(cs);
|
tcp->csum = csumfin(cs);
|
||||||
|
}
|
||||||
MG_VERBOSE(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip4, &ip->src,
|
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->sport), mg_print_ip4, &ip->dst,
|
||||||
mg_ntohs(tcp->dport), tcp->flags, len));
|
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,
|
static struct mg_connection *accept_conn(struct mg_connection *lsn,
|
||||||
struct pkt *pkt) {
|
struct pkt *pkt) {
|
||||||
struct mg_connection *c = mg_alloc_conn(lsn->mgr);
|
struct mg_connection *c = mg_alloc_conn(lsn->mgr);
|
||||||
|
struct connstate *s;
|
||||||
if (c == NULL) {
|
if (c == NULL) {
|
||||||
MG_ERROR(("OOM"));
|
MG_ERROR(("OOM"));
|
||||||
return NULL;
|
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->dmss = 536; // assume default, RFC-9293 3.7.1
|
||||||
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
|
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
|
||||||
memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
|
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) {
|
static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||||
uint16_t frag = mg_ntohs(pkt->ip->frag);
|
uint16_t frag = mg_ntohs(pkt->ip->frag);
|
||||||
if (frag & IP_MORE_FRAGS_MSK || frag & IP_FRAG_OFFSET_MSK) {
|
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);
|
struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
|
||||||
if (c) mg_error(c, "Received fragmented packet");
|
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) {
|
} else if (pkt->ip->proto == 1) {
|
||||||
pkt->icmp = (struct icmp *) (pkt->ip + 1);
|
pkt->icmp = (struct icmp *) (pkt->ip + 1);
|
||||||
if (pkt->pay.len < sizeof(*pkt->icmp)) return;
|
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);
|
rx_udp(ifp, pkt);
|
||||||
}
|
}
|
||||||
} else if (pkt->ip->proto == 6) {
|
} else if (pkt->ip->proto == 6) {
|
||||||
|
uint16_t iplen, off;
|
||||||
pkt->tcp = (struct tcp *) (pkt->ip + 1);
|
pkt->tcp = (struct tcp *) (pkt->ip + 1);
|
||||||
if (pkt->pay.len < sizeof(*pkt->tcp)) return;
|
if (pkt->pay.len < sizeof(*pkt->tcp)) return;
|
||||||
mkpay(pkt, pkt->tcp + 1);
|
mkpay(pkt, pkt->tcp + 1);
|
||||||
uint16_t iplen = mg_ntohs(pkt->ip->len);
|
iplen = mg_ntohs(pkt->ip->len);
|
||||||
uint16_t off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U));
|
off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U));
|
||||||
if (iplen >= off) pkt->pay.len = (size_t) (iplen - off);
|
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_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,
|
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)
|
memcmp(pkt.eth->dst, broadcast, sizeof(pkt.eth->dst)) != 0)
|
||||||
return;
|
return;
|
||||||
if (ifp->enable_crc32_check && len > 4) {
|
if (ifp->enable_crc32_check && len > 4) {
|
||||||
|
uint32_t crc;
|
||||||
len -= 4; // TODO(scaprile): check on bigendian
|
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 (memcmp((void *) ((size_t) buf + len), &crc, sizeof(crc))) return;
|
||||||
}
|
}
|
||||||
if (pkt.eth->type == mg_htons(0x806)) {
|
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
|
// Process timeouts
|
||||||
for (c = ifp->mgr->conns; c != NULL; c = c->next) {
|
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);
|
struct connstate *s = (struct connstate *) (c + 1);
|
||||||
uint32_t rem_ip;
|
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));
|
memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
|
||||||
if (ifp->now > s->timer) {
|
if (ifp->now > s->timer) {
|
||||||
if (s->ttype == MIP_TTYPE_ARP) {
|
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;
|
if (mgr->ifp == NULL || mgr->ifp->driver == NULL) return;
|
||||||
mg_tcpip_poll(mgr->ifp, now);
|
mg_tcpip_poll(mgr->ifp, now);
|
||||||
for (c = mgr->conns; c != NULL; c = tmp) {
|
for (c = mgr->conns; c != NULL; c = tmp) {
|
||||||
tmp = c->next;
|
|
||||||
struct connstate *s = (struct connstate *) (c + 1);
|
struct connstate *s = (struct connstate *) (c + 1);
|
||||||
bool is_tls = c->is_tls && !c->is_resolving && !c->is_arplooking &&
|
bool is_tls = c->is_tls && !c->is_resolving && !c->is_arplooking &&
|
||||||
!c->is_listening && !c->is_connecting;
|
!c->is_listening && !c->is_connecting;
|
||||||
|
tmp = c->next;
|
||||||
mg_call(c, MG_EV_POLL, &now);
|
mg_call(c, MG_EV_POLL, &now);
|
||||||
MG_VERBOSE(("%lu .. %c%c%c%c%c %lu %lu", c->id, c->is_tls ? 'T' : 't',
|
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',
|
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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
enum { // ID1 ID2
|
enum { // ID1 ID2
|
||||||
MG_PHY_KSZ8x = 0x22, // 0022 1561 - KSZ8081RNB
|
MG_PHY_KSZ8x = 0x22, // 0022 1561 - KSZ8081RNB
|
||||||
MG_PHY_DP83x = 0x2000,
|
MG_PHY_DP83x = 0x2000,
|
||||||
MG_PHY_DP83867 = 0xa231, // 2000 a231 - TI DP83867I
|
MG_PHY_DP83867 = 0xa231, // 2000 a231 - TI DP83867I
|
||||||
MG_PHY_DP83825 = 0xa140, // 2000 a140 - TI DP83825I
|
MG_PHY_DP83825 = 0xa140, // 2000 a140 - TI DP83825I
|
||||||
@@ -22071,7 +22079,7 @@ enum { // ID1 ID2
|
|||||||
MG_PHY_LAN87x = 0x7, // 0007 c0fx - LAN8720
|
MG_PHY_LAN87x = 0x7, // 0007 c0fx - LAN8720
|
||||||
MG_PHY_RTL8201 = 0x1C, // 001c c816 - RTL8201,
|
MG_PHY_RTL8201 = 0x1C, // 001c c816 - RTL8201,
|
||||||
MG_PHY_ICS1894x = 0x15,
|
MG_PHY_ICS1894x = 0x15,
|
||||||
MG_PHY_ICS189432 = 0xf450 // 0015 f450 - ICS1894
|
MG_PHY_ICS189432 = 0xf450 // 0015 f450 - ICS1894
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
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));
|
phy->write_reg(phy_addr, MG_PHY_DP83x_REG_RCSR, MG_BIT(7) | MG_BIT(0));
|
||||||
} else if (id1 == MG_PHY_KSZ8x) {
|
} else if (id1 == MG_PHY_KSZ8x) {
|
||||||
// Disable isolation (override hw, it doesn't make sense at this point)
|
// Disable isolation (override hw, it doesn't make sense at this point)
|
||||||
phy->write_reg( // #2848, some NXP boards set ISO, even though
|
// - #2848, some NXP boards set ISO, even though docs say they don't
|
||||||
phy_addr, MG_PHY_REG_BCR, // docs say they don't
|
phy->write_reg(phy_addr, MG_PHY_REG_BCR,
|
||||||
phy->read_reg(phy_addr, MG_PHY_REG_BCR) & (uint16_t) ~MG_BIT(10));
|
(uint16_t) (phy->read_reg(phy_addr, MG_PHY_REG_BCR) &
|
||||||
phy->write_reg(phy_addr, MG_PHY_KSZ8x_REG_PC2R, // now do clock stuff
|
(uint16_t) ~MG_BIT(10)));
|
||||||
MG_BIT(15) | MG_BIT(8) | MG_BIT(7));
|
// 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) {
|
} else if (id1 == MG_PHY_LAN87x) {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
} else if (id1 == MG_PHY_RTL8201) {
|
} else if (id1 == MG_PHY_RTL8201) {
|
||||||
|
|||||||
+10
-8
@@ -1,7 +1,7 @@
|
|||||||
#include "phy.h"
|
#include "phy.h"
|
||||||
|
|
||||||
enum { // ID1 ID2
|
enum { // ID1 ID2
|
||||||
MG_PHY_KSZ8x = 0x22, // 0022 1561 - KSZ8081RNB
|
MG_PHY_KSZ8x = 0x22, // 0022 1561 - KSZ8081RNB
|
||||||
MG_PHY_DP83x = 0x2000,
|
MG_PHY_DP83x = 0x2000,
|
||||||
MG_PHY_DP83867 = 0xa231, // 2000 a231 - TI DP83867I
|
MG_PHY_DP83867 = 0xa231, // 2000 a231 - TI DP83867I
|
||||||
MG_PHY_DP83825 = 0xa140, // 2000 a140 - TI DP83825I
|
MG_PHY_DP83825 = 0xa140, // 2000 a140 - TI DP83825I
|
||||||
@@ -9,7 +9,7 @@ enum { // ID1 ID2
|
|||||||
MG_PHY_LAN87x = 0x7, // 0007 c0fx - LAN8720
|
MG_PHY_LAN87x = 0x7, // 0007 c0fx - LAN8720
|
||||||
MG_PHY_RTL8201 = 0x1C, // 001c c816 - RTL8201,
|
MG_PHY_RTL8201 = 0x1C, // 001c c816 - RTL8201,
|
||||||
MG_PHY_ICS1894x = 0x15,
|
MG_PHY_ICS1894x = 0x15,
|
||||||
MG_PHY_ICS189432 = 0xf450 // 0015 f450 - ICS1894
|
MG_PHY_ICS189432 = 0xf450 // 0015 f450 - ICS1894
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
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));
|
phy->write_reg(phy_addr, MG_PHY_DP83x_REG_RCSR, MG_BIT(7) | MG_BIT(0));
|
||||||
} else if (id1 == MG_PHY_KSZ8x) {
|
} else if (id1 == MG_PHY_KSZ8x) {
|
||||||
// Disable isolation (override hw, it doesn't make sense at this point)
|
// Disable isolation (override hw, it doesn't make sense at this point)
|
||||||
phy->write_reg( // #2848, some NXP boards set ISO, even though
|
// - #2848, some NXP boards set ISO, even though docs say they don't
|
||||||
phy_addr, MG_PHY_REG_BCR, // docs say they don't
|
phy->write_reg(phy_addr, MG_PHY_REG_BCR,
|
||||||
phy->read_reg(phy_addr, MG_PHY_REG_BCR) & (uint16_t) ~MG_BIT(10));
|
(uint16_t) (phy->read_reg(phy_addr, MG_PHY_REG_BCR) &
|
||||||
phy->write_reg(phy_addr, MG_PHY_KSZ8x_REG_PC2R, // now do clock stuff
|
(uint16_t) ~MG_BIT(10)));
|
||||||
MG_BIT(15) | MG_BIT(8) | MG_BIT(7));
|
// 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) {
|
} else if (id1 == MG_PHY_LAN87x) {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
} else if (id1 == MG_PHY_RTL8201) {
|
} else if (id1 == MG_PHY_RTL8201) {
|
||||||
|
|||||||
+38
-30
@@ -161,7 +161,7 @@ static uint32_t csumup(uint32_t sum, const void *buf, size_t len) {
|
|||||||
|
|
||||||
static uint16_t csumfin(uint32_t sum) {
|
static uint16_t csumfin(uint32_t sum) {
|
||||||
while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16);
|
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) {
|
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));
|
tx_ip(ifp, mac_dst, 17, ip_src, ip_dst, len + sizeof(struct udp));
|
||||||
struct udp *udp = (struct udp *) (ip + 1);
|
struct udp *udp = (struct udp *) (ip + 1);
|
||||||
size_t eth_len;
|
size_t eth_len;
|
||||||
|
uint32_t cs;
|
||||||
// MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len));
|
// MG_DEBUG(("UDP XX LEN %d %d", (int) len, (int) ifp->tx.len));
|
||||||
udp->sport = sport;
|
udp->sport = sport;
|
||||||
udp->dport = dport;
|
udp->dport = dport;
|
||||||
udp->len = mg_htons((uint16_t) (sizeof(*udp) + len));
|
udp->len = mg_htons((uint16_t) (sizeof(*udp) + len));
|
||||||
udp->csum = 0;
|
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, buf, len);
|
||||||
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
||||||
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
|
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;
|
break;
|
||||||
if (c->is_udp && pkt->udp && c->loc.port == pkt->udp->dport) 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 &&
|
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;
|
break;
|
||||||
}
|
}
|
||||||
return c;
|
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) {
|
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 hlen = sizeof(struct eth) + sizeof(struct ip) + sizeof(struct icmp);
|
||||||
size_t space = ifp->tx.len - hlen, plen = pkt->pay.len;
|
size_t space = ifp->tx.len - hlen, plen = pkt->pay.len;
|
||||||
|
struct ip *ip;
|
||||||
|
struct icmp *icmp;
|
||||||
if (plen > space) plen = space;
|
if (plen > space) plen = space;
|
||||||
struct ip *ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src,
|
ip = tx_ip(ifp, pkt->eth->src, 1, ifp->ip, pkt->ip->src,
|
||||||
sizeof(struct icmp) + plen);
|
sizeof(*icmp) + plen);
|
||||||
struct icmp *icmp = (struct icmp *) (ip + 1);
|
icmp = (struct icmp *) (ip + 1);
|
||||||
memset(icmp, 0, sizeof(*icmp)); // Set csum to 0
|
memset(icmp, 0, sizeof(*icmp)); // Set csum to 0
|
||||||
memcpy(icmp + 1, pkt->pay.buf, plen); // Copy RX payload to TX
|
memcpy(icmp + 1, pkt->pay.buf, plen); // Copy RX payload to TX
|
||||||
icmp->csum = ipcsum(icmp, sizeof(*icmp) + plen);
|
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
|
ifp->state = MG_TCPIP_STATE_REQ; // REQUESTING state
|
||||||
} else if (msgtype == 5) { // DHCPACK
|
} else if (msgtype == 5) { // DHCPACK
|
||||||
if (ifp->state == MG_TCPIP_STATE_REQ && ip && gw && lease) { // got an IP
|
if (ifp->state == MG_TCPIP_STATE_REQ && ip && gw && lease) { // got an IP
|
||||||
|
uint64_t rand;
|
||||||
ifp->lease_expire = ifp->now + lease * 1000;
|
ifp->lease_expire = ifp->now + lease * 1000;
|
||||||
MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000));
|
MG_INFO(("Lease: %u sec (%lld)", lease, ifp->lease_expire / 1000));
|
||||||
// assume DHCP server = router until ARP resolves
|
// assume DHCP server = router until ARP resolves
|
||||||
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
memcpy(ifp->gwmac, pkt->eth->src, sizeof(ifp->gwmac));
|
||||||
ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
|
ifp->ip = ip, ifp->gw = gw, ifp->mask = mask;
|
||||||
ifp->state = MG_TCPIP_STATE_IP; // BOUND state
|
ifp->state = MG_TCPIP_STATE_IP; // BOUND state
|
||||||
uint64_t rand;
|
|
||||||
mg_random(&rand, sizeof(rand));
|
mg_random(&rand, sizeof(rand));
|
||||||
srand((unsigned int) (rand + mg_millis()));
|
srand((unsigned int) (rand + mg_millis()));
|
||||||
if (ifp->enable_req_dns && dns != 0)
|
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) {
|
static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||||
uint8_t op = 0, *p = pkt->dhcp->options,
|
uint8_t op = 0, *p = pkt->dhcp->options,
|
||||||
*end = (uint8_t *) &pkt->raw.buf[pkt->raw.len];
|
*end = (uint8_t *) &pkt->raw.buf[pkt->raw.len];
|
||||||
if (end < (uint8_t *) (pkt->dhcp + 1)) return;
|
|
||||||
// struct dhcp *req = pkt->dhcp;
|
// struct dhcp *req = pkt->dhcp;
|
||||||
struct dhcp res = {2, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}};
|
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;
|
res.yiaddr = ifp->ip;
|
||||||
((uint8_t *) (&res.yiaddr))[3]++; // Offer our IP + 1
|
((uint8_t *) (&res.yiaddr))[3]++; // Offer our IP + 1
|
||||||
while (p + 1 < end && p[0] != 255) { // Parse options
|
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) {
|
if (c == NULL) {
|
||||||
// No UDP listener on this port. Should send ICMP, but keep silent.
|
// No UDP listener on this port. Should send ICMP, but keep silent.
|
||||||
} else {
|
} else {
|
||||||
|
struct connstate *s = (struct connstate *) (c + 1);
|
||||||
c->rem.port = pkt->udp->sport;
|
c->rem.port = pkt->udp->sport;
|
||||||
memcpy(c->rem.ip, &pkt->ip->src, sizeof(uint32_t));
|
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));
|
memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
|
||||||
if (c->recv.len >= MG_MAX_RECV_SIZE) {
|
if (c->recv.len >= MG_MAX_RECV_SIZE) {
|
||||||
mg_error(c, "max_recv_buf_size reached");
|
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 ip *ip;
|
||||||
struct tcp *tcp;
|
struct tcp *tcp;
|
||||||
uint16_t opts[4 / 2];
|
uint16_t opts[4 / 2];
|
||||||
if (flags & TH_SYN) { // Send MSS, RFC-9293 3.7.1
|
if (flags & TH_SYN) { // Send MSS, RFC-9293 3.7.1
|
||||||
opts[0] = mg_htons(0x0204); // RFC-9293 3.2
|
opts[0] = mg_htons(0x0204); // RFC-9293 3.2
|
||||||
opts[1] = mg_htons(ifp->mtu - 40); // RFC-6691
|
opts[1] = mg_htons((uint16_t) (ifp->mtu - 40)); // RFC-6691
|
||||||
buf = opts;
|
buf = opts;
|
||||||
len = sizeof(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->win = mg_htons(MIP_TCP_WIN);
|
||||||
tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4);
|
tcp->off = (uint8_t) (sizeof(*tcp) / 4 << 4);
|
||||||
if (flags & TH_SYN) tcp->off += (uint8_t) (sizeof(opts) / 4 << 4);
|
if (flags & TH_SYN) tcp->off += (uint8_t) (sizeof(opts) / 4 << 4);
|
||||||
|
{
|
||||||
uint32_t cs = 0;
|
uint32_t cs = 0;
|
||||||
uint16_t n = (uint16_t) (sizeof(*tcp) + len);
|
uint16_t n = (uint16_t) (sizeof(*tcp) + len);
|
||||||
uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)};
|
uint8_t pseudo[] = {0, ip->proto, (uint8_t) (n >> 8), (uint8_t) (n & 255)};
|
||||||
cs = csumup(cs, tcp, n);
|
cs = csumup(cs, tcp, n);
|
||||||
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
cs = csumup(cs, &ip->src, sizeof(ip->src));
|
||||||
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
|
cs = csumup(cs, &ip->dst, sizeof(ip->dst));
|
||||||
cs = csumup(cs, pseudo, sizeof(pseudo));
|
cs = csumup(cs, pseudo, sizeof(pseudo));
|
||||||
tcp->csum = csumfin(cs);
|
tcp->csum = csumfin(cs);
|
||||||
|
}
|
||||||
MG_VERBOSE(("TCP %M:%hu -> %M:%hu fl %x len %u", mg_print_ip4, &ip->src,
|
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->sport), mg_print_ip4, &ip->dst,
|
||||||
mg_ntohs(tcp->dport), tcp->flags, len));
|
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,
|
static struct mg_connection *accept_conn(struct mg_connection *lsn,
|
||||||
struct pkt *pkt) {
|
struct pkt *pkt) {
|
||||||
struct mg_connection *c = mg_alloc_conn(lsn->mgr);
|
struct mg_connection *c = mg_alloc_conn(lsn->mgr);
|
||||||
|
struct connstate *s;
|
||||||
if (c == NULL) {
|
if (c == NULL) {
|
||||||
MG_ERROR(("OOM"));
|
MG_ERROR(("OOM"));
|
||||||
return NULL;
|
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->dmss = 536; // assume default, RFC-9293 3.7.1
|
||||||
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
|
s->seq = mg_ntohl(pkt->tcp->ack), s->ack = mg_ntohl(pkt->tcp->seq);
|
||||||
memcpy(s->mac, pkt->eth->src, sizeof(s->mac));
|
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) {
|
static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||||
uint16_t frag = mg_ntohs(pkt->ip->frag);
|
uint16_t frag = mg_ntohs(pkt->ip->frag);
|
||||||
if (frag & IP_MORE_FRAGS_MSK || frag & IP_FRAG_OFFSET_MSK) {
|
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);
|
struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
|
||||||
if (c) mg_error(c, "Received fragmented packet");
|
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) {
|
} else if (pkt->ip->proto == 1) {
|
||||||
pkt->icmp = (struct icmp *) (pkt->ip + 1);
|
pkt->icmp = (struct icmp *) (pkt->ip + 1);
|
||||||
if (pkt->pay.len < sizeof(*pkt->icmp)) return;
|
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);
|
rx_udp(ifp, pkt);
|
||||||
}
|
}
|
||||||
} else if (pkt->ip->proto == 6) {
|
} else if (pkt->ip->proto == 6) {
|
||||||
|
uint16_t iplen, off;
|
||||||
pkt->tcp = (struct tcp *) (pkt->ip + 1);
|
pkt->tcp = (struct tcp *) (pkt->ip + 1);
|
||||||
if (pkt->pay.len < sizeof(*pkt->tcp)) return;
|
if (pkt->pay.len < sizeof(*pkt->tcp)) return;
|
||||||
mkpay(pkt, pkt->tcp + 1);
|
mkpay(pkt, pkt->tcp + 1);
|
||||||
uint16_t iplen = mg_ntohs(pkt->ip->len);
|
iplen = mg_ntohs(pkt->ip->len);
|
||||||
uint16_t off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U));
|
off = (uint16_t) (sizeof(*pkt->ip) + ((pkt->tcp->off >> 4) * 4U));
|
||||||
if (iplen >= off) pkt->pay.len = (size_t) (iplen - off);
|
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_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,
|
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)
|
memcmp(pkt.eth->dst, broadcast, sizeof(pkt.eth->dst)) != 0)
|
||||||
return;
|
return;
|
||||||
if (ifp->enable_crc32_check && len > 4) {
|
if (ifp->enable_crc32_check && len > 4) {
|
||||||
|
uint32_t crc;
|
||||||
len -= 4; // TODO(scaprile): check on bigendian
|
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 (memcmp((void *) ((size_t) buf + len), &crc, sizeof(crc))) return;
|
||||||
}
|
}
|
||||||
if (pkt.eth->type == mg_htons(0x806)) {
|
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
|
// Process timeouts
|
||||||
for (c = ifp->mgr->conns; c != NULL; c = c->next) {
|
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);
|
struct connstate *s = (struct connstate *) (c + 1);
|
||||||
uint32_t rem_ip;
|
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));
|
memcpy(&rem_ip, c->rem.ip, sizeof(uint32_t));
|
||||||
if (ifp->now > s->timer) {
|
if (ifp->now > s->timer) {
|
||||||
if (s->ttype == MIP_TTYPE_ARP) {
|
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;
|
if (mgr->ifp == NULL || mgr->ifp->driver == NULL) return;
|
||||||
mg_tcpip_poll(mgr->ifp, now);
|
mg_tcpip_poll(mgr->ifp, now);
|
||||||
for (c = mgr->conns; c != NULL; c = tmp) {
|
for (c = mgr->conns; c != NULL; c = tmp) {
|
||||||
tmp = c->next;
|
|
||||||
struct connstate *s = (struct connstate *) (c + 1);
|
struct connstate *s = (struct connstate *) (c + 1);
|
||||||
bool is_tls = c->is_tls && !c->is_resolving && !c->is_arplooking &&
|
bool is_tls = c->is_tls && !c->is_resolving && !c->is_arplooking &&
|
||||||
!c->is_listening && !c->is_connecting;
|
!c->is_listening && !c->is_connecting;
|
||||||
|
tmp = c->next;
|
||||||
mg_call(c, MG_EV_POLL, &now);
|
mg_call(c, MG_EV_POLL, &now);
|
||||||
MG_VERBOSE(("%lu .. %c%c%c%c%c %lu %lu", c->id, c->is_tls ? 'T' : 't',
|
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',
|
c->is_connecting ? 'C' : 'c', c->is_tls_hs ? 'H' : 'h',
|
||||||
|
|||||||
@@ -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 $@
|
$(CC) mip_tap_test.c packed_fs.c $(CFLAGS) $(LDFLAGS) -o $@
|
||||||
ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./$@
|
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
|
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
|
$(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 > $@
|
$(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 > $@
|
||||||
|
|||||||
+3
-2
@@ -74,9 +74,9 @@ static void frag_send_fn(struct mg_connection *c, int ev, void *ev_data) {
|
|||||||
|
|
||||||
static void test_poll(void) {
|
static void test_poll(void) {
|
||||||
int count = 0, i;
|
int count = 0, i;
|
||||||
|
struct mg_tcpip_if mif;
|
||||||
struct mg_mgr mgr;
|
struct mg_mgr mgr;
|
||||||
mg_mgr_init(&mgr);
|
mg_mgr_init(&mgr);
|
||||||
struct mg_tcpip_if mif;
|
|
||||||
memset(&mif, 0, sizeof(mif));
|
memset(&mif, 0, sizeof(mif));
|
||||||
mif.driver = &mg_tcpip_driver_mock;
|
mif.driver = &mg_tcpip_driver_mock;
|
||||||
mg_tcpip_init(&mgr, &mif);
|
mg_tcpip_init(&mgr, &mif);
|
||||||
@@ -295,6 +295,7 @@ static void test_frag_send_path(void) {
|
|||||||
struct mg_mgr mgr;
|
struct mg_mgr mgr;
|
||||||
struct mg_tcpip_driver driver;
|
struct mg_tcpip_driver driver;
|
||||||
struct mg_tcpip_if mif;
|
struct mg_tcpip_if mif;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
mg_mgr_init(&mgr);
|
mg_mgr_init(&mgr);
|
||||||
memset(&mif, 0, sizeof(mif));
|
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
|
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);
|
mg_http_listen(&mgr, "http://0.0.0.0:0", frag_send_fn, NULL);
|
||||||
mgr.conns->pfn = 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);
|
ASSERT(s_seg_sent == 3);
|
||||||
s_driver_data.len = 0;
|
s_driver_data.len = 0;
|
||||||
mg_mgr_free(&mgr);
|
mg_mgr_free(&mgr);
|
||||||
|
|||||||
Reference in new issue
Block a user