1 /*
2 	file2pcap
3 	Code by Martin Zeiser
4 	Started July 2009
5 */
6 
7 
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <string.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <time.h>
16 #include <libgen.h>
17 #include <getopt.h>
18 
19 
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23 #include <errno.h>
24 
25 
26 
27 
28 #define  __FAVOR_BSD
29 #include <netinet/in_systm.h>
30 #include <netinet/in.h>
31 #include <netinet/ip.h>
32 #include <netinet/ip6.h>      // struct ip6_hdr
33 #include <netinet/tcp.h>
34 
35 
36 #include "file2pcap.h"
37 #include "ftp.h"
38 #include "http.h"
39 #include "http2.h"
40 #include "http-gzip.h"
41 #include "smtp.h"
42 #include "pop3.h"
43 #include "imap.h"
44 #include "crc32.h"
45 
46 unsigned short srcport, dstport;
47 struct pcap_packet_header ph;
48 
49 struct 	{
50 		int PCAPMAGIC;
51 		const short major_version;
52 		short minor_version;
53 		int GMT;
54 		int timestamp_granularity;
55 		int entire_packet;
56 		int assume_ethernet;
57 	} pcap_file_header = { 0xA1B2C3D4,2,4,0,0,65535,1};
58 
59 FILE *inFile, *outFile;
60 
61 
62 const int packetLen4 = (sizeof(SRC_ETHER)-1 + sizeof(DST_ETHER)-1 + sizeof(PROTO_ETHER)-1 + sizeof(struct ip) + sizeof(struct tcphdr));
63 const int packetLen6 = (sizeof(SRC_ETHER)-1 + sizeof(DST_ETHER)-1 + sizeof(PROTO_ETHER6)-1 + sizeof(struct ip6_hdr) + sizeof(struct tcphdr));
64 
65 
66 struct pcap_packet_header ph;
67 unsigned short srcport, dstport;
68 struct handover hoFtp;
69 
70 
71 
72 /***************************************************************************************/
73 
74 
usage()75 void usage() {
76 	char *helptext = 	"\nfile2pcap - developed by Martin Zeiser(mzeiser@cisco.com)\n"\
77 				"Version: " VERSION "\n"\
78 				"Takes a file as input and creates a pcap showing that file being transferred between hosts\n"\
79 				"\nOptions:\n"\
80 				"--block-size size\tspecify the payload size per packet[1 to 1200]\n\n"
81 				"--srcemail address\tspecify the sender's email address\n"
82 				"--dstemail address\tspecify the recipient's email address\n\n"
83 				"-e email encoding\r\n"
84 				"\t\t\t0 - base64\n"
85 				"\t\t\t1 - quoted printable\n"
86 				"\t\t\t2 - UU encoding\n"
87 				"\t\t\t[default: base64]\n\n"\
88 				"--http-encoder\t\t0 - default transfer\n"
89 				"\t\t\t1 - gzip compression\n"
90 				"\t\t\t2 - chunked encoding\n"
91 				"\t\t\t3 - gzip compression and chunked encoding\n"
92 				"-m mode\r\n"
93 				"\t\t\th - http GET (download)\r\n"
94 				"\t\t\th2 - http2 GET (download)\r\n"
95 				"\t\t\tH - http POST (upload)\r\n"
96 				"\t\t\ts - smtp\r\n"
97 				"\t\t\tp - pop3\r\n"
98 				"\t\t\ti - imap\r\n"
99 				"\t\t\tf - active ftp\r\n"
100 				"\t\t\tF - passive ftp\r\n"
101 				"\t\t\t[default: http GET]\n\n"\
102 				"-o outfile\t\toutput filename [default: <filename>-<protocol>.pcap]\n"\
103 				"-p port[:port]\t\tspecify [source and] destination port\n"
104 				"\t\t\t-p 8080 will simulate a connection from a random port to port 8080\n"
105 				"\t\t\t-p 1234:80 will simulate a connection from port 1234 to port 80\n"
106 				"\t\t\t[default: use IANA assigned port for the protocol]\n\n"
107 				"--srcip ip_address\tspecify source IP address\n"
108 				"--dstip ip_address\tspecify destination IP address\n\n"
109 				"-6\t\t\tUse IPv6 instead of the default IPv4\n";
110 	char *usage = 		"\nUsage:\n"\
111 				"\t\t\tfile2pcap [options] infile\n";
112 	char *example =		"Examples:\n"\
113 				"\t\t\tfile2pcap malware.pdf\n"\
114 				"\t\t\tfile2pcap -mshp malware.pdf --http-encoder=1\n"\
115 				"\t\t\tfile2pcap -mH -p8080 malware.pdf\n"\
116 				"\t\t\tfile2pcap -mi malware.pdf -o outfile.pcap\n";
117 
118 	printf("%s\n", helptext);
119 	printf("%s\n", usage);
120 	printf("%s\n", example);
121 
122 	exit(0);
123 
124 return;
125 }
126 
127 /**********************************************************************************************************/
128 
ipChecksum(unsigned short * ptr,int nbytes)129 unsigned short ipChecksum (unsigned short *ptr, int nbytes)
130 {
131 	register long sum = 0;
132 	register u_short answer;
133 	u_short oddbyte;
134 
135 	while (nbytes > 1)
136 	{
137 		sum += *ptr++;
138 		nbytes -= 2;
139 	}
140 
141 	if (nbytes == 1)
142 	{
143 		oddbyte = 0;
144 		*((u_char *) & oddbyte) = *(u_char *) ptr;
145 		sum += oddbyte;
146 	}
147 
148 	sum = (sum >> 16) + (sum & 0xffff);
149 	sum += (sum >> 16);
150 	answer = ~sum;
151 	return (answer);
152 }
153 
154 
155 /*****************************************************************/
156 // direction: 0 == client to server. 1 == server to client.
157 
craftIpv4(char * payload,int payloadSize,char direction,struct handover * ho)158 int craftIpv4(char *payload, int payloadSize, char direction, struct handover *ho) {
159 	unsigned int minimalLength;
160 	size_t packetLen = sizeof (struct ip) + payloadSize;
161 	unsigned char minimalip[(minimalLength = 12 + payloadSize)];
162 	char ipv4packet[packetLen];
163 	struct ip *iphdr = (struct ip *) ipv4packet;
164 
165 
166 	memset (ipv4packet, 0, packetLen);
167 	memset (minimalip, 0, minimalLength);
168 
169 
170 	if(payload!=NULL)
171 		memcpy(((unsigned char*)(ipv4packet)) + sizeof (struct ip), payload, payloadSize);
172 
173 
174 	if(direction==TO_SERVER)
175 	{
176 		*((unsigned long *) ((unsigned char *) minimalip + 0)) = ho->srcIP;
177 	        *((unsigned long *) ((unsigned char *) minimalip + 4)) = ho->dstIP;
178 	}
179 	else
180 	{
181 		*((unsigned long *) ((unsigned char *) minimalip + 0)) = ho->dstIP;
182 		*((unsigned long *) ((unsigned char *) minimalip + 4)) = ho->srcIP;
183 	}
184 
185 	*((unsigned char *) ((unsigned char *) minimalip + 8)) = 0;
186 	*((unsigned char *) ((unsigned char *) minimalip + 9)) = IPPROTO_TCP;
187 	*((unsigned short *) ((unsigned char *) minimalip + 10)) = htons (packetLen - sizeof (struct ip));
188 
189 	iphdr->ip_v = 4;
190 	iphdr->ip_hl = 5;
191 
192 	iphdr->ip_id = rand() & 0xFFFF;
193 
194 	if(direction == TO_SERVER)
195 	{
196 		iphdr->ip_src.s_addr = ho->srcIP;
197 		iphdr->ip_dst.s_addr = ho->dstIP;
198 	}
199 	else
200 	{
201 		iphdr->ip_src.s_addr = ho->dstIP;
202 		iphdr->ip_dst.s_addr = ho->srcIP;
203 	}
204 	iphdr->ip_p = IPPROTO_TCP;
205 	iphdr->ip_ttl = 64;
206 	iphdr->ip_len = ntohs(packetLen);
207 	iphdr->ip_sum=0;
208 	iphdr->ip_sum = ipChecksum ((u_short *) iphdr, sizeof (struct ip));
209 
210 	memcpy (minimalip + 12, ((unsigned char *) ipv4packet) + sizeof (struct ip), packetLen - sizeof (struct ip));
211 
212 	write(fileno(outFile), ipv4packet, packetLen);
213 
214 
215 return 0;
216 }
217 
218 /*****************************************************************/
219 // direction: 0 == client to server. 1 == server to client.
220 
craftIpv6(char * payload,int payloadSize,char direction,struct handover * ho)221 int craftIpv6(char *payload, int payloadSize, char direction, struct handover *ho) {
222 	size_t packetLen = sizeof (struct ip6_hdr) + payloadSize;
223 	char ipv6packet[packetLen];
224 	uint16_t tcp6_checksum (struct ip6_hdr, struct tcphdr);
225 	struct ip6_hdr *iphdr = (struct ip6_hdr*) ipv6packet;
226 
227 
228 	memset (ipv6packet, 0, sizeof(ipv6packet));
229 
230 
231 	if(payload!=NULL)
232 		memcpy(((unsigned char*)(ipv6packet)) + sizeof (struct ip6_hdr), payload, payloadSize);
233 
234 	iphdr->ip6_ctlun.ip6_un1.ip6_un1_hlim=64;
235 	iphdr->ip6_ctlun.ip6_un1.ip6_un1_flow=htonl ((6 << 28) | (0 << 20) | 0);
236 	iphdr->ip6_ctlun.ip6_un1.ip6_un1_plen=htons(packetLen-sizeof(struct ip6_hdr));
237 	iphdr->ip6_ctlun.ip6_un1.ip6_un1_nxt=IPPROTO_TCP;
238 
239 
240 
241 
242 	if(direction == TO_SERVER)
243 	{
244 		memcpy(&(iphdr->ip6_src), &ho->srcIP6, sizeof(iphdr->ip6_src));
245 		memcpy(&(iphdr->ip6_dst), &ho->dstIP6, sizeof(iphdr->ip6_dst));
246 	}
247 	else
248 	{
249 		memcpy(&(iphdr->ip6_src), &ho->dstIP6, sizeof(iphdr->ip6_src));
250 		memcpy(&(iphdr->ip6_dst), &ho->srcIP6, sizeof(iphdr->ip6_dst));
251 	}
252 
253 	write(fileno(outFile), ipv6packet, packetLen);
254 
255 
256 return 0;
257 }
258 
259 
260 
261 
262 /*****************************************************************/
263 // direction: 0 == client to server. 1 == server to client.
264 
craftTcp(char * payload,int payloadSize,char direction,unsigned char flags,struct handover * ho)265 int craftTcp(char *payload, int payloadSize, char direction, unsigned char flags, struct handover *ho) {
266 	size_t packetLen;
267 	char packet[(packetLen = sizeof (struct tcphdr) + payloadSize)];
268 	struct tcphdr *tcpheader = (struct tcphdr *) ((unsigned char *) packet);
269 	unsigned int minimalLength, minimalLength6;
270 	unsigned char minimalip[(minimalLength = 12 + sizeof (struct tcphdr) + payloadSize)];
271 	unsigned char minimalip6[(minimalLength6 = 40 + packetLen)];
272 	struct v6_pseudo_header *v6PseudoHeader = (struct v6_pseudo_header*)minimalip6;
273 
274 
275 
276 	memset (packet, 0, packetLen);
277 
278 	if(payload!=NULL)
279 		memcpy(((unsigned char*)(packet)) + sizeof (struct tcphdr), payload, payloadSize);
280 
281 
282 	if(ho->ipV == 4)
283 	{
284         	if(direction==TO_SERVER)
285         	{
286         	        *((unsigned long *) ((unsigned char *) minimalip + 0)) = ho->srcIP;
287         	        *((unsigned long *) ((unsigned char *) minimalip + 4)) = ho->dstIP;
288         	}
289         	else
290         	{
291                 	*((unsigned long *) ((unsigned char *) minimalip + 0)) = ho->dstIP;
292                 	*((unsigned long *) ((unsigned char *) minimalip + 4)) = ho->srcIP;
293         	}
294 
295 		*((unsigned char *) ((unsigned char *) minimalip + 8)) = 0;
296         	*((unsigned char *) ((unsigned char *) minimalip + 9)) = IPPROTO_TCP;
297         	*((unsigned short *) ((unsigned char *) minimalip + 10)) = htons (packetLen);
298 	}
299 	else
300 	{
301 		memset(v6PseudoHeader, 0, sizeof(*v6PseudoHeader));
302 
303 		if(direction == TO_SERVER)
304 		{
305 			memcpy(&(v6PseudoHeader->src), &ho->srcIP6, sizeof(v6PseudoHeader->src));
306 			memcpy(&(v6PseudoHeader->dst), &ho->dstIP6, sizeof(v6PseudoHeader->dst));
307 		}
308 		else
309 		{
310  			memcpy(&(v6PseudoHeader->src), &ho->dstIP6, sizeof(v6PseudoHeader->src));
311 			memcpy(&(v6PseudoHeader->dst), &ho->srcIP6, sizeof(v6PseudoHeader->dst));
312 		}
313 
314 		v6PseudoHeader->length = htonl(packetLen);
315 		v6PseudoHeader->next_header = IPPROTO_TCP;
316 
317 		tcpheader->th_sum = 0;
318 	}
319 
320 
321 	if(direction == TO_SERVER)
322 	{
323 		tcpheader->th_sport = htons(ho->srcPort);
324 		tcpheader->th_dport = htons(ho->dstPort);
325 	}
326 	else
327 	{
328 		tcpheader->th_sport = htons(ho->dstPort);
329 		tcpheader->th_dport = htons(ho->srcPort);
330 	}
331 
332 
333 	if(direction==TO_SERVER)
334 	{
335 		tcpheader->th_seq = htonl(ho->seq);
336 		tcpheader->th_ack = htonl(ho->ack_seq);
337 	}
338 	else
339 	{
340 		tcpheader->th_seq = htonl(ho->ack_seq);
341 		tcpheader->th_ack = htonl(ho->seq);
342 	}
343 
344 	tcpheader->th_off = ((sizeof (struct tcphdr)) / 4);
345 
346 	tcpheader->th_flags = flags;
347 
348 	tcpheader->th_win = htons (5840);
349 
350 	if(ho->ipV == 4)
351 	{
352 		memcpy (minimalip + 12, ((unsigned char *) packet), packetLen);
353 		tcpheader->th_sum = ipChecksum ((u_short *) & minimalip, minimalLength);
354 		craftIpv4(packet, packetLen, direction, ho);
355 	}
356 	else
357 	{
358 		memcpy (minimalip6 + 40, ((unsigned char *) packet), packetLen);
359 		tcpheader->th_sum = ipChecksum((u_short *) & minimalip6, minimalLength6);
360 		craftIpv6(packet, packetLen, direction, ho);
361 	}
362 
363 
364 	if(direction==TO_SERVER)
365 		ho->seq=ho->seq+payloadSize;
366 	else
367 		ho->ack_seq+=payloadSize;
368 
369 
370 return 0;
371 }
372 
373 
374 /**************************************************************************************************************/
375 
tcpSendString(struct handover * ho,char * string,char direction)376 int tcpSendString(struct handover *ho, char *string, char direction) {
377         int packetLen=-1, direction2=-1;
378 
379         if(direction==TO_SERVER)
380         {
381                 direction2 = FROM_SERVER;
382         }
383         else
384         {
385                 direction2 = TO_SERVER;
386         }
387 
388 	if(ho->ipV == 4)
389         	packetLen = packetLen4 + strlen(string);
390 	else
391 		packetLen = packetLen6 + strlen(string);
392 
393 	ph.time = ho->time;
394 	ph.usec = ho->usec;
395 
396 
397 	ph.usec += INTERVAL;
398 
399 	if((ph.usec + INTERVAL) >= 1000000)
400 	{
401 		ph.time+=1;
402 		ph.usec=0;
403 	}
404 
405 
406         ph.length1 = packetLen;
407         ph.length2 = packetLen;
408 
409         write(fileno(ho->outFile), &ph, sizeof(struct pcap_packet_header));
410 
411 
412 	if(direction == TO_SERVER)
413 		write(fileno(ho->outFile), ho->toEther, sizeof(ho->toEther)-1);
414 	else
415 		write(fileno(ho->outFile), ho->fromEther, sizeof(ho->fromEther)-1);
416 
417 
418         craftTcp(string, strlen(string), direction, TH_ACK|TH_PUSH, ho);
419 
420         //and now send the ack
421         ph.usec+=INTERVAL;
422         ph.length1=packetLen-strlen(string);
423         ph.length2=packetLen-strlen(string);
424         write(fileno(ho->outFile), &ph, sizeof(struct pcap_packet_header));
425 
426 	if(direction == TO_SERVER)
427 	        write(fileno(ho->outFile), ho->fromEther, sizeof(ho->fromEther)-1);
428 	else
429 	        write(fileno(ho->outFile), ho->toEther, sizeof(ho->toEther)-1);
430 
431 
432         craftTcp(NULL,0, direction2, TH_ACK, ho);
433 
434 	ho->time = ph.time;
435 	ho->usec = ph.usec;
436 
437 
438 return strlen(string);
439 }
440 
441 
442 /**************************************************************************************************************/
443 
tcpSendData(struct handover * ho,char * buffer,int length,char direction)444 int tcpSendData(struct handover *ho, char *buffer, int length, char direction) {
445         int packetLen=-1, direction2=-1;
446 
447         if(direction==TO_SERVER)
448         {
449                 direction2 = FROM_SERVER;
450         }
451         else
452         {
453                 direction2 = TO_SERVER;
454         }
455 
456 	if(ho->ipV == 4)
457         	packetLen = packetLen4 + length;
458 	else
459 		packetLen = packetLen6 + length;
460 
461 	ph.time = ho->time;
462 	ph.usec = ho->usec;
463 
464 
465 	ph.usec += INTERVAL;
466 
467 	if((ph.usec + INTERVAL) >= 1000000)
468 	{
469 		ph.time+=1;
470 		ph.usec=0;
471 	}
472 
473 
474         ph.length1 = packetLen;
475         ph.length2 = packetLen;
476 
477         write(fileno(ho->outFile), &ph, sizeof(struct pcap_packet_header));
478 
479 
480 	if(direction == TO_SERVER)
481 		write(fileno(ho->outFile), ho->toEther, sizeof(ho->toEther)-1);
482 	else
483 		write(fileno(ho->outFile), ho->fromEther, sizeof(ho->fromEther)-1);
484 
485 
486         craftTcp(buffer, length, direction, TH_ACK|TH_PUSH, ho);
487 
488         //and now send the ack
489         ph.usec+=INTERVAL;
490         ph.length1=packetLen-length;
491         ph.length2=packetLen-length;
492         write(fileno(ho->outFile), &ph, sizeof(struct pcap_packet_header));
493 
494 	if(direction == TO_SERVER)
495 	        write(fileno(ho->outFile), ho->fromEther, sizeof(ho->fromEther)-1);
496 	else
497 	        write(fileno(ho->outFile), ho->toEther, sizeof(ho->toEther)-1);
498 
499 
500         craftTcp(NULL,0, direction2, TH_ACK, ho);
501 
502 	ho->time = ph.time;
503 	ho->usec = ph.usec;
504 
505 
506 return length;
507 }
508 
509 
510 
511 
512 /**********************************************************************************************/
513 
514 
tcpHandshake(struct handover * ho)515 int tcpHandshake(struct handover *ho) {
516 	int packetLen;
517 
518 	if(ho->ipV == 4)
519 		packetLen = packetLen4;
520 	else
521 		packetLen = packetLen6;
522 
523        	ph.usec += INTERVAL;
524        	ph.length1 = packetLen;
525        	ph.length2 = packetLen;
526 
527 
528 	ho->seq=rand() & 0xfff;
529 	ho->seq+=1;
530 	ho->ack_seq=0;
531 
532 
533 	//client to server SYN
534 	write(fileno(outFile), &ph, sizeof(struct pcap_packet_header));
535 
536 	//replace that with a sprintf and a single write
537 
538 	write(fileno(outFile), ho->toEther, sizeof(ho->toEther)-1);
539 
540        	craftTcp(NULL, 0, TO_SERVER, TH_SYN, ho);  //direction 0 - client to server
541 
542 	ho->ack_seq=rand() & 0xfff;
543 	ho->ack_seq+=1;
544 	ho->seq+=1;
545 
546 	//and now send the SYN/ACK
547 	ph.usec+=INTERVAL;
548        	write(fileno(outFile), &ph, sizeof(struct pcap_packet_header));
549 	write(fileno(outFile), ho->fromEther, sizeof(ho->fromEther)-1);
550 	craftTcp(NULL,0, FROM_SERVER, TH_SYN|TH_ACK, ho);	//direction 1 - server to client
551 
552 	ho->ack_seq+=1;
553 
554 	//client to server ACK
555        	ph.usec += INTERVAL;
556 	write(fileno(outFile), &ph, sizeof(struct pcap_packet_header));
557 	write(fileno(outFile), ho->toEther, sizeof(ho->toEther)-1);
558        	craftTcp(NULL, 0, TO_SERVER, TH_ACK, ho);  //direction 0 - client to server
559 
560 
561 	ho->time = ph.time;
562 	ho->usec = ph.usec;
563 
564 
565 return 0;
566 }
567 
568 /*******************************************************************************************/
569 
570 
tcpShutdown(struct handover * ho)571 int tcpShutdown(struct handover *ho) {
572 	int packetLen;
573 
574 
575 	if(ho->ipV == 4)
576 		packetLen = packetLen4;
577 	else
578 		packetLen = packetLen6;
579 
580 
581 	ph.time = ho->time;
582 	ph.usec = ho->usec;
583 
584 
585        	ph.usec += INTERVAL;
586        	ph.length1 = packetLen;
587        	ph.length2 = packetLen;
588 
589 
590 	//server to client FIN
591 	write(fileno(outFile), &ph, sizeof(struct pcap_packet_header));
592 	write(fileno(outFile), ho->fromEther, sizeof(ho->fromEther)-1);
593        	craftTcp(NULL, 0, FROM_SERVER, TH_ACK|TH_FIN, ho);  //direction - server to client
594 
595 	ho->ack_seq+=1;
596 
597 	//and now send the ack
598 	ph.usec+=INTERVAL;
599        	write(fileno(outFile), &ph, sizeof(struct pcap_packet_header));
600 	write(fileno(outFile), ho->toEther, sizeof(ho->toEther)-1);
601 
602 	craftTcp(NULL,0, TO_SERVER, TH_ACK, ho);	//direction - client to server
603 
604 	//client to server FIN
605 	ph.usec+=INTERVAL;
606        	write(fileno(outFile), &ph, sizeof(struct pcap_packet_header));
607 	write(fileno(outFile), ho->toEther, sizeof(ho->toEther)-1);
608        	craftTcp(NULL, 0, TO_SERVER, TH_ACK|TH_FIN, ho);  //direction - client to server
609 
610 	ho->seq+=1;
611 
612 	//and now send the ack
613 	ph.usec+=INTERVAL;
614        	write(fileno(outFile), &ph, sizeof(struct pcap_packet_header));
615 	write(fileno(outFile), ho->fromEther, sizeof(ho->fromEther)-1);
616 	craftTcp(NULL,0, FROM_SERVER, TH_ACK, ho);	//direction - server to client
617 
618 
619 //	printf("Pcap replay length: %d second(s)\n", ph.time - 0x48f35358 + 1);
620 
621 return(0);
622 }
623 
624 
625 /****************************************************************************************************/
626 
openOutFile(struct handover * ho,char * inFileName,char * suffix)627 int openOutFile(struct handover *ho, char *inFileName, char *suffix){
628 	char buffer[500];
629 
630 
631 
632 	if(strlen(ho->dstFile) == 0)
633 	{
634 		snprintf(buffer, sizeof(buffer)-1,"%s%s", inFileName, suffix);
635 	}
636 	else
637 		snprintf(buffer, sizeof(buffer)-1, "%s", ho->dstFile);
638 
639 
640         if((outFile = fopen(buffer, "w"))==NULL)
641         {
642                 printf("Failed to open outfile %s\n", buffer);
643                 exit(-1);
644         }
645         else
646                 ho->outFile = outFile;
647 
648 	printf("Writing to %s\n", buffer);
649 
650         write(fileno(outFile), &pcap_file_header, sizeof(pcap_file_header));
651 
652 return 0;
653 }
654 
655 
656 
657 /*************************************************************************************************/
658 
ftp(struct handover * ho,char mode)659 int ftp(struct handover *ho, char mode) {
660 
661 	srcport = rand() & 0x7fff;        //0 <-> 32k
662 	srcport +=1025;
663 	hoFtp.srcPort=srcport;
664 
665 
666 	//initialize the time in the handover struct. The times have to be correct in all streams
667 	hoFtp.time = ho->time;
668 	hoFtp.usec = ho->usec;
669 
670 	//snprintf(hoFtp.srcFile, sizeof(hoFtp.srcFile)-1, "%s", ho->srcFile);
671 	hoFtp.inFile = ho->inFile;
672 	hoFtp.outFile = ho->outFile;
673 	hoFtp.blockSize = ho->blockSize;
674 
675 	//fill all the parameters into the handover struct
676 	if(mode == PASSIVE_FTP)
677 	{
678 		hoFtp.srcIP = ho->srcIP;
679 		hoFtp.dstIP = ho->dstIP;
680 
681 		memcpy(hoFtp.srcIP6, ho->srcIP6, sizeof(hoFtp.srcIP6));
682 		memcpy(hoFtp.dstIP6, ho->dstIP6, sizeof(hoFtp.dstIP6));
683 
684 
685 		memcpy(hoFtp.srcEther, DST_ETHER, sizeof(hoFtp.dstEther));
686 		memcpy(hoFtp.dstEther, SRC_ETHER, sizeof(hoFtp.srcEther));
687 
688 	}
689 	else
690 	{
691 		hoFtp.srcPort = htons(20);
692 		hoFtp.srcIP = ho->dstIP;
693 		hoFtp.dstIP = ho->srcIP;
694 
695 		memcpy(hoFtp.srcIP6, ho->dstIP6, sizeof(hoFtp.srcIP6));
696 		memcpy(hoFtp.dstIP6, ho->srcIP6, sizeof(hoFtp.dstIP6));
697 
698 
699 		memcpy(hoFtp.srcEther, DST_ETHER, sizeof(hoFtp.srcEther));
700 		memcpy(hoFtp.dstEther, SRC_ETHER, sizeof(hoFtp.dstEther));
701 	}
702 
703 	//Set the protocol the Ethernet is carrying. IPv4 or IPv6
704 	if(hoFtp.ipV == 4)
705 		memcpy(hoFtp.protoEther, PROTO_ETHER, 2);
706 	else
707 		memcpy(hoFtp.protoEther, PROTO_ETHER6, 2);
708 
709 
710 	if(ho->srcFile != NULL)
711 		snprintf(hoFtp.srcFile, sizeof(hoFtp.srcFile),"%s", ho->srcFile);
712 
713 	if(ho->dstFile != NULL)
714 		snprintf(hoFtp.dstFile, sizeof(hoFtp.dstFile),"%s", ho->dstFile);
715 
716 	hoFtp.dstPort = 20;
717 
718 	if(mode == PASSIVE_FTP)
719 	{
720 		hoFtp.direction = FROM_SERVER;
721 		memcpy(hoFtp.toEther, hoFtp.dstEther, 6);
722         	memcpy(hoFtp.toEther+6, hoFtp.srcEther, 6);
723         	memcpy(hoFtp.toEther+12, hoFtp.protoEther, 2);
724 
725         	memcpy(hoFtp.fromEther, hoFtp.srcEther, 6);
726         	memcpy(hoFtp.fromEther+6, hoFtp.dstEther, 6);
727         	memcpy(hoFtp.fromEther+12, hoFtp.protoEther, 2);
728 
729 	}
730 	else
731 	{
732 		ho->direction = FROM_SERVER;
733 		hoFtp.direction = TO_SERVER;
734 
735 		memcpy(hoFtp.toEther, hoFtp.srcEther, 6);
736 	       	memcpy(hoFtp.toEther+6, hoFtp.dstEther, 6);
737         	memcpy(hoFtp.toEther+12, hoFtp.protoEther, 2);
738 
739         	memcpy(hoFtp.fromEther, hoFtp.dstEther, 6);
740         	memcpy(hoFtp.fromEther+6, hoFtp.srcEther, 6);
741         	memcpy(hoFtp.fromEther+12, hoFtp.protoEther, 2);
742 	}
743 
744 
745 	tcpHandshake(ho);
746 
747 	if(mode == ACTIVE_FTP)
748 		hoFtp.dstPort = ftpCommandsStartActive(ho);
749 	else
750 		hoFtp.dstPort = ftpCommandsStartPassive(ho);
751 
752 	tcpHandshake(&hoFtp);
753 	ftpTransferFile(&hoFtp);
754 	tcpShutdown(&hoFtp);
755 
756 	ho->time=hoFtp.time;
757 	ho->usec=hoFtp.usec;
758 
759 	ftpCommandsEnd(ho);
760 	tcpShutdown(ho);
761 
762 return 0;
763 }
764 
765 /***********************************************************************************************/
766 
767 
768 
httpGet(struct handover * ho)769 int httpGet(struct handover *ho) {
770 	int ret;
771 
772         tcpHandshake(ho);
773 
774 	if(ho->httpEncoder == ENC_HTTP_GZIP || ho->httpEncoder == ENC_HTTP_GZIP_CHUNKED)
775 		compressGzip(ho);
776 
777 	httpGetRequest(ho);
778         httpGetRequestAcknowledge(ho);
779 	ho->direction = FROM_SERVER;
780         httpTransferFile(ho);
781 
782 	tcpShutdown(ho);
783 
784 return 0;
785 }
786 
787 /***********************************************************************************************/
788 
789 
http2Get(struct handover * ho)790 int http2Get(struct handover *ho) {
791 
792         tcpHandshake(ho);
793 	http2ConnectionUpgrade(ho);
794 	http2SwitchingProtocols(ho);
795 	http2ClientMagic(ho);
796 
797 	//send settings from server to client
798 	ho->direction = FROM_SERVER;
799 	http2Settings(ho);
800 
801 	//ack server settings and send settings from client to server
802 	ho->direction = TO_SERVER;
803 	http2SettingsAck(ho);
804 	http2Settings(ho);
805 
806 	//ack client settings
807 	ho->direction = FROM_SERVER;
808 	http2SettingsAck(ho);
809 
810 	ho->direction = TO_SERVER;
811 	http2ClientGetRequest(ho);
812 
813 	ho->direction = FROM_SERVER;
814  	http2Headers(ho);
815 	http2TransferFile(ho);
816 	http2DataStreamClose(ho);
817 	http2GoAway(ho);
818         tcpShutdown(ho);
819 
820 return 0;
821 }
822 
823 
824 /***********************************************************************************************/
825 
826 
827 
httpPost(struct handover * ho)828 int httpPost(struct handover *ho) {
829 
830         tcpHandshake(ho);
831 	httpPostRequest(ho);
832 	ho->direction = TO_SERVER;
833         httpTransferFile(ho);
834 	httpPostFinalBoundary(ho);
835         tcpShutdown(ho);
836 
837 return 0;
838 }
839 
840 
841 /*******************************************************************************************/
842 
smtp(struct handover * ho)843 int smtp(struct handover *ho) {
844 
845 	tcpHandshake(ho);
846 	smtpRequest(ho);
847 	tcpShutdown(ho);
848 
849 return 0;
850 }
851 
852 /*********************************************************************************************/
853 
pop3(struct handover * ho)854 int pop3(struct handover *ho) {
855 
856 	tcpHandshake(ho);
857 	pop3Request(ho);
858 	tcpShutdown(ho);
859 
860 return 0;
861 }
862 
863 
864 /********************************************************************************************/
865 
imap(struct handover * ho)866 int imap(struct handover *ho) {
867 
868 	tcpHandshake(ho);
869 	imapRequest(ho);
870 	tcpShutdown(ho);
871 
872 return 0;
873 }
874 
875 
876 /********************************************************************************************/
877 
878 
main(int argc,char ** argv)879 int main(int argc, char **argv) {
880 	char *modeString=NULL, *srcFile=NULL, *dstFile=NULL, *portString=NULL, *tok1=NULL, *tok2=NULL, *encoderString=NULL, *httpEncoderString=NULL, *srcEmail=NULL, *dstEmail=NULL;
881 	char *srcIP=NULL, *dstIP=NULL;
882 	int c, i, option_index=0;
883 	struct stat statbuf, statbuf2;
884 	struct handover ho;
885 	static struct option long_options[] =
886 	{
887 		{"6", no_argument, 0, '6'},
888 		{"block-size", required_argument, 0, 0},
889 //		{"chunk-size", required_argument, 0, 0},
890 		{"dstemail", required_argument, 0, 0},
891 		{"dstip", required_argument, 0, 0},
892 		{"email-encoder", required_argument, 0, 'e'},
893 		{"http-encoder", required_argument, 0, 0},
894 		{"mode", required_argument, 0, 'm'},
895 		{"outfile", required_argument, 0, 'o'},
896 		{"port", required_argument, 0, 'p'},
897 		{"srcemail", required_argument, 0, 0},
898 		{"srcip", required_argument, 0, 0},
899 		{"verbose", no_argument, 0, 'v'},
900 		{0, 0, 0, 0}
901 	};
902 
903 
904 
905 	if(argc < 2)
906 		usage();
907 
908 
909 	memset(ho.srcEmail, 0, sizeof(ho.srcEmail));
910 	memset(ho.dstEmail, 0, sizeof(ho.dstEmail));
911 
912 	//Default is IPv4
913 	ho.ipV = 4;
914 	ho.verbose=FALSE;
915 	ho.blockSize=READ_SIZE;
916 	ho.srcIP = inet_addr(SRC_IP4);
917 	ho.dstIP = inet_addr(DST_IP4);
918 
919 	hoFtp.ipV = 4;
920 
921 	ho.httpEncoder = ENC_HTTP_DEFAULT;
922 	snprintf(ho.srcEmail, sizeof(ho.srcEmail)-1, "%s", SRC_EMAIL);
923 	snprintf(ho.dstEmail, sizeof(ho.dstEmail)-1, "%s", DST_EMAIL);
924 
925 	while ((c = getopt_long (argc, argv, "e:m:o:p:v6", long_options, &option_index)) != -1)
926         {
927 		if(c == -1)
928 			break;
929 
930                 switch (c)
931                 {
932 
933 			case 0:	//long option names
934 //				printf("option %s", long_options[option_index].name);
935 
936 				if (strcmp(long_options[option_index].name, "http-encoder")==0)
937 				{
938 					httpEncoderString = (char*) strdup(optarg);
939 					break;
940 				}
941 				else if(strcmp(long_options[option_index].name,"block-size")==0)
942 				{
943 					ho.blockSize = atoi((char*) strdup(optarg));
944 					if(ho.blockSize < 0 || ho.blockSize > 1200)
945 					{
946 						usage();
947 						exit(-1);
948 					}
949 					break;
950 				}
951 				else if(strcmp(long_options[option_index].name,"srcemail")==0)
952 				{
953 					srcEmail = (char*) strdup(optarg);
954 					break;
955 				}
956 				else if(strcmp(long_options[option_index].name,"dstemail")==0)
957 				{
958 					dstEmail = (char*) strdup(optarg);
959 					break;
960 				}
961 				else if(strcmp(long_options[option_index].name,"srcip")==0)
962                                 {
963                                         srcIP = (char*) strdup(optarg);
964                                         break;
965                                 }
966                                 else if(strcmp(long_options[option_index].name,"dstip")==0)
967                                 {
968                                         dstIP = (char*) strdup(optarg);
969                                         break;
970                                 }
971 
972 				else
973 				{
974         	               		printf("Unknown parameter %s with arg %s", long_options[option_index].name, optarg);
975 					usage();
976 					exit(-1);
977 					break;
978 				}
979 
980 			case 'e':
981 				encoderString = (char*) strdup(optarg);
982 				break;
983 
984         	        case 'm':
985         	                modeString = (char *) strdup (optarg);
986                 	        break;
987 
988 			case 'o':
989 				dstFile = (char *) strdup(optarg);
990 				break;
991 
992 			case 'p':
993 				portString = (char *) strdup(optarg);
994 				break;
995 
996 			case '6':
997 				ho.ipV=6;
998 				hoFtp.ipV = 6;
999 				break;
1000 
1001  			case 'v':
1002 				ho.verbose=TRUE;
1003 				break;
1004 
1005 			default:
1006 				usage();
1007 				exit(0);
1008 		}
1009 	}
1010 
1011 	unlink(TMP_FILE);
1012 
1013 
1014 	if(optind < argc)
1015 	{
1016 		srcFile = (char*) strdup(argv[optind]);
1017 	}
1018 
1019 
1020 	if(srcEmail != NULL)
1021 	{
1022 		snprintf(ho.srcEmail, sizeof(ho.srcEmail)-1,"%s", srcEmail);
1023 		if(ho.verbose==TRUE)
1024 			printf("Using custom source email address: %s\n", srcEmail);
1025 	}
1026 
1027 	if(dstEmail != NULL)
1028 	{
1029 		snprintf(ho.dstEmail, sizeof(ho.dstEmail)-1, "%s", dstEmail);
1030 		if(ho.verbose==TRUE)
1031 			printf("Using custom destination email address: %s\n", dstEmail);
1032 	}
1033 
1034 
1035 
1036         if((srcFile == NULL))
1037 	{
1038 		printf("Input file not found\n");
1039 		exit(-1);
1040 	}
1041 
1042 	//check if the input file is a directory, quit if true
1043 	if(stat(srcFile, &statbuf)==0)
1044 	{
1045 		if(S_ISDIR(statbuf.st_mode))
1046 		{
1047 			printf("Input has to be a file, not a directory\n");
1048 			exit(-1);
1049 		}
1050 	}
1051 	else
1052 	{
1053 		printf("Input file %s not found\n", srcFile);
1054 		exit(-1);
1055 	}
1056 
1057 	if((inFile = fopen(srcFile, "r"))==NULL)
1058 	{
1059 		printf("Failed to open infile %s\n", srcFile);
1060 		exit(-1);
1061 	}
1062 	else
1063 	{
1064 		ho.inFile=inFile;
1065 		hoFtp.inFile=inFile;
1066 	}
1067 
1068 	ho.inFileSize = statbuf.st_size;
1069 
1070 	//init the PRNG
1071 	srand(time(NULL));
1072 
1073 	srcport = rand() & 0x7fff;        //0 <-> 32k
1074 	srcport +=1025;
1075 	ho.srcPort=srcport;
1076 
1077 
1078 
1079         ph.time = 0x48f35358;
1080         ph.usec=0;
1081 
1082 	//initialize the time in the handover struct. The times have to be correct in all streams
1083 	ho.time = ph.time;
1084 	ho.usec = ph.usec;
1085 
1086 
1087 	if(srcIP != NULL)
1088 	{
1089         	ho.srcIP = inet_addr(srcIP);
1090 		if(ho.verbose==TRUE)
1091 	        	printf("Using custom source IP: %s\n", srcIP);
1092     	}
1093 
1094 	if(dstIP != NULL)
1095 	{
1096         	ho.dstIP = inet_addr(dstIP);
1097 		if(ho.verbose==TRUE)
1098 	        	printf("Using custom destination IP: %s\n", dstIP);
1099 	}
1100 
1101 	inet_pton(AF_INET6, SRC_IP6, &(ho.srcIP6));
1102 	inet_pton(AF_INET6, DST_IP6, &(ho.dstIP6));
1103 	memcpy(ho.srcEther, SRC_ETHER, sizeof(ho.srcEther));
1104 	memcpy(ho.dstEther, DST_ETHER, sizeof(ho.dstEther));
1105 
1106 	//Set the protocol the Ethernet is carrying. IPv4 or IPv6
1107 	if(ho.ipV == 4)
1108 		memcpy(ho.protoEther, PROTO_ETHER, 2);
1109 	else
1110 		memcpy(ho.protoEther, PROTO_ETHER6, 2);
1111 
1112 
1113 	snprintf(ho.srcFile, sizeof(ho.srcFile)-1,"%s", srcFile);
1114 
1115 	memset(ho.dstFile, 0, sizeof(ho.dstFile));
1116 	if(dstFile != NULL)
1117 	{
1118 		if(stat(dstFile, &statbuf2) ==0)
1119 		{
1120 			if((statbuf.st_dev == statbuf2.st_dev) && (statbuf.st_ino == statbuf2.st_ino))
1121 			{
1122 				printf("Output file cannot be input file!\n");
1123 				exit(-1);
1124 			}
1125 		}
1126 
1127 		snprintf(ho.dstFile, sizeof(ho.dstFile)-1,"%s", dstFile);
1128 	}
1129 
1130 	ho.outFile = NULL;
1131 	ho.encoder = ENC_BASE64;
1132 	ho.dstPort = 0;
1133 
1134 
1135 	memcpy(ho.toEther, ho.srcEther, 6);
1136         memcpy(ho.toEther+6, ho.dstEther, 6);
1137         memcpy(ho.toEther+12, ho.protoEther, 2);
1138 
1139         memcpy(ho.fromEther, ho.dstEther, 6);
1140         memcpy(ho.fromEther+6, ho.srcEther, 6);
1141         memcpy(ho.fromEther+12, ho.protoEther, 2);
1142 
1143 
1144 
1145 	if(portString != NULL)
1146 	{
1147 		if(strstr(portString,":") != NULL)
1148 		{
1149 			tok1=strtok(portString,":");
1150 			ho.srcPort=atoi(tok1);
1151 
1152 			if(tok1!=NULL)
1153 				tok2=strtok(NULL,":");
1154 			else
1155 			{
1156 				usage();
1157 				exit(-1);
1158 			}
1159 
1160 			if(tok2!=NULL)
1161 				ho.dstPort = atoi(tok2);
1162 			else
1163 			{
1164 				usage();
1165 				exit(-1);
1166 			}
1167 		}
1168 		else
1169 		{
1170 			ho.dstPort=atoi(portString);
1171 		}
1172 	}
1173 
1174 
1175 
1176 
1177 	if(encoderString != NULL)
1178 	{
1179 		switch(atoi(encoderString))
1180 		{
1181 			case 0:
1182 				ho.encoder = ENC_BASE64;
1183 				break;
1184 			case 1:
1185 				ho.encoder = ENC_QUOTED_PRINTABLE;
1186 				break;
1187 			case 2:
1188 				ho.encoder = ENC_UU;
1189 				break;
1190 
1191 		}
1192 	}
1193 
1194 
1195 
1196 	if(httpEncoderString != NULL)
1197 	{
1198 		switch(atoi(httpEncoderString))
1199 		{
1200 			case 0:
1201 				ho.httpEncoder = ENC_HTTP_DEFAULT;
1202 				break;
1203 			case 1:
1204 				ho.httpEncoder = ENC_HTTP_GZIP;
1205 				break;
1206 			case 2:
1207 				ho.httpEncoder = ENC_HTTP_CHUNKED;
1208 				break;
1209 			case 3:
1210 				ho.httpEncoder = ENC_HTTP_GZIP_CHUNKED;
1211 				break;
1212 			default:
1213 				usage();
1214 				exit(-1);
1215 
1216 		}
1217 	}
1218 
1219 
1220 
1221 	if(modeString != NULL)
1222 	{
1223 		if(strlen(modeString) > 1)
1224 		{
1225 			if(ho.dstPort != 0)
1226 				printf("Specifying a destination port is not possible when using multiple modes. Switching to default destination ports.\n");
1227 
1228 			ho.dstPort = 0;
1229 
1230 			if(dstFile != NULL)
1231 			{
1232 				printf("Specifying an output filename does not work when using multiple modes\n");
1233 				usage();
1234 				exit(-1);
1235 			}
1236 		}
1237 
1238 
1239 
1240 		for(i=0; i < strlen(modeString); i++)
1241 		{
1242 			switch (modeString[i])
1243 			{
1244 				case 'f':
1245 					if(ho.dstPort == 0)
1246 						ho.dstPort = 21;
1247 
1248 					openOutFile(&ho, basename(srcFile), "-ftp-active.pcap");
1249 					ftp(&ho, ACTIVE_FTP);
1250 
1251 					fclose(ho.outFile);
1252 					ho.dstPort = 0;
1253 					break;
1254 
1255 				case 'F':
1256 
1257 					if(ho.dstPort == 0)
1258 						ho.dstPort = 21;
1259 
1260 					openOutFile(&ho, basename(srcFile), "-ftp-passive.pcap");
1261 					ftp(&ho, PASSIVE_FTP);
1262 
1263 					fclose(ho.outFile);
1264 					ho.dstPort = 0;
1265 					break;
1266 
1267 				case 'h':
1268 					if(ho.dstPort == 0)
1269 						ho.dstPort = 80;
1270 
1271 					if(modeString[i+1] == '2')
1272 					{
1273 						openOutFile(&ho, basename(srcFile), "-http2-get.pcap");
1274 						http2Get(&ho);
1275 						i++;
1276 					}
1277 					else
1278 					{
1279 						openOutFile(&ho, basename(srcFile), "-http-get.pcap");
1280 						httpGet(&ho);
1281 					}
1282 
1283 					fclose(ho.outFile);
1284 					ho.dstPort = 0;
1285 					break;
1286 
1287 				case 'H':
1288 					if(ho.dstPort == 0)
1289 						ho.dstPort = 80;
1290 					openOutFile(&ho, basename(srcFile), "-http-post.pcap");
1291 					httpPost(&ho);
1292 					fclose(ho.outFile);
1293 					ho.dstPort = 0;
1294 					break;
1295 
1296 
1297 				case 's':
1298 					if(ho.dstPort == 0)
1299 						ho.dstPort = 25;
1300 					openOutFile(&ho, basename(srcFile), "-smtp.pcap");
1301 					smtp(&ho);
1302 					fclose(ho.outFile);
1303 					ho.dstPort = 0;
1304 					break;
1305 
1306 				case 'p':
1307 					if(ho.dstPort == 0)
1308 						ho.dstPort = 110;
1309                                         openOutFile(&ho, basename(srcFile), "-pop3.pcap");
1310 					pop3(&ho);
1311 					fclose(ho.outFile);
1312 					ho.dstPort = 0;
1313 					break;
1314 
1315 				case 'i':
1316 					if(ho.dstPort == 0)
1317 						ho.dstPort = 143;
1318                                         openOutFile(&ho, basename(srcFile), "-imap.pcap");
1319 					imap(&ho);
1320 					fclose(ho.outFile);
1321 					ho.dstPort = 0;
1322 					break;
1323 
1324 				case 'x':
1325 					if(ho.dstPort == 0)
1326 						ho.dstPort = 80;
1327 					openOutFile(&ho, basename(srcFile), "-http2-get.pcap");
1328 
1329 
1330 					http2Get(&ho);
1331 					fclose(ho.outFile);
1332 					ho.dstPort = 0;
1333 					break;
1334 
1335 
1336 
1337 
1338 				default:
1339 					usage();
1340 					exit(-1);
1341 					break;
1342 			}
1343 		}
1344 	}
1345 	else
1346 	{
1347 		if(ho.dstPort == 0)
1348 			ho.dstPort = 80;
1349 		openOutFile(&ho, basename(srcFile), "-http-get.pcap");
1350 		httpGet(&ho);
1351 		fclose(ho.outFile);
1352 	}
1353 
1354 
1355 	unlink(TMP_FILE);
1356 exit(0);
1357 }
1358 
1359