void init_instance::read_config_file() { int node; char name[1024]; FILE *f = fopen("cluster-config.txt", "r"); if (debugging) { fprintf(stderr,"Reading cluster config file...\n"); } for (;;) { fscanf(f, "%d %s", &node, name); if (feof(f)) break; string s(name); thread_machines[node] = lookup_ip(s.c_str()); threadInfo[node].t_host_ip = lookup_ip(s.c_str()); if (debugging) { fprintf(stderr,"thread:%d machine:%s\n", node, name); } } if (debugging) { fprintf(stderr,"\n"); } fclose(f); }
static int ioctl_set_svc(ITF *itf,uint32_t ip,struct sockaddr_atmsvc *addr, const struct atm_qos *qos,int sndbuf,int flags) { ENTRY *entry; if (flags & ATF_ARPSRV) flags |= ATF_PERM; if (lookup_ip(itf,ip)) return -EEXIST; entry = alloc_entry(1); entry->state = as_valid; entry->ip = ip; entry->addr = alloc_t(struct sockaddr_atmsvc); *entry->addr = *addr; entry->qos = *qos; entry->sndbuf = sndbuf; entry->flags = flags; if (!(flags & ATF_PERM) || (flags & ATF_ARPSRV)) { if (itf->arp_srv) START_TIMER(entry,CREVAL); else START_TIMER(entry,SREVAL); } entry->itf = itf; Q_INSERT_HEAD(itf->table,entry); if (!(flags & ATF_ARPSRV)) return 0; entry->state = as_invalid; itf->arp_srv = entry; (void) want_arp_srv(itf); return 0; }
extern char *ip_to_host(const char *ip) { struct hostent *hep = lookup_ip(ip); static char host[128]; return (hep ? strcpy(host, hep->h_name) : empty_str); }
static int ioctl_delete(ITF *itf,uint32_t ip,int flags) { ENTRY *entry,*walk,*next; if (!(entry = lookup_ip(itf,ip))) { diag(COMPONENT,DIAG_WARN,"ioctl_delete didn't find entry"); return -ENOENT; } if ((flags ^ entry->flags) & ATF_ARPSRV) return -EINVAL; send_notifications(entry,0); if ((entry->flags & ATF_ARPSRV) && entry->itf) for (walk = entry->itf->table; walk; walk = next) { next = walk->next; if (walk != entry && walk->state == as_resolv) { send_notifications(walk,0); if (!walk->vccs && !(walk->flags & ATF_PERM)) /* PERM is rather unlikely here, since this would be a second ARP server (only ARP servers can go as_resolv if PERM), but we'll check for it anyway. */ discard_entry(walk); else { STOP_TIMER(walk); walk->state = as_invalid; } } } discard_entry(entry); return 0; }
int main(int argc, char *argv[]) { int listenfd; int bytes_read; int retval; int snmp_tunnel_sock, snmp_local_sock, snmp_trap_sock; parse_options(argc, argv); if (is_client) { snmp_manager_addr.sin_family = AF_INET; snmp_manager_addr.sin_port = htons(snmp_manager_port); retval = lookup_ip(snmp_manager_host,&(snmp_manager_addr.sin_addr)); if (retval) { printf("Can't get snmp_manager->sin_addr.s_addr\n"); exit(1); } while(1) { snmp_tunnel_sock = snmp_tunnel_ap_connect(&snmp_manager_addr); snmp_trap_sock = snmp_trap_setup(); snmp_tunnel_ap_run(snmp_tunnel_sock,snmp_trap_sock); } } }
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); } }
static int resolve(ITF *itf,uint32_t ip,ENTRY **entry,int want_vc) { *entry = lookup_ip(itf,ip); if ((!*entry || (*entry)->state != as_valid) && !itf->arp_srv) return -1; /* bad luck - no ARP server when we need one */ if (*entry) { if (want_vc) (*entry)->flags &= ~ATF_NOVC; switch ((*entry)->state) { case as_resolv: return 1; /* somebody else is already taking care of that */ case as_valid: if (!(*entry)->vccs && !((*entry)->flags & ATF_NOVC)) connect_me(*entry); return 0; case as_invalid: if ((*entry)->svc && (*entry)->itf && (*entry)->itf->arp_srv && !((*entry)->flags & ATF_ARPSRV)) break; return -1; default: diag(COMPONENT,DIAG_FATAL,"bad state %d",(*entry)->state); } } else { *entry = alloc_entry(1); (*entry)->flags = ATF_PUBL | (want_vc ? 0 : ATF_NOVC); (*entry)->ip = ip; (*entry)->itf = itf; Q_INSERT_HEAD(itf->table,*entry); (*entry)->qos = itf->qos; } revalidate(*entry); return 1; }
static int ioctl_set_pvc(ITF *itf,uint32_t ip,struct sockaddr_atmpvc *addr, const struct atm_qos *qos,int sndbuf,int flags) { ENTRY *entry; VCC *vcc; int fd,result; if (lookup_ip(itf,ip)) return -EEXIST; if ((fd = connect_vcc((struct sockaddr *) addr,qos,sndbuf,0)) < 0) return fd; if ((result = set_ip(fd,ip)) < 0) { do_close(fd); return result; } if (flags & ATF_NULL) { if ((result = set_encap(fd,0)) < 0) return result; flags |= ATF_PERM; } entry = alloc_entry(0); entry->state = as_valid; entry->ip = ip; entry->qos = *qos; entry->sndbuf = sndbuf; entry->flags = flags; entry->itf = itf; vcc = alloc_t(VCC); vcc->active = 1; vcc->connecting = 0; vcc->fd = fd; vcc->entry = entry; if (!(flags & ATF_PERM)) START_TIMER(entry,CREVAL); Q_INSERT_HEAD(entry->vccs,vcc); Q_INSERT_HEAD(itf->table,entry); return 0; }
extern struct hostent *resolv(const char *stuff) { struct hostent *hep; if ((hep = lookup_host(stuff)) == NULL) hep = lookup_ip(stuff); return hep; }
static void str_to_ip(const char *str, ovs_be32 *ip) { struct in_addr in_addr; if (lookup_ip(str, &in_addr)) { ovs_fatal(0, "%s: could not convert to IP address", str); } *ip = in_addr.s_addr; }
/* Parses 'str' as an IP address into '*ip'. * * Returns NULL if successful, otherwise a malloc()'d string describing the * error. The caller is responsible for freeing the returned string. */ char * OVS_WARN_UNUSED_RESULT str_to_ip(const char *str, ovs_be32 *ip) { struct in_addr in_addr; if (lookup_ip(str, &in_addr)) { return xasprintf("%s: could not convert to IP address", str); } *ip = in_addr.s_addr; return NULL; }
static int tcp_open(const char *name, char *suffix, struct vconn **vconnp) { char *save_ptr; const char *host_name; const char *port_string; struct sockaddr_in sin; int retval; int fd; /* Glibc 2.7 has a bug in strtok_r when compiling with optimization that * can cause segfaults here: * http://sources.redhat.com/bugzilla/show_bug.cgi?id=5614. * Using "::" instead of the obvious ":" works around it. */ host_name = strtok_r(suffix, "::", &save_ptr); port_string = strtok_r(NULL, "::", &save_ptr); if (!host_name) { ofp_error(0, "%s: bad peer name format", name); return EAFNOSUPPORT; } memset(&sin, 0, sizeof sin); sin.sin_family = AF_INET; if (lookup_ip(host_name, &sin.sin_addr)) { return ENOENT; } sin.sin_port = htons(port_string ? atoi(port_string) : OFP_TCP_PORT); fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { VLOG_ERR("%s: socket: %s", name, strerror(errno)); return errno; } retval = set_nonblocking(fd); if (retval) { close(fd); return retval; } retval = connect(fd, (struct sockaddr *) &sin, sizeof sin); if (retval < 0) { if (errno == EINPROGRESS) { return new_tcp_vconn(name, fd, EAGAIN, &sin, vconnp); } else { int error = errno; VLOG_ERR("%s: connect: %s", name, strerror(error)); close(fd); return error; } } else { return new_tcp_vconn(name, fd, 0, &sin, vconnp); } }
/* create a client connection to a specified host according to a specified host name or an ip address. Inputs: <host> the name of the host <port> the listening port <ip> the ip value of the host, if host is a NULL value Outputs: <ip> the ip value of the host Returns: -1 on failure, otherwise the socket */ int tcp_make_client (char *host, int *port, unsigned int *ip, int nonblocking) { struct sockaddr_in sin; unsigned short listen_port; int fd, st; char localhost[64]; /* set everything up */ listen_port = (unsigned short) *port; memset (&sin, 0, sizeof (sin)); sin.sin_port = htons (listen_port); sin.sin_family = AF_INET; if (!host && !ip) { if (gethostname(localhost,64)==0) host = localhost; else return -1; } if (host) *ip = lookup_ip (host); if (*ip == 0) return -2; sin.sin_addr.s_addr = *ip; /* create a socket */ fd = tcp_open_socket (nonblocking); if (fd < 0) return -3; /* make the connection */ st = connect (fd, (struct sockaddr *) &sin, sizeof (sin)); /* get the local port bound to this socket */ *port = tcp_get_local_port(fd); if (st < 0) { /* for nonblocking, it is okay for the following error # */ if (nonblocking && (NET_ERRNO == EINPROGRESS || NET_ERRNO == EWOULDBLOCK)) { dbgprintf ("connecting to (%s:%hu) at port %hu", inet_ntoa (sin.sin_addr), listen_port, *port); return fd; } dbgprintf ("tcp_make_client : fail to connect to %s error %d", host, NET_ERRNO); closesocket (fd); return -4; } else { dbgprintf ("connected to (%s:%hu) at port %hu", inet_ntoa (sin.sin_addr), listen_port, *port); } return fd; }
static void str_to_ip(const char *str_, uint32_t *ip, uint32_t *maskp) { char *str = xstrdup(str_); char *save_ptr = NULL; const char *name, *netmask; struct in_addr in_addr; ovs_be32 mask; int retval; name = strtok_r(str, "/", &save_ptr); retval = name ? lookup_ip(name, &in_addr) : EINVAL; if (retval) { ovs_fatal(0, "%s: could not convert to IP address", str); } *ip = in_addr.s_addr; netmask = strtok_r(NULL, "/", &save_ptr); if (netmask) { uint8_t o[4]; if (sscanf(netmask, "%"SCNu8".%"SCNu8".%"SCNu8".%"SCNu8, &o[0], &o[1], &o[2], &o[3]) == 4) { mask = htonl((o[0] << 24) | (o[1] << 16) | (o[2] << 8) | o[3]); } else { int prefix = atoi(netmask); if (prefix <= 0 || prefix > 32) { ovs_fatal(0, "%s: network prefix bits not between 1 and 32", str); } else if (prefix == 32) { mask = htonl(UINT32_MAX); } else { mask = htonl(((1u << prefix) - 1) << (32 - prefix)); } } } else { mask = htonl(UINT32_MAX); } *ip &= mask; if (maskp) { *maskp = mask; } else { if (mask != htonl(UINT32_MAX)) { ovs_fatal(0, "%s: netmask not allowed here", str_); } } free(str); }
static void learn_nak(uint32_t ip) { ITF *itf; ENTRY *entry; if (!ip) return; itf = lookup_itf_by_ip(ip); if (!itf) return; entry = lookup_ip(itf,ip); if (!entry || entry->state != as_resolv) return; send_notifications(entry,0); if (entry->flags & ATF_PERM) return; if (entry->vccs) entry->state = as_invalid; else discard_entry(entry); }
/* Accept an incoming connection from another user, given the file descriptor we * were listening on. */ void accept_new_connection(int fd) { int s; int i; /* Create address struct to hold details of incoming connection. The * call to accept() will populate it. */ struct sockaddr_in client_addr; struct sockaddr *client_addr_p = (struct sockaddr *)&client_addr; socklen_t client_addr_len = sizeof(struct sockaddr_in); memset(client_addr_p,0,client_addr_len); if ((s = accept(fd,client_addr_p,&client_addr_len)) < 0) { perror("accept new connection"); if (close(s) < 0) { perror("accept new connection"); } return; } /* reverse look up user details to get username */ /* UNSAFE CONCURRENT STUFF BEGINS */ pthread_mutex_lock(&user_list_lock); if ((i = lookup_ip(client_addr.sin_addr.s_addr)) < 0 || user_list[i].flags & USER_BLOCKED) { /* they're not on the user list, or they're not wanted. close connection. */ if (close(s) < 0) { perror("accept new connection"); } } else { /* set the bit */ user_list[i].flags |= USER_CONNECTED; /* store the socket (file descriptor) */ user_list[i].socket = s; printf("\naccepted incoming connection from " USERNAME_PRINT_FMT ".", user_list[i].name); fflush(stdout); /* needed to force output to screen if we don't * print a newline */ } pthread_mutex_unlock(&user_list_lock); /* UNSAFE CONCURRENT STUFF ENDS */ return; }
SOCKET make_tcp_connection(const char *host, unsigned short port, unsigned int *ip) { struct sockaddr_in sin; SOCKET f; memset(&sin, 0, sizeof(sin)); sin.sin_port = htons(port); sin.sin_family = AF_INET; if((sin.sin_addr.s_addr = lookup_ip(host)) == 0) return INVALID_SOCKET; if(ip) *ip = sin.sin_addr.s_addr; if((f = new_tcp_socket(ON_NONBLOCKING)) == INVALID_SOCKET) return INVALID_SOCKET; /* if an interface was specify, bind to it before connecting */ if(global.iface) bind_interface(f, global.iface, 0); /* turn on TCP/IP keepalive messages */ set_keepalive(f, 1); log_message_level(LOG_LEVEL_DEBUG, "make_tcp_connection: connecting to %s:%hu", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); if(connect(f, (struct sockaddr *) &sin, sizeof(sin)) < 0) { if(N_ERRNO != EINPROGRESS #ifdef WIN32 /* winsock returns EWOULDBLOCK even in nonblocking mode! ugh!!! */ && N_ERRNO != EWOULDBLOCK #endif ) { nlogerr("make_tcp_connection", "connect"); CLOSE(f); return INVALID_SOCKET; } log_message_level(LOG_LEVEL_SERVER, "make_tcp_connection: connection to %s in progress", host); } else log_message_level(LOG_LEVEL_SERVER, "make_tcp_connection: connection established to %s", host); return f; }
/* Parses 'target', which should be a string in the format "[<port>][:<ip>]": * * - If 'default_port' is -1, then <port> is required. Otherwise, if * <port> is omitted, then 'default_port' is used instead. * * - If <port> (or 'default_port', if used) is 0, then no port is bound * and the TCP/IP stack will select a port. * * - If <ip> is omitted then the IP address is wildcarded. * * If successful, stores the address into '*sinp' and returns true; otherwise * zeros '*sinp' and returns false. */ bool inet_parse_passive(const char *target_, int default_port, struct sockaddr_in *sinp) { char *target = xstrdup(target_); char *string_ptr = target; const char *host_name; const char *port_string; bool ok = false; int port; /* Address defaults. */ memset(sinp, 0, sizeof *sinp); sinp->sin_family = AF_INET; sinp->sin_addr.s_addr = htonl(INADDR_ANY); sinp->sin_port = htons(default_port); /* Parse optional port number. */ port_string = strsep(&string_ptr, ":"); if (port_string && str_to_int(port_string, 10, &port)) { sinp->sin_port = htons(port); } else if (default_port < 0) { printf("%s: port number must be specified\n", target_); goto exit; } /* Parse optional bind IP. */ host_name = strsep(&string_ptr, ":"); if (host_name && host_name[0] && lookup_ip(host_name, &sinp->sin_addr)) { goto exit; } ok = true; exit: if (!ok) { memset(sinp, 0, sizeof *sinp); } free(target); return ok; }
/* Parses 'target', which should be a string in the format "<host>[:<port>]". * <host> is required. If 'default_port' is nonzero then <port> is optional * and defaults to 'default_port'. * * On success, returns true and stores the parsed remote address into '*sinp'. * On failure, logs an error, stores zeros into '*sinp', and returns false. */ bool inet_parse_active(const char *target_, uint16_t default_port, struct sockaddr_in *sinp) { char *target = xstrdup(target_); char *save_ptr = NULL; const char *host_name; const char *port_string; bool ok = false; /* Defaults. */ sinp->sin_family = AF_INET; sinp->sin_port = htons(default_port); /* Tokenize. */ host_name = strtok_r(target, ":", &save_ptr); port_string = strtok_r(NULL, ":", &save_ptr); if (!host_name) { goto exit; } /* Look up IP, port. */ if (lookup_ip(host_name, &sinp->sin_addr)) { goto exit; } if (port_string && atoi(port_string)) { sinp->sin_port = htons(atoi(port_string)); } else if (!default_port) { goto exit; } ok = true; exit: if (!ok) { memset(sinp, 0, sizeof *sinp); } free(target); return ok; }
inline int add_logfile_entry(time_t date, struct in_addr src_ip, unsigned long src_port, struct in_addr dst_ip, unsigned long dst_port, double packets, double bytes, struct t_ip_groups *groups ) { char date_str[80]; int src_grp, dst_grp; int traf_idx; int flag_local1, flag_local2; /* Если начальное время еще неопределено, берем его из перой строки */ if (groups->start == (time_t)-1) { struct tm t; /* Округляем время на начало часа */ localtime_r(&date, &t); t.tm_sec = 0; t.tm_min = 0; groups->start = mktime(&t); if ( groups->start == (time_t)-1 ) { fprintf(stderr, "cannot convert time\n"); return -1; } } traf_idx = time2idx(groups->start, date); if ( traf_idx < 0 || traf_idx >= MAX_HOUR_CNT) { ctime_r(&groups->start, date_str); date_str[24]='\0'; fprintf(stderr, "timedate out of range +Start time: %s, max num hour: %u\n", date_str, MAX_HOUR_CNT); return -2; } /* Максимальный индекс для опеределения с какого и по какое время выдавать результат */ if ( groups->traf_max < traf_idx) groups->traf_max = traf_idx; src_grp = lookup_ip(groups, src_ip, &flag_local1); dst_grp = lookup_ip(groups, dst_ip, &flag_local2); if ( (src_grp == -1) && (dst_grp >= 0) ) { /* Входящий трафик (к клиенту) */ groups->grp[dst_grp].traf_inb[traf_idx] += bytes; }else if ( (src_grp >= 0) && (dst_grp == -1) ) { /* Исходящий трафик (от клиента) */ groups->grp[src_grp].traf_outb[traf_idx] += bytes; }else if ( (src_grp >= 0) && (dst_grp >= 0) ) { /* * Локальный трафик (либо между узлами определенными в группах) * Его надо либо не считать, либо записывать только в одну группу * Если его записывать в обе группы, он испортит общую статистику * по загрузке. */ /* groups->grp[dst_grp].traf_inb[traf_idx] += bytes; */ /* Выводим трафик как локальный. local_flag устанавливается чтобы * выводить меньше одинаковых строк локального трафика */ if ( !flag_local1 || !flag_local2 ) { char src_ip_str[16]; char dst_ip_str[16]; set_local_flag(groups, src_ip, 1); set_local_flag(groups, dst_ip, 1); strncpy(src_ip_str, inet_ntoa(src_ip), sizeof(src_ip_str) - 1); strncpy(dst_ip_str, inet_ntoa(dst_ip), sizeof(dst_ip_str) - 1); ctime_r(&date, date_str); date_str[24]='\0'; fprintf(stderr, "local: %s(%i) from %s:%lu(%i) to %s:%lu(%i) - %lg packets %lg bytes\n", date_str, traf_idx, src_ip_str, src_port, src_grp>=0?groups->grp[src_grp].num:src_grp, dst_ip_str, dst_port, dst_grp>=0?groups->grp[dst_grp].num:dst_grp, packets, bytes); } }else /*if ( (src_grp == -1 ) && (dst_grp == -1) ) */ { /* Неопределенный трафик */ char src_ip_str[16]; char dst_ip_str[16]; strncpy(src_ip_str, inet_ntoa(src_ip), sizeof(src_ip_str) - 1); strncpy(dst_ip_str, inet_ntoa(dst_ip), sizeof(dst_ip_str) - 1); ctime_r(&date, date_str); date_str[24]='\0'; fprintf(stderr, "unknown: %s(%i) from %s:%lu(%i) to %s:%lu(%i) - %lg packets %lg bytes\n", date_str, traf_idx, src_ip_str, src_port, src_grp>=0?groups->grp[src_grp].num:src_grp, dst_ip_str, dst_port, dst_grp>=0?groups->grp[dst_grp].num:dst_grp, packets, bytes); } return 0; }
int resolve (char *host, struct in_addr *addr) { return (lookup_host(host,addr) || lookup_ip(host,addr)); }
void stat_server_read(void) { int n; char *p; int do_close = 0; char *salt, *servername; n = READ(global.stat_server_fd, Buf, sizeof(Buf)); if(n <= 0) { if(n == -1) logerr("stat_server_read", "read"); log_message_level( LOG_LEVEL_ERROR, "stat_server_read: got hangup"); do_close = 1; } else { /* find end of line */ p = strpbrk(Buf, "\r\n"); if(*p) *p = 0; p = Buf; n = atoi(Buf); if(n == 220) { /* got connect * first, save the salt */ next_arg(&p); salt = next_arg(&p); if(!salt) { log_message_level( LOG_LEVEL_ERROR, "stat_server_read:unable to get salt string"); strcpy(Buf, "QUIT\r\n"); WRITE(global.stat_server_fd, Buf, strlen(Buf)); } else { if(stat_server_salt) FREE(stat_server_salt); stat_server_salt = STRDUP(salt); snprintf(Buf, sizeof(Buf), "USER %s\r\n", global.stat_user); WRITE(global.stat_server_fd, Buf, strlen(Buf)); } } else if(n == 221) { /* server hangup */ do_close = 1; } else if(n == 300) { struct md5_ctx md; char hash[33]; md5_init_ctx(&md); md5_process_bytes(stat_server_salt, strlen(stat_server_salt), &md); md5_process_bytes(global.stat_pass, strlen(global.stat_pass), &md); md5_finish_ctx(&md, hash); expand_hex(hash, 16); hash[32] = 0; snprintf(Buf, sizeof(Buf), "PASS %s\r\n", hash); WRITE(global.stat_server_fd, Buf, strlen(Buf)); } else if(n == 201) { /* auth complete */ log_message_level( LOG_LEVEL_SERVER, "stat_server_read: logged in"); /* send updated ip:port in case we are a dynamic server */ snprintf(Buf, sizeof(Buf), "IPPORT %s %s %d\r\n",global.report_name, global.report_ip, global.report_port); WRITE(global.stat_server_fd, Buf, strlen(Buf)); /* force immediate update */ stat_server_push(); } /* The >= comparison made the comparison for == 400 some lines below not to work any more. So dynamic server addresses are not updated any more. But this solution is cumbersome - to say the least. Is there any better - and ofc any quicker detection of an ip address change possible? Now it takes up to stats_click seconds for a hub to recognize the change. */ else if(n / 100 > 4) { /* something failed */ log_message_level( LOG_LEVEL_SERVER, "stat_server_read:%s", Buf); strcpy(Buf, "QUIT\r\n"); WRITE(global.stat_server_fd, Buf, strlen(Buf)); } /* this part is needed if a server owner wants to use an alias usually server aliases are not resolvable - leodav */ else if(n == 400) { servername = lookup_hostname2(); log_message_level( LOG_LEVEL_SERVER, "stat_server_read:%s", Buf); strcpy(Buf, "QUIT\r\n"); WRITE(global.stat_server_fd, Buf, strlen(Buf)); global.serverIP = lookup_ip(servername); global.report_ip = STRDUP(my_ntoa(global.serverIP)); log_message_level( LOG_LEVEL_ERROR, "napigator.c:debug: %s", servername); } else if(n == 200) { /* stats updated successfully */ } else { log_message_level( LOG_LEVEL_ERROR, "stat_server_read: unhandled:%s", Buf); } } if(do_close) { log_message_level( LOG_LEVEL_SERVER, "stat_server_read: closing connection"); CLOSE(global.stat_server_fd); #if HAVE_POLL remove_fd(global.stat_server_fd); #else FD_CLR(global.stat_server_fd, &global.read_fds); FD_CLR(global.stat_server_fd, &global.write_fds); #endif global.stat_server_fd = INVALID_SOCKET; } }
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); }
void incoming_arp(VCC *vcc,struct atmarphdr *hdr,int len) { ITF *itf; ENTRY *entry; void *sha,*ssa,*spa,*tha,*tsa,*tpa; struct sockaddr_atmsvc source,target; uint32_t src_ip,tgt_ip; unsigned char *here; if (len < hdr->data-(unsigned char *) hdr) { diag(COMPONENT,DIAG_ERROR,"got truncated ARP packet (%d bytes)",len); return; } if (hdr->ar_hrd != htons(ARPHRD_ATM)) { diag(COMPONENT,DIAG_ERROR,"unknown hw protocol 0x%04x", ntohs(hdr->ar_hrd)); return; } if (hdr->ar_pro != htons(ETH_P_IP)) { diag(COMPONENT,DIAG_ERROR,"unknown upper protocol 0x%04x", ntohs(hdr->ar_pro)); return; } if (!(hdr->ar_shtl & TL_LEN)) hdr->ar_shtl = 0; /* paranoia */ if (!(hdr->ar_thtl & TL_LEN)) hdr->ar_thtl = 0; here = hdr->data; sha = get_addr(&here,hdr->ar_shtl & TL_LEN); ssa = get_addr(&here,hdr->ar_sstl & TL_LEN); spa = get_addr(&here,hdr->ar_spln); tha = get_addr(&here,hdr->ar_thtl & TL_LEN); tsa = get_addr(&here,hdr->ar_tstl & TL_LEN); tpa = get_addr(&here,hdr->ar_tpln); if (here-(unsigned char *) hdr > len) { diag(COMPONENT,DIAG_ERROR,"message too short (got %d, need %d)",len, here-(unsigned char *) hdr); return; } set_addr(&source,sha,ssa,hdr->ar_shtl,hdr->ar_sstl); set_addr(&target,tha,tsa,hdr->ar_thtl,hdr->ar_tstl); src_ip = get_ip(spa); tgt_ip = get_ip(tpa); { unsigned char *ipp; char buffer[MAX_ATM_ADDR_LEN+1]; ipp = (unsigned char *) &src_ip; diag(COMPONENT,DIAG_DEBUG," SRC IP: %d.%d.%d.%d",ipp[0],ipp[1],ipp[2], ipp[3]); if (atm2text(buffer,MAX_ATM_ADDR_LEN+1,(struct sockaddr *) &source,pretty) >= 0) diag(COMPONENT,DIAG_DEBUG," SRC ATM: %s",buffer); ipp = (unsigned char *) &tgt_ip; diag(COMPONENT,DIAG_DEBUG," DST IP: %d.%d.%d.%d",ipp[0],ipp[1],ipp[2], ipp[3]); if (atm2text(buffer,MAX_ATM_ADDR_LEN+1,(struct sockaddr *) &target,pretty) >= 0) diag(COMPONENT,DIAG_DEBUG," DST ATM: %s",buffer); } switch (ntohs(hdr->ar_op)) { case ARPOP_REQUEST: diag(COMPONENT,DIAG_DEBUG,"got ARP_REQ"); if (learn(vcc,src_ip,&source)) break; entry = NULL; itf = lookup_itf_by_ip(tgt_ip); entry = itf ? lookup_ip(itf,tgt_ip) : NULL; if (entry && entry->state == as_valid && (entry->flags & ATF_PUBL)) { if (entry->addr) arp_reply(vcc,tgt_ip,entry->addr,src_ip,&source); else arp_nak(vcc,tgt_ip,src_ip,&source); } else { if (itf && itf->local_ip == tgt_ip) arp_reply(vcc,tgt_ip,NULL,src_ip,&source); else arp_nak(vcc,tgt_ip,src_ip,&source); } break; case ARPOP_REPLY: diag(COMPONENT,DIAG_DEBUG,"got ARP_REP"); if (!vcc->entry || !(vcc->entry->flags & ATF_ARPSRV)) { diag(COMPONENT,DIAG_ERROR,"got ARP response from charlatan"); break; } (void) learn(NULL,src_ip,&source); break; case ARPOP_InREQUEST: diag(COMPONENT,DIAG_DEBUG,"got InARP_REQ"); if (!learn(vcc,src_ip,&source)) inarp_reply(vcc,src_ip,&source); break; case ARPOP_InREPLY: diag(COMPONENT,DIAG_DEBUG,"got InARP_REP"); (void) learn(vcc,src_ip,&source); break; case ARPOP_NAK: diag(COMPONENT,DIAG_DEBUG,"got ARP_NAK"); if (!vcc->entry || !(vcc->entry->flags & ATF_ARPSRV)) { diag(COMPONENT,DIAG_ERROR,"got ARP response from charlatan"); break; } learn_nak(tgt_ip); break; default: diag(COMPONENT,DIAG_ERROR,"unrecognized ARP op 0x%x", ntohs(hdr->ar_op)); } }
static int learn(VCC *vcc,uint32_t ip,struct sockaddr_atmsvc *addr) { ENTRY *entry; ITF *itf; VCC *walk,*next; unsigned char *ipp; int result = 0; if (!ip) return 0; ipp = (unsigned char *) &ip; itf = lookup_itf_by_ip(ip); if (!itf) { diag(COMPONENT,DIAG_ERROR,"got unroutable IP address %d.%d.%d.%d", ipp[0],ipp[1],ipp[2],ipp[3]); return 0; } entry = lookup_ip(itf,ip); assert(!vcc || vcc->entry); /* * If the entry on which we received the update isn't dangling but it * doesn't correspond to the one with the address, ... */ if (entry && vcc && vcc->entry->itf && entry != vcc->entry) { diag(COMPONENT,DIAG_DEBUG,"collision on %d.%d.%d.%d",ipp[0],ipp[1], ipp[2],ipp[3]); return 0; } /* * If the entry on which we received the update is dangling and we found * an entry that already describes that IP address, ... */ if (entry && vcc && !vcc->entry->itf) { if (!entry->svc) { diag(COMPONENT,DIAG_ERROR,"attempt to overwrite PVC for IP " "%d.%d.%d.%d",ipp[0],ipp[1],ipp[2],ipp[3]); return 0; } STOP_TIMER(vcc->entry); Q_REMOVE(unknown_incoming,vcc->entry); free(vcc->entry); vcc->entry = entry; Q_INSERT_HEAD(entry->vccs,vcc); set_sndbuf(vcc); entry->flags &= ~ATF_NOVC; assert(!vcc->connecting); if (set_ip(vcc->fd,ip) < 0) { diag(COMPONENT,DIAG_ERROR,"set_ip: %s",strerror(errno)); disconnect_vcc(vcc); vcc = NULL; result = -1; } } /* * If we still don't have an entry, we try to use the entry that already * belongs to the VCC (InARP), or we create a new one (ARP). */ if (!entry) { if (vcc) { entry = vcc->entry; if (!entry->itf) { Q_REMOVE(unknown_incoming,entry); entry->sndbuf = itf->sndbuf; set_sndbuf(vcc); } else if (entry->ip && entry->ip != ip && (entry->flags & ATF_PERM) && !(entry->flags & ATF_ARPSRV)) { diag(COMPONENT,DIAG_ERROR,"ignoring attempt to change IP " "address of permanent entry (to %d.%d.%d.%d)",ipp[0], ipp[1],ipp[2],ipp[3]); return result; } } else { entry = alloc_entry(1); entry->flags = ATF_PUBL; } } if (!atmsvc_addr_in_use(*addr)) addr = NULL; if (entry->addr && addr && (entry->flags & ATF_PERM) && !atm_equal((struct sockaddr *) entry->addr,(struct sockaddr *) addr,0,0)) { diag(COMPONENT,DIAG_ERROR,"ignoring attempt to change ATM address of " "permanent entry"); return result; } if (entry->state == as_valid && entry->ip == ip && (!addr || (entry->addr && atm_equal((struct sockaddr *) entry->addr,(struct sockaddr *) addr,0, 0)))) return result; /* no news */ STOP_TIMER(entry); if (entry->ip != ip) send_notifications(entry,0); entry->ip = ip; if (!entry->itf) { entry->itf = itf; /* @@@ * Need to fix this is in case we allow entries without a valid IP * address but with a pre-set QOS, e.g. a VC on a given PVC with an * unknown remote end. */ entry->qos = entry->itf->qos; adjust_qos(entry->itf,&entry->qos,0); Q_INSERT_HEAD(itf->table,entry); } if (entry->itf != itf) diag(COMPONENT,DIAG_ERROR,"interesting, interface has changed ... " "(%d -> %d)",entry->itf->number,itf->number); if (addr) { if (!entry->addr) entry->addr = alloc(sizeof(*addr)); *entry->addr = *addr; if (merge) { ENTRY *incoming; while ((incoming = lookup_incoming(addr))) { STOP_TIMER(incoming); Q_REMOVE(unknown_incoming,incoming); incoming->vccs->entry = entry; Q_INSERT_HEAD(entry->vccs,incoming->vccs); set_sndbuf(incoming->vccs); free(incoming); } } } for (walk = entry->vccs; walk; walk = next) { next = walk->next; if (!walk->connecting) if (set_ip(walk->fd,ip) < 0) { diag(COMPONENT,DIAG_ERROR,"set_ip: %s",strerror(errno)); disconnect_vcc(walk); if (walk == vcc) result = -1; } } if (entry->state != as_valid) { if (!entry->vccs && itf->arp_srv && !(entry->flags & ATF_NOVC)) connect_me(entry); send_notifications(entry,1); } if ((entry->flags & ATF_ARPSRV) || !(entry->flags & ATF_PERM)) { if (entry->itf->arp_srv) START_TIMER(entry,CREVAL); else START_TIMER(entry,SREVAL); } entry->state = as_valid; return result; }