dc.c 10.7 KB
Newer Older
1
2
3
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
4
5
6
7
8
#include <stdlib.h>
#include <stdio.h>
#include <sys/shm.h>
#include <string.h>
#include <errno.h>
's avatar
committed
9

10
11
12
13
14
15
16
17
#include "mapidflib.h"
#include "mapidlib.h"
#include "mapidevices.h"
#include "mapid.h"
#include "fhelp.h"
#include "debug.h"
#include "mapiipc.h"
#include "mstring.h"
18
19
20
#include "acsmx2.h"
#include "mapi_errors.h"

's avatar
committed
21
#include <pcap.h>
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <netinet/in.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>

#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <time.h>

's avatar
committed
42
#include "log.h"
43
#include "trackflib.h"
's avatar
committed
44

45
46
47
48
49
50
struct filters {
	int protocol;
	unsigned int saddr;
	unsigned int daddr;
	uint16_t sp;
	uint16_t dp;
's avatar
committed
51
	struct timeval ts;
52
53
54
55
56
57
58
59
	struct filters *next;
};

struct list{
	struct filters *head;
	struct filters *tail;
};

's avatar
committed
60
61
#define STRING_NUM 15

's avatar
committed
62
63
int isDc(mapidflib_function_instance_t *instance, unsigned char *pkt, unsigned int len);

's avatar
committed
64
65
66
char *dc_strings[STRING_NUM]={"$MyNick","$Lock EXTENDEDPROTOCOL" ,"$Sending", "$Direction Download ","$Direction Upload ","$Supports", "$GetNickList|",
					"$ValidateNick", "$ConnectToMe","$HubName","$Hello","$MyINFO $ALL","$GetINFO","$Search Hub:","$OpList"};
/* Backup Strings
67
68
69
* "$Key","$Get","$Send|","$ValidateDenide", "$GetPass", "$MyPass", "$LogedIn", "$BadPass", "$GetListLen", "$ListLen", "$MaxedOut", "$Error",
* "$FileLength", "$Canceled", "$SR","$Ping", "$Version", "$NickList", "$MultiConnectToMe", "$RevConnectToMe", "$To:", "$Quit","$OpForceMove $Who:",
* "$ForceMove","$Kick", "$Search", "$Up", "$UpToo"
's avatar
committed
70
*/
71

's avatar
committed
72
73
74
75
76
int dc_string_len[STRING_NUM] = {0};

//char *dc_strings[2]={"|$Lock EXTENDEDPROTOCOLABCABCABCABCABCABC Pk=DCPLUSPLUS", "|$Direction Download"};

///int isDc(mapidflib_function_instance_t *, unsigned char *, int );
77

78
struct mapid_dc {
79
#ifndef __WITH_AHO__
's avatar
committed
80
81
	int *shift[STRING_NUM];
	int *skip[STRING_NUM];
82
83
84
#else 
	ACSM_STRUCT2 *acsm;
#endif
's avatar
committed
85
	struct list **dclist;
86
87
};

88
static int dc_init(mapidflib_function_instance_t *instance, MAPI_UNUSED int fd)
89
{
's avatar
committed
90
	int i=0;	
91
92
93
94
#ifdef __WITH_AHO__
	char *p;
#endif

95
	instance->internal_data = malloc(sizeof(struct mapid_dc));
's avatar
committed
96
97
98
99
100
101
102
	((struct mapid_dc*)instance->internal_data)->dclist = (struct list**)malloc(sizeof(struct list*)*HASHTABLESIZE);
	memset(((struct mapid_dc*)instance->internal_data)->dclist, 0, (sizeof(struct list*)*HASHTABLESIZE));
	for(i = 0; i < HASHTABLESIZE; i++) {
		((struct mapid_dc*)instance->internal_data)->dclist[i] = (struct list*)malloc(sizeof(struct list));
		((struct mapid_dc*)instance->internal_data)->dclist[i]->head = NULL;
		((struct mapid_dc*)instance->internal_data)->dclist[i]->tail = NULL;
	}
103
#ifndef __WITH_AHO__
's avatar
committed
104
	for(i=0;i<STRING_NUM;i++) {
105
106
107
		((struct mapid_dc*)instance->internal_data)->shift[i] = make_shift(dc_strings[i],strlen(dc_strings[i]));
		((struct mapid_dc*)instance->internal_data)->skip[i] = make_skip(dc_strings[i], strlen(dc_strings[i]));
	}
108
109
#else
	((struct mapid_dc*)instance->internal_data)->acsm = acsmNew2();
110

111
112
113
114
115
116
117
118
119
120
121
122
	if(!(((struct mapid_dc*)instance->internal_data)->acsm)) {
		return MAPID_MEM_ALLOCATION_ERROR;
	}

	for(i = 0; i< STRING_NUM; i++) {
		p = dc_strings[i];

		acsmAddPattern2(((struct mapid_dc*)instance->internal_data)->acsm, p, strlen(p), 1, 0, 0, (void*)p, i);
	}
	
	acsmCompile2(((struct mapid_dc*)instance->internal_data)->acsm);
#endif
123
124
125
	return 0;
}	

