From f212691624e0b6b453e8e194b19db864ff672865 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Fri, 8 Apr 2022 15:41:54 +0200 Subject: [PATCH] eth2tr: Don't assume proto, it is length! --- tr-bridge.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tr-bridge.c b/tr-bridge.c index abbbf18..72efabb 100644 --- a/tr-bridge.c +++ b/tr-bridge.c @@ -176,7 +176,7 @@ static int eth2tr(struct bridge_state *bst) uint8_t buf[2000]; const struct ethhdr *ethh = (struct ethhdr *) buf; struct tr_hdr trh; - int rc, ethlen; + int rc, ethlen, eth_payload_len; rc = read(bst->eth.socket, buf, sizeof(buf)); if (rc <= 0) { @@ -193,9 +193,11 @@ static int eth2tr(struct bridge_state *bst) mac2str_buf(eth_src, ethh->h_source); mac2str_buf(eth_dst, ethh->h_dest); - if (ethh->h_proto != htons(ETH_P_802_2)) { - fprintf(stderr, "TR<-ETH: Not bridging unexpected frame for proto %s->%s 0x%04x\n", - eth_src, eth_dst, ntohs(ethh->h_proto)); + /* 802.3 frame: 'proto' is actually the length */ + eth_payload_len = htons(ethh->h_proto); + if (sizeof(*ethh) + eth_payload_len > ethlen) { + fprintf(stderr, "TR<-ETH: Not bridging unrealistically long (%lu > %u) frame %s->%s\n", + sizeof(*ethh) + eth_payload_len, ethlen, eth_src, eth_dst); return 0; } @@ -211,7 +213,7 @@ static int eth2tr(struct bridge_state *bst) if (mac_table_empty(&bst->tr.mac_tbl) || mac_table_contains(&bst->tr.mac_tbl, trh.daddr)) { printf("TR<-ETH: %s/%s <- %s/%s\n", tr_src, eth_src, tr_dst, eth_dst); - return write_tr(bst->tr.socket, &trh, buf + sizeof(*ethh), ethlen - sizeof(*ethh)); + return write_tr(bst->tr.socket, &trh, buf + sizeof(*ethh), eth_payload_len); } else { printf("TR<-ETH: Ignoring frame to unknown MAC %s\n", mac2str(trh.daddr)); return 0;