]> rtime.felk.cvut.cz Git - sojka/can-utils.git/blob - vcan.c
Changed color order at colorized output.
[sojka/can-utils.git] / vcan.c
1 /*
2  * a real quick'n'dirty hack to add/remove vcan interfaces.
3  * (also to have something to test the new RTNL API in vcan.)
4  * this will be added to ip(8) of the iproute package, making
5  * this hack obsolete.
6  * 
7  * we don't check the return value of sendto() and don't wait for
8  * a reply using recvmsg().  We just hope everything works fine,
9  * otherwise use strace, or feel free to add the code before this
10  * whole thing is dumped to the bit bucket.
11  *
12  * Parts of this code were taken from the iproute source.
13  *
14  * urs
15  */
16
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include <sys/socket.h>
23 #include <net/if.h>
24
25 #include <asm/types.h>
26 #include <linux/netlink.h>
27 #include <linux/rtnetlink.h>
28
29 //#include <linux/if_link.h>
30
31 #define IFLA_LINKINFO 18
32
33 enum
34 {
35     IFLA_INFO_UNSPEC,
36     IFLA_INFO_NAME,
37     IFLA_INFO_DATA,
38     IFLA_INFO_XSTATS,
39     __IFLA_INFO_MAX,
40 };
41
42 #define NLMSG_TAIL(nmsg) \
43         ((struct rtattr *)(((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
44
45 int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
46               int alen);
47
48 void usage()
49 {
50     fprintf(stderr, "Usage: vcan create\n"
51                     "       vcan delete iface\n");
52     exit(1);
53 }
54
55 int main(int argc, char **argv)
56 {
57     int s;
58     char *cmd, *dev;
59     struct {
60         struct nlmsghdr  n;
61         struct ifinfomsg i;
62         char             buf[1024];
63     } req;
64     struct sockaddr_nl nladdr;
65     struct rtattr *linkinfo;
66
67 #ifdef OBSOLETE
68     fprintf(stderr, "This program is a temporary hack and is now obsolete.\n"
69             "Please use ip(8) instead, i.e.\n"
70             "    ip link add type vcan       or\n"
71             "    ip link delete iface\n");
72     exit(1);
73 #endif
74     if (argc < 2)
75         usage();
76     cmd = argv[1];
77
78     s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
79
80     memset(&req, 0, sizeof(req));
81
82     if (strcmp(cmd, "create") == 0) {
83         req.n.nlmsg_len   = NLMSG_LENGTH(sizeof(struct ifinfomsg));
84         req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
85         req.n.nlmsg_type  = RTM_NEWLINK;
86         req.n.nlmsg_seq   = 0;
87         req.i.ifi_family  = AF_UNSPEC;
88
89         linkinfo = NLMSG_TAIL(&req.n);
90         addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
91         addattr_l(&req.n, sizeof(req), IFLA_INFO_NAME, "vcan", strlen("vcan"));
92         linkinfo->rta_len = (void*)NLMSG_TAIL(&req.n) - (void*)linkinfo;
93
94     } else if (strcmp(cmd, "delete") == 0) {
95         if (argc < 3)
96             usage();
97         dev = argv[2];
98         req.n.nlmsg_len   = NLMSG_LENGTH(sizeof(struct ifinfomsg));
99         req.n.nlmsg_flags = NLM_F_REQUEST;
100         req.n.nlmsg_type  = RTM_DELLINK;
101         req.i.ifi_family  = AF_UNSPEC;
102         req.i.ifi_index   = if_nametoindex(dev);
103     } else
104         usage();
105
106     memset(&nladdr, 0, sizeof(nladdr));
107     nladdr.nl_family = AF_NETLINK;
108     nladdr.nl_pid    = 0;
109     nladdr.nl_groups = 0;
110 #if 1
111     sendto(s, &req, req.n.nlmsg_len, 0,
112            (struct sockaddr*)&nladdr, sizeof(nladdr));
113 #else
114     {
115         int i;
116
117         for (i = 0; i < req.n.nlmsg_len; i++) {
118             printf(" %02x", ((unsigned char*)&req)[i]);
119             if (i % 16 == 15)
120                 putchar('\n');
121         }
122         putchar('\n');
123     }
124 #endif
125     close(s);
126
127     return 0;
128 }
129
130 int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
131               int alen)
132 {
133     int len = RTA_LENGTH(alen);
134     struct rtattr *rta;
135
136     if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
137         fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",
138                 maxlen);
139         return -1;
140     }
141     rta = NLMSG_TAIL(n);
142     rta->rta_type = type;
143     rta->rta_len = len;
144     memcpy(RTA_DATA(rta), data, alen);
145     n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
146     return 0;
147 }