Current File : //usr/share/doc/net-snmp/html/snmpUDPDomain_8c_source.html
<!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/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>net-snmp: snmpUDPDomain.c Source File</title>

<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />



</head>
<body>
<div id="top"><!-- do not remove this div! -->


<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  
  
  <td style="padding-left: 0.5em;">
   <div id="projectname">net-snmp
   &#160;<span id="projectnumber">5.4.1</span>
   </div>
   
  </td>
  
  
  
 </tr>
 </tbody>
</table>
</div>

<!-- Generated by Doxygen 1.7.6.1 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
      <li><a href="examples.html"><span>Examples</span></a></li>
    </ul>
  </div>
  <div id="navrow2" class="tabs2">
    <ul class="tablist">
      <li><a href="files.html"><span>File&#160;List</span></a></li>
      <li><a href="globals.html"><span>Globals</span></a></li>
    </ul>
  </div>
</div>
<div class="header">
  <div class="headertitle">
<div class="title">snmpUDPDomain.c</div>  </div>
</div><!--header-->
<div class="contents">
<div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/* Portions of this file are subject to the following copyright(s).  See</span>
<a name="l00002"></a>00002 <span class="comment"> * the Net-SNMP&#39;s COPYING file for more details and other copyrights</span>
<a name="l00003"></a>00003 <span class="comment"> * that may apply:</span>
<a name="l00004"></a>00004 <span class="comment"> */</span>
<a name="l00005"></a>00005 <span class="comment">/*</span>
<a name="l00006"></a>00006 <span class="comment"> * Portions of this file are copyrighted by:</span>
<a name="l00007"></a>00007 <span class="comment"> * Copyright Copyright 2003 Sun Microsystems, Inc. All rights reserved.</span>
<a name="l00008"></a>00008 <span class="comment"> * Use is subject to license terms specified in the COPYING file</span>
<a name="l00009"></a>00009 <span class="comment"> * distributed with the Net-SNMP package.</span>
<a name="l00010"></a>00010 <span class="comment"> */</span>
<a name="l00011"></a>00011 
<a name="l00012"></a>00012 <span class="preprocessor">#include &lt;net-snmp/net-snmp-config.h&gt;</span>
<a name="l00013"></a>00013 
<a name="l00014"></a>00014 <span class="preprocessor">#include &lt;stdio.h&gt;</span>
<a name="l00015"></a>00015 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
<a name="l00016"></a>00016 <span class="preprocessor">#include &lt;ctype.h&gt;</span>
<a name="l00017"></a>00017 <span class="preprocessor">#include &lt;errno.h&gt;</span>
<a name="l00018"></a>00018 
<a name="l00019"></a>00019 <span class="preprocessor">#if HAVE_STRING_H</span>
<a name="l00020"></a>00020 <span class="preprocessor"></span><span class="preprocessor">#include &lt;string.h&gt;</span>
<a name="l00021"></a>00021 <span class="preprocessor">#else</span>
<a name="l00022"></a>00022 <span class="preprocessor"></span><span class="preprocessor">#include &lt;strings.h&gt;</span>
<a name="l00023"></a>00023 <span class="preprocessor">#endif</span>
<a name="l00024"></a>00024 <span class="preprocessor"></span><span class="preprocessor">#if HAVE_STDLIB_H</span>
<a name="l00025"></a>00025 <span class="preprocessor"></span><span class="preprocessor">#include &lt;stdlib.h&gt;</span>
<a name="l00026"></a>00026 <span class="preprocessor">#endif</span>
<a name="l00027"></a>00027 <span class="preprocessor"></span><span class="preprocessor">#if HAVE_UNISTD_H</span>
<a name="l00028"></a>00028 <span class="preprocessor"></span><span class="preprocessor">#include &lt;unistd.h&gt;</span>
<a name="l00029"></a>00029 <span class="preprocessor">#endif</span>
<a name="l00030"></a>00030 <span class="preprocessor"></span><span class="preprocessor">#if HAVE_SYS_SOCKET_H</span>
<a name="l00031"></a>00031 <span class="preprocessor"></span><span class="preprocessor">#include &lt;sys/socket.h&gt;</span>
<a name="l00032"></a>00032 <span class="preprocessor">#endif</span>
<a name="l00033"></a>00033 <span class="preprocessor"></span><span class="preprocessor">#if HAVE_NETINET_IN_H</span>
<a name="l00034"></a>00034 <span class="preprocessor"></span><span class="preprocessor">#include &lt;netinet/in.h&gt;</span>
<a name="l00035"></a>00035 <span class="preprocessor">#endif</span>
<a name="l00036"></a>00036 <span class="preprocessor"></span><span class="preprocessor">#if HAVE_ARPA_INET_H</span>
<a name="l00037"></a>00037 <span class="preprocessor"></span><span class="preprocessor">#include &lt;arpa/inet.h&gt;</span>
<a name="l00038"></a>00038 <span class="preprocessor">#endif</span>
<a name="l00039"></a>00039 <span class="preprocessor"></span><span class="preprocessor">#if HAVE_NETDB_H</span>
<a name="l00040"></a>00040 <span class="preprocessor"></span><span class="preprocessor">#include &lt;netdb.h&gt;</span>
<a name="l00041"></a>00041 <span class="preprocessor">#endif</span>
<a name="l00042"></a>00042 <span class="preprocessor"></span><span class="preprocessor">#if HAVE_SYS_UIO_H</span>
<a name="l00043"></a>00043 <span class="preprocessor"></span><span class="preprocessor">#include &lt;sys/uio.h&gt;</span>
<a name="l00044"></a>00044 <span class="preprocessor">#endif</span>
<a name="l00045"></a>00045 <span class="preprocessor"></span>
<a name="l00046"></a>00046 <span class="preprocessor">#if HAVE_WINSOCK_H</span>
<a name="l00047"></a>00047 <span class="preprocessor"></span><span class="preprocessor">#include &lt;winsock2.h&gt;</span>
<a name="l00048"></a>00048 <span class="preprocessor">#include &lt;ws2tcpip.h&gt;</span>
<a name="l00049"></a>00049 <span class="preprocessor">#endif</span>
<a name="l00050"></a>00050 <span class="preprocessor"></span>
<a name="l00051"></a>00051 <span class="preprocessor">#if HAVE_DMALLOC_H</span>
<a name="l00052"></a>00052 <span class="preprocessor"></span><span class="preprocessor">#include &lt;dmalloc.h&gt;</span>
<a name="l00053"></a>00053 <span class="preprocessor">#endif</span>
<a name="l00054"></a>00054 <span class="preprocessor"></span>
<a name="l00055"></a>00055 <span class="preprocessor">#include &lt;net-snmp/types.h&gt;</span>
<a name="l00056"></a>00056 <span class="preprocessor">#include &lt;net-snmp/output_api.h&gt;</span>
<a name="l00057"></a>00057 <span class="preprocessor">#include &lt;net-snmp/config_api.h&gt;</span>
<a name="l00058"></a>00058 
<a name="l00059"></a>00059 <span class="preprocessor">#include &lt;net-snmp/library/snmp_transport.h&gt;</span>
<a name="l00060"></a>00060 <span class="preprocessor">#include &lt;net-snmp/library/snmpUDPDomain.h&gt;</span>
<a name="l00061"></a>00061 <span class="preprocessor">#include &lt;net-snmp/library/system.h&gt;</span>
<a name="l00062"></a>00062 <span class="preprocessor">#include &lt;<a class="code" href="tools_8h.html">net-snmp/library/tools.h</a>&gt;</span>
<a name="l00063"></a>00063 
<a name="l00064"></a>00064 <span class="preprocessor">#ifndef INADDR_NONE</span>
<a name="l00065"></a>00065 <span class="preprocessor"></span><span class="preprocessor">#define INADDR_NONE     -1</span>
<a name="l00066"></a>00066 <span class="preprocessor"></span><span class="preprocessor">#endif</span>
<a name="l00067"></a>00067 <span class="preprocessor"></span>
<a name="l00068"></a>00068 <span class="keyword">static</span> <a class="code" href="structnetsnmp__tdomain__s.html">netsnmp_tdomain</a> udpDomain;
<a name="l00069"></a>00069 
<a name="l00070"></a>00070 <span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair_s</a> {
<a name="l00071"></a>00071     <span class="keyword">struct </span>sockaddr_in remote_addr;
<a name="l00072"></a>00072     <span class="keyword">struct </span>in_addr local_addr;
<a name="l00073"></a>00073 } <a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>;
<a name="l00074"></a>00074 
<a name="l00075"></a>00075 <span class="comment">/*</span>
<a name="l00076"></a>00076 <span class="comment"> * not static, since snmpUDPIPv6Domain needs it, but not public, either.</span>
<a name="l00077"></a>00077 <span class="comment"> * (ie don&#39;t put it in a public header.)</span>
<a name="l00078"></a>00078 <span class="comment"> */</span>
<a name="l00079"></a>00079 <span class="keywordtype">void</span> _netsnmp_udp_sockopt_set(<span class="keywordtype">int</span> fd, <span class="keywordtype">int</span> server);
<a name="l00080"></a>00080 <span class="keywordtype">int</span>
<a name="l00081"></a>00081 netsnmp_sockaddr_in2(<span class="keyword">struct</span> sockaddr_in *addr,
<a name="l00082"></a>00082                      <span class="keyword">const</span> <span class="keywordtype">char</span> *inpeername, <span class="keyword">const</span> <span class="keywordtype">char</span> *default_target);
<a name="l00083"></a>00083 
<a name="l00084"></a>00084 <span class="comment">/*</span>
<a name="l00085"></a>00085 <span class="comment"> * Return a string representing the address in data, or else the &quot;far end&quot;</span>
<a name="l00086"></a>00086 <span class="comment"> * address if data is NULL.  </span>
<a name="l00087"></a>00087 <span class="comment"> */</span>
<a name="l00088"></a>00088 
<a name="l00089"></a>00089 <span class="keyword">static</span> <span class="keywordtype">char</span> *
<a name="l00090"></a>00090 netsnmp_udp_fmtaddr(<a class="code" href="structnetsnmp__transport__s.html">netsnmp_transport</a> *t, <span class="keywordtype">void</span> *data, <span class="keywordtype">int</span> len)
<a name="l00091"></a>00091 {
<a name="l00092"></a>00092     <a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a> *addr_pair = NULL;
<a name="l00093"></a>00093 
<a name="l00094"></a>00094     <span class="keywordflow">if</span> (data != NULL &amp;&amp; len == <span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>)) {
<a name="l00095"></a>00095         addr_pair = (<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a> *) data;
<a name="l00096"></a>00096     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (t != NULL &amp;&amp; t-&gt;data != NULL) {
<a name="l00097"></a>00097         addr_pair = (<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a> *) t-&gt;data;
<a name="l00098"></a>00098     }
<a name="l00099"></a>00099 
<a name="l00100"></a>00100     <span class="keywordflow">if</span> (addr_pair == NULL) {
<a name="l00101"></a>00101         <span class="keywordflow">return</span> strdup(<span class="stringliteral">&quot;UDP: unknown&quot;</span>);
<a name="l00102"></a>00102     } <span class="keywordflow">else</span> {
<a name="l00103"></a>00103         <span class="keyword">struct </span>sockaddr_in *to = NULL;
<a name="l00104"></a>00104         <span class="keywordtype">char</span> tmp[64];
<a name="l00105"></a>00105         to = (<span class="keyword">struct </span>sockaddr_in *) &amp;(addr_pair-&gt;remote_addr);
<a name="l00106"></a>00106         <span class="keywordflow">if</span> (to == NULL) {
<a name="l00107"></a>00107             <span class="keywordflow">return</span> strdup(<span class="stringliteral">&quot;UDP: unknown&quot;</span>);
<a name="l00108"></a>00108         }
<a name="l00109"></a>00109 
<a name="l00110"></a>00110         sprintf(tmp, <span class="stringliteral">&quot;UDP: [%s]:%hu&quot;</span>,
<a name="l00111"></a>00111                 inet_ntoa(to-&gt;sin_addr), ntohs(to-&gt;sin_port));
<a name="l00112"></a>00112         <span class="keywordflow">return</span> strdup(tmp);
<a name="l00113"></a>00113     }
<a name="l00114"></a>00114 }
<a name="l00115"></a>00115 
<a name="l00116"></a>00116 
<a name="l00117"></a>00117 
<a name="l00118"></a>00118 <span class="preprocessor">#if defined(linux) &amp;&amp; defined(IP_PKTINFO)</span>
<a name="l00119"></a>00119 <span class="preprocessor"></span>
<a name="l00120"></a>00120 <span class="preprocessor"># define netsnmp_dstaddr(x) (&amp;(((struct in_pktinfo *)(CMSG_DATA(x)))-&gt;ipi_addr))</span>
<a name="l00121"></a>00121 <span class="preprocessor"></span>
<a name="l00122"></a>00122 <span class="keyword">static</span> <span class="keywordtype">int</span> netsnmp_udp_recvfrom(<span class="keywordtype">int</span> s, <span class="keywordtype">void</span> *buf, <span class="keywordtype">int</span> len, <span class="keyword">struct</span> sockaddr *from, socklen_t *fromlen, <span class="keyword">struct</span> in_addr *dstip)
<a name="l00123"></a>00123 {
<a name="l00124"></a>00124     <span class="keywordtype">int</span> r;
<a name="l00125"></a>00125     <span class="keyword">struct </span>iovec iov[1];
<a name="l00126"></a>00126     <span class="keywordtype">char</span> cmsg[CMSG_SPACE(<span class="keyword">sizeof</span>(<span class="keyword">struct</span> in_pktinfo))];
<a name="l00127"></a>00127     <span class="keyword">struct </span>cmsghdr *cmsgptr;
<a name="l00128"></a>00128     <span class="keyword">struct </span>msghdr msg;
<a name="l00129"></a>00129 
<a name="l00130"></a>00130     iov[0].iov_base = buf;
<a name="l00131"></a>00131     iov[0].iov_len = len;
<a name="l00132"></a>00132 
<a name="l00133"></a>00133     memset(&amp;msg, 0, <span class="keyword">sizeof</span> msg);
<a name="l00134"></a>00134     msg.msg_name = from;
<a name="l00135"></a>00135     msg.msg_namelen = *fromlen;
<a name="l00136"></a>00136     msg.msg_iov = iov;
<a name="l00137"></a>00137     msg.msg_iovlen = 1;
<a name="l00138"></a>00138     msg.msg_control = &amp;cmsg;
<a name="l00139"></a>00139     msg.msg_controllen = <span class="keyword">sizeof</span>(cmsg);
<a name="l00140"></a>00140 
<a name="l00141"></a>00141     r = recvmsg(s, &amp;msg, 0);
<a name="l00142"></a>00142 
<a name="l00143"></a>00143     <span class="keywordflow">if</span> (r == -1) {
<a name="l00144"></a>00144         <span class="keywordflow">return</span> -1;
<a name="l00145"></a>00145     }
<a name="l00146"></a>00146     
<a name="l00147"></a>00147     DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp&quot;</span>, <span class="stringliteral">&quot;got source addr: %s\n&quot;</span>, inet_ntoa(((<span class="keyword">struct</span> sockaddr_in *)from)-&gt;sin_addr)));
<a name="l00148"></a>00148     <span class="keywordflow">for</span> (cmsgptr = CMSG_FIRSTHDR(&amp;msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&amp;msg, cmsgptr)) {
<a name="l00149"></a>00149         <span class="keywordflow">if</span> (cmsgptr-&gt;cmsg_level == SOL_IP &amp;&amp; cmsgptr-&gt;cmsg_type == IP_PKTINFO) {
<a name="l00150"></a>00150             memcpy((<span class="keywordtype">void</span> *) dstip, netsnmp_dstaddr(cmsgptr), <span class="keyword">sizeof</span>(<span class="keyword">struct</span> in_addr));
<a name="l00151"></a>00151             DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp&quot;</span>, <span class="stringliteral">&quot;got destination (local) addr %s\n&quot;</span>,
<a name="l00152"></a>00152                     inet_ntoa(*dstip)));
<a name="l00153"></a>00153         }
<a name="l00154"></a>00154     }
<a name="l00155"></a>00155     <span class="keywordflow">return</span> r;
<a name="l00156"></a>00156 }
<a name="l00157"></a>00157 
<a name="l00158"></a>00158 <span class="keyword">static</span> <span class="keywordtype">int</span> netsnmp_udp_sendto(<span class="keywordtype">int</span> fd, <span class="keyword">struct</span> in_addr *srcip, <span class="keyword">struct</span> sockaddr *remote,
<a name="l00159"></a>00159                         <span class="keywordtype">void</span> *data, <span class="keywordtype">int</span> len)
<a name="l00160"></a>00160 {
<a name="l00161"></a>00161     <span class="keyword">struct </span>iovec iov = { data, len };
<a name="l00162"></a>00162     <span class="keyword">struct </span>{
<a name="l00163"></a>00163         <span class="keyword">struct </span>cmsghdr cm;
<a name="l00164"></a>00164         <span class="keyword">struct </span>in_pktinfo ipi;
<a name="l00165"></a>00165     } cmsg;
<a name="l00166"></a>00166     <span class="keyword">struct </span>msghdr m;
<a name="l00167"></a>00167 
<a name="l00168"></a>00168     cmsg.cm.cmsg_len = <span class="keyword">sizeof</span>(<span class="keyword">struct </span>cmsghdr) + sizeof(struct in_pktinfo);
<a name="l00169"></a>00169     cmsg.cm.cmsg_level = SOL_IP;
<a name="l00170"></a>00170     cmsg.cm.cmsg_type = IP_PKTINFO;
<a name="l00171"></a>00171     cmsg.ipi.ipi_ifindex = 0;
<a name="l00172"></a>00172     cmsg.ipi.ipi_spec_dst.s_addr = (srcip ? srcip-&gt;s_addr : INADDR_ANY);
<a name="l00173"></a>00173 
<a name="l00174"></a>00174     m.msg_name          = remote;
<a name="l00175"></a>00175     m.msg_namelen       = <span class="keyword">sizeof</span>(<span class="keyword">struct </span>sockaddr_in);
<a name="l00176"></a>00176     m.msg_iov           = &amp;iov;
<a name="l00177"></a>00177     m.msg_iovlen        = 1;
<a name="l00178"></a>00178     m.msg_control       = &amp;cmsg;
<a name="l00179"></a>00179     m.msg_controllen    = <span class="keyword">sizeof</span>(cmsg);
<a name="l00180"></a>00180     m.msg_flags         = 0;
<a name="l00181"></a>00181 
<a name="l00182"></a>00182     <span class="keywordflow">return</span> sendmsg(fd, &amp;m, MSG_NOSIGNAL|MSG_DONTWAIT);
<a name="l00183"></a>00183 }
<a name="l00184"></a>00184 <span class="preprocessor">#endif </span><span class="comment">/* linux &amp;&amp; IP_PKTINFO */</span>
<a name="l00185"></a>00185 
<a name="l00186"></a>00186 <span class="comment">/*</span>
<a name="l00187"></a>00187 <span class="comment"> * You can write something into opaque that will subsequently get passed back </span>
<a name="l00188"></a>00188 <span class="comment"> * to your send function if you like.  For instance, you might want to</span>
<a name="l00189"></a>00189 <span class="comment"> * remember where a PDU came from, so that you can send a reply there...  </span>
<a name="l00190"></a>00190 <span class="comment"> */</span>
<a name="l00191"></a>00191 
<a name="l00192"></a>00192 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00193"></a>00193 netsnmp_udp_recv(<a class="code" href="structnetsnmp__transport__s.html">netsnmp_transport</a> *t, <span class="keywordtype">void</span> *buf, <span class="keywordtype">int</span> size,
<a name="l00194"></a>00194                  <span class="keywordtype">void</span> **opaque, <span class="keywordtype">int</span> *olength)
<a name="l00195"></a>00195 {
<a name="l00196"></a>00196     <span class="keywordtype">int</span>             rc = -1;
<a name="l00197"></a>00197     socklen_t       fromlen = <span class="keyword">sizeof</span>(<span class="keyword">struct </span>sockaddr);
<a name="l00198"></a>00198     <a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a> *addr_pair = NULL;
<a name="l00199"></a>00199     <span class="keyword">struct </span>sockaddr *from;
<a name="l00200"></a>00200 
<a name="l00201"></a>00201     <span class="keywordflow">if</span> (t != NULL &amp;&amp; t-&gt;sock &gt;= 0) {
<a name="l00202"></a>00202         addr_pair = (<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a> *) malloc(<span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>));
<a name="l00203"></a>00203         <span class="keywordflow">if</span> (addr_pair == NULL) {
<a name="l00204"></a>00204             *opaque = NULL;
<a name="l00205"></a>00205             *olength = 0;
<a name="l00206"></a>00206             <span class="keywordflow">return</span> -1;
<a name="l00207"></a>00207         } <span class="keywordflow">else</span> {
<a name="l00208"></a>00208             memset(addr_pair, 0, <span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>));
<a name="l00209"></a>00209             from = (<span class="keyword">struct </span>sockaddr *) &amp;(addr_pair-&gt;remote_addr);
<a name="l00210"></a>00210         }
<a name="l00211"></a>00211 
<a name="l00212"></a>00212         <span class="keywordflow">while</span> (rc &lt; 0) {
<a name="l00213"></a>00213 <span class="preprocessor">#if defined(linux) &amp;&amp; defined(IP_PKTINFO)</span>
<a name="l00214"></a>00214 <span class="preprocessor"></span>            rc = netsnmp_udp_recvfrom(t-&gt;sock, buf, size, from, &amp;fromlen, &amp;(addr_pair-&gt;local_addr));
<a name="l00215"></a>00215 <span class="preprocessor">#else</span>
<a name="l00216"></a>00216 <span class="preprocessor"></span>            rc = recvfrom(t-&gt;sock, buf, size, 0, from, &amp;fromlen);
<a name="l00217"></a>00217 <span class="preprocessor">#endif </span><span class="comment">/* linux &amp;&amp; IP_PKTINFO */</span>
<a name="l00218"></a>00218             <span class="keywordflow">if</span> (rc &lt; 0 &amp;&amp; errno != EINTR) {
<a name="l00219"></a>00219                 <span class="keywordflow">break</span>;
<a name="l00220"></a>00220             }
<a name="l00221"></a>00221         }
<a name="l00222"></a>00222 
<a name="l00223"></a>00223         <span class="keywordflow">if</span> (rc &gt;= 0) {
<a name="l00224"></a>00224             <span class="keywordtype">char</span> *str = netsnmp_udp_fmtaddr(NULL, addr_pair, <span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>));
<a name="l00225"></a>00225             DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp&quot;</span>,
<a name="l00226"></a>00226                         <span class="stringliteral">&quot;recvfrom fd %d got %d bytes (from %s)\n&quot;</span>,
<a name="l00227"></a>00227                         t-&gt;sock, rc, str));
<a name="l00228"></a>00228             free(str);
<a name="l00229"></a>00229         } <span class="keywordflow">else</span> {
<a name="l00230"></a>00230             DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp&quot;</span>, <span class="stringliteral">&quot;recvfrom fd %d err %d (\&quot;%s\&quot;)\n&quot;</span>,
<a name="l00231"></a>00231                         t-&gt;sock, errno, strerror(errno)));
<a name="l00232"></a>00232         }
<a name="l00233"></a>00233         *opaque = (<span class="keywordtype">void</span> *)addr_pair;
<a name="l00234"></a>00234         *olength = <span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>);
<a name="l00235"></a>00235     }
<a name="l00236"></a>00236     <span class="keywordflow">return</span> rc;
<a name="l00237"></a>00237 }
<a name="l00238"></a>00238 
<a name="l00239"></a>00239 
<a name="l00240"></a>00240 
<a name="l00241"></a>00241 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00242"></a>00242 netsnmp_udp_send(<a class="code" href="structnetsnmp__transport__s.html">netsnmp_transport</a> *t, <span class="keywordtype">void</span> *buf, <span class="keywordtype">int</span> size,
<a name="l00243"></a>00243                  <span class="keywordtype">void</span> **opaque, <span class="keywordtype">int</span> *olength)
<a name="l00244"></a>00244 {
<a name="l00245"></a>00245     <span class="keywordtype">int</span> rc = -1;
<a name="l00246"></a>00246     <a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a> *addr_pair = NULL;
<a name="l00247"></a>00247     <span class="keyword">struct </span>sockaddr *to = NULL;
<a name="l00248"></a>00248 
<a name="l00249"></a>00249     <span class="keywordflow">if</span> (opaque != NULL &amp;&amp; *opaque != NULL &amp;&amp;
<a name="l00250"></a>00250         *olength == <span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>)) {
<a name="l00251"></a>00251         addr_pair = (<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a> *) (*opaque);
<a name="l00252"></a>00252     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (t != NULL &amp;&amp; t-&gt;data != NULL &amp;&amp;
<a name="l00253"></a>00253                 t-&gt;data_length == <span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>)) {
<a name="l00254"></a>00254         addr_pair = (<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a> *) (t-&gt;data);
<a name="l00255"></a>00255     }
<a name="l00256"></a>00256 
<a name="l00257"></a>00257     to = (<span class="keyword">struct </span>sockaddr *) &amp;(addr_pair-&gt;remote_addr);
<a name="l00258"></a>00258 
<a name="l00259"></a>00259     <span class="keywordflow">if</span> (to != NULL &amp;&amp; t != NULL &amp;&amp; t-&gt;sock &gt;= 0) {
<a name="l00260"></a>00260         <span class="keywordtype">char</span> *str = netsnmp_udp_fmtaddr(NULL, (<span class="keywordtype">void</span> *) addr_pair,
<a name="l00261"></a>00261                                         <span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>));
<a name="l00262"></a>00262         DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp&quot;</span>, <span class="stringliteral">&quot;send %d bytes from %p to %s on fd %d\n&quot;</span>,
<a name="l00263"></a>00263                     size, buf, str, t-&gt;sock));
<a name="l00264"></a>00264         free(str);
<a name="l00265"></a>00265         <span class="keywordflow">while</span> (rc &lt; 0) {
<a name="l00266"></a>00266 <span class="preprocessor">#if defined(linux) &amp;&amp; defined(IP_PKTINFO)</span>
<a name="l00267"></a>00267 <span class="preprocessor"></span>            rc = netsnmp_udp_sendto(t-&gt;sock, addr_pair ? &amp;(addr_pair-&gt;local_addr) : NULL, to, buf, size);
<a name="l00268"></a>00268 <span class="preprocessor">#else</span>
<a name="l00269"></a>00269 <span class="preprocessor"></span>            rc = sendto(t-&gt;sock, buf, size, 0, to, <span class="keyword">sizeof</span>(<span class="keyword">struct</span> sockaddr));
<a name="l00270"></a>00270 <span class="preprocessor">#endif </span><span class="comment">/* linux &amp;&amp; IP_PKTINFO */</span>
<a name="l00271"></a>00271             <span class="keywordflow">if</span> (rc &lt; 0 &amp;&amp; errno != EINTR) {
<a name="l00272"></a>00272                 DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp&quot;</span>, <span class="stringliteral">&quot;sendto error, rc %d (errno %d)\n&quot;</span>,
<a name="l00273"></a>00273                             rc, errno));
<a name="l00274"></a>00274                 <span class="keywordflow">break</span>;
<a name="l00275"></a>00275             }
<a name="l00276"></a>00276         }
<a name="l00277"></a>00277     }
<a name="l00278"></a>00278     <span class="keywordflow">return</span> rc;
<a name="l00279"></a>00279 }
<a name="l00280"></a>00280 
<a name="l00281"></a>00281 
<a name="l00282"></a>00282 
<a name="l00283"></a>00283 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00284"></a>00284 netsnmp_udp_close(<a class="code" href="structnetsnmp__transport__s.html">netsnmp_transport</a> *t)
<a name="l00285"></a>00285 {
<a name="l00286"></a>00286     <span class="keywordtype">int</span> rc = -1;
<a name="l00287"></a>00287     <span class="keywordflow">if</span> (t-&gt;sock &gt;= 0) {
<a name="l00288"></a>00288 <span class="preprocessor">#ifndef HAVE_CLOSESOCKET</span>
<a name="l00289"></a>00289 <span class="preprocessor"></span>        rc = close(t-&gt;sock);
<a name="l00290"></a>00290 <span class="preprocessor">#else</span>
<a name="l00291"></a>00291 <span class="preprocessor"></span>        rc = closesocket(t-&gt;sock);
<a name="l00292"></a>00292 <span class="preprocessor">#endif</span>
<a name="l00293"></a>00293 <span class="preprocessor"></span>        t-&gt;sock = -1;
<a name="l00294"></a>00294     }
<a name="l00295"></a>00295     <span class="keywordflow">return</span> rc;
<a name="l00296"></a>00296 }
<a name="l00297"></a>00297 
<a name="l00298"></a>00298 <span class="comment">/*</span>
<a name="l00299"></a>00299 <span class="comment"> * find largest possible buffer between current size and specified size.</span>
<a name="l00300"></a>00300 <span class="comment"> *</span>
<a name="l00301"></a>00301 <span class="comment"> * Try to maximize the current buffer of type &quot;optname&quot;</span>
<a name="l00302"></a>00302 <span class="comment"> * to the maximum allowable size by the OS (as close to</span>
<a name="l00303"></a>00303 <span class="comment"> * size as possible)</span>
<a name="l00304"></a>00304 <span class="comment"> */</span>
<a name="l00305"></a>00305 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00306"></a>00306 _sock_buffer_maximize(<span class="keywordtype">int</span> s, <span class="keywordtype">int</span> optname, <span class="keyword">const</span> <span class="keywordtype">char</span> *buftype, <span class="keywordtype">int</span> size)
<a name="l00307"></a>00307 {
<a name="l00308"></a>00308     <span class="keywordtype">int</span>            curbuf = 0;
<a name="l00309"></a>00309     <span class="keywordtype">size_t</span>         curbuflen = <span class="keyword">sizeof</span>(int);
<a name="l00310"></a>00310     <span class="keywordtype">int</span>            lo, mid, hi;
<a name="l00311"></a>00311 
<a name="l00312"></a>00312     <span class="comment">/*</span>
<a name="l00313"></a>00313 <span class="comment">     * First we need to determine our current buffer</span>
<a name="l00314"></a>00314 <span class="comment">     */</span>
<a name="l00315"></a>00315     <span class="keywordflow">if</span> ((getsockopt(s, SOL_SOCKET, optname, (<span class="keywordtype">void</span> *) &amp;curbuf,
<a name="l00316"></a>00316                     &amp;curbuflen) == 0) 
<a name="l00317"></a>00317             &amp;&amp; (curbuflen == <span class="keyword">sizeof</span>(int))) {
<a name="l00318"></a>00318 
<a name="l00319"></a>00319         DEBUGMSGTL((<span class="stringliteral">&quot;verbose:socket:buffer:max&quot;</span>, <span class="stringliteral">&quot;Current %s is %d\n&quot;</span>,
<a name="l00320"></a>00320                     buftype, curbuf));
<a name="l00321"></a>00321 
<a name="l00322"></a>00322         <span class="comment">/*</span>
<a name="l00323"></a>00323 <span class="comment">         * Let&#39;s not be stupid ... if we were asked for less than what we</span>
<a name="l00324"></a>00324 <span class="comment">         * already have, then forget about it</span>
<a name="l00325"></a>00325 <span class="comment">         */</span>
<a name="l00326"></a>00326         <span class="keywordflow">if</span> (size &lt;= curbuf) {
<a name="l00327"></a>00327             DEBUGMSGTL((<span class="stringliteral">&quot;verbose:socket:buffer:max&quot;</span>,
<a name="l00328"></a>00328                         <span class="stringliteral">&quot;Requested %s &lt;= current buffer\n&quot;</span>, buftype));
<a name="l00329"></a>00329             <span class="keywordflow">return</span> curbuf;
<a name="l00330"></a>00330         }
<a name="l00331"></a>00331 
<a name="l00332"></a>00332         <span class="comment">/*</span>
<a name="l00333"></a>00333 <span class="comment">         * Do a binary search the optimal buffer within 1k of the point of</span>
<a name="l00334"></a>00334 <span class="comment">         * failure. This is rather bruteforce, but simple</span>
<a name="l00335"></a>00335 <span class="comment">         */</span>
<a name="l00336"></a>00336         hi = size;
<a name="l00337"></a>00337         lo = curbuf;
<a name="l00338"></a>00338 
<a name="l00339"></a>00339         <span class="keywordflow">while</span> (hi - lo &gt; 1024) {
<a name="l00340"></a>00340             mid = (lo + hi) / 2;
<a name="l00341"></a>00341             <span class="keywordflow">if</span> (setsockopt(s, SOL_SOCKET, optname, (<span class="keywordtype">void</span> *) &amp;mid,
<a name="l00342"></a>00342                         <span class="keyword">sizeof</span>(<span class="keywordtype">int</span>)) == 0) {
<a name="l00343"></a>00343                 lo = mid; <span class="comment">/* Success: search between mid and hi */</span>
<a name="l00344"></a>00344             } <span class="keywordflow">else</span> {
<a name="l00345"></a>00345                 hi = mid; <span class="comment">/* Failed: search between lo and mid */</span>
<a name="l00346"></a>00346             }
<a name="l00347"></a>00347         }
<a name="l00348"></a>00348 
<a name="l00349"></a>00349         <span class="comment">/*</span>
<a name="l00350"></a>00350 <span class="comment">         * Now print if this optimization helped or not</span>
<a name="l00351"></a>00351 <span class="comment">         */</span>
<a name="l00352"></a>00352         <span class="keywordflow">if</span> (getsockopt(s,SOL_SOCKET, optname, (<span class="keywordtype">void</span> *) &amp;curbuf,
<a name="l00353"></a>00353                     &amp;curbuflen) == 0) {
<a name="l00354"></a>00354             DEBUGMSGTL((<span class="stringliteral">&quot;socket:buffer:max&quot;</span>, 
<a name="l00355"></a>00355                         <span class="stringliteral">&quot;Maximized %s: %d\n&quot;</span>,buftype, curbuf));
<a name="l00356"></a>00356         } 
<a name="l00357"></a>00357     } <span class="keywordflow">else</span> {
<a name="l00358"></a>00358         <span class="comment">/*</span>
<a name="l00359"></a>00359 <span class="comment">         * There is really not a lot we can do anymore.</span>
<a name="l00360"></a>00360 <span class="comment">         * If the OS doesn&#39;t give us the current buffer, then what&#39;s the </span>
<a name="l00361"></a>00361 <span class="comment">         * point in trying to make it better</span>
<a name="l00362"></a>00362 <span class="comment">         */</span>
<a name="l00363"></a>00363         DEBUGMSGTL((<span class="stringliteral">&quot;socket:buffer:max&quot;</span>, <span class="stringliteral">&quot;Get %s failed ... giving up!\n&quot;</span>,
<a name="l00364"></a>00364                     buftype));
<a name="l00365"></a>00365         curbuf = -1;
<a name="l00366"></a>00366     }
<a name="l00367"></a>00367 
<a name="l00368"></a>00368     <span class="keywordflow">return</span> curbuf;
<a name="l00369"></a>00369 }
<a name="l00370"></a>00370 
<a name="l00371"></a>00371 
<a name="l00372"></a>00372 <span class="keyword">static</span> <span class="keyword">const</span> <span class="keywordtype">char</span> *
<a name="l00373"></a>00373 _sock_buf_type_get(<span class="keywordtype">int</span> optname, <span class="keywordtype">int</span> local)
<a name="l00374"></a>00374 {
<a name="l00375"></a>00375     <span class="keywordflow">if</span> (optname == SO_SNDBUF) {
<a name="l00376"></a>00376         <span class="keywordflow">if</span> (local)
<a name="l00377"></a>00377             <span class="keywordflow">return</span> <span class="stringliteral">&quot;server send buffer&quot;</span>;
<a name="l00378"></a>00378         <span class="keywordflow">else</span>
<a name="l00379"></a>00379             <span class="keywordflow">return</span> <span class="stringliteral">&quot;client send buffer&quot;</span>;
<a name="l00380"></a>00380     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (optname == SO_RCVBUF) {
<a name="l00381"></a>00381         <span class="keywordflow">if</span> (local)
<a name="l00382"></a>00382             <span class="keywordflow">return</span> <span class="stringliteral">&quot;server receive buffer&quot;</span>;
<a name="l00383"></a>00383         <span class="keywordflow">else</span>
<a name="l00384"></a>00384             <span class="keywordflow">return</span> <span class="stringliteral">&quot;client receive buffer&quot;</span>;
<a name="l00385"></a>00385     }
<a name="l00386"></a>00386 
<a name="l00387"></a>00387     <span class="keywordflow">return</span> <span class="stringliteral">&quot;unknown buffer&quot;</span>;
<a name="l00388"></a>00388 }
<a name="l00389"></a>00389 
<a name="l00390"></a>00390 <span class="comment">/*</span>
<a name="l00391"></a>00391 <span class="comment"> *</span>
<a name="l00392"></a>00392 <span class="comment"> * Get the requested buffersize, based on</span>
<a name="l00393"></a>00393 <span class="comment"> * - sockettype : client (local = 0) or server (local = 1) </span>
<a name="l00394"></a>00394 <span class="comment"> * - buffertype : send (optname = SO_SNDBUF) or recv (SO_RCVBUF)</span>
<a name="l00395"></a>00395 <span class="comment"> *</span>
<a name="l00396"></a>00396 <span class="comment"> * In case a compile time buffer was specified, then use that one</span>
<a name="l00397"></a>00397 <span class="comment"> * if there was no runtime configuration override</span>
<a name="l00398"></a>00398 <span class="comment"> */</span>
<a name="l00399"></a>00399 <span class="keyword">static</span> <span class="keywordtype">int</span>
<a name="l00400"></a>00400 _sock_buffer_size_get(<span class="keywordtype">int</span> optname, <span class="keywordtype">int</span> local, <span class="keyword">const</span> <span class="keywordtype">char</span> **buftype)
<a name="l00401"></a>00401 {
<a name="l00402"></a>00402     <span class="keywordtype">int</span> size;
<a name="l00403"></a>00403 
<a name="l00404"></a>00404     <span class="keywordflow">if</span> (NULL != buftype)
<a name="l00405"></a>00405         *buftype = _sock_buf_type_get(optname, local);
<a name="l00406"></a>00406 
<a name="l00407"></a>00407     <span class="keywordflow">if</span> (optname == SO_SNDBUF) {
<a name="l00408"></a>00408         <span class="keywordflow">if</span> (local) {
<a name="l00409"></a>00409             size = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, 
<a name="l00410"></a>00410                     NETSNMP_DS_LIB_SERVERSENDBUF);
<a name="l00411"></a>00411 <span class="preprocessor">#ifdef NETSNMP_DEFAULT_SERVER_SEND_BUF</span>
<a name="l00412"></a>00412 <span class="preprocessor"></span>            <span class="keywordflow">if</span> (size &lt;= 0)
<a name="l00413"></a>00413                size = NETSNMP_DEFAULT_SERVER_SEND_BUF;
<a name="l00414"></a>00414 <span class="preprocessor">#endif</span>
<a name="l00415"></a>00415 <span class="preprocessor"></span>        } <span class="keywordflow">else</span> {
<a name="l00416"></a>00416             size = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, 
<a name="l00417"></a>00417                     NETSNMP_DS_LIB_CLIENTSENDBUF);
<a name="l00418"></a>00418 <span class="preprocessor">#ifdef NETSNMP_DEFAULT_CLIENT_SEND_BUF</span>
<a name="l00419"></a>00419 <span class="preprocessor"></span>            <span class="keywordflow">if</span> (size &lt;= 0)
<a name="l00420"></a>00420                size = NETSNMP_DEFAULT_CLIENT_SEND_BUF;
<a name="l00421"></a>00421 <span class="preprocessor">#endif</span>
<a name="l00422"></a>00422 <span class="preprocessor"></span>        }
<a name="l00423"></a>00423     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (optname == SO_RCVBUF) {
<a name="l00424"></a>00424         <span class="keywordflow">if</span> (local) {
<a name="l00425"></a>00425             size = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, 
<a name="l00426"></a>00426                     NETSNMP_DS_LIB_SERVERRECVBUF);
<a name="l00427"></a>00427 <span class="preprocessor">#ifdef NETSNMP_DEFAULT_SERVER_RECV_BUF</span>
<a name="l00428"></a>00428 <span class="preprocessor"></span>            <span class="keywordflow">if</span> (size &lt;= 0)
<a name="l00429"></a>00429                size = NETSNMP_DEFAULT_SERVER_RECV_BUF;
<a name="l00430"></a>00430 <span class="preprocessor">#endif</span>
<a name="l00431"></a>00431 <span class="preprocessor"></span>        } <span class="keywordflow">else</span> {
<a name="l00432"></a>00432             size = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID, 
<a name="l00433"></a>00433                     NETSNMP_DS_LIB_CLIENTRECVBUF);
<a name="l00434"></a>00434 <span class="preprocessor">#ifdef NETSNMP_DEFAULT_CLIENT_RECV_BUF</span>
<a name="l00435"></a>00435 <span class="preprocessor"></span>            <span class="keywordflow">if</span> (size &lt;= 0)
<a name="l00436"></a>00436                size = NETSNMP_DEFAULT_CLIENT_RECV_BUF;
<a name="l00437"></a>00437 <span class="preprocessor">#endif</span>
<a name="l00438"></a>00438 <span class="preprocessor"></span>        }
<a name="l00439"></a>00439     } <span class="keywordflow">else</span> {
<a name="l00440"></a>00440         size = 0;
<a name="l00441"></a>00441     }
<a name="l00442"></a>00442 
<a name="l00443"></a>00443     DEBUGMSGTL((<span class="stringliteral">&quot;socket:buffer&quot;</span>, <span class="stringliteral">&quot;Requested %s is %d\n&quot;</span>,
<a name="l00444"></a>00444                 (buftype) ? *buftype : <span class="stringliteral">&quot;unknown buffer&quot;</span>, size));
<a name="l00445"></a>00445 
<a name="l00446"></a>00446     <span class="keywordflow">return</span>(size);
<a name="l00447"></a>00447 }
<a name="l00448"></a>00448 
<a name="l00449"></a>00449 <span class="comment">/*</span>
<a name="l00450"></a>00450 <span class="comment"> * set socket buffer size</span>
<a name="l00451"></a>00451 <span class="comment"> *</span>
<a name="l00452"></a>00452 <span class="comment"> * @param ss     : socket</span>
<a name="l00453"></a>00453 <span class="comment"> * @param optname: SO_SNDBUF or SO_RCVBUF</span>
<a name="l00454"></a>00454 <span class="comment"> * @param local  : 1 for server, 0 for client</span>
<a name="l00455"></a>00455 <span class="comment"> * @param reqbuf : requested size, or 0 for default</span>
<a name="l00456"></a>00456 <span class="comment"> *</span>
<a name="l00457"></a>00457 <span class="comment"> * @retval    -1 : error</span>
<a name="l00458"></a>00458 <span class="comment"> * @retval    &gt;0 : new buffer size</span>
<a name="l00459"></a>00459 <span class="comment"> */</span>
<a name="l00460"></a>00460 <span class="keywordtype">int</span>
<a name="l00461"></a>00461 netsnmp_sock_buffer_set(<span class="keywordtype">int</span> s, <span class="keywordtype">int</span> optname, <span class="keywordtype">int</span> local, <span class="keywordtype">int</span> size)
<a name="l00462"></a>00462 {
<a name="l00463"></a>00463 <span class="preprocessor">#if ! defined(SO_SNDBUF) &amp;&amp; ! defined(SO_RCVBUF)</span>
<a name="l00464"></a>00464 <span class="preprocessor"></span>    DEBUGMSGTL((<span class="stringliteral">&quot;socket:buffer&quot;</span>, <span class="stringliteral">&quot;Changing socket buffer is not supported\n&quot;</span>));
<a name="l00465"></a>00465     <span class="keywordflow">return</span> -1;
<a name="l00466"></a>00466 <span class="preprocessor">#else</span>
<a name="l00467"></a>00467 <span class="preprocessor"></span>    <span class="keyword">const</span> <span class="keywordtype">char</span>     *buftype;
<a name="l00468"></a>00468     <span class="keywordtype">int</span>            curbuf = 0;
<a name="l00469"></a>00469     <span class="keywordtype">size_t</span>         curbuflen = <span class="keyword">sizeof</span>(int);
<a name="l00470"></a>00470 
<a name="l00471"></a>00471 <span class="preprocessor">#   ifndef  SO_SNDBUF</span>
<a name="l00472"></a>00472 <span class="preprocessor"></span>    <span class="keywordflow">if</span> (SO_SNDBUF == optname) {
<a name="l00473"></a>00473         DEBUGMSGTL((<span class="stringliteral">&quot;socket:buffer&quot;</span>,
<a name="l00474"></a>00474                     <span class="stringliteral">&quot;Changing socket send buffer is not supported\n&quot;</span>));
<a name="l00475"></a>00475         <span class="keywordflow">return</span> -1;
<a name="l00476"></a>00476     }
<a name="l00477"></a>00477 <span class="preprocessor">#   endif                          </span><span class="comment">/*SO_SNDBUF */</span>
<a name="l00478"></a>00478 <span class="preprocessor">#   ifndef  SO_RCVBUF</span>
<a name="l00479"></a>00479 <span class="preprocessor"></span>    <span class="keywordflow">if</span> (SO_RCVBUF == optname) {
<a name="l00480"></a>00480         DEBUGMSGTL((<span class="stringliteral">&quot;socket:buffer&quot;</span>,
<a name="l00481"></a>00481                     <span class="stringliteral">&quot;Changing socket receive buffer is not supported\n&quot;</span>));
<a name="l00482"></a>00482         <span class="keywordflow">return</span> -1;
<a name="l00483"></a>00483     }
<a name="l00484"></a>00484 <span class="preprocessor">#   endif                          </span><span class="comment">/*SO_RCVBUF */</span>
<a name="l00485"></a>00485 
<a name="l00486"></a>00486     <span class="comment">/*</span>
<a name="l00487"></a>00487 <span class="comment">     * What is the requested buffer size ?</span>
<a name="l00488"></a>00488 <span class="comment">     */</span>
<a name="l00489"></a>00489     <span class="keywordflow">if</span> (0 == size)
<a name="l00490"></a>00490         size = _sock_buffer_size_get(optname, local, &amp;buftype);
<a name="l00491"></a>00491     <span class="keywordflow">else</span> {
<a name="l00492"></a>00492         buftype = _sock_buf_type_get(optname, local);
<a name="l00493"></a>00493         DEBUGMSGT((<span class="stringliteral">&quot;verbose:socket:buffer&quot;</span>, <span class="stringliteral">&quot;Requested %s is %d\n&quot;</span>,
<a name="l00494"></a>00494                    buftype, size));
<a name="l00495"></a>00495     }
<a name="l00496"></a>00496 
<a name="l00497"></a>00497     <span class="keywordflow">if</span> ((getsockopt(s, SOL_SOCKET, optname, (<span class="keywordtype">void</span> *) &amp;curbuf,
<a name="l00498"></a>00498                     &amp;curbuflen) == 0) 
<a name="l00499"></a>00499         &amp;&amp; (curbuflen == <span class="keyword">sizeof</span>(<span class="keywordtype">int</span>))) {
<a name="l00500"></a>00500         
<a name="l00501"></a>00501         DEBUGMSGT((<span class="stringliteral">&quot;verbose:socket:buffer&quot;</span>, <span class="stringliteral">&quot;Original %s is %d\n&quot;</span>,
<a name="l00502"></a>00502                    buftype, curbuf));
<a name="l00503"></a>00503         <span class="keywordflow">if</span> (curbuf &gt;= size) {
<a name="l00504"></a>00504             DEBUGMSGT((<span class="stringliteral">&quot;verbose:socket:buffer&quot;</span>,
<a name="l00505"></a>00505                       <span class="stringliteral">&quot;New %s size is smaller than original!\n&quot;</span>, buftype));
<a name="l00506"></a>00506         }
<a name="l00507"></a>00507     }
<a name="l00508"></a>00508 
<a name="l00509"></a>00509     <span class="comment">/*</span>
<a name="l00510"></a>00510 <span class="comment">     * If the buffersize was not specified or it was a negative value</span>
<a name="l00511"></a>00511 <span class="comment">     * then don&#39;t change the OS buffers at all</span>
<a name="l00512"></a>00512 <span class="comment">     */</span>
<a name="l00513"></a>00513     <span class="keywordflow">if</span> (size &lt;= 0) {
<a name="l00514"></a>00514        DEBUGMSGT((<span class="stringliteral">&quot;socket:buffer&quot;</span>,
<a name="l00515"></a>00515                     <span class="stringliteral">&quot;%s not valid or not specified; using OS default(%d)\n&quot;</span>,
<a name="l00516"></a>00516                     buftype,curbuf));
<a name="l00517"></a>00517        <span class="keywordflow">return</span> curbuf;
<a name="l00518"></a>00518     }
<a name="l00519"></a>00519 
<a name="l00520"></a>00520     <span class="comment">/*</span>
<a name="l00521"></a>00521 <span class="comment">     * Try to set the requested send buffer</span>
<a name="l00522"></a>00522 <span class="comment">     */</span>
<a name="l00523"></a>00523     <span class="keywordflow">if</span> (setsockopt(s, SOL_SOCKET, optname, (<span class="keywordtype">void</span> *) &amp;size, <span class="keyword">sizeof</span>(<span class="keywordtype">int</span>)) == 0) {
<a name="l00524"></a>00524         <span class="comment">/*</span>
<a name="l00525"></a>00525 <span class="comment">         * Because some platforms lie about the actual buffer that has been </span>
<a name="l00526"></a>00526 <span class="comment">         * set (Linux will always say it worked ...), we print some </span>
<a name="l00527"></a>00527 <span class="comment">         * diagnostic output for debugging</span>
<a name="l00528"></a>00528 <span class="comment">         */</span>
<a name="l00529"></a>00529         DEBUGIF(<span class="stringliteral">&quot;socket:buffer&quot;</span>) {
<a name="l00530"></a>00530             DEBUGMSGT((<span class="stringliteral">&quot;socket:buffer&quot;</span>, <span class="stringliteral">&quot;Set %s to %d\n&quot;</span>,
<a name="l00531"></a>00531                        buftype, size));
<a name="l00532"></a>00532             <span class="keywordflow">if</span> ((getsockopt(s, SOL_SOCKET, optname, (<span class="keywordtype">void</span> *) &amp;curbuf,
<a name="l00533"></a>00533                             &amp;curbuflen) == 0) 
<a name="l00534"></a>00534                     &amp;&amp; (curbuflen == <span class="keyword">sizeof</span>(<span class="keywordtype">int</span>))) {
<a name="l00535"></a>00535 
<a name="l00536"></a>00536                 DEBUGMSGT((<span class="stringliteral">&quot;verbose:socket:buffer&quot;</span>,
<a name="l00537"></a>00537                            <span class="stringliteral">&quot;Now %s is %d\n&quot;</span>, buftype, curbuf));
<a name="l00538"></a>00538             }
<a name="l00539"></a>00539         }
<a name="l00540"></a>00540         <span class="comment">/*</span>
<a name="l00541"></a>00541 <span class="comment">         * If the new buffer is smaller than the size we requested, we will</span>
<a name="l00542"></a>00542 <span class="comment">         * try to increment the new buffer with 1k increments </span>
<a name="l00543"></a>00543 <span class="comment">         * (this will sometime allow us to reach a more optimal buffer.)</span>
<a name="l00544"></a>00544 <span class="comment">         *   For example : On Solaris, if the max OS buffer is 100k and you</span>
<a name="l00545"></a>00545 <span class="comment">         *   request 110k, you end up with the default 8k :-(</span>
<a name="l00546"></a>00546 <span class="comment">         */</span>
<a name="l00547"></a>00547         <span class="keywordflow">if</span> (curbuf &lt; size) {
<a name="l00548"></a>00548             curbuf = _sock_buffer_maximize(s, optname, buftype, size);
<a name="l00549"></a>00549             <span class="keywordflow">if</span>(-1 != curbuf)
<a name="l00550"></a>00550                 size = curbuf;
<a name="l00551"></a>00551         }
<a name="l00552"></a>00552 
<a name="l00553"></a>00553     } <span class="keywordflow">else</span> {
<a name="l00554"></a>00554         <span class="comment">/*</span>
<a name="l00555"></a>00555 <span class="comment">         * Obviously changing the buffer failed, most like like because we </span>
<a name="l00556"></a>00556 <span class="comment">         * requested a buffer greater than the OS limit.</span>
<a name="l00557"></a>00557 <span class="comment">         * Therefore we need to search for an optimal buffer that is close</span>
<a name="l00558"></a>00558 <span class="comment">         * enough to the point of failure.</span>
<a name="l00559"></a>00559 <span class="comment">         * This will allow us to reach a more optimal buffer.</span>
<a name="l00560"></a>00560 <span class="comment">         *   For example : On Solaris, if the max OS buffer is 100k and you </span>
<a name="l00561"></a>00561 <span class="comment">         *   request 110k, you end up with the default 8k :-(</span>
<a name="l00562"></a>00562 <span class="comment">         *   After this quick seach we would get 1k close to 100k (the max)</span>
<a name="l00563"></a>00563 <span class="comment">         */</span>
<a name="l00564"></a>00564         DEBUGMSGTL((<span class="stringliteral">&quot;socket:buffer&quot;</span>, <span class="stringliteral">&quot;couldn&#39;t set %s to %d\n&quot;</span>,
<a name="l00565"></a>00565                     buftype, size));
<a name="l00566"></a>00566 
<a name="l00567"></a>00567         curbuf = _sock_buffer_maximize(s, optname, buftype, size);
<a name="l00568"></a>00568         <span class="keywordflow">if</span>(-1 != curbuf)
<a name="l00569"></a>00569             size = curbuf;
<a name="l00570"></a>00570     }
<a name="l00571"></a>00571 
<a name="l00572"></a>00572     <span class="keywordflow">return</span> size;
<a name="l00573"></a>00573 <span class="preprocessor">#endif</span>
<a name="l00574"></a>00574 <span class="preprocessor"></span>}
<a name="l00575"></a>00575 
<a name="l00576"></a>00576 <span class="comment">/*</span>
<a name="l00577"></a>00577 <span class="comment"> * Open a UDP-based transport for SNMP.  Local is TRUE if addr is the local</span>
<a name="l00578"></a>00578 <span class="comment"> * address to bind to (i.e. this is a server-type session); otherwise addr is </span>
<a name="l00579"></a>00579 <span class="comment"> * the remote address to send things to.  </span>
<a name="l00580"></a>00580 <span class="comment"> */</span>
<a name="l00581"></a>00581 
<a name="l00582"></a>00582 <a class="code" href="structnetsnmp__transport__s.html">netsnmp_transport</a> *
<a name="l00583"></a>00583 netsnmp_udp_transport(<span class="keyword">struct</span> sockaddr_in *addr, <span class="keywordtype">int</span> local)
<a name="l00584"></a>00584 {
<a name="l00585"></a>00585     <a class="code" href="structnetsnmp__transport__s.html">netsnmp_transport</a> *t = NULL;
<a name="l00586"></a>00586     <span class="keywordtype">int</span>             rc = 0;
<a name="l00587"></a>00587     <span class="keywordtype">char</span>           *str = NULL;
<a name="l00588"></a>00588     <span class="keywordtype">char</span>           *client_socket = NULL;
<a name="l00589"></a>00589     <a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a> addr_pair;
<a name="l00590"></a>00590 
<a name="l00591"></a>00591     <span class="keywordflow">if</span> (addr == NULL || addr-&gt;sin_family != AF_INET) {
<a name="l00592"></a>00592         <span class="keywordflow">return</span> NULL;
<a name="l00593"></a>00593     }
<a name="l00594"></a>00594 
<a name="l00595"></a>00595     memset(&amp;addr_pair, 0, <span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>));
<a name="l00596"></a>00596     memcpy(&amp;(addr_pair.remote_addr), addr, <span class="keyword">sizeof</span>(<span class="keyword">struct</span> sockaddr_in));
<a name="l00597"></a>00597 
<a name="l00598"></a>00598     t = (<a class="code" href="structnetsnmp__transport__s.html">netsnmp_transport</a> *) malloc(<span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__transport__s.html">netsnmp_transport</a>));
<a name="l00599"></a>00599     <span class="keywordflow">if</span> (t == NULL) {
<a name="l00600"></a>00600         <span class="keywordflow">return</span> NULL;
<a name="l00601"></a>00601     }
<a name="l00602"></a>00602 
<a name="l00603"></a>00603     str = netsnmp_udp_fmtaddr(NULL, (<span class="keywordtype">void</span> *)&amp;addr_pair,
<a name="l00604"></a>00604                                  <span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>));
<a name="l00605"></a>00605     DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp&quot;</span>, <span class="stringliteral">&quot;open %s %s\n&quot;</span>, local ? <span class="stringliteral">&quot;local&quot;</span> : <span class="stringliteral">&quot;remote&quot;</span>,
<a name="l00606"></a>00606                 str));
<a name="l00607"></a>00607     free(str);
<a name="l00608"></a>00608 
<a name="l00609"></a>00609     memset(t, 0, <span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__transport__s.html">netsnmp_transport</a>));
<a name="l00610"></a>00610 
<a name="l00611"></a>00611     t-&gt;domain = netsnmpUDPDomain;
<a name="l00612"></a>00612     t-&gt;domain_length = netsnmpUDPDomain_len;
<a name="l00613"></a>00613 
<a name="l00614"></a>00614     t-&gt;sock = socket(PF_INET, SOCK_DGRAM, 0);
<a name="l00615"></a>00615     <span class="keywordflow">if</span> (t-&gt;sock &lt; 0) {
<a name="l00616"></a>00616         netsnmp_transport_free(t);
<a name="l00617"></a>00617         <span class="keywordflow">return</span> NULL;
<a name="l00618"></a>00618     }
<a name="l00619"></a>00619 
<a name="l00620"></a>00620     _netsnmp_udp_sockopt_set(t-&gt;sock, local);
<a name="l00621"></a>00621 
<a name="l00622"></a>00622     <span class="keywordflow">if</span> (local) {
<a name="l00623"></a>00623         <span class="comment">/*</span>
<a name="l00624"></a>00624 <span class="comment">         * This session is inteneded as a server, so we must bind on to the</span>
<a name="l00625"></a>00625 <span class="comment">         * given IP address, which may include an interface address, or could</span>
<a name="l00626"></a>00626 <span class="comment">         * be INADDR_ANY, but certainly includes a port number.</span>
<a name="l00627"></a>00627 <span class="comment">         */</span>
<a name="l00628"></a>00628 
<a name="l00629"></a>00629       t-&gt;local = (u_char *) malloc(6);
<a name="l00630"></a>00630         <span class="keywordflow">if</span> (t-&gt;local == NULL) {
<a name="l00631"></a>00631             netsnmp_transport_free(t);
<a name="l00632"></a>00632             <span class="keywordflow">return</span> NULL;
<a name="l00633"></a>00633         }
<a name="l00634"></a>00634         memcpy(t-&gt;local, (u_char *) &amp; (addr-&gt;sin_addr.s_addr), 4);
<a name="l00635"></a>00635         t-&gt;local[4] = (htons(addr-&gt;sin_port) &amp; 0xff00) &gt;&gt; 8;
<a name="l00636"></a>00636         t-&gt;local[5] = (htons(addr-&gt;sin_port) &amp; 0x00ff) &gt;&gt; 0;
<a name="l00637"></a>00637         t-&gt;local_length = 6;
<a name="l00638"></a>00638 
<a name="l00639"></a>00639 <span class="preprocessor">#if defined(linux) &amp;&amp; defined(IP_PKTINFO)</span>
<a name="l00640"></a>00640 <span class="preprocessor"></span>        { 
<a name="l00641"></a>00641             <span class="keywordtype">int</span> sockopt = 1;
<a name="l00642"></a>00642             <span class="keywordflow">if</span> (setsockopt(t-&gt;sock, SOL_IP, IP_PKTINFO, &amp;sockopt, <span class="keyword">sizeof</span> sockopt) == -1) {
<a name="l00643"></a>00643                 DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp&quot;</span>, <span class="stringliteral">&quot;couldn&#39;t set IP_PKTINFO: %s\n&quot;</span>,
<a name="l00644"></a>00644                     strerror(errno)));
<a name="l00645"></a>00645                 <span class="keywordflow">return</span> NULL;
<a name="l00646"></a>00646             }
<a name="l00647"></a>00647             DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp&quot;</span>, <span class="stringliteral">&quot;set IP_PKTINFO\n&quot;</span>));
<a name="l00648"></a>00648         }
<a name="l00649"></a>00649 <span class="preprocessor">#endif</span>
<a name="l00650"></a>00650 <span class="preprocessor"></span>        rc = bind(t-&gt;sock, (<span class="keyword">struct</span> sockaddr *) addr,
<a name="l00651"></a>00651                   <span class="keyword">sizeof</span>(<span class="keyword">struct</span> sockaddr));
<a name="l00652"></a>00652         <span class="keywordflow">if</span> (rc != 0) {
<a name="l00653"></a>00653             netsnmp_udp_close(t);
<a name="l00654"></a>00654             netsnmp_transport_free(t);
<a name="l00655"></a>00655             <span class="keywordflow">return</span> NULL;
<a name="l00656"></a>00656         }
<a name="l00657"></a>00657         t-&gt;data = NULL;
<a name="l00658"></a>00658         t-&gt;data_length = 0;
<a name="l00659"></a>00659     } <span class="keywordflow">else</span> {
<a name="l00660"></a>00660         <span class="comment">/*</span>
<a name="l00661"></a>00661 <span class="comment">         * This is a client session.  If we&#39;ve been given a</span>
<a name="l00662"></a>00662 <span class="comment">         * client address to send from, then bind to that.</span>
<a name="l00663"></a>00663 <span class="comment">         * Otherwise the send will use &quot;something sensible&quot;.</span>
<a name="l00664"></a>00664 <span class="comment">         */</span>
<a name="l00665"></a>00665         client_socket = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
<a name="l00666"></a>00666                                               NETSNMP_DS_LIB_CLIENT_ADDR);
<a name="l00667"></a>00667         <span class="keywordflow">if</span> (client_socket) {
<a name="l00668"></a>00668             <span class="keyword">struct </span>sockaddr_in client_addr;
<a name="l00669"></a>00669             netsnmp_sockaddr_in2(&amp;client_addr, client_socket, NULL);
<a name="l00670"></a>00670             client_addr.sin_port = 0;
<a name="l00671"></a>00671             bind(t-&gt;sock, (<span class="keyword">struct</span> sockaddr *)&amp;client_addr,
<a name="l00672"></a>00672                   <span class="keyword">sizeof</span>(<span class="keyword">struct</span> sockaddr));
<a name="l00673"></a>00673         }
<a name="l00674"></a>00674         <span class="comment">/*</span>
<a name="l00675"></a>00675 <span class="comment">         * Save the (remote) address in the</span>
<a name="l00676"></a>00676 <span class="comment">         * transport-specific data pointer for later use by netsnmp_udp_send.</span>
<a name="l00677"></a>00677 <span class="comment">         */</span>
<a name="l00678"></a>00678 
<a name="l00679"></a>00679         t-&gt;data = malloc(<span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>));
<a name="l00680"></a>00680         t-&gt;remote = (u_char *)malloc(6);
<a name="l00681"></a>00681         <span class="keywordflow">if</span> (t-&gt;data == NULL || t-&gt;remote == NULL) {
<a name="l00682"></a>00682             netsnmp_transport_free(t);
<a name="l00683"></a>00683             <span class="keywordflow">return</span> NULL;
<a name="l00684"></a>00684         }
<a name="l00685"></a>00685         memcpy(t-&gt;remote, (u_char *) &amp; (addr-&gt;sin_addr.s_addr), 4);
<a name="l00686"></a>00686         t-&gt;remote[4] = (htons(addr-&gt;sin_port) &amp; 0xff00) &gt;&gt; 8;
<a name="l00687"></a>00687         t-&gt;remote[5] = (htons(addr-&gt;sin_port) &amp; 0x00ff) &gt;&gt; 0;
<a name="l00688"></a>00688         t-&gt;remote_length = 6;
<a name="l00689"></a>00689         memcpy(t-&gt;data, &amp;addr_pair, <span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>));
<a name="l00690"></a>00690         t-&gt;data_length = <span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>);
<a name="l00691"></a>00691     }
<a name="l00692"></a>00692 
<a name="l00693"></a>00693     <span class="comment">/*</span>
<a name="l00694"></a>00694 <span class="comment">     * 16-bit length field, 8 byte UDP header, 20 byte IPv4 header  </span>
<a name="l00695"></a>00695 <span class="comment">     */</span>
<a name="l00696"></a>00696 
<a name="l00697"></a>00697     t-&gt;msgMaxSize = 0xffff - 8 - 20;
<a name="l00698"></a>00698     t-&gt;f_recv     = netsnmp_udp_recv;
<a name="l00699"></a>00699     t-&gt;f_send     = netsnmp_udp_send;
<a name="l00700"></a>00700     t-&gt;f_close    = netsnmp_udp_close;
<a name="l00701"></a>00701     t-&gt;f_accept   = NULL;
<a name="l00702"></a>00702     t-&gt;f_fmtaddr  = netsnmp_udp_fmtaddr;
<a name="l00703"></a>00703 
<a name="l00704"></a>00704     <span class="keywordflow">return</span> t;
<a name="l00705"></a>00705 }
<a name="l00706"></a>00706 
<a name="l00707"></a>00707 
<a name="l00708"></a>00708 <span class="keywordtype">void</span>
<a name="l00709"></a>00709 _netsnmp_udp_sockopt_set(<span class="keywordtype">int</span> fd, <span class="keywordtype">int</span> local)
<a name="l00710"></a>00710 {
<a name="l00711"></a>00711 <span class="preprocessor">#ifdef  SO_BSDCOMPAT</span>
<a name="l00712"></a>00712 <span class="preprocessor"></span>    <span class="comment">/*</span>
<a name="l00713"></a>00713 <span class="comment">     * Patch for Linux.  Without this, UDP packets that fail get an ICMP</span>
<a name="l00714"></a>00714 <span class="comment">     * response.  Linux turns the failed ICMP response into an error message</span>
<a name="l00715"></a>00715 <span class="comment">     * and return value, unlike all other OS&#39;s.  </span>
<a name="l00716"></a>00716 <span class="comment">     */</span>
<a name="l00717"></a>00717     <span class="keywordflow">if</span> (0 == netsnmp_os_prematch(<span class="stringliteral">&quot;Linux&quot;</span>,<span class="stringliteral">&quot;2.4&quot;</span>))
<a name="l00718"></a>00718     {
<a name="l00719"></a>00719         <span class="keywordtype">int</span>             one = 1;
<a name="l00720"></a>00720         DEBUGMSGTL((<span class="stringliteral">&quot;socket:option&quot;</span>, <span class="stringliteral">&quot;setting socket option SO_BSDCOMPAT\n&quot;</span>));
<a name="l00721"></a>00721         setsockopt(fd, SOL_SOCKET, SO_BSDCOMPAT, (<span class="keywordtype">void</span> *) &amp;one,
<a name="l00722"></a>00722                    <span class="keyword">sizeof</span>(one));
<a name="l00723"></a>00723     }
<a name="l00724"></a>00724 <span class="preprocessor">#endif                          </span><span class="comment">/*SO_BSDCOMPAT */</span>
<a name="l00725"></a>00725     <span class="comment">/*</span>
<a name="l00726"></a>00726 <span class="comment">     * SO_REUSEADDR will allow multiple apps to open the same port at</span>
<a name="l00727"></a>00727 <span class="comment">     * the same time. Only the last one to open the socket will get</span>
<a name="l00728"></a>00728 <span class="comment">     * data. Obviously, for an agent, this is a bad thing. There should</span>
<a name="l00729"></a>00729 <span class="comment">     * only be one listener.</span>
<a name="l00730"></a>00730 <span class="comment">     */</span>
<a name="l00731"></a>00731 <span class="preprocessor">#ifdef ALLOW_PORT_HIJACKING</span>
<a name="l00732"></a>00732 <span class="preprocessor"></span><span class="preprocessor">#ifdef  SO_REUSEADDR</span>
<a name="l00733"></a>00733 <span class="preprocessor"></span>    <span class="comment">/*</span>
<a name="l00734"></a>00734 <span class="comment">     * Allow the same port to be specified multiple times without failing.</span>
<a name="l00735"></a>00735 <span class="comment">     *    (useful for a listener)</span>
<a name="l00736"></a>00736 <span class="comment">     */</span>
<a name="l00737"></a>00737     {
<a name="l00738"></a>00738         <span class="keywordtype">int</span>             one = 1;
<a name="l00739"></a>00739         DEBUGMSGTL((<span class="stringliteral">&quot;socket:option&quot;</span>, <span class="stringliteral">&quot;setting socket option SO_REUSEADDR\n&quot;</span>));
<a name="l00740"></a>00740         setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (<span class="keywordtype">void</span> *) &amp;one,
<a name="l00741"></a>00741                    <span class="keyword">sizeof</span>(one));
<a name="l00742"></a>00742     }
<a name="l00743"></a>00743 <span class="preprocessor">#endif                          </span><span class="comment">/*SO_REUSEADDR */</span>
<a name="l00744"></a>00744 <span class="preprocessor">#endif</span>
<a name="l00745"></a>00745 <span class="preprocessor"></span>
<a name="l00746"></a>00746     <span class="comment">/*</span>
<a name="l00747"></a>00747 <span class="comment">     * Try to set the send and receive buffers to a reasonably large value, so</span>
<a name="l00748"></a>00748 <span class="comment">     * that we can send and receive big PDUs (defaults to 8192 bytes (!) on</span>
<a name="l00749"></a>00749 <span class="comment">     * Solaris, for instance).  Don&#39;t worry too much about errors -- just</span>
<a name="l00750"></a>00750 <span class="comment">     * plough on regardless.  </span>
<a name="l00751"></a>00751 <span class="comment">     */</span>
<a name="l00752"></a>00752     netsnmp_sock_buffer_set(fd, SO_SNDBUF, local, 0);
<a name="l00753"></a>00753     netsnmp_sock_buffer_set(fd, SO_RCVBUF, local, 0);
<a name="l00754"></a>00754 }
<a name="l00755"></a>00755 
<a name="l00756"></a>00756 <span class="keywordtype">int</span>
<a name="l00757"></a>00757 netsnmp_sockaddr_in2(<span class="keyword">struct</span> sockaddr_in *addr,
<a name="l00758"></a>00758                      <span class="keyword">const</span> <span class="keywordtype">char</span> *inpeername, <span class="keyword">const</span> <span class="keywordtype">char</span> *default_target)
<a name="l00759"></a>00759 {
<a name="l00760"></a>00760 <span class="preprocessor">#if HAVE_GETADDRINFO</span>
<a name="l00761"></a>00761 <span class="preprocessor"></span>    <span class="keyword">struct </span>addrinfo *addrs = NULL;
<a name="l00762"></a>00762     <span class="keyword">struct </span>addrinfo hint;
<a name="l00763"></a>00763     <span class="keywordtype">int</span>             err;
<a name="l00764"></a>00764 <span class="preprocessor">#elif HAVE_GETIPNODEBYNAME</span>
<a name="l00765"></a>00765 <span class="preprocessor"></span>    <span class="keyword">struct </span>hostent *hp = NULL;
<a name="l00766"></a>00766     <span class="keywordtype">int</span>             err;
<a name="l00767"></a>00767 <span class="preprocessor">#elif HAVE_GETHOSTBYNAME</span>
<a name="l00768"></a>00768 <span class="preprocessor"></span>    <span class="keyword">struct </span>hostent *hp = NULL;
<a name="l00769"></a>00769 <span class="preprocessor">#endif</span>
<a name="l00770"></a>00770 <span class="preprocessor"></span>
<a name="l00771"></a>00771     <span class="keywordflow">if</span> (addr == NULL) {
<a name="l00772"></a>00772         <span class="keywordflow">return</span> 0;
<a name="l00773"></a>00773     }
<a name="l00774"></a>00774 
<a name="l00775"></a>00775     DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>,
<a name="l00776"></a>00776                 <span class="stringliteral">&quot;addr %p, inpeername \&quot;%s\&quot;, default_target \&quot;%s\&quot;\n&quot;</span>,
<a name="l00777"></a>00777                 addr, inpeername ? inpeername : <span class="stringliteral">&quot;[NIL]&quot;</span>,
<a name="l00778"></a>00778                 default_target ? default_target : <span class="stringliteral">&quot;[NIL]&quot;</span>));
<a name="l00779"></a>00779 
<a name="l00780"></a>00780     memset(addr, 0, <span class="keyword">sizeof</span>(<span class="keyword">struct</span> sockaddr_in));
<a name="l00781"></a>00781     addr-&gt;sin_addr.s_addr = htonl(INADDR_ANY);
<a name="l00782"></a>00782     addr-&gt;sin_family = AF_INET;
<a name="l00783"></a>00783     addr-&gt;sin_port = htons((u_short)SNMP_PORT);
<a name="l00784"></a>00784 
<a name="l00785"></a>00785     {
<a name="l00786"></a>00786         <span class="keywordtype">int</span> port = netsnmp_ds_get_int(NETSNMP_DS_LIBRARY_ID,
<a name="l00787"></a>00787                                       NETSNMP_DS_LIB_DEFAULT_PORT);
<a name="l00788"></a>00788 
<a name="l00789"></a>00789         <span class="keywordflow">if</span> (port != 0) {
<a name="l00790"></a>00790             addr-&gt;sin_port = htons((u_short)port);
<a name="l00791"></a>00791         } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (default_target != NULL)
<a name="l00792"></a>00792             netsnmp_sockaddr_in2(addr, default_target, NULL);
<a name="l00793"></a>00793     }
<a name="l00794"></a>00794 
<a name="l00795"></a>00795     <span class="keywordflow">if</span> (inpeername != NULL &amp;&amp; *inpeername != <span class="charliteral">&#39;\0&#39;</span>) {
<a name="l00796"></a>00796         <span class="keyword">const</span> <span class="keywordtype">char</span>     *host, *port;
<a name="l00797"></a>00797         <span class="keywordtype">char</span>           *peername = NULL;
<a name="l00798"></a>00798         <span class="keywordtype">char</span>           *cp;
<a name="l00799"></a>00799         <span class="comment">/*</span>
<a name="l00800"></a>00800 <span class="comment">         * Duplicate the peername because we might want to mank around with</span>
<a name="l00801"></a>00801 <span class="comment">         * it.  </span>
<a name="l00802"></a>00802 <span class="comment">         */</span>
<a name="l00803"></a>00803 
<a name="l00804"></a>00804         peername = strdup(inpeername);
<a name="l00805"></a>00805         <span class="keywordflow">if</span> (peername == NULL) {
<a name="l00806"></a>00806             <span class="keywordflow">return</span> 0;
<a name="l00807"></a>00807         }
<a name="l00808"></a>00808 
<a name="l00809"></a>00809         <span class="comment">/*</span>
<a name="l00810"></a>00810 <span class="comment">         * Try and extract an appended port number.  </span>
<a name="l00811"></a>00811 <span class="comment">         */</span>
<a name="l00812"></a>00812         cp = strchr(peername, <span class="charliteral">&#39;:&#39;</span>);
<a name="l00813"></a>00813         <span class="keywordflow">if</span> (cp != NULL) {
<a name="l00814"></a>00814             *cp = <span class="charliteral">&#39;\0&#39;</span>;
<a name="l00815"></a>00815             port = cp + 1;
<a name="l00816"></a>00816             host = peername;
<a name="l00817"></a>00817         } <span class="keywordflow">else</span> {
<a name="l00818"></a>00818             host = NULL;
<a name="l00819"></a>00819             port = peername;
<a name="l00820"></a>00820         }
<a name="l00821"></a>00821 
<a name="l00822"></a>00822         <span class="comment">/*</span>
<a name="l00823"></a>00823 <span class="comment">         * Try to convert the user port specifier</span>
<a name="l00824"></a>00824 <span class="comment">         */</span>
<a name="l00825"></a>00825         <span class="keywordflow">if</span> (port &amp;&amp; *port == <span class="charliteral">&#39;\0&#39;</span>)
<a name="l00826"></a>00826             port = NULL;
<a name="l00827"></a>00827 
<a name="l00828"></a>00828         <span class="keywordflow">if</span> (port != NULL) {
<a name="l00829"></a>00829             <span class="keywordtype">long</span> <span class="keywordtype">int</span> l;
<a name="l00830"></a>00830             <span class="keywordtype">char</span>* ep;
<a name="l00831"></a>00831 
<a name="l00832"></a>00832             DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>, <span class="stringliteral">&quot;check user service %s\n&quot;</span>,
<a name="l00833"></a>00833                         port));
<a name="l00834"></a>00834 
<a name="l00835"></a>00835             l = strtol(port, &amp;ep, 10);
<a name="l00836"></a>00836             <span class="keywordflow">if</span> (ep != port &amp;&amp; *ep == <span class="charliteral">&#39;\0&#39;</span> &amp;&amp; 0 &lt;= l &amp;&amp; l &lt;= 0x0ffff)
<a name="l00837"></a>00837                 addr-&gt;sin_port = htons((u_short)l);
<a name="l00838"></a>00838             <span class="keywordflow">else</span> {
<a name="l00839"></a>00839                 <span class="keywordflow">if</span> (host == NULL) {
<a name="l00840"></a>00840                     DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>,
<a name="l00841"></a>00841                                 <span class="stringliteral">&quot;servname not numeric, &quot;</span>
<a name="l00842"></a>00842                                 <span class="stringliteral">&quot;check if it really is a destination)&quot;</span>));
<a name="l00843"></a>00843                     host = port;
<a name="l00844"></a>00844                     port = NULL;
<a name="l00845"></a>00845                 } <span class="keywordflow">else</span> {
<a name="l00846"></a>00846                     DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>,
<a name="l00847"></a>00847                                 <span class="stringliteral">&quot;servname not numeric&quot;</span>));
<a name="l00848"></a>00848                     free(peername);
<a name="l00849"></a>00849                     <span class="keywordflow">return</span> 0;
<a name="l00850"></a>00850                 }
<a name="l00851"></a>00851             }
<a name="l00852"></a>00852         }
<a name="l00853"></a>00853 
<a name="l00854"></a>00854         <span class="comment">/*</span>
<a name="l00855"></a>00855 <span class="comment">         * Try to convert the user host specifier</span>
<a name="l00856"></a>00856 <span class="comment">         */</span>
<a name="l00857"></a>00857         <span class="keywordflow">if</span> (host &amp;&amp; *host == <span class="charliteral">&#39;\0&#39;</span>)
<a name="l00858"></a>00858             host = NULL;
<a name="l00859"></a>00859 
<a name="l00860"></a>00860         <span class="keywordflow">if</span> (host != NULL) {
<a name="l00861"></a>00861             DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>,
<a name="l00862"></a>00862                         <span class="stringliteral">&quot;check destination %s\n&quot;</span>, host));
<a name="l00863"></a>00863 
<a name="l00864"></a>00864 <span class="preprocessor">#if HAVE_GETADDRINFO</span>
<a name="l00865"></a>00865 <span class="preprocessor"></span>            memset(&amp;hint, 0, <span class="keyword">sizeof</span> hint);
<a name="l00866"></a>00866             hint.ai_flags = 0;
<a name="l00867"></a>00867             hint.ai_family = PF_INET;
<a name="l00868"></a>00868             hint.ai_socktype = SOCK_DGRAM;
<a name="l00869"></a>00869             hint.ai_protocol = 0;
<a name="l00870"></a>00870 
<a name="l00871"></a>00871             err = getaddrinfo(peername, NULL, &amp;hint, &amp;addrs);
<a name="l00872"></a>00872             <span class="keywordflow">if</span> (err != 0) {
<a name="l00873"></a>00873 <span class="preprocessor">#if HAVE_GAI_STRERROR</span>
<a name="l00874"></a>00874 <span class="preprocessor"></span>                <a class="code" href="group__snmp__logging.html#ga9ba905368ea1c551b969af44b13e37c2" title="This snmp logging function allows variable argument list given the specified format and priority...">snmp_log</a>(LOG_ERR, <span class="stringliteral">&quot;getaddrinfo: %s %s\n&quot;</span>, peername,
<a name="l00875"></a>00875                          gai_strerror(err));
<a name="l00876"></a>00876 <span class="preprocessor">#else</span>
<a name="l00877"></a>00877 <span class="preprocessor"></span>                <a class="code" href="group__snmp__logging.html#ga9ba905368ea1c551b969af44b13e37c2" title="This snmp logging function allows variable argument list given the specified format and priority...">snmp_log</a>(LOG_ERR, <span class="stringliteral">&quot;getaddrinfo: %s (error %d)\n&quot;</span>, peername,
<a name="l00878"></a>00878                          err);
<a name="l00879"></a>00879 <span class="preprocessor">#endif</span>
<a name="l00880"></a>00880 <span class="preprocessor"></span>                free(peername);
<a name="l00881"></a>00881                 <span class="keywordflow">return</span> 0;
<a name="l00882"></a>00882             }
<a name="l00883"></a>00883             <span class="keywordflow">if</span> (addrs != NULL) {
<a name="l00884"></a>00884                 DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>,
<a name="l00885"></a>00885                             <span class="stringliteral">&quot;hostname (resolved okay)\n&quot;</span>));
<a name="l00886"></a>00886                 memcpy(&amp;addr-&gt;sin_addr,
<a name="l00887"></a>00887                        &amp;((<span class="keyword">struct</span> sockaddr_in *) addrs-&gt;ai_addr)-&gt;sin_addr,
<a name="l00888"></a>00888                        <span class="keyword">sizeof</span>(<span class="keyword">struct</span> in_addr));
<a name="l00889"></a>00889                 freeaddrinfo(addrs);
<a name="l00890"></a>00890             }
<a name="l00891"></a>00891             <span class="keywordflow">else</span> {
<a name="l00892"></a>00892                 DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>,
<a name="l00893"></a>00893                             <span class="stringliteral">&quot;Failed to resolve IPv4 hostname\n&quot;</span>));
<a name="l00894"></a>00894             }
<a name="l00895"></a>00895 <span class="preprocessor">#elif HAVE_GETHOSTBYNAME</span>
<a name="l00896"></a>00896 <span class="preprocessor"></span>            hp = gethostbyname(host);
<a name="l00897"></a>00897             <span class="keywordflow">if</span> (hp == NULL) {
<a name="l00898"></a>00898                 DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>,
<a name="l00899"></a>00899                             <span class="stringliteral">&quot;hostname (couldn&#39;t resolve)\n&quot;</span>));
<a name="l00900"></a>00900                 free(peername);
<a name="l00901"></a>00901                 <span class="keywordflow">return</span> 0;
<a name="l00902"></a>00902             } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (hp-&gt;h_addrtype != AF_INET) {
<a name="l00903"></a>00903                 DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>,
<a name="l00904"></a>00904                             <span class="stringliteral">&quot;hostname (not AF_INET!)\n&quot;</span>));
<a name="l00905"></a>00905                 free(peername);
<a name="l00906"></a>00906                 <span class="keywordflow">return</span> 0;
<a name="l00907"></a>00907             } <span class="keywordflow">else</span> {
<a name="l00908"></a>00908                 DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>,
<a name="l00909"></a>00909                             <span class="stringliteral">&quot;hostname (resolved okay)\n&quot;</span>));
<a name="l00910"></a>00910                 memcpy(&amp;addr-&gt;sin_addr, hp-&gt;h_addr, hp-&gt;h_length);
<a name="l00911"></a>00911             }
<a name="l00912"></a>00912 <span class="preprocessor">#elif HAVE_GETIPNODEBYNAME</span>
<a name="l00913"></a>00913 <span class="preprocessor"></span>            hp = getipnodebyname(peername, AF_INET, 0, &amp;err);
<a name="l00914"></a>00914             <span class="keywordflow">if</span> (hp == NULL) {
<a name="l00915"></a>00915                 DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>,
<a name="l00916"></a>00916                             <span class="stringliteral">&quot;hostname (couldn&#39;t resolve = %d)\n&quot;</span>, err));
<a name="l00917"></a>00917                 free(peername);
<a name="l00918"></a>00918                 <span class="keywordflow">return</span> 0;
<a name="l00919"></a>00919             }
<a name="l00920"></a>00920             DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>,
<a name="l00921"></a>00921                         <span class="stringliteral">&quot;hostname (resolved okay)\n&quot;</span>));
<a name="l00922"></a>00922             memcpy(&amp;(addr-&gt;sin_addr), hp-&gt;h_addr, hp-&gt;h_length);
<a name="l00923"></a>00923 <span class="preprocessor">#else </span><span class="comment">/* HAVE_GETIPNODEBYNAME */</span>
<a name="l00924"></a>00924             <span class="comment">/*</span>
<a name="l00925"></a>00925 <span class="comment">             * There is no name resolving function available.</span>
<a name="l00926"></a>00926 <span class="comment">             */</span>
<a name="l00927"></a>00927             DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>,
<a name="l00928"></a>00928                         <span class="stringliteral">&quot;no getaddrinfo()/getipnodebyname()/gethostbyname()\n&quot;</span>));
<a name="l00929"></a>00929             free(peername);
<a name="l00930"></a>00930             <span class="keywordflow">return</span> 0;
<a name="l00931"></a>00931 <span class="preprocessor">#endif </span><span class="comment">/* HAVE_GETHOSTBYNAME */</span>
<a name="l00932"></a>00932         }
<a name="l00933"></a>00933         free(peername);
<a name="l00934"></a>00934     }
<a name="l00935"></a>00935 
<a name="l00936"></a>00936     <span class="comment">/*</span>
<a name="l00937"></a>00937 <span class="comment">     * Finished</span>
<a name="l00938"></a>00938 <span class="comment">     */</span>
<a name="l00939"></a>00939 
<a name="l00940"></a>00940     DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_sockaddr_in&quot;</span>, <span class="stringliteral">&quot;return { AF_INET, %s:%hu }\n&quot;</span>,
<a name="l00941"></a>00941                 inet_ntoa(addr-&gt;sin_addr), ntohs(addr-&gt;sin_port)));
<a name="l00942"></a>00942     <span class="keywordflow">return</span> 1;
<a name="l00943"></a>00943 }
<a name="l00944"></a>00944 
<a name="l00945"></a>00945 
<a name="l00946"></a>00946 <span class="keywordtype">int</span>
<a name="l00947"></a>00947 netsnmp_sockaddr_in(<span class="keyword">struct</span> sockaddr_in *addr,
<a name="l00948"></a>00948                     <span class="keyword">const</span> <span class="keywordtype">char</span> *inpeername, <span class="keywordtype">int</span> remote_port)
<a name="l00949"></a>00949 {
<a name="l00950"></a>00950     <span class="keywordtype">char</span> buf[<span class="keyword">sizeof</span>(int) * 3 + 2];
<a name="l00951"></a>00951     sprintf(buf, <span class="stringliteral">&quot;:%u&quot;</span>, remote_port);
<a name="l00952"></a>00952     <span class="keywordflow">return</span> netsnmp_sockaddr_in2(addr, inpeername, remote_port ? buf : NULL);
<a name="l00953"></a>00953 }
<a name="l00954"></a>00954 
<a name="l00955"></a>00955 <span class="preprocessor">#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)</span>
<a name="l00956"></a>00956 <span class="preprocessor"></span><span class="comment">/*</span>
<a name="l00957"></a>00957 <span class="comment"> * The following functions provide the &quot;com2sec&quot; configuration token</span>
<a name="l00958"></a>00958 <span class="comment"> * functionality for compatibility.  </span>
<a name="l00959"></a>00959 <span class="comment"> */</span>
<a name="l00960"></a>00960 
<a name="l00961"></a>00961 <span class="preprocessor">#define EXAMPLE_NETWORK         &quot;NETWORK&quot;</span>
<a name="l00962"></a>00962 <span class="preprocessor"></span><span class="preprocessor">#define EXAMPLE_COMMUNITY       &quot;COMMUNITY&quot;</span>
<a name="l00963"></a>00963 <span class="preprocessor"></span>
<a name="l00964"></a><a class="code" href="struct__com2SecEntry.html">00964</a> <span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="struct__com2SecEntry.html">_com2SecEntry</a> {
<a name="l00965"></a>00965     <span class="keywordtype">char</span>            community[COMMUNITY_MAX_LEN];
<a name="l00966"></a>00966     <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>   network;
<a name="l00967"></a>00967     <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>   mask;
<a name="l00968"></a>00968     <span class="keywordtype">char</span>            secName[VACMSTRINGLEN];
<a name="l00969"></a>00969     <span class="keywordtype">char</span>            contextName[VACMSTRINGLEN];
<a name="l00970"></a>00970     <span class="keyword">struct </span><a class="code" href="struct__com2SecEntry.html">_com2SecEntry</a> *next;
<a name="l00971"></a>00971 } <a class="code" href="struct__com2SecEntry.html">com2SecEntry</a>;
<a name="l00972"></a>00972 
<a name="l00973"></a>00973 <a class="code" href="struct__com2SecEntry.html">com2SecEntry</a>   *com2SecList = NULL, *com2SecListLast = NULL;
<a name="l00974"></a>00974 
<a name="l00975"></a>00975 <span class="keywordtype">void</span>
<a name="l00976"></a>00976 netsnmp_udp_parse_security(<span class="keyword">const</span> <span class="keywordtype">char</span> *token, <span class="keywordtype">char</span> *param)
<a name="l00977"></a>00977 {
<a name="l00978"></a>00978     <span class="keywordtype">char</span>            secName[VACMSTRINGLEN];
<a name="l00979"></a>00979     <span class="keywordtype">char</span>            contextName[VACMSTRINGLEN];
<a name="l00980"></a>00980     <span class="keywordtype">char</span>            community[COMMUNITY_MAX_LEN];
<a name="l00981"></a>00981     <span class="keywordtype">char</span>            source[SNMP_MAXBUF_SMALL];
<a name="l00982"></a>00982     <span class="keywordtype">char</span>           *cp = NULL;
<a name="l00983"></a>00983     <span class="keyword">const</span> <span class="keywordtype">char</span>     *strmask = NULL;
<a name="l00984"></a>00984     <a class="code" href="struct__com2SecEntry.html">com2SecEntry</a>   *e = NULL;
<a name="l00985"></a>00985     in_addr_t   network = 0, mask = 0;
<a name="l00986"></a>00986 
<a name="l00987"></a>00987     <span class="comment">/*</span>
<a name="l00988"></a>00988 <span class="comment">     * Get security, source address/netmask and community strings.  </span>
<a name="l00989"></a>00989 <span class="comment">     */</span>
<a name="l00990"></a>00990 
<a name="l00991"></a>00991     cp = copy_nword( param, secName, <span class="keyword">sizeof</span>(secName));
<a name="l00992"></a>00992     <span class="keywordflow">if</span> (strcmp(secName, <span class="stringliteral">&quot;-Cn&quot;</span>) == 0) {
<a name="l00993"></a>00993         <span class="keywordflow">if</span> (!cp) {
<a name="l00994"></a>00994             config_perror(<span class="stringliteral">&quot;missing CONTEXT_NAME parameter&quot;</span>);
<a name="l00995"></a>00995             <span class="keywordflow">return</span>;
<a name="l00996"></a>00996         }
<a name="l00997"></a>00997         cp = copy_nword( cp, contextName, <span class="keyword">sizeof</span>(contextName));
<a name="l00998"></a>00998         cp = copy_nword( cp, secName, <span class="keyword">sizeof</span>(secName));
<a name="l00999"></a>00999     } <span class="keywordflow">else</span> {
<a name="l01000"></a>01000         contextName[0] = <span class="charliteral">&#39;\0&#39;</span>;
<a name="l01001"></a>01001     }
<a name="l01002"></a>01002     <span class="keywordflow">if</span> (secName[0] == <span class="charliteral">&#39;\0&#39;</span>) {
<a name="l01003"></a>01003         config_perror(<span class="stringliteral">&quot;missing NAME parameter&quot;</span>);
<a name="l01004"></a>01004         <span class="keywordflow">return</span>;
<a name="l01005"></a>01005     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (strlen(secName) &gt; (VACMSTRINGLEN - 1)) {
<a name="l01006"></a>01006         config_perror(<span class="stringliteral">&quot;security name too long&quot;</span>);
<a name="l01007"></a>01007         <span class="keywordflow">return</span>;
<a name="l01008"></a>01008     }
<a name="l01009"></a>01009     cp = copy_nword( cp, source, <span class="keyword">sizeof</span>(source));
<a name="l01010"></a>01010     <span class="keywordflow">if</span> (source[0] == <span class="charliteral">&#39;\0&#39;</span>) {
<a name="l01011"></a>01011         config_perror(<span class="stringliteral">&quot;missing SOURCE parameter&quot;</span>);
<a name="l01012"></a>01012         <span class="keywordflow">return</span>;
<a name="l01013"></a>01013     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (strncmp(source, EXAMPLE_NETWORK, strlen(EXAMPLE_NETWORK)) ==
<a name="l01014"></a>01014                0) {
<a name="l01015"></a>01015         config_perror(<span class="stringliteral">&quot;example config NETWORK not properly configured&quot;</span>);
<a name="l01016"></a>01016         <span class="keywordflow">return</span>;
<a name="l01017"></a>01017     }
<a name="l01018"></a>01018     cp = copy_nword( cp, community, <span class="keyword">sizeof</span>(community));
<a name="l01019"></a>01019     <span class="keywordflow">if</span> (community[0] == <span class="charliteral">&#39;\0&#39;</span>) {
<a name="l01020"></a>01020         config_perror(<span class="stringliteral">&quot;missing COMMUNITY parameter\n&quot;</span>);
<a name="l01021"></a>01021         <span class="keywordflow">return</span>;
<a name="l01022"></a>01022     } <span class="keywordflow">else</span>
<a name="l01023"></a>01023         <span class="keywordflow">if</span> (strncmp
<a name="l01024"></a>01024             (community, EXAMPLE_COMMUNITY, strlen(EXAMPLE_COMMUNITY))
<a name="l01025"></a>01025             == 0) {
<a name="l01026"></a>01026         config_perror(<span class="stringliteral">&quot;example config COMMUNITY not properly configured&quot;</span>);
<a name="l01027"></a>01027         <span class="keywordflow">return</span>;
<a name="l01028"></a>01028     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (strlen(community) &gt; (COMMUNITY_MAX_LEN - 1)) {
<a name="l01029"></a>01029         config_perror(<span class="stringliteral">&quot;community name too long&quot;</span>);
<a name="l01030"></a>01030         <span class="keywordflow">return</span>;
<a name="l01031"></a>01031     }
<a name="l01032"></a>01032 
<a name="l01033"></a>01033     <span class="comment">/*</span>
<a name="l01034"></a>01034 <span class="comment">     * Process the source address/netmask string.  </span>
<a name="l01035"></a>01035 <span class="comment">     */</span>
<a name="l01036"></a>01036 
<a name="l01037"></a>01037     cp = strchr(source, <span class="charliteral">&#39;/&#39;</span>);
<a name="l01038"></a>01038     <span class="keywordflow">if</span> (cp != NULL) {
<a name="l01039"></a>01039         <span class="comment">/*</span>
<a name="l01040"></a>01040 <span class="comment">         * Mask given.  </span>
<a name="l01041"></a>01041 <span class="comment">         */</span>
<a name="l01042"></a>01042         *cp = <span class="charliteral">&#39;\0&#39;</span>;
<a name="l01043"></a>01043         strmask = cp + 1;
<a name="l01044"></a>01044     }
<a name="l01045"></a>01045 
<a name="l01046"></a>01046     <span class="comment">/*</span>
<a name="l01047"></a>01047 <span class="comment">     * Deal with the network part first.  </span>
<a name="l01048"></a>01048 <span class="comment">     */</span>
<a name="l01049"></a>01049 
<a name="l01050"></a>01050     <span class="keywordflow">if</span> ((strcmp(source, <span class="stringliteral">&quot;default&quot;</span>) == 0)
<a name="l01051"></a>01051         || (strcmp(source, <span class="stringliteral">&quot;0.0.0.0&quot;</span>) == 0)) {
<a name="l01052"></a>01052         network = 0;
<a name="l01053"></a>01053         strmask = <span class="stringliteral">&quot;0.0.0.0&quot;</span>;
<a name="l01054"></a>01054     } <span class="keywordflow">else</span> {
<a name="l01055"></a>01055         <span class="comment">/*</span>
<a name="l01056"></a>01056 <span class="comment">         * Try interpreting as a dotted quad.  </span>
<a name="l01057"></a>01057 <span class="comment">         */</span>
<a name="l01058"></a>01058         network = inet_addr(source);
<a name="l01059"></a>01059 
<a name="l01060"></a>01060         <span class="keywordflow">if</span> (network == (in_addr_t) -1) {
<a name="l01061"></a>01061             <span class="comment">/*</span>
<a name="l01062"></a>01062 <span class="comment">             * Nope, wasn&#39;t a dotted quad.  Must be a hostname.  </span>
<a name="l01063"></a>01063 <span class="comment">             */</span>
<a name="l01064"></a>01064 <span class="preprocessor">#ifdef  HAVE_GETHOSTBYNAME</span>
<a name="l01065"></a>01065 <span class="preprocessor"></span>            <span class="keyword">struct </span>hostent *hp = gethostbyname(source);
<a name="l01066"></a>01066             <span class="keywordflow">if</span> (hp == NULL) {
<a name="l01067"></a>01067                 config_perror(<span class="stringliteral">&quot;bad source address&quot;</span>);
<a name="l01068"></a>01068                 <span class="keywordflow">return</span>;
<a name="l01069"></a>01069             } <span class="keywordflow">else</span> {
<a name="l01070"></a>01070                 <span class="keywordflow">if</span> (hp-&gt;h_addrtype != AF_INET) {
<a name="l01071"></a>01071                     config_perror(<span class="stringliteral">&quot;no IP address for source hostname&quot;</span>);
<a name="l01072"></a>01072                     <span class="keywordflow">return</span>;
<a name="l01073"></a>01073                 }
<a name="l01074"></a>01074                 network = *((in_addr_t *) hp-&gt;h_addr);
<a name="l01075"></a>01075             }
<a name="l01076"></a>01076 <span class="preprocessor">#else                           </span><span class="comment">/*HAVE_GETHOSTBYNAME */</span>
<a name="l01077"></a>01077             <span class="comment">/*</span>
<a name="l01078"></a>01078 <span class="comment">             * Oh dear.  </span>
<a name="l01079"></a>01079 <span class="comment">             */</span>
<a name="l01080"></a>01080             config_perror(<span class="stringliteral">&quot;cannot resolve source hostname&quot;</span>);
<a name="l01081"></a>01081             <span class="keywordflow">return</span>;
<a name="l01082"></a>01082 <span class="preprocessor">#endif                          </span><span class="comment">/*HAVE_GETHOSTBYNAME */</span>
<a name="l01083"></a>01083         }
<a name="l01084"></a>01084     }
<a name="l01085"></a>01085 
<a name="l01086"></a>01086     <span class="comment">/*</span>
<a name="l01087"></a>01087 <span class="comment">     * Now work out the mask.  </span>
<a name="l01088"></a>01088 <span class="comment">     */</span>
<a name="l01089"></a>01089 
<a name="l01090"></a>01090     <span class="keywordflow">if</span> (strmask == NULL || *strmask == <span class="charliteral">&#39;\0&#39;</span>) {
<a name="l01091"></a>01091         <span class="comment">/*</span>
<a name="l01092"></a>01092 <span class="comment">         * No mask was given.  Use 255.255.255.255.  </span>
<a name="l01093"></a>01093 <span class="comment">         */</span>
<a name="l01094"></a>01094         mask = 0xffffffffL;
<a name="l01095"></a>01095     } <span class="keywordflow">else</span> {
<a name="l01096"></a>01096         <span class="keywordflow">if</span> (strchr(strmask, <span class="charliteral">&#39;.&#39;</span>)) {
<a name="l01097"></a>01097             <span class="comment">/*</span>
<a name="l01098"></a>01098 <span class="comment">             * Try to interpret mask as a dotted quad.  </span>
<a name="l01099"></a>01099 <span class="comment">             */</span>
<a name="l01100"></a>01100             mask = inet_addr(strmask);
<a name="l01101"></a>01101             <span class="keywordflow">if</span> (mask == (in_addr_t) -1 &amp;&amp;
<a name="l01102"></a>01102                 strncmp(strmask, <span class="stringliteral">&quot;255.255.255.255&quot;</span>, 15) != 0) {
<a name="l01103"></a>01103                 config_perror(<span class="stringliteral">&quot;bad mask&quot;</span>);
<a name="l01104"></a>01104                 <span class="keywordflow">return</span>;
<a name="l01105"></a>01105             }
<a name="l01106"></a>01106         } <span class="keywordflow">else</span> {
<a name="l01107"></a>01107             <span class="comment">/*</span>
<a name="l01108"></a>01108 <span class="comment">             * Try to interpret mask as a &quot;number of 1 bits&quot;.  </span>
<a name="l01109"></a>01109 <span class="comment">             */</span>
<a name="l01110"></a>01110             <span class="keywordtype">int</span>             maskLen = atoi(strmask), maskBit = 0x80000000L;
<a name="l01111"></a>01111             <span class="keywordflow">if</span> (maskLen &lt;= 0 || maskLen &gt; 32) {
<a name="l01112"></a>01112                 config_perror(<span class="stringliteral">&quot;bad mask length&quot;</span>);
<a name="l01113"></a>01113                 <span class="keywordflow">return</span>;
<a name="l01114"></a>01114             }
<a name="l01115"></a>01115             <span class="keywordflow">while</span> (maskLen--) {
<a name="l01116"></a>01116                 mask |= maskBit;
<a name="l01117"></a>01117                 maskBit &gt;&gt;= 1;
<a name="l01118"></a>01118             }
<a name="l01119"></a>01119             mask = htonl(mask);
<a name="l01120"></a>01120         }
<a name="l01121"></a>01121     }
<a name="l01122"></a>01122 
<a name="l01123"></a>01123     <span class="comment">/*</span>
<a name="l01124"></a>01124 <span class="comment">     * Check that the network and mask are consistent.  </span>
<a name="l01125"></a>01125 <span class="comment">     */</span>
<a name="l01126"></a>01126 
<a name="l01127"></a>01127     <span class="keywordflow">if</span> (network &amp; ~mask) {
<a name="l01128"></a>01128         config_perror(<span class="stringliteral">&quot;source/mask mismatch&quot;</span>);
<a name="l01129"></a>01129         <span class="keywordflow">return</span>;
<a name="l01130"></a>01130     }
<a name="l01131"></a>01131 
<a name="l01132"></a>01132     e = (<a class="code" href="struct__com2SecEntry.html">com2SecEntry</a> *) malloc(<span class="keyword">sizeof</span>(<a class="code" href="struct__com2SecEntry.html">com2SecEntry</a>));
<a name="l01133"></a>01133     <span class="keywordflow">if</span> (e == NULL) {
<a name="l01134"></a>01134         config_perror(<span class="stringliteral">&quot;memory error&quot;</span>);
<a name="l01135"></a>01135         <span class="keywordflow">return</span>;
<a name="l01136"></a>01136     }
<a name="l01137"></a>01137 
<a name="l01138"></a>01138     <span class="comment">/*</span>
<a name="l01139"></a>01139 <span class="comment">     * Everything is okay.  Copy the parameters to the structure allocated</span>
<a name="l01140"></a>01140 <span class="comment">     * above and add it to END of the list.  </span>
<a name="l01141"></a>01141 <span class="comment">     */</span>
<a name="l01142"></a>01142 
<a name="l01143"></a>01143     DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp_parse_security&quot;</span>,
<a name="l01144"></a>01144                 <span class="stringliteral">&quot;&lt;\&quot;%s\&quot;, 0x%08x/0x%08x&gt; =&gt; \&quot;%s\&quot;\n&quot;</span>, community, network,
<a name="l01145"></a>01145                 mask, secName));
<a name="l01146"></a>01146 
<a name="l01147"></a>01147     strcpy(e-&gt;contextName, contextName);
<a name="l01148"></a>01148     strcpy(e-&gt;secName, secName);
<a name="l01149"></a>01149     strcpy(e-&gt;community, community);
<a name="l01150"></a>01150     e-&gt;network = network;
<a name="l01151"></a>01151     e-&gt;mask = mask;
<a name="l01152"></a>01152     e-&gt;next = NULL;
<a name="l01153"></a>01153 
<a name="l01154"></a>01154     <span class="keywordflow">if</span> (com2SecListLast != NULL) {
<a name="l01155"></a>01155         com2SecListLast-&gt;next = e;
<a name="l01156"></a>01156         com2SecListLast = e;
<a name="l01157"></a>01157     } <span class="keywordflow">else</span> {
<a name="l01158"></a>01158         com2SecListLast = com2SecList = e;
<a name="l01159"></a>01159     }
<a name="l01160"></a>01160 }
<a name="l01161"></a>01161 
<a name="l01162"></a>01162 
<a name="l01163"></a>01163 <span class="keywordtype">void</span>
<a name="l01164"></a>01164 netsnmp_udp_com2SecList_free(<span class="keywordtype">void</span>)
<a name="l01165"></a>01165 {
<a name="l01166"></a>01166     <a class="code" href="struct__com2SecEntry.html">com2SecEntry</a>   *e = com2SecList;
<a name="l01167"></a>01167     <span class="keywordflow">while</span> (e != NULL) {
<a name="l01168"></a>01168         <a class="code" href="struct__com2SecEntry.html">com2SecEntry</a>   *tmp = e;
<a name="l01169"></a>01169         e = e-&gt;next;
<a name="l01170"></a>01170         free(tmp);
<a name="l01171"></a>01171     }
<a name="l01172"></a>01172     com2SecList = com2SecListLast = NULL;
<a name="l01173"></a>01173 }
<a name="l01174"></a>01174 <span class="preprocessor">#endif </span><span class="comment">/* support for community based SNMP */</span>
<a name="l01175"></a>01175 
<a name="l01176"></a>01176 <span class="keywordtype">void</span>
<a name="l01177"></a>01177 netsnmp_udp_agent_config_tokens_register(<span class="keywordtype">void</span>)
<a name="l01178"></a>01178 {
<a name="l01179"></a>01179 <span class="preprocessor">#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)</span>
<a name="l01180"></a>01180 <span class="preprocessor"></span>    register_app_config_handler(<span class="stringliteral">&quot;com2sec&quot;</span>, netsnmp_udp_parse_security,
<a name="l01181"></a>01181                                 netsnmp_udp_com2SecList_free,
<a name="l01182"></a>01182                                 <span class="stringliteral">&quot;[-Cn CONTEXT] secName IPv4-network-address[/netmask] community&quot;</span>);
<a name="l01183"></a>01183 <span class="preprocessor">#endif </span><span class="comment">/* support for community based SNMP */</span>
<a name="l01184"></a>01184 }
<a name="l01185"></a>01185 
<a name="l01186"></a>01186 
<a name="l01187"></a>01187 
<a name="l01188"></a>01188 <span class="comment">/*</span>
<a name="l01189"></a>01189 <span class="comment"> * Return 0 if there are no com2sec entries, or return 1 if there ARE com2sec </span>
<a name="l01190"></a>01190 <span class="comment"> * entries.  On return, if a com2sec entry matched the passed parameters,</span>
<a name="l01191"></a>01191 <span class="comment"> * then *secName points at the appropriate security name, or is NULL if the</span>
<a name="l01192"></a>01192 <span class="comment"> * parameters did not match any com2sec entry.  </span>
<a name="l01193"></a>01193 <span class="comment"> */</span>
<a name="l01194"></a>01194 
<a name="l01195"></a>01195 <span class="preprocessor">#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)</span>
<a name="l01196"></a>01196 <span class="preprocessor"></span><span class="keywordtype">int</span>
<a name="l01197"></a>01197 netsnmp_udp_getSecName(<span class="keywordtype">void</span> *opaque, <span class="keywordtype">int</span> olength,
<a name="l01198"></a>01198                        <span class="keyword">const</span> <span class="keywordtype">char</span> *community,
<a name="l01199"></a>01199                        <span class="keywordtype">size_t</span> community_len, <span class="keywordtype">char</span> **secName,
<a name="l01200"></a>01200                        <span class="keywordtype">char</span> **contextName)
<a name="l01201"></a>01201 {
<a name="l01202"></a>01202     <a class="code" href="struct__com2SecEntry.html">com2SecEntry</a>   *c;
<a name="l01203"></a>01203     <a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a> *addr_pair = (<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a> *) opaque;
<a name="l01204"></a>01204     <span class="keyword">struct </span>sockaddr_in *from = (<span class="keyword">struct </span>sockaddr_in *) &amp;(addr_pair-&gt;remote_addr);
<a name="l01205"></a>01205     <span class="keywordtype">char</span>           *ztcommunity = NULL;
<a name="l01206"></a>01206 
<a name="l01207"></a>01207     <span class="keywordflow">if</span> (secName != NULL) {
<a name="l01208"></a>01208         *secName = NULL;  <span class="comment">/* Haven&#39;t found anything yet */</span>
<a name="l01209"></a>01209     }
<a name="l01210"></a>01210 
<a name="l01211"></a>01211     <span class="comment">/*</span>
<a name="l01212"></a>01212 <span class="comment">     * Special case if there are NO entries (as opposed to no MATCHING</span>
<a name="l01213"></a>01213 <span class="comment">     * entries).  </span>
<a name="l01214"></a>01214 <span class="comment">     */</span>
<a name="l01215"></a>01215 
<a name="l01216"></a>01216     <span class="keywordflow">if</span> (com2SecList == NULL) {
<a name="l01217"></a>01217         DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp_getSecName&quot;</span>, <span class="stringliteral">&quot;no com2sec entries\n&quot;</span>));
<a name="l01218"></a>01218         <span class="keywordflow">return</span> 0;
<a name="l01219"></a>01219     }
<a name="l01220"></a>01220 
<a name="l01221"></a>01221     <span class="comment">/*</span>
<a name="l01222"></a>01222 <span class="comment">     * If there is no IPv4 source address, then there can be no valid security</span>
<a name="l01223"></a>01223 <span class="comment">     * name.  </span>
<a name="l01224"></a>01224 <span class="comment">     */</span>
<a name="l01225"></a>01225 
<a name="l01226"></a>01226     <span class="keywordflow">if</span> (opaque == NULL || olength != <span class="keyword">sizeof</span>(<a class="code" href="structnetsnmp__udp__addr__pair__s.html">netsnmp_udp_addr_pair</a>) ||
<a name="l01227"></a>01227         from-&gt;sin_family != AF_INET) {
<a name="l01228"></a>01228         DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp_getSecName&quot;</span>,
<a name="l01229"></a>01229                     <span class="stringliteral">&quot;no IPv4 source address in PDU?\n&quot;</span>));
<a name="l01230"></a>01230         <span class="keywordflow">return</span> 1;
<a name="l01231"></a>01231     }
<a name="l01232"></a>01232 
<a name="l01233"></a>01233     DEBUGIF(<span class="stringliteral">&quot;netsnmp_udp_getSecName&quot;</span>) {
<a name="l01234"></a>01234         ztcommunity = (<span class="keywordtype">char</span> *)malloc(community_len + 1);
<a name="l01235"></a>01235         <span class="keywordflow">if</span> (ztcommunity != NULL) {
<a name="l01236"></a>01236             memcpy(ztcommunity, community, community_len);
<a name="l01237"></a>01237             ztcommunity[community_len] = <span class="charliteral">&#39;\0&#39;</span>;
<a name="l01238"></a>01238         }
<a name="l01239"></a>01239 
<a name="l01240"></a>01240         DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp_getSecName&quot;</span>, <span class="stringliteral">&quot;resolve &lt;\&quot;%s\&quot;, 0x%08x&gt;\n&quot;</span>,
<a name="l01241"></a>01241                     ztcommunity ? ztcommunity : <span class="stringliteral">&quot;&lt;malloc error&gt;&quot;</span>,
<a name="l01242"></a>01242                     from-&gt;sin_addr.s_addr));
<a name="l01243"></a>01243     }
<a name="l01244"></a>01244 
<a name="l01245"></a>01245     <span class="keywordflow">for</span> (c = com2SecList; c != NULL; c = c-&gt;next) {
<a name="l01246"></a>01246         DEBUGMSGTL((<span class="stringliteral">&quot;netsnmp_udp_getSecName&quot;</span>,<span class="stringliteral">&quot;compare &lt;\&quot;%s\&quot;, 0x%08x/0x%08x&gt;&quot;</span>,
<a name="l01247"></a>01247                     c-&gt;community, c-&gt;network, c-&gt;mask));
<a name="l01248"></a>01248         <span class="keywordflow">if</span> ((community_len == strlen(c-&gt;community)) &amp;&amp;
<a name="l01249"></a>01249             (memcmp(community, c-&gt;community, community_len) == 0) &amp;&amp;
<a name="l01250"></a>01250             ((from-&gt;sin_addr.s_addr &amp; c-&gt;mask) == c-&gt;network)) {
<a name="l01251"></a>01251             DEBUGMSG((<span class="stringliteral">&quot;netsnmp_udp_getSecName&quot;</span>, <span class="stringliteral">&quot;... SUCCESS\n&quot;</span>));
<a name="l01252"></a>01252             <span class="keywordflow">if</span> (secName != NULL) {
<a name="l01253"></a>01253                 *secName = c-&gt;secName;
<a name="l01254"></a>01254                 *contextName = c-&gt;contextName;
<a name="l01255"></a>01255             }
<a name="l01256"></a>01256             <span class="keywordflow">break</span>;
<a name="l01257"></a>01257         }
<a name="l01258"></a>01258         DEBUGMSG((<span class="stringliteral">&quot;netsnmp_udp_getSecName&quot;</span>, <span class="stringliteral">&quot;... nope\n&quot;</span>));
<a name="l01259"></a>01259     }
<a name="l01260"></a>01260     <span class="keywordflow">if</span> (ztcommunity != NULL) {
<a name="l01261"></a>01261         free(ztcommunity);
<a name="l01262"></a>01262     }
<a name="l01263"></a>01263     <span class="keywordflow">return</span> 1;
<a name="l01264"></a>01264 }
<a name="l01265"></a>01265 <span class="preprocessor">#endif </span><span class="comment">/* support for community based SNMP */</span>
<a name="l01266"></a>01266 
<a name="l01267"></a>01267 
<a name="l01268"></a>01268 <a class="code" href="structnetsnmp__transport__s.html">netsnmp_transport</a> *
<a name="l01269"></a>01269 netsnmp_udp_create_tstring(<span class="keyword">const</span> <span class="keywordtype">char</span> *str, <span class="keywordtype">int</span> local,
<a name="l01270"></a>01270                            <span class="keyword">const</span> <span class="keywordtype">char</span> *default_target)
<a name="l01271"></a>01271 {
<a name="l01272"></a>01272     <span class="keyword">struct </span>sockaddr_in addr;
<a name="l01273"></a>01273 
<a name="l01274"></a>01274     <span class="keywordflow">if</span> (netsnmp_sockaddr_in2(&amp;addr, str, default_target)) {
<a name="l01275"></a>01275         <span class="keywordflow">return</span> netsnmp_udp_transport(&amp;addr, local);
<a name="l01276"></a>01276     } <span class="keywordflow">else</span> {
<a name="l01277"></a>01277         <span class="keywordflow">return</span> NULL;
<a name="l01278"></a>01278     }
<a name="l01279"></a>01279 }
<a name="l01280"></a>01280 
<a name="l01281"></a>01281 
<a name="l01282"></a>01282 <a class="code" href="structnetsnmp__transport__s.html">netsnmp_transport</a> *
<a name="l01283"></a>01283 netsnmp_udp_create_ostring(<span class="keyword">const</span> u_char * o, <span class="keywordtype">size_t</span> o_len, <span class="keywordtype">int</span> local)
<a name="l01284"></a>01284 {
<a name="l01285"></a>01285     <span class="keyword">struct </span>sockaddr_in addr;
<a name="l01286"></a>01286 
<a name="l01287"></a>01287     <span class="keywordflow">if</span> (o_len == 6) {
<a name="l01288"></a>01288         <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> porttmp = (o[4] &lt;&lt; 8) + o[5];
<a name="l01289"></a>01289         addr.sin_family = AF_INET;
<a name="l01290"></a>01290         memcpy((u_char *) &amp; (addr.sin_addr.s_addr), o, 4);
<a name="l01291"></a>01291         addr.sin_port = htons(porttmp);
<a name="l01292"></a>01292         <span class="keywordflow">return</span> netsnmp_udp_transport(&amp;addr, local);
<a name="l01293"></a>01293     }
<a name="l01294"></a>01294     <span class="keywordflow">return</span> NULL;
<a name="l01295"></a>01295 }
<a name="l01296"></a>01296 
<a name="l01297"></a>01297 
<a name="l01298"></a>01298 <span class="keywordtype">void</span>
<a name="l01299"></a>01299 netsnmp_udp_ctor(<span class="keywordtype">void</span>)
<a name="l01300"></a>01300 {
<a name="l01301"></a>01301     udpDomain.name = netsnmpUDPDomain;
<a name="l01302"></a>01302     udpDomain.name_length = netsnmpUDPDomain_len;
<a name="l01303"></a>01303     udpDomain.prefix = (<span class="keyword">const</span> <span class="keywordtype">char</span>**)calloc(2, <span class="keyword">sizeof</span>(<span class="keywordtype">char</span> *));
<a name="l01304"></a>01304     udpDomain.prefix[0] = <span class="stringliteral">&quot;udp&quot;</span>;
<a name="l01305"></a>01305 
<a name="l01306"></a>01306     udpDomain.f_create_from_tstring_new = netsnmp_udp_create_tstring;
<a name="l01307"></a>01307     udpDomain.f_create_from_ostring = netsnmp_udp_create_ostring;
<a name="l01308"></a>01308 
<a name="l01309"></a>01309     netsnmp_tdomain_register(&amp;udpDomain);
<a name="l01310"></a>01310 }
</pre></div></div><!-- contents -->


<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.7.6.1
</small></address>

</body>
</html>