1 /*
2  * $smu-mark$
3  * $name: sendip_handler.c$
4  * $author: Salvatore Sanfilippo <antirez@invece.org>$
5  * $copyright: Copyright (C) 1999 by Salvatore Sanfilippo$
6  * $license: This software is under GPL version 2 of license$
7  * $date: Fri Nov  5 11:55:49 MET 1999$
8  * $rev: 3$
9  */
10 
11 /* $Id: sendip_handler.c,v 1.2 2003/09/01 00:22:06 antirez Exp $ */
12 
13 #include <stdio.h>
14 
15 #include "hping2.h"
16 #include "globals.h"
17 
send_ip_handler(char * packet,unsigned int size)18 void send_ip_handler(char *packet, unsigned int size)
19 {
20 	ip_optlen = ip_opt_build(ip_opt);
21 
22 	if (!opt_fragment && (size+ip_optlen+20 >= h_if_mtu))
23 	{
24 		/* auto-activate fragmentation */
25 		virtual_mtu = h_if_mtu-20;
26 		virtual_mtu = virtual_mtu - (virtual_mtu % 8);
27 		opt_fragment = TRUE;
28 		opt_mf = opt_df = FALSE; /* deactivate incompatible options */
29 		if (opt_verbose || opt_debug)
30 			printf("auto-activate fragmentation, fragments size: %d\n", virtual_mtu);
31 	}
32 
33 	if (!opt_fragment)
34 	{
35 		unsigned short fragment_flag = 0;
36 
37 		if (opt_mf) fragment_flag |= MF; /* more fragments */
38 		if (opt_df) fragment_flag |= DF; /* dont fragment */
39 		send_ip((char*)&local.sin_addr,
40 			(char*)&remote.sin_addr,
41 			packet, size, fragment_flag, ip_frag_offset,
42 			ip_opt, ip_optlen);
43 	}
44 	else
45 	{
46 		unsigned int remainder = size;
47 		int frag_offset = 0;
48 
49 		while(1) {
50 			if (remainder <= virtual_mtu)
51 				break;
52 
53 			send_ip((char*)&local.sin_addr,
54 				(char*)&remote.sin_addr,
55 				packet+frag_offset,
56 				virtual_mtu, MF, frag_offset,
57 				ip_opt, ip_optlen);
58 
59 			remainder-=virtual_mtu;
60 			frag_offset+=virtual_mtu;
61 		}
62 
63 		send_ip((char*)&local.sin_addr,
64 			(char*)&remote.sin_addr,
65 			packet+frag_offset,
66 			remainder, NF, frag_offset,
67 			ip_opt, ip_optlen);
68 	}
69 }
70