﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-幽灵狼</title><link>http://www.cnitblog.com/SpiWolf/</link><description>狼团队中的每一位成员，共同承担团体生存的责任， 并为此付出自己的独特技能和力量。 我是狼， 相信自己， 相信伙伴。</description><language>zh-cn</language><lastBuildDate>Wed, 29 Apr 2026 06:00:07 GMT</lastBuildDate><pubDate>Wed, 29 Apr 2026 06:00:07 GMT</pubDate><ttl>60</ttl><item><title>Writing Programs with NCURSES</title><link>http://www.cnitblog.com/SpiWolf/archive/2006/02/25/6933.html</link><dc:creator>幽灵狼</dc:creator><author>幽灵狼</author><pubDate>Sat, 25 Feb 2006 02:51:00 GMT</pubDate><guid>http://www.cnitblog.com/SpiWolf/archive/2006/02/25/6933.html</guid><wfw:comment>http://www.cnitblog.com/SpiWolf/comments/6933.html</wfw:comment><comments>http://www.cnitblog.com/SpiWolf/archive/2006/02/25/6933.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cnitblog.com/SpiWolf/comments/commentRss/6933.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/SpiWolf/services/trackbacks/6933.html</trackback:ping><description><![CDATA[<A href="http://www.cs.mun.ca/~rod/ncurses/ncurses.html">http://www.cs.mun.ca/~rod/ncurses/ncurses.html</A><img src ="http://www.cnitblog.com/SpiWolf/aggbug/6933.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/SpiWolf/" target="_blank">幽灵狼</a> 2006-02-25 10:51 <a href="http://www.cnitblog.com/SpiWolf/archive/2006/02/25/6933.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>google的妙用一则</title><link>http://www.cnitblog.com/SpiWolf/archive/2006/02/18/6687.html</link><dc:creator>幽灵狼</dc:creator><author>幽灵狼</author><pubDate>Sat, 18 Feb 2006 01:30:00 GMT</pubDate><guid>http://www.cnitblog.com/SpiWolf/archive/2006/02/18/6687.html</guid><wfw:comment>http://www.cnitblog.com/SpiWolf/comments/6687.html</wfw:comment><comments>http://www.cnitblog.com/SpiWolf/archive/2006/02/18/6687.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/SpiWolf/comments/commentRss/6687.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/SpiWolf/services/trackbacks/6687.html</trackback:ping><description><![CDATA[<P>在搜索框上输入： “index of/ ” 　inurl:lib </P>
<P>再按搜索你将进入许多图书馆，并且一定能下载自己喜欢的书籍。 </P>
<P><BR>在搜索框上输入： “index of /” 　cnki </P>
<P>再按搜索你就可以找到许多图书馆的CNKI、VIP、超星等入口！ <BR>&nbsp;</P>
<P>在搜索框上输入：　“index of /” 　ppt </P>
<P>再按搜索你就可以突破网站入口下载powerpint作品！ </P>
<P><BR>在搜索框上输入： “index of /” 　mp3 </P>
<P>再按搜索你就可以突破网站入口下载mp3、rm等影视作品！ </P>
<P><BR>在搜索框上输入：　“index of /” 　swf </P>
<P>再按搜索你就可以突破网站入口下载flash作品！ </P>
<P><BR>在搜索框上输入： “index of /” 　要下载的软件名 </P>
<P>再按搜索你就可以突破网站入口下载软件！ </P>
<P><BR>注意引号应是英文的！ </P>
<P><BR>再透露一下，如果你输入： </P>
<P><BR>“index of /” 　AVI </P>
<P>你会找到什么呢？同理，把AVI换为MPEG看看又会找到什么呢？呵呵！接下来不用我再教了吧？</P><img src ="http://www.cnitblog.com/SpiWolf/aggbug/6687.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/SpiWolf/" target="_blank">幽灵狼</a> 2006-02-18 09:30 <a href="http://www.cnitblog.com/SpiWolf/archive/2006/02/18/6687.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>The best anti-trojan programs</title><link>http://www.cnitblog.com/SpiWolf/archive/2005/12/22/5706.html</link><dc:creator>幽灵狼</dc:creator><author>幽灵狼</author><pubDate>Thu, 22 Dec 2005 12:19:00 GMT</pubDate><guid>http://www.cnitblog.com/SpiWolf/archive/2005/12/22/5706.html</guid><wfw:comment>http://www.cnitblog.com/SpiWolf/comments/5706.html</wfw:comment><comments>http://www.cnitblog.com/SpiWolf/archive/2005/12/22/5706.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/SpiWolf/comments/commentRss/5706.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/SpiWolf/services/trackbacks/5706.html</trackback:ping><description><![CDATA[<p align="center"> 
                        <b><font color="#000080" face="Arial" size="4">
                        Anti-trojan Software Reviews</font></b></p>

                  
                
              
            
            
<p align="center"><b><font color="#000080" face="Arial" size="1"> 
              &nbsp; &nbsp; 
              <a href="http://www.anti-trojan-software-reviews.com/test-procedure.htm">Anti-trojans - how we reviewed</a>&nbsp;&nbsp; <a href="http://www.anti-trojan-software-reviews.com/what-is-a-trojan.htm">What is a Trojan Horse?</a>&nbsp;<font color="#000080">&nbsp; &nbsp;</font><a href="http://www.anti-trojan-software-reviews.com/about_site.htm">About 
              us</a>&nbsp;&nbsp;&nbsp; </font> <font face="Arial" size="1"> <a href="mailto:reviews@anti-trojan-software-reviews.com?subject=Suggested%20site%20for%20review">
            Anti-trojan suggestions</a></font></b></p>

        
         
           
<p align="center"><span style="background-color: rgb(255, 255, 0);"><b> 
              <font color="#000080" face="Arial">A survey of the</font></b></span><b><span style="background-color: rgb(255, 255, 0);"><font color="#000080" face="Arial" size="3"> 
              best anti-trojan programs</font></span></b><br>
              <font color="#000080" face="Arial"> <b> <span style="background-color: rgb(255, 255, 0);">from 
              <a href="http://www.techsupportalert.com/">Tech Support Alert</a></span></b></font></p>

          <!-- / message -->
            
<p><font face="Arial" size="2">Most folk harbor the belief that they 
              are totally protected from malicious <a href="http://www.anti-trojan-software-reviews.com/what-is-a-trojan.htm">trojan 
              horses</a> by their anti-virus scanner.</font></p>

            
<p><font face="Arial" size="2">The bad news is that many anti-virus 
              scanners give only limited protection against trojans.&nbsp;Just 
            how limited can be gauged from the fact that Norton Anti-Virus 2004&nbsp; 
            missed every single trojan in the test data set we used in these 
            series of reviews.&nbsp; Other anti-virus programs didn't do much 
            better.</font></p>

            
<p><font face="Arial" size="2">For 
              the best protection against trojans you really need a specialist 
              anti-trojan program <b>in addition to</b> your anti-virus software. 
            Simple as that.</font></p>

            
<p><font face="Arial" size="2">At&nbsp;Tech Support Alert we <a href="http://www.anti-trojan-software-reviews.com/anti-trojans.htm">
            identified 44 </a> currently available anti-trojan / trojan remover programs. After a lot of 
              culling and testing we ended up with only eight products we felt 
            were worth reviewing in detail. On completing detailed reviews 
            of these, we felt we could only recommend five products. To see how we reviewed, click <a href="http://www.anti-trojan-software-reviews.com/test-procedure.htm"> 
              here.</a>&nbsp;  </font></p>

            
<p><font face="Arial" size="2">All the recommended products listed below, 
            offer good protection against trojans and have powerful trojan removal capabilities. 
              All would make valuable adjuncts to your anti-virus program and 
              firewall in providing your PC with maximum protection against a 
              hostile attack. </font></p>

            
<p><font face="Arial" size="2">We've made recommendations on the products 
              that impressed us most, but we suggest you read the reviews and 
              make your own decision.&nbsp; Without doubt, the best product is 
              the one that best suits YOUR needs.</font></p>

            
<p align="left"><b><font color="#800000" face="Arial" size="3"> 
            <a href="http://www.anti-trojan-software-reviews.com/images/trophy_gold.gif"> 
            <img src="http://www.anti-trojan-software-reviews.com/images/trophy_gold.gif" alt="trojan remover gold award" border="0" height="53" width="45"></a></font><font color="#000080" face="Arial" size="3">Outstanding 
              Anti-trojan Programs</font></b><font color="#000080"> </font> 
            </p>
