This is the patch for the user space cangw app that corresponds to the previously submitted kernel module patch "[PATCH can-gw] add support for counter byte". --- gw.h.orig 2018-08-30 14:00:26.642686000 -0400 +++ gw.h 2018-09-06 13:14:44.182811000 -0400 @@ -80,6 +80,7 @@ enum { CGW_DELETED, /* number of deleted CAN frames (see max_hops param) */ CGW_LIM_HOPS, /* limit the number of hops of this specific rule */ CGW_MOD_UID, /* user defined identifier for modification updates */ + CGW_COUNTER, /* set message counter into data[index] */ __CGW_MAX }; @@ -107,6 +108,18 @@ struct cgw_frame_mod { #define CGW_MODATTR_LEN sizeof(struct cgw_frame_mod) +/* message counter modifiers */ +struct cgw_counter { + __s8 result_idx; /* byte index of the counter */ + __u8 min_count; /* value that the counter is reset to after hitting max_count */ + __u8 max_count; /* count up to this value */ + __u8 counter_mask; /* allows you to not take up the whole byte with the counter */ + __u8 counter_value; /* current value of counter */ +} __attribute__((packed)); + +/* length of message counter parameters. idx = index in CAN frame data[] */ +#define CGW_COUNTER_LEN sizeof(struct cgw_counter) + struct cgw_csum_xor { __s8 from_idx; __s8 to_idx; --- cangw.c.orig 2018-08-30 13:59:38.978686000 -0400 +++ cangw.c 2018-09-17 13:20:12.827000000 -0400 @@ -184,6 +184,13 @@ void print_cs_crc8(struct cgw_csum_crc8 print_cs_crc8_profile(cs_crc8); } +void print_counter(struct cgw_counter *msgcounter) +{ + printf("-n %d:%d:%d:%d ", + msgcounter->result_idx, msgcounter->min_count, + msgcounter->max_count, msgcounter->counter_mask); +} + void print_usage(char *prg) { fprintf(stderr, "%s - manage PF_CAN netlink gateway.\n", prg); @@ -204,6 +211,7 @@ void print_usage(char *prg) fprintf(stderr, " -l <hops> (limit the number of frame hops / routings)\n"); fprintf(stderr, " -f <filter> (set CAN filter)\n"); fprintf(stderr, " -m <mod> (set frame modifications)\n"); + fprintf(stderr, " -n <result_idx>:<min_count>:<max_count>:<mask> (message counter)\n"); fprintf(stderr, " -x <from_idx>:<to_idx>:<result_idx>:<init_xor_val> (XOR checksum)\n"); fprintf(stderr, " -c <from>:<to>:<result>:<init_val>:<xor_val>:<crctab[256]> (CRC8 cs)\n"); fprintf(stderr, " -p <profile>:[<profile_data>] (CRC8 checksum profile & parameters)\n"); @@ -427,6 +435,7 @@ int parse_rtlist(char *prgname, unsigned case CGW_MOD_SET: case CGW_MOD_UID: case CGW_LIM_HOPS: + case CGW_COUNTER: case CGW_CS_XOR: case CGW_CS_CRC8: break; @@ -507,6 +516,10 @@ int parse_rtlist(char *prgname, unsigned printf("-l %d ", *(__u8 *)RTA_DATA(rta)); break; + case CGW_COUNTER: + print_counter((struct cgw_counter *)RTA_DATA(rta)); + break; + case CGW_CS_XOR: print_cs_xor((struct cgw_csum_xor *)RTA_DATA(rta)); break; @@ -548,6 +561,7 @@ int main(int argc, char **argv) int cmd = UNSPEC; int have_filter = 0; + int have_counter = 0; int have_cs_xor = 0; int have_cs_crc8 = 0; @@ -571,6 +585,7 @@ int main(int argc, char **argv) struct can_filter filter; struct sockaddr_nl nladdr; + struct cgw_counter msgcounter; struct cgw_csum_xor cs_xor; struct cgw_csum_crc8 cs_crc8; char crc8tab[513] = {0}; @@ -580,10 +595,11 @@ int main(int argc, char **argv) int i; memset(&req, 0, sizeof(req)); + memset(&msgcounter, 0, sizeof(msgcounter)); memset(&cs_xor, 0, sizeof(cs_xor)); memset(&cs_crc8, 0, sizeof(cs_crc8)); - while ((opt = getopt(argc, argv, "ADFLs:d:teiu:l:f:c:p:x:m:?")) != -1) { + while ((opt = getopt(argc, argv, "ADFLs:d:teiu:l:f:c:p:n:x:m:?")) != -1) { switch (opt) { case 'A': @@ -696,6 +712,23 @@ int main(int argc, char **argv) exit(0); break; + case 'n': + /* increment counter at result_idx by one each time that a message is sent, + * counting from min to max + */ + + if ((sscanf(optarg, "%hhd:%hhd:%hhd:%hhx", + &msgcounter.result_idx, &msgcounter.min_count, + &msgcounter.max_count, &msgcounter.counter_mask) == 4)) { + msgcounter.counter_value = msgcounter.max_count; /* first transmitted message will start with min_count after incrementing from max_count */ + have_counter = 1; + } else { + printf("Bad counter definition '%s'.\n", optarg); + exit(1); + } + + break; + default: fprintf(stderr, "Unknown option %c\n", opt); print_usage(basename(argv[0])); @@ -768,6 +801,9 @@ int main(int argc, char **argv) if (have_filter) addattr_l(&req.nh, sizeof(req), CGW_FILTER, &filter, sizeof(filter)); + if (have_counter) + addattr_l(&req.nh, sizeof(req), CGW_COUNTER, &msgcounter, sizeof(msgcounter)); + if (have_cs_crc8) addattr_l(&req.nh, sizeof(req), CGW_CS_CRC8, &cs_crc8, sizeof(cs_crc8)); Signed-off by: Brad Drehmer <b.drehmer@xxxxxxxxxxxxxxxxx> TESTING THE FUTURE for OVER 20 YEARS NOTICE: This e-mail and any attachments may contain confidential, privileged and proprietary information of D & V Electronics Ltd. and all such material is subject to copyright protection in favor of D & V Electronics Ltd. Any unauthorized disclosure or other use of this e-mail or the information contained herein or in any documents attached hereto may be unlawful and is strictly prohibited. If you have received this e-mail in error, please notify the sender immediately and delete this e-mail without reading, printing, copying or forwarding it to anyone. This email was sent from D & V Electronics Ltd. To receive no further email communications, you can send an email to unsubscribe@xxxxxxxxxxxxxxxxx. D & V Electronics is located at 130 Zenway Blvd. Woodbridge, Ontario, Canada.