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] */