/[monit]/monit/net.c
ViewVC logotype

Diff of /monit/net.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.37 by martinp, Wed Sep 17 18:40:21 2003 UTC revision 1.38 by martinp, Thu Sep 25 15:22:10 2003 UTC
# Line 39  Line 39 
39  #define _BSD_SOCKLEN_T_  #define _BSD_SOCKLEN_T_
40  #endif  #endif
41    
42    #ifdef HAVE_NETINET_IN_H
43    #include <netinet/in.h>
44    #endif
45    
46  #ifdef HAVE_SYS_SOCKET_H  #ifdef HAVE_SYS_SOCKET_H
47  #include <sys/socket.h>  #include <sys/socket.h>
48  #endif  #endif
# Line 67  Line 71 
71  #include <netdb.h>  #include <netdb.h>
72  #endif  #endif
73    
 #ifdef HAVE_NETINET_IN_H  
 #include <netinet/in.h>  
 #endif  
   
74  #ifdef HAVE_SYS_TIME_H  #ifdef HAVE_SYS_TIME_H
75  #include <sys/time.h>  #include <sys/time.h>
76  #endif  #endif
# Line 87  Line 87 
87  #include <sys/filio.h>  #include <sys/filio.h>
88  #endif  #endif
89    
90    #ifdef HAVE_NETINET_IP_H
91    #include <netinet/ip.h>
92    #endif
93    
94    #ifdef HAVE_NETINET_IP_ICMP_H
95    #include <netinet/ip_icmp.h>
96    #endif
97    
98  #ifdef HAVE_STRING_H  #ifdef HAVE_STRING_H
99  #include <string.h>  #include <string.h>
100  #endif  #endif
# Line 113  Line 121 
121   *  General purpose Network and Socket methods.   *  General purpose Network and Socket methods.
122   *   *
123   *  @author Jan-Henrik Haukeland, <hauk@tildeslash.com>   *  @author Jan-Henrik Haukeland, <hauk@tildeslash.com>
124   *  @author Christian Hopp <chopp@iei.tu-clausthal.de>   *  @author Christian Hopp, <chopp@iei.tu-clausthal.de>
125     *  @author Martin Pala, <martin.pala@iol.cz>
126   *   *
127   *  @version \$Id$   *  @version \$Id$
128   *   *
# Line 124  Line 133 
133  /* -------------------------------------------------------------- Prototypes */  /* -------------------------------------------------------------- Prototypes */
134    
135    
136  static int do_connect(int s, const struct sockaddr *addr,  static int do_connect(int, const struct sockaddr *, socklen_t, int);
137                        socklen_t addrlen, int timeout);  static unsigned short checksum_ip(unsigned char *, int);
138    
139    
140  /* ------------------------------------------------------------------ Public */  /* ------------------------------------------------------------------ Public */
# Line 230  int check_udp_socket(int socket) { Line 239  int check_udp_socket(int socket) {
239    
240  /**  /**
241   * Create a non-blocking socket against hostname:port with the given   * Create a non-blocking socket against hostname:port with the given
242   * protocol. The protocol should be either SOCK_STREAM or SOCK_DGRAM.   * type. The type should be either SOCK_STREAM or SOCK_DGRAM.
243   * @param hostname The host to open a socket at   * @param hostname The host to open a socket at
244   * @param port The port number to connect to   * @param port The port number to connect to
245   * @param protocol Socket protocol to use (SOCK_STREAM|SOCK_DGRAM)   * @param type Socket type to use (SOCK_STREAM|SOCK_DGRAM)
246   * @param timeout If not connected within timeout seconds abort and return -1   * @param timeout If not connected within timeout seconds abort and return -1
247   * @return The socket or -1 if an error occured.   * @return The socket or -1 if an error occured.
248   */   */
249  int create_socket(const char *hostname, int port, int protocol, int timeout) {  int create_socket(const char *hostname, int port, int type, int timeout) {
250    
251    int s;    int s;
252    struct hostent *hp;    struct hostent *hp;
# Line 249  int create_socket(const char *hostname, Line 258  int create_socket(const char *hostname,
258      return -1;      return -1;
259    }    }
260    
261    if((s= socket(AF_INET, protocol, 0)) < 0) {    if((s= socket(AF_INET, type, 0)) < 0) {
262      return -1;      return -1;
263    }    }
264    
# Line 368  int create_server_socket(int port, int b Line 377  int create_server_socket(int port, int b
377        
378    if(bindAddr) {    if(bindAddr) {
379      struct hostent *h= gethostbyname(bindAddr);      struct hostent *h= gethostbyname(bindAddr);
     endhostent();  
380      if(h==NULL) {      if(h==NULL) {
381        errno= h_errno;        errno= h_errno;
382        goto error;        goto error;
# Line 378  int create_server_socket(int port, int b Line 386  int create_server_socket(int port, int b
386      myaddr.sin_addr.s_addr= htonl(INADDR_ANY);      myaddr.sin_addr.s_addr= htonl(INADDR_ANY);
387    }    }
388        
389    if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(int)) < 0)    if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)) < 0)
390      goto error;      goto error;
391        
392    if(! set_noblock(s))    if(! set_noblock(s))
# Line 578  int sock_read(int socket, void *buffer, Line 586  int sock_read(int socket, void *buffer,
586  }  }
587    
588    
589    /**
590     * Create a ICMP socket against hostname, send echo and wait for response.
591     * @param hostname The host to open a socket at
592     * @param timeout If response will not come within timeout seconds abort
593     * @return TRUE on succes, FALSE on error
594     */
595    int icmp_echo(const char *hostname, int timeout) {
596    
597      struct hostent *hp;
598      struct sockaddr_in sin;
599      struct sockaddr_in sout;
600      struct iphdr *iphdrin;
601      struct icmphdr *icmphdrin= NULL;
602      struct icmphdr *icmphdrout= NULL;
603      struct timeval tv;
604      size_t size;
605      fd_set rset;
606      int s;
607      int n= 0;
608      int rv= FALSE;
609      unsigned ttl= 255;
610      unsigned short mypid;
611      char buf[STRLEN];
612      
613      ASSERT(hostname);
614    
615      mypid= getpid();
616    
617      if( (hp= gethostbyname(hostname)) == NULL )
618        return FALSE;
619    
620      if( (s= socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0 )
621        return FALSE;
622    
623      if( setsockopt(s, SOL_IP, IP_TTL, (char *)&ttl, sizeof(ttl)) < 0 )
624        goto error;
625    
626      icmphdrout= (struct icmphdr *)xmalloc(sizeof(struct icmphdr));
627      icmphdrout->type= ICMP_ECHO;
628      icmphdrout->code= 0;
629      icmphdrout->un.echo.id= mypid;
630      icmphdrout->un.echo.sequence= 0;
631      icmphdrout->checksum= checksum_ip((unsigned char *)icmphdrout,
632                                        sizeof(struct icmphdr));
633    
634      sout.sin_family= AF_INET;
635      sout.sin_port= 0;
636      memcpy(&sout.sin_addr, hp->h_addr, hp->h_length);
637    
638      sendto(s, (char *)icmphdrout, sizeof(struct icmphdr), 0,
639             (struct sockaddr *)&sout, sizeof(struct sockaddr));
640    
641      tv.tv_sec= timeout;
642      tv.tv_usec= 0;
643    
644      do {
645    
646        FD_ZERO(&rset);
647        FD_SET(s, &rset);
648    
649        do {
650          n= select(s+1, &rset, NULL, NULL, &tv);
651        } while(n == -1 && errno == EINTR);
652    
653        if(n <= 0)
654          goto error;
655    
656        size= sizeof(struct sockaddr_in);
657    
658        if(recvfrom(s, buf, STRLEN, 0, (struct sockaddr *)&sin, &size) == -1)
659          goto error;
660    
661        iphdrin= (struct iphdr *)buf;
662        icmphdrin= (struct icmphdr *)(buf + iphdrin->ihl * 4);
663    
664        if( (icmphdrin->un.echo.id == mypid) &&
665            (icmphdrin->type == ICMP_ECHOREPLY) &&
666            (icmphdrin->un.echo.sequence == 0) ) {
667    
668          rv= TRUE;
669          break;
670    
671        }
672    
673      } while(! ( (icmphdrin->un.echo.id == mypid) &&
674                  (icmphdrin->type == ICMP_ECHOREPLY) &&
675                  (icmphdrin->un.echo.sequence == 0) ) );
676    
677      error:
678      free(icmphdrout);
679      close_socket(s);
680    
681      return rv;
682    
683    }
684    
685    
686  /* ----------------------------------------------------------------- Private */  /* ----------------------------------------------------------------- Private */
687    
688    
# Line 595  static int do_connect(int s, const struc Line 700  static int do_connect(int s, const struc
700    error= 0;    error= 0;
701        
702    if(0 > (n= connect(s, addr, addrlen)))    if(0 > (n= connect(s, addr, addrlen)))
703        if(errno != EINPROGRESS)      if(errno != EINPROGRESS)
704            return -1;        return -1;
705        
706    FD_ZERO(&rset);    FD_ZERO(&rset);
707    FD_SET(s, &rset);    FD_SET(s, &rset);
# Line 613  static int do_connect(int s, const struc Line 718  static int do_connect(int s, const struc
718    if(FD_ISSET(s, &rset) || FD_ISSET(s, &wset)) {    if(FD_ISSET(s, &rset) || FD_ISSET(s, &wset)) {
719      int len= sizeof(error);      int len= sizeof(error);
720      if(getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) < 0)      if(getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
         return -1;  
   } else  
721        return -1;        return -1;
722      } else
723        return -1;
724    
725    if(error) {    if(error) {
726      errno= error;      errno= error;
# Line 626  static int do_connect(int s, const struc Line 731  static int do_connect(int s, const struc
731        
732  }  }
733    
734    
735    /*
736     * Compute Internet Checksum for "count" bytes beginning at location "addr".
737     * Based on RFC1071.
738     */
739    static unsigned short checksum_ip(unsigned char *addr, int count) {
740    
741      register long sum= 0;
742    
743      while(count > 1) {
744        sum += *((unsigned short *)addr)++;
745        count -= 2;
746      }
747    
748      /* Add left-over byte, if any */
749      if(count > 0)
750        sum += *(unsigned char *)addr;
751    
752      /* Fold 32-bit sum to 16 bits */
753      while(sum >> 16)
754        sum= (sum & 0xffff) + (sum >> 16);
755    
756      return ~sum;
757    
758    }
759    

Legend:
Removed from v.1.37  
changed lines
  Added in v.1.38

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26