#include <string.h>
#include <errno.h>
#include <linux/can.h>
+#include <inttypes.h>
#include "m_ematch.h"
#define EM_CAN_RULES_SIZE 32
"Example: u32(sff 0x123 sff 0x124 sff 0x125:0xf)\n");
}
+static int can_parse_rule(struct can_filter *rule, struct bstr *a, int iseff)
+{
+ unsigned int can_id = 0;
+ unsigned int can_mask = 0;
+
+ if (sscanf(a->data, "%"SCNx32 ":" "%"SCNx32, &can_id, &can_mask) != 2) {
+ if (sscanf(a->data, "%"SCNx32, &can_id) != 1) {
+ return -1;
+ } else
+ can_mask = CAN_SFF_MASK;
+ }
+ rule->can_id = can_id | (iseff) ? CAN_EFF_FLAG : 0 ;
+ rule->can_mask = can_mask;
+
+ return 0;
+}
+
static int can_parse_eopt(struct nlmsghdr *n, struct tcf_ematch_hdr *hdr,
struct bstr *args)
{
struct bstr *a;
- unsigned long canid;
- unsigned long canmask;
struct can_filter rules_raw[EM_CAN_RULES_SIZE];
int iseff = 0;
int i = 0;
+ int ret;
memset(&rules_raw, 0, sizeof(rules_raw));
if (a == NULL)
return PARSE_ERR(a, "can: missing key");
- canid = bstrtoul(a);
- if (canid == ULONG_MAX)
- return PARSE_ERR(a, "can: invalid ID, must be numeric");
- //FIXME parse mask
-
- rules_raw[i].can_id = canid | (iseff) ? CAN_EFF_FLAG : 0 ;
+ ret = can_parse_rule(&rules_raw[0], a, iseff);
+ if (ret == -1)
+ return PARSE_ERR(a, "can: Improperly formed CAN ID & mask\n");
for (i = 1; i < (sizeof(rules_raw)/sizeof(struct can_filter)); i++) {
a = bstr_next(args);
if (a == NULL)
break;
- canid = bstrtoul(a);
- if (canid == ULONG_MAX)
+ ret = can_parse_rule(&rules_raw[i], a, iseff);
+ if (ret == -1)
+ return PARSE_ERR(a, "can: Improperly formed CAN ID & mask\n");
+
+#if 0
+ can_id = bstrtoul(a);
+ if (can_id == ULONG_MAX)
return PARSE_ERR(a, "can: invalid ID, must be numeric");
- rules_raw[i].can_id = canid | (iseff) ? CAN_EFF_FLAG : 0 ;
+ rules_raw[i].can_id = can_id | (iseff) ? CAN_EFF_FLAG : 0 ;
+#endif
}
+ if (a->next)
+ return PARSE_ERR(a->next, "can: unexpected trailer");
+
addraw_l(n, MAX_MSG, hdr, sizeof(*hdr));
addraw_l(n, MAX_MSG, &rules_raw, sizeof(struct can_filter) * i); // FIXME is size ok