<p align="left">&nbsp;</p>
<p align="left"><font face="Arial" size="2"><b>
            
            <a onmouseover="window.status='http://www.misec.net';return true;" onmouseout="window.status=' ';return true;" target="_top" href="http://www.anti-trojan-software-reviews.com/review-trojan-hunter.htm">
           <font color="#000080">Trojan 
              Hunter</font></a><font color="#000080"> </font></b><font color="#800000"><b>Editors Choice: Best for most 
              users</b></font></font><font color="#800000">&nbsp; <br></font>
            <font face="Arial" size="2">Trojan Hunter's sophisticated multifaceted 
            detection capabilities allow it to detect insidious modern trojans 
            with an ease that is only bettered by TDS-3. Unlike TDS-3, it has a 
            friendly user interface which means that it can be used even by 
            inexperienced users. As a trojan remover its performance was 
            outstanding. Add to that the fact that it's fast, technically 
            sophisticated and is very well supported and you have a winning 
            combination.<font color="#800000">&nbsp;
            <a href="http://www.anti-trojan-software-reviews.com/review-trojan-hunter.htm">Click 
              here</a></font> for full review </font>
            </p>
<p align="left"><b><font color="#000080" face="Arial" size="2">
            <a href="http://www.anti-trojan-software-reviews.com/review-ewido.htm">Ewido</a> </font></b><br>
          <font face="Arial" size="2">Ewido is a new product that managed to 
          impress us immensely with its a technically sophisticated design yet 
          is relative ease to use. It detects trojans almost as well as 
            Trojan Hunter, has a fast scanner and has an excellent trojan remover 
            as well.&nbsp; As an added bonus it has proved to be an excellent 
            performer in removing some difficult-to-remove spyware products. The only thing that stopped us 
            awarding this product the Editor's choice rating was the lack of an in-product help system and 
            meager web based support resources. <font color="#800000">
            <a href="http://www.anti-trojan-software-reviews.com/review-ewido.htm">Click 
            here</a></font> for full review </font>
            </p>
<p align="left"><font face="Arial" size="2"><b>
            <a onmouseover="window.status='http://www.diamondcs.com.au';return true;" onmouseout="window.status=' ';return true;" target="_top" href="http://www.anti-trojan-software-reviews.com/review-tds-3.htm"><font color="#000080">TDS-3</font></a> </b><font color="#000080">&nbsp; 
              </font> </font><b><font color="#800000" face="Arial" size="2">
            Note: This product was discontinued by the developer on 22nd July, 
            2005</font></b><br>
              <font face="Arial" size="2"> If you want the highest level of protection 
              against trojans that is currently available, then you need TDS-3. 
              However be prepared to pay for its extraordinary level of security 
              in terms of product complexity and resource usage.&nbsp; TDS-3 is 
              a reassuring product for</font> <font face="Arial" size="2"> experienced 
              users but a daunting one for many others. <a href="http://www.anti-trojan-software-reviews.com/review-tds-3.htm">Click 
              here</a> for full review.</font>
            </p>
<p align="left"><b><font color="#800000" face="Arial" size="3"> 
            <img src="http://www.anti-trojan-software-reviews.com/images/trophy_silver.gif" alt="anti-trojan silver award" border="0" height="53" width="45"></font><font color="#000080" face="Arial" size="3"> 
            Highly 
            Recommended </font></b> 
            </p>
<p align="left">
          <b><font color="#000080" face="Arial" size="2">
          <a href="http://www.anti-trojan-software-reviews.com/review-a2.htm">A Squared</a> </font></b><font face="Arial" size="2">
          <font color="#0000ff"><b>(a<sup>2)</sup> </b></font> <br>
          We liked a<sup>2</sup> a lot but unfortunately some of its most 
          attractive features are yet to be fully implemented. When these are 
          delivered in the upcoming version 2 we anticipate a<sup>2</sup> will leap 
          directly into our "outstanding" category. As of the moment though, it 
          is a work in progress. <font color="#800000"><a href="http://www.anti-trojan-software-reviews.com/review-a2.htm">Click 
              here</a></font> for full review </font></p>
<p align="left"> <font face="Arial" size="2"><b>
                <a onmouseover="window.status='http://www.moosoft.com/';return true;" onmouseout="window.status=' ';return true;" target="_top" href="http://www.anti-trojan-software-reviews.com/review-the-cleaner.htm">
              <font color="#000080">The Cleaner</font></a>&nbsp;</b></font><br>
              <font face="Arial" size="2">This is a well established and easy to 
          use product. The folks behind The Cleaner have, in the last 12 months, 
          put a lot of work in expanding the product's signature database and 
          this shows in markedly improved detection rate. However its slow scan 
          speed will&nbsp; be a problem for some users. <a href="http://www.anti-trojan-software-reviews.com/review-the-cleaner.htm">
          Click here</a> 
              for full review.</font>
            </p>
<p align="left"> <b><font color="#000080" face="Arial" size="3"> Other Programs Reviewed</font></b>
            </p>
<p align="left"> <font face="Arial" size="2"><b>
            <a onmouseover="window.status='http://www.nsclean.com';return true;" onmouseout="window.status=' ';return true;" target="_top" href="http://www.anti-trojan-software-reviews.com/review-boclean.htm"><font color="#000080">
            BOClean</font></a><font color="#000080">&nbsp; 
              </font> </b></font><br>
              <font face="Arial" size="2">A few years back BOClean was arguably the best 
          anti-trojan monitor on the market and attracted a loyal following even 
          though it lacked an on-demand scanner. Now other anti-trojan vendors 
          offer monitors that perform just as as well as BOClean and include an 
          on-demand scanner as well for the same selling price. However for those prepared to trade 
            convenience for ultimate protection, BoClean is still a viable 
            option. <a href="http://www.anti-trojan-software-reviews.com/review-boclean.htm">Click here</a> for full&nbsp; 
          review.</font></p>
<p align="left"> <font face="Arial" size="2"><b> 
            <a onmouseover="window.status='http://www.agnitum.com';return true;" onmouseout="window.status=' ';return true;" target="_top" href="http://www.anti-trojan-software-reviews.com/review-tauscan.htm">
              <font color="#000080">Tauscan</font></a></b></font><br>
              <font face="Arial" size="2">Tauscan is a is an easy to use program 
          with a very fast scanner. It&nbsp; offers reasonable detection 
          capabilities though well below the top products. We can't help feeling 
          that Tauscan is looking a little dated compared to new products like 
          Ewido. <a href="http://www.anti-trojan-software-reviews.com/review-tauscan.htm"> 
              Click here</a> for full review.</font>&nbsp;
            </p>
<p align="left"> <font face="Arial" size="2"><b> 
            <a onmouseover="window.status='http://www.safersite.com/';return true;" onmouseout="window.status=' ';return true;" target="_top" href="http://www.anti-trojan-software-reviews.com/review-pest-patrol.htm"> 
              <font color="#000080">Pest Patrol</font></a>&nbsp; </b></font><br>
              <font face="Arial" size="2">This program does a lot more than 
            detect&nbsp;and remove trojans; it will also detects spyware, adware and 
            a variety of other undesirable pests. However when it comes to the 
            specific task of detecting trojans, PestPatrol is largely outclassed 
            by the dedicated anti-trojan products covered in this review.&nbsp; <a href="http://www.anti-trojan-software-reviews.com/review-pest-patrol.htm">Click here</a> 
              for full review.</font>
            </p>
<img src ="http://www.cnitblog.com/SpiWolf/aggbug/5706.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/SpiWolf/" target="_blank">幽灵狼</a> 2005-12-22 20:19 <a href="http://www.cnitblog.com/SpiWolf/archive/2005/12/22/5706.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>The 46 Best-ever Freeware Utilities</title><link>http://www.cnitblog.com/SpiWolf/archive/2005/12/22/5705.html</link><dc:creator>幽灵狼</dc:creator><author>幽灵狼</author><pubDate>Thu, 22 Dec 2005 12:15:00 GMT</pubDate><guid>http://www.cnitblog.com/SpiWolf/archive/2005/12/22/5705.html</guid><wfw:comment>http://www.cnitblog.com/SpiWolf/comments/5705.html</wfw:comment><comments>http://www.cnitblog.com/SpiWolf/archive/2005/12/22/5705.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/SpiWolf/comments/commentRss/5705.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/SpiWolf/services/trackbacks/5705.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: The             46 Best-ever Freeware Utilities            There are a lot of great             freeware products out there. Many are as good or even better than             their commerci...&nbsp;&nbsp;<a href='http://www.cnitblog.com/SpiWolf/archive/2005/12/22/5705.html'>阅读全文</a><img src ="http://www.cnitblog.com/SpiWolf/aggbug/5705.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/SpiWolf/" target="_blank">幽灵狼</a> 2005-12-22 20:15 <a href="http://www.cnitblog.com/SpiWolf/archive/2005/12/22/5705.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux Netlink Sockets</title><link>http://www.cnitblog.com/SpiWolf/archive/2005/12/17/5516.html</link><dc:creator>幽灵狼</dc:creator><author>幽灵狼</author><pubDate>Sat, 17 Dec 2005 09:46:00 GMT</pubDate><guid>http://www.cnitblog.com/SpiWolf/archive/2005/12/17/5516.html</guid><wfw:comment>http://www.cnitblog.com/SpiWolf/comments/5516.html</wfw:comment><comments>http://www.cnitblog.com/SpiWolf/archive/2005/12/17/5516.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/SpiWolf/comments/commentRss/5516.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/SpiWolf/services/trackbacks/5516.html</trackback:ping><description><![CDATA[<p>Netlink Sockets are the method that the Linux Kernel uses to pass
Routing, Interface and other miscellaneous networking information
around, both within the kernel and between the kernel and userspace. It
replaces the old <a href="http://www.wlug.org.nz/ioctl%282%29" class="wiki">ioctl(2)</a>
based method and is far far superior - infact as soon as the kernel
receives a networking ioctl it is converted to a netlink message before
being shipped off for further processing.</p>

