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>
38 #include <vdecommon.h>
43 static struct nstx_item
* get_item_by_id(unsigned int id
);
44 static struct nstx_item
* alloc_item(unsigned int id
);
45 static char * dealloc_item(struct nstx_item
*ptr
, int *l
);
46 static int add_data(struct nstx_item
*item
, struct nstxhdr
*pkt
, int datalen
);
47 static void check_timeouts(void);
49 static struct nstx_item
*nstx_list
= NULL
;
52 nstx_handlepacket(const char *ptr
, size_t len
,
53 void (*nstx_usepacket
)(const char*, size_t))
55 struct nstxhdr
*nstxpkt
= (struct nstxhdr
*) ptr
;
56 struct nstx_item
*nstxitem
;
60 if ((!ptr
) || (signed int) len
< (signed int) sizeof(struct nstxhdr
))
66 nstxitem
= get_item_by_id(nstxpkt
->id
);
69 nstxitem
= alloc_item(nstxpkt
->id
);
71 if (add_data(nstxitem
, nstxpkt
, len
)) {
72 netpacket
= dealloc_item(nstxitem
, &netpacketlen
);
73 nstx_usepacket(netpacket
, netpacketlen
);
78 static struct nstx_item
* get_item_by_id(unsigned int id
) {
79 struct nstx_item
*ptr
= nstx_list
;
92 static struct nstx_item
* alloc_item(unsigned int id
) {
93 struct nstx_item
*ptr
;
95 ptr
= malloc(sizeof(struct nstx_item
));
96 memset(ptr
, 0, sizeof(struct nstx_item
));
97 ptr
->next
= nstx_list
;
99 ptr
->next
->prev
= ptr
;
106 static char * dealloc_item(struct nstx_item
*ptr
, int *l
) {
107 static char *data
= NULL
;
109 struct clist
*c
, *tmp
;
112 ptr
->prev
->next
= ptr
->next
;
114 nstx_list
= ptr
->next
;
116 ptr
->next
->prev
= ptr
->prev
;
120 data
= realloc(data
, len
+c
->len
);
121 memcpy(data
+len
, c
->data
, c
->len
);
135 static void add_data_chunk(struct nstx_item
*item
, int seq
,
136 char *data
, int len
) {
137 struct clist
*next
, *prev
, *ptr
;
141 ptr
= item
->chunks
= malloc(sizeof(struct clist
));
142 else if (item
->chunks
->seq
== seq
)
144 else if (item
->chunks
->seq
> seq
) {
146 ptr
= item
->chunks
= malloc(sizeof(struct clist
));
149 while (prev
->next
&& (prev
->next
->seq
< seq
))
152 if (next
&& (next
->seq
== seq
))
154 ptr
= malloc(sizeof(struct clist
));
156 memset(ptr
, 0, sizeof(struct clist
));
162 ptr
->data
= malloc(len
);
163 memcpy(ptr
->data
, data
, len
);
166 static int find_sequence (struct nstx_item
*item
) {
170 for (i
= 0, list
= item
->chunks
; list
; i
++, list
= list
->next
)
177 static int add_data(struct nstx_item
*item
, struct nstxhdr
*pkt
, int datalen
) {
180 payload
= ((char *) pkt
) + sizeof(struct nstxhdr
);
181 item
->timestamp
= time(NULL
);
182 if (pkt
->flags
& NSTX_LF
) {
183 item
->frc
= pkt
->seq
+1;
186 add_data_chunk(item
, pkt
->seq
, payload
, datalen
-sizeof(struct nstxhdr
));
187 if (item
->frc
&& (find_sequence(item
) == item
->frc
)) {
193 static void check_timeouts(void) {
195 struct nstx_item
*ptr
= nstx_list
, *ptr2
;
202 if (now
> (ptr2
->timestamp
+ NSTX_TIMEOUT
)) {
203 dealloc_item(ptr2
, NULL
);