1 /*
2  * $smu-mark$
3  * $name: sendtcp.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: 8$
9  */
10 
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <time.h>
15 #include <sys/time.h>
16 #include <unistd.h>
17 #include <signal.h>
18 
19 #include "hping2.h"
20 #include "globals.h"
21 
send_tcp(void)22 void send_tcp(void)
23 {
24 	int			packet_size;
25 	int			tcp_opt_size = 0;
26 	char			*packet, *data;
27 	struct mytcphdr		*tcp;
28 	struct pseudohdr	*pseudoheader;
29 	unsigned char		*tstamp;
30 
31 	if (opt_tcp_timestamp)
32 		tcp_opt_size = 12;
33 
34 	packet_size = TCPHDR_SIZE + tcp_opt_size + data_size;
35 	packet = malloc(PSEUDOHDR_SIZE + packet_size);
36 	if (packet == NULL) {
37 		perror("[send_tcphdr] malloc()");
38 		return;
39 	}
40 	pseudoheader = (struct pseudohdr*) packet;
41 	tcp =  (struct mytcphdr*) (packet+PSEUDOHDR_SIZE);
42 	tstamp = (unsigned char*) (packet+PSEUDOHDR_SIZE+TCPHDR_SIZE);
43 	data = (char*) (packet+PSEUDOHDR_SIZE+TCPHDR_SIZE+tcp_opt_size);
44 
45 	memset(packet, 0, PSEUDOHDR_SIZE+packet_size);
46 
47 	/* tcp pseudo header */
48 	memcpy(&pseudoheader->saddr, &local.sin_addr.s_addr, 4);
49 	memcpy(&pseudoheader->daddr, &remote.sin_addr.s_addr, 4);
50 	pseudoheader->protocol		= 6; /* tcp */
51 	pseudoheader->lenght		= htons(TCPHDR_SIZE+tcp_opt_size+data_size);
52 
53 	/* tcp header */
54 	tcp->th_dport	= htons(dst_port);
55 	tcp->th_sport	= htons(src_port);
56 
57 	/* sequence number and ack are random if not set */
58 	tcp->th_seq = (set_seqnum) ? htonl(tcp_seqnum) : htonl(rand());
59 	tcp->th_ack = (set_ack) ? htonl(tcp_ack) : htonl(rand());
60 
61 	tcp->th_off	= src_thoff + (tcp_opt_size >> 2);
62 	tcp->th_win	= htons(src_winsize);
63 	tcp->th_flags	= tcp_th_flags;
64 
65 	/* tcp timestamp option */
66 	if (opt_tcp_timestamp) {
67 		__u32 randts = rand() ^ (rand() << 16);
68 		tstamp[0] = tstamp[1] = 1; /* NOOP */
69 		tstamp[2] = 8;
70 		tstamp[3] = 10; /* 10 bytes, kind+len+T1+T2 */
71 		memcpy(tstamp+4, &randts, 4); /* random */
72 		memset(tstamp+8, 0, 4); /* zero */
73 	}
74 
75 	/* data */
76 	data_handler(data, data_size);
77 
78 	/* compute checksum */
79 #ifdef STUPID_SOLARIS_CHECKSUM_BUG
80 	tcp->th_sum = packet_size;
81 #else
82 	tcp->th_sum = cksum((u_short*) packet, PSEUDOHDR_SIZE +
83 		      packet_size);
84 #endif
85 
86 	/* adds this pkt in delaytable */
87 	delaytable_add(sequence, src_port, time(NULL), get_usec(), S_SENT);
88 
89 	/* send packet */
90 	send_ip_handler(packet+PSEUDOHDR_SIZE, packet_size);
91 	free(packet);
92 
93 	sequence++;	/* next sequence number */
94 	if (!opt_keepstill)
95 		src_port = (sequence + initsport) % 65536;
96 
97 	if (opt_force_incdport)
98 		dst_port++;
99 }
100