linux内核如何创建一个TCP包并能发送
急!!!linux内核编程如何创建一个TCP包并能发送,最好能对TCP包的内容可以修改~~~求大神帮助!!! 回复 1# liuyusen10
内核目前只支持UDP发送,TCP数据包请在用户态去发送。不要什么东西都放内核态去做!
__sock_create()? raw_socket不能满足需求吗?回复 1# liuyusen10
谢谢你的回答。
请教你一个问题好吗
我需要修改一个TCP包的选项长度为20Bytes,但是这个包现在的选项长度是12Bytes,怎么处理呢?回复 2# Tinnal
回复 5# liuyusen10
为什么要这么去做呢?有什么背后的需求? 这个背后的需求的问题还比较难以阐述,简单来讲就是一个小项目刚好遇到了这样的难题,发现TCP报文的选项需要进行一下填充。
有什么方法吗?
回复 6# Tinnal
回复 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;
}
} 谢谢大神,我研究研究
回复 8# Tinnal
回复 9# liuyusen10
单纯的改一个包没效果的
这个包之后的所有包都要修改
因为 ack 和seq字段变了
其实只要这两个 字段 和校验和 对
其他的 你随便该
因为linux内核包 data字段本身是按最大长度分配的
不过最好不好这样做
除非你安全性要求低
因为一旦乱序的情况出现(一般情况下 tcp包是有序发送的如packet1 packet2 packet3,但协议本身是支持乱序的如 packet2 packet1 packet3),本条tcp链接就废了。
你要是想考虑到所有情况,那就太复杂了
页:
[1]
2