126
127
128
129
130
131
132
133
134
135
136
137
138
139
#ifdef __WITH_AHO__

static int global_index = -1;
static char *found = NULL;

	int dc_matchFound(void* id, int my_index, MAPI_UNUSED void *data) 
	{
  		global_index = my_index;
		found = (char *)id;

		return my_index;
	}
#endif

's avatar
committed
140
int isDc(mapidflib_function_instance_t *instance, unsigned char *pkt, unsigned int len)
141
{
142
#ifndef __WITH_AHO__
143
	int i=0;
144
145
146
147
#else
	global_index = -1;
	found = NULL;
#endif
148

149
#ifndef __WITH_AHO__
's avatar
committed
150
151
152
153
154
	for(i=0;i<STRING_NUM;i++) {
		if(len < strlen(dc_strings[i]))
				continue;
		
		if(len >= 100) {
's avatar
committed
155
			if(mSearch((char *)(pkt), 100, dc_strings[i], strlen(dc_strings[i]),
's avatar
committed
156
157
158
159
160
161
162
						((struct mapid_dc *)instance->internal_data)->skip[i],
						((struct mapid_dc *)instance->internal_data)->shift[i]))
			{
				return i;
			}
		}
		else {
's avatar
committed
163
			if(mSearch((char *)(pkt), len, dc_strings[i], strlen(dc_strings[i]),
's avatar
committed
164
165
166
167
168
						((struct mapid_dc *)instance->internal_data)->skip[i],
						((struct mapid_dc *)instance->internal_data)->shift[i]))
			{
				return i;
			}
169
170
		}
	}
171
172
173
174
175
176
#else 
	acsmSearch2(((struct mapid_dc*)instance->internal_data)->acsm, pkt, len, dc_matchFound, (void *)0);
	
	return global_index;

#endif 
's avatar
committed
177
	return -1;
178
179
180
181

}