<h3 id="hdr_basic_introduction">Basic Introduction</h3>

<p>The netlink protocol uses a special type of <a href="http://www.wlug.org.nz/socket%282%29" class="wiki">socket(2)</a>
to communicate with the Linux kernel. This socket is called a "Netlink
Socket" surprisingly enough and can be created by specifing AF_NETLINK
as the first argument to a <a href="http://www.wlug.org.nz/socket%282%29" class="wiki">socket(2)</a>
call, The socket type (second argument) can be either SOCK_DGRAM or
SOCK_RAW, it makes absolutely no difference!, the third argument
(netlink family) specifies which part of the linux networking stack you
want to modify, for example NETLINK_ROUTE can be specified to modify
the routing table (including interfaces), or NETLINK_ARPD can be
specified to allow the arp table to be manipulated. A full list of
available netlink families is found in <a href="http://www.wlug.org.nz/netlink%287%29" class="wiki">netlink(7)</a>.</p>

<p>NETLINK_ROUTE is the most commonly used netlink family as it is used
to add, delete and modify routes from the kernels routing table and can
also be used to add, delete and modify the interfaces on the machine.</p>

<p>Some of the basic Netlink principles are documented in <a href="http://rfc.net/rfc3549.html" class="interwiki"><img src="http://www.wlug.org.nz/phpwiki/themes/default/images/interwiki.png" alt="[link]" class="linkicon" border="0">RFC:<span class="wikipage">3549</span></a>.</p>

<h3 id="hdr_programming_netlink">Programming Netlink</h3>

<p>There is somewhat of a lack of easy to read documentation regarding
how to program using netlink sockets, however the information is all
there in the end. As a start try the <a href="http://www.wlug.org.nz/netlink%283%29" class="wiki">netlink(3)</a>, <a href="http://www.wlug.org.nz/netlink%287%29" class="wiki">netlink(7)</a>, <a href="http://www.wlug.org.nz/rtnetlink%283%29" class="wiki">rtnetlink(3)</a> and <a href="http://www.wlug.org.nz/rtnetlink%287%29" class="wiki">rtnetlink(7)</a>
manpages which provide a very technical description of the netlink
protocol, all the information that you need to write a program using
netlink is contained in these manpages.... should be easy from here
right?</p>

<p>The iproute2 package is the base implementation of the netlink
interface, it replaces all the old linux networking utilities
(ifconfig, route, etc) into a single binary called ip which performs
all of the tasks using the netlink interface. I highly recommend that
you use this package as a reference when coding netlink related
applications. In particular iproute2 contains a netlink library
(libnetlink) which deals with much of the low level protocol
interactions between your application and the kernel. Unfortunately the
library is not seperately packaged and you'll have to spend some time
extracting it from the iproute2 package before it is useful.</p>

<p>Coming Soon - Some basic examples of how to program using libnetlink -- Talk to <a href="http://www.wlug.org.nz/MattBrown" class="wiki">MattBrown</a> if you want them and they're not here yet!</p>

