V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
micxin2011
V2EX  ›  问与答

为什么 TCP Socket 能发其他协议的包

  •  
  •   micxin2011 · 2017-05-25 20:17:12 +08:00 · 2941 次点击
    这是一个创建于 2740 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如题,今日调用 C 里面 INET 库时创建了一个 raw_tcp_socket,后来由于疏忽把组装的 TCP/UDP/ICMP 包都通过这个 socket 发了出去,却发现都能发送到目标上,十分不解,特此求教
    19 条回复    2017-05-26 09:30:00 +08:00
    johnlui
        1
    johnlui  
       2017-05-25 20:21:28 +08:00
    socket 只是一个开发软件包,估计是这个软件包内部做了容错吧
    KeepPro
        2
    KeepPro  
       2017-05-25 20:24:45 +08:00 via Android
    我记得网络协议是分了 7 层的吧。tcp 只是控制层?的协议,可能其他应用层的协议可以随意组合吧
    catror
        3
    catror  
       2017-05-25 20:25:04 +08:00 via Android
    raw socket 是 IP 层之上的
    micxin2011
        4
    micxin2011  
    OP
       2017-05-25 20:35:20 +08:00 via Android
    @KeepPro TCP UDP 都是一层里的我记得
    micxin2011
        5
    micxin2011  
    OP
       2017-05-25 20:41:09 +08:00 via Android
    @catror 主要是我传进去的协议参数是 IPROTO_TCP,其他的协议包一样能发送是什么道理
    nbndco
        6
    nbndco  
       2017-05-25 21:24:26 +08:00
    因为系统觉得没有必要浪费时间来检查你发送的包到底是不是符合你给定的协议的
    zinan
        7
    zinan  
       2017-05-25 21:25:54 +08:00
    TCP 把其他协议的数据包封装在 tcp 报文里的, tcp 不会关心他封装的数据是什么, 你给它什么数据他就传什么数据, 他只负责把数据传送给对面的 tcp 对等实体
    nbndco
        8
    nbndco  
       2017-05-25 21:30:20 +08:00
    @zinan 并不是封装成 TCP 流的形式传过去了,系统根本没检查这个包是不是合法的 TCP,只是加上一个标记类型为 TCP 的 IP 头就发出去了。
    catror
        9
    catror  
       2017-05-25 22:29:00 +08:00 via Android
    传进去的协议类型应该被异常处理忽略掉了吧,具体不知,可以把代码扒出来看一下嘛
    JackyBao
        10
    JackyBao  
       2017-05-25 22:39:14 +08:00 via Android
    https://github.com/Chion82/kcptun-raw

    lz 让我想到了上面这个 repo,把 udp 包伪装成 tcp 包。
    CRVV
        11
    CRVV  
       2017-05-25 23:57:16 +08:00
    "把组装的 TCP/UDP/ICMP 包都通过这个 socket 发了出去,却发现都能发送到目标上"

    怎么发现的?
    wwqgtxx
        12
    wwqgtxx  
       2017-05-26 01:02:30 +08:00
    用 wireshark 抓包看看不就知道他到底发了什么包了么
    yangxin0
        13
    yangxin0  
       2017-05-26 01:44:57 +08:00 via iPhone
    socket 是网络协议栈的接口,可以应用到任何一层,raw sockst 可以首发链路层协议所以当然可以发 IP 层协议,所以可以发 UDP。
    micxin2011
        14
    micxin2011  
    OP
       2017-05-26 08:59:32 +08:00 via Android
    @CRVV tcpdump
    micxin2011
        15
    micxin2011  
    OP
       2017-05-26 09:01:18 +08:00 via Android
    @nbndco 我自己组建了完整的 IP 头部加 TCP/UDP/ICMP 头部的包,他还会帮我再标记一个头部么
    nbndco
        16
    nbndco  
       2017-05-26 09:03:18 +08:00   ❤️ 1
    @micxin2011 开了 IP_HDRINCL ?那 IPPROTO_TCP 就被忽略了
    micxin2011
        17
    micxin2011  
    OP
       2017-05-26 09:04:05 +08:00 via Android
    @catror 简而言之就是把 netinet/下的头部(包括 TCP UDP ICMP 和可选的 ether)组装好,然后通过 socket(AF_INET, SOCK_RAW, IPROTO_TCP)发送出去
    micxin2011
        18
    micxin2011  
    OP
       2017-05-26 09:04:28 +08:00 via Android
    @nbndco 嗯是的,原来如此,谢谢
    catror
        19
    catror  
       2017-05-26 09:30:00 +08:00 via Android
    @micxin2011 😂我的意思是你找一下 socket 这个函数的代码看下,应该是创建 socket 的过程中处理了这种异常情况,因为协议类型一般传 0 也没啥问题
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5584 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 07:17 · PVG 15:17 · LAX 23:17 · JFK 02:17
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.