diff options
author | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2016-07-28 15:00:52 +0200 |
---|---|---|
committer | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2016-07-28 15:05:10 +0200 |
commit | 240f0f897d5f84230d4bb3592ddfeecb2f4fa586 (patch) | |
tree | 4ca3c80bb23d6d2cad506d0d48bdb206fa98b480 | |
parent | 67de2ae5f7aee25c077096bd90a8d4cd3cdcf094 (diff) | |
download | ouroboros-240f0f897d5f84230d4bb3592ddfeecb2f4fa586.tar.gz ouroboros-240f0f897d5f84230d4bb3592ddfeecb2f4fa586.zip |
ipcpd: shim-eth-llc: Use correct frame length
Upon receipt of a frame, the minimum of the length reported in the
frame and the frame length reported by kernel is taken. Some device
drivers change the length in the frame. Some others add padding,
making the length reported by the kernel too high. This is a lousy
workaround to make it work on as many systems as possible.
-rw-r--r-- | src/ipcpd/shim-eth-llc/main.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index 87458359..c2309272 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -614,6 +614,7 @@ static void * eth_llc_ipcp_sdu_reader(void * o) uint8_t dst_mac[MAC_SIZE]; uint8_t br_addr[MAC_SIZE]; int frame_len = 0; + int len_frame = 0; uint8_t ssap = 0; uint8_t dsap = 0; int i = 0; @@ -694,6 +695,9 @@ static void * eth_llc_ipcp_sdu_reader(void * o) #endif continue; } + + len_frame = ((buf[i]) << 8) + buf[i + 1]; + len_frame -= 3; i += 2; dsap = reverse_bits(buf[i++]); @@ -702,6 +706,15 @@ static void * eth_llc_ipcp_sdu_reader(void * o) frame_len -= i; + /* + * Take minimum of length reported in frame + * and frame length reported by kernel. Some device + * drivers change the length in the frame. Some + * others add padding, making the length reported + * by the kernel too high. Sigh. Lousy workaround. + */ + frame_len = MIN(frame_len, len_frame); + if (ssap == MGMT_SAP && dsap == MGMT_SAP) { eth_llc_ipcp_mgmt_frame((uint8_t *) (buf + i), @@ -712,7 +725,8 @@ static void * eth_llc_ipcp_sdu_reader(void * o) j = addr_and_saps_to_index(src_mac, ssap, dsap); if (j < 0) { - pthread_rwlock_unlock(&shim_data(_ipcp)->flows_lock); + pthread_rwlock_unlock(&shim_data(_ipcp)-> + flows_lock); pthread_rwlock_unlock(&_ipcp->state_lock); #if defined(PACKET_RX_RING) && defined(PACKET_TX_RING) offset = (offset + 1) |