www.w3.org

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html"; charset="UTF-8" />
<meta content="360doc" name="classification">
<meta content="netfilter" name=keywords>
<meta content="Linux netfilter hacking HOWTO" name=description>
<meta content="www.360doc.com" name="author">

  
<title>Linux netfilter hacking HOWTO</title>
<link href="http://www.360doc.com/css/StickySystemIEBlue.css" rel="stylesheet" type="text/css" />
<script>
window.onerror = ignoreError;       
function ignoreError()
{
   return true;

</script>
</head>
<body  οnmοuseup="setDragEnd()" οnmοusemοve="DragDiv();" οnclick="delAllDiv(event)">
<div class="top2">
 <div class="top_con">
  <div class="logo02"><img src="http://www.360doc.com/images/logo02.gif" alt="360doc" /></div>
  <div class="nav_3">
   <div class="ad01" id="ad01">

   </div>
    <span class="nav_2_tit02 link_underline">
     <a target="_blank" href="http://www.360doc.com/help.html">帮助</a>&nbsp;
     |&nbsp;
     <a target="_blank" href="http://www.360doc.com/advice.html">留言交流</a>&nbsp;
     |&nbsp;
                                        <span id="loginstatus"></span>
    </span>   
  </div>
  <div class="navcg1">
    <div class="search_mokuaicg1">
      <div class="mokuai_navcg1">
                                                   <span class="uncleckedcg1 link_blackcg1"><a href="http://www.360doc.com/index.html">首页</a></span>
                                                   <span class="unclecked link_black"><a href="http://www.360doc.com/myfiles.aspx">我的图书馆</a></span>
                                                   <span class="unclecked link_black"><a href="http://www.360doc.com/topic.html">主题阅读</a></span>
                                                   <span class="uncleckedcg1 link_blackcg1"><a href="http://www.360doc.com/catalog.html">精彩目录</a></span>
                                                   <span class="uncleckedcg1 link_blackcg1"><a href="http://www.360doc.com/firstarticle.html">精品文苑</a></span>
                                                   <span class="uncleckedcg1 link_blackcg1"><a href="http://www.360doc.com/tags.html">Tags</a></span>
                                                   <span class="uncleckedcg1 link_blackcg1"><a href="http://www.360doc.com/topuser.html">会员浏览</a></span>
                                                   <span class="uncleckedcg1 link_blackcg1"><a href="http://www.360doc.com/Books.html"><span style="font-size: 11px;">好书推荐</span></a></span>
                                                </div>
      <div class="mokuai_concg1">
       <div  style="display:none;" id="a_ul_0"></div>
       <div style="display:none;" id="a_ul_1"></div>
       <div style="display:none;" id="a_ul_2"></div>
       <div style="display:none;" id="a_ul_3"></div>
       <div style="display:none;" id="a_ul_4"></div>
       <div style="display:none;" id="a_ul_5"></div>
       <div style="display:none;" id="a_ul_6"></div>
      </div>
      
     </div> 
   </div> 
    
 </div>
</div>
<div class="index_main">
 <div class="wenzhang_tit">Linux netfilter hacking HOWTO(转载)</div>

       <div class="wenzhang_ft link_underline"><table><tr><td ><span class="link_green"><A href="http://www.360doc.com/UserHome/116188" target="_blank">vclyin</A></span>  收录于2010-01-26 阅读数:<span id="360doc_Readnum"></span></td>  <td ><div id="360doc_saverNum"></div></td>  <td ><div id="360doc_artpermission">公众公开&nbsp;</div></td>  <td  valign="bottom"><span class="link_underlinecg"></span> </td></tr></table></div>
<div class="wenzhang_ft tags"><strong>tags: </strong><A href="http://www.360doc.com/tagarticle.aspx?tag=netfilter" target='_blank'>netfilter</A>  </div>
        <div id="360docIsStrangerUp"></div> 
 <div class="wenzhang_cz">
  <table width="100%">
            <tr>
                <td align="left" valign="top">
                    <div id="headFirst"></div>
                </td>
                <td align="right" valign="top">
                    <div id="headSecond" style="float: right"></div>
                </td>
            </tr>
        </table>
 </div> 
 
 <table width="100%" border="0" cellspacing="1" cellpadding="1"  class="index_main">
<tbody>
   <tr>
  <td align="left" valign="top" width="740px">
                        <div  style=' z-index:1'  ><script type='text/javascript'>
cpro_client='360doc168_cpr';
cpro_at='text_image';
cpro_161=4;
cpro_flush=4;
cpro_w=728;
cpro_h=90;
cpro_template='text_default_728_90';
cpro_cbd='#86AC5F';
cpro_cbg='#FFFFFF';
cpro_ctitle='#0000ff';
cpro_cdesc='#444444';
cpro_curl='#008000';
cpro_cflush='#e10900';
cpro_uap=1;
cpro_cad=1;
cpro_channel=5;
</script>
<script language='JavaScript' type='text/javascript' src='http://cpro.baidu.com/cpro/ui/cp.js'></script>
<table><tr><td width=3></td></tr></table>
</div>
                        <span id="articlecontent" class="wenzhang_con" οnmοuseup="NewHighlight(event)" style="width: 740px"><div>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><span lang=EN-US style="FONT-SIZE: 16pt">Linux netfilter hacking HOWTO<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt; mso-char-indent-count: 2.0"><em><span style="FONT-SIZE: 12pt; FONT-STYLE: normal; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-style: italic">本文描述了</span></em><em><span lang=EN-US style="FONT-SIZE: 12pt; FONT-STYLE: normal; mso-bidi-font-style: italic">Linux</span></em><em><span style="FONT-SIZE: 12pt; FONT-STYLE: normal; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-style: italic">的</span></em><em><span lang=EN-US style="FONT-SIZE: 12pt; FONT-STYLE: normal; mso-bidi-font-style: italic">netfilter</span></em><em><span style="FONT-SIZE: 12pt; FONT-STYLE: normal; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-style: italic">架构,如何在此架构下编写程序,以及在此架构之上实现的主要功能模块,如包过滤,连接跟踪和地址转换等。</span></em><em><span lang=EN-US style="FONT-SIZE: 12pt; FONT-STYLE: normal; mso-bidi-font-style: italic"><o:p></o:p></span></em></p>
<h1 style="MARGIN: 17pt 0cm 16.5pt 33.75pt; TEXT-INDENT: -33.75pt; tab-stops: list 33.75pt; mso-list: l6 level1 lfo1"><span lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">1、</span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">介绍</span></h1>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">大家好:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这篇文章就像是一段旅程,有些路程路途平坦,但有些路程却崎岖不平。我可以给你的最好建议就是端一大杯可口的咖啡或者热巧克力,坐到一把舒适的椅子上,喝一口,然后进入有时看起来是艰险的</span><span lang=EN-US style="FONT-SIZE: 12pt">Linux</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">网络世界。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为了更好地理解</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">框架,我建议你先看看</span><span lang=EN-US style="FONT-SIZE: 12pt">Packet Filtering HOWTO</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">NAT HOWTO</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。如果你想了解内核编程方面的知识,请阅读</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p><font face=宋体>大家好</font></p>
<p><font face=宋体>这篇文章就像是一段旅程,有些路程路途平坦,但有些路程却崎岖不平。我可以给你的最好建议就是端一大杯可口的咖啡或者热巧克力,坐到一把舒适的椅子上,喝一口,然后进入有时看起来是艰险的<span lang=EN-US>Linux</span>网络世界。<span lang=EN-US>Rusty's Unreliable Guide to Kernel Hacking </span>和<span lang=EN-US>Rusty's Unreliable Guide to Kernel Locking</span>。</font></p>
<p><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;</span>(C) 2000 Paul `Rusty' Russell. Licenced under the GNU GPL</font></span></p>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>1.1</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、什么是</span><span lang=EN-US><font face=Arial>netfilter</font></span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是一个独立在基本的</span><span lang=EN-US style="FONT-SIZE: 12pt">Berkeley socket</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口之外的包处理框架。它包括四个部分。首先,每个协议族定义一些&#8220;钩子&#8221;(</span><span lang=EN-US style="FONT-SIZE: 12pt">IPV4</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">定义了五个),它们是一些仔细选择的分布在协议栈中包处理路径上的店。在每一个点上,协议栈会调用</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">框架并传递它相应的包和钩子的编号。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">其次,内核可以在不同协议的不同钩子上注册函数去监听流经这些钩子的包。所以,当一个包经过</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">框架时,它会检查是否在此协议的此钩子上有注册的函数;如果有,这些函数就有机会按一定的顺序去检查(或者修改)这个包,接着它会丢弃这个包(</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_DROP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">),允许它通过(</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_ACCEPT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">),告诉</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不要理睬这个包(</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_STOLEN</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">),或者告诉</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将这个包放入队列传递到用户空间(</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_QUEUE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">第三,放入队列的包可以送往用户空间(由</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_queue</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模块完成);这些包可以被异步处理。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最后,代码有很好的注释和文档。这对任何一个试验性的项目都是非常必要的。</span><span lang=EN-US style="FONT-SIZE: 12pt">Netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的格言是(来自</span><span lang=EN-US style="FONT-SIZE: 12pt"> Cort Dougan</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">):&#8220;那么,这如何比</span><span lang=EN-US style="FONT-SIZE: 12pt">KDE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">做得更好?&#8221;。(这个格言用另一句话说就是&#8220;给我一个理由,让我用</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;)除了基础的框架之外,许多实现了与</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类似功能的模块被加入内核,比如,一个可扩展的</span><span lang=EN-US style="FONT-SIZE: 12pt">NAT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">系统,一个可扩展的包过滤系统(</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>1.2</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、在</span><span lang=EN-US><font face=Arial>2.0</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">和</span><span lang=EN-US><font face=Arial>2.2</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">中,我们犯了什么错?</span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt">1</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、没有把包传递到用户空间的基础设施</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l9 level1 lfo2"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内核编码比较复杂</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l9 level1 lfo2"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内核编码必须使用</span><span lang=EN-US style="FONT-SIZE: 12pt">c/c++<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l9 level1 lfo2"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">动态过滤策略不属于内核</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l9 level1 lfo2"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang=EN-US style="FONT-SIZE: 12pt">2.2</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">引入了通过</span><span lang=EN-US style="FONT-SIZE: 12pt">netlink</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将包传递到用户空间的机制,但是将包重新注入内核非常慢,而且很难通过合法性检查。比如,如果将包注入内核时声明这个包来自一个特定的设备就不太可能。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt">2</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、透明代理是一个大麻烦</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l13 level1 lfo3"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我们必须查找每一个包来确定是否有</span><span lang=EN-US style="FONT-SIZE: 12pt">socket</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">绑定到它的地址</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l13 level1 lfo3"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang=EN-US style="FONT-SIZE: 12pt">Root</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用户允许绑定外部地址</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l13 level1 lfo3"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不能重定向本地生成的包</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l13 level1 lfo3"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">重定向没有处理</span><span lang=EN-US style="FONT-SIZE: 12pt">UDP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应答:重定向</span><span lang=EN-US style="FONT-SIZE: 12pt">UDP named</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包到</span><span lang=EN-US style="FONT-SIZE: 12pt">1153</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">端口不能工作,因为一些客户端不能处理</span><span lang=EN-US style="FONT-SIZE: 12pt">53</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">端口之外的应答包</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l13 level1 lfo3"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">重定向没有和</span><span lang=EN-US style="FONT-SIZE: 12pt">tcp/udp</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的端口分配机制很好的配合:用户可能会得到一个由重定向规则适用的端口</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l13 level1 lfo3"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US style="FONT-SIZE: 12pt">2.1</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">系列中,至少崩溃了两次以上</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l13 level1 lfo3"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">代码非常具有侵略性。在</span><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US style="FONT-SIZE: 12pt">2.2.1</span></st1:chsdate><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中</span><span lang=EN-US style="FONT-SIZE: 12pt">#ifdef CONFIG_IP_TRANSPARENT_PROXY</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US style="FONT-SIZE: 12pt">11</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个文件中出现了</span><span lang=EN-US style="FONT-SIZE: 12pt">34</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">次。与之相比较,</span><span lang=EN-US style="FONT-SIZE: 12pt">CONFIG_IP_FIREWALL</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">只在</span><span lang=EN-US style="FONT-SIZE: 12pt">5</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个文件中出现了</span><span lang=EN-US style="FONT-SIZE: 12pt">10</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">次。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt">3</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、不可能创建独立于接口地址的包过滤规则</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l15 level1 lfo4"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">必须知道本地接口的地址才能区分本机产生的包或者本机发生的包</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l15 level1 lfo4"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">转发链只知道出接口的信息,这就意味着你必须通过网络拓扑的信息才能知道这个包来自哪里</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt">4</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、地址伪装的代码放到了包过滤代码之中:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这两部分代码之间的交叉使得代码变得复杂</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l0 level1 lfo5"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US style="FONT-SIZE: 12pt">input</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">链上,应答包看起来就像是发给本机的</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l0 level1 lfo5"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US style="FONT-SIZE: 12pt">forward</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">链上,解伪装的包根本看不到</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l0 level1 lfo5"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US style="FONT-SIZE: 12pt">output</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">链上,包看起来就像是本机发出的包</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-char-indent-count: -1.5"><span lang=EN-US style="FONT-SIZE: 12pt">5</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US style="FONT-SIZE: 12pt">TOS</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">处理,重定向,</span><span lang=EN-US style="FONT-SIZE: 12pt">ICMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不可达和标记(它会影响端口转发,路由和</span><span lang=EN-US style="FONT-SIZE: 12pt">QOS</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">)同样被放到了包过滤的代码中</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-char-indent-count: -1.5"><span lang=EN-US style="FONT-SIZE: 12pt">6</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的代码既不模块化,也不能被扩展(例如,</span><span lang=EN-US style="FONT-SIZE: 12pt">mac</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址过滤,</span><span lang=EN-US style="FONT-SIZE: 12pt">ip</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">过滤项过滤等)</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-char-indent-count: -1.5"><span lang=EN-US style="FONT-SIZE: 12pt">7</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、缺少一个有效的基础架构,使得在现有的架构上,需要使用不同的技术来实现不同的功能</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; tab-stops: list 39.0pt; mso-list: l8 level1 lfo6"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址伪装,每种协议一个模块</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; tab-stops: list 39.0pt; mso-list: l8 level1 lfo6"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通过路由进行快速静态地址转换(没有针对协议的处理)</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; tab-stops: list 39.0pt; mso-list: l8 level1 lfo6"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">端口转发,重定向和自动转发</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; tab-stops: list 39.0pt; mso-list: l8 level1 lfo6"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang=EN-US style="FONT-SIZE: 12pt">Linux NAT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">Virtual server</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">项目</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt">8</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、包过滤和</span><span lang=EN-US style="FONT-SIZE: 12pt">CONFIG_NET_FASTROUTE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">选项不兼容</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l7 level1 lfo7"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">转发的包都会经过三个链</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l7 level1 lfo7"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">没有办法实现跳过某个链的功能</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt">9</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、不能检查因为路由保护而丢弃的包(比如:源路由验证)</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt">10</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、没有办法自动读取包过滤规则上的计数器</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 24pt; TEXT-INDENT: -24pt; mso-char-indent-count: -2.0"><span lang=EN-US style="FONT-SIZE: 12pt">11</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US style="FONT-SIZE: 12pt">CONFIG_IP_ALWAYS_DEFRAG</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是编译时的选项,使得制作一个通过的内核变得困难</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>1.3</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、你是谁?</span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我是唯一一个傻得去完成这段代码的人。作为</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的合作者和当前</span><span lang=EN-US style="FONT-SIZE: 12pt">LINUX</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内核防火墙的维护者,我看到人们使用当前系统所遇到的问题,并且越来越清楚他们需要什么样的功能。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>1.4</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、为什么它会崩溃?</span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt">Woah</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">!这应该是你上周碰到的问题。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">因为我不是你们所想象的那么聪明的程序员,并且也没有测试所有的情境(缺少时间,设备和灵感),所以有问题很正常。但是我创建了一个测试集,欢迎大家扩展这个测试集。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h1 style="MARGIN: 17pt 0cm 16.5pt 33.75pt; TEXT-INDENT: -33.75pt; tab-stops: list 33.75pt; mso-list: l6 level1 lfo1"><span lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">2、</span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">哪里可以取到最新代码?</span></h1>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">netfilter.org</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang=EN-US style="FONT-SIZE: 12pt">CVS</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">服务器上有最新的</span><span lang=EN-US style="FONT-SIZE: 12pt">HOWTOS</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,用户空间工具和测试集。如果是随意的浏览,可以使用一下链接。如果是取最新的代码,可以执行一下操作:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; tab-stops: list 18.0pt; mso-list: l11 level1 lfo8"><span lang=EN-US style="FONT-SIZE: 12pt; mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">1、</span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">匿名登录</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang=EN-US style="FONT-SIZE: 12pt">CVS</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">服务器</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt"><span lang=EN-US style="FONT-SIZE: 12pt">cvs &#8211;d :pserver:cvs@pserver.netfilter.org:/cvspublic login<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; tab-stops: list 18.0pt; mso-list: l11 level1 lfo8"><span lang=EN-US style="FONT-SIZE: 12pt; mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">2、</span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果提示输入密码,输入&#8216;</span><span lang=EN-US style="FONT-SIZE: 12pt">cvs</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8217;</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; tab-stops: list 18.0pt; mso-list: l11 level1 lfo8"><span lang=EN-US style="FONT-SIZE: 12pt; mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">3、</span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">取出代码使用命令:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt"><span lang=EN-US style="FONT-SIZE: 12pt">#cvs &#8211;d :pserver:cvs@pserver.netfilter.org/cvspublic co netfilter/userspace<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; tab-stops: list 18.0pt; mso-list: l11 level1 lfo8"><span lang=EN-US style="FONT-SIZE: 12pt; mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">4、</span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">更新到最新版本,使用</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 18pt"><span lang=EN-US style="FONT-SIZE: 12pt">cvs update &#8211;d -p<o:p></o:p></span></p>
<h1 style="MARGIN: 17pt 0cm 16.5pt 33.75pt; TEXT-INDENT: -33.75pt; tab-stops: list 33.75pt; mso-list: l6 level1 lfo1"><span lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">3、</span></span><span lang=EN-US>netfilter</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的框架</span></h1>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">仅仅是协议栈中不同点上的一系列钩子(目前只有</span><span lang=EN-US style="FONT-SIZE: 12pt">IPv4</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt">IPv6</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt">DECnet</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">)。理想状况下的</span><span lang=EN-US style="FONT-SIZE: 12pt">IPv4</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的流程图如下所示:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<pre><span lang=EN-US><font face=宋体>A Packet Traversing the Netfilter System:</font></span></pre>
<pre><span lang=EN-US><o:p><font face=宋体>&nbsp;</font></o:p></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp; </span>---&gt;[1]---&gt;[ROUTE]---&gt;[3]---&gt;[4]---&gt;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>^</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>[ROUTE]</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>v<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>[2]<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>[5]</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;</span>^</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>v<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|</font></span></pre>
<pre style="tab-stops: 21.75pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt"><font face=宋体><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span></span>包从左面所示的箭头流入:通过简单的合法性检查(例如,包长度合法,<span lang=EN-US>IP</span>校验合法,不是混杂模式收到的包),然后流到<span lang=EN-US>netfilter</span>框架中的</font></pre>
<pre><font face=宋体><span lang=EN-US>NF_IP_PRE_ROUTING[1]</span>的钩子上。</font></pre>
<pre style="TEXT-INDENT: 24pt"><font face=宋体>接下来,包进入路由代码,它判断这个包是发往另一个接口还是发往一个本地进程。路由代码会丢弃那些不能路由的包。</font></pre>
<pre style="TEXT-INDENT: 24pt"><font face=宋体>如果这个包发往本机,那么在发往本机进程前(如果有的话),<span lang=EN-US>netfilter</span>框架中的<span lang=EN-US>NF_IP_LOCAL_IN[2]</span>钩子会被调用。</font></pre>
<pre style="TEXT-INDENT: 24pt"><font face=宋体>如果这个包是发往另一个接口,<span lang=EN-US>netfilter</span>框架中的<span lang=EN-US>NF_IP_FORWARD[3]</span>会被调用。</font></pre>
<pre style="TEXT-INDENT: 24pt"><font face=宋体>接下来,在把这个包发往网卡之前,最有一个<span lang=EN-US>netfilter</span>钩子</font></pre>
<pre><font face=宋体><span lang=EN-US>NF_IP_POST_ROUTING[4]</span>会被调用。</font></pre>
<pre><font face=宋体><span lang=EN-US><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span></span>本机产生的包在发生之前会调用<span lang=EN-US>NF_IP_LOCAL_OUT[5]</span>钩子。此处你可以看到,在这个钩子之后会调用路由代码:实际上,路由代码在此之前已经被调用过一次(确定包的源地址和<span lang=EN-US>IP</span>选项)。<br>如果你想修改路由,你必须自己修改<span lang=EN-US>skb-&gt;dst</span>里面的值,可以参考<span lang=EN-US>NAT</span>代码。</font></pre>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>3.1</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、</span><span lang=EN-US><font face=Arial>Netfilter Base</font></span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这里我们有一个</span><span lang=EN-US style="FONT-SIZE: 12pt">IPv4</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的例子,你可以看到每个钩子是何时被激活的,这是</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">核心所在。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内核模块可以注册监听任何一个钩子。内核模块在注册函数时必须指定此函数在钩子上条用的优先级;这样当网络协议栈代码在调用</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的钩子函数时,内核模块注册在这个钩子上的函数就会按优先级的顺序被调用,这样就能方便的处理网络包。一个模块可以让</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">做如下五件事情:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l2 level1 lfo9"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang=EN-US style="FONT-SIZE: 12pt">NF_ACCEPT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:继续按正常的协议栈流程处理。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l2 level1 lfo9"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang=EN-US style="FONT-SIZE: 12pt">NF_DROP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:丢弃包,中止协议栈的流程。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l2 level1 lfo9"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang=EN-US style="FONT-SIZE: 12pt">NF_STOLEN</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:这个包已被缓存,中止协议栈的流程。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l2 level1 lfo9"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang=EN-US style="FONT-SIZE: 12pt">NF_QUEUE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:把包放到队列中(通常会把包转发到用户空间处理)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l2 level1 lfo9"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang=EN-US style="FONT-SIZE: 12pt">NF_REPEAT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:再此调用这个钩子函数。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有关</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的其他话题(处理队列中的包,精彩的评论等)会在后面的内核部分描述。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在这个基础上,我们可以创建相对复杂的包处理程序,如下面两章所示。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>3.2</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、包选择:</span><span lang=EN-US><font face=Arial>IP Tables</font></span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>IP Tables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是一个构建在</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">框架之上的包选择系统。它是</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的直系厚道(</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">从</span><span lang=EN-US style="FONT-SIZE: 12pt">ipfwadm</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">演变而来,而</span><span lang=EN-US style="FONT-SIZE: 12pt">ipfwadm</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">从</span><span lang=EN-US style="FONT-SIZE: 12pt">BSD</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang=EN-US style="FONT-SIZE: 12pt">ipfw IIRC</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">演变而来)。</span><span lang=EN-US style="FONT-SIZE: 12pt">IP Tables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">提供更强的可扩展性。内核模块可以注册一个新的表,并且</span><span style="FONT-SIZE: 12pt"> </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以让一个包经过一个特定的表。这个包选择系统可以被用来做包过滤(</span><span lang=EN-US style="FONT-SIZE: 12pt">filter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表),地址转换(</span><span lang=EN-US style="FONT-SIZE: 12pt">nat</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表)和通常的包处理(</span><span lang=EN-US style="FONT-SIZE: 12pt">mangle</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上注册的钩子函数如下所示(这些钩子函数按它们被调用的顺序排列):</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp; </span>---&gt;PRE------&gt;[ROUTE]---&gt;FWD----------&gt;POST------&gt;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Conntrack<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Mangle<span style="mso-spacerun: yes">&nbsp;&nbsp; </span>^<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>Mangle</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Mangle<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Filter<span style="mso-spacerun: yes">&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>NAT (Src)</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>NAT (Dst)<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>Conntrack</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>(QDisc)<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>[ROUTE]</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>v<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>IN Filter<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OUT Conntrack</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp; </span>Conntrack<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </span>^<span style="mso-spacerun: yes">&nbsp; </span>Mangle</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp; </span>Mangle<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp; </span>NAT (Dst)</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>v<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|<span style="mso-spacerun: yes">&nbsp; </span>Filter</font></span></pre>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>3.2.1</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、包过滤</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8220;</span><span lang=EN-US style="FONT-SIZE: 12pt">filter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;表只过滤包,但不会修改包。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">Iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">相对于</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">德一个优势在于它比较小并且快速,它只在</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt">NF_IP_LOCAL_IN</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_IP_FORWARD</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_IP_LOCAL_OUT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">三个点上注册钩子函数。这就意味着对每一个包来说,有且仅有一个点可以过滤它。这使得用户可以更方便地使用它。同时,</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">框架在</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_IP_FORWARD</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">点上同时提供入接口和出接口,这使得过滤更加简单。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注意:我已经把</span><span lang=EN-US style="FONT-SIZE: 12pt">ipc</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">ipfwadm</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的内核部分作为内核模块移植到了</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上。用户可以继续使用旧的</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span><span lang=EN-US style="FONT-SIZE: 12pt">ipfwadm</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">工具而不需要额外的升级。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>3.2.2</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址转换</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对&#8220;</span><span lang=EN-US style="FONT-SIZE: 12pt">nat</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;表来说,包会在两个钩子上被处理:对非本地包来说,</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_IP_PRE_ROUTING</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_IP_POST_ROUTING</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">两个钩子可以用于目的转换盒源转换,并且</span><span style="FONT-SIZE: 12pt"> </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在相对应的钩子上座相反的操作。如果打开</span><span lang=EN-US style="FONT-SIZE: 12pt">CONFIG_IP_NF_NAT_LOCAL</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">编译选项,可以在</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_IP_LOCAL_OUT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_IP_LOCAL_IN</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">钩子上修改本地包的地址。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8220;</span><span lang=EN-US style="FONT-SIZE: 12pt">nat</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;表与&#8220;</span><span lang=EN-US style="FONT-SIZE: 12pt">filter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;表完全不同,在&#8220;</span><span lang=EN-US style="FONT-SIZE: 12pt">nat</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;表上,只有新连接的第一个包会经过表:当第一个包经过表之后,会创建相应的状态,后续的统一连接的包会按状态中所记录的信息来做相应的处理。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>3.2.3</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、地址伪装,端口转发和透明代理</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我吧地址转换分为源转换(包的源地址会改变)和目的转换(包的目的地址会改变)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址伪装是特殊形式的源转换,端口转发和透明代理是特殊形式的目的转换。它们都可以在地址转换的框架内实现,而不需要额外的编程。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>3.2.4</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、包处理</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包处理表(&#8220;</span><span lang=EN-US style="FONT-SIZE: 12pt">mangle</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;)用于修改包的信息。一般涉及到</span><span lang=EN-US style="FONT-SIZE: 12pt">TOS</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span><span lang=EN-US style="FONT-SIZE: 12pt">TCPMSS</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的应用程序会使用这个表。</span><span lang=EN-US style="FONT-SIZE: 12pt">Mangle</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表在五个钩子上都可以注册钩子函数。(需要注意的是这个改动是从</span><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US style="FONT-SIZE: 12pt">2.4.18</span></st1:chsdate><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本开始的,以前的版本中</span><span lang=EN-US style="FONT-SIZE: 12pt">mangle</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表只在三个点子上注册钩子函数)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>3.3</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、连接跟踪</span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">连接跟踪是地址转换的基础,但是它被实现成一个独立的模块。这允许包过滤代码可以通过扩展来简单方便地使用连接跟踪(比如&#8220;</span><span lang=EN-US style="FONT-SIZE: 12pt">state</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;模块)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>3.4</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、其他</span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">新框架的灵活性给人们在实现一些有趣的功能或增强已有功能,或者完全替换现有功能提供了便利。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h1 style="MARGIN: 17pt 0cm 16.5pt"><span lang=EN-US>4</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、编程信息</span></h1>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">告诉你一个秘密,我的宠物</span><span lang=EN-US style="FONT-SIZE: 12pt">hamster</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">编写了所有的代码,在我的宠物的计划里,我只是个代理,所以,如果抱怨代码里有错误,去抱怨我的宠物,而不是我。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>4.1</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、理解</span><span lang=EN-US><font face=Arial> ip_tables</font></span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">Iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在内存中提供了一个规则数组(因此命名为</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">),这些信息会在包经过钩子函数时被检查。当一个表注册后,用户空间的程序可以使用</span><span lang=EN-US style="FONT-SIZE: 12pt">getsockopt</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">setsockopt</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数读取或替换表的内容。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">Iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">没有注册任何</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">钩子函数:其他模块会注册钩子函数并把包当做一个参数传递给它。模块必须把</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">钩子寒素和</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_tables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">分开注册,并且提供一种机制,使得调用钩子函数时可以访问</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_tables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.1.1</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US>ip_tables</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据结构</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为了使用方便,同样的数据结构可以再用户空间和内核空间使用,当然,一些变量只能在内核中使用。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">每条规则都包含如下几个部分:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l3 level1 lfo10"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l3 level1 lfo10"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">零个或多个</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry_match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,每一个都会附带一个变长数据</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l3 level1 lfo10"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry_target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,包含一个变长数据</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">规则的可变特性会扩展带来了巨大的灵活性,就像我们所看到的,每个</span><span lang=EN-US style="FONT-SIZE: 12pt">macth</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都会附带一定量的数据。这些数据会造成一些陷阱,所以我们必须让这些数据对齐。我们保证</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry_match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry_target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构的大小合适,并且所有的数据都通过</span><span lang=EN-US style="FONT-SIZE: 12pt">IPT_ALIGN()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏来保证和机器最大对齐值一致。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt">Ipt_entry</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有如下域:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l12 level1 lfo11"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_ip</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,用于匹配</span><span lang=EN-US style="FONT-SIZE: 12pt">IP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">头的信息</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l12 level1 lfo11"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_cache</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">位域,用于标识这条规则检查包的哪一部分</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l12 level1 lfo11"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个</span><span lang=EN-US style="FONT-SIZE: 12pt">target_offset</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">域,表示从规则头开始到</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry_target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构之间的偏移。这个偏移值必须正确对齐(用</span><span lang=EN-US style="FONT-SIZE: 12pt">IPT_MACRO</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏)</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l12 level1 lfo11"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个</span><span lang=EN-US style="FONT-SIZE: 12pt">next_offset</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">域,标识这条规则的总长度,包括这条规则中所有的</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,这个值也必须正确对齐</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l12 level1 lfo11"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个</span><span lang=EN-US style="FONT-SIZE: 12pt">comefrom</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">域,被规则链用于向前回溯</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l12 level1 lfo11"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_counters</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构域,标识匹配这条规则的包计数和字节计数</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">Ipt_entry_match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry_target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">很相似,它们都包含一个表示总长度的域(</span><span lang=EN-US style="FONT-SIZE: 12pt">match_size</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">target_size</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">)和一个指向</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">名的联合(在用户空间使用),还有一个指针(在内核空间使用)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由于规则数据结构比较复杂,所有内核提供了如下的辅助函数:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">Ipt_get_target()<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个</span><span lang=EN-US style="FONT-SIZE: 12pt">inline</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数返回规则中</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的指针</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">IPT_MATCH_ITERATE()<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个宏对规则上的每一个</span><span lang=EN-US style="FONT-SIZE: 12pt">macth</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">调用给定的函数。这个函数的第一个参数时结构</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_match_entry</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,其他参数(如果有的话)是在</span><span lang=EN-US style="FONT-SIZE: 12pt">IPT_MATCH_ITERATE()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏中提供的参数。这个函数返回</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示继续遍历,或者是一个非</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">值表示停止。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">IPT_ENTRY_ITERATE()<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个宏的参数时一个指向规则的指针,规则表的总长度,和一个需要调用的函数。函数的第一个参数时结构</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,其他参数是(如果有的话)是在</span><span lang=EN-US style="FONT-SIZE: 12pt">IPT_ENTRY_ITERATE()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏中提供的参数。这个函数返回</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示继续遍历,或者是一个非</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">值标识停止</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.1.2</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、用户空间的</span><span lang=EN-US>ip_tables</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用户空间有四种操作:它可以读当前的表,读表的信息(钩子函数的位置和表的大小),替换表(并且获得旧的计数器),或者添加一个新的计数器。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它允许在用户空间中模拟任意原子操作:通过使用</span><span lang=EN-US style="FONT-SIZE: 12pt">libiptc</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">库,用户空间的程序可以实现&#8220;添加</span><span lang=EN-US style="FONT-SIZE: 12pt">/</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">删除</span><span lang=EN-US style="FONT-SIZE: 12pt">/</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">替换&#8221;的语义。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由于这些规则表可以传入内核空间,内核对齐就成了一个重要的问题,特别是那些用户空间和啮合空间的数据结构长度不一致的机器(比如</span><span lang=EN-US style="FONT-SIZE: 12pt">Sparc64</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的内核时</span><span lang=EN-US style="FONT-SIZE: 12pt">64</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">位,而用户空间是</span><span lang=EN-US style="FONT-SIZE: 12pt">32</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">位)。可以通过修改</span><span lang=EN-US style="FONT-SIZE: 12pt">libiptc.h</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件中的</span><span lang=EN-US style="FONT-SIZE: 12pt">IPT_ALIGN</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏的定义来解决这个问题。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.1.3</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US>ip_tables</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的使用和遍历</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内核从钩子函数中指定的位置开始遍历规则表。当规则被检查时,如果</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_ip</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构被匹配,这个规则上的每一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry_match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构按顺序被检查(同时与此</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">相关的函数被调用)。如果</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数返回</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,遍历过程就在这条规则上停止。如果这个规则的&#8216;</span><span lang=EN-US style="FONT-SIZE: 12pt">hotdrop</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8217;参数为</span><span lang=EN-US style="FONT-SIZE: 12pt">1</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,匹配规则的包会被立即丢弃(这会在匹配到一些异常包时使用,比如在</span><span lang=EN-US style="FONT-SIZE: 12pt">tcp match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数中就有这样的操作)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果规则完全匹配,计数器就会增加,同时</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry_target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">会被检查:如果这是一个标准</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,它的&#8216;</span><span lang=EN-US style="FONT-SIZE: 12pt">verdict</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8217;值就是结果(负值表示这个包如何处理,正值表示跳转的偏移量)。如果结果是正值,但是偏移不是下一条规则,&#8216;</span><span lang=EN-US style="FONT-SIZE: 12pt">back</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8217;变量就会被赋值,前一个&#8216;</span><span lang=EN-US style="FONT-SIZE: 12pt">back</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8217;值会被赋到此规则的&#8216;</span><span lang=EN-US style="FONT-SIZE: 12pt">comefrom</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8217;域。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果不是标准</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的函数会被调用:它返回一个值(非标准的</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不能跳转,否则会破坏静态循环检测算法)。这个值可以是</span><span lang=EN-US style="FONT-SIZE: 12pt">IPT_CONTINUE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,表示继续检查下一条规则。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>4.2</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、扩展</span><span lang=EN-US><font face=Arial>iptables</font></span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">因为我比较懒,所以</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">做得非常容易扩展。这是一个将工作交给其他人的手段,开源软件都是这样(自由软件,</span><span lang=EN-US style="FONT-SIZE: 12pt">RMS</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">会说,与自由有关,当我写下这些的时候,我正在听他的一个演讲)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">扩展</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">基本上有两方面的工作:通过写一个新模块扩展内核,然后写一个新的共享库来扩展用户空间的</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.2.1</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、内核</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">写一个内核模块非常简单,你可以参考例子。有一个需要注意的地方就是你的代码必须是可重入的:可能存在一个包从用户空间发出,而同时另一个包从中断到达。事实上,从</span><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US style="FONT-SIZE: 12pt">2.3.4</span></st1:chsdate><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开始,</span><span lang=EN-US style="FONT-SIZE: 12pt">SMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以在每个</span><span lang=EN-US style="FONT-SIZE: 12pt">CPU</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上的网卡中断上收发网络包。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这些函数你需要知道:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">init_module()<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这是模块的入口。它返回负值表示出错,或者返回</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示成功地将自己注册到了内核。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">cleanup_module()<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这是模块的出口,在卸载模块是调用。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">ipt_register_match()<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数用来注册一个新的</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型。你可以传递给它一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_macth</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的结构,这个结构通常被声明成一个静态变量(文件范围内)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">ipt_register_target()<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数用来注册一个新的</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型。你可以传递给它一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的结构,这个结构通常被声明成一个静态变量(文件范围内)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">ipt_unregister_target()<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">卸载你的注册的</span><span lang=EN-US style="FONT-SIZE: 12pt">target<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">ipt_unregister_match()<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">卸载你主持的</span><span lang=EN-US style="FONT-SIZE: 12pt">match<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在你的新</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的扩展空间中做一些有趣的事情(比如提供一个计数器)时要注意。在</span><span lang=EN-US style="FONT-SIZE: 12pt">SMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">机器上,整个规则表通过</span><span lang=EN-US style="FONT-SIZE: 12pt">memcpy</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">给每个</span><span lang=EN-US style="FONT-SIZE: 12pt">cpu</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">负值一份:如果你需要保存集中的信息,你可以参考在</span><span lang=EN-US style="FONT-SIZE: 12pt">limit match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中所使用的方法。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.2.2</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、新</span><span lang=EN-US>Match</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">新的</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一般都是一个独立的模块。但是可以让你的模块具有有可扩展的特性,当然这不是必须的。一种方法试试用</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">框架提供的</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_register_sockopt</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数允许用户与你的模块直接交互。另一种方法试把内部符号导出给其他模块使用,</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_tables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就是使用这种方法。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">新</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的核心是一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,这个结构有以下域:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">list<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域被初始化为&#8216;</span><span lang=EN-US style="FONT-SIZE: 12pt">{NULL</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt">NULL}</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8217;。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">name<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域是</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的名字,这个名字在用户空间中被引用。名字必须和模块的名称匹配(比如,如果名字是&#8220;</span><span lang=EN-US style="FONT-SIZE: 12pt">mac</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;,模块名称必须是&#8220;</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_mac.o</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;),这样才能自动加载。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">match<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></strong><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域是指向</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数的一个指针,函数的参数时</span><span lang=EN-US style="FONT-SIZE: 12pt">skb</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,进、出设备的指针(其中之一可能为空,这与钩子的位置相关),一个指向规则中</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据的指针(这个结构在用户空间中初始化),</span><span lang=EN-US style="FONT-SIZE: 12pt">IP offset</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">(非</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标识一个没有头部的分片),一个指向协议头的指针(比如只有</span><span lang=EN-US style="FONT-SIZE: 12pt">IP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">头部),数据的长度(例如包长度减去</span><span lang=EN-US style="FONT-SIZE: 12pt">IP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">头的长度),和一个指向</span><span lang=EN-US style="FONT-SIZE: 12pt">hotdrop</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">变量的指针。如果包匹配规则,它必须返回一个非</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">值,同时,如果它返回</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,它可以设置</span><span lang=EN-US style="FONT-SIZE: 12pt">hotdrop</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">变量为</span><span lang=EN-US style="FONT-SIZE: 12pt">1</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,表示包必须被立即丢弃。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">checkentry<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域是一个函数指针,这个函数检查规则的参数;如果函数返回</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,这条规则就不会被用户接受。例如,</span><span lang=EN-US style="FONT-SIZE: 12pt">tcp match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">值接受</span><span lang=EN-US style="FONT-SIZE: 12pt">tcp</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包,如果规则中的</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_ip</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">部分没有指定规则的协议时</span><span lang=EN-US style="FONT-SIZE: 12pt">tcp</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,它就会返回</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt">tablename</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">变量允许你的</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">去控制它可以被那些表引用,</span><span lang=EN-US style="FONT-SIZE: 12pt">hook_mask</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">变量表示规则可以被哪些钩子引用:如果你的</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">域</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的钩子没有关系,你可以不设置这个值。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">destroy<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域是一个函数指针,这个函数在引用这个</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的变量被删除时调用,它允许你在</span><span lang=EN-US style="FONT-SIZE: 12pt">checkentry</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中动态分配内存,并在这个函数中它们释放掉。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">me<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域被设置为&#8220;</span><span lang=EN-US style="FONT-SIZE: 12pt">THIS_MODULE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;,它是一个指向你的模块的指针。它的使用计数在规则创建或释放时增减。这样就可以防止用户删除一个模块(在</span><span lang=EN-US style="FONT-SIZE: 12pt">cleanup_module()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时调用),而其他规则在引用这个模块。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.2.3</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、新的</span><span lang=EN-US>target</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果你的</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">修改数据包(头部或者是数据部分),它必须调用</span><span lang=EN-US style="FONT-SIZE: 12pt">skb_unshare</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来</span><span lang=EN-US style="FONT-SIZE: 12pt">copy</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">整个数据包,特别是这个数据包是被克隆的:否则原始</span><span lang=EN-US style="FONT-SIZE: 12pt">socket</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中</span><span lang=EN-US style="FONT-SIZE: 12pt">skbuff</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是被修改过的(必须用户在使用</span><span lang=EN-US style="FONT-SIZE: 12pt">tcpdump</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的时候会看到一些很奇怪的包)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">新</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">同样是一个独立的模块。上面关于新</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的讨论通用适用于新</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">新</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的核心是一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,它被当做参数传递给</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_register_target()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数,这个结构有如下域:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">list<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域被初始化成&#8216;</span><span lang=EN-US style="FONT-SIZE: 12pt">{NULL</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt">NULL}</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8217;。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">name<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域是</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数的名称,这个名字在用户空间中被引用。名字必须和模块的名称一致(例如,如果名称是&#8220;</span><span lang=EN-US style="FONT-SIZE: 12pt">REJECT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;,那么模块名称必须是&#8220;</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_REJECT.o</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">&#8221;),这是模块自动加载所必须的。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">target<o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个指向</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数的指针,函数的参数时</span><span lang=EN-US style="FONT-SIZE: 12pt">skbuff</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,钩子的编号,入、出设备的指针(这两个指针都可以为空),一个指向</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据的指针,一个指向表中规则位置的指针。</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数可以返回</span><span lang=EN-US style="FONT-SIZE: 12pt">IPT_CONTINUE </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">(</span><span lang=EN-US style="FONT-SIZE: 12pt">-1</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">),如果需要继续遍历;或者是</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所定义的值(</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_DROP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_ACCEPT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_STOLEN etc.</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">)。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">checkentry <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域指向一个函数,它检查规则的定义,如果它返回</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,那么这条规则就不能被用户接受。</span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">destroy <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域指向一个函数,它在引用此</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的实体被删除时调用。这就允许你在</span><span lang=EN-US style="FONT-SIZE: 12pt">checkentry</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中动态分配资源而在此函数将其释放。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">me <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域被设置为</span><span lang=EN-US style="FONT-SIZE: 12pt">`THIS_MODULE'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,它是一个指向你的模块的指针。它的使用计数在引用此</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的规则创建或释放时增减。这就防止用户释放一个模块</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">调用</span><span lang=EN-US style="FONT-SIZE: 12pt">cleanup_module()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,而同时还有一条规则在引用这个规则。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.2.4</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、新</span><span lang=EN-US>table</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果有需求,你可以创建一个新的</span><span lang=EN-US style="FONT-SIZE: 12pt">table</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。为了完成这个任务,你可以调用</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_register_table()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数注册一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_table</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,这个结构有如下域:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">list <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域被初始化为</span><span lang=EN-US style="FONT-SIZE: 12pt">{ NULL, NULL }</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">name <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域是</span><span lang=EN-US style="FONT-SIZE: 12pt">table</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的名字,它会在用户空间中被引用。这个名字必须和模块名称一致</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">例如,如果</span><span lang=EN-US style="FONT-SIZE: 12pt"> table</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的名称是</span><span lang=EN-US style="FONT-SIZE: 12pt">nat</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,那么模块名称必须是</span><span lang=EN-US style="FONT-SIZE: 12pt">iptable_nat.o)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,这是模块自动加载所必须的。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">table <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这是一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_replace</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,它在用户空间里被用来替换</span><span lang=EN-US style="FONT-SIZE: 12pt">table</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构。它的</span><span lang=EN-US style="FONT-SIZE: 12pt">'counters'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指针必须被设置为</span><span lang=EN-US style="FONT-SIZE: 12pt">NULL</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这个数据结构可以被声明为</span><span lang=EN-US style="FONT-SIZE: 12pt">'_initdata'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,这样就可以在启动之后释放掉。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">valid_hooks <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这是一个</span><span lang=EN-US style="FONT-SIZE: 12pt">IPv4</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">钩子的字掩码,它代表可以引用表的钩子:它被用来检查规则指针是否正确,而且可以在</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang=EN-US style="FONT-SIZE: 12pt">checkentry</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数中计算可能被引用的钩子。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">lock <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这是整个表的读写自旋锁。它被初始化为</span><span lang=EN-US style="FONT-SIZE: 12pt">RW_LOCK_UNLOCKED</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">private <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个域在</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_tables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">代码中内部引用。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.2.5</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、用户空间工具</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">现在你可以开始写内核模块了,但是你也许会需要在用户空间来设置内核的某些选项。我们不会为每个</span><span style="FONT-SIZE: 12pt"> </span><span lang=EN-US>iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">扩展创建一个分支,相反,我们使用共享库。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">新的表通常不需要对</span><span lang=EN-US>iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进行扩展:用户使用</span><span lang=EN-US style="FONT-SIZE: 12pt">"-t"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">参数来引用新的表。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">共享库必须有一个</span><span lang=EN-US style="FONT-SIZE: 12pt">'_init()'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数,它会在加载时调用:这与内核模块的</span><span lang=EN-US style="FONT-SIZE: 12pt">'init_module'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数等价。在这个函数中,需要调用</span><span lang=EN-US style="FONT-SIZE: 12pt">register_match()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span><span lang=EN-US style="FONT-SIZE: 12pt">register_target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,这取决于你的共享库中提供的是新的</span><span lang=EN-US style="FONT-SIZE: 12pt"> match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">还是新的</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你需要提供一个共享库:它可以用来初始化结构或者提供附加的选项。我坚持使用共享库,即使这个库什么都不做,这样可以减少有关共享库找不到的问题报告。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables.h</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中定义了一些有用的函数,特别是如下几个:</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">check_inverse() <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">检查参数是否有</span><span lang=EN-US style="FONT-SIZE: 12pt">'!'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,如果有,设置参数的</span><span lang=EN-US style="FONT-SIZE: 12pt">'invert'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标记。如果它返回真,你就可以增加</span><span lang=EN-US style="FONT-SIZE: 12pt">optind</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,就像例子中所做的一样。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">string_to_number() <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">把字串转换成一个给定范围内的数字,如果字符串的格式错误或者数字超出了范围,它返回</span><span lang=EN-US style="FONT-SIZE: 12pt">-1</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt">'string_to_number'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">依赖于</span><span lang=EN-US style="FONT-SIZE: 12pt">'strtol'(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">参见手册</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,这就意味着,如果字串开头是</span><span lang=EN-US style="FONT-SIZE: 12pt">"0x"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,字串将被转成</span><span lang=EN-US style="FONT-SIZE: 12pt">16</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进制的数字,如果是</span><span lang=EN-US style="FONT-SIZE: 12pt">"0"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,字串将被转换成</span><span lang=EN-US style="FONT-SIZE: 12pt">8</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">进制的数字。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">exit_error() <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数在有错误发生的时候调用。通常,第一个参数是</span><span lang=EN-US style="FONT-SIZE: 12pt">`PARAMETER_PROBLEM</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,表示用户的使用方式有错误。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.2.6</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、新的</span><span lang=EN-US>Match</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你的共享库中的</span><span lang=EN-US style="FONT-SIZE: 12pt">_init()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数调用</span><span lang=EN-US style="FONT-SIZE: 12pt">register_match()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数这次一个</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables_match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,这个结构有如下域:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">next <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个指针用于创建一个</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的链表</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就像规则链表一样</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。它必须被初始化为</span><span lang=EN-US style="FONT-SIZE: 12pt">NULL</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">name <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的名称,它必须和库的名称一致</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">比如</span><span lang=EN-US style="FONT-SIZE: 12pt">tcp</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">libipt_tcp.so)<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">version <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通常被设置为</span><span lang=EN-US style="FONT-SIZE: 12pt">IPTABLES_VERSION</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:这保证</span><span lang=EN-US>iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">程序不会加载错误的共享库。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">size <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据的大小,你必须使用</span><span lang=EN-US style="FONT-SIZE: 12pt">IPT_ALIGN()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏来保证它正确地对齐。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">userspacesize <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对有些</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来说,内核会在内部修改一些值</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">比如</span><span lang=EN-US style="FONT-SIZE: 12pt">limit match)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这就意味着,只用</span><span lang=EN-US style="FONT-SIZE: 12pt">memcmp</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来比较两条规则是否相同是不够的</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它会在删除匹配规则的函数中调用</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。在这种情况下,把所有不改变的域放到结构的开始部分,同时把不改变的域的大小值赋给</span><span lang=EN-US style="FONT-SIZE: 12pt">userspacesize</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。一般情况下,这个值和</span><span lang=EN-US style="FONT-SIZE: 12pt">size</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">值相同。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">help <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打印</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的使用语法的函数。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">init <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数被用来初始化</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry_match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构中的扩展空间</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果有的话</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,并设置</span><span lang=EN-US style="FONT-SIZE: 12pt"> nfcache</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">位的值。如果你检查的值不能用</span><span lang=EN-US style="FONT-SIZE: 12pt">linux/include/netfilter_ipv4.h</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中所定义的值来表达,你可以简单的把</span><span lang=EN-US style="FONT-SIZE: 12pt">nfcache</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">逻辑或</span><span lang=EN-US style="FONT-SIZE: 12pt">NFC_UNKNOWN</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这个函数在</span><span lang=EN-US style="FONT-SIZE: 12pt">parse()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数之前调用。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">parse <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数用于解析命令行上的参数:如果某些参数是必须的,它返回非</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">值。如果选项前有</span><span lang=EN-US style="FONT-SIZE: 12pt">'!', 'invert'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">值为真。</span><span lang=EN-US style="FONT-SIZE: 12pt">'flags'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指针在</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">库中使用,它用一个位与的掩码来表示命令行上有哪些选项。你需要确认你是否修改了</span><span lang=EN-US style="FONT-SIZE: 12pt">nfcache</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">域。如果需要的话,你可以通过重新分配内存来扩充</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry_match </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构的大小,但是你必须保证你所传递的结构的大小值是通过</span><span lang=EN-US style="FONT-SIZE: 12pt">IPT_ALIGN</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏对齐的。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">final_check <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数在命令行选项被解析后调用。它处理你</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry_match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的</span><span lang=EN-US style="FONT-SIZE: 12pt">flags</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">项。它可以检查是否所有的必选项都已经有了,如果没有,则调用</span><span lang=EN-US style="FONT-SIZE: 12pt">exit_error()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">print <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由规则的列表函数调用</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">到标准输出</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来打印</span><span lang=EN-US style="FONT-SIZE: 12pt">match</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的额外信息。如果用户指定了</span><span lang=EN-US style="FONT-SIZE: 12pt">-n</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">选项,则打印成数字的</span><span lang=EN-US style="FONT-SIZE: 12pt">flag</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">会被置位。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">save <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它与</span><span lang=EN-US style="FONT-SIZE: 12pt">parse</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数刚好相反:它被</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables-save</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">调用,用来生成规则的命令行。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">extra_opts <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这是一个以</span><span lang=EN-US style="FONT-SIZE: 12pt">NULL</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结束的数组,表示你的库所能处理的扩展选项。它和当前的选项一起传递给</span><span lang=EN-US style="FONT-SIZE: 12pt">getopt_long</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,详情请参考手册。</span><span lang=EN-US style="FONT-SIZE: 12pt">get_long</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的返回值做为第一个参数</span><span lang=EN-US style="FONT-SIZE: 12pt">('c')</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">传递给你的</span><span lang=EN-US style="FONT-SIZE: 12pt">'parse()'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在结构的最后有其他区的一些域,这些域由</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内部使用,你不需要设置它们。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.2.7</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、新的</span><span lang=EN-US>target</span></font></h3>
<p style="TEXT-INDENT: 21pt"><font face=宋体>你的共享库中的<span lang=EN-US>_init</span>函数调用<span lang=EN-US>register_target()</span>函数注册<span lang=EN-US>iptables_target</span>结构,它的域和上面所描述的<span lang=EN-US>iptables_match</span>的域类似。</font></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.2.8</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、使用</span><span lang=EN-US>'libiptc'</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">libiptc</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是一个用于列表、处理内核模块中规则的库。它目前用在</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">程序中,当然,它也可以用来方便地写其他工具。使用这些函数,你必须是根用户。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内核中的表只是一个规则表和一些代表入口的数字。链名</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">比如</span><span lang=EN-US style="FONT-SIZE: 12pt">"INPUT")</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用来表示这些规则。用户定义的链通过在用户定义的链之前插入一个错误代码来标识,它的链名放在</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的扩展数据中</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标准链的位置由三个表的入口位置所定义</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以下几个是标准的</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:</span><span lang=EN-US style="FONT-SIZE: 12pt">ACCEPT,DROP,QUEUE(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它们被相应的解释为</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_ACCEPT,NF_DROP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_QUEUE)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt"> RETURN(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它被翻译为</span><span lang=EN-US style="FONT-SIZE: 12pt">IPT_RETURN</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,这个值在</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_tables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中会特殊处理</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,和</span><span lang=EN-US style="FONT-SIZE: 12pt">JUMP(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它把链的名称翻译为表中的偏移值</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p style="TEXT-INDENT: 21pt"><span style="mso-font-kerning: 1.0pt; mso-bidi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font face=宋体>当</font></span><span lang=EN-US style="FONT-FAMILY: 'Times New Roman','serif'; mso-font-kerning: 1.0pt">iptc_init</span><span style="mso-font-kerning: 1.0pt; mso-bidi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font face=宋体>调用时,表</font></span><span lang=EN-US style="FONT-FAMILY: 'Times New Roman','serif'; mso-font-kerning: 1.0pt">(</span><span style="mso-font-kerning: 1.0pt; mso-bidi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"><font face=宋体>包括计数器</font></span><span lang=EN-US style="FONT-FAMILY: 'Times New Roman','serif'; mso-font-kerning: 1.0pt">)</span><font face=宋体><span style="mso-font-kerning: 1.0pt; mso-bidi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">被读出。这个表可以用下面这些函数处理:</span><span lang=EN-US style="FONT-FAMILY: 'Times New Roman','serif'; mso-font-kerning: 1.0pt"><o:p></o:p></span></font></p>
<p><font face=宋体><span lang=EN-US>`iptc_insert_entry()', `iptc_replace_entry()', `iptc_append_entry()', `iptc_delete_entry()', `iptc_delete_num_entry()', `iptc_flush_entries()', `iptc_zero_entries()', `iptc_create_chain()' `iptc_delete_chain()', `iptc_set_policy()'</span>。<span lang=EN-US style="FONT-FAMILY: 'Times New Roman','serif'; mso-font-kerning: 1.0pt"><o:p></o:p></span></font></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对表的修改直到调用</span><span lang=EN-US style="FONT-SIZE: 12pt">iptc_commit()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">后才被提交。这就意味着如果有两个用户调用库来处理同一个链就会出现死锁。这就需要加锁来避免这种情况,但是目前的实现中还没有锁。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">计数器不存在死锁的问题。在读写操作过程中,内核计数器的增加会在新的表中体现出来。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以下是一些辅助函数:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">iptc_first_chain() <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数返回表中的第一个链。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">iptc_next_chain() <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数返回表中下一个链的名称,如果不存在,返回</span><span lang=EN-US style="FONT-SIZE: 12pt">NULL</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">iptc_builtin() <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">返回真,如果这个链名是一个内建的链。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">iptc_first_rule() <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">返回给定链中的第一条规则,如果没有规则,返回</span><span lang=EN-US style="FONT-SIZE: 12pt">NULL</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">iptc_next_rule() <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">返回给的链中的下一条规则,如果到了链尾,返回</span><span lang=EN-US style="FONT-SIZE: 12pt">NULL</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">iptc_get_target() <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">取给定规则中的</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。如果这是一个扩展的</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,返回</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的名称。如果这是一个到其他链的跳转,返回那个链的名称。如果这是一个判断</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">比如</span><span lang=EN-US style="FONT-SIZE: 12pt">DROP)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,返回其名称。如果没有</span><span lang=EN-US style="FONT-SIZE: 12pt"> target(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一条统计规则</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,则返回空串。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">需要指出的是,应该使用这个函数,而不是直接返回</span><span lang=EN-US style="FONT-SIZE: 12pt">ipt_entry</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构中的</span><span lang=EN-US style="FONT-SIZE: 12pt">verdict</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">值。使用这个函数可以在标准的判断值上增加更多的解释。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">iptc_get_policy() <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">取内建链的策略值,并把</span><span lang=EN-US style="FONT-SIZE: 12pt">counter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">参数填充为匹配此策略的计数。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">iptc_strerror() <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数对</span><span lang=EN-US style="FONT-SIZE: 12pt">iptc</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">库中的每个错误值返回一个描述性的字串。如果函数出错,它通常会设置</span><span lang=EN-US style="FONT-SIZE: 12pt">errno:</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个值可以传递给</span><span lang=EN-US style="FONT-SIZE: 12pt">iptc_strerror</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,它可以输出错误信息。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>4.3</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、理解地址转换</span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">欢迎来到内核地址转换的世界。需要指出的是,目前所涉及的架构,首要目标是满足完备性而不是高效。将来的工作会大大地提升系统的性能。但目前来说,让我满意的是基本的功能都工作正常。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址转换分为连接跟踪(它不会修改包的内容)和地址转换两部分。连接跟踪同样也会被</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模块使用,因此在</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">里用到的一些连接跟踪的状态,在地址转换中根本不会用到。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.3.1</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、连接跟踪</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">连接跟踪的钩子函数在</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_IP_LOCAL_OUT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_IP_PRE_ROUTING</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">钩子上的优先级较高,这样就可以在包进入系统之前记录它。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">skb</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的</span><span lang=EN-US style="FONT-SIZE: 12pt">nfct</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">域是一个指向</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构中</span><span lang=EN-US style="FONT-SIZE: 12pt">infos[]</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数组中的某个项的指针。因此我们可以通过</span><span lang=EN-US style="FONT-SIZE: 12pt">nfct</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所指向的域在</span><span lang=EN-US style="FONT-SIZE: 12pt">infos[]</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数组中的位置来判断</span><span lang=EN-US style="FONT-SIZE: 12pt">skb</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的状态:这个指针把</span><span lang=EN-US style="FONT-SIZE: 12pt">skb</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与状态结构以及</span><span lang=EN-US style="FONT-SIZE: 12pt">skb</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的状态关联起来。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">取</span><span lang=EN-US style="FONT-SIZE: 12pt">nfct</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">域最好的方法是调用</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_get</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数,如果</span><span lang=EN-US style="FONT-SIZE: 12pt">nfct</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">没有设置,它返回</span><span lang=EN-US style="FONT-SIZE: 12pt">NULL</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,如果已经设置,它返回指向连接的指针,并且给</span><span lang=EN-US style="FONT-SIZE: 12pt">ctinfo</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">赋值,</span><span lang=EN-US style="FONT-SIZE: 12pt">ctinfo</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">描述了包与连接的关系。这个枚举类型有以下几个值:</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">IP_CT_ESTABLISHED <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个包属于已建立连接,并且在原方向上。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">IP_CT_RELATED <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个包与连接相关,并且在原方向上。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">IP_CT_NEW <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个包将创建一个新连接</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">很明显,它在原方向上</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">IP_CT_ESTABLISHED + IP_CT_IS_REPLY <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个包属于已建立连接,并且在应答方向上。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">IP_CT_RELATED + IP_CT_IS_REPLY <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个包与连接相关,并且在应答方向上。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应答方向的包可以通过检查状态值是否大于等于</span><span lang=EN-US>IP_CT_IS_REPLY</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来判断。</span></p>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>4.4</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、扩展连接跟踪和地址转换</span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个框架需要适应任意协议和地址映射类型。有些映射类型会比较特殊,比如负载均衡</span><span lang=EN-US style="FONT-SIZE: 12pt">/</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">高可用映射等。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">从内部来说,在做绑定或匹配规则前,连接跟踪会把一个包转换成一个</span><span lang=EN-US style="FONT-SIZE: 12pt">"tuple"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,它代表了连接跟踪对包感兴趣的部分。这个</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有一个可改变部分和一个不可改变部分,叫做</span><span lang=EN-US style="FONT-SIZE: 12pt">"src"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">"dst"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,这是源转换中对第一个包的视图</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对目的转换来说,这是第一个应答包的视图</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这个</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对同一流的同一方向上的包是一样的。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">例如</span><span lang=EN-US style="FONT-SIZE: 12pt">,</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对一个</span><span lang=EN-US style="FONT-SIZE: 12pt">TCP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包的</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来说,它包含一个可改变部分:源地址和源端口;一个不可改变部分:目的地址和目的端口。可改变部分和不可改变部分并不一定是同一类型,例如,一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ICMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包的</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包括可改变部分:源地址和</span><span lang=EN-US style="FONT-SIZE: 12pt">ICMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang=EN-US style="FONT-SIZE: 12pt">ID</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,不可改变部分:目的地址和</span><span lang=EN-US style="FONT-SIZE: 12pt">ICMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的类型和代码。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">每一个</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都有一个反向的</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,它代表应答方向上的</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。例如,</span><span lang=EN-US style="FONT-SIZE: 12pt">ICMP ping</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包的</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</span><span lang=EN-US style="FONT-SIZE: 12pt">icmp id 12345</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,从</span><span lang=EN-US style="FONT-SIZE: 12pt">192.168.1.1</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">到</span><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US style="FONT-SIZE: 12pt">1.2.3</span></st1:chsdate><span lang=EN-US style="FONT-SIZE: 12pt">.4</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,而</span><span lang=EN-US style="FONT-SIZE: 12pt">ICMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应答包的</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</span><span lang=EN-US style="FONT-SIZE: 12pt">icmp id 12345</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,从</span><span lang=EN-US style="FONT-SIZE: 12pt">1.2.3.4</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">到</span><span lang=EN-US style="FONT-SIZE: 12pt">192.168 .1.1</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这些</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的类型是</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,它的用途很广泛。事实上,一个包的完整信息就包括:这个包是在哪个钩子函数中处理的</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这会决定哪些信息是可改变的</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,从哪个设备进、出,和这个包的</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">大多数</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都包含在</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_tuple_hash</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构中,这个结构有一个链表结构和一个指向</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所代表连接的指针。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">连接的数据结构类型是</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:它有两个</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_tuple_hash</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">类型的域,一个表示原方向的包</span><span lang=EN-US style="FONT-SIZE: 12pt">(tuplehash[IP_CT_DIR_ORIGINAL])</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,一个表示应答方向的包</span><span lang=EN-US style="FONT-SIZE: 12pt">(tuplehash[IP_CT_DIR_REPLY])</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址转换代码首先检查</span><span lang=EN-US style="FONT-SIZE: 12pt">skbuff</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang=EN-US style="FONT-SIZE: 12pt">nfct</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">域来判断当前包是否属于一个已创建的连接。如果不是,它是否要创建一个新的连接,如果是,这个包在哪个方向上。如果是已存在连接,它就可以根据连接中的可改变部分来决定需要修改包的哪个部分。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果是创建新的连接,它首先遍历</span><span lang=EN-US style="FONT-SIZE: 12pt">nat</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表来查找这个包匹配的规则。如果有规则匹配到,它就会初始化连接中两个方向上可改变的部分。同时修改连接中的应答方向上的</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,使得应答包可以匹配到这个连接。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果没有匹配到任何规则,地址转换代码也会创建一个空绑定。这不会修改任何包,但是可以防止其他流错误地映射到已存在的连接上。有时,我们可能无法创建一个空绑定,因为在当前地连接上已经有了一个映射,在这种情况下,协议处理代码可能会重新映射当前流,即使这是一个空绑定。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.4.1</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、标准地址转换</span><span lang=EN-US>target</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址转换</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和其他</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的扩展</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的基本情况一样,但是它只检查</span><span lang=EN-US style="FONT-SIZE: 12pt">nat</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表。</span><span lang=EN-US style="FONT-SIZE: 12pt">SNAT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">DNAT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都有一个</span><span lang=EN-US style="FONT-SIZE: 12pt"> ip_nat_multi_range</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构的参数,这个参数描述了映射地址的范围。一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_nat_range</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构描述了地址范围</span><span lang=EN-US style="FONT-SIZE: 12pt"> (</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最小地址和最大地址</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和与协议相关</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">比如</span><span lang=EN-US style="FONT-SIZE: 12pt">tcp</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议的端口</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的端口范围</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最小端口和最大端口</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这个结构中还有一个</span><span lang=EN-US style="FONT-SIZE: 12pt">flags</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">域描述</span><span lang=EN-US style="FONT-SIZE: 12pt">IP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址是否可以被映射</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有些时候,我们只想映射协议</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的某一部分,而不是地址</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,另外它还描述协议相关部分的映射范围是否正确。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">ip_nat_multi_range</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构是一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_nat_rangle</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">元素的数组,这就意味这一个范围可以是</span><span lang=EN-US style="FONT-SIZE: 12pt">"<st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False">1.1.1</st1:chsdate>.1-1.1. 1.2 ports 50-55 </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">并且</span><span lang=EN-US style="FONT-SIZE: 12pt"> 1.1.1.2 port 80"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。每一个范围元素都加到了范围集合中</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这是一个集合,符合集合的约束</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.4.2</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、新的协议</span></font></h3>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.4.3</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、深入内核</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实现一个新协议的地址转换,首先需要考虑的是一个</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中,哪些是可改变的,哪些是不可改变的。</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的参数可以唯一确定一个流。可改变部分是我们可以做地址转换的部分:对</span><span lang=EN-US style="FONT-SIZE: 12pt">tcp</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来说,它是源端口,对</span><span lang=EN-US style="FONT-SIZE: 12pt">ICMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来说,它是</span><span lang=EN-US style="FONT-SIZE: 12pt"> icmp ID</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">;一些被用作</span><span lang=EN-US style="FONT-SIZE: 12pt">&#8220;</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">流标识</span><span lang=EN-US style="FONT-SIZE: 12pt">"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。剩余的部分同样可以唯一的标识一个流,但是我们不能改变它</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">例如</span><span lang=EN-US style="FONT-SIZE: 12pt">tcp</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的目的端口,</span><span lang=EN-US style="FONT-SIZE: 12pt"> ICMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的类型等</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一旦确定了这些事情,你可以写一个连接跟踪的扩展,你需要调用</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_register_protocol()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数去注册一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_protocol</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_protocol</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构中有如下域:</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">list <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化为</span><span lang=EN-US style="FONT-SIZE: 12pt">{ NULL, NULL }</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">proto <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议号,可以参考</span><span lang=EN-US style="FONT-SIZE: 12pt">/etc/protocols<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">name <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议名称,这个名称是用户可以看到的名称,所以最好使用</span><span lang=EN-US style="FONT-SIZE: 12pt">/etc/protocols</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的经典名称。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">pkt_to_tuple <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">给定一个网络包,取网络包的参数构造一个</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt">'datah'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指针指向网络包的头</span><span lang=EN-US style="FONT-SIZE: 12pt"> (</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">只有</span><span lang=EN-US style="FONT-SIZE: 12pt">IP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">头</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt">datalen</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示网络包的长度。如果网络包的长度小于标准头部的长度,返回</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">;</span><span lang=EN-US style="FONT-SIZE: 12pt">datalen</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">必须至少有</span><span lang=EN-US style="FONT-SIZE: 12pt">8</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个字节长</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这是框架强制规定</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">invert_tuple <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数根据</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">构造一个应答的</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">print_tuple <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数用于打印</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中与协议相关的部分,通常会把</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的值打印到一个缓冲区中。函数会返回打印缓冲区的长度。这个函数也被</span><span lang=EN-US style="FONT-SIZE: 12pt">/proc</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数用来打印状态信息。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">print_conntrack <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数用来打印</span><span lang=EN-US style="FONT-SIZE: 12pt">conntrack</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构中的私有值,当然,也被</span><span lang=EN-US style="FONT-SIZE: 12pt">/proc</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数用来打印状态信息。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">packet <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果连接在已建立状态下收到的包就调用这个函数。你可以得到一个指向</span><span lang=EN-US style="FONT-SIZE: 12pt">conntrack</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构的指针,</span><span lang=EN-US style="FONT-SIZE: 12pt">IP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">头,长度和</span><span lang=EN-US style="FONT-SIZE: 12pt">ctinfo</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。对这个包,你可以返回一个判断</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通常是</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_ACCEPT)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,或者是</span><span lang=EN-US style="FONT-SIZE: 12pt">-1</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,表示这个包不是正常的包。如果你愿意,你可以在着个函数中删除连接,但是你必须遵守一定的规则以避免死锁</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">请参考</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_ proto_icmp.c</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的代码</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">:</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt">if (del_timer(&amp;ct-&gt;timeout))<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ct-&gt;timeout.function((unsigned long)ct);<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">new <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数在创建一个新连接时调用。这个函数没有</span><span lang=EN-US style="FONT-SIZE: 12pt">ctinfo</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">参数,因为创建连接的第一个包的</span><span lang=EN-US style="FONT-SIZE: 12pt">ctinfo</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是</span><span lang=EN-US style="FONT-SIZE: 12pt"> IP_CT_NEW</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。如果创建失败,这个函数返回</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,或者返回新连接的超时值。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当你完成并测试了你的新协议的连接跟踪代码,你就可以在地址转换代码中加入相应的对新协议的处理。这就意味这你需要写一个新的模块来扩展地址转换代码。首先,你需要调用</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_nat_protocol_register()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数注册一个</span><span lang=EN-US style="FONT-SIZE: 12pt"> ip_nat_protocol</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,这个结构有如下域:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">list <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化为</span><span lang=EN-US style="FONT-SIZE: 12pt">{ NULL, NULL }</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">name <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议的名称。这个名称会呈现给用户,所以最好使用</span><span lang=EN-US style="FONT-SIZE: 12pt">/etc/protocols</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中定义的经典名称,这也有利于自动加载,这个问题会在后面讲到。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">protonum <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议号,请参考</span><span lang=EN-US style="FONT-SIZE: 12pt">/etc/protocols</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">manip_pkt <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这是连接跟踪中</span><span lang=EN-US style="FONT-SIZE: 12pt">pkt_to_tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数的另一半:你可以把它想象成</span><span lang=EN-US style="FONT-SIZE: 12pt">"tuple_to_pkt"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。当然,它们还有一些区别:你可以得到</span><span lang=EN-US style="FONT-SIZE: 12pt">IP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">头的指针,网络包的总长度。这是因为在有些协议中</span><span lang=EN-US style="FONT-SIZE: 12pt">(UDP,TCP)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">需要知道</span><span lang=EN-US style="FONT-SIZE: 12pt">IP </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">头的信息。你可以从</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_nat_tuple_manip</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中得到</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中需要修改的部分</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">比如</span><span lang=EN-US style="FONT-SIZE: 12pt">src</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">域</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,而不是修改整个</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,你还可以知道需要做哪种转换。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">in_range <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数可以告诉我们给定的</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的可改变部分是否在给定范围之内。这个函数用了点小技巧:我们已经知道了对</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">做哪种转换,它会告诉我们如何去解释范围的涵义</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我们的目标是源范围还是目的范围?</span><span lang=EN-US style="FONT-SIZE: 12pt">)<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数可以检查已创建的映射是否在正确的范围内,并且可以告诉所做的修改是否必要。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">unique_tuple <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数是地址转换代码的核心:给定一个</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和范围,我们在给定的范围内修改</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的值并保证这个新的</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是唯一的。如果我们不能找到一个未使用的</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,函数返回</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。我们同样会得到一个指向</span><span lang=EN-US style="FONT-SIZE: 12pt">conntrack</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构的指针,这个指针会在</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_nat_used_tuple()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数中用到。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一般的方法是简单的在范围之内遍历所有可用值,并使用</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_nat_used_tuple()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数检查新的</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是否已经存在。重复这个过程,直到</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_nat_used_tuple()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数返回</span><span lang=EN-US style="FONT-SIZE: 12pt">false</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">空绑定在这种情况下已经被检查了,这是因为:空绑定要么超出了给定范围,要么已经存在。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果没有设置</span><span lang=EN-US style="FONT-SIZE: 12pt">IP_NAT_RANGE_PROTO_SPECIFIED</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标记,那么只需要做地址转换,而不是地址伪装:在指定的范围内做地址转换。如果不需要做转换</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">例如,在</span><span lang=EN-US style="FONT-SIZE: 12pt">TCP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的目的转换中,除非要求,否则不转换其目的端口</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,就返回</span><span lang=EN-US style="FONT-SIZE: 12pt"> 0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">print <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">给定一个字符缓冲区,一个</span><span lang=EN-US style="FONT-SIZE: 12pt">match tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和掩码,打印协议相关的部分并返回打印缓冲区的长度。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">print_range <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">给定一个字符缓冲区和范围,打印协议相关的范围并返回打印缓冲区的长度。如果</span><span lang=EN-US style="FONT-SIZE: 12pt"> IP_NAT_RANGE_PROTO_SPECIFIED</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">没有设置,这个函数不会被调用。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.4.4</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、新的地址转换</span><span lang=EN-US>target</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这部分很有趣。你可以写新的地址转换</span><span lang=EN-US style="FONT-SIZE: 12pt">target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来提供新的映射类型。在基本的映射类型之外,我们还提供了</span><span lang=EN-US style="FONT-SIZE: 12pt"> MASQUERADE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">REDIRECT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。它们都很简单,足够你学会如何写一个新的地址转换</span><span lang=EN-US style="FONT-SIZE: 12pt">target.<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它们的写法和其他</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables target</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">没什么区别,但是在内部,它们会扩展连接并调用</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_nat_setup_info() </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.4.5</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US>helper</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">连接跟踪的</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以使得连接跟踪代码处理多连接的协议</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">比如</span><span lang=EN-US style="FONT-SIZE: 12pt">FTP)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,并且可以创建新连接并把它标识为当前连接的子连接,子连接的地址从协议流中获取。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址转换的</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">做两件事情:首先,它修改当前流中的协议地址;其次;它可以根据原有连接的信息来对新连接做地址转换。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.4.6</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、连接跟踪</span><span lang=EN-US>helper</span></font></h3>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.4.7</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、描述</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">连接跟踪的任务就是确定某个包是否属于一个已建立的连接。它通过以下手段来完成这项工作:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l4 level1 lfo12"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">告诉</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我们的模块对哪些包感兴趣(通常</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">只监控一个特定的端口)</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l4 level1 lfo12"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注册一个函数。这个函数会在包匹配时被调用</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l4 level1 lfo12"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通过调用</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_expect_related()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数来创建一个</span><span lang=EN-US style="FONT-SIZE: 12pt">expect</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,标识将要创建的相关连接</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当新连接的第一个包到来时,还需要做一些额外的工作,模块注册了一个回调函数来完成这些工作。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.4.8</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、可用的结构和函数</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你的内核模块首先需要调用</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_helper_register()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数来注册一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,这个结构有如下的域:</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">list <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所有的连接跟踪</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">放到一个链表中。初始化为</span><span lang=EN-US style="FONT-SIZE: 12pt">{ NULL, NULL }</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">name <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的名字,可以使用</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所关心的协议名称</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">比如</span><span lang=EN-US style="FONT-SIZE: 12pt">ftp,irc</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">等</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">flags <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个标记集合,有如下值可选:</span><span lang=EN-US style="FONT-SIZE: 12pt"> IP_CT_HELPER_F_REUSE_EXPECT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果达到</span><span lang=EN-US style="FONT-SIZE: 12pt">expect</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的上限,是否要重用。</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">me <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指向</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模块的指针。用</span><span lang=EN-US style="FONT-SIZE: 12pt">THIS_MODULE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏初始化。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">max_expected <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以创建未确认的</span><span lang=EN-US style="FONT-SIZE: 12pt">expect</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的最大数。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">timeout <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">未确认的</span><span lang=EN-US style="FONT-SIZE: 12pt">expect</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的存活时间</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">单位:秒</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt">expect</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">超时后被删除。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">tuple <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,表示此模块关心的连接的参数。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">mask <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">另一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,是上面</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的掩码,描述</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关心的域。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">help <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对每一个匹配</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple+mask</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的包调用找个函数。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.4.9</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、一个连接跟踪</span><span lang=EN-US>helper</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">范例</span></font></h3>
<pre><span lang=EN-US><font face=宋体>#define FOO_PORT<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>111</font></span></pre>
<pre><span lang=EN-US><font face=宋体>static int foo_expectfn(struct ip_conntrack *new)</font></span></pre>
<pre><span lang=EN-US><font face=宋体>{</font></span></pre>
<pre><font face=宋体><span lang=EN-US><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>/* </span>当新连接的第一个包到达时调用<span lang=EN-US> */</span></font></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return 0;</font></span></pre>
<pre><span lang=EN-US><font face=宋体>}</font></span></pre>
<pre><span lang=EN-US><font face=宋体>static int foo_help(const struct iphdr *iph, size_t len, </font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>struct ip_conntrack *ct, </font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>enum ip_conntrack_info ctinfo)</font></span></pre>
<pre><span lang=EN-US><font face=宋体>{</font></span></pre>
<pre><font face=宋体><span lang=EN-US><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>/* </span>分析协议<span lang=EN-US> */</span></font></pre>
<pre><font face=宋体><span lang=EN-US><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>/* </span>取出协议相关的地址和端口<span lang=EN-US> */</span></font></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ct-&gt;help.ct_foo_info = ...</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>if (there_will_be_new_packets_related_to_this_connection)</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct ip_conntrack_expect exp;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>memset(&amp;exp, 0, sizeof(exp));</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exp.t = tuple_specifying_related_packets;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exp.mask = mask_for_above_tuple;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exp.expectfn = foo_expectfn;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exp.seq = tcp_sequence_number_of_expectation_cause;</font></span></pre>
<pre><font face=宋体><span lang=EN-US><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>/* </span>新连接相关的信息<span lang=EN-US> */</span></font></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exp.help.exp_foo_info = ...</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ip_conntrack_expect_related(ct, &amp;exp);</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return NF_ACCEPT;</font></span></pre>
<pre><span lang=EN-US><font face=宋体>}<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></font></span></pre>
<pre><span lang=EN-US><font face=宋体>static struct ip_conntrack_helper foo;</font></span></pre>
<pre><span lang=EN-US><font face=宋体>static int __init init(void)</font></span></pre>
<pre><span lang=EN-US><font face=宋体>{</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>memset(&amp;foo, 0, sizeof(struct ip_conntrack_helper);</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>foo.name = "foo";</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>foo.flags = IP_CT_HELPER_F_REUSE_EXPECT;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>foo.me = THIS_MODULE;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>foo.max_expected = 1;<span style="mso-spacerun: yes">&nbsp;&nbsp; </span>/* one expectation at a time */</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>foo.timeout = 0;<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>/* expectation never expires */</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>/* we are interested in all TCP packets with destport 111 */</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>foo.tuple.dst.protonum = IPPROTO_TCP;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>foo.tuple.dst.u.tcp.port = htons(FOO_PORT);</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>foo.mask.dst.protonum = 0xFFFF;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>foo.mask.dst.u.tcp.port = 0xFFFF;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>foo.help = foo_help;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return ip_conntrack_helper_register(&amp;foo);<span style="mso-spacerun: yes">&nbsp; </span></font></span></pre>
<pre><span lang=EN-US><font face=宋体>}</font></span></pre>
<pre><span lang=EN-US><font face=宋体>static void __exit fini(void)</font></span></pre>
<pre><span lang=EN-US><font face=宋体>{</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ip_conntrack_helper_unregister(&amp;foo);</font></span></pre>
<pre><span lang=EN-US><font face=宋体>}</font></span></pre>
<h3 style="MARGIN: 13pt 0cm"><font size=5><span lang=EN-US>4.4.10</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、地址转换</span><span lang=EN-US>helper</span><span lang=EN-US style="FONT-SIZE: 13.5pt; LINE-HEIGHT: 173%"><o:p></o:p></span></font></h3>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.4.11</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、描述</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址转换</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对一些应用协议做特殊处理。通常是对协议数据的改动:比如在</span><span lang=EN-US style="FONT-SIZE: 12pt">FTP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议中,</span><span lang=EN-US style="FONT-SIZE: 12pt">PORT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">命令会把客户端的</span><span lang=EN-US style="FONT-SIZE: 12pt">IP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址和端口告诉服务器,让服务器来连接。这种情况下,</span><span lang=EN-US style="FONT-SIZE: 12pt">FTP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议的地址转换</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">必须替换这个地址和端口,否则服务器无法连接客户端。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果应用协议是基于</span><span lang=EN-US style="FONT-SIZE: 12pt">TCP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的,就会复杂一点。一个原因就是可能会改变包的大小</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以</span><span lang=EN-US style="FONT-SIZE: 12pt">FTP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议为例,替换后的</span><span lang=EN-US style="FONT-SIZE: 12pt"> IP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址、端口可能和原来的</span><span lang=EN-US style="FONT-SIZE: 12pt">IP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址、端口长度不一样</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。如果我们改变了包的大小,在</span><span lang=EN-US style="FONT-SIZE: 12pt">NAT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的两边,</span><span lang=EN-US style="FONT-SIZE: 12pt">syn/ack</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的序列号就会不同。</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">例如:如果我们扩展了</span><span lang=EN-US style="FONT-SIZE: 12pt">4</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">个字节,我们就需要把找个方向上的</span><span lang=EN-US style="FONT-SIZE: 12pt">tcp</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包的序列号加上这个偏移值</span><span lang=EN-US style="FONT-SIZE: 12pt">)<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与原连接相关的连接需要做地址转换。以</span><span lang=EN-US style="FONT-SIZE: 12pt">FTP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为例,所有数据连接的包都需要修改为与原连接对应的地址,而不是通过</span><span lang=EN-US style="FONT-SIZE: 12pt">nat</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表的规则来创建地址转换结构。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l14 level1 lfo13"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对原连接的包调用回调函数</span><span lang=EN-US style="FONT-SIZE: 12pt">foo_help<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l14 level1 lfo13"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对新连接的包调用回调函数</span><span lang=EN-US style="FONT-SIZE: 12pt">foo_nat_expected<o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.4.12</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、可用的结构和函数</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在地址转换</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模块的</span><span lang=EN-US style="FONT-SIZE: 12pt">_init</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数中需要调用</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_nat_helper_register()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数来注册一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_nat_helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,这个结构有如下域:</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">list <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化为</span><span lang=EN-US style="FONT-SIZE: 12pt">{ NULL, NULL }<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">name <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的名称,可以使用协议名。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">flags <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标记值,有以下选项:</span><span lang=EN-US style="FONT-SIZE: 12pt"> IP_NAT_HELPER_F_ALWAYS</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对每一个包都调用</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的函数,而不仅仅是那些包含</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所感兴趣的地址和端口的包</span><span lang=EN-US style="FONT-SIZE: 12pt"> IP_NAT_HELPER_F_STANDALONE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这是一个独立的</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,没有与之对应的连接跟踪的</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">me <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">指向</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模块。可以用</span><span lang=EN-US style="FONT-SIZE: 12pt">THIS_MODULE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏初始化</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">tuple <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,描述</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所感兴趣包的信息</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">mask <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_conntrack_tuple</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,与上一个结构相与可以描述</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所感兴趣的属性。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">help <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对每一个和</span><span lang=EN-US style="FONT-SIZE: 12pt">tuple+mask</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">匹配的包调用这个函数</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">expect <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对新连接的第一个包调用这个函数以创建连接的地址转换结构</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">写一个地址转换</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与写一个连接跟踪</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">非常类似。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.4.13</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、地址转换</span><span lang=EN-US>helper</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的例子</span><code><span lang=EN-US style="FONT-SIZE: 12pt; LINE-HEIGHT: 173%"><o:p></o:p></span></code></font></h3>
<pre><span lang=EN-US><font face=宋体>#define FOO_PORT<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>111</font></span></pre>
<pre><span lang=EN-US><font face=宋体>static int foo_nat_expected(struct sk_buff **pksb,</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>unsigned int hooknum,</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct ip_conntrack *ct,</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct ip_nat_info *info)</font></span></pre>
<pre><span lang=EN-US><font face=宋体>/* called whenever the first packet of a related connection arrives.</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp; </span>params:<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pksb<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>packet buffer</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hooknum HOOK the call comes from (POST_ROUTING, PRE_ROUTING)</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ct<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>information about this (the related) connection</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>info<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>&amp;ct-&gt;nat.info</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp; </span>return value: Verdict (NF_ACCEPT, ...)</font></span></pre>
<pre><span lang=EN-US><font face=宋体>{</font></span></pre>
<pre><font face=宋体><span lang=EN-US><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>/* </span>对新连接调用<span lang=EN-US>ip_nat_setup_info</span>创建地址转换结构,返回<span lang=EN-US>NF_ACCEPT */</span></font></pre>
<pre><span lang=EN-US><font face=宋体>}<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></font></span></pre>
<pre><span lang=EN-US><font face=宋体>static int foo_help(struct ip_conntrack *ct,<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span></font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>struct ip_conntrack_expect *exp,</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct ip_nat_info *info,</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>enum ip_conntrack_info ctinfo,</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>unsigned int hooknum,</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct sk_buff<span style="mso-spacerun: yes">&nbsp; </span>**pksb)</font></span></pre>
<pre><span lang=EN-US><font face=宋体>/* called for every packet where conntrack detected an expectation-cause</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp; </span>params:<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ct<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>struct ip_conntrack of the master connection</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>exp<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </span>struct ip_conntrack_expect of the expectation</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>caused by the conntrack helper for this protocol</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>info<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>(STATE: related, new, established, ... )</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hooknum HOOK the call comes from (POST_ROUTING, PRE_ROUTING)</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>pksb<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>packet buffer</font></span></pre>
<pre><span lang=EN-US><font face=宋体>*/</font></span></pre>
<pre><span lang=EN-US><font face=宋体>{</font></span></pre>
<pre><font face=宋体><span lang=EN-US><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>/* </span>协议分析并替换地址端口,并重新计算<span lang=EN-US>checksum</span>和序列号<span lang=EN-US> */</span></font></pre>
<pre><span lang=EN-US><font face=宋体>}</font></span></pre>
<pre><span lang=EN-US><font face=宋体>static struct ip_nat_helper hlpr;</font></span></pre>
<pre><span lang=EN-US><o:p><font face=宋体>&nbsp;</font></o:p></span></pre>
<pre><span lang=EN-US><font face=宋体>static int __init(void)</font></span></pre>
<pre><span lang=EN-US><font face=宋体>{</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;</span>int ret;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>memset(&amp;hlpr, 0, sizeof(struct ip_nat_helper));</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hlpr.list = { NULL, NULL };</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hlpr.tuple.dst.protonum = IPPROTO_TCP;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hlpr.tuple.dst.u.tcp.port = htons(FOO_PORT);</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hlpr.mask.dst.protonum = 0xFFFF;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hlpr.mask.dst.u.tcp.port = 0xFFFF;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hlpr.help = foo_help;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>hlpr.expect = foo_nat_expect;</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ret = ip_nat_helper_register(hlpr);</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>return ret;</font></span></pre>
<pre><span lang=EN-US><font face=宋体>}</font></span></pre>
<pre><span lang=EN-US><font face=宋体>static void __exit(void)</font></span></pre>
<pre><span lang=EN-US><font face=宋体>{</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>ip_nat_helper_unregister(&amp;hlpr);</font></span></pre>
<pre><span lang=EN-US><font face=宋体>}<code><o:p></o:p></code></font></span></pre>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>4.5</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、理解</span><span lang=EN-US><font face=Arial>netfilter</font></span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">很简单,前面的章节已经很详细的描述了它的结构。但是,有时需要超越地址转换和</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_tables </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">框所提供的便利,或者你想完全替换它们。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将来在</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中一个重要的问题是缓存。每个</span><span lang=EN-US style="FONT-SIZE: 12pt">skb</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都有一个</span><span lang=EN-US style="FONT-SIZE: 12pt">nfcache</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">域:这是一个位掩码,表示包头的哪些部分被检查了,还有包是否被修改了。每个检查包的</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">钩子都用一个位来标识自己是否检查过这个包,这样就可以写一个缓存系统来缓存那些不会被</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">转发的包。</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最重要的标记是</span><span lang=EN-US style="FONT-SIZE: 12pt">NFC_ALTERED</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,表示这个包被修改了</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个标记在</span><span lang=EN-US style="FONT-SIZE: 12pt">IPv4</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_IP_LOCAL_OUT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">钩子中使用过,它会重新路由修改过的包</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,还有</span><span lang=EN-US style="FONT-SIZE: 12pt">NFC_UNKNOWN</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,它表示不应该缓存这个包,因为这个包有些无法预测的项。如果有疑问,可以在你的钩子函数中设置</span><span lang=EN-US style="FONT-SIZE: 12pt">NFC_UNKNOWN</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标记。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>4.6</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、写一个新</span><span lang=EN-US><font face=Arial>netfilter</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">模块</span></h2>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.6.1</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、挂接到</span><span lang=EN-US>Netfilter</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的钩子上</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为了在内核里接收或处理网络包,你可以写一个模块注册一个</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">钩子函数。实际钩子的位置与协议相关,并且在协议相关的</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">头文件中定义,例如</span><span lang=EN-US style="FONT-SIZE: 12pt">"netfilter_ipv4.h"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为了注册和卸载</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">钩子函数,你可以使用函数</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_register_hook</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_unregister_hook</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数。它们都由一个</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_hook_ops</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构的参数,这个结构的域如下所示:</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">list <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化为</span><span lang=EN-US style="FONT-SIZE: 12pt">{ NULL,NULL }<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">hook <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数在包到的这个钩子时调用。你的函数必须返回</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_ACCEPT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_DROP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或者</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_QUEUE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。如果返回值是</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_ACCEPT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,下一个在这个钩子点上的钩子函数会被调用。如果返回值是</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_DROP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,网络包被丢弃。如果返回值是</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_QUEUE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,这个包被放入队列。你有一个指向</span><span lang=EN-US style="FONT-SIZE: 12pt">skb</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的指针,因此你可以对</span><span lang=EN-US style="FONT-SIZE: 12pt">skb</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">做任何事。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">flush <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当前没有被使用。它被设计为当</span><span lang=EN-US style="FONT-SIZE: 12pt">cache</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">被清空后,如果包通过这个钩子函数时调用。目前被置为</span><span lang=EN-US style="FONT-SIZE: 12pt">NULL</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">pf <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议族值。对</span><span lang=EN-US style="FONT-SIZE: 12pt">IPv4</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议来说是</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_INET</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">hooknum <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">钩子点的位置。比如</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_IP_LOCAL_OUT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.6.2</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、如何处理放入队列的包</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个接口当前被</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_queue</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用,你可以注册一个函数来处理给定协议的队列包。这和注册一个钩子函数类似,但是你可以阻塞当前的处理流程。当然,你只能看到那些返回</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_QUEUE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的包。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有两个函数可以用来注册队列处理函数,一个是</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_register_queue_handler</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,一个是</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_unregister_ queue_handler()</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。你注册的函数有一个参数是</span><span lang=EN-US style="FONT-SIZE: 12pt">void*</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果没有注册任何函数来处理队列,</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_QUEUE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">返回值相当于</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_DROP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一旦你注册了相应的处理函数,你就可以处理队列中的网络包。你可以做任何事,但是你在完成处理后必须调用</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_reinject</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数。当你调用</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_reinject</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数时,你传递给它一个</span><span lang=EN-US style="FONT-SIZE: 12pt">skb</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,一个</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_info</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个结构由你的队列处理函数给出</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,和一个判断值:</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_DROP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示丢弃这些包,</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_ACCEPT</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示这些包会继续被</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">处理,</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_QUEUE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示重新将这些包放入队列,</span><span lang=EN-US style="FONT-SIZE: 12pt">NF_REPEART</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示对这些包重新调用缓存它们的钩子函数</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注意避免无限循环</span><span lang=EN-US style="FONT-SIZE: 12pt">)<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你可以检查</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_info</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构来得到关于网络包的信息,比如接口和钩子点等。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>4.6.3</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、用户空间命令</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用户空间需要和</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模块交互。我们使用的是</span><span lang=EN-US style="FONT-SIZE: 12pt">setsockopt</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">机制。注意,每个新协议都需要自己修改</span><span lang=EN-US style="FONT-SIZE: 12pt">setsockopt </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的代码来调用</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_setsockopt(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对</span><span lang=EN-US style="FONT-SIZE: 12pt">getsockopt</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">也是一样,需要修改</span><span lang=EN-US style="FONT-SIZE: 12pt">getsockopt</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的代码</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,不过目前</span><span lang=EN-US style="FONT-SIZE: 12pt">IPv4</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</span><span lang=EN-US style="FONT-SIZE: 12pt"> IPv6</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">DECnet</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的已经修改了。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一个常用的方法是用</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_register_sockopt</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注册一个</span><span lang=EN-US style="FONT-SIZE: 12pt">nf_sockopt_opt</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构,这个结构有以下域:</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">list <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化为</span><span lang=EN-US style="FONT-SIZE: 12pt">{ NULL,NULL }<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">pf <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">协议族的编号,比如</span><span lang=EN-US style="FONT-SIZE: 12pt">PF_INET</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">set_optmin <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">set_optmax <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">描述</span><span lang=EN-US style="FONT-SIZE: 12pt">setsockopt</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以设置值的范围,如果是</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,表示不设置任何值。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">set <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数会在</span><span lang=EN-US style="FONT-SIZE: 12pt">setsockopt</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中调用。你需要检查</span><span lang=EN-US style="FONT-SIZE: 12pt">NET_ADMIN</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">属性以确认用户是否有权利修改此参数</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">get_optmin <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">get_optmax <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">描述</span><span lang=EN-US style="FONT-SIZE: 12pt">getsockopt</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以取值的范围,如果是</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,表示不能取任何值。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">get <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数会在</span><span lang=EN-US style="FONT-SIZE: 12pt">getsockopts</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中调用。你需要检查</span><span lang=EN-US style="FONT-SIZE: 12pt">NET_ADMIN</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">属性以确认用户是否有权利取这个值。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span lang=EN-US style="FONT-SIZE: 12pt"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最后需要注意的两个问题</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><span lang=EN-US><font face=Arial>4.7</font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">、在用户空间处理包</span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你可以在</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_queue</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模块中使用</span><span lang=EN-US style="FONT-SIZE: 12pt">libipq</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">库,而且所有在内核中可以做的事你都可以在用户空间完成。这就意味着,除了速度的限制,你完全可以在用户空间开发你的代码。除非你需要过滤很大带宽的包,否则你会发现这种方法比在内核中处理包更方便。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在早期的</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中,我将一个试验性质的</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">移植到了用户空间。</span><span lang=EN-US style="FONT-SIZE: 12pt">Netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对人们是开放的,他们可以用他们喜欢的语言去编写</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模块。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h1 style="MARGIN: 17pt 0cm 16.5pt"><span lang=EN-US>5</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、将</span><span lang=EN-US>2.0</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span><span lang=EN-US>2.2</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的过滤模块移植到</span><span lang=EN-US>2.4</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上</span></h1>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">请参考</span><span lang=EN-US style="FONT-SIZE: 12pt">ip_fw_compat.c</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件,它封装了一个简单的层次,可以使得移植工作更简单。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h1 style="MARGIN: 17pt 0cm 16.5pt; TEXT-INDENT: 0cm; tab-stops: list 0cm; mso-list: l5 level1 lfo16"><span lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">6、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如何在</span><span lang=EN-US>netfilter</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">里撰写隧道相关的应用</span></h1>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US style="FONT-SIZE: 12pt">2.4</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">内核中编写隧道(或者封装)驱动,必须遵循以下两个规则(代码可以参考</span><span lang=EN-US style="FONT-SIZE: 12pt">net/ipv4/ipip.c</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">):</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l11 level2 lfo8"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果你要修改一个包(例如:封装或者去封装),你需要释放掉</span><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">skb-&gt;nfct</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">的引用计数。如果你是把修改后的包放入一个新的<span lang=EN-US>skb</span>,你不需要释放旧包的<span lang=EN-US>skb-&gt;nfct</span>;但是,如果不是创建一个新的包,你必须释放这个包的<span lang=EN-US>skb-&gt;nfct</span>。否则,地址转换代码就会使用旧的连接跟踪信息来修改包,这样将导致错误的结果。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -21pt; tab-stops: list 42.0pt; mso-list: l11 level2 lfo8"><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-family: Wingdings"><span style="mso-list: Ignore">l<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">需要保证封装的包流过<span lang=EN-US>LOCAL_OUT</span>钩子,同时解封装的包走过<span lang=EN-US>PRE_ROUTING</span>钩子<span lang=EN-US>(</span>大部分的隧道都使用<span lang=EN-US>ip_rcv</span>,在这个函数里已经做了这些<span lang=EN-US>)</span>。否则,用户就不能过滤那些流经隧道的包。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">最经典的办法是在你的封装或解封装包的代码前插入如下的代码:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">/* </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">这样会让<span lang=EN-US>netfilter</span>认为这个包与前一个不同<span lang=EN-US>! */<o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">#ifdef CONFIG_NETFILTER<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>nf_conntrack_put(skb-&gt;nfct);<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>skb-&gt;nfct = NULL;<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">#ifdef CONFIG_NETFILTER_DEBUG<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>skb-&gt;nf_debug = 0;<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">#endif<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">#endif<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 27.75pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">通常,你还需要做第二步,就是找到新封装的包会在哪里调用<span lang=EN-US>ip_send</span>,然后用下面的代码替换它:<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">/* </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">新的包从本机发出<span lang=EN-US> */<o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt-&gt;u.dst.dev, ip_send);<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 24pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt; mso-char-indent-count: 2.0" align=left><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">遵循这些规则意味着如果用户需要过滤一个流经隧道的包,他将会看到包是按如下的顺序流经协议栈的:<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: list 42.0pt left 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt; mso-list: l1 level1 lfo14" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><span style="mso-list: Ignore">1.<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FORWARD hook</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">:正常的包(从<span lang=EN-US>eth0-&gt;eth1</span>)<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: list 42.0pt left 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt; mso-list: l1 level1 lfo14" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><span style="mso-list: Ignore">2.<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">LOCAL_OUT hook</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">:封装的包(到<span lang=EN-US>eth1</span>)<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 21.75pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><span style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">对应答包来说:<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 21.75pt list 42.0pt left 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt; mso-list: l10 level1 lfo15" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><span style="mso-list: Ignore">1.<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">LOCAL_IN hook</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">:封装的应答包(来自<span lang=EN-US>eth1</span>)<span lang=EN-US><o:p></o:p></span></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt 42pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; tab-stops: 21.75pt list 42.0pt left 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt; mso-list: l10 level1 lfo15" align=left><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><span style="mso-list: Ignore">2.<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span lang=EN-US style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">FORWARD hoot</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体">:正常的应答包(从<span lang=EN-US>eth1-&gt;eth0</span>)<span lang=EN-US><o:p></o:p></span></span></p>
<h1 style="MARGIN: 17pt 0cm 16.5pt; TEXT-INDENT: 0cm; tab-stops: list 0cm; mso-list: l5 level1 lfo16"><span lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">7、<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">测试集</span></h1>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US style="FONT-SIZE: 12pt">CVS</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">仓库里有一个测试集:测试集覆盖的范围越广,你就越有信心去修改代码而不用担心修改会导致代码不能工作。基本的测试和复杂的测试同样重要:复杂的测试都是由基本测试组成</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就像你所知道的,在优化代码之前,先让它能跑起来</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">测试都很简单</span><span lang=EN-US style="FONT-SIZE: 12pt">:</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它们都是些</span><span lang=EN-US style="FONT-SIZE: 12pt">shell</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">脚本,位于</span><span lang=EN-US style="FONT-SIZE: 12pt">testsuite/</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">目录下。测试脚本按字母顺序运行,因此</span><span lang=EN-US style="FONT-SIZE: 12pt"> '01test'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US style="FONT-SIZE: 12pt">'02test'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">之前运行。目前有五个测试目录:</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">00netfilter/ <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">基本的</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">框架测试</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">01iptables/ <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">iptables</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">测试</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">02conntrack/ <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">连接跟踪测试</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">03NAT/ <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">地址转换测试</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">04ipchains-compat/ <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt">ipchians/ipfwadm</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的兼容性测试</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US style="FONT-SIZE: 12pt">testsuite/</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">目录下,有个</span><span lang=EN-US style="FONT-SIZE: 12pt">test.sh</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">脚本。它会配置两个虚拟接口</span><span lang=EN-US style="FONT-SIZE: 12pt">(tap0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">tap1)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,并且打开转发,删除所有的</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模块。然后,它会调用上面五个目录中的</span><span lang=EN-US style="FONT-SIZE: 12pt">test.sh</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">脚本,直到测试结束或者测试出错。这个测试脚本有两个参数:</span><span lang=EN-US style="FONT-SIZE: 12pt">"-v"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示打印测试过程中的信息;另一个是测试的名称,如果给定测试的名称,那么只有相关目录下的测试脚本会被调用。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><a name=ss7.1><span lang=EN-US><font face=Arial>7.1</font></span></a><span lang=EN-US><font face=Arial> </font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">编写一个测试</span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在相应的目录下创建一个新的测试脚本,测试脚本的名称需要正确命名,这样可以保证它会按正确的顺序被调用。例如,如果要测试</span><span lang=EN-US style="FONT-SIZE: 12pt">ICMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应答的连接跟踪</span><span lang=EN-US style="FONT-SIZE: 12pt">(02conntrack/02reply.sh)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,我们需要首先保证</span><span lang=EN-US style="FONT-SIZE: 12pt"> ICMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">请求的连接跟踪正确</span><span lang=EN-US style="FONT-SIZE: 12pt">(02conntrack/01simple.sh)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最好是创建一些小文件,每个测试一个项目,这样有利于在运行测试集时分离和定位错误。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果测试出错,请调用</span><span lang=EN-US style="FONT-SIZE: 12pt">"exit 1"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,它会返回一个错误值,如果你的测试出错,你应该打印出错误信息。如果你的测试完全正确,你需要在最后调用</span><span lang=EN-US style="FONT-SIZE: 12pt">"exit 0"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来返回。你需要检查每一条命令的返回值,你可以在脚本开头调用</span><span lang=EN-US style="FONT-SIZE: 12pt">'set -e'</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或者在每个命令后面附加</span><span lang=EN-US style="FONT-SIZE: 12pt">"|| exit 1"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">字串。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span lang=EN-US style="FONT-SIZE: 12pt">load_module</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">remove_module</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">两个函数可以帮你加载和卸载模块。你不应该依赖于系统去自动加载模块,除非你是在测试这个功能。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><a name=ss7.2><span lang=EN-US><font face=Arial>7.2</font></span></a><span lang=EN-US><font face=Arial> </font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">运行环境和环境变量</span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你可以使用两个接口</span><span lang=EN-US style="FONT-SIZE: 12pt">:tap0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">tap1</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。它们的地址分别用变量</span><span lang=EN-US>$TAP0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US>$TAP1</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示。它们的掩码都是</span><span lang=EN-US style="FONT-SIZE: 12pt">255.255.255.0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,而它们所在的网络分别用</span><span lang=EN-US style="FONT-SIZE: 12pt">$TAP0NET</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">STAP1NET</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表示。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">测试中会创建一个临时文件</span><span lang=EN-US style="FONT-SIZE: 12pt">$TMPFILE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,它会在测试结束后删除</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你的测试脚本放在</span><span lang=EN-US style="FONT-SIZE: 12pt">testsuite/</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">目录下,你需要在这个目录下运行它们。因此,如果你要访问其他命令</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">比如</span><span lang=EN-US style="FONT-SIZE: 12pt">iptables)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,你需要在命令前加</span><span lang=EN-US style="FONT-SIZE: 12pt">"../userspace"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">路径。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果设置了</span><span lang=EN-US style="FONT-SIZE: 12pt">$VERBOSE</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">值,你的脚本可以打印更多信息</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这意味着用户在命令行上使用了</span><span lang=EN-US style="FONT-SIZE: 12pt">-v</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">参数</span><span lang=EN-US style="FONT-SIZE: 12pt">)<o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><a name=ss7.3><span lang=EN-US><font face=Arial>7.3</font></span></a><span lang=EN-US><font face=Arial> </font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">有用工具</span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span><span lang=EN-US style="FONT-SIZE: 12pt">tools</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">目录下有一些有用的工具,在发生错误的情况下,它们返回非零值。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>7.3.1</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US>gen_ip</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你可以使用</span><span lang=EN-US style="FONT-SIZE: 12pt">gen_ip</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">生成</span><span lang=EN-US style="FONT-SIZE: 12pt">IP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据包,并在标准输出上打印出来。你可以通过将标准输出定向到</span><span lang=EN-US style="FONT-SIZE: 12pt"> /dev/tap0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span><span lang=EN-US style="FONT-SIZE: 12pt">/dev/tap1</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来模拟向这个两个设备发包</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这两个设备在测试集开始运行时创建</span><span lang=EN-US style="FONT-SIZE: 12pt">)<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span lang=EN-US style="FONT-SIZE: 12pt">gen_ip</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是一个简单的工具,但它的命令行参数却非常复杂,让我们先来看看它的命令行参数:</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">FRAG=offset,length <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">创建一个包,然后取它的</span><span lang=EN-US style="FONT-SIZE: 12pt">offset</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">处</span><span lang=EN-US style="FONT-SIZE: 12pt">,length</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">长度的分片。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">MF <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设置包的</span><span lang=EN-US style="FONT-SIZE: 12pt">"More Fragment"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标志</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">MAC=xx:xx:xx:xx:xx:xx <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设置包的源</span><span lang=EN-US style="FONT-SIZE: 12pt">MAC<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">TOS=tos <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设置包的</span><span lang=EN-US style="FONT-SIZE: 12pt">tos</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">域</span><span lang=EN-US style="FONT-SIZE: 12pt">(0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">到</span><span lang=EN-US style="FONT-SIZE: 12pt">255)<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下面是一些必选项</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">source ip <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包的源地址</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">dest ip <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包的目的地址</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">length <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包的总长度,包括包头的长度</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">protocol <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包的协议号,比如</span><span lang=EN-US style="FONT-SIZE: 12pt">17=UDP<o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span lang=EN-US style="FONT-SIZE: 12pt"><o:p>&nbsp;</o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">然后是一些与协议相关的选项:对</span><span lang=EN-US style="FONT-SIZE: 12pt">UDP(17)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来说,它们是源端口和目的端口。对</span><span lang=EN-US style="FONT-SIZE: 12pt">ICMP(1)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来说,它们是</span><span lang=EN-US style="FONT-SIZE: 12pt"> ICMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的类型和号码。如果类型是</span><span lang=EN-US style="FONT-SIZE: 12pt">0</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span><span lang=EN-US style="FONT-SIZE: 12pt">8(ping</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应答或请求</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,还有两个必须要填的项</span><span lang=EN-US style="FONT-SIZE: 12pt">(ID</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和序列号</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。对</span><span lang=EN-US style="FONT-SIZE: 12pt">TCP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来说,它们是源端口,目的端口,还有标记</span><span lang=EN-US style="FONT-SIZE: 12pt">("SYN", "SYN/ACK", "ACK", "RST" or "FIN")</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,这是必选项。还有三个可选项:</span><span lang=EN-US style="FONT-SIZE: 12pt">"OPT="</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">后面是逗号分隔的选项值,</span><span lang=EN-US style="FONT-SIZE: 12pt">"SYN="</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">后面是序列号,</span><span lang=EN-US style="FONT-SIZE: 12pt">"ACK="</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">后面是</span><span lang=EN-US style="FONT-SIZE: 12pt">ACK</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的序列号。最后,可选项</span><span lang=EN-US style="FONT-SIZE: 12pt">DATA</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">后面是</span><span lang=EN-US style="FONT-SIZE: 12pt">TCP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包的内容。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>7.3.2</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US>rcv_ip</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">你可以使用</span><span lang=EN-US style="FONT-SIZE: 12pt">rcv_ip</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来接收并打印网络包,它打印的格式与</span><span lang=EN-US style="FONT-SIZE: 12pt">gen_ip</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的输入格式相同</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">除分片包外</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这对分析网络包很有用处。它有两个必选的参数:</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">wait time <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在标准输入上等待一个包的最大时间</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><strong style="mso-bidi-font-weight: normal"><span lang=EN-US style="FONT-SIZE: 12pt">iterations <o:p></o:p></span></strong></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">连续接收包的数量</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它有一个可选参数</span><span lang=EN-US style="FONT-SIZE: 12pt">"DATA"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。如果有这个参数</span><span lang=EN-US style="FONT-SIZE: 12pt">rcv_ip</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">会将包的内容打印到标准输出上</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标准的在</span><span lang=EN-US style="FONT-SIZE: 12pt">shell</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">脚本中使用</span><span lang=EN-US style="FONT-SIZE: 12pt">rcv_ip</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的方式如下:</span><span lang=EN-US style="FONT-SIZE: 12pt"> <o:p></o:p></span></p>
<pre><span lang=EN-US><font face=宋体># Set up job control, so we can use &amp; in shell scripts.</font></span></pre>
<pre><span lang=EN-US><font face=宋体>set -m</font></span></pre>
<pre><span lang=EN-US><font face=宋体># Wait two seconds for one packet from tap0</font></span></pre>
<pre><span lang=EN-US><font face=宋体>../tools/rcv_ip 2 1 &lt; /dev/tap0 &gt; $TMPFILE &amp;</font></span></pre>
<pre><span lang=EN-US><font face=宋体># Make sure that rcv_ip has started running.</font></span></pre>
<pre><span lang=EN-US><font face=宋体>sleep 1</font></span></pre>
<pre><span lang=EN-US><font face=宋体># Send a ping packet</font></span></pre>
<pre><span lang=EN-US><font face=宋体>../tools/gen_ip $TAP1NET.2 $TAP0NET.2 100 1 8 0 55 57 &gt; /dev/tap1 || exit 1</font></span></pre>
<pre><span lang=EN-US><font face=宋体># Wait for rcv_ip,</font></span></pre>
<pre><span lang=EN-US><font face=宋体>if wait %../tools/rcv_ip; then :</font></span></pre>
<pre><span lang=EN-US><font face=宋体>else</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>echo rcv_ip failed:</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>cat $TMPFILE</font></span></pre>
<pre><span lang=EN-US><font face=宋体><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>exit 1</font></span></pre>
<pre><span lang=EN-US><font face=宋体>fi</font></span></pre>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>7.3.3</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US>gen_err</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个程序从标准输入上读入一个包</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以用</span><span lang=EN-US style="FONT-SIZE: 12pt">gen_ip</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">生成</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,并根据它生成一个</span><span lang=EN-US style="FONT-SIZE: 12pt">ICMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">错误应答</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">它有三个参数:源地址,类型和号码。</span><span lang=EN-US style="FONT-SIZE: 12pt">ICMP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包的目的地址将设置为从标准输入上读入包的源地址。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h3 style="MARGIN: 13pt 0cm"><font size=5><st1:chsdate w:st="on" Year="1899" Month="12" Day="30" IsLunarDate="False" IsROCDate="False"><span lang=EN-US>7.3.4</span></st1:chsdate><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span><span lang=EN-US>local_ip</span></font></h3>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这个函数从标准输入读入一个包并通过原始</span><span lang=EN-US style="FONT-SIZE: 12pt">socket</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">发送到内核中。这样,这个包看起来就像是从本地发出的包。</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与之对应的是,如果向</span><span lang=EN-US style="FONT-SIZE: 12pt">ethertap</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设备写入包,这个包看起来就像是从远端发出的包</span><span lang=EN-US style="FONT-SIZE: 12pt">)<o:p></o:p></span></p>
<h2 style="MARGIN: 13pt 0cm"><a name=ss7.4><span lang=EN-US><font face=Arial>7.4</font></span></a><span lang=EN-US><font face=Arial> </font></span><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">几点建议</span></h2>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所有的工具都假设它们都只需读写一次。这对</span><span lang=EN-US style="FONT-SIZE: 12pt">ethercap</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设备是正确的,但是如果你使用了管道,情况可能就不是这样了。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span lang=EN-US style="FONT-SIZE: 12pt">dd</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用来剪切包。</span><span lang=EN-US style="FONT-SIZE: 12pt">dd</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有一个</span><span lang=EN-US style="FONT-SIZE: 12pt">obs(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">块输出</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">选项,它可以在一次写动作里将整个包输出到标准输出上。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">先测试能够成功的情况。比如,如果需要测试包是否被禁止。首先要测试包是否能够正常通过,</span><span style="FONT-SIZE: 12pt"> </span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">然后测试包是否被禁止。否则,一些异常错误可能导致包不能通过。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">写一些精确的测试,而不是</span><span lang=EN-US style="FONT-SIZE: 12pt">&#8220;</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">随便试试,看有什么情况发生</span><span lang=EN-US style="FONT-SIZE: 12pt">"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的测试。如果一个精确的测试出现错误,错误原因可以定位。但如果是一个随意的测试,错误现象就不能重现,这样对定位错误没有任何帮助。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果一个命令出错,但是没有输出任何信息。你可以在脚本开头加入</span><span lang=EN-US style="FONT-SIZE: 12pt">"-x"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">选项</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">例如:</span><span lang=EN-US style="FONT-SIZE: 12pt">'#!/bin/sh -x')</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,这样就能看到是哪一条命令出错了。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果测试错误随机出现,就需要检查那些随机的网络流量</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">试着将所有的外部接口停掉</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。例如,我有一次和</span><span lang=EN-US style="FONT-SIZE: 12pt">Andrew Tridgell</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在同一网络,就被网络上的</span><span lang=EN-US style="FONT-SIZE: 12pt">Windows</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">广播包搞得很恼火。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h1 style="MARGIN: 17pt 0cm 16.5pt 36pt; TEXT-INDENT: -36pt; tab-stops: list 36.0pt; mso-list: l5 level1 lfo16"><span lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">8、<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">动机</span></h1>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在我开发</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的时候,我意识到包过滤的位置可能有问题。我给</span><span lang=EN-US style="FONT-SIZE: 12pt">Alan cox</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">发邮件告诉他这个问题,他的回答是</span><span lang=EN-US style="FONT-SIZE: 12pt">"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为什么不先完成目前的代码,或许它是正确的</span><span lang=EN-US style="FONT-SIZE: 12pt">"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这样,实用主义占了上风,</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">还是按原来的思路开发了出来。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在我完成</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">后,对</span><span lang=EN-US style="FONT-SIZE: 12pt">ipfwadm</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的改动就非常少了。主要的工作集中在撰写手册和帮助。在这个过程中,我发现在</span><span lang=EN-US style="FONT-SIZE: 12pt">LINUX</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">社区中,诸如包过滤、地址伪装、端口转发等概念非常混乱,这样导致使用这些功能变得非常困难。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在给这个工具做技术支持的过程中,我不断了解到用户在尝试做什么,他们的困难是什么。自由软件对用户有用处,他们才会使用它</span><span lang=EN-US style="FONT-SIZE: 12pt">(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不是吗</span><span lang=EN-US style="FONT-SIZE: 12pt">?)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这就意味着,你需要写简单的软件。</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的错误不是在文档上,而是在系统的架构上。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有了</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的经验,我了解到了用户需要什么样的包过滤工具。但是,这里有两个问题:</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">首先,我不想再重回安全领域。做为一个安全顾问,你就像是在你的良心和钱包之间拔河一样。基本上,你卖的是你对安全的感觉,但它与真正的安全有一定的差距。也许在一个军事基地工作,和那些真正懂安全的人一起工作,安全咨询才有用武之地。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">第二个问题是我不能只关注那些初级用户。越来越多的大公司和</span><span lang=EN-US style="FONT-SIZE: 12pt">ISP</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都在什么这个工具。我必须使这个工具足够可靠,而能够在更复杂的环境中使用。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">这些问题在我</span><span lang=EN-US style="FONT-SIZE: 12pt">1998</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">年</span><span lang=EN-US style="FONT-SIZE: 12pt">7</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">月在</span><span lang=EN-US style="FONT-SIZE: 12pt">Usenix</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上碰到</span><span lang=EN-US style="FONT-SIZE: 12pt">WatchGuard</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的名人</span><span lang=EN-US style="FONT-SIZE: 12pt">David Bonn</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时得到了解决。他们需要一个内核的编程人员。最终,他们同意我去他们西雅图的办公室一个月并谈谈如何定一个合同来资助我的新代码和我目前正在支持的代码。他们给的比我要求的多,报酬也没有打折。这就意味着,在一段时间里,我不需要考虑做咨询工作来糊口了。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span lang=EN-US style="FONT-SIZE: 12pt">WatchGuard</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">给了我接触他们的大客户的机会,并允许我平等的支持所有的用户,即使有些用户是他们的竞争对手。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接着,我开始写</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">并把</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">移植过去,目前这项工作已经完成了。不幸的是,内核中所有的地址伪装代码都被删除了:把地址伪装代码独立出来胜于把整个过滤代码删除掉。但是地址伪装还是需要在</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">框架上重新实现。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">同样,根据我在实现</span><span lang=EN-US style="FONT-SIZE: 12pt">ipfwadm</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span><span lang=EN-US style="FONT-SIZE: 12pt">"</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设备地址</span><span lang=EN-US style="FONT-SIZE: 12pt">"(</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">我把它从</span><span lang=EN-US style="FONT-SIZE: 12pt">ipchains</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中删掉了</span><span lang=EN-US style="FONT-SIZE: 12pt">)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时的经验,如果仅仅把地址伪装代码独立出来是不会有人帮我把它移植到</span><span lang=EN-US style="FONT-SIZE: 12pt">netfilter</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">框架上的,即使他们需要这个功能。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">因此,我需要在当前代码上实现尽可能多的功能,至少要比</span><span lang=EN-US style="FONT-SIZE: 12pt">2.2</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">提供的功能多,这样就可以鼓励新用户使用它。这意味这替换透明代理,地址伪装和端口转发,换句话说,就是实现一个完整的地址转换层。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">即使我要把目前的地址伪装层移植过来而不是写一个新的、通用的地址转换系统,地址伪装的代码也太旧了,并且缺少维护。目前已没有人支持这段代码了。这也显示出,正式的用户没有使用地址伪装,而家庭用户也很少使用它。虽然</span><span lang=EN-US style="FONT-SIZE: 12pt">Juan Ciarlante</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">做了一些修正,但是这段代码已经走到了尽头,现在需要重新写一个来替换它。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 18pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">请注意,我并不是最适合重写地址转换的那个人。我没有使用过地址伪装,而且当时也没有时间研究这段代码。这也许是它占用了我更长时间的原因。但重写的结果令人满意,从我的角度来书,我学到了很多。毫无疑问,一旦我们获取了更多用户如何使用这些工具的信息,我们就会写出来一个更好的版本来替换当前的版本。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
<h1 style="MARGIN: 17pt 0cm 16.5pt 36pt; TEXT-INDENT: -36pt; tab-stops: list 36.0pt; mso-list: l5 level1 lfo16"><span lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">9、<span style="FONT: 7pt 'Times New Roman'">&nbsp; </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">致谢</span></h1>
<p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">感谢那些帮助过我的人,特别是</span><span lang=EN-US style="FONT-SIZE: 12pt">Harald Welte</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,它撰写了协议</span><span lang=EN-US style="FONT-SIZE: 12pt">helper</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一节。</span><span lang=EN-US style="FONT-SIZE: 12pt"><o:p></o:p></span></p>
</div></span>                     
                        <div id="360docIsStranger"></div>
                        <div class="wenzhang_bt_list" id="UserPreNextArt"><div>上一篇:<a  title='Tracert和Traceroute详解Tracert命令(for windows)Tracert 命令用 IP 生存时间 (TTL) 字段和 ICMP 错误消息来确定从一个主机到网络上其它主机的路由。通过向目标发送不同 IP 生存时间 (TTL) 值的&quot;Internet 控制消息协议 (ICMP)&quot;回应数据包,Tracert 诊断程序确定到目标所采取的路由。使用tracert命令确定数据包在网络上的停止位置。traceroute指令让你追踪网络数据包的路由途径,预设数据包大小是40bytes,用户可另行设置。' href='http://www.360doc.com/content/09/1230/17/116188_12318633.shtml' target='_blank'>Tracert和Traceroute详解</a></div><div>下一篇:<a  title='使用Fail2ban保护Linux系统[参考文章]:Fail2ban    作者:    http://blog.candyz.org/20070820/1533使用 fail2ban 自动封IP   作者:佚名http://www.diybl.com/course/6_system/linux/Linuxjs/200896/139504.html使用Fail2ban保护Linux系统   作者:allbluehttp://allblue.mllm.org/node/186#comment-194    最近公司的服务器22端口(SSH服务端口)老被攻击,在网上搜索了一番,发现Fail2ban是一个不错的选择。' href='http://www.360doc.com/content/09/1203/10/116188_10257097.shtml' target='_blank'>使用Fail2ban保护Linux系统</a></div></div>
   <div class="wenzhang_cz2">
                                <span id="saverDiv"></span>    
    <span id="360docCopyArtUrl"></span> &nbsp;
    (<span class="link_green"><A href="http://www.360doc.com/UserHome/116188" target="_blank">vclyin</A></span> 的分类目录 <span class="link_underlinecg">[<A href="http://www.360doc.com/userHome.aspx?userid=116188&cid=2" target="_blank">Linux</A>])</span>
   </div>
<div class="ad02" id="ad02New">
<script type="text/javascript">
<!--
google_ad_client = "pub-6625678643128649";
google_alternate_color = "FFFFFF";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text_image";
google_ad_channel ="";
//-->
</script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<script type="text/javascript">

     var   url=   window.location.toString()
            var indexArticleFirst = url.lastIndexOf("_");
            var indexArticleLast ="";
           
            if (url.indexOf("shtml")>-1)
            {
                //shtml
                indexArticleLast = url.lastIndexOf(".shtml");
            }
            else
            {
                indexArticleLast = url.lastIndexOf(".html");
            }
            if (indexArticleLast >= 0) {
                ArticleID = url.substring(indexArticleFirst + 1, indexArticleLast);
            }
            else {
                ArticleID = url.substring(indexArticleFirst + 1);
            }  
     if (ArticleID<18263934)
{
   //?
}
else
{
   //?
   document.getElementById('ad02New').style.display='';
   document.getElementById('ad02New').innerHTML="";
}

</script>
</div>?  <div class="wenzhang_bt">相关文章</div><div class="wenzhang_bt_list"><ul><li><a  title='DLL命令 api_SetWindowsHookExA, 整数型, , "SetWindowsHookExA"    .参数 idHook, 整数型, , Hook类型,例如WH_KEYBOARD,WH_MOUSE    .参数 lpfn, 子程序指针, , 钩子回调函数,Hook处理过程函数的地址,    .参数 nMod, 整数型, , 包含Hook处理过程函数的dll句柄(若在本进程可以为NULL)    .参数 dwThreadID, 整数型, , 要Hook的线程ID,若为0,表示全局Hook所有。返回 (修改API首地址(取当前进程伪句柄 (), API, API_BAK))' href='http://www.360doc.com/content/09/0121/17/98883_2378292.shtml' target='_blank'>勾子基本概念</a><span class="time3 link_green">2009-01-21 ????<a href="http://www.360doc.com/UserHome/98883" target='_blank'>fort</a></span> </li><li><a  title='[收藏]C++ Tips(4)--参数的检查 /*这一系列文章《C++ Tips》是公司Code Committee专家会推荐工程师看的,感觉很好,拿出来与大家共同提高。--coofucoo*/对函数的输入参数进行适当的检查经常会有这样的程序:foo(char* str){写有参数的函数时,首要工作,就是要对传进来的所有参数进行合法性检查。而对于传出的参数也应该进行检查,这个动作当然应该在函数的外部,也就是说,调用完一个函数后,应该对其传出的值进行检查。' href='http://www.360doc.com/content/05/0929/14/1894_15844.shtml' target='_blank'>[收藏]C++ Tips(4)--参数的检查 - 心如止水--c...</a><span class="time3 link_green">2005-09-29 ????<a href="http://www.360doc.com/UserHome/1894" target='_blank'>shaolong007</a></span> </li><li><a  title='总结:现在我们有点明白Drupal的菜单机制了吧, 它主要由菜单api和菜单模块组成, 提供一种框架, 使得其他功能模块能过注册菜单路由项, 并在分发过程中, 通过该菜单路由表完成用户页面请求(具体URL)到功能模块业务逻辑的映射. 当然Drupal的菜单机制还有很多复杂特性, 来日方长, 有空继续钻研.' href='http://www.360doc.com/content/08/1017/11/75523_1778390.shtml' target='_blank'>从头学习Drupal--基本架构三 | Drupal China</a><span class="time3 link_green">2008-10-17 ????<a href="http://www.360doc.com/UserHome/75523" target='_blank'>gaofrank</a></span> </li><li><a  title='} /* Saves the union ipt_targinfo in parsable form to stdout. */static voidsave(const struct ipt_ip *ip, const struct ipt_entry_target *target){} staticstruct iptables_target id= { NULL,    "ID",    IPTABLES_VERSION,    IPT_ALIGN(sizeof(struct ipt_id_target_info)),    IPT_ALIGN(sizeof(struct ipt_id_target_info)),    &help,    &init,    &parse,    &final_check,    &print,    &save,    opts};' href='http://www.360doc.com/content/09/1110/11/36491_8725465.shtml' target='_blank'>自定义iptables/netfilter的目标模块 - sah...</a><span class="time3 link_green">2009-11-10 ????<a href="http://www.360doc.com/UserHome/36491" target='_blank'>jijo</a></span> </li><li><a  title='static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match){const struct ipt_ipaddr_info *info = (const struct ipt_ipaddr_info *)match->data;static void print(const struct ipt_ip *ip,const struct ipt_entry_match *match,int numeric){const struct ipt_ipaddr_info *info = (const struct ipt_ipaddr_info *)match->data;struct ipt_ipaddr_info {struct ipt_ipaddr ipaddr;' href='http://www.360doc.com/content/09/0827/17/36491_5320572.shtml' target='_blank'>lf367, KernelCorner: 自己写 Netfilt...</a><span class="time3 link_green">2009-08-27 ????<a href="http://www.360doc.com/UserHome/36491" target='_blank'>jijo</a></span> </li><li><a  title='' href='http://www.360doc.com/content/09/1024/20/59579_7789724.shtml' target='_blank'>__declspec(novtable) 的用法 - 程序员的故...</a><span class="time3 link_green">2009-10-24 ????<a href="http://www.360doc.com/UserHome/59579" target='_blank'>ShaneWu</a></span> </li><li><a  title='' href='http://www.360doc.com/content/06/0109/09/2908_55737.shtml' target='_blank'>WINDOWS数据类型—编程爱好者网站 http://www.p...</a><span class="time3 link_green">2006-01-09 ????<a href="http://www.360doc.com/UserHome/2908" target='_blank'>kenwang</a></span> </li><li><a  title='2005/10/2 12:58 | sun201201 # re: 金山词霸&quot;屏幕取词技术揭密(讨论稿) 我的系统是xp的,但为什么不能用金山词霸的屏幕取词功能--一打开金山词霸的屏幕取词功能,屏幕只要鼠标有移动就立即刷屏。2006/12/27 20:12 | vane # 回复: 金山词霸&quot;屏幕取词技术揭密(讨论稿) 哈哈,我同意楼上的,超级简单 2007/1/18 10:27 | Rachel # 回复: 金山词霸&quot;屏幕取词技术揭密(讨论稿) 我是使用金山的dll怎么只能获取28个字就不能使用了。' href='http://www.360doc.com/content/08/0618/21/7635_1348255.shtml' target='_blank'>金山词霸”屏幕取词技术揭密(讨论稿) - yaodong - 博...</a><span class="time3 link_green">2008-06-18 ????<a href="http://www.360doc.com/UserHome/7635" target='_blank'>凡尘一滴</a></span> </li></ul><div style="float:right; font-size:12px;" class="link_underline"><a href="http://www.360doc.com/relevant/2/5/8/6/14416852_more.shtml"  target="_blank">查看更多文章>></a></div></div>
                 
                <div><span id="Reflction"><div id="360docRefTN" class="wenzhang_bt" style="display:none;"></div><div id="360docRefCT"></div><div id="360docRefPB"></div></span></div> 
   <div class="wenzhang_bt">发表评论 <span id="isLogInSpan" class="wenzhang_pl_fb_tit link_red"></span></div>
   <div class="wenzhang_bt_1" id="loginNickname"></div>
   
                              <table width="100%"  cellpadding="0" cellspacing="0">
                                 <tr>
                                   <td align="left" valign="top">
                                      <textarea name="textarea" id="TextBox1"  rows="12"  style="width:95%;"></textarea> 
                                  </td>
                                  <td id="360docTdAdID" align="right" valign="top" >
                                     <div id="360docAdReflection" >
                                     
                                     </div>
                                  </td>
                                </tr>
                                <tr><td height="5px"></td><td></td></tr>
                                <tr>
                                  <td>
                                      <div id="360docRelfection" align="left">
                                         <input name="" type="checkbox" id="isCopy"  checked="checked" value="" />发送评论时内容自动复制到剪切板
                                        <input name="" type="button" id="Button1"  οnclick="SubmitReflection();" value="发送" class="botton" />
                                     </div>
                                 </td>
                                 <td>
                                 </td>           
                               </tr>
                            </table> 
  </td>
                <td width="10px">
                </td>
  <td valign="top" align="center">
                      <div class="WidthRight"><div class="wenzhang_bt">热点推荐</div><div class="wenzhang_bt_listCG"><ul><li><a href="http://www.360doc.com/content/07/1210/08/41005_883106.shtml" target="_blank" >克格勃大解密 </a></li><li><a href="http://www.360doc.com/content/08/1212/19/77937_2110070.shtml" target="_blank" >七年级语文知识归纳(人... </a></li><li><a href="http://www.360doc.com/content/06/1113/22/11958_258896.shtml" target="_blank" >【创业专栏】是什么决定... </a></li><li><a href="http://www.360doc.com/content/09/0424/16/138015_3253778.shtml" target="_blank" >畅销世界70年的成功励... </a></li><li><a href="http://www.360doc.com/content/08/1209/11/87426_2083417.shtml" target="_blank" >风力发电技术与功率半导... </a></li><li><a href="http://www.360doc.com/content/06/0226/00/142_72367.shtml" target="_blank" >写给1975-1989... </a></li><li><a href="http://www.360doc.com/content/09/0316/00/71349_2819127.shtml" target="_blank" >橱柜是厨房装修占据比例最大的 </a></li><li><a href="http://www.360doc.com/content/07/0615/11/16670_559433.shtml" target="_blank" >笑蜀:山西奴工事件本质... </a></li><li><a href="http://www.360doc.com/content/06/1201/15/9737_279516.shtml" target="_blank" >如何走出心理迷茫期 </a></li><li><a href="http://www.360doc.com/content/09/0112/17/77484_2318475.shtml" target="_blank" >挺中肯的几句话,慢慢悟吧! </a></li><li><a href="http://www.360doc.com/content/08/1228/21/60172_2218638.shtml" target="_blank" >年轻人心理成熟的10标准 </a></li><li><a href="http://www.360doc.com/content/08/0803/22/62878_1506715.shtml" target="_blank" >46个不得不知的生活小常识 </a></li><li><a href="http://www.360doc.com/content/09/0119/05/83855_2362108.shtml" target="_blank" >古代风俗百图[100P] </a></li><li><a href="http://www.360doc.com/content/06/1031/21/13001_246536.shtml" target="_blank" >中华人民共和国的57个... </a></li><li><a href="http://www.360doc.com/content/07/0501/00/19693_476194.shtml" target="_blank" >生命心境 </a></li><li><a href="http://www.360doc.com/content/09/0114/21/49636_2335149.shtml" target="_blank" >脑筋急转弯_网易新闻论坛 </a></li><li><a href="http://www.360doc.com/content/09/0121/11/97948_2376157.shtml" target="_blank" >逆向思维让孩子聪明翻倍 </a></li><li><a href="http://www.360doc.com/content/08/0803/14/37063_1505135.shtml" target="_blank" >震撼世界——禁宫的绝世... </a></li><li><a href="http://www.360doc.com/content/08/1228/21/94753_2218585.shtml" target="_blank" >我年轻时所不了解的事情 </a></li><li><a href="http://www.360doc.com/content/07/0404/16/2311_430180.shtml" target="_blank" >男人恋爱的七大死穴 </a></li></ul><br/></div></div><div id="AdArtRight" align="center"></div><div class="WidthRight"><div class="wenzhang_bt">主题阅读</div><div class="wenzhang_bt_listCG"><ul><li><a href="http://www.360doc.com/content/07/0328/14/22501_417799.shtml" target="_blank" >开眼界了,西瓜竟然可以... </a></li><li><a href="http://www.360doc.com/content/06/0315/14/5999_80187.shtml" target="_blank" >中外精品酒瓶欣赏 </a></li><li><a href="http://www.360doc.com/content/08/0810/17/47553_1528794.shtml" target="_blank" >如此婚纱照,您见过吗?... </a></li><li><a href="http://www.360doc.com/content/05/1228/11/142_50863.shtml" target="_blank" >蜡烛(图) </a></li><li><a href="http://www.360doc.com/content/06/0417/12/5368_99927.shtml" target="_blank" >水果蔬菜也疯狂--可爱不? </a></li><li><a href="http://www.360doc.com/content/09/0202/17/50324_2442653.shtml" target="_blank" >最全的书信折纸 </a></li><li><a href="http://www.360doc.com/content/06/0528/13/267_123829.shtml" target="_blank" >精美的肥皂雕刻(组图) </a></li><li><a href="http://www.360doc.com/content/08/0805/01/47553_1510943.shtml" target="_blank" >69件创意生活小物品[... </a></li><li><a href="http://www.360doc.com/content/07/1228/06/15797_929584.shtml" target="_blank" >世界各地的男女厕所标志 </a></li><li><a href="http://www.360doc.com/content/08/0815/23/47553_1545647.shtml" target="_blank" >蛋糕,也能做成这样滴 </a></li><li><a href="http://www.360doc.com/content/09/1125/00/1_9703427.shtml" target="_blank" >古怪气球赏,创意设计 </a></li><li><a href="http://www.360doc.com/content/09/1003/15/180455_6746803.shtml" target="_blank" >宅生活,创意过 </a></li></ul><br/></div></div><div id="360docAdBetween"></div><div ID="Getbook_list" class="WidthRight"></div>
         
   </td>
   </tr>
</tbody>
 </table>

</div>
<div style="display:none" id="ImgCache"></div>


<script language="javascript" type="text/javascript">


      


       var ArticleID=14416852;
        var userid=116188;
        var SearchByArt="href='http://www.google.cn/search?hl=zh-CN&amp;q=%e5%87%bd%e6%95%b0%2b%e9%92%a9%e5%ad%90%2b%e6%a8%a1%e5%9d%97&amp;lr=lang_zh-CN' target='_blank'";
        var xmlHttp=null;
        var xmlDom =null;
        var xslDom =null;

 

 var appName = navigator.appName.toLowerCase();
   if (appName.indexOf("microsoft internet explorer")>-1)
   {
       document.write("<scr"+"ipt type='text/javascript' src='http://www.360doc.com/js/StickySystemIE090401.js'></sc"+"ript>");      
   }
   else
   {
      document.write("<scr"+"ipt type='text/javascript' src='http://www.360doc.com/js/StickySystemOther090401.js'></sc"+"ript>");
   }

 </script>

 

 

 

<script>GerLookingUserInfo(0,1,1);</script>
<script type="text/javascript" src="http://www.360doc.com/js/albb3.js"></script>
?<div class="copyright">
<div class="index_main">
<table width="100%" border="0" cellspacing="2" cellpadding="2" >
  <tr>
    <td width="55%">(本文为 360doc 用户收藏,不代表 360doc 观点)<br />
      <a target="_blank" href="http://www.360doc.com/help.html">360doc简介</a> <a target="_blank" href="http://www.360doc.com/service.html">服务条款</a> <a href="javascript:void(0)" οnclick="setHomepage('http://www.360doc.com')">设360doc为首页</a> <a target="_blank" href="http://www.360doc.com/advice.html">留言交流</a> <a target="_blank" href="http://www.360doc.com/contactus.html">联系我们</a> 客服QQ:524562434<br />
      Copyright &copy; 2009 360doc.com</td>
    <td valign="top" width="45%"><div align="left">360doc个人图书馆------您的知识管理平台
      <br />
      <a href="http://www.360doc.com" target="_blank"><img src="http://www.360doc.com/images/copyright_bt.gif"  width="150" height="39" border="0"  /></a>
   </td>
  </tr>
</table>

</div>
</div>
</body>
</html>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值