tagging vde-2 version 2.3.2
[vde.git] / 2.3.2 / src / vde_over_ns / vde_io.c
blobab3959dec8b5f3631a20773ef31e38f25af4df0e
1 /* ----------------------------------------------------------------------------
3 VDE_OVER_NS
4 (C) 2007 Daniele Lacamera
6 Derived from:
7 NSTX -- tunneling network-packets over DNS
9 (C) 2000 by Florian Heinz and Julien Oster
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License version 2, as
13 published by the Free Software Foundation.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 -------------------------------------------------------------------------- */
25 #include <sys/types.h>
26 #include <sys/ioctl.h>
27 #include <sys/time.h>
28 #include <sys/stat.h>
29 #include <sys/socket.h>
30 #include <net/if.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include <sys/socket.h>
34 #include <fcntl.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <errno.h>
40 #include <sysexits.h>
42 #include <config.h>
43 #include <vde.h>
44 #include <vdecommon.h>
46 #include "fun.h"
48 #define MAXPKT 2000
51 static int ifd,ofd,nfd;
52 VDECONN *vconn = NULL;
54 void
55 init_vdesock(char *s)
57 struct vde_open_args open_args={.port=0,.group=NULL,.mode=0700};
58 if(s){
59 vconn = vde_open(s,"vde_over_ns",&open_args);
60 if(!vconn){
61 fprintf(stderr,"Fatal Error. Vdeplug %s: %s\n",s,strerror(errno));
62 exit(1);
64 ifd = ofd = vde_datafd(vconn);
65 return;
68 ifd = STDIN_FILENO, ofd = STDOUT_FILENO, nfd = -1;
71 void
72 open_ns(const char *ip)
74 struct sockaddr_in sock = { 0 };
76 fprintf(stderr, "Opening nameserver-socket... ");
77 if ((nfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
78 perror("failed!\nUnexpected error creating socket");
79 exit(EX_OSERR);
81 sock.sin_family = AF_INET;
82 sock.sin_port = htons(53);
83 sock.sin_addr.s_addr = inet_addr(ip);
84 if (connect(nfd, (struct sockaddr *)&sock,
85 sizeof(struct sockaddr_in))) {
86 perror("connect");
87 exit(EXIT_FAILURE);
89 fprintf(stderr, "Using nameserver %s\n", ip);
92 void
93 open_ns_bind(in_addr_t bindip)
95 struct sockaddr_in sock = { 0 };
97 fprintf(stderr, "Opening nameserver-socket... ");
98 if ((nfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
99 perror("failed!\nUnexpected error creating socket");
100 exit(EX_OSERR);
102 sock.sin_family = AF_INET;
103 sock.sin_port = htons(53);
105 sock.sin_addr.s_addr = bindip;
106 if (bind (nfd, (struct sockaddr *) &sock, sizeof(struct sockaddr_in))) {
107 fprintf(stderr, "failed!\n");
108 switch (errno) {
109 case EADDRINUSE:
110 fprintf(stderr, "Address is in use, please kill other processes "
111 "listening on UDP-Port 53 on %s\n",
112 bindip == INADDR_ANY ?
113 "all local IPs" : "the specified IP");
114 break;
115 case EACCES:
116 case EPERM:
117 fprintf(stderr, "Permission denied binding port 53. You generally "
118 "have to be root to bind privileged ports.\n");
119 break;
120 default:
121 fprintf(stderr, "Unexpected error: bind: %s\n", strerror(errno));
122 break;
124 exit(EXIT_FAILURE);
126 fprintf(stderr, "listening on 53/UDP\n");
129 struct nstxmsg *nstx_select (int timeout)
131 unsigned peerlen;
132 int c,pollret;
133 struct pollfd pfd[2];
134 static struct nstxmsg *ret = NULL;
135 u_int16_t vde_len;
136 pfd[0].fd=ifd;
137 pfd[1].fd=nfd;
138 pfd[0].events=pfd[1].events= POLLIN | POLLHUP;
139 for(;;){
140 pollret=poll(pfd,2,1000);
141 if(pollret<0){
142 perror("poll");
143 exit(1);
145 if (!ret)
146 ret = malloc(sizeof(struct nstxmsg));
147 if (pfd[0].revents&POLLIN) {
149 if(vconn!=NULL){
150 ret->len = vde_recv(vconn,ret->data,MAXPKT,0);
151 }else{
152 c=read(ifd,ret->data,2);
153 if(c<2)
154 return NULL;
155 vde_len=0;
156 vde_len+=((unsigned char)(ret->data[0]))<<8;
157 vde_len+=(unsigned char)(ret->data[1]);
159 ret->len=2;
160 while(ret->len < (vde_len + 2)){
161 ret->len += read(ifd, ret->data+ret->len, ((vde_len+2) - ret->len));
164 // fprintf(stderr,"Read %d.\n",vde_len);
166 ret->src = FROMTUN;
167 return ret;
171 if (pfd[1].revents&POLLIN) {
172 peerlen = sizeof(struct sockaddr_in);
173 ret->len = recvfrom(nfd, ret->data, MAXPKT, 0,
174 (struct sockaddr *) &ret->peer, &peerlen);
175 if(ret->len > 0){
177 #ifdef WITH_PKTDUMP
178 pktdump("/tmp/nstx/pkt.", *((unsigned short *)ret->data),
179 ret->data, ret->len, 0);
180 #endif
181 ret->src = FROMNS;
182 return ret;
186 return NULL;
191 void
192 send_vde(const char *data, size_t len)
194 static unsigned int outbuf[MAXPKT];
195 static int outp;
196 static u_int16_t outlen;
197 if(len<=0)
198 return;
199 if (vconn!=NULL){
200 vde_send(vconn,data,len,0);
201 return;
203 if(outp==0 && (len >=2) ){
204 outlen=2;
205 outlen+=(unsigned char)data[1];
206 outlen+=((unsigned char)(data[0]))<<8;
209 if(len>=outlen){
210 write(ofd,data,outlen);
211 send_vde(data+outlen,len-outlen);
212 return;
215 memcpy(outbuf+outp,data,len);
216 outp+=len;
217 if(outp>=outlen){
218 write(ofd,outbuf,outlen);
219 outp=0;
224 void
225 sendns (const char *data, size_t len, const struct sockaddr *peer)
227 if (peer)
228 sendto(nfd, data, len, 0, peer,
229 sizeof(struct sockaddr_in));
230 else
231 send(nfd, data, len, 0);
232 #ifdef WITH_PKTDUMP
233 pktdump("/tmp/nstx/pkt.", *((unsigned short *)data), data, len, 1);
234 #endif