AF_NETBEUI is not defined in some FreeBSD/MACOSX versions. Fixed.
[vde.git] / vde-2 / src / kvde_switch / datasock.c
blobac14c5d1e3f8cc49e9209ae3539f82a8bdc9793f
1 /* Copyright 2005 Renzo Davoli - VDE-2
2 * --pidfile/-p and cleanup management by Mattia Belletti (C) 2004.
3 * Licensed under the GPLv2
4 * Modified by Ludovico Gardenghi 2005
5 * -g option (group management) by Daniel P. Berrange
6 * dir permission patch by Alessio Caprari 2006
7 */
9 #include <stdio.h>
10 #include <fcntl.h>
11 #include <errno.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include <syslog.h>
15 #include <stdlib.h>
16 #include <stdint.h>
17 #include <libgen.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <sys/ioctl.h>
21 #include <sys/socket.h>
22 #include <sys/types.h>
23 #include <sys/un.h>
24 #include <net/if.h>
25 #include <stdarg.h>
26 #include <limits.h>
27 #include <grp.h>
28 #define _GNU_SOURCE
29 #include <getopt.h>
31 #include <config.h>
32 #include <vde.h>
33 #include <vdecommon.h>
35 #include "../vde_switch/switch.h"
36 #include "sockutils.h"
37 #include "consmgmt.h"
39 /* will be inserted in a af_ipn.h include */
40 #ifndef AF_IPN
41 #define AF_IPN 34 /* IPN sockets */
42 #define PF_IPN AF_IPN
43 #endif
44 #ifndef AF_NETBEUI
45 #ifdef PF_NETBEUI
46 #define AF_NETBEUI PF_NETBEUI
47 #else
48 #define AF_NETBEUI 13
49 #endif
50 #endif
51 #define AF_IPN_STOLEN AF_NETBEUI /* IPN temporary sockets */
52 #define PF_IPN_STOLEN AF_IPN_STOLEN
54 #define IPN_ANY 0
55 #define IPN_BROADCAST 1
56 #define IPN_HUB 1
57 #define IPN_VDESWITCH 2
58 #define IPN_VDESWITCH_L3 3
60 #define IPN_SO_PREBIND 0x80
61 #define IPN_SO_PORT 0
62 #define IPN_SO_DESCR 1
63 #define IPN_SO_CHANGE_NUMNODES 2
64 #define IPN_SO_HANDLE_OOB 3
65 #define IPN_SO_WANT_OOB_NUMNODES 4
66 #define IPN_SO_MTU (IPN_SO_PREBIND | 0)
67 #define IPN_SO_NUMNODES (IPN_SO_PREBIND | 1)
68 #define IPN_SO_MSGPOOLSIZE (IPN_SO_PREBIND | 2)
69 #define IPN_SO_FLAGS (IPN_SO_PREBIND | 3)
70 #define IPN_SO_MODE (IPN_SO_PREBIND | 4)
72 #define IPN_PORTNO_ANY -1
74 #define IPN_DESCRLEN 128
76 #define IPN_FLAG_LOSSLESS 1
77 #define IPN_FLAG_TERMINATED 0x1000
79 #define IPN_NODEFLAG_TAP 0x10 /* This is a tap interface */
80 #define IPN_NODEFLAG_GRAB 0x20 /* This is a grab of a real interface */
82 /* Ioctl defines */
83 #define IPN_SETPERSIST_NETDEV _IOW('I', 200, int)
84 #define IPN_CLRPERSIST_NETDEV _IOW('I', 201, int)
85 #define IPN_CONN_NETDEV _IOW('I', 202, int)
86 #define IPN_JOIN_NETDEV _IOW('I', 203, int)
87 #define IPN_SETPERSIST _IOW('I', 204, int)
89 static struct swmodule swmi;
90 static unsigned int ctl_type;
91 static int mode = 0700;
93 static char real_ctl_socket[PATH_MAX];
94 static char *ctl_socket = real_ctl_socket;
95 static gid_t grp_owner = -1;
97 #define MODULENAME "kernel module interface"
99 static void handle_input(unsigned char type,int fd,int revents,int *arg)
101 /*here OOB messages will be delivered for debug options */
104 static void cleanup(unsigned char type,int fd,int arg)
106 unlink(ctl_socket);
109 static struct option long_options[] = {
110 {"sock", 1, 0, 's'},
111 {"vdesock", 1, 0, 's'},
112 {"unix", 1, 0, 's'},
113 {"mod", 1, 0, 'm'},
114 {"group", 1, 0, 'g'},
115 {"tap", 1, 0, 't'},
116 {"grab", 1, 0, 'g'},
120 #define Nlong_options (sizeof(long_options)/sizeof(struct option));
122 static void usage(void)
124 printf(
125 "(opts from datasock module)\n"
126 " -s, --sock SOCK control directory pathname\n"
127 " -s, --vdesock SOCK Same as --sock SOCK\n"
128 " -s, --unix SOCK Same as --sock SOCK\n"
129 " -m, --mod MODE Standard access mode for comm sockets (octal)\n"
130 " -g, --group GROUP Group owner for comm sockets\n"
131 " -t, --tap TAP Enable routing through TAP tap interface\n"
132 " -G, --grab INT Enable routing grabbing an existing interface\n");
135 struct extinterface {
136 char type;
137 char *name;
138 struct extinterface *next;
141 static struct extinterface *extifhead;
142 static struct extinterface **extiftail=&extifhead;
144 static void addextinterface(char type,char *name)
146 struct extinterface *new=malloc(sizeof (struct extinterface));
147 if (new) {
148 new->type=type;
149 new->name=strdup(name);
150 new->next=NULL;
151 *extiftail=new;
152 extiftail=&(new->next);
156 static void runextinterfaces(int kvdefd)
158 struct extinterface *iface,*oldiface;
159 struct ifreq ifr;
160 for (iface=extifhead;iface != NULL;iface=oldiface)
162 memset(&ifr, 0, sizeof(ifr));
163 strncpy(ifr.ifr_name,iface->name,IFNAMSIZ);
164 if (iface->type == 't')
165 ifr.ifr_flags=IPN_NODEFLAG_TAP;
166 else
167 ifr.ifr_flags=IPN_NODEFLAG_GRAB;
168 // printf("ioctl\n");
169 if (ioctl(kvdefd, IPN_CONN_NETDEV, (void *) &ifr) < 0) {
170 printlog(LOG_ERR, "%s interface %s error: %s", iface->name,
171 (iface->type == 't')?"tap":"grab",strerror(errno));
172 exit(-1);
174 free(iface->name);
175 oldiface=iface->next;
176 free(iface);
178 extifhead=NULL;
181 static int parseopt(int c, char *optarg)
183 int outc=0;
184 struct group *grp;
185 switch (c) {
186 case 's':
187 /* This should returns NULL as the path probably does not exist */
188 vde_realpath(optarg, ctl_socket);
189 break;
190 case 'm':
191 sscanf(optarg,"%o",&mode);
192 break;
193 case 'g':
194 if (!(grp = getgrnam(optarg))) {
195 printlog(LOG_ERR, "No such group '%s'", optarg);
196 exit(1);
198 grp_owner=grp->gr_gid;
199 break;
200 case 't':
201 case 'G':
202 addextinterface(c,optarg);
203 break;
204 default:
205 outc=c;
207 return outc;
210 static void init(void)
212 int kvdefd;
213 struct sockaddr_un sun;
214 int family = AF_IPN;
215 kvdefd = socket(AF_IPN,SOCK_RAW,IPN_VDESWITCH);
216 if (kvdefd < 0) {
217 family=AF_IPN_STOLEN;
218 kvdefd = socket(AF_IPN_STOLEN,SOCK_RAW,IPN_VDESWITCH);
219 if (kvdefd < 0) {
220 printlog(LOG_ERR,"kvde_switch requires ipn and kvde_switch kernel modules loaded");
221 exit(-1);
224 sun.sun_family = family;
225 snprintf(sun.sun_path,sizeof(sun.sun_path),"%s",ctl_socket);
226 if(bind(kvdefd, (struct sockaddr *) &sun, sizeof(sun)) < 0) {
227 printlog(LOG_ERR,"cannot bind socket %s",ctl_socket);
228 exit(-1);
230 if(chmod(ctl_socket, mode) <0) {
231 printlog(LOG_ERR, "chmod: %s", strerror(errno));
232 exit(1);
234 if(chown(ctl_socket,-1,grp_owner) < 0) {
235 printlog(LOG_ERR, "chown: %s", strerror(errno));
236 exit(1);
238 runextinterfaces(kvdefd);
239 add_fd(kvdefd,ctl_type,-1);
242 static int showinfo(FILE *fd)
244 printoutc(fd,"ctl dir %s",ctl_socket);
245 printoutc(fd,"std mode 0%03o",mode);
246 return 0;
249 static struct comlist cl[]={
250 {"ds","============","DATA SOCKET MENU",NULL,NOARG},
251 {"ds/showinfo","","show ds info",showinfo,NOARG|WITHFILE},
255 static void delep (int fd, void* data, void *descr)
257 if (fd>=0) remove_fd(fd);
258 if (data) free(data);
259 if (descr) free(descr);
263 void start_datasock(void)
265 strcpy(ctl_socket,(geteuid()==0)?VDESTDSOCK:VDETMPSOCK);
266 swmi.swmnopts=Nlong_options;
267 swmi.swmopts=long_options;
268 swmi.usage=usage;
269 swmi.parseopt=parseopt;
270 swmi.init=init;
271 swmi.handle_input=handle_input;
272 swmi.cleanup=cleanup;
273 ADDCL(cl);
274 add_swm(&swmi);