summaryrefslogtreecommitdiff
path: root/exploits/7350855/packet.c
diff options
context:
space:
mode:
authorRoot THC2026-02-24 12:42:47 +0000
committerRoot THC2026-02-24 12:42:47 +0000
commitc9cbeced5b3f2bdd7407e29c0811e65954132540 (patch)
treeaefc355416b561111819de159ccbd86c3004cf88 /exploits/7350855/packet.c
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'exploits/7350855/packet.c')
-rw-r--r--exploits/7350855/packet.c487
1 files changed, 487 insertions, 0 deletions
diff --git a/exploits/7350855/packet.c b/exploits/7350855/packet.c
new file mode 100644
index 0000000..686ad81
--- /dev/null
+++ b/exploits/7350855/packet.c
@@ -0,0 +1,487 @@
1/* packet handling functions (originally from zodiac)
2 *
3 * packet handling and queueing routines
4 * by scut
5 *
6 * -Smiler
7 * Changed pq_grind to remove link layer. Changed other functions to
8 * accept ip packets instead of ethernet packets.
9 */
10
11#include <sys/types.h>
12#include <sys/socket.h>
13#include <sys/time.h>
14#include <netinet/in.h>
15#include <arpa/inet.h>
16#include <unistd.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <semaphore.h>
21#include <pthread.h>
22#include <pcap.h>
23#include "common.h"
24#include "packet.h"
25#include "sniff.h"
26
27
28struct in_addr localip;
29
30
31/* watching data. should be set before any pq_* functions are active
32 */
33pthread_mutex_t watch_mutex = PTHREAD_MUTEX_INITIALIZER;
34
35int watch = 0;
36struct in_addr watch_ipsrc,
37 watch_ipdst;
38unsigned long int watch_src_seq,
39 watch_dst_seq;
40unsigned long int watch_src_ack,
41 watch_dst_ack;
42unsigned short int watch_sport,
43 watch_dport;
44
45/* pq_grind
46 *
47 * grind the packets received from the sniffer thread, stripping ethernet
48 * header, filter non-TCP packets, add them to the packet queue, then raise
49 * the correct semaphore.
50 *
51 * `sinfo' gives information about the sniffing thread and the packet queue,
52 * `pkthdr' is from the pcap handler and `pkt' contains the real packet data.
53 */
54
55void
56pq_grind (void *sinfov, struct pcap_pkthdr *pkthdr, u_char *pkt)
57{
58 sniff_info * sinfo = (sniff_info *) sinfov;
59
60
61 if (sinfo->device->linktype == DLT_EN10MB) {
62 if (((eth_hdr *) pkt)->ether_type != htons (ETHERTYPE_IP))
63 goto pq_glend;
64 }
65 pkt += sinfo->device->linkhdrlen;
66 pkthdr->caplen -= sinfo->device->linkhdrlen;
67
68 if (pq_filter (pkt, pkthdr->caplen) == 0)
69 goto pq_glend;
70
71 /* update connection table
72 */
73#if 0
74 /* compute real IP/TCP packet size and append it to the right queue
75 */
76 if (pq_add (pkt, pkthdr->caplen, &pkthdr->ts, sinfo->pq_thd))
77 goto pq_glend;
78#endif
79
80 /* notify the corresponding thread about the new packet in it's queue
81 */
82 pq_notify (sinfo->pq_thd);
83
84pq_glend:
85 return;
86}
87
88
89/* pq_add
90 *
91 * append a packet queue description (pq_desc) with packet content `p_data' to
92 * the packet queue associated with thread `thd'.
93 * the packet data is copied, so the packet data pointer `p_data' has to be
94 * freed by the calling function. the time value `rcv_time' is the time when the
95 * packet was sniffed from the pcap library.
96 *
97 * return 0 on success
98 * will never fail tho ;-D
99 */
100
101int
102pq_add (unsigned char *p_data, unsigned long int p_size,
103 struct timeval *rcv_time, pq_thread *pqt)
104{
105 pq_desc * np; /* new packet in queue */
106
107
108 np = xcalloc (1, sizeof (pq_desc));
109
110 /* initialize the packet mutex and get hold of it
111 */
112 pthread_mutex_init (&np->pq_mutex, NULL);
113 pthread_mutex_lock (&np->pq_mutex);
114
115 /* get memory for the packet
116 */
117 np->p_len = p_size;
118 np->p_data = xcalloc (1, np->p_len);
119
120 /* copy packet data, create hash and copy time values
121 */
122 memcpy (np->p_data, p_data, np->p_len);
123 np->next = NULL;
124 memcpy (&np->rcv_time, rcv_time, sizeof (struct timeval));
125
126 /* now add the packet to the thread queue
127 */
128 pthread_mutex_lock (&pqt->pq_mutex);
129
130 /* no packet added yet, then just modify the root pointer, else
131 * append the packet
132 */
133 if (pqt->root == NULL) {
134 pqt->root = np;
135 } else {
136 pq_desc *cur = pqt->root; /* help pointers to step through the list */
137 pq_desc *last = pqt->root;
138
139 /* cycle through linked list, until end is reached
140 */
141 while (cur != NULL) {
142 last = cur;
143
144 pthread_mutex_lock (&last->pq_mutex);
145 cur = last->next;
146 pthread_mutex_unlock (&last->pq_mutex);
147 }
148
149 pthread_mutex_lock (&last->pq_mutex);
150 last->next = np;
151 pthread_mutex_unlock (&last->pq_mutex);
152 }
153
154 pthread_mutex_unlock (&pqt->pq_mutex);
155 pthread_mutex_unlock (&np->pq_mutex);
156
157 /* added packet successfully
158 */
159 return (0);
160}
161
162
163/* pq_handle
164 *
165 * main (threaded) packet processor routine
166 */
167
168void *
169pq_handle (pq_thread *pq)
170{
171 pq_desc *packet; /* packet pointer */
172 ip_hdr *ip; /* IP packet header pointer */
173 tcp_hdr *tcp; /* TCP packet header pointer */
174 unsigned char *data; /* packet data pointer :-) */
175 char *p_data;
176
177
178 do {
179 unsigned int psize;
180
181 do {
182 sem_wait (&pq->pq_active); /* wait for a packet */
183
184 /* get, unlink and then process the packet
185 */
186 packet = pq_get (pq);
187 } while (packet == NULL);
188
189 p_data = packet->p_data;
190
191 pq_offset (p_data, &ip, &tcp, &data);
192
193/* hexdump ("packets-rawdns", (unsigned char *) ip, (packet->p_len - sizeof (eth_hdr)));
194*/
195 psize = packet->p_len;
196// XXX dns_handle (ip, udp, dns, data, psize);
197
198#if 0
199 /* now, if the packet is directed to port 53, we add the id to the queue
200 * then update the display. but first check whether it is a self-originated
201 * packet, then skip the whole procedure.
202 */
203 if (udp->uh_dport == htons (53) && dns_tag_check_n (&ip->ip_src,
204 &ip->ip_dst, htons (udp->uh_sport), htons (udp->uh_dport),
205 htons (dns->id)) == 0)
206 {
207 id_add (ip->ip_src, ntohs (dns->id), &packet->rcv_time);
208 id_qprint (ms, ms->winid);
209 }
210#endif
211
212 pq_free (packet);
213
214 } while (1);
215
216 return (NULL);
217}
218
219
220/* pq_create
221 *
222 * create a packet handler
223 *
224 * return NULL on failure
225 * return pointer to pq_thread structure on success
226 */
227
228pq_thread *
229pq_create (void)
230{
231 int n; /* temporary return value */
232 pq_thread *pq_new; /* main thread structure of new thread */
233
234 pq_new = xcalloc (1, sizeof (pq_thread));
235
236 pthread_mutex_init (&pq_new->pq_mutex, NULL);
237 pq_new->pq_count = pq_new->pq_curcount = 0;
238 sem_init (&pq_new->pq_active, 0, 0);
239
240 n = pthread_create (&pq_new->pq_tid, NULL, (void *) pq_handle, (void *) pq_new);
241 if (n == -1) {
242 pq_destroy (pq_new);
243
244 return (NULL);
245 }
246
247 return (pq_new);
248}
249
250
251void
252pq_destroy (pq_thread *pq)
253{
254 pthread_mutex_destroy (&pq->pq_mutex);
255 sem_destroy (&pq->pq_active);
256
257 free (pq);
258
259 return;
260}
261
262/* pq_notify
263 *
264 * notify the correct thread using a semaphore
265 */
266
267void
268pq_notify (pq_thread *pqt)
269{
270 /* raise the semaphore
271 */
272 sem_post (&pqt->pq_active);
273
274 return;
275}
276
277
278/* pq_get
279 *
280 * return one packet from the packet stack pointed to by `pqt'.
281 *
282 * return NULL on failure
283 * return pointer to packet description on success
284 */
285
286pq_desc *
287pq_get (pq_thread *pqt)
288{
289 pq_desc *next;
290 pq_desc *this = NULL;
291
292 pthread_mutex_lock (&pqt->pq_mutex);
293
294 next = pqt->root;
295
296 if (next != NULL) {
297
298 /* if there is a packet, unlink first one, and shift all
299 * following packets
300 */
301 pthread_mutex_lock (&pqt->root->pq_mutex);
302 next = pqt->root->next;
303 pthread_mutex_unlock (&pqt->root->pq_mutex);
304
305 /* shift packets, we are helding pq_mutex tho :)
306 */
307 this = pqt->root;
308 pqt->root = next;
309
310 }
311
312 pthread_mutex_unlock (&pqt->pq_mutex);
313
314 return (this);
315}
316
317/* pq_remove
318 *
319 * remove the first packet from packet thread queue `thd'.
320 *
321 * return in any case
322 */
323
324void
325pq_remove (pq_thread *pqt)
326{
327 pq_desc *next;
328
329 pthread_mutex_lock (&pqt->pq_mutex);
330
331 if (pqt->root != NULL) {
332 pthread_mutex_lock (&pqt->root->pq_mutex);
333 next = pqt->root->next;
334 pthread_mutex_unlock (&pqt->root->pq_mutex);
335
336 pq_free (pqt->root);
337 pqt->root = next;
338 }
339
340 pthread_mutex_unlock (&pqt->pq_mutex);
341 return;
342}
343
344
345/* pq_free
346 *
347 * free a pq_desc structure with all associated data
348 */
349
350void
351pq_free (pq_desc *packet)
352{
353 /* some sanity checking inside :)
354 */
355 if (packet == NULL)
356 return;
357
358 /* if data is associated, free it
359 */
360 if (packet->p_data != NULL) {
361 free (packet->p_data);
362 }
363
364 /* destroy mutex and free structure
365 */
366 pthread_mutex_destroy (&packet->pq_mutex);
367 free (packet);
368
369 return;
370}
371
372
373/* pq_filter
374 *
375 * check wether packet with packet data pointed to by `p_data' is a UDP
376 * nameserver packet or not
377 *
378 * return 1 if it is
379 * return 0 if it is not
380 */
381
382int
383pq_filter (unsigned char *p_data, unsigned long p_size)
384{
385 int match = 0;
386 unsigned int iplen;
387 ip_hdr * ip = NULL;
388 tcp_hdr * tcp = NULL;
389
390
391 if (p_size < (sizeof (ip_hdr) + sizeof (tcp_hdr)))
392 return (0);
393
394 /* now check if the ip header encloses a udp packet
395 */
396 ip = (ip_hdr *) (p_data); /* caveat here: don't miss brackets ! */
397 if (ip->ip_p != IPPROTO_TCP)
398 return (0);
399
400 iplen = ip->ip_hl << 2;
401 if (iplen > p_size) /* XXX: is this correct ;) ? */
402 return (0);
403
404
405 tcp = (tcp_hdr *) (p_data + iplen);
406 tcp->th_sport = ntohs (tcp->th_sport);
407 tcp->th_dport = ntohs (tcp->th_dport);
408
409 /* quick and ugly wanted-matching
410 */
411 pthread_mutex_lock (&watch_mutex);
412 if (tcp->th_sport == watch_sport &&
413 tcp->th_dport == watch_dport &&
414 ip->ip_src.s_addr == watch_ipsrc.s_addr &&
415 ip->ip_dst.s_addr == watch_ipdst.s_addr)
416 {
417 match = 1;
418 } else if (tcp->th_sport == watch_dport &&
419 tcp->th_dport == watch_sport &&
420 ip->ip_src.s_addr == watch_ipdst.s_addr &&
421 ip->ip_dst.s_addr == watch_ipsrc.s_addr)
422 {
423 match = 1;
424 }
425
426 if (watch == 0)
427 match = 0;
428
429 /* XXX kludge: update seq# here */
430 if (match == 1) {
431 if (ip->ip_src.s_addr == watch_ipsrc.s_addr &&
432 tcp->th_sport == watch_sport)
433 {
434 watch_src_seq = ntohl (tcp->th_seq);
435 watch_src_ack = ntohl (tcp->th_ack);
436#ifdef DEBUG
437 fprintf (stderr, "(%5hu -> %5hu) src #: 0x%08lx | 0x%08lx\n",
438 tcp->th_sport, tcp->th_dport,
439 watch_src_seq, watch_src_ack);
440#endif
441 } else if (ip->ip_src.s_addr == watch_ipdst.s_addr &&
442 tcp->th_sport == watch_dport)
443 {
444 watch_dst_seq = ntohl (tcp->th_seq);
445 watch_dst_ack = ntohl (tcp->th_ack);
446#ifdef DEBUG
447 fprintf (stderr, "(%5hu -> %5hu) dst #: 0x%08lx | 0x%08lx\n\n",
448 tcp->th_sport, tcp->th_dport,
449 watch_dst_seq, watch_dst_ack);
450#endif
451 }
452 }
453 pthread_mutex_unlock (&watch_mutex);
454
455
456 return (match);
457}
458
459
460/* pq_offset
461 *
462 * stupidly calculate offsets for IP, UDP and DNS offsets within a IP data
463 * block
464 *
465 * return nothing
466 */
467
468void
469pq_offset (unsigned char *data, ip_hdr **ip, tcp_hdr **tcp,
470 unsigned char **tcp_data)
471{
472 size_t ip_len;
473
474
475 if (data == NULL)
476 return;
477
478 *ip = (ip_hdr *) data;
479 ip_len = (*ip)->ip_hl << 2;
480 *tcp = (tcp_hdr *) (data + ip_len);
481
482 /* FIXME: assuming stock tcp header */
483 *tcp_data = (unsigned char *) (data + ip_len + sizeof (tcp_hdr));
484
485 return;
486}
487