00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #ifdef HAVE_SYS_TYPES_H
00025 #include <sys/types.h>
00026 #endif
00027 #include <sys/socket.h>
00028 #include <fcntl.h>
00029 #include <errno.h>
00030 #include <stdarg.h>
00031 #include <signal.h>
00032 #include <net/if.h>
00033 #include <sys/un.h>
00034
00035 #ifdef HAVE_NETDB_H
00036 #include <netdb.h>
00037 #endif
00038
00039 #ifdef HAVE_NETINET_IN_H
00040 #include <netinet/in.h>
00041 #endif
00042
00043 #ifdef HAVE_SYS_TIME_H
00044 #include <sys/time.h>
00045 #endif
00046
00047 #ifdef HAVE_SYS_FILIO_H
00048 #include <sys/filio.h>
00049 #endif
00050
00051 #ifdef HAVE_SYS_IOCTL_H
00052 #include <sys/ioctl.h>
00053 #endif
00054
00055 #ifdef HAVE_SYS_FILIO_H
00056 #include <sys/filio.h>
00057 #endif
00058
00059 #ifdef HAVE_STRING_H
00060 #include <string.h>
00061 #endif
00062
00063 #ifdef HAVE_UNISTD_H
00064 #include <unistd.h>
00065 #endif
00066
00067 #ifdef HAVE_SYS_STAT_H
00068 #include <sys/stat.h>
00069 #endif
00070
00071 #ifdef HAVE_STROPTS_H
00072 #include <stropts.h>
00073 #endif
00074
00075 #include "monitor.h"
00076 #include "net.h"
00077
00090
00091
00092
00102 int check_connect(char *hostname, int port, int protocol) {
00103
00104 int socket;
00105 int rv= TRUE;
00106
00107 if ((socket= create_socket(hostname, port, protocol)) < 0) {
00108
00109 rv= FALSE;
00110
00111 } else if (! check_socket(socket)) {
00112
00113 rv= FALSE;
00114
00115 }
00116
00117 close_socket(socket);
00118
00119 return rv;
00120
00121 }
00122
00123
00129 int check_host(char *hostname) {
00130
00131 struct hostent *hp;
00132
00133 if ((hp = gethostbyname(hostname)) == NULL) {
00134
00135 return FALSE;
00136
00137 }
00138
00139 return TRUE;
00140
00141 }
00142
00143
00152 int check_connection_io(Port_T p) {
00153
00154 switch(p->type) {
00155 case SOCK_STREAM: return check_socket(p->socket);
00156 case SOCK_DGRAM: return check_udp_socket(p->socket);
00157 default: break;
00158 }
00159
00160 return FALSE;
00161
00162 }
00163
00164
00170 int check_socket(int socket) {
00171
00172 fd_set rset, wset;
00173 struct timeval tv;
00174
00175 FD_ZERO(&rset);
00176 FD_ZERO(&wset);
00177 FD_SET(socket, &rset);
00178 FD_SET(socket, &wset);
00179 tv.tv_sec= SELECT_TIMEOUT;
00180 tv.tv_usec= 0;
00181
00182 return (select(socket+1, &rset, &wset, NULL, &tv) > 0);
00183 }
00184
00185
00192 int check_udp_socket(int socket) {
00193
00194 int r;
00195 char buf[1]= {0};
00196
00197
00198
00199
00200
00201 set_noblock(socket);
00202 write(socket, buf, 1);
00203 sleep(1);
00204 r= read(socket, buf, 1);
00205 set_block(socket);
00206 if(0>r) {
00207 switch(errno) {
00208 case ECONNREFUSED: return FALSE;
00209 default: break;
00210 }
00211 }
00212
00213 return TRUE;
00214
00215 }
00216
00217
00226 int create_socket(char *hostname, int port, int protocol) {
00227
00228 int s;
00229 struct hostent *hp;
00230 struct sockaddr_in sin;
00231
00232 if ((hp= gethostbyname(hostname)) == NULL) {
00233
00234 return -1;
00235
00236 }
00237
00238 if ((s= socket(AF_INET, protocol, 0)) < 0) {
00239
00240 return -1;
00241
00242 }
00243
00244 sin.sin_family= AF_INET;
00245 sin.sin_port= htons(port);
00246 memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
00247
00248 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
00249
00250 close_socket(s);
00251 return -1;
00252
00253 }
00254
00255 return s;
00256
00257 }
00258
00259
00266 int create_generic_socket(Port_T pp) {
00267
00268 int socket_fd= -1;
00269
00270 if(pp->family == AF_INET) {
00271
00272 socket_fd= create_socket(pp->hostname, pp->port, pp->type);
00273
00274 } else if(pp->family == AF_UNIX) {
00275
00276 socket_fd= create_unix_socket(pp->pathname, pp->type);
00277
00278 }
00279
00280 return socket_fd;
00281
00282 }
00283
00284
00292 int create_unix_socket(char *pathname, int protocol) {
00293
00294 int s;
00295 struct sockaddr_un unixsocket;
00296
00297 if ((s= socket(PF_UNIX, protocol, 0)) < 0) {
00298
00299 return -1;
00300
00301 }
00302
00303 unixsocket.sun_family= AF_UNIX;
00304 snprintf(unixsocket.sun_path, sizeof(unixsocket.sun_path), "%s", pathname);
00305
00306 if (connect(s, (struct sockaddr *)&unixsocket, sizeof(unixsocket)) < 0) {
00307
00308 close_socket(s);
00309 return -1;
00310
00311 }
00312
00313 return s;
00314
00315 }
00316
00317
00332 int create_server_socket(int port, int backlog, char *bindAddr) {
00333
00334 int s;
00335 int flag= 1;
00336 struct sockaddr_in myaddr;
00337
00338 if ((s= socket(AF_INET, SOCK_STREAM, 0)) < 0)
00339 return -1;
00340
00341 memset(&myaddr, 0, sizeof(struct sockaddr_in));
00342 myaddr.sin_family= AF_INET;
00343 myaddr.sin_port= htons(port);
00344
00345 if(bindAddr) {
00346 struct hostent *h= gethostbyname(bindAddr);
00347 endhostent();
00348 if(h==NULL) {
00349 errno= h_errno;
00350 goto error;
00351 }
00352 myaddr.sin_addr= *(struct in_addr*)h->h_addr_list[0];
00353 } else {
00354 myaddr.sin_addr.s_addr= htonl(INADDR_ANY);
00355 }
00356
00357 if (setsockopt(s, SOL_SOCKET,
00358 SO_REUSEADDR, (char *)&flag, sizeof(int)) < 0)
00359 goto error;
00360
00361 if (bind(s, (struct sockaddr *)&myaddr, sizeof(struct sockaddr_in)) < 0)
00362 goto error;
00363
00364 if (listen(s, backlog) < 0)
00365 goto error;
00366
00367 if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1)
00368 goto error;
00369
00370 return s;
00371
00372 error:
00373 close(s);
00374
00375 return -1;
00376
00377 }
00378
00379
00385 int close_socket(int socket) {
00386
00387 int rv= TRUE;
00388
00389 if ((shutdown(socket, 2) < 0)) {
00390
00391 rv= FALSE;
00392
00393 }
00394
00395 if (close(socket) < 0) {
00396
00397 rv= FALSE;
00398
00399 }
00400
00401 return rv;
00402
00403 }
00404
00405
00413 int set_sotimeout(int socket, int timeout) {
00414
00415 struct timeval tv= {timeout, 0};
00416
00417 return ((setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))==0) &&
00418 (setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv))==0));
00419
00420 }
00421
00422
00428 int set_noblock(int socket) {
00429
00430 int flag= 1;
00431
00432 return (! ioctl(socket, FIONBIO, &flag));
00433
00434 }
00435
00436
00442 int set_block(int socket) {
00443
00444 int flag= 0;
00445
00446 return (! ioctl(socket, FIONBIO, &flag));
00447
00448 }
00449
00450
00460 int sock_send(int sock, const char *msg, int len, int flags) {
00461
00462 int rv;
00463 fd_set fdset;
00464 struct timeval t;
00465 int retry;
00466
00467 if (! set_noblock(sock)) {
00468
00469 return -1;
00470
00471 }
00472
00473 rv= send(sock, msg, len, flags);
00474 if (rv <= 0) {
00475
00476 if (errno == EWOULDBLOCK)
00477 do {
00478
00479 retry= FALSE;
00480 FD_ZERO(&fdset);
00481 FD_SET(sock, &fdset);
00482 t.tv_sec= SELECT_TIMEOUT;
00483 t.tv_usec= 0;
00484 rv = select(sock+1, NULL, &fdset, NULL, &t);
00485 if (rv <= 0) {
00486
00487 rv= -1;
00488
00489 }
00490 else {
00491
00492 rv = send(sock, msg, len, flags);
00493 if (rv <= 0) {
00494
00495 if(errno == EWOULDBLOCK) {
00496
00497 retry= TRUE;
00498 sleep(1);
00499
00500 }
00501
00502 }
00503
00504 }
00505
00506 } while(retry);
00507
00508 }
00509
00510 set_block(sock);
00511
00512 return rv;
00513
00514 }
00515
00516
00526 int sock_recv(int sock, char *buf, int len, int flags) {
00527
00528 int rv;
00529 fd_set fdset;
00530 struct timeval t;
00531
00532 if (! set_noblock(sock)) {
00533
00534 return -1;
00535
00536 }
00537
00538 rv= recv(sock, buf, len, flags);
00539 if (rv <= 0) {
00540
00541 if (errno == EWOULDBLOCK) {
00542
00543 FD_ZERO(&fdset);
00544 FD_SET(sock, &fdset);
00545 t.tv_sec= SELECT_TIMEOUT;
00546 t.tv_usec = 0;
00547 rv = select(sock+1, &fdset, NULL, NULL, &t);
00548 if (rv <= 0) {
00549
00550 rv= -1;
00551
00552 }
00553 else {
00554
00555 rv= recv(sock, buf, len, flags);
00556
00557 }
00558
00559 }
00560
00561 }
00562
00563 set_block(sock);
00564
00565 return rv;
00566
00567 }
00568
00569
00575 char *get_localhostname() {
00576
00577 char hostname[256];
00578
00579 if (gethostname(hostname, sizeof(hostname)) < 0) {
00580
00581 return NULL;
00582
00583 }
00584
00585 return (strdup(hostname));
00586
00587 }
00588
00589
00596 char *get_remote_host(int socket) {
00597
00598 struct hostent *h;
00599 struct sockaddr_in r;
00600 int l= sizeof(struct sockaddr_in);
00601
00602 if (getpeername(socket, (struct sockaddr*)&r, &l) < 0) {
00603
00604 return NULL;
00605
00606 } else {
00607
00608 h=gethostbyaddr((char *)&r.sin_addr, sizeof(struct in_addr), AF_INET);
00609 if (h) {
00610
00611 return strdup(h->h_name);
00612
00613 }
00614
00615 }
00616
00617 return NULL;
00618
00619 }
00620