summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSander Vrijders <sander.vrijders@intec.ugent.be>2016-07-28 15:00:52 +0200
committerSander Vrijders <sander.vrijders@intec.ugent.be>2016-07-28 15:05:10 +0200
commit240f0f897d5f84230d4bb3592ddfeecb2f4fa586 (patch)
tree4ca3c80bb23d6d2cad506d0d48bdb206fa98b480
parent67de2ae5f7aee25c077096bd90a8d4cd3cdcf094 (diff)
downloadouroboros-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.c16
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)