static int dc_process(mapidflib_function_instance_t *instance,
's avatar
committed
182
183
			MAPI_UNUSED unsigned char* dev_pkt,
			unsigned char* pkt,
184
185
186
187
			mapid_pkthdr_t* pkt_head)
{
	struct filters *temp = NULL, *prev = NULL, *new = NULL;
	int len = pkt_head->caplen;
's avatar
committed
188
	unsigned char *p = NULL;
's avatar
committed
189
190
	struct timeval ts;

's avatar
committed
191
	struct list **dclist = ((struct mapid_dc*)instance->internal_data)->dclist;
192
193
	uint16_t ethertype;
	struct ether_header *ep = NULL;
's avatar
committed
194
195
196
197
	struct pos_header {
		uint16_t af;
		uint16_t cf;
	}	*pp = NULL;
198
199
200
	struct iphdr *iph = NULL;
	struct tcphdr *tcph = NULL;
	struct udphdr *udph = NULL;
's avatar
committed
201
202
203

	struct vlan_802q_header *vlan_header;

204
205
	unsigned int saddr, daddr;
	
's avatar
committed
206
	struct in_addr source, dest;
207
	uint16_t sp, dp;
's avatar
committed
208
209
	
	unsigned int hashval = 0;
's avatar
committed
210
	int i = 0;
211

212
213
214
	int pkt_color = pkt_head->color;

	if(pkt_color != 0 && pkt_color != DC_COLOR) {
215
216
		return 0;
	}
217

's avatar
committed
218
	p = pkt;
's avatar
committed
219

's avatar
committed
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
	switch(instance->hwinfo->link_type) {
		case DLT_EN10MB:
				// lay the Ethernet header struct over the packet data
				ep = (struct ether_header *)p;

				// skip ethernet header
				p += sizeof(struct ether_header);
				len -= sizeof(struct ether_header);

				ethertype = ntohs(ep->ether_type);

				if(ethertype  == ETHERTYPE_8021Q) {
					vlan_header = (struct vlan_802q_header*)p;
					ethertype = ntohs(vlan_header->ether_type);
					p += sizeof(struct vlan_802q_header);
				}
				
				if(ethertype == MPLS_MASK) {
					p += 4;			
				}
				else if(ethertype != ETHERTYPE_IP) {
					return 0;
				}
			break;
		case DLT_CHDLC:
				pp = (struct pos_header *)p;

				p += sizeof(struct pos_header);
				len -= sizeof(struct pos_header);

				ethertype = ntohs(pp->cf);

				if (ethertype != ETHERTYPE_IP) {
					return 0;
				}
			break;
		default:
			//DEBUG_CMD(Debug_Message("Link layer not supported"));
			return 0;
259
260
261
262
263
264
265
266
	}
	
	// IP header struct over the packet data;
	iph = (struct iphdr*)p;

	saddr = *((unsigned int *)&(iph->saddr));
	daddr = *((unsigned int *)&(iph->daddr));
	
's avatar
committed
267
268
	source.s_addr = (unsigned long int)iph->saddr ;
	dest.s_addr = (unsigned long int)iph->daddr;
269

's avatar
committed
270
271
	p += iph->ihl * 4;
	len -= iph->ihl * 4;
272

's avatar
committed
273
	hashval = (saddr + daddr) % HASHTABLESIZE;
's avatar
committed
274

275
276
277
278
279
280
	if(iph->protocol == 6)	// TCP
	{
		tcph = (struct tcphdr *)p;
		
		sp = ntohs(tcph->source);
		dp = ntohs(tcph->dest);
's avatar
committed
281
282
283
284

		p += tcph->doff * 4;
		len -= tcph->doff * 4;

's avatar
committed
285
		if((unsigned int)(p - pkt) == pkt_head->caplen) {
's avatar
committed
286
287
			return 0;
		}
288
289
290
291
292
293
294
	}
	else if(iph->protocol == 17)	// UDP
	{
		udph = (struct udphdr *)p;

		sp = ntohs(udph->source);
		dp = ntohs(udph->dest);
's avatar
committed
295
296
297
298

		p += sizeof(struct udphdr);
		len -= sizeof(struct udphdr);

's avatar
committed
299
		if((unsigned int)(p - pkt) == pkt_head->caplen) {
's avatar
committed
300
301
			return 0;
		}
302
303
304
305
306
307
	}
	else
	{
		return 0;
	}

's avatar
committed
308
	gettimeofday(&ts, NULL);
's avatar
committed
309

's avatar
committed
310
	for(temp = dclist[hashval]->head, prev = dclist[hashval]->head; temp != NULL; prev = temp, temp = temp->next)
311
312
313
314
315
316
317
318
	{
			if(temp->protocol == iph->protocol &&
					(
					(temp->saddr == saddr && temp->daddr == daddr && temp->sp == sp && temp->dp == dp)
					||
					(temp->saddr == daddr && temp->daddr == saddr && temp->sp == dp && temp->dp == sp))
			  )
			{
's avatar
committed
319
320
				gettimeofday(&(temp->ts), NULL);

's avatar
committed
321
				if(iph->protocol == 6 && tcph->fin) {
's avatar
committed
322
323
					if(temp == dclist[hashval]->head){
						dclist[hashval]->head = temp->next;
's avatar
committed
324
325
326
327
					}
					else {
						prev->next = temp->next;
					}
328
329
330
					temp->next = NULL;
					free(temp);
				}
331
332
			
				pkt_head->color = DC_COLOR;
333
334
				return 1;
			}
's avatar
committed
335
336
			
			if(ts.tv_sec - temp->ts.tv_sec > 60) {
's avatar
committed
337
338
				if(temp == dclist[hashval]->head){
					dclist[hashval]->head = temp->next;
's avatar
committed
339
340
341
342
343
344
345
				}
				else {
					prev->next = temp->next;
				}
				temp->next = NULL;
				free(temp);
			}
346
347
348
	}


's avatar
committed
349
	if(iph->protocol == 6) {
's avatar
committed
350
		if(p == NULL) {
's avatar
committed
351
			return 0;
's avatar
committed
352
		}
's avatar
committed
353
		
's avatar
committed
354
		if(*p != '$') {
's avatar
committed
355
			return 0;
's avatar
committed
356
		}
's avatar
committed
357
358
359
360
361
		
/*		if(p[len - 1] != '|')
			return 0;
*/	}
	else if(iph->protocol == 17) {
's avatar
committed
362
		if(p == NULL) {
's avatar
committed
363
			return 0;
's avatar
committed
364
		}
's avatar
committed
365
		
's avatar
committed
366
		if(*p != '$') {
's avatar
committed
367
			return 0;
's avatar
committed
368
		}
's avatar
committed
369
370
371
372
373
374
375
376
377
		
/*		if(p[len - 1] != '|')
			return 0;
*/	}
	else {
		return 0;
	}
	if((i = isDc(instance,pkt,len)) >= 0)
	{
378
		
379
380
381
382
383
384
385
		new = (struct filters*)malloc(sizeof(struct filters));
		
		new->protocol = iph->protocol;
		new->saddr = saddr;
		new->daddr = daddr;
		new->sp = sp;
		new->dp = dp;
386
#ifdef __TRACKFLIB_LOGGING__
's avatar
committed
387
		unsigned char *p_b = p;
388
	#ifndef __WITH_AHO__
's avatar
committed
389
		write_to_log("DC++", dc_strings[i], iph->protocol, source, sp, dest, dp, p_b, len);
390
391
392
	#else
		write_to_log("DC++", found, iph->protocol, source, sp, dest, dp, p_b, len);
	#endif 
393
#endif
's avatar
committed
394
395
		
		for(temp = dclist[hashval]->head; temp != NULL; temp = temp->next)
396
397
398
399
400
401
402
403
		{
			if(new->protocol == temp->protocol && (
					(new->saddr == temp->saddr && new->daddr == temp->daddr && new->sp == temp->sp && new->dp == temp->dp) 
					||
					(new->daddr == temp->saddr && new->saddr == temp->daddr && new->dp == temp->sp && new->sp == temp->dp)
					)
				)
			{
404
				pkt_head->color = DC_COLOR;
405
406
407
408
				return 1;
			}
		}

's avatar
committed
409
410
		gettimeofday(&(new->ts), NULL);
		
's avatar
committed
411
412
		new->next = dclist[hashval]->head;
		dclist[hashval]->head = new;
413

414
		pkt_head->color = DC_COLOR;
's avatar
committed
415

416
417
418
419
420
421
422
423
		return 1;
	}
	return 0;
}

