/* * Send a virtual frame to the vde_plug process associated * with the peer */ void send_vdeplug(const char *data, size_t len, struct peer *p) { static unsigned int outbuf[MAXPKT]; static int outp=0; static u_int16_t outlen; if(len<=0) return; if(outp==0 && (len >=2) ){ outlen=2; outlen+=(unsigned char)data[1]; outlen+=((unsigned char)(data[0]))<<8; } if(len>=outlen){ vde_send(p->plug,data,outlen,0); send_vdeplug(data+outlen,len-outlen, p); return; } memcpy(outbuf+outp,data,len); outp+=len; if(outp>=outlen){ vde_send(p->plug,(char *)outbuf,outlen,0); } vc_printlog(3,"VDE - Sent a %dB datagram.",outlen); }
int vde_user_write(void *conn, void *buf, int len) { VDECONN *vconn = conn; if (vconn == NULL) return 0; return vde_send(vconn, buf, len, 0); }
ssize_t vdeplug_recv(void *opaque, void *buf, size_t count) { VDECONN *conn=opaque; #ifdef VDE_IP_LOG if (vde_ip_log) vde_ip_check(buf,count); #endif return vde_send(conn,(char *)buf,count,0); }
static int pico_vde_send(struct pico_device *dev, void *buf, int len) { struct pico_device_vde *vde = (struct pico_device_vde *) dev; //printf("[%s] send %d bytes.\n", dev->name, len); if ((vde->lost_out == 0) || ((pico_rand() % 100) > vde->lost_out)) return (int)vde_send(vde->conn, buf, (uint32_t)len, 0); else return len; /* Silently discarded "on the wire" */ }
static ssize_t vde_receive(NetClientState *nc, const uint8_t *buf, size_t size) { VDEState *s = DO_UPCAST(VDEState, nc, nc); ssize_t ret; do { ret = vde_send(s->vde, (const char *)buf, size, 0); } while (ret < 0 && errno == EINTR); return ret; }
int main(int argc, char **argv) { static char *sockname=NULL; static char *tapname=NULL; int daemonize=0; int tapfd; register ssize_t nx; struct vde_open_args open_args={.port=0,.group=NULL,.mode=0700}; int c; static struct pollfd pollv[]={{0,POLLIN|POLLHUP}, {0,POLLIN|POLLHUP}, {0,POLLIN|POLLHUP}}; int npollv; prog=argv[0]; while (1) { int option_index = 0; static struct option long_options[] = { {"sock", 1, 0, 's'}, {"port", 1, 0, 'p'}, {"help",0,0,'h'}, {"mod",1,0,'m'}, {"group",1,0,'g'}, {"daemon",0,0,'d'}, {"pidfile", 1, 0, 'P'}, {0, 0, 0, 0} }; c = GETOPT_LONG (argc, argv, "hdP:p:s:m:g:", long_options, &option_index); if (c == -1) break; switch (c) { case 'p': open_args.port=atoi(optarg); if (open_args.port <= 0) usage(); //implies exit break; case 'h': usage(); //implies exit break; case 's': sockname=strdup(optarg); break; case 'm': sscanf(optarg,"%o",(unsigned int *)&(open_args.mode)); break; case 'g': open_args.group=strdup(optarg); break; case 'd': daemonize=1; break; case 'P': pidfile=strdup(optarg); break; default: usage(); //implies exit } } if (daemonize) { openlog(basename(prog), LOG_PID, 0); logok=1; syslog(LOG_INFO,"VDE_PLUG2TAP started"); } /* saves current path in pidfile_path, because otherwise with daemonize() we * forget it */ if(getcwd(pidfile_path, PATH_MAX-1) == NULL) { printlog(LOG_ERR, "getcwd: %s", strerror(errno)); exit(1); } strcat(pidfile_path, "/"); if (daemonize && daemon(0, 0)) { printlog(LOG_ERR,"daemon: %s",strerror(errno)); exit(1); } /* once here, we're sure we're the true process which will continue as a * server: save PID file if needed */ if(pidfile) save_pidfile(); if (optind < argc) tapname=argv[optind]; else usage(); // implies exit atexit(cleanup); setsighandlers(); tapfd=open_tap(tapname); if(tapfd<0) exit(1); pollv[0].fd=tapfd; if (sockname==NULL || strcmp(sockname,"-") != 0) { conn=vde_open(sockname,"vde_plug2tap:",&open_args); if (conn == NULL) { printlog(LOG_ERR,"vde_open %s: %s",sockname?sockname:"DEF_SWITCH",strerror(errno)); exit(1); } pollv[1].fd=vde_datafd(conn); pollv[2].fd=vde_ctlfd(conn); npollv=3; } else { vdestream=vdestream_open(&tapfd,STDOUT_FILENO,vde_plug2tap_recv,NULL); if (vdestream == NULL) exit(1); pollv[1].fd=STDIN_FILENO; npollv=2; } for(;;) { poll(pollv,3,-1); if ((pollv[0].revents | pollv[1].revents | pollv[2].revents) & POLLHUP || (npollv > 2 && pollv[2].revents & POLLIN)) break; if (pollv[0].revents & POLLIN) { nx=read(tapfd,bufin,sizeof(bufin)); /* if POLLIN but not data it means that the stream has been * closed at the other end */ //fprintf(stderr,"%s: RECV %d %x %x \n",prog,nx,bufin[0],bufin[1]); if (nx<=0) break; if (conn != NULL) vde_send(conn,bufin,nx,0); else vdestream_send(vdestream, bufin, nx); } if (pollv[1].revents & POLLIN) { if (conn != NULL) { nx=vde_recv(conn,bufin,sizeof(bufin),0); if (nx<=0) break; write(tapfd,bufin,nx); } else { nx=read(STDIN_FILENO,bufin,sizeof(bufin)); if (nx<=0) break; vdestream_recv(vdestream,bufin,nx); } //fprintf(stderr,"%s: SENT %d %x %x \n",prog,nx,bufin[0],bufin[1]); } } return(0); }
static int pico_vde_send(struct pico_device *dev, void *buf, int len) { struct pico_device_vde *vde = (struct pico_device_vde *) dev; /* dbg("[%s] send %d bytes.\n", dev->name, len); */ return vde_send(vde->conn, buf, len, 0); }