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

's avatar
committed
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"
's avatar
committed
18 19

#include <pcap.h>
's avatar
committed
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
#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>
's avatar
committed
37
#include <netdb.h>
's avatar
committed
38 39 40 41 42
#include <sys/time.h>
#include <time.h>

#include "log.h"
#include "trackflib.h"
's avatar
committed
43
#include "mapi_errors.h"
's avatar
committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

struct filters {
	int protocol;
	unsigned int addr;
	uint16_t port;
	struct timeval ts;
	struct filters *next;
	struct port_list **port_usage_list;
	struct port_usage *top_port;
};

struct port_usage {
	uint16_t port;
	unsigned long long pkts;
	unsigned long long bytes;
	struct port_usage *next;
};

struct port_list {
	struct port_usage *head;
	struct port_usage *tail;
};

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

#define SKYPE_UI "ui.skype.com"

int isSkype(mapidflib_function_instance_t *, unsigned char *, int );

struct mapid_skype{
	char **skype_host_addrs;
	struct list **skypelist;
	struct list **cntlist;
};

static int trackskype_init(mapidflib_function_instance_t *instance, MAPI_UNUSED int fd)
{
	int i=0;
	struct hostent* hosts = NULL;

	instance->internal_data = malloc(sizeof(struct mapid_skype));
	((struct mapid_skype*)instance->internal_data)->skypelist = (struct list**)malloc(sizeof(struct list*)*HASHTABLESIZE);
's avatar
committed
89 90 91
	if(((struct mapid_skype*)instance->internal_data)->skypelist == NULL) {
		return MAPID_MEM_ALLOCATION_ERROR;
	}
's avatar
committed
92
	((struct mapid_skype*)instance->internal_data)->cntlist = (struct list**)malloc(sizeof(struct list*)*HASHTABLESIZE);
's avatar
committed
93 94 95
	if(((struct mapid_skype*)instance->internal_data)->cntlist == NULL) {
		return MAPID_MEM_ALLOCATION_ERROR;
	}
's avatar
committed
96 97 98
		
	for(i = 0; i < HASHTABLESIZE; i++) {
		((struct mapid_skype*)instance->internal_data)->skypelist[i] = (struct list*)malloc(sizeof(struct list));
's avatar
committed
99 100 101
		if(((struct mapid_skype*)instance->internal_data)->skypelist[i] == NULL) {
			return MAPID_MEM_ALLOCATION_ERROR;
		}
's avatar
committed
102 103 104 105
		((struct mapid_skype*)instance->internal_data)->skypelist[i]->head = NULL;
		((struct mapid_skype*)instance->internal_data)->skypelist[i]->tail = NULL;
		
		((struct mapid_skype*)instance->internal_data)->cntlist[i] = (struct list*)malloc(sizeof(struct list));
's avatar
committed
106 107 108
		if(((struct mapid_skype*)instance->internal_data)->cntlist[i] == NULL) {
			return MAPID_MEM_ALLOCATION_ERROR;
		}
's avatar
committed
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
		((struct mapid_skype*)instance->internal_data)->cntlist[i]->head = NULL;
		((struct mapid_skype*)instance->internal_data)->cntlist[i]->tail = NULL;
	}
	
	if((hosts = gethostbyname(SKYPE_UI)) != NULL) {
		((struct mapid_skype*)instance->internal_data)->skype_host_addrs = hosts->h_addr_list;
	}
	
	return 0;
}	

