2 * A real quick'n'dirty hack to add a netlink CAN gateway entry.
4 * Parts of this code were taken from the iproute source and the original
5 * vcan.c from Urs Thuermann.
7 * Oliver Hartkopp 2010-02-18
15 #include <sys/socket.h>
18 #include <asm/types.h>
19 #include <linux/netlink.h>
20 #include <linux/rtnetlink.h>
21 #include <socketcan/can/gw.h>
23 #include <linux/if_link.h>
25 #define NLMSG_TAIL(nmsg) \
26 ((struct rtattr *)(((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
28 int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
31 int len = RTA_LENGTH(alen);
34 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
35 fprintf(stderr, "addattr_l: message exceeded bound of %d\n",
42 memcpy(RTA_DATA(rta), data, alen);
43 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
47 int main(int argc, char **argv)
59 struct can_filter filter;
60 struct sockaddr_nl nladdr;
62 struct cgw_frame_mod modmsg;
64 u_int32_t src = if_nametoindex("vcan2");
65 u_int32_t dst = if_nametoindex("vcan3");
67 s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
69 memset(&req, 0, sizeof(req));
71 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtcanmsg));
72 req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
73 req.n.nlmsg_type = RTM_NEWROUTE;
76 req.r.can_family = AF_CAN;
77 req.r.gwtype = CGW_TYPE_CAN_CAN;
78 req.r.flags = CGW_FLAGS_CAN_ECHO;
80 addattr_l(&req.n, sizeof(req), CGW_SRC_IF, &src, sizeof(src));
81 addattr_l(&req.n, sizeof(req), CGW_DST_IF, &dst, sizeof(dst));
83 /* add new attributes here */
85 filter.can_id = 0x400;
86 filter.can_mask = 0x700;
88 addattr_l(&req.n, sizeof(req), CGW_FILTER, &filter, sizeof(filter));
90 if (sizeof(modmsg) != CGW_MODATTR_LEN) {
91 printf("Problem with packed msg. Use linear copy instead.\n");
95 modmsg.cf.can_id = 0x555;
96 modmsg.cf.can_dlc = 5;
97 *(unsigned long long *)modmsg.cf.data = 0x5555555555555555ULL;
99 modmsg.modtype = CGW_MOD_ID;
100 addattr_l(&req.n, sizeof(req), CGW_MOD_SET, &modmsg, CGW_MODATTR_LEN);
102 modmsg.modtype = CGW_MOD_DLC;
103 addattr_l(&req.n, sizeof(req), CGW_MOD_AND, &modmsg, CGW_MODATTR_LEN);
105 modmsg.modtype = CGW_MOD_DATA;
106 addattr_l(&req.n, sizeof(req), CGW_MOD_XOR, &modmsg, CGW_MODATTR_LEN);
108 memset(&nladdr, 0, sizeof(nladdr));
109 nladdr.nl_family = AF_NETLINK;
111 nladdr.nl_groups = 0;
113 err = sendto(s, &req, req.n.nlmsg_len, 0,
114 (struct sockaddr*)&nladdr, sizeof(nladdr));
116 perror("netlink says ");