## modules/up/src/util/net.cc

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. init_ipAddr
2. setAddress
3. setAddress
4. Socket
5. setsockopt
6. write
7. read
8. wait_for_reply
9. TCP
10. init_server
11. TCP
12. TCP
13. init_tcp
14. UDP
15. UDP

       1 /*
       2 //  $Id: net.cc,v 1.1.1.1 2000/03/10 16:32:15 engin Exp $
       3 //
       4 //  Copyright (c) 1994 by the University of Southern California
       5 //  All rights reserved.
       6 //
       7 //  Permission to use, copy, modify, and distribute this software and its
       8 //  documentation in source and binary forms for lawful non-commercial
       9 //  purposes and without fee is hereby granted, provided that the above
      10 //  copyright notice appear in all copies and that both the copyright
      11 //  notice and this permission notice appear in supporting documentation,
      12 //  and that any documentation, advertising materials, and other materials
      13 //  related to such distribution and use acknowledge that the software was
      14 //  developed by the University of Southern California, Information
      15 //  Sciences Institute. The name of the USC may not be used to endorse or
      16 //  promote products derived from this software without specific prior
      17 //  written permission.
      18 //
      19 //  THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY
      20 //  REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY
      21 //  PURPOSE.  THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
      22 //  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
      23 //  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
      24 //  TITLE, AND NON-INFRINGEMENT.
      25 //
      26 //  IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
      27 //  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT, TORT,
      28 //  OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH, THE USE
      29 //  OR PERFORMANCE OF THIS SOFTWARE.
      30 //
      31 //  Questions concerning this software should be directed to
      32 //  ratoolset@isi.edu.
      33 //
      34 //  Author(s): eddy@isi.edu
      35 */
      36
      37 #include "net.hh"
      38
      39 //
      40 // setName sets either the hexaddr or the hostname, then calls
      41 // _getHostent() to fill in the hostent and copy the official
      42 // values into the redundant vars in the ipAddr class
      43 //
      44 void
      45 ipAddr::init_ipAddr () {
         /* [<][>][^][v][top][bottom][index][help] */
      46     bzero ((char *) &hostname, MAXHOSTNAMELEN);
      47     bzero ((char *) &dottedaddr, sizeof (dottedaddr));
      48     bzero ((char *) &maskedaddr, sizeof (maskedaddr));
      49     bzero ((char *) &asname, sizeof (asname));
      50     hp = (struct hostent *) NULL;
      51     mask   = 32;                // default to a host, unless changed
      52     hexaddr = 0;
      53 }
      54
      55 int
      56 ipAddr::setAddress (const char *addr)
         /* [<][>][^][v][top][bottom][index][help] */
      57 {
      58     hp = (struct hostent *) NULL;
      59     hexaddr = (u_long) inet_addr (addr);
      60     if (hexaddr != INADDR_NONE) {
      61         hp = gethostbyaddr ((char *) &hexaddr, sizeof (hexaddr), AF_INET);
      62     } else {
      63         hp = gethostbyname ((char *) addr);
      64     }
      65     if (hp) {
      66         bcopy (hp->h_addr, (caddr_t) &hexaddr, (size_t) hp->h_length);
      67         strcpy (hostname, hp->h_name);
      68     }
      69     if (hp == NULL && hexaddr == INADDR_NONE)
      70         error.fatal ("Could not resolve %s\0", addr);
      71     return (error());
      72 }
      73
      74 int
      75 ipAddr::setAddress (u_long hex)
         /* [<][>][^][v][top][bottom][index][help] */
      76 {
      77     hp = (struct hostent *) NULL;
      78     hexaddr = hex;
      79     hp = gethostbyaddr ((char *) &hexaddr, sizeof (hexaddr), AF_INET);
      80     if (hp) {
      81         bcopy (hp->h_addr, (caddr_t) &hexaddr, (size_t) hp->h_length);
      82         strcpy (hostname, hp->h_name);
      83     }
      84     // we should do a range check on hexaddr and throw an exception
      85     if (!hp)
      86         error.fatal ("Could not set ipaddr for 0x%x", hex);
      87     return (error());
      88 }
      89
      90 ////////////////////////////////////////////////////////////////////////
      91 Socket::Socket (u_int f, u_int t, u_int p)
         /* [<][>][^][v][top][bottom][index][help] */
      92 {
      93     bzero ((char *) &sockdst, sizeof (sockdst));
      94     bzero ((char *) &socksrc, sizeof (socksrc));
      95     send_flags = 0;
      96     sockdst.sin_family = family = f;
      97     sockdst.sin_port = proto = p;
      98     socksrc.sin_family = family = f;
      99     socksrc.sin_port = proto = p;
     100     in = out = NULL;
     101     type   = t;
     102     sock = socket (family, type, proto);
     103     if (sock < 0)
     104         error.fatal ("socket");
     105 }
     106
     107 int
     108 Socket::setsockopt (int level, int optname, char *data, int dlen)
         /* [<][>][^][v][top][bottom][index][help] */
     109 {
     110     int on = 1;
     111     switch (level) {
     112       case SOL_SOCKET :
     113         if (optname & SO_DEBUG) {
     114             (void) ::setsockopt (sock, level, SO_DEBUG,
     115                                  (char *) &on, sizeof (on));
     116         }
     117         if (optname & SO_DONTROUTE) {
     118             (void) ::setsockopt (sock, level, SO_DONTROUTE,
     119                                  (char *) &on, sizeof (on));
     120         }
     121         if (optname & SO_SNDBUF) {
     122             error = ::setsockopt(sock, level, SO_SNDBUF,
     123                                  (char *)&data, dlen);
     124             if (error())
     125                 return error.fatal ("setsocketopt: SO_SNDBUF");
     126         }
     127         break;                  // SOL_SOCKET
     128       case IPPROTO_IP:
     129         switch (optname) {
     130 #ifdef IP_HDRINCL
     131          case IP_HDRINCL:
     132             error = ::setsockopt (sock, level, optname, (char *)&on, sizeof(on));
     133             if (error())
     134                 error("setsockopt: IP_HDRINCL");
     135             return error();
     136             break;              // IP_HDRINCL
     137 #endif IP_HDRINCL
     138         }
     139 #ifdef IP_OPTIONS
     140       default:
     141         int err = ::setsockopt (sock, level, optname, (char *) data, dlen);
     142         if (err)
     143             error.fatal ("setsockopt: level: %d, optname: %d\n", level, optname);
     144         return error();
     145         break;
     146 #endif IP_OPTIONS
     147     }
     148 }
     149
     150
     151 int
     152 Socket::write (char *buf, int len)
         /* [<][>][^][v][top][bottom][index][help] */
     153 {
     154     char *b = (char *) buf;
     155     int l = len;
     156     while (l > 0) {
     157         int c = ::write (sock, b, l);
     158         if (c < 0) {
     159             // Added by wlee@isi.edu
     160             if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
     161               errno = 0;
     162               continue;
     163             }
     164             return error.fatal ("write");
     165         }
     166         l -= c;
     167         b += c;
     168     }
     169     return (len - l);
     170 }
     171
     172 int
     173 Socket::read (char *buf, int len)
         /* [<][>][^][v][top][bottom][index][help] */
     174 {
     175     int c = -1;
     176     while (c < 0) {
     177         c = ::read (sock, buf, len);
     178         if (c < 0) {
     179             // Modified by wlee@isi.edu
     180             if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
     181                 errno = 0;
     182                 continue;
     183             }
     184             return error.fatal ("Socket::read");
     185         }
     186     }
     187     return c;
     188 }
     189
     190 int
     191 Socket::wait_for_reply (char *buffer, int size = MAXPACKETLEN, int seconds = 0)
         /* [<][>][^][v][top][bottom][index][help] */
     192 {
     193     fd_set fds;
     194     FD_ZERO (&fds);
     195     FD_SET  (sock, &fds);
     196     Timer timeout(seconds);
     197     int c = select (sock+1, &fds, (fd_set *) NULL, (fd_set *) NULL, timeout.tval());
     198     if (c > 0) {
     199         c = recvfrom ((char *)buffer, 1024);
     200     }
     201     if (c < 0)
     202         error.fatal ("Socket.wait_for_reply");
     203     return c;                   // < 0 = count; 0 = timeout; > 0 = system err
     204 }
     205
     206
     207 ////////////////////////////////////////////////////////////////////////
     208 //
     209 // open up a connection to listen on
     210 //
     211 ////////////////////////////////////////////////////////////////////////
     212 TCP::TCP (int p) :
         /* [<][>][^][v][top][bottom][index][help] */
     213     Socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)
     214 {
     215     init_server (p);
     216 }
     217
     218 int TCP::init_server (int p) {
         /* [<][>][^][v][top][bottom][index][help] */
     219     setLocalPort (p);
     220     bind();
     221     listen();
     222     if (error())
     223         error.fatal ("TCP socket");
     224 }
     225
     226 TCP::TCP (char *hostname, int p) : Socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)
         /* [<][>][^][v][top][bottom][index][help] */
     227 {
     228     service = (struct servent *) NULL;
     229     init_tcp (hostname, p);
     230 }
     231
     232 TCP::TCP (char *hostname, char *s) : Socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)
         /* [<][>][^][v][top][bottom][index][help] */
     233 {
     234     service = getservbyname (s, "tcp");
     235     if (service == NULL) {
     236         error.fatal ("tcp: unknown service: %s\n", s);
     237         return;
     238     }
     239     init_tcp (hostname, service->s_port);
     240 }
     241
     242 int
     243 TCP::init_tcp (char *hostname, int p)
         /* [<][>][^][v][top][bottom][index][help] */
     244 {
     245     ipaddr->setAddress (hostname);
     246     set_dstInaddr (ipaddr->getInaddr());
     247     setPort (p);
     248     port = p;
     249     connect ();
     250     return error();
     251 }
     252
     253
     254
     255 ////////////////////////////////////////////////////////////////////////
     256 UDP::UDP (char *hostname, int p) : Socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)
         /* [<][>][^][v][top][bottom][index][help] */
     257 {
     258     init_udp (hostname, p);
     259 }
     260
     261 UDP::UDP (char *hostname, char *s) : Socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)
         /* [<][>][^][v][top][bottom][index][help] */
     262 {
     263     service = getservbyname (s, "udp");
     264     if (service == NULL) {
     265         error.fatal ("udp: unknown service: %s\n", s);
     266         return;
     267     }
     268     init_udp (hostname, service->s_port);
     269 }

/* [<][>][^][v][top][bottom][index][help] */