int add_port_usage(struct filters *temp, uint16_t port, struct timeval ts) 
{
	int i = 0;
	
	struct port_usage *tmp = NULL, *new = NULL;
	unsigned int hashval = port % HASHTABLESIZE;

	if(temp->port_usage_list == NULL) {
		temp->port_usage_list = (struct port_list**)malloc(sizeof(struct port_list*)*HASHTABLESIZE);
's avatar
committed
129
		if(temp->port_usage_list == NULL) {
130
			DEBUG_CMD(Debug_Message("could not alloc temp->port_usage_list"));
's avatar
committed
131
		}
's avatar
committed
132 133 134
		
		for(i = 0; i < HASHTABLESIZE; i++) {
			temp->port_usage_list[i] = (struct port_list*)malloc(sizeof(struct port_list));
's avatar
committed
135
			if(temp->port_usage_list[i] == NULL) {
136
				DEBUG_CMD(Debug_Message("Could not alloc temp->port_usage_list[%d]", i));
's avatar
committed
137
			}
's avatar
committed
138 139 140 141 142 143 144 145 146 147 148
			temp->port_usage_list[i]->head = NULL;
			temp->port_usage_list[i]->tail = NULL;
		}
	}

	for(tmp = temp->port_usage_list[hashval]->head; tmp != NULL; tmp = tmp->next) {
		if(tmp->port == port) {
			tmp->pkts++;

			if(temp->top_port == NULL) {
				temp->top_port = (struct port_usage*)malloc(sizeof(struct port_usage));
's avatar
committed
149 150
				temp->top_port->port = 0;
				temp->top_port->pkts = 0;
's avatar
committed
151
				if(temp->top_port == NULL) {
152
					DEBUG_CMD(Debug_Message("Could not alloc temp->top_port"));
's avatar
committed
153
				}
's avatar
committed
154 155 156 157 158 159 160 161 162 163
				temp->top_port->port = tmp->port;
				temp->top_port->pkts = tmp->pkts;
			}
			else {
				if(tmp->pkts > temp->top_port->pkts) {
					temp->top_port->pkts = tmp->pkts;
				}
			}

			if((ts.tv_sec - temp->ts.tv_sec) >= 10) {
164
					DEBUG_CMD(Debug_Message("%ld", ts.tv_sec - temp->ts.tv_sec));
's avatar
committed
165 166 167 168 169 170 171
					return 2;
			}
			return 1;
		}
	}

	new = (struct port_usage*)malloc(sizeof(struct port_usage));
's avatar
committed
172
	if(new == NULL) {
173
		DEBUG_CMD(Debug_Message("could not alloc new"));
's avatar
committed
174
	}
's avatar
committed
175 176 177 178 179 180 181 182 183 184 185 186
	new->port = port;
	new->pkts = 1;
	new->next = NULL;

	if(temp->port_usage_list[hashval] == NULL) {
		temp->port_usage_list[hashval]->head = new;
	}
	else {
		new->next =  temp->port_usage_list[hashval]->head;
		temp->port_usage_list[hashval]->head = new;
	}

's avatar
committed
187 188 189
	if(temp->top_port == NULL) {
		temp->top_port = (struct port_usage*)malloc(sizeof(struct port_usage));
		if(temp->top_port == NULL) {
190
			DEBUG_CMD(Debug_Message("Could not alloc temp->top_port"));
's avatar
committed
191 192 193 194 195
		}
		temp->top_port->port = new->port;
		temp->top_port->pkts = new->pkts;
	}

's avatar
committed
196
	if((ts.tv_sec - temp->ts.tv_sec) >= 10) {
197 198
		DEBUG_CMD(Debug_Message("%ld", ts.tv_sec - temp->ts.tv_sec));
		return 2;
's avatar
committed
199 200 201 202 203
	}

	return 1;
}