static int dc_cleanup(mapidflib_function_instance_t *instance) 
{
	struct filters *temp = NULL, *tmp = NULL;
's avatar
committed
424
	int i = 0;
425

's avatar
committed
426
427
428
429
430
431
432
433
434
  if(instance->internal_data != NULL){
	  for(i = 0; i < HASHTABLESIZE; i++) {
		  temp = ((struct mapid_dc*)instance->internal_data)->dclist[i]->head;
		  
		  while(temp != NULL) {
			  tmp = temp;
			  temp = temp->next;
			  free(tmp);
		  }
435
		  free(((struct mapid_dc*)instance->internal_data)->dclist[i]);
's avatar
committed
436
	  }
437
438
439
440
441
442
443
444
445
446

#ifndef __WITH_AHO__
        for(i=0;i<STRING_NUM;i++) {
                free(((struct mapid_dc*)instance->internal_data)->shift[i]);
                free(((struct mapid_dc*)instance->internal_data)->skip[i]);
        }
#else
        acsmFree2(((struct mapid_dc*)instance->internal_data)->acsm);
#endif

447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
	free(((struct mapid_dc*)instance->internal_data)->dclist);
	free(instance->internal_data);
  }
  return 0;
}

static mapidflib_function_def_t finfo={
  "",
  "TRACK_DC",
  "Searches for Direct Connect (DC) packets\n",
  "",
  MAPI_DEVICE_ALL,
  MAPIRES_NONE,
  0, //shm size
  0, //modifies_pkts
462
463
  1, //filters packets
  MAPIOPT_NONE,
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
  NULL,
  dc_init,
  dc_process,
  NULL, //get_result
  NULL, //reset
  dc_cleanup,
  NULL, //client_init
  NULL, //client_read_result
  NULL  //client_cleanup
};

mapidflib_function_def_t* dc_get_funct_info();
mapidflib_function_def_t* dc_get_funct_info() {
  return &finfo;
};