From 3a8c5b4d1b0499773737fda854b2c037cfe94a7a Mon Sep 17 00:00:00 2001 From: Alex Suhan Date: Wed, 2 Dec 2009 02:29:00 +0200 Subject: [PATCH] Simple compressed conversation generator. --- pack-gen.c | 716 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 716 insertions(+) create mode 100644 pack-gen.c diff --git a/pack-gen.c b/pack-gen.c new file mode 100644 index 0000000..d84ff35 --- /dev/null +++ b/pack-gen.c @@ -0,0 +1,716 @@ +/* + * Pack-gen Simple one-pack TCP conversation generator. + * + * Author: Alex Suhan + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#define __USE_BSD +#include +#include +#include +#define __FAVOR_BSD +#include +#include +#include +#include +#include +#include +#include +#include + +// libipq stuff +#include +#include + +// zlib stuff +#include + +#define MAGIC_TS 3031184 +#define MAGIC_PORT 39171 +#define MAGIC_WINDOW 5840 + +#define DATAGRAM_SIZE 4096 + +#define CHUNK 16384 + +unsigned char uncomp_data_buff[] = "1111111111111111111111111111111\n"; +unsigned char comp_data_buff[DATAGRAM_SIZE]; + +/* Compress from 'source' repeated 'times' times to 'dest' until EOF on source. + def_repeat() returns Z_OK on success, Z_MEM_ERROR if memory could not be + allocated for processing, Z_STREAM_ERROR if an invalid compression + level is supplied, Z_VERSION_ERROR if the version of zlib.h and the + version of the library linked do not match, or Z_ERRNO if there is + an error reading or writing the files. */ +int def_repeat(unsigned char *source, size_t src_count, unsigned char *dest, unsigned *dest_off, unsigned times, int level) +{ + int ret, flush; + unsigned have; + z_stream strm; + *dest_off = 0; + unsigned crt_avail_in = 0; + unsigned char *orig_source = source; + unsigned orig_source_count = src_count; + + /* allocate deflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = deflateInit(&strm, level); + if (ret != Z_OK) + return ret; + + /* compress until end of file */ + do { + crt_avail_in = CHUNK < src_count ? CHUNK : src_count; + + strm.avail_in = crt_avail_in; + + src_count -= crt_avail_in; + + if (src_count == 0) + times--; + + flush = (times == 1 && src_count == 0) ? Z_FINISH : Z_NO_FLUSH; + + strm.next_in = source; + + /* run deflate() on input until output buffer not full, finish + compression if all of source has been read in */ + do { + strm.avail_out = CHUNK; + strm.next_out = dest + *dest_off; + ret = deflate(&strm, flush); /* no bad return value */ + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + have = CHUNK - strm.avail_out; + *dest_off += have; + } while (strm.avail_out == 0); + assert(strm.avail_in == 0); /* all input will be used */ + + if (src_count > 0) + source += crt_avail_in; + else if (times > 1) + { + src_count = orig_source_count; + source = orig_source; + } + + /* done when last data in file processed */ + } while (flush != Z_FINISH); + assert(ret == Z_STREAM_END); /* stream will be complete */ + + /* clean up and return */ + (void)deflateEnd(&strm); + return Z_OK; +} + +/* checksum over buf1 concatenated with buf2 */ +unsigned short csum(unsigned short *buf1, unsigned short *buf2, int nwords1, int nwords2) +{ + unsigned long sum; + for (sum = 0; nwords1 > 0; nwords1--) + sum += *buf1++; + for (; nwords2 > 0; nwords2--) + sum += *buf2++; + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + return ~sum; +} + +unsigned char pseudo_header[] = +{ + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x00 +}; + +static void die(struct ipq_handle *h) +{ + ipq_perror("passer"); + ipq_destroy_handle(h); + exit(1); +} + +int main(int argc, char **argv) +{ + unsigned off; + unsigned option_off; + unsigned seq; + unsigned peer_seq = 0; + unsigned short magic_port; + unsigned comp_size; + unsigned times = 1 << atoi(argv[4]); + unsigned uncomp_size = (sizeof(uncomp_data_buff) - 1) * times; + + def_repeat(uncomp_data_buff, sizeof(uncomp_data_buff) - 1, comp_data_buff, &comp_size, 2, Z_DEFAULT_COMPRESSION); + + // ipq library handle + struct ipq_handle *h; + int status; + + // message + unsigned char datagram[DATAGRAM_SIZE]; + + // socket + int raw_sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); + + // headers + struct ip *iph = (struct ip *) datagram; + struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof(struct ip)); + + // socket endpoint address + struct sockaddr_in sin; + sin.sin_family = AF_INET; + + if(argc < 5) { + printf("Usage : %s \n", argv[0]); + return -1; + } + + sin.sin_port = htons(atoi(argv[3])); + sin.sin_addr.s_addr = inet_addr(argv[2]); + + h = ipq_create_handle(0, NFPROTO_IPV4); + if (!h) + die(h); + + status = ipq_set_mode(h, IPQ_COPY_PACKET, DATAGRAM_SIZE); + if (status < 0) + die(h); + + memset(datagram, 0, DATAGRAM_SIZE); + + int options_size = 16; + + iph->ip_hl = 5; + iph->ip_v = 4; + iph->ip_tos = 0x10; + iph->ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr) + options_size); + iph->ip_id = htons(random()); + iph->ip_off = htons(0 | IP_DF); + iph->ip_ttl = 64; + iph->ip_p = 6; + iph->ip_sum = 0; + iph->ip_src.s_addr = inet_addr(argv[1]); + iph->ip_dst.s_addr = sin.sin_addr.s_addr; + iph->ip_sum = csum((unsigned short *) datagram, NULL, (sizeof(struct ip) + sizeof(struct ip) % 2) / 2, 0); + + unsigned char *src_bytes = (unsigned char *) (&iph->ip_src.s_addr); + unsigned char *dst_bytes = (unsigned char *) (&iph->ip_dst.s_addr); + + memcpy(pseudo_header, src_bytes, 4); + memcpy(pseudo_header + 4, dst_bytes, 4); + + srand(time(NULL)); + seq = random(); + magic_port = 40000 + random() % 5000; + + unsigned tcp_header_size = sizeof(struct tcphdr) + options_size; // ok, ok, ar trebui rotunjit la multiplu de 4 + + tcph->th_sport = htons(magic_port); + tcph->th_dport = htons(atoi(argv[3])); + tcph->th_seq = htonl(seq); + tcph->th_ack = 0; + tcph->th_x2 = 0; + tcph->th_flags = TH_SYN; + tcph->th_win = htons(MAGIC_WINDOW); + tcph->th_sum = 0; + tcph->th_urp = 0; + tcph->th_off = tcp_header_size / 4; + + option_off = sizeof(struct tcphdr) + sizeof(struct ip); + + // MSS + datagram[option_off] = 0x02; + datagram[option_off + 1] = 0x04; + *((unsigned short *) (datagram + option_off + 2)) = htons(1460); + + option_off += 4; + + // SACK permitted + datagram[option_off] = 0x04; + datagram[option_off + 1] = 0x02; + + option_off += 2; + + // Window scale + datagram[option_off] = 0x03; + datagram[option_off + 1] = 0x03; + datagram[option_off + 2] = 0x06; + + option_off += 3; + + // NOP's + datagram[option_off] = 0x01; + datagram[option_off + 1] = 0x01; + datagram[option_off + 2] = 0x01; + + option_off += 3; + + // tcp-comp related + datagram[option_off] = 253; + datagram[option_off + 1] = 0x04; + datagram[option_off + 2] = 0; + datagram[option_off + 3] = 0x01; + + option_off += 4; + + pseudo_header[sizeof(pseudo_header) - 1] = tcp_header_size; + + unsigned short check = + csum((unsigned short *) pseudo_header, (unsigned short *) (datagram + sizeof(struct ip)), + sizeof(pseudo_header) / 2, (tcp_header_size + tcp_header_size % 2) / 2); + + tcph->th_sum = check; + + printf("CHECKSUM: %04x\n", check); + + printf("Sending SYN packet\n"); + printf("------------------\n"); + for (off = 0; off < sizeof(struct ip); off += 4) + printf("0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", + (unsigned char) datagram[off], + (unsigned char) datagram[off + 1], + (unsigned char) datagram[off + 2], + (unsigned char) datagram[off + 3] + ); + for (off = 0; off < tcp_header_size; off += 4) + printf("0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", + (unsigned char) datagram[off + sizeof(struct ip)], + (unsigned char) datagram[off + 1 + sizeof(struct ip)], + (unsigned char) datagram[off + 2 + sizeof(struct ip)], + (unsigned char) datagram[off + 3 + sizeof(struct ip)] + ); + printf("\n"); + + int one = 1; + const int *val = &one; + if (setsockopt(raw_sock, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0) + { + fprintf(stderr, "Can't set socket option\n"); + return -1; + } + + int err = + sendto(raw_sock, datagram, sizeof(struct ip) + tcp_header_size, 0, (struct sockaddr *) &sin, sizeof(sin)); + + memset(datagram, 0, sizeof(datagram)); + + status = ipq_read(h, datagram, DATAGRAM_SIZE, 0); + if (status < 0) + die(h); + + switch (ipq_message_type(datagram)) + { + case NLMSG_ERROR: + fprintf(stderr, "Received error message %d\n", ipq_get_msgerr(datagram)); + break; + case IPQM_PACKET: + { + ipq_packet_msg_t *m = ipq_get_packet(datagram); + + iph = (struct ip *) m->payload; + printf("IP header length: %d\n", iph->ip_hl); + tcph = (struct tcphdr *) (m->payload + (iph->ip_hl << 2)); + printf("TCP header length: %d\n", tcph->th_off << 2); + + peer_seq = ntohl(tcph->th_seq); + printf("%u %u\n\n", seq, peer_seq); + + status = ipq_set_verdict(h, m->packet_id, NF_DROP, 0, NULL); + if (status < 0) + die(h); + break; + } + default: + fprintf(stderr, "Unknown message type!\n"); + break; + } + + iph = (struct ip *) datagram; + tcph = (struct tcphdr *) (datagram + sizeof(struct ip)); + + option_off = sizeof(struct tcphdr) + sizeof(struct ip); + + // ACK segment + memset(datagram, 0, DATAGRAM_SIZE); + + options_size = 0; + + iph->ip_hl = 5; + iph->ip_v = 4; + iph->ip_tos = 0x10; + iph->ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr) + options_size); + iph->ip_id = htons(random()); + iph->ip_off = htons(0 | IP_DF); + iph->ip_ttl = 64; + iph->ip_p = 6; + iph->ip_sum = 0; + iph->ip_src.s_addr = inet_addr(argv[1]); + iph->ip_dst.s_addr = sin.sin_addr.s_addr; + iph->ip_sum = csum((unsigned short *) datagram, NULL, (sizeof(struct ip) + sizeof(struct ip) % 2) / 2, 0); + + src_bytes = (unsigned char *) (&iph->ip_src.s_addr); + dst_bytes = (unsigned char *) (&iph->ip_dst.s_addr); + + memcpy(pseudo_header, src_bytes, 4); + memcpy(pseudo_header + 4, dst_bytes, 4); + + tcp_header_size = sizeof(struct tcphdr) + options_size; + + tcph->th_sport = htons(magic_port); + tcph->th_dport = htons(atoi(argv[3])); + tcph->th_seq = htonl(seq + 1); + tcph->th_ack = htonl(peer_seq + 1); + tcph->th_x2 = 0; + tcph->th_flags = TH_ACK; + tcph->th_win = htons(MAGIC_WINDOW / 64); + tcph->th_sum = 0; + tcph->th_urp = 0; + tcph->th_off = tcp_header_size / 4; + + pseudo_header[sizeof(pseudo_header) - 1] = tcp_header_size; + + check = + csum((unsigned short *) pseudo_header, (unsigned short *) (datagram + sizeof(struct ip)), + sizeof(pseudo_header) / 2, (tcp_header_size + tcp_header_size % 2) / 2); + + tcph->th_sum = check; + + printf("Sending ACK packet\n"); + printf("------------------\n"); + for (off = 0; off < sizeof(struct ip); off += 4) + printf("0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", + (unsigned char) datagram[off], + (unsigned char) datagram[off + 1], + (unsigned char) datagram[off + 2], + (unsigned char) datagram[off + 3] + ); + for (off = 0; off < tcp_header_size; off += 4) + printf("0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", + (unsigned char) datagram[off + sizeof(struct ip)], + (unsigned char) datagram[off + 1 + sizeof(struct ip)], + (unsigned char) datagram[off + 2 + sizeof(struct ip)], + (unsigned char) datagram[off + 3 + sizeof(struct ip)] + ); + printf("\n"); + + err = + sendto(raw_sock, datagram, sizeof(struct ip) + tcp_header_size, 0, (struct sockaddr *) &sin, sizeof(sin)); + + // data segment + memset(datagram, 0, DATAGRAM_SIZE); + + int data_size = comp_size; + + options_size = 12; + + int data_off = sizeof(struct tcphdr) + sizeof(struct ip) + options_size; + + iph->ip_hl = 5; + iph->ip_v = 4; + iph->ip_tos = 0x10; + iph->ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr) + options_size + data_size); + iph->ip_id = htons(random()); + iph->ip_off = htons(0 | IP_DF); + iph->ip_ttl = 64; + iph->ip_p = 6; + iph->ip_sum = 0; + iph->ip_src.s_addr = inet_addr(argv[1]); + iph->ip_dst.s_addr = sin.sin_addr.s_addr; + iph->ip_sum = csum((unsigned short *) datagram, NULL, (sizeof(struct ip) + sizeof(struct ip) % 2) / 2, 0); + + src_bytes = (unsigned char *) (&iph->ip_src.s_addr); + dst_bytes = (unsigned char *) (&iph->ip_dst.s_addr); + + memcpy(pseudo_header, src_bytes, 4); + memcpy(pseudo_header + 4, dst_bytes, 4); + + tcp_header_size = sizeof(struct tcphdr) + options_size; + + tcph->th_sport = htons(magic_port); + tcph->th_dport = htons(atoi(argv[3])); + tcph->th_seq = htonl(seq + 1); + tcph->th_ack = htonl(peer_seq + 1); + tcph->th_x2 = 0; + tcph->th_flags = TH_ACK | TH_PUSH; + tcph->th_win = htons(MAGIC_WINDOW / 64); + tcph->th_sum = 0; + tcph->th_urp = 0; + tcph->th_off = tcp_header_size / 4; + + option_off = sizeof(struct tcphdr) + sizeof(struct ip); + + datagram[option_off + 0] = 0x01; + datagram[option_off + 1] = 0x01; + datagram[option_off + 2] = 0xfd; + datagram[option_off + 3] = 0x0a; + *((unsigned int *) (datagram + option_off + 4)) = htonl(comp_size); + *((unsigned int *) (datagram + option_off + 8)) = htonl(uncomp_size); + + option_off += 12; + + pseudo_header[sizeof(pseudo_header) - 1] = tcp_header_size + data_size; + + memcpy(datagram + data_off, comp_data_buff, data_size); + + check = + csum((unsigned short *) pseudo_header, (unsigned short *) (datagram + sizeof(struct ip)), + sizeof(pseudo_header) / 2, ((tcp_header_size + data_size) +(tcp_header_size + data_size) % 2) / 2); + + tcph->th_sum = check; + + printf("Sending DATA packet\n"); + printf("------------------\n"); + for (off = 0; off < sizeof(struct ip); off += 4) + printf("0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", + (unsigned char) datagram[off], + (unsigned char) datagram[off + 1], + (unsigned char) datagram[off + 2], + (unsigned char) datagram[off + 3] + ); + for (off = 0; off < tcp_header_size + data_size; off += 4) + printf("0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", + (unsigned char) datagram[off + sizeof(struct ip)], + (unsigned char) datagram[off + 1 + sizeof(struct ip)], + (unsigned char) datagram[off + 2 + sizeof(struct ip)], + (unsigned char) datagram[off + 3 + sizeof(struct ip)] + ); + printf("\n"); + + err = + sendto(raw_sock, datagram, sizeof(struct ip) + tcp_header_size + data_size, 0, (struct sockaddr *) &sin, sizeof(sin)); + + // reading the response + + memset(datagram, 0, sizeof(datagram)); + + while (1) + { + status = ipq_read(h, datagram, DATAGRAM_SIZE, 0); + if (status < 0) + die(h); + + switch (ipq_message_type(datagram)) + { + case NLMSG_ERROR: + fprintf(stderr, "Received error message %d\n", ipq_get_msgerr(datagram)); + return -1; + case IPQM_PACKET: + { + ipq_packet_msg_t *m = ipq_get_packet(datagram); + + iph = (struct ip *) m->payload; + printf("IP header length: %d\n", iph->ip_hl); + tcph = (struct tcphdr *) (m->payload + (iph->ip_hl << 2)); + printf("TCP header length: %d\n", tcph->th_off << 2); + + peer_seq = ntohl(tcph->th_seq); + printf("%u %u\n\n", seq, peer_seq); + + status = ipq_set_verdict(h, m->packet_id, NF_DROP, 0, NULL); + if (status < 0) + die(h); + break; + } + default: + fprintf(stderr, "Unknown message type!\n"); + return -1; + } + + if (tcph->th_flags & TH_ACK) + break; + } + + iph = (struct ip *) datagram; + tcph = (struct tcphdr *) (datagram + sizeof(struct ip)); + + option_off = sizeof(struct tcphdr) + sizeof(struct ip); + + // FIN segment + memset(datagram, 0, DATAGRAM_SIZE); + + options_size = 0; + + iph->ip_hl = 5; + iph->ip_v = 4; + iph->ip_tos = 0x10; + iph->ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr) + options_size); + iph->ip_id = htons(random()); + iph->ip_off = htons(0 | IP_DF); + iph->ip_ttl = 64; + iph->ip_p = 6; + iph->ip_sum = 0; + iph->ip_src.s_addr = inet_addr(argv[1]); + iph->ip_dst.s_addr = sin.sin_addr.s_addr; + iph->ip_sum = csum((unsigned short *) datagram, NULL, (sizeof(struct ip) + sizeof(struct ip) % 2) / 2, 0); + + src_bytes = (unsigned char *) (&iph->ip_src.s_addr); + dst_bytes = (unsigned char *) (&iph->ip_dst.s_addr); + + memcpy(pseudo_header, src_bytes, 4); + memcpy(pseudo_header + 4, dst_bytes, 4); + + tcp_header_size = sizeof(struct tcphdr) + options_size; + + tcph->th_sport = htons(magic_port); + tcph->th_dport = htons(atoi(argv[3])); + tcph->th_seq = htonl(seq + 1 + uncomp_size); + tcph->th_ack = htonl(peer_seq + 1); + tcph->th_x2 = 0; + tcph->th_flags = TH_FIN | TH_ACK; + tcph->th_win = htons(MAGIC_WINDOW / 64); + tcph->th_sum = 0; + tcph->th_urp = 0; + tcph->th_off = tcp_header_size / 4; + + pseudo_header[sizeof(pseudo_header) - 1] = tcp_header_size; + + check = + csum((unsigned short *) pseudo_header, (unsigned short *) (datagram + sizeof(struct ip)), + sizeof(pseudo_header) / 2, (tcp_header_size + tcp_header_size % 2) / 2); + + tcph->th_sum = check; + + printf("Sending FIN packet\n"); + printf("------------------\n"); + for (off = 0; off < sizeof(struct ip); off += 4) + printf("0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", + (unsigned char) datagram[off], + (unsigned char) datagram[off + 1], + (unsigned char) datagram[off + 2], + (unsigned char) datagram[off + 3] + ); + for (off = 0; off < tcp_header_size; off += 4) + printf("0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", + (unsigned char) datagram[off + sizeof(struct ip)], + (unsigned char) datagram[off + 1 + sizeof(struct ip)], + (unsigned char) datagram[off + 2 + sizeof(struct ip)], + (unsigned char) datagram[off + 3 + sizeof(struct ip)] + ); + printf("\n"); + + err = + sendto(raw_sock, datagram, sizeof(struct ip) + tcp_header_size, 0, (struct sockaddr *) &sin, sizeof(sin)); + + // reading the response + + memset(datagram, 0, sizeof(datagram)); + + while (1) + { + status = ipq_read(h, datagram, DATAGRAM_SIZE, 0); + if (status < 0) + die(h); + + switch (ipq_message_type(datagram)) + { + case NLMSG_ERROR: + fprintf(stderr, "Received error message %d\n", ipq_get_msgerr(datagram)); + return -1; + case IPQM_PACKET: + { + ipq_packet_msg_t *m = ipq_get_packet(datagram); + + iph = (struct ip *) m->payload; + printf("IP header length: %d\n", iph->ip_hl); + tcph = (struct tcphdr *) (m->payload + (iph->ip_hl << 2)); + printf("TCP header length: %d\n", tcph->th_off << 2); + + peer_seq = ntohl(tcph->th_seq); + printf("%u %u\n\n", seq, peer_seq); + + status = ipq_set_verdict(h, m->packet_id, NF_DROP, 0, NULL); + if (status < 0) + die(h); + break; + } + default: + fprintf(stderr, "Unknown message type!\n"); + return -1; + } + + if (tcph->th_flags & TH_FIN) + break; + } + + iph = (struct ip *) datagram; + tcph = (struct tcphdr *) (datagram + sizeof(struct ip)); + + option_off = sizeof(struct tcphdr) + sizeof(struct ip); + + // ACK segment + memset(datagram, 0, DATAGRAM_SIZE); + + options_size = 0; + + iph->ip_hl = 5; + iph->ip_v = 4; + iph->ip_tos = 0x10; + iph->ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr) + options_size); + iph->ip_id = htons(random()); + iph->ip_off = htons(0 | IP_DF); + iph->ip_ttl = 64; + iph->ip_p = 6; + iph->ip_sum = 0; + iph->ip_src.s_addr = inet_addr(argv[1]); + iph->ip_dst.s_addr = sin.sin_addr.s_addr; + iph->ip_sum = csum((unsigned short *) datagram, NULL, (sizeof(struct ip) + sizeof(struct ip) % 2) / 2, 0); + + src_bytes = (unsigned char *) (&iph->ip_src.s_addr); + dst_bytes = (unsigned char *) (&iph->ip_dst.s_addr); + + memcpy(pseudo_header, src_bytes, 4); + memcpy(pseudo_header + 4, dst_bytes, 4); + + tcp_header_size = sizeof(struct tcphdr) + options_size; + + tcph->th_sport = htons(magic_port); + tcph->th_dport = htons(atoi(argv[3])); + tcph->th_seq = htonl(seq + 1 + uncomp_size); + tcph->th_ack = htonl(peer_seq + 1); + tcph->th_x2 = 0; + tcph->th_flags = TH_ACK; + tcph->th_win = htons(MAGIC_WINDOW / 64); + tcph->th_sum = 0; + tcph->th_urp = 0; + tcph->th_off = tcp_header_size / 4; + + pseudo_header[sizeof(pseudo_header) - 1] = tcp_header_size; + + check = + csum((unsigned short *) pseudo_header, (unsigned short *) (datagram + sizeof(struct ip)), + sizeof(pseudo_header) / 2, (tcp_header_size + tcp_header_size % 2) / 2); + + tcph->th_sum = check; + + printf("Sending ACK packet\n"); + printf("------------------\n"); + for (off = 0; off < sizeof(struct ip); off += 4) + printf("0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", + (unsigned char) datagram[off], + (unsigned char) datagram[off + 1], + (unsigned char) datagram[off + 2], + (unsigned char) datagram[off + 3] + ); + for (off = 0; off < tcp_header_size; off += 4) + printf("0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", + (unsigned char) datagram[off + sizeof(struct ip)], + (unsigned char) datagram[off + 1 + sizeof(struct ip)], + (unsigned char) datagram[off + 2 + sizeof(struct ip)], + (unsigned char) datagram[off + 3 + sizeof(struct ip)] + ); + printf("\n"); + + err = + sendto(raw_sock, datagram, sizeof(struct ip) + tcp_header_size, 0, (struct sockaddr *) &sin, sizeof(sin)); + + ipq_destroy_handle(h); + + return err; +} -- 2.11.4.GIT