's avatar
committed
204
int clean_port_list(struct filters *to_clean) 
's avatar
committed
205
{
's avatar
committed
206
		struct port_usage *tmp = NULL;
's avatar
committed
207
		unsigned int i = 0;
's avatar
committed
208
			
's avatar
committed
209 210
		// cleaning port counter status
		for(i = 0; i < HASHTABLESIZE; i++) {
's avatar
committed
211 212
				for(tmp = to_clean->port_usage_list[i]->head; tmp != NULL; tmp = tmp->next) {
						to_clean->port_usage_list[i]->head = tmp->next;
's avatar
committed
213 214
						free(tmp);
				}
's avatar
committed
215 216 217
			
			free(to_clean->port_usage_list[i]);
				to_clean->port_usage_list[i] = NULL;
's avatar
committed
218
		}
's avatar
committed
219 220 221
		free(to_clean->port_usage_list);
		to_clean->port_usage_list = NULL;
	
's avatar
committed
222 223 224 225 226 227 228 229 230 231
		return 1;
						
}
int add_to_ui_hash(mapidflib_function_instance_t *instance, int protocol, unsigned int addr, struct timeval ts) {
	unsigned int hashval = htonl(addr)%HASHTABLESIZE;
	struct filters *temp = NULL, *new = NULL;
	struct list **cntlist = ((struct mapid_skype*)instance->internal_data)->cntlist;


	for(temp = cntlist[hashval]->head; temp != NULL; temp = temp->next) {
's avatar
committed
232 233
		if((addr == temp->addr)) {
			//printf("already in\n");
's avatar
committed
234 235 236 237
			return 1;
		}
	}
	
's avatar
committed
238 239 240
	new = (struct filters *)malloc(sizeof(struct filters));

	if(new == NULL) {
241
		DEBUG_CMD(Debug_Message("ERROR could not allocate memory"));
's avatar
committed
242 243 244 245 246
	}

	new->protocol = protocol;
	new->addr = addr;
	new->ts = ts;
's avatar
committed
247 248 249 250 251
	new->port = 0;
	new->next = NULL;
	new->port_usage_list = NULL;
	new->top_port = NULL;
	
's avatar
committed
252

's avatar
committed
253
//	gettimeofday(&(new->ts), NULL);
's avatar
committed
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
	
	new->next = cntlist[hashval]->head;
	cntlist[hashval]->head = new;
	
	return 1;
}

