Chinaunix首页 | 论坛 | 博客
  • 博客访问: 907405
  • 博文数量: 201
  • 博客积分: 8078
  • 博客等级: 中将
  • 技术积分: 2162
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-20 17:22
文章分类

全部博文(201)

文章存档

2013年(3)

2012年(11)

2011年(34)

2010年(25)

2009年(51)

2008年(77)

分类: BSD

2010-11-14 20:17:33

不多少,google上找。
代码(来自网上,供学习TCP对时间戳的处理)

#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);
}


阅读(3747) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~