]> rtime.felk.cvut.cz Git - lisovros/iproute2_canprio.git/commitdiff
em_can: More advanced parameter parsing
authorRostislav Lisovy <lisovy@gmail.com>
Mon, 11 Jun 2012 11:42:16 +0000 (13:42 +0200)
committerRostislav Lisovy <lisovy@gmail.com>
Mon, 11 Jun 2012 11:42:16 +0000 (13:42 +0200)
tc/em_can.c

index bcd09226ecf34568a4096dd6fc094cda07c33dc7..4c0984daf4c690edab53451764b48d41ca27c93e 100644 (file)
@@ -20,6 +20,7 @@
 #include <string.h>
 #include <errno.h>
 #include <linux/can.h>
+#include <inttypes.h>
 #include "m_ematch.h"
 
 #define EM_CAN_RULES_SIZE                              32
@@ -36,15 +37,31 @@ static void can_print_usage(FILE *fd)
            "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));
 
@@ -65,25 +82,31 @@ static int can_parse_eopt(struct nlmsghdr *n, struct tcf_ematch_hdr *hdr,
        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