static int trackskype_process(mapidflib_function_instance_t *instance,
			MAPI_UNUSED unsigned char* dev_pkt,
			unsigned char* pkt,
			mapid_pkthdr_t* pkt_head)
{
	struct filters *temp = NULL, *prev = NULL;
	int len = pkt_head->wlen;
	unsigned char *p = NULL;
	struct timeval ts;

	struct list **skypelist = ((struct mapid_skype*)instance->internal_data)->skypelist;
	struct list **cntlist = ((struct mapid_skype*)instance->internal_data)->cntlist;
	uint16_t ethertype;
	struct ether_header *ep = NULL;
's avatar
committed
275 276 277 278
	struct pos_header {
		uint16_t af;
		uint16_t cf;
	}	*pp = NULL;
's avatar
committed
279 280 281 282 283 284 285 286 287 288
	struct iphdr *iph = NULL;
	struct tcphdr *tcph = NULL;
	struct udphdr *udph = NULL;	
	unsigned int saddr, daddr;
	
	struct in_addr source, dest;
	struct vlan_802q_header *vlan_header;

	uint16_t sp, dp;

's avatar
committed
289
	unsigned int hashval = 0, skype_hashval = 0;
's avatar
committed
290 291 292 293 294

	int i = 0;
	int udp_len = 0;
	int ret = 0;

295 296 297
	int pkt_color = pkt_head->color;

	if(pkt_color != 0 && pkt_color != SKYPE_COLOR) {
's avatar
committed
298 299
		return 0;
	}
's avatar
committed
300

's avatar
committed
301 302
	p = pkt;

's avatar
committed
303 304 305 306
	switch(instance->hwinfo->link_type) {
		case DLT_EN10MB:
				// lay the Ethernet header struct over the packet data
				ep = (struct ether_header *)p;
's avatar
committed
307

's avatar
committed
308 309 310
				// skip ethernet header
				p += sizeof(struct ether_header);
				len -= sizeof(struct ether_header);
's avatar
committed
311

's avatar
committed
312
				ethertype = ntohs(ep->ether_type);
's avatar
committed
313

's avatar
committed
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
				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;
's avatar
committed
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
	}
	
	// IP header struct over the packet data;
	iph = (struct iphdr*)p;

	saddr = *((unsigned int *)&(iph->saddr));
	daddr = *((unsigned int *)&(iph->daddr));

	source.s_addr = (unsigned long int)iph->saddr ;
	dest.s_addr = (unsigned long int)iph->daddr;

	p += iph->ihl * 4;
	len -= iph->ihl *4;

	
	if(iph->protocol == 6)	// TCP
	{
		tcph = (struct tcphdr *)p;
		
		sp = ntohs(tcph->source);
		dp = ntohs(tcph->dest);

		p += tcph->doff * 4;

's avatar
committed
366
		len -= tcph->doff * 4;
's avatar
committed
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
	}
	else if(iph->protocol == 17) {	// UDP
			udph = (struct udphdr *)p;
			udp_len = sizeof(struct udphdr);

			sp = ntohs(udph->source);
			dp = ntohs(udph->dest);

			p += sizeof(struct udphdr);

			len -= sizeof(struct udphdr);
	}
	else
	{
		return 0;
	}

's avatar
committed
384 385
	//gettimeofday(&ts, NULL);
	ts.tv_sec = pkt_head->ts >> 32;
's avatar
committed
386 387 388 389 390 391 392

	/*
	 *	First look for already found skype adrress/port pairs
	 */
	
	hashval = (htonl(saddr)*sp) % HASHTABLESIZE;

's avatar
committed
393 394
	temp = skypelist[hashval]->head;

's avatar
committed
395 396
	for(temp = skypelist[hashval]->head, prev = skypelist[hashval]->head; temp != NULL; prev = temp, temp = temp->next) {
		if(((temp->addr == saddr && temp->port == sp) || (temp->addr == daddr && temp->port == dp))) {
's avatar
committed
397 398
//			gettimeofday(&(temp->ts), NULL);
			temp->ts = ts;
399
			pkt_head->color = SKYPE_COLOR;
's avatar
committed
400 401 402 403
			return 1;
		}
		
		// flow cleanup
's avatar
committed
404
		if(ts.tv_sec - temp->ts.tv_sec > 600) {
's avatar
committed
405 406 407 408 409 410 411 412
			if(temp == skypelist[hashval]->head) {
				skypelist[hashval]->head = temp->next;
			}
			else {
				prev->next = temp->next;
			}
			temp->next = NULL;
			free(temp);
's avatar
committed
413
			temp = prev;
's avatar
committed
414 415 416 417 418 419 420
		}	
	}

	hashval = (htonl(daddr)*dp) % HASHTABLESIZE;

	for(temp = skypelist[hashval]->head, prev = skypelist[hashval]->head; temp != NULL; prev = temp, temp = temp->next) {
		if(((temp->addr == saddr && temp->port == sp) || (temp->addr == daddr && temp->port == dp))) {
's avatar
committed
421 422
//			gettimeofday(&(temp->ts), NULL);
			temp->ts = ts;
423
			pkt_head->color = SKYPE_COLOR;
's avatar
committed
424 425 426 427
			return 1;
		}
		
		// flow cleanup
's avatar
committed
428
		if(ts.tv_sec - temp->ts.tv_sec > 600) {
's avatar
committed
429 430 431 432 433 434 435 436
			if(temp == skypelist[hashval]->head) {
				skypelist[hashval]->head = temp->next;
			}
			else {
				prev->next = temp->next;
			}
			temp->next = NULL;
			free(temp);
's avatar
committed
437
			temp = prev;
's avatar
committed
438 439 440 441 442 443 444 445 446 447 448
		}	
	}

	// not an already skype machine
	// looking if it has talk with the skype UI and we are on the port measuring process

//	printf("source address %s %d-> ", inet_ntoa(source), sp);
//	printf("\tadding address %s %d\n", inet_ntoa(dest), dp);

	hashval = (htonl(saddr)) % HASHTABLESIZE;

's avatar
committed
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
	if(iph->protocol == 17) {
		for(temp = cntlist[hashval]->head, prev = cntlist[hashval]->head; temp != NULL; prev = temp, temp = temp->next) {
			if((temp->addr == saddr)) {
				//printf("----adding usage for port %d\n", sp);
				ret = add_port_usage(temp, sp, ts);
				
				if(ret == 2) {
					// found a skype IP/port pair and adding it to list
					//printf("found IP/port pair with top port %d\n", temp->top_port->port);
					temp->port = temp->top_port->port;
					clean_port_list(temp);
					
					// remove form cntlist
					if(temp == cntlist[hashval]->head) {
						cntlist[hashval]->head = temp->next;
					}
					else {
						prev->next = temp->next;
					}
					
					// adding skype IP/port pair to hashtable skypelist
					skype_hashval = (htonl(saddr)*sp) % HASHTABLESIZE;
's avatar
committed
471 472
	//				gettimeofday(&(temp->ts), NULL);
					temp->ts = ts;
's avatar
committed
473 474 475 476
					temp->next = skypelist[skype_hashval]->head;
					skypelist[skype_hashval]->head = temp;

					//printf("Found Skype port\n");
's avatar
committed
477
#ifdef __TRACKFLIB_LOGGING__
's avatar
committed
478
					write_to_log("Skype", "Found_Skype_port", iph->protocol, source, temp->top_port->port, 0, 0, p_b, len);
's avatar
committed
479
#endif
's avatar
committed
480 481 482 483 484 485 486 487
					free(temp->top_port);
					temp->top_port = NULL;

					pkt_head->color = SKYPE_COLOR;
					return 1;
				}
			}
			
's avatar
committed
488
			if(ts.tv_sec - temp->ts.tv_sec > 20) { 
's avatar
committed
489
				//printf("removing data from cntlist\n");
's avatar
committed
490
				if(temp == cntlist[hashval]->head) {
's avatar
committed
491
					cntlist[hashval]->head = temp->next;
's avatar
committed
492 493 494 495
				}
				else {
					prev->next = temp->next;
				}
's avatar
committed
496 497 498
				temp->next = NULL;
				free(temp);
				temp = prev;
's avatar
committed
499 500 501 502 503 504
			}
		}
	}

	hashval = (htonl(daddr)) % HASHTABLESIZE;
	
's avatar
committed
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525
	if(iph->protocol == 17) {
		for(temp = cntlist[hashval]->head, prev = cntlist[hashval]->head; temp != NULL; prev = temp, temp = temp->next) {
			if((temp->addr == daddr)) {
				ret = add_port_usage(temp, dp, ts);
				//printf("adding usage for port %d\n", dp);
				
				if(ret == 2) {
					// found a skype IP/port pair and adding it to list
					//printf("found IP/port pair with top port %d\n", temp->top_port->port);
					temp->port = temp->top_port->port;
					clean_port_list(temp);
					
					// remove form cntlist
					if(temp == cntlist[hashval]->head) {
						cntlist[hashval]->head = temp->next;
					}
					else {
						prev->next = temp->next;
					}
					
					// adding skype IP/port pair to hashtable skypelist
's avatar
committed
526 527 528
					skype_hashval = (htonl(daddr)*dp) % HASHTABLESIZE;
//					gettimeofday(&(temp->ts), NULL);
					temp->ts = ts;
's avatar
committed
529 530 531 532
					temp->next = skypelist[skype_hashval]->head;
					skypelist[skype_hashval]->head = temp;


's avatar
committed
533
#ifdef __TRACKFLIB_LOGGING__
's avatar
committed
534
					write_to_log("Skype", "Found_Skype_port", iph->protocol, source, temp->top_port->port, 0, 0, p_b, len);
's avatar
committed
535
#endif
's avatar
committed
536 537 538 539 540 541 542 543
					free(temp->top_port);
					temp->top_port = NULL;

					pkt_head->color = SKYPE_COLOR;
					return 1;
				}
			}
			
's avatar
committed
544
			if(ts.tv_sec - temp->ts.tv_sec > 20) { 
's avatar
committed
545
				//printf("removing port after 10 secs daddr\n");
's avatar
committed
546
				if(temp == cntlist[hashval]->head) {
's avatar
committed
547
					cntlist[hashval]->head = temp->next;
's avatar
committed
548 549 550 551
				}
				else {
					prev->next = temp->next;
				}
's avatar
committed
552 553 554
				temp->next = NULL;
				free(temp);
				temp = prev;
's avatar
committed
555 556 557 558 559 560 561 562 563 564
			}
		}
	}

	// neither that.
	// we are now looking if we have a conversation with the skype ui
	for(i = 0; ((((struct mapid_skype*)instance->internal_data)->skype_host_addrs[i])) != NULL; i++) {
		if(source.s_addr == (*((struct in_addr *)((struct mapid_skype*)instance->internal_data)->skype_host_addrs[i])).s_addr) {
			// found traffic from skype ui
			add_to_ui_hash(instance, iph->protocol, daddr, ts);
's avatar
committed
565
			//printf("\tadding address %s\n", inet_ntoa(dest));
's avatar
committed
566 567 568
#ifdef __TRACKFLIB_LOGGING__
			write_to_log("Skype", "Host_Contacted_with_ui_skype_com", iph->protocol, source, sp, dest, dp, p_b, len);
#endif
569
			pkt_head->color = SKYPE_COLOR;
's avatar
committed
570 571 572 573 574 575 576 577 578 579
			return 1;
		}
		else if(dest.s_addr == (*((struct in_addr *)((struct mapid_skype*)instance->internal_data)->skype_host_addrs[i])).s_addr) {
			// found traffic to skype ui
			add_to_ui_hash(instance, iph->protocol, saddr, ts);
			//printf("\tadding address %s\n", inet_ntoa(source));
#ifdef __TRACKFLIB_LOGGING__
			write_to_log("Skype", "Host_Contacted_with_ui_skype_com", iph->protocol, source, sp, dest, dp, p_b, len);
#endif

580
			pkt_head->color = SKYPE_COLOR;
's avatar
committed
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
			return 1;
		}
	}

	return 0;
}

