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 -------------------------------------------------------------------------- */
31 #include <sys/types.h>
32 #include <sys/socket.h>
34 #include <netinet/in.h>
39 static struct nstx_item
* get_item_by_id(unsigned int id
);
40 static struct nstx_item
* alloc_item(unsigned int id
);
41 static char * dealloc_item(struct nstx_item
*ptr
, int *l
);
42 static int add_data(struct nstx_item
*item
, struct nstxhdr
*pkt
, int datalen
);
43 static void check_timeouts(void);
45 static struct nstx_item
*nstx_list
= NULL
;
48 nstx_handlepacket(const char *ptr
, size_t len
,
49 void (*nstx_usepacket
)(const char*, size_t))
51 struct nstxhdr
*nstxpkt
= (struct nstxhdr
*) ptr
;
52 struct nstx_item
*nstxitem
;
56 if ((!ptr
) || (signed int) len
< (signed int) sizeof(struct nstxhdr
))
62 nstxitem
= get_item_by_id(nstxpkt
->id
);
65 nstxitem
= alloc_item(nstxpkt
->id
);
67 if (add_data(nstxitem
, nstxpkt
, len
)) {
68 netpacket
= dealloc_item(nstxitem
, &netpacketlen
);
69 nstx_usepacket(netpacket
, netpacketlen
);
74 static struct nstx_item
* get_item_by_id(unsigned int id
) {
75 struct nstx_item
*ptr
= nstx_list
;
88 static struct nstx_item
* alloc_item(unsigned int id
) {
89 struct nstx_item
*ptr
;
91 ptr
= malloc(sizeof(struct nstx_item
));
92 memset(ptr
, 0, sizeof(struct nstx_item
));
93 ptr
->next
= nstx_list
;
95 ptr
->next
->prev
= ptr
;
102 static char * dealloc_item(struct nstx_item
*ptr
, int *l
) {
103 static char *data
= NULL
;
105 struct clist
*c
, *tmp
;
108 ptr
->prev
->next
= ptr
->next
;
110 nstx_list
= ptr
->next
;
112 ptr
->next
->prev
= ptr
->prev
;
116 data
= realloc(data
, len
+c
->len
);
117 memcpy(data
+len
, c
->data
, c
->len
);
131 static void add_data_chunk(struct nstx_item
*item
, int seq
,
132 char *data
, int len
) {
133 struct clist
*next
, *prev
, *ptr
;
137 ptr
= item
->chunks
= malloc(sizeof(struct clist
));
138 else if (item
->chunks
->seq
== seq
)
140 else if (item
->chunks
->seq
> seq
) {
142 ptr
= item
->chunks
= malloc(sizeof(struct clist
));
145 while (prev
->next
&& (prev
->next
->seq
< seq
))
148 if (next
&& (next
->seq
== seq
))
150 ptr
= malloc(sizeof(struct clist
));
152 memset(ptr
, 0, sizeof(struct clist
));
158 ptr
->data
= malloc(len
);
159 memcpy(ptr
->data
, data
, len
);
162 static int find_sequence (struct nstx_item
*item
) {
166 for (i
= 0, list
= item
->chunks
; list
; i
++, list
= list
->next
)
173 static int add_data(struct nstx_item
*item
, struct nstxhdr
*pkt
, int datalen
) {
176 payload
= ((char *) pkt
) + sizeof(struct nstxhdr
);
177 item
->timestamp
= time(NULL
);
178 if (pkt
->flags
& NSTX_LF
) {
179 item
->frc
= pkt
->seq
+1;
182 add_data_chunk(item
, pkt
->seq
, payload
, datalen
-sizeof(struct nstxhdr
));
183 if (item
->frc
&& (find_sequence(item
) == item
->frc
)) {
189 static void check_timeouts(void) {
191 struct nstx_item
*ptr
= nstx_list
, *ptr2
;
198 if (now
> (ptr2
->timestamp
+ NSTX_TIMEOUT
)) {
199 dealloc_item(ptr2
, NULL
);