upgraded to vde 2.1.0
[vde.git] / vde / vdetaplib / vdetap.c
blob3c1997f48528aba2151f938fcbd0de3c2bae2537
1 /* Copyright 2004 Renzo Davoli
2 * Reseased under the GPLv2 */
4 #include <config.h>
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <sys/select.h>
8 #include <sys/poll.h>
9 #include <sys/socket.h>
10 #include <sys/un.h>
12 #define SWITCH_MAGIC 0xfeedface
13 #define BUFSIZE 2048
15 enum request_type { REQ_NEW_CONTROL };
16 struct request_v3 {
17 uint32_t magic;
18 uint32_t version;
19 enum request_type type;
20 struct sockaddr_un sock;
23 static unsigned char bufin[BUFSIZE];
25 static int send_fd(char *name, int fddata, struct sockaddr_un *datasock, int intno, int group)
27 int pid = getpid();
28 struct request_v3 req;
29 int fdctl;
31 struct sockaddr_un sock;
33 if((fdctl = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
34 perror("socket");
35 exit(1);
38 sock.sun_family = AF_UNIX;
39 snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
40 if(connect(fdctl, (struct sockaddr *) &sock, sizeof(sock))){
41 perror("connect");
42 exit(1);
45 req.magic=SWITCH_MAGIC;
46 req.version=3;
47 req.type=REQ_NEW_CONTROL+((group > 0)?((geteuid()<<8) + group) << 8:0);
49 req.sock.sun_family=AF_UNIX;
50 memset(req.sock.sun_path, 0, sizeof(req.sock.sun_path));
51 sprintf(&req.sock.sun_path[1], "%5d-%2d", pid, intno);
53 if(bind(fddata, (struct sockaddr *) &req.sock, sizeof(req.sock)) < 0){
54 perror("bind");
55 exit(1);
58 if (send(fdctl,&req,sizeof(req),0) < 0) {
59 perror("send");
60 exit(1);
63 if (recv(fdctl,datasock,sizeof(struct sockaddr_un),0)<0) {
64 perror("recv");
65 exit(1);
68 return fdctl;
71 static struct pollfd pollv[]={{0,POLLIN|POLLHUP,0},{0,POLLIN|POLLHUP,0}};
73 main(int argc,char *argv[])
75 int fd,fddata;
76 struct sockaddr_un dataout,datain;
77 int datainsize,result,nx;
78 register int i;
79 /*printf("argc = %d\n",argc);
80 for (i=0;i<argc;i++)
81 printf("argv %d -%s-\n",i,argv[i]);*/
82 if (argc != 3 && argv[0][0] != '-') {
83 fprintf(stderr,"vdetap must be activated by libvdetap e.g.\n"
84 " sh%% export LD_PRELOAD=/usr/local/lib/libvdetap.so\n"
85 " csh%% setenv LD_PRELOAD /usr/local/lib/libvdetap.so\n");
86 exit (-1);
89 fd = atoi(argv[1]);
90 for (i=3;i<FD_SETSIZE;i++)
91 if (i != fd)
92 close(i);
93 if((fddata = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0){
94 perror("socket");
95 exit(1);
97 send_fd(argv[2],fddata,&dataout,0,0);
98 pollv[0].fd=fd;
99 pollv[1].fd=fddata;
100 for(;;) {
101 result=poll(pollv,2,-1);
102 if (pollv[0].revents & POLLHUP || pollv[1].revents & POLLHUP)
103 break;
104 if (pollv[0].revents & POLLIN) {
105 nx=read(fd,bufin,sizeof(bufin));
106 /*fprintf(stderr,"RX from pgm %d\n",nx);*/
107 //send(connected_fd,bufin,nx,0);
108 sendto(fddata,bufin,nx,0,(struct sockaddr *) &dataout, sizeof(struct sockaddr_un));
110 if (pollv[1].revents & POLLIN) {
111 datainsize=sizeof(datain);
112 nx=recvfrom(fddata,bufin,BUFSIZE,0,(struct sockaddr *) &datain, &datainsize);
113 /*fprintf(stderr,"TX to pgm %d\n",nx);*/
114 write(fd,bufin,nx);