static int trackskype_cleanup(mapidflib_function_instance_t *instance) 
{
	struct filters *temp = NULL, *tmp = NULL;
	int i = 0;
	
  if(instance->internal_data != NULL){
	  for(i = 0; i < HASHTABLESIZE; i++) {
		  temp = ((struct mapid_skype*)instance->internal_data)->skypelist[i]->head;
		  
		  while(temp != NULL) {
			  tmp = temp;
			  temp = temp->next;
			  free(tmp);
's avatar
committed
601
			  tmp = NULL;
's avatar
committed
602 603 604 605 606 607 608 609 610
		  }

		
		  temp = ((struct mapid_skype*)instance->internal_data)->cntlist[i]->head;
		  
		  while(temp != NULL) {
			  tmp = temp;
			  temp = temp->next;
			  free(tmp);
's avatar
committed
611
			  tmp = NULL;
's avatar
committed
612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
		  }
	  }
	free(((struct mapid_skype*)instance->internal_data)->skypelist);
	free(((struct mapid_skype*)instance->internal_data)->cntlist);
	free(instance->internal_data);
  }
  return 0;
}

static mapidflib_function_def_t finfo={
  "",
  "TRACK_SKYPE",
  "Searches for SKYPE packets\n",
  "",
  MAPI_DEVICE_ALL,
  MAPIRES_NONE,
  0, //shm size
  0, //modifies_pkts
  1, //filters packets
  MAPIOPT_NONE,
  NULL,
  trackskype_init,
  trackskype_process,
  NULL, //get_result
  NULL, //reset
  trackskype_cleanup,
  NULL, //client_init
  NULL, //client_read_result
  NULL  //client_cleanup
};

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