summaryrefslogtreecommitdiff
path: root/src/ipcpd/shim-eth-llc/main.c
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 /src/ipcpd/shim-eth-llc/main.c
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.
Diffstat (limited to 'src/ipcpd/shim-eth-llc/main.c')
-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)