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>
29 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include <sys/socket.h>
44 #include <vdecommon.h>
51 static int ifd
,ofd
,nfd
;
52 VDECONN
*vconn
= NULL
;
57 struct vde_open_args open_args
={.port
=0,.group
=NULL
,.mode
=0700};
59 vconn
= vde_open(s
,"vde_over_ns",&open_args
);
61 fprintf(stderr
,"Fatal Error. Vdeplug %s: %s\n",s
,strerror(errno
));
64 ifd
= ofd
= vde_datafd(vconn
);
68 ifd
= STDIN_FILENO
, ofd
= STDOUT_FILENO
, nfd
= -1;
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");
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
))) {
89 fprintf(stderr
, "Using nameserver %s\n", ip
);
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");
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");
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");
117 fprintf(stderr
, "Permission denied binding port 53. You generally "
118 "have to be root to bind privileged ports.\n");
121 fprintf(stderr
, "Unexpected error: bind: %s\n", strerror(errno
));
126 fprintf(stderr
, "listening on 53/UDP\n");
129 struct nstxmsg
*nstx_select (int timeout
)
133 struct pollfd pfd
[2];
134 static struct nstxmsg
*ret
= NULL
;
138 pfd
[0].events
=pfd
[1].events
= POLLIN
| POLLHUP
;
140 pollret
=poll(pfd
,2,1000);
146 ret
= malloc(sizeof(struct nstxmsg
));
147 if (pfd
[0].revents
&POLLIN
) {
150 ret
->len
= vde_recv(vconn
,ret
->data
,MAXPKT
,0);
152 c
=read(ifd
,ret
->data
,2);
156 vde_len
+=((unsigned char)(ret
->data
[0]))<<8;
157 vde_len
+=(unsigned char)(ret
->data
[1]);
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);
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
);
178 pktdump("/tmp/nstx/pkt.", *((unsigned short *)ret
->data
),
179 ret
->data
, ret
->len
, 0);
192 send_vde(const char *data
, size_t len
)
194 static unsigned int outbuf
[MAXPKT
];
196 static u_int16_t outlen
;
200 vde_send(vconn
,data
,len
,0);
203 if(outp
==0 && (len
>=2) ){
205 outlen
+=(unsigned char)data
[1];
206 outlen
+=((unsigned char)(data
[0]))<<8;
210 write(ofd
,data
,outlen
);
211 send_vde(data
+outlen
,len
-outlen
);
215 memcpy(outbuf
+outp
,data
,len
);
218 write(ofd
,outbuf
,outlen
);
225 sendns (const char *data
, size_t len
, const struct sockaddr
*peer
)
228 sendto(nfd
, data
, len
, 0, peer
,
229 sizeof(struct sockaddr_in
));
231 send(nfd
, data
, len
, 0);
233 pktdump("/tmp/nstx/pkt.", *((unsigned short *)data
), data
, len
, 1);