<p>(ha! It's been ages and you've not put up any examples!  So I've written one that shows route add/del events, see <a href="http://www.wlug.org.nz/LinuxNetlinkSocketExample" class="wiki">LinuxNetlinkSocketExample</a> --<a href="http://www.wlug.org.nz/PerryLorier" class="wiki">PerryLorier</a>).</p>

<h3 id="hdr_applications_known_to_use_netlink_sockets">Applications Known to Use Netlink Sockets</h3>

<ul>
<li><a href="http://www.wlug.org.nz/Quagga" class="wiki">Quagga</a></li><li>/sbin/ip (<a href="http://www.wlug.org.nz/IpRoute" class="wiki">IpRoute</a>2 package)</li>
</ul>

<h3 id="hdr_random_notes_things_i_wish_were_documented_somewhere_but_aren_t_">Random notes (things I wish were documented somewhere but aren't)</h3>

<ul>
<li>if you want to recieve RTM_NEWNEIGH messages, you need <tt>/proc/sys/net/ipv{4,6}/neigh/*/app_probes</tt> to be non 0.</li>
</ul>

<p>I don't know why.  They might have been drunk at the time -- <a href="http://www.wlug.org.nz/PerryLorier" class="wiki">PerryLorier</a><br>
The reason why is that much of the system parameters are moving this
way and they were just too lazy to convert other ones too I suspect -- <a href="http://www.wlug.org.nz/IanMcDonald" class="wiki">IanMcDonald</a><br>
</p>
<p>URL for this article: <a href="http://www.wlug.org.nz/LinuxNetlinkSockets">http://www.wlug.org.nz/LinuxNetlinkSockets</a><br>
</p>
<img src ="http://www.cnitblog.com/SpiWolf/aggbug/5516.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/SpiWolf/" target="_blank">幽灵狼</a> 2005-12-17 17:46 <a href="http://www.cnitblog.com/SpiWolf/archive/2005/12/17/5516.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux Netlink Socket Example</title><link>http://www.cnitblog.com/SpiWolf/archive/2005/12/17/5515.html</link><dc:creator>幽灵狼</dc:creator><author>幽灵狼</author><pubDate>Sat, 17 Dec 2005 09:37:00 GMT</pubDate><guid>http://www.cnitblog.com/SpiWolf/archive/2005/12/17/5515.html</guid><wfw:comment>http://www.cnitblog.com/SpiWolf/comments/5515.html</wfw:comment><comments>http://www.cnitblog.com/SpiWolf/archive/2005/12/17/5515.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/SpiWolf/comments/commentRss/5515.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/SpiWolf/services/trackbacks/5515.html</trackback:ping><description><![CDATA[<div id="wikicontent">
            <div class="wikitext"><div><p>This
is a sample program that uses a netlink socket to listen to route
change events and prints out some rudimentary information about them.
It's very simple and boring, but hopefully useful.</p>
<p>This being a wiki, I also expect everyone to hack on this code and
make it nicer, this is pretty hideous, but I want to get on with my
real program now. So if you're reading this page your mission (if you
choose to accept it) is to clean up the below code a little bit
(doesn't need to be much).</p>
<p>See <a href="http://www.wlug.org.nz/LinuxNetlinkSockets" class="wiki">LinuxNetlinkSockets</a></p>
<hr><pre>#include &lt;asm/types.h&gt;<br><br>#include &lt;sys/socket.h&gt;<br>#include &lt;unistd.h&gt;<br>#include &lt;err.h&gt;<br>#include &lt;stdio.h&gt;<br>#include &lt;netinet/in.h&gt;<br><br>#include &lt;linux/netlink.h&gt;<br>#include &lt;linux/rtnetlink.h&gt;<br><br>#if 0<br>//#define MYPROTO NETLINK_ARPD<br>#define MYMGRP RTMGRP_NEIGH<br>// if you want the above you'll find that the kernel must be compiled with CONFIG_ARPD, and<br>// that you need MYPROTO=NETLINK_ROUTE, since the kernel arp code {re,ab}uses rtnl (NETLINK_ROUTE)<br><br>#else<br>#define MYPROTO NETLINK_ROUTE<br>#define MYMGRP RTMGRP_IPV4_ROUTE<br>#endif<br><br>struct msgnames_t {<br>        int id;<br>        char *msg;<br>} typenames[] = {<br>#define MSG(x) { x, #x }<br>        MSG(RTM_NEWROUTE),<br>        MSG(RTM_DELROUTE),<br>        MSG(RTM_GETROUTE),<br>#undef MSG<br>        {0,0}<br>};<br><br>char *lookup_name(struct msgnames_t *db,int id)<br>{<br>        static char name[512];<br>        struct msgnames_t *msgnamesiter;<br>        for(msgnamesiter=db;msgnamesiter-&gt;msg;++msgnamesiter) {<br>                if (msgnamesiter-&gt;id == id)<br>                        break;<br>        }<br>        if (msgnamesiter-&gt;msg) {<br>                return msgnamesiter-&gt;msg;<br>        }<br>        snprintf(name,sizeof(name),"#%i",id);<br>        return name;<br>}<br><br>int open_netlink()<br>{<br>        int sock = socket(AF_NETLINK,SOCK_RAW,MYPROTO);<br>        struct sockaddr_nl addr;<br><br>        memset((void *)&amp;addr, 0, sizeof(addr));<br><br>        if (sock&lt;0)<br>                return sock;<br>        addr.nl_family = AF_NETLINK;<br>        addr.nl_pid = getpid();<br>        addr.nl_groups = MYMGRP;<br>        if (bind(sock,(struct sockaddr *)&amp;addr,sizeof(addr))&lt;0)<br>                return -1;<br>        return sock;<br>}<br><br>int read_event(int sock)<br>{<br>        struct sockaddr_nl nladdr;<br>        struct msghdr msg;<br>        struct iovec iov[2];<br>        struct nlmsghdr nlh;<br>        char buffer[65536];<br>        int ret;<br>        iov[0].iov_base = (void *)&amp;nlh;<br>        iov[0].iov_len = sizeof(nlh);<br>        iov[1].iov_base = (void *)buffer;<br>        iov[1].iov_len = sizeof(buffer);<br>        msg.msg_name = (void *)&amp;(nladdr);<br>        msg.msg_namelen = sizeof(nladdr);<br>        msg.msg_iov = iov;<br>        msg.msg_iovlen = sizeof(iov)/sizeof(iov[0]);<br>        ret=recvmsg(sock, &amp;msg, 0);<br>        if (ret&lt;0) {<br>                return ret;<br>        }<br>        printf("Type: %i (%s)\n",(nlh.nlmsg_type),lookup_name(typenames,nlh.nlmsg_type));<br>        printf("Flag:");<br>#define FLAG(x) if (nlh.nlmsg_type &amp; x) printf(" %s",#x)<br>        FLAG(NLM_F_REQUEST);<br>        FLAG(NLM_F_MULTI);<br>        FLAG(NLM_F_ACK);<br>        FLAG(NLM_F_ECHO);<br>        FLAG(NLM_F_REPLACE);<br>        FLAG(NLM_F_EXCL);<br>        FLAG(NLM_F_CREATE);<br>        FLAG(NLM_F_APPEND);<br>#undef FLAG<br>        printf("\n");<br>        printf("Seq : %i\n",nlh.nlmsg_seq);<br>        printf("Pid : %i\n",nlh.nlmsg_pid);<br>        printf("\n");<br>        return 0;<br>}<br><br>int main(int argc, char *argv[])<br>{         int nls = open_netlink();<br>        if (nls&lt;0) {<br>                err(1,"netlink");<br>        }<br>        while (1)<br>                read_event(nls);<br>        return 0;<br>}</pre>
</div>
</div>
</div>
<img src ="http://www.cnitblog.com/SpiWolf/aggbug/5515.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/SpiWolf/" target="_blank">幽灵狼</a> 2005-12-17 17:37 <a href="http://www.cnitblog.com/SpiWolf/archive/2005/12/17/5515.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Netlink Socket for Linux</title><link>http://www.cnitblog.com/SpiWolf/archive/2005/12/17/5514.html</link><dc:creator>幽灵狼</dc:creator><author>幽灵狼</author><pubDate>Sat, 17 Dec 2005 09:31:00 GMT</pubDate><guid>http://www.cnitblog.com/SpiWolf/archive/2005/12/17/5514.html</guid><wfw:comment>http://www.cnitblog.com/SpiWolf/comments/5514.html</wfw:comment><comments>http://www.cnitblog.com/SpiWolf/archive/2005/12/17/5514.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/SpiWolf/comments/commentRss/5514.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/SpiWolf/services/trackbacks/5514.html</trackback:ping><description><![CDATA[<h1 class="title">Kernel Korner - Why and How to Use Netlink Socket</h1>

           
         

<!-- begin content -->

  
     
     
    <span class="submitted">By <a href="http://www.linuxjournal.com/user/801239" title="View user profile.">Kevin He</a> on Wed, 2005-01-05 02:00.</span>
    <span class="taxonomy"><a href="http://www.linuxjournal.com/taxonomy/term/8">SysAdmin</a></span>

    
Use this bidirectional, versatile method to pass <a target="_blank" href="http://www.linuxjournal.com/#" style="border-bottom: 0.1em solid darkgreen; font-weight: normal; text-decoration: underline; color: darkgreen; padding-bottom: 1px; background-color: transparent;" class="iAs">data</a> between kernel and user space.

<div class="article" lang="en">

<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x8573a08"></a></h2>
</div>
<p>Due to the complexity of developing and maintaining the kernel, only the most essential and
performance-critical code are placed in the kernel. Other things, such as GUI, management and control code,
typically are programmed as user-space applications. This practice of splitting the implementation of certain
features between kernel and user space is quite common in <a target="_blank" href="http://www.linuxjournal.com/#" style="border-bottom: 0.1em solid darkgreen; font-weight: normal; text-decoration: underline; color: darkgreen; padding-bottom: 1px; background-color: transparent;" class="iAs">Linux</a>. Now the question is how can kernel code and
user-space code communicate with each other?</p>
<p>The answer is the various IPC methods that exist between kernel and user space, such as system call,
ioctl, proc filesystem or netlink socket. This article discusses netlink socket and reveals its advantages as
a network feature-friendly IPC.</p>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x8573ab8"></a> Introduction</h2>
</div>
<p>Netlink socket is a special IPC used for transferring information between kernel and user-space processes.
It provides a full-duplex communication link between the two by way of standard socket APIs for user-space
processes and a special kernel API for kernel modules. Netlink socket uses the address family AF_NETLINK, as
compared to AF_INET used by TCP/IP socket. Each netlink socket feature defines its own protocol type in the
kernel header file include/linux/netlink.h.</p>
<p>The following is a subset of features and their protocol types currently supported by the netlink
socket:</p>
<div class="itemizedlist">
<ul type="disc"><li>
<p>NETLINK_ROUTE: communication channel between user-space routing dæmons, such as BGP, OSPF, RIP and
kernel packet forwarding module. User-space routing dæmons update the kernel routing table through this
netlink protocol type.</p>
</li><li>
<p>NETLINK_FIREWALL: receives packets sent by the IPv4 firewall code.</p>
</li><li>
<p>NETLINK_NFLOG: communication channel for the user-space iptable management tool and kernel-space Netfilter
module.</p>
</li><li>
<p>NETLINK_ARPD: for managing the arp table from user space.</p>
</li></ul>
</div>
<p>Why do the above features use netlink instead of system calls, ioctls or proc filesystems for
communication between user and kernel worlds? It is a nontrivial task to add system calls, ioctls or proc
files for new features; we risk polluting the kernel and damaging the stability of the system. Netlink socket
is simple, though: only a constant, the protocol type, needs to be added to netlink.h. Then, the kernel
module and application can talk using socket-style APIs immediately.</p>
<p>Netlink is asynchronous because, as with any other socket API, it provides a socket queue to smooth the
burst of messages. The system call for sending a netlink message queues the message to the receiver's netlink
queue and then invokes the receiver's reception handler. The receiver, within the reception handler's
context, can decide whether to process the message immediately or leave the message in the queue and process
it later in a different context. Unlike netlink, system calls require synchronous processing. Therefore, if
we use a system call to pass a message from user space to the kernel, the kernel scheduling granularity may
be affected if the time to process that message is long.</p>
<p>The code implementing a system call in the kernel is linked statically to the kernel in compilation time;
thus, it is not appropriate to include system call code in a loadable module, which is the case for most
device drivers. With netlink socket, no compilation time dependency exists between the netlink core of Linux
kernel and the netlink application living in loadable kernel modules.</p>
<p>Netlink socket supports multicast, which is another benefit over system calls, ioctls and proc. One
process can multicast a message to a netlink group address, and any number of other processes can listen to
that group address. This provides a near-perfect mechanism for event distribution from kernel to user
space.</p>
<p>System call and ioctl are simplex IPCs in the sense that a session for these IPCs can be initiated only by
user-space applications. But, what if a kernel module has an urgent message for a user-space application?
There is no way of doing that directly using these IPCs. Normally, applications periodically need to poll the
kernel to get the state changes, although intensive polling is expensive. Netlink solves this problem
gracefully by allowing the kernel to initiate sessions too. We call it the duplex characteristic of the
netlink socket.</p>
<p>Finally, netlink socket provides a BSD socket-style API that is well understood by the software
development community. Therefore, training costs are less as compared to using the rather cryptic system call
APIs and ioctls.</p>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x8573dfc"></a> Relating to the BSD Routing Socket</h2>
</div>
<p>In BSD TCP/IP stack implementation, there is a special socket called the routing socket. It has an address
family of AF_ROUTE, a protocol family of PF_ROUTE and a socket type of SOCK_RAW. The routing socket in BSD is
used by processes to add or delete routes in the kernel routing table.</p>
<p>In Linux, the equivalent function of the routing socket is provided by the netlink socket protocol type
NETLINK_ROUTE. Netlink socket provides a functionality superset of BSD's routing socket.</p>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x8573eac"></a> Netlink Socket APIs</h2>
</div>
<p>The standard socket APIs-socket(), sendmsg(), recvmsg() and close()-can be used by user-space applications
to <a target="_blank" href="http://www.linuxjournal.com/#" style="border-bottom: 0.1em solid darkgreen; font-weight: normal; text-decoration: underline; color: darkgreen; padding-bottom: 1px; background-color: transparent;" class="iAs">access</a> netlink socket. Consult the man pages for detailed definitions of these APIs. Here, we discuss how
to choose parameters for these APIs only in the context of netlink socket. The APIs should be familiar to
anyone who has written an ordinary network application using TCP/IP sockets.</p>
<p>To create a socket with socket(), enter:</p>
<pre class="programlisting"><tt>int socket(int domain, int type, int protocol)<br></tt>
</pre>
<br>
<br>
<p>The socket domain (address family) is AF_NETLINK, and the type of socket is either SOCK_RAW or SOCK_DGRAM,
because netlink is a datagram-oriented service.</p>
<p>The protocol (protocol type) selects for which netlink feature the socket is used. The following are some
predefined netlink protocol types: NETLINK_ROUTE, NETLINK_FIREWALL, NETLINK_ARPD, NETLINK_ROUTE6 and
NETLINK_IP6_FW. You also can add your own netlink protocol type easily.</p>
<p>Up to 32 multicast groups can be defined for each netlink protocol type. Each multicast group is
represented by a bit mask, 1&lt;&lt;i, where 0&lt;=i&lt;=31. This is extremely useful when a group of
processes and the kernel process coordinate to implement the same feature-sending multicast netlink messages
can reduce the number of system calls used and alleviate applications from the burden of maintaining the
multicast group membership.</p>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x857400c"></a> bind()</h2>
</div>
<p>As for a TCP/IP socket, the netlink bind() API associates a local (source) socket address with the opened
socket. The netlink address structure is as follows:</p>
<pre class="programlisting"><tt>struct sockaddr_nl<br>{<br>  sa_family_t    nl_family;  /* AF_NETLINK   */<br>  unsigned short nl_pad;     /* zero         */<br>  __u32          nl_pid;     /* process pid */<br>  __u32          nl_groups;  /* mcast groups mask */<br>} nladdr;<br></tt>
</pre>
<br>
<br>
<p>When used with bind(), the nl_pid field of the sockaddr_nl can be filled with the calling process' own
pid. The nl_pid serves here as the local address of this netlink socket. The application is responsible for
picking a unique 32-bit integer to fill in nl_pid:</p>
<pre class="programlisting"><tt>NL_PID Formula 1:  nl_pid = getpid();<br></tt>
</pre>
<br>
<br>
<p>Formula 1 uses the process ID of the application as nl_pid, which is a natural choice if, for the given
netlink protocol type, only one netlink socket is needed for the process.</p>
<p>In scenarios where different threads of the same process want to have different netlink sockets opened
under the same netlink protocol, Formula 2 can be used to generate the nl_pid:</p>
<pre class="programlisting"><tt><br>NL_PID Formula 2: pthread_self() &lt;&lt; 16 | getpid();<br></tt>
</pre>
<br>
<br>
<p>In this way, different pthreads of the same process each can have their own netlink socket for the same
netlink protocol type. In fact, even within a single pthread it's possible to create multiple netlink sockets
for the same protocol type. Developers need to be more creative, however, in generating a unique nl_pid, and
we don't consider this to be a normal-use case.</p>
<p>If the application wants to receive netlink messages of the protocol type that are destined for certain
multicast groups, the bitmasks of all the interested multicast groups should be ORed together to form the
nl_groups field of sockaddr_nl. Otherwise, nl_groups should be zeroed out so the application receives only
the unicast netlink message of the protocol type destined for the application. After filling in the nladdr,
do the bind as follows:</p>
<pre class="programlisting"><tt><br>bind(fd, (struct sockaddr*)&amp;nladdr, sizeof(nladdr));<br></tt>
</pre>
<br>
<br>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x857421c"></a> Sending a Netlink Message</h2>
</div>
<p>In order to send a netlink message to the kernel or other user-space processes, another struct sockaddr_nl
nladdr needs to be supplied as the destination address, the same as sending a UDP packet with sendmsg(). If
the message is destined for the kernel, both nl_pid and nl_groups should be supplied with 0.</p>
<p>If the message is a unicast message destined for another process, the nl_pid is the other process' pid and
nl_groups is 0, assuming nlpid Formula 1 is used in the system.</p>
<p>If the message is a multicast message destined for one or multiple multicast groups, the bitmasks of all
the destination multicast groups should be ORed together to form the nl_groups field. We then can supply the
netlink address to the struct msghdr msg for the sendmsg() API, as follows:</p>
<pre class="programlisting"><tt><br>struct msghdr msg;<br>msg.msg_name = (void *)&amp;(nladdr);<br>msg.msg_namelen = sizeof(nladdr);<br></tt>
</pre>
<br>
<br>
<p>The netlink socket requires its own message header as well. This is for providing a common ground for
netlink messages of all protocol types.</p>
<p>Because the Linux kernel netlink core assumes the existence of the following header in each netlink
message, an application must supply this header in each netlink message it sends:</p>
<pre class="programlisting"><tt><br>struct nlmsghdr<br>{<br>  __u32 nlmsg_len;   /* Length of message */<br>  __u16 nlmsg_type;  /* Message type*/<br>  __u16 nlmsg_flags; /* Additional flags */<br>  __u32 nlmsg_seq;   /* Sequence number */<br>  __u32 nlmsg_pid;   /* Sending process PID */<br>};<br></tt>
</pre>
<br>
<br>
<p>nlmsg_len has to be completed with the total length of the netlink message, including the header, and is
required by netlink core. nlmsg_type can be used by applications and is an opaque value to netlink core.
nlmsg_flags is used to give additional control to a message; it is read and updated by netlink core.
nlmsg_seq and nlmsg_pid are used by applications to track the message, and they are opaque to netlink core as
well.</p>
<p>A netlink message thus consists of nlmsghdr and the message payload. Once a message has been entered, it
enters a buffer pointed to by the nlh pointer. We also can send the message to the struct msghdr msg:</p>
<pre class="programlisting"><tt><br>struct iovec iov;<br>iov.iov_base = (void *)nlh;<br>iov.iov_len = nlh-&gt;nlmsg_len;<br>msg.msg_iov = &amp;iov;<br>msg.msg_iovlen = 1;<br></tt>
</pre>
<br>
<br>
<p>After the above steps, a call to sendmsg() kicks out the netlink message:</p>
<pre class="programlisting"><tt><br>sendmsg(fd, &amp;msg, 0);<br></tt>
</pre>
<br>
<br>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x8574484"></a> Receiving Netlink Messages</h2>
</div>
<p>A receiving application needs to allocate a buffer large enough to hold netlink message headers and
message payloads. It then fills the struct msghdr msg as shown below and uses the standard recvmsg() to
receive the netlink message, assuming the buffer is pointed to by nlh:</p>
<pre class="programlisting"><tt><br>struct sockaddr_nl nladdr;<br>struct msghdr msg;<br>struct iovec iov;<br>iov.iov_base = (void *)nlh;<br>iov.iov_len = MAX_NL_MSG_LEN;<br>msg.msg_name = (void *)&amp;(nladdr);<br>msg.msg_namelen = sizeof(nladdr);<br>msg.msg_iov = &amp;iov;<br>msg.msg_iovlen = 1;<br>recvmsg(fd, &amp;msg, 0);<br></tt>
</pre>
<br>
<br>
<p>After the message has been received correctly, the nlh should point to the header of the just-received
netlink message. nladdr should hold the destination address of the received message, which consists of the
pid and the multicast groups to which the message is sent. And, the macro NLMSG_DATA(nlh), defined in
netlink.h, returns a pointer to the payload of the netlink message. A call to close(fd) closes the netlink
socket identified by file descriptor fd.</p>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x8574560"></a> Kernel-Space Netlink APIs</h2>
</div>
<p>The kernel-space netlink API is supported by the netlink core in the kernel, net/core/af_netlink.c. From
the kernel side, the API is different from the user-space API. The API can be used by kernel modules to
access the netlink socket and to communicate with user-space applications. Unless you leverage the existing
netlink socket protocol types, you need to add your own protocol type by adding a constant to netlink.h. For
example, we can add a netlink protocol type for testing purposes by inserting this line into netlink.h:</p>
<pre class="programlisting"><tt>#define NETLINK_TEST  17<br></tt>
</pre>
<br>
<br>
<p>Afterward, you can reference the added protocol type anywhere in the Linux kernel.</p>
<p>In user space, we call socket() to create a netlink socket, but in kernel space, we call the following
API:</p>
<pre class="programlisting"><tt><br>struct sock *<br>netlink_kernel_create(int unit, <br>           void (*input)(struct sock *sk, int len));<br></tt>
</pre>
<br>
<br>
<p>The parameter unit is, in fact, the netlink protocol type, such as NETLINK_TEST. The function pointer,
input, is a callback function invoked when a message arrives at this netlink socket.</p>
<p>After the kernel has created a netlink socket for protocol NETLINK_TEST, whenever user space sends a
netlink message of the NETLINK_TEST protocol type to the kernel, the callback function, input(), which is
registered by netlink_kernel_create(), is invoked. The following is an example implementation of the callback
function input:</p>
<pre class="programlisting"><tt><br>void input (struct sock *sk, int len)<br>{<br> struct sk_buff *skb;<br> struct nlmsghdr *nlh = NULL;<br> u8 *payload = NULL;<br> while ((skb = skb_dequeue(&amp;sk-&gt;receive_queue)) <br>       != NULL) {<br> /* process netlink message pointed by skb-&gt;data */<br> nlh = (struct nlmsghdr *)skb-&gt;data;<br> payload = NLMSG_DATA(nlh);<br> /* process netlink message with header pointed by <br>  * nlh and payload pointed by payload<br>  */<br> }   <br>}<br></tt>
</pre>
<br>
<br>
<p>This input() function is called in the context of the sendmsg() system call invoked by the sending
process. It is okay to process the netlink message inside input() if it's fast. When the processing of
netlink message takes a long time, however, we want to keep it out of input() to avoid blocking other system
calls from entering the kernel. Instead, we can use a dedicated kernel thread to perform the following steps
indefinitely. Use <tt>skb = skb_recv_datagram(nl_sk)</tt> where <tt>nl_sk</tt> is the netlink socket returned
by netlink_kernel_create(). Then, process the netlink message pointed to by skb-&gt;data.</p>
<p>This kernel thread sleeps when there is no netlink message in nl_sk. Thus, inside the callback function
input(), we need to wake up only the sleeping kernel thread, like this:</p>
<pre class="programlisting"><tt><br>void input (struct sock *sk, int len)<br>{<br>  wake_up_interruptible(sk-&gt;sleep);<br>}<br></tt>
</pre>
<br>
<br>
<p>This is a more scalable communication model between user space and kernel. It also improves the
granularity of context switches.</p>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x85d2bd8"></a> Sending Netlink Messages from the Kernel</h2>
</div>
<p>Just as in user space, the source netlink address and destination netlink address need to be set when
sending a netlink message. Assuming the socket buffer holding the netlink message to be sent is struct
sk_buff *skb, the local address can be set with:</p>
<pre class="programlisting"><tt><br>NETLINK_CB(skb).groups = local_groups;<br>NETLINK_CB(skb).pid = 0;   /* from kernel */<br></tt>
</pre>
<br>
<br>
<p>The destination address can be set like this:</p>
<pre class="programlisting"><tt><br>NETLINK_CB(skb).dst_groups = dst_groups;<br>NETLINK_CB(skb).dst_pid = dst_pid;<br></tt>
</pre>
<br>
<br>
<p>Such information is not stored in skb-&gt;data. Rather, it is stored in the netlink control block of the
socket buffer, skb.</p>
<p>To send a unicast message, use:</p>
<pre class="programlisting"><tt><br>int <br>netlink_unicast(struct sock *ssk, struct sk_buff <br>                *skb, u32 pid, int nonblock);<br></tt>
</pre>
<br>
<br>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x85d2d64"></a></h2>
</div>
<p>where <tt>ssk</tt> is the netlink socket returned by netlink_kernel_create(), <tt>skb-&gt;data</tt> points
to the netlink message to be sent and <tt>pid</tt> is the receiving application's pid, assuming NLPID Formula
1 is used. <tt>nonblock</tt> indicates whether the API should block when the receiving buffer is unavailable
or immediately return a failure.</p>
<p>You also can send a multicast message. The following API delivers a netlink message to both the process
specified by pid and the multicast groups specified by group:</p>
<pre class="programlisting"><tt><br>void <br>netlink_broadcast(struct sock *ssk, struct sk_buff <br>         *skb, u32 pid, u32 group, int allocation);<br></tt>
</pre>
<br>
<br>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x85d2ef0"></a></h2>
</div>
<p><tt>group</tt> is the ORed bitmasks of all the receiving multicast groups. <tt>allocation</tt> is the
kernel memory allocation type. Typically, GFP_ATOMIC is used if from interrupt context; GFP_KERNEL if
otherwise. This is due to the fact that the API may need to allocate one or many socket buffers to clone the
multicast message.</p>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x85d2fcc"></a> Closing a Netlink Socket from the Kernel</h2>
</div>
<p>Given the struct sock *nl_sk returned by netlink_kernel_create(), we can call the following kernel API to
close the netlink socket in the kernel:</p>
<pre class="programlisting"><tt><br>sock_release(nl_sk-&gt;socket);<br></tt>
</pre>
<br>
<br>
<p>So far, we have shown only the bare minimum code framework to illustrate the concept of netlink
programming. We now will use our NETLINK_TEST netlink protocol type and assume it already has been added to
the kernel header file. The kernel module code listed here contains only the netlink-relevant part, so it
should be inserted into a complete kernel module skeleton, which you can find from many other reference
sources.</p>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x85d30a8"></a> Unicast Communication between Kernel and
Application</h2>
</div>
<p>In this example, a user-space process sends a netlink message to the kernel module, and the kernel module
echoes the message back to the sending process. Here is the user-space code:</p>
<pre class="programlisting"><tt><br>#include &lt;sys/socket.h&gt;<br>#include &lt;linux/netlink.h&gt;<br>#define MAX_PAYLOAD 1024  /* maximum payload size*/<br>struct sockaddr_nl src_addr, dest_addr;<br>struct nlmsghdr *nlh = NULL;<br>struct iovec iov;<br>int sock_fd;<br>void main() {<br> sock_fd = socket(PF_NETLINK, SOCK_RAW,NETLINK_TEST);<br> memset(&amp;src_addr, 0, sizeof(src_addr));<br> src__addr.nl_family = AF_NETLINK;      <br> src_addr.nl_pid = getpid();  /* self pid */<br> src_addr.nl_groups = 0;  /* not in mcast groups */<br> bind(sock_fd, (struct sockaddr*)&amp;src_addr, <br>      sizeof(src_addr));<br> memset(&amp;dest_addr, 0, sizeof(dest_addr));<br> dest_addr.nl_family = AF_NETLINK;<br> dest_addr.nl_pid = 0;   /* For Linux Kernel */<br> dest_addr.nl_groups = 0; /* unicast */<br> nlh=(struct nlmsghdr *)malloc(<br>                         NLMSG_SPACE(MAX_PAYLOAD));<br> /* Fill the netlink message header */<br> nlh-&gt;nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);<br> nlh-&gt;nlmsg_pid = getpid();  /* self pid */<br> nlh-&gt;nlmsg_flags = 0;<br> /* Fill in the netlink message payload */<br> strcpy(NLMSG_DATA(nlh), "Hello you!");<br> iov.iov_base = (void *)nlh;<br> iov.iov_len = nlh-&gt;nlmsg_len;<br> msg.msg_name = (void *)&amp;dest_addr;<br> msg.msg_namelen = sizeof(dest_addr);<br> msg.msg_iov = &amp;iov;<br> msg.msg_iovlen = 1;<br> sendmsg(fd, &amp;msg, 0);<br> /* Read message from kernel */<br> memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));<br> recvmsg(fd, &amp;msg, 0);<br> printf(" Received message payload: %s\n", <br>        NLMSG_DATA(nlh));<br>    <br> /* Close Netlink Socket */<br> close(sock_fd);<br>}    <br></tt>
</pre>
<br>
<br>
<p>And, here is the kernel code:</p>
<pre class="programlisting"><tt><br>struct sock *nl_sk = NULL;<br>void nl_data_ready (struct sock *sk, int len)<br>{<br>  wake_up_interruptible(sk-&gt;sleep);<br>}<br>void netlink_test() {<br> struct sk_buff *skb = NULL;<br> struct nlmsghdr *nlh = NULL;<br> int err;<br> u32 pid;     <br> nl_sk = netlink_kernel_create(NETLINK_TEST, <br>                                   nl_data_ready);<br> /* wait for message coming down from user-space */<br> skb = skb_recv_datagram(nl_sk, 0, 0, &amp;err);<br> nlh = (struct nlmsghdr *)skb-&gt;data;<br> printk("%s: received netlink message payload:%s\n", <br>        __FUNCTION__, NLMSG_DATA(nlh));<br> pid = nlh-&gt;nlmsg_pid; /*pid of sending process */<br> NETLINK_CB(skb).groups = 0; /* not in mcast group */<br> NETLINK_CB(skb).pid = 0;      /* from kernel */<br> NETLINK_CB(skb).dst_pid = pid;<br> NETLINK_CB(skb).dst_groups = 0;  /* unicast */<br> netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT);<br> sock_release(nl_sk-&gt;socket);<br>}    <br></tt>
</pre>
<br>
<br>
<p>After loading the kernel module that executes the kernel code above, when we run the user-space
executable, we should see the following dumped from the user-space program:</p>
<pre class="programlisting"><tt>Received message payload: Hello you!<br></tt>
</pre>
<br>
<br>
<p>And, the following message should appear in the output of dmesg:</p>
<pre class="programlisting"><tt>netlink_test: received netlink message payload: <br>Hello you!<br></tt>
</pre>
<br>
<br>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x85d3260"></a> Multicast Communication between Kernel and
Applications</h2>
</div>
<p>In this example, two user-space applications are listening to the same netlink multicast group. The kernel
module pops up a message through netlink socket to the multicast group, and all the applications receive it.
Here is the user-space code:</p>
<pre class="programlisting"><tt><br>#include &lt;sys/socket.h&gt;<br>#include &lt;linux/netlink.h&gt;<br>#define MAX_PAYLOAD 1024  /* maximum payload size*/<br>struct sockaddr_nl src_addr, dest_addr;<br>struct nlmsghdr *nlh = NULL;<br>struct iovec iov;<br>int sock_fd;<br>void main() {<br> sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);<br> memset(&amp;src_addr, 0, sizeof(local_addr));<br> src_addr.nl_family = AF_NETLINK;       <br> src_addr.nl_pid = getpid();  /* self pid */<br> /* interested in group 1&lt;&lt;0 */  <br> src_addr.nl_groups = 1;<br> bind(sock_fd, (struct sockaddr*)&amp;src_addr, <br>      sizeof(src_addr));<br> memset(&amp;dest_addr, 0, sizeof(dest_addr)); <br> nlh = (struct nlmsghdr *)malloc(<br>                          NLMSG_SPACE(MAX_PAYLOAD));<br> memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));      <br>    <br> iov.iov_base = (void *)nlh;<br> iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD);<br> msg.msg_name = (void *)&amp;dest_addr;<br> msg.msg_namelen = sizeof(dest_addr);<br> msg.msg_iov = &amp;iov;<br> msg.msg_iovlen = 1;<br> printf("Waiting for message from kernel\n");<br> /* Read message from kernel */<br> recvmsg(fd, &amp;msg, 0);<br> printf(" Received message payload: %s\n", <br>        NLMSG_DATA(nlh));<br> close(sock_fd);<br>}    <br></tt>
</pre>
<br>
<br>
<p>And, here is the kernel code:</p>
<pre class="programlisting"><tt><br>#define MAX_PAYLOAD 1024 <br>struct sock *nl_sk = NULL;<br>void netlink_test() {<br> sturct sk_buff *skb = NULL;<br> struct nlmsghdr *nlh;<br> int err;<br> nl_sk = netlink_kernel_create(NETLINK_TEST, <br>                               nl_data_ready);<br> skb=alloc_skb(NLMSG_SPACE(MAX_PAYLOAD),GFP_KERNEL);<br> nlh = (struct nlmsghdr *)skb-&gt;data;<br> nlh-&gt;nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);<br> nlh-&gt;nlmsg_pid = 0;  /* from kernel */<br> nlh-&gt;nlmsg_flags = 0;<br> strcpy(NLMSG_DATA(nlh), "Greeting from kernel!");<br> /* sender is in group 1&lt;&lt;0 */<br> NETLINK_CB(skb).groups = 1;<br> NETLINK_CB(skb).pid = 0;  /* from kernel */<br> NETLINK_CB(skb).dst_pid = 0;  /* multicast */<br> /* to mcast group 1&lt;&lt;0 */<br> NETLINK_CB(skb).dst_groups = 1;<br> /*multicast the message to all listening processes*/<br> netlink_broadcast(nl_sk, skb, 0, 1, GFP_KERNEL);<br> sock_release(nl_sk-&gt;socket);<br>}    <br></tt>
</pre>
<br>
<br>
<p>Assuming the user-space code is compiled into the executable nl_recv, we can run two instances of
nl_recv:</p>
<pre class="programlisting"><tt><br>./nl_recv &amp;<br>Waiting for message from kernel<br>./nl_recv &amp;<br>Waiting for message from kernel<br></tt>
</pre>
<br>
<br>
<p>Then, after we load the kernel module that executes the kernel-space code, both instances of nl_recv
should receive the following message:</p>
<pre class="programlisting"><tt>Received message payload: Greeting from kernel!<br>Received message payload: Greeting from kernel!<br></tt>
</pre>
<br>
<br>
</div>
<div class="simplesect" lang="en">
<div class="titlepage">
<h2 class="title"><a name="N0x850ca10.0x85d3418"></a>Conclusion</h2>
</div>
<p>Netlink socket is a flexible interface for communication between user-space applications and kernel
modules. It provides an easy-to-use socket API to both applications and the kernel. It provides advanced
communication features, such as full-duplex, buffered I/O, multicast and asynchronous communication, which
are absent in other kernel/user-space IPCs.</p>
</div>
</div>

