]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - can-utils/vcan.c
90bd36d97919ef6d546a85c3a35b87d1a4828b9e
[socketcan-devel.git] / can-utils / 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 #if 0
32 #define IFLA_LINKINFO 18
33
34 enum
35 {
36         IFLA_INFO_UNSPEC,
37         IFLA_INFO_NAME,
38         IFLA_INFO_DATA,
39         IFLA_INFO_XSTATS,
40         __IFLA_INFO_MAX,
41 };
42 #endif
43
44 #define NLMSG_TAIL(nmsg)                                                \
45         ((struct rtattr *)(((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
46
47 int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
48               int alen);
49
50 void usage()
51 {
52         fprintf(stderr, "Usage: vcan create\n"
53                 "       vcan delete iface\n");
54         exit(1);
55 }
56
57 int main(int argc, char **argv)
58 {
59         int s;
60         char *cmd, *dev;
61         struct {
62                 struct nlmsghdr  n;
63                 struct ifinfomsg i;
64                 char             buf[1024];
65         } req;
66         struct sockaddr_nl nladdr;
67         struct rtattr *linkinfo;
68
69 #ifdef OBSOLETE
70         fprintf(stderr, "This program is a temporary hack and is now obsolete.\n"
71                 "Please use ip(8) instead, i.e.\n"
72                 "    ip link add type vcan       or\n"
73                 "    ip link delete iface\n");
74         exit(1);
75 #endif
76         if (argc < 2)
77                 usage();
78         cmd = argv[1];
79
80         s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
81
82         memset(&req, 0, sizeof(req));
83
84         if (strcmp(cmd, "create") == 0) {
85                 req.n.nlmsg_len   = NLMSG_LENGTH(sizeof(struct ifinfomsg));
86                 req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
87                 req.n.nlmsg_type  = RTM_NEWLINK;
88                 req.n.nlmsg_seq   = 0;
89                 req.i.ifi_family  = AF_UNSPEC;
90
91                 linkinfo = NLMSG_TAIL(&req.n);
92                 addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
93                 addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, "vcan", strlen("vcan"));
94                 linkinfo->rta_len = (void*)NLMSG_TAIL(&req.n) - (void*)linkinfo;
95
96         } else if (strcmp(cmd, "delete") == 0) {
97                 if (argc < 3)
98                         usage();
99                 dev = argv[2];
100                 req.n.nlmsg_len   = NLMSG_LENGTH(sizeof(struct ifinfomsg));
101                 req.n.nlmsg_flags = NLM_F_REQUEST;
102                 req.n.nlmsg_type  = RTM_DELLINK;
103                 req.i.ifi_family  = AF_UNSPEC;
104                 req.i.ifi_index   = if_nametoindex(dev);
105         } else
106                 usage();
107
108         memset(&nladdr, 0, sizeof(nladdr));
109         nladdr.nl_family = AF_NETLINK;
110         nladdr.nl_pid    = 0;
111         nladdr.nl_groups = 0;
112 #if 1
113         sendto(s, &req, req.n.nlmsg_len, 0,
114                (struct sockaddr*)&nladdr, sizeof(nladdr));
115 #else
116         {
117                 int i;
118
119                 for (i = 0; i < req.n.nlmsg_len; i++) {
120                         printf(" %02x", ((unsigned char*)&req)[i]);
121                         if (i % 16 == 15)
122                                 putchar('\n');
123                 }
124                 putchar('\n');
125         }
126 #endif
127         close(s);
128
129         return 0;
130 }
131
132 int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
133               int alen)
134 {
135         int len = RTA_LENGTH(alen);
136         struct rtattr *rta;
137
138         if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
139                 fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",
140                         maxlen);
141                 return -1;
142         }
143         rta = NLMSG_TAIL(n);
144         rta->rta_type = type;
145         rta->rta_len = len;
146         memcpy(RTA_DATA(rta), data, alen);
147         n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
148         return 0;
149 }