<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>RAW_SOCKET on kamuszhou&#39;s blog</title>
    <link>https://ykyi.net/tags/raw_socket/</link>
    <description>Recent content in RAW_SOCKET on kamuszhou&#39;s blog</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Thu, 26 Dec 2013 02:13:56 +0000</lastBuildDate>
    <atom:link href="https://ykyi.net/tags/raw_socket/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>抓包程序的一些分享</title>
      <link>https://ykyi.net/?p=1102/</link>
      <pubDate>Thu, 26 Dec 2013 02:13:56 +0000</pubDate>
      <guid>https://ykyi.net/?p=1102/</guid>
      <description>&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;昨晚同白总和adden提到抓包的问题。因为写过相关的代码，遇到过抓包的各种各样的坑，此文分享一些相关的经验。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;strong&gt;1. Linux cooked capture&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;在用tcpdump或wireshark看数据包时，有时会看到数据链路层的的包头称为Linux cooked capture。这不是一个真实的包头，当用tcpdump指定从所有网络介质 -i any 抓包时，所有抓到的包的数据链路层被换成了Linux cooked capture。在wireshark官方网站对Linux cooked capture的解释中: 这是一个在linux上被libpcap抓包库使用的“假协议”(pseudo-protocal)，当从“any”设备在抓包，或者本地的数据链路层包头无效时被使用。更多，见&lt;a href=&#34;http://wiki.wireshark.org/SLL&#34;&gt;&lt;a href=&#34;http://wiki.wireshark.org/SLL&#34;&gt;http://wiki.wireshark.org/SLL&lt;/a&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;strong&gt;2. IP over IP tunnel&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;wikipedia的示例图显示IP tunnel上的包的结构是：&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;img loading=&#34;lazy&#34; decoding=&#34;async&#34; class=&#34;alignnone&#34; height=&#34;100&#34; src=&#34;http://upload.wikimedia.org/wikipedia/en/thumb/2/2d/IPTunnelDiagram_01-12-07.jpg/300px-IPTunnelDiagram_01-12-07.jpg&#34; width=&#34;300&#34; /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;但实战中用libpcap库从我们的线上机的IP隧道抓包时，pcap_loop或pcap_dispatch或pcap_next函数返回的数据包只有Inner IP header + IP payload，没有Outer IP headr，也没链路层的头部。多么幸运啊！&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;&lt;strong&gt;3. 混乱的RAW_SOCKET，PF_PACKET协议族&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;这不是工业标准定义的神秘领域，非常之混乱，谨慎进入。如果要写这方面的socket，可供参考。个人经验，用linux原生的socket抓包时，socket()的三的参数如下组合时的神奇效果.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;     &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;        _recv_fd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;        从此socket中读所有的IP包，返回的IP包没有链路层包头,因为第二个参数是SOCK_DGRAM，链路层包头返回时被去掉。第三个参数指定的是IP包。奇怪的是，如果出站的IP包的目的地址不是本机，则出站的IP包不会被抓到。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;       &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;        _recv_fd = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_IP));&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;        和上一个socket的区别是，这个会返回链路层包头。和上一个socket一样，同样只能装到部分出站的包。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;      &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;            _recv_fd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;        这行代码只可以读入站的包，抓不到出站的包。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style=&#34;font-size:14px;&#34;&gt;            _recv_fd = socket(AF_PACKET , SOCK_RAW , htons(ETH_P_ALL));&lt;/span&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