<p>Kevin Kaichuan He (<a href="mailto:hek_u5@yahoo.com">hek_u5@yahoo.com</a>) is a principal software
engineer at Solustek Corp. He currently is working on embedded system, device driver and networking protocols
projects. His previous work experience includes senior software engineer at Cisco Systems and research
assistant at CS, Purdue University. In his spare time, he enjoys digital photography, PS2 games and
literature.<br>
</p>
<p><font color="#ff0000">The URL of this article: <a href="http://www.linuxjournal.com/article/7356">http://www.linuxjournal.com/article/7356</a></font><br>
</p>

<img src ="http://www.cnitblog.com/SpiWolf/aggbug/5514.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/SpiWolf/" target="_blank">幽灵狼</a> 2005-12-17 17:31 <a href="http://www.cnitblog.com/SpiWolf/archive/2005/12/17/5514.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>I/O in FreeBSD</title><link>http://www.cnitblog.com/SpiWolf/archive/2005/12/14/5359.html</link><dc:creator>幽灵狼</dc:creator><author>幽灵狼</author><pubDate>Wed, 14 Dec 2005 03:19:00 GMT</pubDate><guid>http://www.cnitblog.com/SpiWolf/archive/2005/12/14/5359.html</guid><wfw:comment>http://www.cnitblog.com/SpiWolf/comments/5359.html</wfw:comment><comments>http://www.cnitblog.com/SpiWolf/archive/2005/12/14/5359.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/SpiWolf/comments/commentRss/5359.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/SpiWolf/services/trackbacks/5359.html</trackback:ping><description><![CDATA[<P align=left>buf(9) manual<BR></P><img src ="http://www.cnitblog.com/SpiWolf/aggbug/5359.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/SpiWolf/" target="_blank">幽灵狼</a> 2005-12-14 11:19 <a href="http://www.cnitblog.com/SpiWolf/archive/2005/12/14/5359.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Project Evil: Windows network drivers on FreeBSD</title><link>http://www.cnitblog.com/SpiWolf/archive/2005/11/20/4751.html</link><dc:creator>幽灵狼</dc:creator><author>幽灵狼</author><pubDate>Sun, 20 Nov 2005 13:52:00 GMT</pubDate><guid>http://www.cnitblog.com/SpiWolf/archive/2005/11/20/4751.html</guid><wfw:comment>http://www.cnitblog.com/SpiWolf/comments/4751.html</wfw:comment><comments>http://www.cnitblog.com/SpiWolf/archive/2005/11/20/4751.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/SpiWolf/comments/commentRss/4751.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/SpiWolf/services/trackbacks/4751.html</trackback:ping><description><![CDATA[related url:<BR><A href="http://www.pingwales.co.uk/2005/07/15/Project-Evil.html">http://www.pingwales.co.uk/2005/07/15/Project-Evil.html</A><BR><A href="http://lists.freebsd.org/pipermail/freebsd-hardware/2004-January/001005.html">http://lists.freebsd.org/pipermail/freebsd-hardware/2004-January/001005.html</A><BR><BR>In this article:<BR><A href="http://www.pingwales.co.uk/tutorials/project-evil.html#part1"><STRONG><FONT color=#000000>Introducing Evil</FONT></STRONG></A><BR><A href="http://www.pingwales.co.uk/tutorials/project-evil.html#part2"><STRONG><FONT color=#000000>How does it work?</FONT></STRONG></A><BR><A href="http://www.pingwales.co.uk/tutorials/project-evil.html#part3"><STRONG><FONT color=#000000>Building the kernel modules</FONT></STRONG></A><BR><A href="http://www.pingwales.co.uk/tutorials/project-evil.html#part4"><STRONG><FONT color=#000000>The old way</FONT></STRONG></A><BR><A href="http://www.pingwales.co.uk/tutorials/project-evil.html#part5"><STRONG><FONT color=#000000>The new way</FONT></STRONG></A><BR><BR><A name=part1></A>
<P><STRONG>Introducing Evil</STRONG></P>
<P>One of the problems plaguing the Free Software community is the availability of device drivers. Unless an operating system has a significant market share, it does not make economic sense for a manufacturer to write device drivers for that system. Many manufacturers won't even provide documentation allowing open source drivers to be written, claiming that it would require disclosure of valuable intellectual property.</P>
<P>In the case of WiFi cards, this can be a problem. It is very difficult to tell in advance which chipset is used in a given card - some manufacturers change the hardware completely without changing the model number - and so finding a WiFi card compatible with your favourite OS can be difficult.</P>
<P>OpenBSD has a strong ideological attitude in this respect. If a manufacturer is not willing to release documentation, then they will not include closed-source drivers. This argument makes sense from a security point of view - if the drivers are closed then you can't audit them and so they may end up compromising the base system.</P>
<P>FreeBSD is more pragmatic. They include Project Evil, a partial implementation of the Windows driver API, which allows Windows drivers to be used for network cards. While not quite as useful as a native driver, they are a significant improvement over no driver at all.</P><A name=part2></A>
<P><B>How does it work?</B></P>
<P>Project Evil provides a set of basic functions commonly used by Windows network drivers. These functions are then translated internally to the FreeBSD driver model. To the driver, it appears that it is running in a normal Windows environment. To the OS, it appears that a native FreeBSD kernel module containing the driver is present.</P>
<P>On Windows, a WiFi driver comes in three components. The driver itself usually has the extension <SPAN class=file><FONT face="Courier New">.sys</FONT></SPAN>. There is also a <SPAN class=file><FONT face="Courier New">.inf</FONT></SPAN> file which contains information about the driver, such as the device ID of the hardware. Finally there is a copy of the driver firmware.</P>
<P>Traditionally, the firmware - software embedded in the device - for a network interface would be burned into ROM and shipped with the card. Then it was realised that the ability to update the firmware was desirable and so it was put in Flash, or similar. In modern, low budget, cards, the Flash is left off, and the firmware is stored in RAM. This means that the driver must load it before the card can be used.</P>
<P>To make matters more complicated, some drivers have separate firmware for the ethernet controller and radio portions of the firmware. Firmware files usually have the <SPAN class=file><FONT face="Courier New">.bin</FONT></SPAN> extension.</P><A name=part3></A>
<P><B>Building the kernel modules</B></P>
<P>You will need a copy of the Windows driver. This will probably be on a CD included with your network card, or available from the manufacturer&amp;apos;s web site. You should copy everything with a <SPAN class=file><FONT face="Courier New">.sys</FONT></SPAN>, <SPAN class=file><FONT face="Courier New">.inf</FONT></SPAN>, or <SPAN class=file><FONT face="Courier New">.bin</FONT></SPAN> extension to <SPAN class=file><FONT face="Courier New">/sys/modules/if_ndis</FONT></SPAN>.</P>
<P>I will use the file names of my driver for the rest of this tutorial, but you should substitute your own. The files supplied for my card are:</P>
<DL>
<DT><SPAN class=file><FONT face="Courier New">Fw1130.bin</FONT></SPAN> 
<DD>Network interface firmware. 
<DT><SPAN class=file><FONT face="Courier New">FwRad16.bin</FONT></SPAN> 
<DD>Radio firmware. 
<DT><SPAN class=file><FONT face="Courier New">TNET1130.INF</FONT></SPAN> 
<DD>Driver information file. 
<DT><SPAN class=file><FONT face="Courier New">tnet1130.sys</FONT></SPAN> 
<DD>Driver binary. </DD></DL>
<P>The way of generating Project Evil kernel modules changed between FreeBSD 5.3 and FreeBSD 5.4, and unfortunately the documentation shipped with 5.4 still reflects the 5.3 method which no longer works. I will explain both methods.</P>
<P>It might be worth upgrading to -STABLE before you start, as work on Project Evil is constantly in progress - my interface wouldn't work with FreeBSD 5.3, but it would with a snapshot of -STABLE a couple of weeks after the release.</P><A name=part4></A>
<P><B>The old way</B></P>
<P>Before you start you will need to have the kernel sources for the release you are running installed.</P>
<P>The old way of installing a Project Evil module required you to build three different modules - the ndis stub driver, a specific driver for your card, and a module containing the firmware. This can be done with the following commands:</P><PRE class=commands># cd /sys/modules/ndis
# make depend
...
# make
...
# make install
...
# cd ../if_ndis
# ndiscvt -i TNET1130.INF -s tnet1130.sys 
-f Fw1130.bin -o ndis_driver_data.h
...
# make depend
...
# make
...
# make install
# ndiscvt -f FwRad16.bin
# cp FwRad16.bin.ko /boot/kernel
</PRE>
<P>The driver should now be installed. The next step is to test it. The driver will not work if it can't find the firmware, so the order in which these are loaded is important.</P><PRE class=commands># kldload FwRad16.bin
# kldload if_ndis
</PRE>
<P>The driver should now be loaded. The easiest way to configure the adapter is to run <SPAN class=file><FONT face="Courier New">/stand/sysinstall</FONT></SPAN> and follow the instructions.</P>
<P>If you want your driver to load every time you reboot (which you probably do) you can add it to <SPAN class=file><FONT face="Courier New">/boot/loader.conf</FONT></SPAN>. You will need to add a line for each module, so you should end up with something that looks like this:</P><PRE class=configFile>FwRad16.bin_load="YES"
if_ndis_load="YES"
</PRE><A name=part5></A>
<P><B>The new way</B></P>
<P>The new way doesn&amp;apos;t require the kernel sources installed. The ndis and if_ndis kernel modules should already be installed. You will need to create one module for your card, which will contain the driver and the firmware. This is handled by an undocumented wizard called <SPAN class=file><FONT face="Courier New">ndisgen</FONT></SPAN>.</P><PRE class=commands># ndisgen
</PRE>
<P>This will ask you for the location of your driver and firmware files. Note that they are case-sensitive and require full paths. At the end, it will create a single <SPAN class=file><FONT face="Courier New">.ko</FONT></SPAN> file. In my case, this was <SPAN class=file><FONT face="Courier New">tnet1130_sys.ko</FONT></SPAN>. You need to move this module to a location where it can be found by <SPAN class=file><FONT face="Courier New">kldload</FONT></SPAN>, and then load it.</P><PRE class=commands># cp tnet1130_sys.ko /boot/kernel/
# kldload ndis
# kldload if_ndis
# kldload tnet1130_sys
</PRE>
<P>Note the order of the <SPAN class=file><FONT face="Courier New">kldload</FONT></SPAN> statements. It is very important that they be performed in this order. Attempting to load the network card driver before the ndis stub driver can result in a kernel panic.</P>
<P>As with the old way, you load the driver at boot by adding it to <SPAN class=file><FONT face="Courier New">/boot/loader.conf</FONT></SPAN>. You will need to add a line for each module of the three modules, so you should end up with something that looks like this:</P><PRE class=configFile>ndis_load="YES"
if_ndis_load="YES"
tnet1130_sys_load="YES"
</PRE>
<P>You can now reboot and have your network card available at boot time. As before, use <SPAN class=file><FONT face="Courier New">/stand/sysinstall</FONT></SPAN> to set up the interface.</P>
<P><I>If you've found this article helpful, and would like to see similar tutorials on a particular topic, send your suggestions and requests to <A href="mailto:features@pingwales.co.uk"><STRONG><FONT color=#000000>&amp;#x66&amp;#x65&amp;#x61t&amp;#x75&amp;#x72es@p&amp;#x69&amp;#x6Egwal&amp;#x65s&amp;#x2E&amp;#x63&amp;#x6F.uk</FONT></STRONG></A></I></P><img src ="http://www.cnitblog.com/SpiWolf/aggbug/4751.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/SpiWolf/" target="_blank">幽灵狼</a> 2005-11-20 21:52 <a href="http://www.cnitblog.com/SpiWolf/archive/2005/11/20/4751.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Concept of DMZ</title><link>http://www.cnitblog.com/SpiWolf/archive/2005/11/19/4685.html</link><dc:creator>幽灵狼</dc:creator><author>幽灵狼</author><pubDate>Sat, 19 Nov 2005 02:28:00 GMT</pubDate><guid>http://www.cnitblog.com/SpiWolf/archive/2005/11/19/4685.html</guid><wfw:comment>http://www.cnitblog.com/SpiWolf/comments/4685.html</wfw:comment><comments>http://www.cnitblog.com/SpiWolf/archive/2005/11/19/4685.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/SpiWolf/comments/commentRss/4685.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/SpiWolf/services/trackbacks/4685.html</trackback:ping><description><![CDATA[<!--StartFragment --><SPAN id=intelliTxt name="intelliTxt">(pronounced as separate letters) Short for <I><B>d</B>e<B>m</B>ilitarized <B>z</B>one</I>, a <U>computer</U> or small subnetwork that sits between a trusted internal <U>network</U>, such as a corporate private <U>LAN</U>, and an untrusted external <U>network</U>, such as the public <U>Internet</U>. 
<P>Typically, the DMZ contains devices accessible to <U>Internet traffic</U>, such as Web (<U>HTTP</U> ) <U>servers</U>, <U>FTP</U> servers, <U>SMTP</U> (e-mail) servers and <U>DNS</U> servers. </P>
<P>The term comes from military use, meaning a buffer area between two enemies. </P></SPAN><img src ="http://www.cnitblog.com/SpiWolf/aggbug/4685.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/SpiWolf/" target="_blank">幽灵狼</a> 2005-11-19 10:28 <a href="http://www.cnitblog.com/SpiWolf/archive/2005/11/19/4685.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>