1 /* ----------------------------------------------------------------------------
4 (C) 2007 Daniele Lacamera
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>
28 #include "compat/poll.h"
30 #include <sys/socket.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34 #include <sys/socket.h>
50 static int ifd
,ofd
,nfd
;
51 VDECONN
*vconn
= NULL
;
56 struct vde_open_args open_args
={.port
=0,.group
=NULL
,.mode
=0700};
58 vconn
= vde_open(s
,"vde_over_ns",&open_args
);
60 fprintf(stderr
,"Fatal Error. Vdeplug %s: %s\n",s
,strerror(errno
));
63 ifd
= ofd
= vde_datafd(vconn
);
67 ifd
= STDIN_FILENO
, ofd
= STDOUT_FILENO
, nfd
= -1;
71 open_ns(const char *ip
)
73 struct sockaddr_in sock
= { 0 };
75 fprintf(stderr
, "Opening nameserver-socket... ");
76 if ((nfd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
77 perror("failed!\nUnexpected error creating socket");
80 sock
.sin_family
= AF_INET
;
81 sock
.sin_port
= htons(53);
82 sock
.sin_addr
.s_addr
= inet_addr(ip
);
83 if (connect(nfd
, (struct sockaddr
*)&sock
,
84 sizeof(struct sockaddr_in
))) {
88 fprintf(stderr
, "Using nameserver %s\n", ip
);
92 open_ns_bind(in_addr_t bindip
)
94 struct sockaddr_in sock
= { 0 };
96 fprintf(stderr
, "Opening nameserver-socket... ");
97 if ((nfd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
98 perror("failed!\nUnexpected error creating socket");
101 sock
.sin_family
= AF_INET
;
102 sock
.sin_port
= htons(53);
104 sock
.sin_addr
.s_addr
= bindip
;
105 if (bind (nfd
, (struct sockaddr
*) &sock
, sizeof(struct sockaddr_in
))) {
106 fprintf(stderr
, "failed!\n");
109 fprintf(stderr
, "Address is in use, please kill other processes "
110 "listening on UDP-Port 53 on %s\n",
111 bindip
== INADDR_ANY
?
112 "all local IPs" : "the specified IP");
116 fprintf(stderr
, "Permission denied binding port 53. You generally "
117 "have to be root to bind privileged ports.\n");
120 fprintf(stderr
, "Unexpected error: bind: %s\n", strerror(errno
));
125 fprintf(stderr
, "listening on 53/UDP\n");
128 struct nstxmsg
*nstx_select (int timeout
)
132 struct pollfd pfd
[2];
133 static struct nstxmsg
*ret
= NULL
;
137 pfd
[0].events
=pfd
[1].events
= POLLIN
| POLLHUP
;
139 pollret
=poll(pfd
,2,1000);
145 ret
= malloc(sizeof(struct nstxmsg
));
146 if (pfd
[0].revents
&POLLIN
) {
149 ret
->len
= vde_recv(vconn
,ret
->data
,MAXPKT
,0);
151 c
=read(ifd
,ret
->data
,2);
155 vde_len
+=((unsigned char)(ret
->data
[0]))<<8;
156 vde_len
+=(unsigned char)(ret
->data
[1]);
159 while(ret
->len
< (vde_len
+ 2)){
160 ret
->len
+= read(ifd
, ret
->data
+ret
->len
, ((vde_len
+2) - ret
->len
));
163 // fprintf(stderr,"Read %d.\n",vde_len);
170 if (pfd
[1].revents
&POLLIN
) {
171 peerlen
= sizeof(struct sockaddr_in
);
172 ret
->len
= recvfrom(nfd
, ret
->data
, MAXPKT
, 0,
173 (struct sockaddr
*) &ret
->peer
, &peerlen
);
177 pktdump("/tmp/nstx/pkt.", *((unsigned short *)ret
->data
),
178 ret
->data
, ret
->len
, 0);
191 send_vde(const char *data
, size_t len
)
193 static unsigned int outbuf
[MAXPKT
];
195 static u_int16_t outlen
;
199 vde_send(vconn
,data
,len
,0);
202 if(outp
==0 && (len
>=2) ){
204 outlen
+=(unsigned char)data
[1];
205 outlen
+=((unsigned char)(data
[0]))<<8;
209 write(ofd
,data
,outlen
);
210 send_vde(data
+outlen
,len
-outlen
);
214 memcpy(outbuf
+outp
,data
,len
);
217 write(ofd
,outbuf
,outlen
);
224 sendns (const char *data
, size_t len
, const struct sockaddr
*peer
)
227 sendto(nfd
, data
, len
, 0, peer
,
228 sizeof(struct sockaddr_in
));
230 send(nfd
, data
, len
, 0);
232 pktdump("/tmp/nstx/pkt.", *((unsigned short *)data
), data
, len
, 1);