void handle_resolve_dns(int parc, char *parv[]) { char *id = rb_strdup(parv[1]); char qtype = *parv[2]; char *record = parv[3]; int aftype = AF_INET; switch(qtype) { case '6': aftype = AF_INET6; case '4': if(!lookup_ip(record, aftype, submit_dns_answer, id)) submit_dns_answer(NULL, false, qtype, NULL); break; case 'S': case 'R': if(!lookup_hostname(record, submit_dns_answer, id)) submit_dns_answer(NULL, false, qtype, NULL); break; default: warn_opers(L_CRIT, "DNS: handle_resolve_dns got an unknown query: %c", qtype); exit(EX_DNS_ERROR); } }
int main(int argc, char *argv[]) { struct ovs_cmdl_context ctx = { .argc = 0, }; set_program_name(argv[0]); vlog_set_levels(NULL, VLF_ANY_DESTINATION, VLL_EMER); parse_options(argc, argv); ctx.argc = argc - optind; ctx.argv = argv + optind; ovs_cmdl_run_command(&ctx, get_all_commands()); return 0; } static void parse_target(const char *s_, struct in_addr *addr, unsigned short int *min, unsigned short int *max) { char *s = xstrdup(s_); char *colon; int error; colon = strchr(s, ':'); if (colon) { *colon = '\0'; } if (*s != '\0') { error = lookup_hostname(s, addr); if (error) { ovs_fatal(error, "failed to look up IP address for \"%s\"", s_); } } else { addr->s_addr = htonl(INADDR_ANY); } *min = *max = 0; if (colon && colon[1] != '\0') { const char *ports = colon + 1; if (ovs_scan(ports, "%hu-%hu", min, max)) { if (*min > *max) { ovs_fatal(0, "%s: minimum is greater than maximum", s_); } } else if (ovs_scan(ports, "%hu", min)) { *max = *min; } else { ovs_fatal(0, "%s: number or range expected", s_); } } free(s); }
/** Parse a string of the form "host[:port]" from <b>addrport</b>. If * <b>address</b> is provided, set *<b>address</b> to a copy of the * host portion of the string. If <b>addr</b> is provided, try to * resolve the host portion of the string and store it into * *<b>addr</b> (in host byte order). If <b>port_out</b> is provided, * store the port number into *<b>port_out</b>, or 0 if no port is given. * If <b>port_out</b> is NULL, then there must be no port number in * <b>addrport</b>. * Return 0 on success, -1 on failure. */ int parse_addr_port(int severity, const char *addrport, char **address, uint32_t *addr, uint16_t *port_out) { const char *colon; char *_address = NULL; int _port; int ok = 1; assert(addrport); colon = strchr(addrport, ':'); if (colon) { _address = tor_strndup(addrport, colon-addrport); _port = (int) parse_long(colon+1,10,1,65535,NULL,NULL); if (!_port) { fprintf(stderr, "Port %s out of range\n", colon+1); ok = 0; } if (!port_out) { fprintf(stderr, "Port %s given on %s when not required\n", colon+1, addrport); ok = 0; } } else { _address = strdup(addrport); _port = 0; } if (addr) { /* There's an addr pointer, so we need to resolve the hostname. */ if (lookup_hostname(_address,addr)) { fprintf(stderr, "Couldn't look up %s\n", _address); ok = 0; *addr = 0; } } if (address && ok) { *address = _address; } else { if (address) *address = NULL; free(_address); } if (port_out) *port_out = ok ? ((uint16_t) _port) : 0; return ok ? 0 : -1; }
static void parse_target(const char *s_, struct in_addr *addr, unsigned short int *min, unsigned short int *max) { char *s = xstrdup(s_); char *colon; int error; colon = strchr(s, ':'); if (colon) { *colon = '\0'; } if (*s != '\0') { error = lookup_hostname(s, addr); if (error) { ovs_fatal(error, "failed to look up IP address for \"%s\"", s_); } } else { addr->s_addr = htonl(INADDR_ANY); } *min = *max = 0; if (colon && colon[1] != '\0') { const char *ports = colon + 1; if (sscanf(ports, "%hu-%hu", min, max) == 2) { if (*min > *max) { ovs_fatal(0, "%s: minimum is greater than maximum", s_); } } else if (sscanf(ports, "%hu", min) == 1) { *max = *min; } else { ovs_fatal(0, "%s: number or range expected", s_); } } free(s); }
int xdebug_create_socket(const char *hostname, int dport) { struct sockaddr sa; struct sockaddr_in address; int sockfd; int status; struct timeval timeout; int actually_connected; socklen_t size = sizeof(sa); #if WIN32|WINNT WORD wVersionRequested; WSADATA wsaData; char optval = 1; const char yes = 1; u_long no = 0; wVersionRequested = MAKEWORD(2, 2); WSAStartup(wVersionRequested, &wsaData); #else long optval = 1; #endif memset(&address, 0, sizeof(address)); lookup_hostname(hostname, &address.sin_addr); address.sin_family = AF_INET; address.sin_port = htons((unsigned short)dport); sockfd = socket(address.sin_family, SOCK_STREAM, 0); if (sockfd == SOCK_ERR) { #ifndef DEBUGGER_FAIL_SILENTLY #if WIN32|WINNT printf("create_debugger_socket(\"%s\", %d) socket: %d\n", hostname, dport, WSAGetLastError()); #else printf("create_debugger_socket(\"%s\", %d) socket: %s\n", hostname, dport, strerror(errno)); #endif #endif return -1; } /* Put socket in non-blocking mode so we can use select for timeouts */ timeout.tv_sec = 0; timeout.tv_usec = 200000; #ifdef WIN32 ioctlsocket(sockfd, FIONBIO, (u_long*)&yes); #else fcntl(sockfd, F_SETFL, O_NONBLOCK); #endif /* connect */ status = connect(sockfd, (struct sockaddr*)&address, sizeof(address)); if (status < 0) { #ifdef WIN32 errno = WSAGetLastError(); if (errno != WSAEINPROGRESS && errno != WSAEWOULDBLOCK) { close(sockfd); return -1; } #else if (errno == EACCES) { close(sockfd); return -3; } if (errno != EINPROGRESS) { close(sockfd); return -1; } #endif while (1) { fd_set rset, wset, eset; FD_ZERO(&rset); FD_SET(sockfd, &rset); FD_ZERO(&wset); FD_SET(sockfd, &wset); FD_ZERO(&eset); FD_SET(sockfd, &eset); if (select(sockfd+1, &rset, &wset, &eset, &timeout) == 0) { close(sockfd); return -2; } /* if our descriptor has an error */ if (FD_ISSET(sockfd, &eset)) { close(sockfd); return -1; } /* if our descriptor is ready break out */ if (FD_ISSET(sockfd, &wset) || FD_ISSET(sockfd, &rset)) { break; } } actually_connected = getpeername(sockfd, &sa, &size); if (actually_connected == -1) { close(sockfd); return -1; } } #ifdef WIN32 ioctlsocket(sockfd, FIONBIO, &no); #else fcntl(sockfd, F_SETFL, 0); #endif setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval)); return sockfd; }
int lkboot_txn(const char *host, const char *_cmd, int txfd, const char *args) { msg_hdr_t hdr; in_addr_t addr; char cmd[128]; char tmp[65536]; off_t txlen = 0; int len; int s; if (txfd != -1) { txlen = lseek(txfd, 0, SEEK_END); if (txlen > (512*1024*1024)) { fprintf(stderr, "error: file too large\n"); return -1; } lseek(txfd, 0, SEEK_SET); } len = snprintf(cmd, 128, "%s:%d:%s", _cmd, (int) txlen, args); if (len > 127) { fprintf(stderr, "error: command too large\n"); return -1; } addr = lookup_hostname(host); if (addr == 0) { fprintf(stderr, "error: cannot find host '%s'\n", host); return -1; } if ((s = tcp_connect(addr, 1023)) < 0) { fprintf(stderr, "error: cannot connect to host '%s'\n", host); return -1; } hdr.opcode = MSG_CMD; hdr.extra = 0; hdr.length = len; if (write(s, &hdr, sizeof(hdr)) != sizeof(hdr)) goto iofail; if (write(s, cmd, len) != len) goto iofail; for (;;) { if (readx(s, &hdr, sizeof(hdr))) goto iofail; switch (hdr.opcode) { case MSG_GO_AHEAD: if (upload(s, txfd, txlen)) goto fail; break; case MSG_OKAY: close(s); return 0; case MSG_FAIL: len = (hdr.length > 127) ? 127 : hdr.length; if (readx(s, cmd, len)) { cmd[0] = 0; } else { cmd[len] = 0; } fprintf(stderr,"error: remote failure: %s\n", cmd); goto fail; case MSG_SEND_DATA: len = hdr.length + 1; if (readx(s, tmp, len)) goto iofail; if (len > (REPLYMAX - replylen)) { fprintf(stderr, "error: too much reply data\n"); goto fail; } memcpy(replybuf + replylen, tmp, len); replylen += len; break; default: fprintf(stderr, "error: unknown opcode %d\n", hdr.opcode); goto fail; } } iofail: fprintf(stderr, "error: socket io\n"); fail: close(s); return -1; }
int lkboot_txn(const char *host, const char *_cmd, int txfd, const char *args) { msg_hdr_t hdr; in_addr_t addr; char cmd[128]; char tmp[65536]; off_t txlen = 0; int do_endian_swap = 0; int once = 1; int len; int s; if (txfd != -1) { txlen = lseek(txfd, 0, SEEK_END); if (txlen > (512*1024*1024)) { fprintf(stderr, "error: file too large\n"); return -1; } lseek(txfd, 0, SEEK_SET); } if (!strcmp(_cmd, "fpga")) { /* if we were asked to send an fpga image, try to find the sync words and * trim all the data before it */ txlen = trim_fpga_image(txfd, txlen); if (txlen < 0) { fprintf(stderr, "error: fpga image doesn't contain sync pattern\n"); return -1; } /* it'll need a 4 byte endian swap as well */ do_endian_swap = 1; } len = snprintf(cmd, 128, "%s:%d:%s", _cmd, (int) txlen, args); if (len > 127) { fprintf(stderr, "error: command too large\n"); return -1; } addr = lookup_hostname(host); if (addr == 0) { fprintf(stderr, "error: cannot find host '%s'\n", host); return -1; } while ((s = tcp_connect(addr, 1023)) < 0) { if (once) { fprintf(stderr, "error: cannot connect to host '%s'. retrying...\n", host); once = 0; } usleep(100000); } hdr.opcode = MSG_CMD; hdr.extra = 0; hdr.length = len; if (write(s, &hdr, sizeof(hdr)) != sizeof(hdr)) goto iofail; if (write(s, cmd, len) != len) goto iofail; for (;;) { if (readx(s, &hdr, sizeof(hdr))) goto iofail; switch (hdr.opcode) { case MSG_GO_AHEAD: if (upload(s, txfd, txlen, do_endian_swap)) goto fail; break; case MSG_OKAY: close(s); return 0; case MSG_FAIL: len = (hdr.length > 127) ? 127 : hdr.length; if (readx(s, cmd, len)) { cmd[0] = 0; } else { cmd[len] = 0; } fprintf(stderr,"error: remote failure: %s\n", cmd); goto fail; case MSG_SEND_DATA: len = hdr.length + 1; if (readx(s, tmp, len)) goto iofail; if (len > (REPLYMAX - replylen)) { fprintf(stderr, "error: too much reply data\n"); goto fail; } memcpy(replybuf + replylen, tmp, len); replylen += len; break; default: fprintf(stderr, "error: unknown opcode %d\n", hdr.opcode); goto fail; } } iofail: fprintf(stderr, "error: socket io\n"); fail: close(s); return -1; }
static const char *get_ip_address(struct hostinfo *hi) { lookup_hostname(hi); return hi->ip_address.buf; }
static const char *get_canon_hostname(struct hostinfo *hi) { lookup_hostname(hi); return hi->canon_hostname.buf; }
int thttpd_run(void) { char* cp; struct passwd* pwd; uid_t uid = 32767; gid_t gid = 32767; int num_ready; int cnum; connecttab* c; httpd_conn* hc; httpd_sockaddr sa4; httpd_sockaddr sa6; int gotv4, gotv6; struct timeval tv; cp = getenv( "GHTTPPORT" ); if ( cp ) port = atoi( cp ); if( port == 0 ) port = 9999; /* Read zone info now, in case we chroot(). */ tzset(); /* Look up hostname now, in case we chroot(). */ lookup_hostname( &sa4, sizeof(sa4), &gotv4, &sa6, sizeof(sa6), &gotv6 ); if ( ! ( gotv4 || gotv6 ) ) { memset(&sa4, 0, sizeof sa4); gotv4 = 1; } /* Initialize the fdwatch package. Have to do this before chroot, ** if /dev/poll is used. */ max_connects = fdwatch_get_nfiles(); if ( max_connects < 0 ) { return; } max_connects -= SPARE_FDS; /* Set up to catch signals. */ #ifdef HAVE_SIGSET (void) sigset( SIGPIPE, SIG_IGN ); /* get EPIPE instead */ #else /* HAVE_SIGSET */ (void) signal( SIGPIPE, SIG_IGN ); /* get EPIPE instead */ #endif /* HAVE_SIGSET */ /* Initialize the timer package. */ tmr_init(); /* Initialize the HTTP layer. Got to do this before giving up root, ** so that we can bind to a privileged port. */ hs = httpd_initialize( hostname, gotv4 ? &sa4 : (httpd_sockaddr*) 0, gotv6 ? &sa6 : (httpd_sockaddr*) 0, port, cgi_pattern, cgi_limit, charset, p3p, max_age, "/", no_log, no_symlink_check, do_vhost, do_global_passwd, url_pattern, local_pattern, no_empty_referers ); if ( hs == (httpd_server*) 0 ) exit( 1 ); /* Set up the occasional timer. */ if ( tmr_create( (struct timeval*) 0, occasional, JunkClientData, OCCASIONAL_TIME * 1000L, 1 ) == (Timer*) 0 ) { return; } /* Set up the idle timer. */ if ( tmr_create( (struct timeval*) 0, idle, JunkClientData, 5 * 1000L, 1 ) == (Timer*) 0 ) { return; } start_time = stats_time = time( (time_t*) 0 ); stats_connections = 0; stats_bytes = 0; stats_simultaneous = 0; /* Initialize our connections table. */ connects = NEW( connecttab, max_connects ); if ( connects == (connecttab*) 0 ) { return; } for ( cnum = 0; cnum < max_connects; ++cnum ) { connects[cnum].conn_state = CNST_FREE; connects[cnum].next_free_connect = cnum + 1; connects[cnum].hc = (httpd_conn*) 0; } connects[max_connects - 1].next_free_connect = -1; /* end of link list */ first_free_connect = 0; num_connects = 0; httpd_conn_count = 0; if ( hs != (httpd_server*) 0 ) { if ( hs->listen4_fd != -1 ) fdwatch_add_fd( hs->listen4_fd, (void*) 0, FDW_READ ); if ( hs->listen6_fd != -1 ) fdwatch_add_fd( hs->listen6_fd, (void*) 0, FDW_READ ); } /* Main loop. */ (void) gettimeofday( &tv, (struct timezone*) 0 ); while ( ( ! terminate ) || num_connects > 0 ) { /* Do the fd watch. */ num_ready = fdwatch( tmr_mstimeout( &tv ) ); if ( num_ready < 0 ) { if ( errno == EINTR || errno == EAGAIN ) continue; /* try again */ return; } (void) gettimeofday( &tv, (struct timezone*) 0 ); if ( num_ready == 0 ) { /* No fd's are ready - run the timers. */ tmr_run( &tv ); continue; } /* Is it a new connection? */ if ( hs != (httpd_server*) 0 && hs->listen6_fd != -1 && fdwatch_check_fd( hs->listen6_fd ) ) { if ( handle_newconnect( &tv, hs->listen6_fd ) ) /* Go around the loop and do another fdwatch, rather than ** dropping through and processing existing connections. ** New connections always get priority. */ continue; } if ( hs != (httpd_server*) 0 && hs->listen4_fd != -1 && fdwatch_check_fd( hs->listen4_fd ) ) { if ( handle_newconnect( &tv, hs->listen4_fd ) ) /* Go around the loop and do another fdwatch, rather than ** dropping through and processing existing connections. ** New connections always get priority. */ continue; } /* Find the connections that need servicing. */ while ( ( c = (connecttab*) fdwatch_get_next_client_data() ) != (connecttab*) -1 ) { if ( c == (connecttab*) 0 ) continue; hc = c->hc; if ( ! fdwatch_check_fd( hc->conn_fd ) ) /* Something went wrong. */ clear_connection( c, &tv ); else switch ( c->conn_state ) { case CNST_READING: handle_read( c, &tv ); break; case CNST_SENDING: handle_send( c, &tv ); break; case CNST_LINGERING: handle_linger( c, &tv ); break; } } tmr_run( &tv ); } /* The main loop terminated. */ shut_down(); return 0; }
int main( int argc, char** argv ) { char* cp; struct passwd* pwd; uid_t uid; gid_t gid; char cwd[MAXPATHLEN]; FILE* logfp; int num_ready; int cnum, ridx; connecttab* c; httpd_conn* hc; httpd_sockaddr sa4; httpd_sockaddr sa6; int gotv4, gotv6; struct timeval tv; argv0 = argv[0]; cp = strrchr( argv0, '/' ); if ( cp != (char*) 0 ) ++cp; else cp = argv0; openlog( cp, LOG_NDELAY|LOG_PID, LOG_FACILITY ); /* Handle command-line arguments. */ parse_args( argc, argv ); /* Check port number. */ if ( port <= 0 ) { syslog( LOG_CRIT, "illegal port number" ); (void) fprintf( stderr, "%s: illegal port number\n", argv0 ); exit( 1 ); } /* Read zone info now, in case we chroot(). */ tzset(); /* Look up hostname now, in case we chroot(). */ lookup_hostname( &sa4, sizeof(sa4), &gotv4, &sa6, sizeof(sa6), &gotv6 ); if ( ! ( gotv4 || gotv6 ) ) { syslog( LOG_ERR, "can't find any valid address" ); (void) fprintf( stderr, "%s: can't find any valid address\n", argv0 ); exit( 1 ); } /* Throttle file. */ numthrottles = 0; maxthrottles = 0; throttles = (throttletab*) 0; if ( throttlefile != (char*) 0 ) read_throttlefile( throttlefile ); /* Log file. */ if ( logfile != (char*) 0 ) { if ( strcmp( logfile, "/dev/null" ) == 0 ) { no_log = 1; logfp = (FILE*) 0; } else { logfp = fopen( logfile, "a" ); if ( logfp == (FILE*) 0 ) { syslog( LOG_CRIT, "%.80s - %m", logfile ); perror( logfile ); exit( 1 ); } (void) fcntl( fileno( logfp ), F_SETFD, 1 ); } } else logfp = (FILE*) 0; /* Figure out uid/gid from user. */ pwd = getpwnam( user ); if ( pwd == (struct passwd*) 0 ) { syslog( LOG_CRIT, "unknown user - '%.80s'", user ); (void) fprintf( stderr, "%s: unknown user - '%s'\n", argv0, user ); exit( 1 ); } uid = pwd->pw_uid; gid = pwd->pw_gid; /* Switch directories if requested. */ if ( dir != (char*) 0 ) { if ( chdir( dir ) < 0 ) { syslog( LOG_CRIT, "chdir - %m" ); perror( "chdir" ); exit( 1 ); } } #ifdef USE_USER_DIR else if ( getuid() == 0 ) { /* No explicit directory was specified, we're root, and the ** USE_USER_DIR option is set - switch to the specified user's ** home dir. */ if ( chdir( pwd->pw_dir ) < 0 ) { syslog( LOG_CRIT, "chdir - %m" ); perror( "chdir" ); exit( 1 ); } } #endif /* USE_USER_DIR */ /* Get current directory. */ (void) getcwd( cwd, sizeof(cwd) - 1 ); if ( cwd[strlen( cwd ) - 1] != '/' ) (void) strcat( cwd, "/" ); if ( ! debug ) { /* We're not going to use stdin stdout or stderr from here on, so close ** them to save file descriptors. */ (void) fclose( stdin ); (void) fclose( stdout ); (void) fclose( stderr ); /* Daemonize - make ourselves a subprocess. */ #ifdef HAVE_DAEMON if ( daemon( 1, 1 ) < 0 ) { syslog( LOG_CRIT, "daemon - %m" ); exit( 1 ); } #else /* HAVE_DAEMON */ switch ( fork() ) { case 0: break; case -1: syslog( LOG_CRIT, "fork - %m" ); exit( 1 ); default: exit( 0 ); } #ifdef HAVE_SETSID (void) setsid(); #endif /* HAVE_SETSID */ #endif /* HAVE_DAEMON */ } else { /* Even if we don't daemonize, we still want to disown our parent ** process. */ #ifdef HAVE_SETSID (void) setsid(); #endif /* HAVE_SETSID */ } if ( pidfile != (char*) 0 ) { /* Write the PID file. */ FILE* pidfp = fopen( pidfile, "w" ); if ( pidfp == (FILE*) 0 ) { syslog( LOG_CRIT, "%.80s - %m", pidfile ); exit( 1 ); } (void) fprintf( pidfp, "%d\n", (int) getpid() ); (void) fclose( pidfp ); } /* Chroot if requested. */ if ( do_chroot ) { if ( chroot( cwd ) < 0 ) { syslog( LOG_CRIT, "chroot - %m" ); perror( "chroot" ); exit( 1 ); } (void) strcpy( cwd, "/" ); /* Always chdir to / after a chroot. */ if ( chdir( cwd ) < 0 ) { syslog( LOG_CRIT, "chroot chdir - %m" ); perror( "chroot chdir" ); exit( 1 ); } } /* Set up to catch signals. */ (void) signal( SIGTERM, handle_term ); (void) signal( SIGINT, handle_term ); (void) signal( SIGPIPE, SIG_IGN ); /* get EPIPE instead */ (void) signal( SIGHUP, handle_hup ); got_usr1 = 0; (void) signal( SIGUSR1, handle_usr1 ); (void) signal( SIGUSR2, handle_usr2 ); /* Initialize the timer package. */ tmr_init(); /* Initialize the HTTP layer. Got to do this before giving up root, ** so that we can bind to a privileged port. */ hs = httpd_initialize( hostname, gotv4 ? &sa4 : (httpd_sockaddr*) 0, gotv6 ? &sa6 : (httpd_sockaddr*) 0, port, cgi_pattern, charset, cwd, no_log, logfp, no_symlink, do_vhost, do_global_passwd, url_pattern, local_pattern, no_empty_referers ); if ( hs == (httpd_server*) 0 ) exit( 1 ); /* Set up the occasional timer. */ if ( tmr_create( (struct timeval*) 0, occasional, JunkClientData, OCCASIONAL_TIME * 1000L, 1 ) == (Timer*) 0 ) { syslog( LOG_CRIT, "tmr_create(occasional) failed" ); exit( 1 ); } if ( numthrottles > 0 ) { /* Set up the throttles timer. */ if ( tmr_create( (struct timeval*) 0, update_throttles, JunkClientData, THROTTLE_TIME * 1000L, 1 ) == (Timer*) 0 ) { syslog( LOG_CRIT, "tmr_create(update_throttles) failed" ); exit( 1 ); } } #ifdef STATS_TIME /* Set up the stats timer. */ if ( tmr_create( (struct timeval*) 0, show_stats, JunkClientData, STATS_TIME * 1000L, 1 ) == (Timer*) 0 ) { syslog( LOG_CRIT, "tmr_create(show_stats) failed" ); exit( 1 ); } #endif /* STATS_TIME */ start_time = stats_time = time( (time_t*) 0 ); stats_connections = stats_bytes = 0L; stats_simultaneous = 0; /* If we're root, try to become someone else. */ if ( getuid() == 0 ) { /* Set aux groups to null. */ if ( setgroups( 0, (const gid_t*) 0 ) < 0 ) { syslog( LOG_CRIT, "setgroups - %m" ); exit( 1 ); } /* Set primary group. */ if ( setgid( gid ) < 0 ) { syslog( LOG_CRIT, "setgid - %m" ); exit( 1 ); } /* Try setting aux groups correctly - not critical if this fails. */ if ( initgroups( user, gid ) < 0 ) syslog( LOG_WARNING, "initgroups - %m" ); #ifdef HAVE_SETLOGIN /* Set login name. */ (void) setlogin( user ); #endif /* HAVE_SETLOGIN */ /* Set uid. */ if ( setuid( uid ) < 0 ) { syslog( LOG_CRIT, "setuid - %m" ); exit( 1 ); } /* Check for unnecessary security exposure. */ if ( ! do_chroot ) syslog( LOG_CRIT, "started as root without requesting chroot(), warning only" ); } /* Initialize our connections table. */ maxconnects = fdwatch_get_nfiles(); if ( maxconnects < 0 ) { syslog( LOG_CRIT, "fdwatch initialization failure" ); exit( 1 ); } maxconnects -= SPARE_FDS; connects = NEW( connecttab, maxconnects ); if ( connects == (connecttab*) 0 ) { syslog( LOG_CRIT, "out of memory allocating a connecttab" ); exit( 1 ); } for ( cnum = 0; cnum < maxconnects; ++cnum ) { connects[cnum].conn_state = CNST_FREE; connects[cnum].hc = (httpd_conn*) 0; } numconnects = 0; httpd_conn_count = 0; if ( hs != (httpd_server*) 0 ) { if ( hs->listen4_fd != -1 ) fdwatch_add_fd( hs->listen4_fd, (void*) 0, FDW_READ ); if ( hs->listen6_fd != -1 ) fdwatch_add_fd( hs->listen6_fd, (void*) 0, FDW_READ ); } /* Main loop. */ (void) gettimeofday( &tv, (struct timezone*) 0 ); while ( ( ! terminate ) || numconnects > 0 ) { /* Do the fd watch. */ num_ready = fdwatch( tmr_mstimeout( &tv ) ); if ( num_ready < 0 ) { if ( errno == EINTR ) continue; /* try again */ syslog( LOG_ERR, "fdwatch - %m" ); exit( 1 ); } (void) gettimeofday( &tv, (struct timezone*) 0 ); if ( num_ready == 0 ) { /* No fd's are ready - run the timers. */ tmr_run( &tv ); continue; } /* Is it a new connection? */ if ( hs != (httpd_server*) 0 && hs->listen6_fd != -1 && fdwatch_check_fd( hs->listen6_fd ) ) { if ( handle_newconnect( &tv, hs->listen6_fd ) ) /* Go around the loop and do another fdwatch, rather than ** dropping through and processing existing connections. ** New connections always get priority. */ continue; } if ( hs != (httpd_server*) 0 && hs->listen4_fd != -1 && fdwatch_check_fd( hs->listen4_fd ) ) { if ( handle_newconnect( &tv, hs->listen4_fd ) ) /* Go around the loop and do another fdwatch, rather than ** dropping through and processing existing connections. ** New connections always get priority. */ continue; } /* Find the connections that need servicing. */ for ( ridx = 0; ridx < num_ready; ++ridx ) { c = (connecttab*) fdwatch_get_client_data( ridx ); if ( c == (connecttab*) 0 ) continue; hc = c->hc; if ( c->conn_state == CNST_READING && fdwatch_check_fd( hc->conn_fd ) ) handle_read( c, &tv ); else if ( c->conn_state == CNST_SENDING && fdwatch_check_fd( hc->conn_fd ) ) handle_send( c, &tv ); else if ( c->conn_state == CNST_LINGERING && fdwatch_check_fd( hc->conn_fd ) ) handle_linger( c, &tv ); } tmr_run( &tv ); if ( got_usr1 && ! terminate ) { terminate = 1; if ( hs != (httpd_server*) 0 ) { httpd_terminate( hs ); hs = (httpd_server*) 0; } } } /* The main loop terminated. */ shut_down(); syslog( LOG_NOTICE, "exiting" ); closelog(); exit( 0 ); }
int main(int argc, char *argv[]) { const char *args = "hnp:s:d:SDxor:L"; static int SORT_ROW = 1; static int EXT_VIEW = 0; static int RESOLVE = 1; static int no_hdr = 0; static char PROTOCOL[4]; FILE *f; char line[200]; char src[50]; char dst[50]; char buf[100]; char buf2[100]; char *pa[MAX_CONN][ROWS]; char *store; int index,a,b,c,j,r; // check parameters while ((c = getopt(argc, argv, args)) != -1 ) { switch (c) { case 'h': display_help(); return 1; case '?': display_help(); return 1; case 'n': RESOLVE = 0; break; case 'p': strcpy (PROTOCOL, optarg); break; case 's': strcpy (SRC_IP, optarg); lookup_ip(SRC_IP); break; case 'd': strcpy (DST_IP, optarg); lookup_ip(DST_IP); break; case 'S': DNAT = 0; break; case 'D': SNAT = 0; break; case 'L': SNAT = 0; DNAT = 0; LOCAL = 1; break; case 'x': EXT_VIEW = 1; break; case 'o': no_hdr = 1; break; case 'r': if (optarg == NULL || optarg == '\0') { display_help(); return 1; } if (strcmp(optarg, "scr") == 0) SORT_ROW = 1; //default if (strcmp(optarg, "dst") == 0) SORT_ROW = 2; if (strcmp(optarg, "src-port") == 0) SORT_ROW = 3; if (strcmp(optarg, "dst-port") == 0) SORT_ROW = 4; if (strcmp(optarg, "state") == 0) SORT_ROW = 5; break; } } // some checking for IPTables and read file f=fopen("/proc/net/ip_conntrack","r"); if (!f) { printf("Make sure netfilter/IPtables is enabled by kernel or modules.\n"); return 1; } // process conntrack table if (!no_hdr) { if (!EXT_VIEW) { printf("%-6s%-31s%-31s%-6s\n","Proto","NATed Address","Foreign Address","State"); } else { printf("%-6s%-41s%-41s%-6s\n","Proto","NATed Address","Foreign Address","State"); } } while (fgets(line,1000,f)!=NULL) { if ((!strcmp(PROTOCOL, "tcp")) || (!strcmp(PROTOCOL, ""))) { if(match(line, "tcp")) { protocol_tcp(line); } } if ((!strcmp(PROTOCOL, "udp")) || (!strcmp(PROTOCOL, ""))) { if((match(line, "udp")) && (match(line, "UNREPLIED"))) { protocol_udp_unr(line); } if((match(line, "udp")) && (match(line, "ASSURED"))) { protocol_udp_ass(line); } if((match(line, "udp")) && (!match(line, "ASSURED")) && (!match(line, "UNREPLIED"))) { protocol_udp(line); } } if ((!strcmp(PROTOCOL, "icmp")) || (!strcmp(PROTOCOL, ""))) { if((match(line, "icmp")) && (match(line, "UNREPLIED"))) { protocol_icmp_unr(line); } if((match(line, "icmp")) && (!match(line, "UNREPLIED"))) { protocol_icmp_rep(line); } } } fclose(f); // create array pointed to main connection array for (index = 0; index < connection_index; index++) { for (j=0; j<ROWS; j++) { pa[index][j] = &connection_table[index][j][0]; } } // sort by protocol and defined row for (a = 0;a < connection_index-1; a++) { for (b = a+1; b < connection_index; b++) { r = strcmp(pa[a][0], pa[b][0]); if (r > 0) { for (j=0;j<ROWS-1;j++) { store = pa[a][j]; pa[a][j] = pa[b][j]; pa[b][j] = store; } } if (r == 0) { if (strcmp(pa[a][SORT_ROW], pa[b][SORT_ROW]) > 0) { for (j=0;j<ROWS;j++) { store = pa[a][j]; pa[a][j] = pa[b][j]; pa[b][j] = store; } } } } } // print connections for (index = 0; index < connection_index; index++) { if (RESOLVE) { lookup_hostname(pa[index][1]); lookup_hostname(pa[index][2]); if (strlen(pa[index][3]) > 0 || strlen(pa[index][4]) > 0) { lookup_portname(pa[index][3], pa[index][0]); lookup_portname(pa[index][4], pa[index][0]); } } if (!EXT_VIEW) { strcpy(buf ,""); strncat(buf, pa[index][1], 29 - strlen(pa[index][3])); sprintf(buf2, "%s:%s", buf, pa[index][3]); sprintf(src , "%-31s", buf2); strcpy(buf ,""); strncat(buf, pa[index][2], 29 - strlen(pa[index][4])); sprintf(buf2, "%s:%s", buf, pa[index][4]); sprintf(dst , "%-31s", buf2); } else { strcpy(buf ,""); strncat(buf, pa[index][1], 39 - strlen(pa[index][3])); sprintf(buf2, "%s:%s", buf, pa[index][3]); sprintf(src , "%-41s", buf2); strcpy(buf ,""); strncat(buf, pa[index][2], 39 - strlen(pa[index][4])); sprintf(buf2, "%s:%s", buf, pa[index][4]); sprintf(dst , "%-41s", buf2); } printf("%-6s%s%s%-11s\n", pa[index][0], src, dst, pa[index][5]); } return(0); }