summaryrefslogtreecommitdiff
path: root/src/ipcpd
diff options
context:
space:
mode:
authorDimitri Staessens <[email protected]>2018-03-10 19:42:57 +0100
committerSander Vrijders <[email protected]>2018-03-10 22:14:01 +0100
commit103e9d80b2970b4e8fc1f45d3bf48d95b8937d6a (patch)
treedc93efb97aa3cc0ed66de6f687c38c8f96b98f02 /src/ipcpd
parent2936dd5e4232f7d7d9c720d89bb4a696abcd1830 (diff)
downloadouroboros-103e9d80b2970b4e8fc1f45d3bf48d95b8937d6a.tar.gz
ouroboros-103e9d80b2970b4e8fc1f45d3bf48d95b8937d6a.zip
ipcpd: Add length field to eth-dix
Some NICs added padding to the Ethernet II frames causing bad frame lengths and GPB unpack fails. This adds a 2-byte length field to the DIX frame to circumvent this. Signed-off-by: Dimitri Staessens <[email protected]> Signed-off-by: Sander Vrijders <[email protected]>
Diffstat (limited to 'src/ipcpd')
-rw-r--r--src/ipcpd/eth/eth.c119
1 files changed, 57 insertions, 62 deletions
diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c
index ce806dc2..9bbadf91 100644
--- a/src/ipcpd/eth/eth.c
+++ b/src/ipcpd/eth/eth.c
@@ -88,67 +88,70 @@
#define NETMAP_WITH_LIBS
#include <net/netmap_user.h>
#elif defined(HAVE_BPF)
-#define BPF_DEV_MAX 256
-#define BPF_BLEN sysconf(_SC_PAGESIZE)
+#define BPF_DEV_MAX 256
+#define BPF_BLEN sysconf(_SC_PAGESIZE)
#include <net/bpf.h>
#endif
-#define MAC_SIZE 6
-#define ETH_TYPE_LENGTH_SIZE 2
-#define ETH_HEADER_SIZE (2 * MAC_SIZE + ETH_TYPE_LENGTH_SIZE)
+#define MAC_SIZE 6
+#define ETH_TYPE_LENGTH_SIZE sizeof(uint16_t)
+#define ETH_HEADER_SIZE (2 * MAC_SIZE + ETH_TYPE_LENGTH_SIZE)
#if defined(BUILD_ETH_DIX)
-#define THIS_TYPE IPCP_ETH_DIX
-#define MGMT_EID 0
-#define DIX_HEADER_SIZE 2
-#define MAX_EIDS (1 << (8 * DIX_HEADER_SIZE))
-#define ETH_MAX_SDU_SIZE (1500 - DIX_HEADER_SIZE)
-#define ETH_FRAME_SIZE (ETH_HEADER_SIZE + DIX_HEADER_SIZE \
- + ETH_MAX_SDU_SIZE)
+#define THIS_TYPE IPCP_ETH_DIX
+#define MGMT_EID 0
+#define DIX_EID_SIZE sizeof(uint16_t)
+#define DIX_LENGTH_SIZE sizeof(uint16_t)
+#define DIX_HEADER_SIZE (DIX_EID_SIZE + DIX_LENGTH_SIZE)
+#define MAX_EIDS (1 << (8 * DIX_EID_SIZE))
+#define ETH_MAX_SDU_SIZE (1500 - DIX_HEADER_SIZE)
+#define ETH_FRAME_SIZE (ETH_HEADER_SIZE + DIX_HEADER_SIZE \
+ + ETH_MAX_SDU_SIZE)
#elif defined(BUILD_ETH_LLC)
-#define THIS_TYPE IPCP_ETH_LLC
-#define MGMT_SAP 0x01
-#define LLC_HEADER_SIZE 3
-#define MAX_SAPS 64
-#define ETH_MAX_SDU_SIZE (1500 - LLC_HEADER_SIZE)
-#define ETH_FRAME_SIZE (ETH_HEADER_SIZE + LLC_HEADER_SIZE \
- + ETH_MAX_SDU_SIZE)
-#endif
-#define ALLOC_TIMEO 10 /* ms */
-#define NAME_QUERY_TIMEO 2000 /* ms */
-#define MGMT_TIMEO 100 /* ms */
-
-#define FLOW_REQ 0
-#define FLOW_REPLY 1
-#define NAME_QUERY_REQ 2
-#define NAME_QUERY_REPLY 3
+#define THIS_TYPE IPCP_ETH_LLC
+#define MGMT_SAP 0x01
+#define LLC_HEADER_SIZE 3
+#define MAX_SAPS 64
+#define ETH_MAX_SDU_SIZE (1500 - LLC_HEADER_SIZE)
+#define ETH_FRAME_SIZE (ETH_HEADER_SIZE + LLC_HEADER_SIZE \
+ + ETH_MAX_SDU_SIZE)
+#endif
+#define ALLOC_TIMEO 10 /* ms */
+#define NAME_QUERY_TIMEO 2000 /* ms */
+#define MGMT_TIMEO 100 /* ms */
+
+#define FLOW_REQ 0
+#define FLOW_REPLY 1
+#define NAME_QUERY_REQ 2
+#define NAME_QUERY_REPLY 3
struct mgmt_msg {
- uint8_t code;
+ uint8_t code;
#if defined(BUILD_ETH_DIX)
uint16_t seid;
uint16_t deid;
#elif defined(BUILD_ETH_LLC)
- uint8_t ssap;
- uint8_t dsap;
+ uint8_t ssap;
+ uint8_t dsap;
#endif
- uint8_t qoscube;
- int8_t response;
+ uint8_t qoscube;
+ int8_t response;
} __attribute__((packed));
struct eth_frame {
- uint8_t dst_hwaddr[MAC_SIZE];
- uint8_t src_hwaddr[MAC_SIZE];
+ uint8_t dst_hwaddr[MAC_SIZE];
+ uint8_t src_hwaddr[MAC_SIZE];
#if defined(BUILD_ETH_DIX)
- uint8_t ethertype[ETH_TYPE_LENGTH_SIZE];
- uint8_t eid[DIX_HEADER_SIZE];
+ uint16_t ethertype;
+ uint16_t eid;
+ uint16_t length;
#elif defined(BUILD_ETH_LLC)
- uint8_t length[ETH_TYPE_LENGTH_SIZE];
- uint8_t dsap;
- uint8_t ssap;
- uint8_t cf;
+ uint16_t length;
+ uint8_t dsap;
+ uint8_t ssap;
+ uint8_t cf;
#endif
- uint8_t payload;
+ uint8_t payload;
} __attribute__((packed));
struct ef {
@@ -344,18 +347,14 @@ static int eth_ipcp_send_frame(const uint8_t * dst_addr,
const uint8_t * payload,
size_t len)
{
- uint32_t frame_len = 0;
+ uint32_t frame_len = 0;
#ifdef BUILD_ETH_LLC
- uint8_t cf = 0x03;
- uint16_t length;
+ uint8_t cf = 0x03;
#endif
- uint8_t frame[ETH_MAX_SDU_SIZE];
- struct eth_frame * e_frame;
+ uint8_t frame[ETH_MAX_SDU_SIZE];
+ struct eth_frame * e_frame;
- if (payload == NULL) {
- log_err("Payload was NULL.");
- return -1;
- }
+ assert(payload);
if (len > ETH_MAX_SDU_SIZE)
return -1;
@@ -371,13 +370,12 @@ static int eth_ipcp_send_frame(const uint8_t * dst_addr,
#endif /* HAVE_NETMAP */
MAC_SIZE);
#if defined(BUILD_ETH_DIX)
- memcpy(&e_frame->ethertype, &eth_data.ethertype, ETH_TYPE_LENGTH_SIZE);
- deid = htons(deid);
- memcpy(&e_frame->eid, &deid, DIX_HEADER_SIZE);
+ e_frame->ethertype = eth_data.ethertype;
+ e_frame->eid = htons(deid);
+ e_frame->length = htons(len);
frame_len = ETH_HEADER_SIZE + DIX_HEADER_SIZE + len;
#elif defined(BUILD_ETH_LLC)
- length = htons(LLC_HEADER_SIZE + len);
- memcpy(&e_frame->length, &length, sizeof(length));
+ e_frame->length = htons(LLC_HEADER_SIZE + len);
e_frame->dsap = dsap;
e_frame->ssap = ssap;
e_frame->cf = cf;
@@ -410,6 +408,7 @@ static int eth_ipcp_send_frame(const uint8_t * dst_addr,
return -1;
}
#endif /* HAVE_NETMAP */
+
return 0;
}
@@ -821,16 +820,12 @@ static void * eth_ipcp_sdu_reader(void * o)
}
#endif
+ length = ntohs(e_frame->length);
#if defined(BUILD_ETH_DIX)
- length = frame_len - ETH_HEADER_SIZE - DIX_HEADER_SIZE;
- memcpy(&deid, &e_frame->eid, sizeof(deid));
- deid = ntohs(deid);
+ deid = ntohs(e_frame->eid);
if (deid == MGMT_EID) {
#elif defined (BUILD_ETH_LLC)
- memcpy(&length, &e_frame->length, sizeof(length));
- length = ntohs(length);
-
if (length > 0x05FF) /* DIX */
continue;