liuyusen10 发表于 2015-01-26 19:51

linux内核如何创建一个TCP包并能发送

急!!!linux内核编程如何创建一个TCP包并能发送,最好能对TCP包的内容可以修改~~~
求大神帮助!!!

Tinnal 发表于 2015-01-26 22:35

回复 1# liuyusen10


    内核目前只支持UDP发送,TCP数据包请在用户态去发送。不要什么东西都放内核态去做!

wait_rabbit 发表于 2015-01-27 06:22


__sock_create()?

zsszss0000 发表于 2015-01-27 19:04

raw_socket不能满足需求吗?回复 1# liuyusen10


   

liuyusen10 发表于 2015-01-28 16:41

谢谢你的回答。
请教你一个问题好吗
我需要修改一个TCP包的选项长度为20Bytes,但是这个包现在的选项长度是12Bytes,怎么处理呢?回复 2# Tinnal


   

Tinnal 发表于 2015-01-28 20:25

回复 5# liuyusen10


    为什么要这么去做呢?有什么背后的需求?

liuyusen10 发表于 2015-01-29 14:32

这个背后的需求的问题还比较难以阐述,简单来讲就是一个小项目刚好遇到了这样的难题,发现TCP报文的选项需要进行一下填充。
有什么方法吗?
回复 6# Tinnal


   

Tinnal 发表于 2015-01-29 22:57

回复 7# liuyusen10

TCP的选项字段是由如下的函数生成的,你非要option为20字节,可以用的方法有:
1. 通过合理的现成TCP参数,凑够20个字节。但这个不好控制,以后的需求变更了就又得凑一次了。
2. 自己改改这个函数,通过TCPOPT_NOP自己填充到20个字节。static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
                              struct tcp_out_options *opts)
{
        u8 options = opts->options;        /* mungable copy */

        /* Having both authentication and cookies for security is redundant,
       * and there's certainly not enough room.Instead, the cookie-less
       * extension variant is proposed.
       *
       * Consider the pessimal case with authentication.The options
       * could look like:
       *   COOKIE|MD5(20) + MSS(4) + SACK|TS(12) + WSCALE(4) == 40
       */
        if (unlikely(OPTION_MD5 & options)) {
                if (unlikely(OPTION_COOKIE_EXTENSION & options)) {
                        *ptr++ = htonl((TCPOPT_COOKIE << 24) |
                                     (TCPOLEN_COOKIE_BASE << 16) |
                                     (TCPOPT_MD5SIG << 8) |
                                     TCPOLEN_MD5SIG);
                } else {
                        *ptr++ = htonl((TCPOPT_NOP << 24) |
                                     (TCPOPT_NOP << 16) |
                                     (TCPOPT_MD5SIG << 8) |
                                     TCPOLEN_MD5SIG);
                }
                options &= ~OPTION_COOKIE_EXTENSION;
                /* overload cookie hash location */
                opts->hash_location = (__u8 *)ptr;
                ptr += 4;
        }

        if (unlikely(opts->mss)) {
                *ptr++ = htonl((TCPOPT_MSS << 24) |
                             (TCPOLEN_MSS << 16) |
                             opts->mss);
        }

        if (likely(OPTION_TS & options)) {
                if (unlikely(OPTION_SACK_ADVERTISE & options)) {
                        *ptr++ = htonl((TCPOPT_SACK_PERM << 24) |
                                     (TCPOLEN_SACK_PERM << 16) |
                                     (TCPOPT_TIMESTAMP << 8) |
                                     TCPOLEN_TIMESTAMP);
                        options &= ~OPTION_SACK_ADVERTISE;
                } else {
                        *ptr++ = htonl((TCPOPT_NOP << 24) |
                                     (TCPOPT_NOP << 16) |
                                     (TCPOPT_TIMESTAMP << 8) |
                                     TCPOLEN_TIMESTAMP);
                }
                *ptr++ = htonl(opts->tsval);
                *ptr++ = htonl(opts->tsecr);
        }

        /* Specification requires after timestamp, so do it now.
       *
       * Consider the pessimal case without authentication.The options
       * could look like:
       *   MSS(4) + SACK|TS(12) + COOKIE(20) + WSCALE(4) == 40
       */
        if (unlikely(OPTION_COOKIE_EXTENSION & options)) {
                __u8 *cookie_copy = opts->hash_location;
                u8 cookie_size = opts->hash_size;

                /* 8-bit multiple handled in tcp_cookie_size_check() above,
               * and elsewhere.
               */
                if (0x2 & cookie_size) {
                        __u8 *p = (__u8 *)ptr;

                        /* 16-bit multiple */
                        *p++ = TCPOPT_COOKIE;
                        *p++ = TCPOLEN_COOKIE_BASE + cookie_size;
                        *p++ = *cookie_copy++;
                        *p++ = *cookie_copy++;
                        ptr++;
                        cookie_size -= 2;
                } else {
                        /* 32-bit multiple */
                        *ptr++ = htonl(((TCPOPT_NOP << 24) |
                                        (TCPOPT_NOP << 16) |
                                        (TCPOPT_COOKIE << 8) |
                                        TCPOLEN_COOKIE_BASE) +
                                     cookie_size);
                }

                if (cookie_size > 0) {
                        memcpy(ptr, cookie_copy, cookie_size);
                        ptr += (cookie_size / 4);
                }
        }

        if (unlikely(OPTION_SACK_ADVERTISE & options)) {
                *ptr++ = htonl((TCPOPT_NOP << 24) |
                             (TCPOPT_NOP << 16) |
                             (TCPOPT_SACK_PERM << 8) |
                             TCPOLEN_SACK_PERM);
        }

        if (unlikely(OPTION_WSCALE & options)) {
                *ptr++ = htonl((TCPOPT_NOP << 24) |
                             (TCPOPT_WINDOW << 16) |
                             (TCPOLEN_WINDOW << 8) |
                             opts->ws);
        }

        if (unlikely(opts->num_sack_blocks)) {
                struct tcp_sack_block *sp = tp->rx_opt.dsack ?
                        tp->duplicate_sack : tp->selective_acks;
                int this_sack;

                *ptr++ = htonl((TCPOPT_NOP<< 24) |
                             (TCPOPT_NOP<< 16) |
                             (TCPOPT_SACK <<8) |
                             (TCPOLEN_SACK_BASE + (opts->num_sack_blocks *
                                                     TCPOLEN_SACK_PERBLOCK)));

                for (this_sack = 0; this_sack < opts->num_sack_blocks;
                     ++this_sack) {
                        *ptr++ = htonl(sp.start_seq);
                        *ptr++ = htonl(sp.end_seq);
                }

                tp->rx_opt.dsack = 0;
        }
}

liuyusen10 发表于 2015-02-02 14:37

谢谢大神,我研究研究
回复 8# Tinnal


   

anyhit 发表于 2015-02-02 16:37

回复 9# liuyusen10
单纯的改一个包没效果的
这个包之后的所有包都要修改
因为 ack 和seq字段变了

其实只要这两个 字段 和校验和 对
其他的 你随便该
因为linux内核包 data字段本身是按最大长度分配的


不过最好不好这样做
除非你安全性要求低

因为一旦乱序的情况出现(一般情况下 tcp包是有序发送的如packet1 packet2 packet3,但协议本身是支持乱序的如 packet2 packet1 packet3),本条tcp链接就废了。
你要是想考虑到所有情况,那就太复杂了

   
页: [1] 2
查看完整版本: linux内核如何创建一个TCP包并能发送