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