void * run_snmpd(void) { int c; union { struct sockaddr_in sa; #ifdef __IPV6__ struct sockaddr_in6 sa6; #endif } sockaddr; my_socklen_t socklen; struct timeval tv_last; struct timeval tv_now; struct timeval tv_sleep; struct ifreq ifreq; int ticks; fd_set rfds; fd_set wfds; int nfds; int i; /* Prevent TERM and HUP signals from interrupting system calls */ signal(SIGTERM, handle_signal); signal(SIGHUP, handle_signal); siginterrupt(SIGTERM, 0); siginterrupt(SIGHUP, 0); /* Open the syslog connection if needed */ #ifdef SYSLOG openlog("mini_snmpd", LOG_CONS | LOG_PID, LOG_DAEMON); #endif /* Print a starting message (so the user knows the args were ok) */ if (g_bind_to_device[0] != '\0') { lprintf(LOG_INFO, "started, listening on port %d/udp and %d/tcp on interface %s\n", g_udp_port, g_tcp_port, g_bind_to_device); } else { lprintf(LOG_INFO, "started, listening on port %d/udp and %d/tcp\n", g_udp_port, g_tcp_port); } /* Store the starting time since we need it for MIB updates */ if (gettimeofday(&tv_last, NULL) == -1) { memset(&tv_last, 0, sizeof (tv_last)); memset(&tv_sleep, 0, sizeof (&tv_sleep)); } else { tv_sleep.tv_sec = g_timeout / 100; tv_sleep.tv_usec = (g_timeout % 100) * 10000; } /* Build the MIB and execute the first MIB update to get actual values */ if (mib_build() == -1) { exit(EXIT_SYSCALL); } else if (mib_update(1) == -1) { exit(EXIT_SYSCALL); } #ifdef DEBUG dump_mib(g_mib, g_mib_length); #endif /* Open the server's UDP port and prepare it for listening */ g_udp_sockfd = socket((g_family == AF_INET) ? PF_INET : PF_INET6, SOCK_DGRAM, 0); if (g_udp_sockfd == -1) { lprintf(LOG_ERR, "could not create UDP socket: %m\n"); exit(EXIT_SYSCALL); } if (g_family == AF_INET) { sockaddr.sa.sin_family = g_family; sockaddr.sa.sin_port = htons(g_udp_port); sockaddr.sa.sin_addr = inaddr_any; socklen = sizeof(sockaddr.sa); #ifdef __IPV6__ } else { sockaddr.sa6.sin6_family = g_family; sockaddr.sa6.sin6_port = htons(g_udp_port); sockaddr.sa6.sin6_addr = in6addr_any; socklen = sizeof(sockaddr.sa6); #endif } if (bind(g_udp_sockfd, (struct sockaddr *)&sockaddr, socklen) == -1) { lprintf(LOG_ERR, "could not bind UDP socket to port %d: %m\n", g_udp_port); exit(EXIT_SYSCALL); } if (g_bind_to_device[0] != '\0') { snprintf(ifreq.ifr_ifrn.ifrn_name, sizeof (ifreq.ifr_ifrn.ifrn_name), "%s", g_bind_to_device); if (setsockopt(g_udp_sockfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&ifreq, sizeof(ifreq)) == -1) { lprintf(LOG_WARNING, "could not bind UDP socket to device %s: %m\n", g_bind_to_device); exit(EXIT_SYSCALL); } } /* Open the server's TCP port and prepare it for listening */ g_tcp_sockfd = socket((g_family == AF_INET) ? PF_INET : PF_INET6, SOCK_STREAM, 0); if (g_tcp_sockfd == -1) { lprintf(LOG_ERR, "could not create TCP socket: %m\n"); exit(EXIT_SYSCALL); } if (g_bind_to_device[0] != '\0') { snprintf(ifreq.ifr_ifrn.ifrn_name, sizeof (ifreq.ifr_ifrn.ifrn_name), "%s", g_bind_to_device); if (setsockopt(g_tcp_sockfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&ifreq, sizeof(ifreq)) == -1) { lprintf(LOG_WARNING, "could not bind TCP socket to device %s: %m\n", g_bind_to_device); exit(EXIT_SYSCALL); } } i = 1; if (setsockopt(g_tcp_sockfd, SOL_SOCKET, SO_REUSEADDR, &c, sizeof (i)) == -1) { lprintf(LOG_WARNING, "could not set SO_REUSEADDR on TCP socket: %m\n"); exit(EXIT_SYSCALL); } if (g_family == AF_INET) { sockaddr.sa.sin_family = g_family; sockaddr.sa.sin_port = htons(g_udp_port); sockaddr.sa.sin_addr = inaddr_any; socklen = sizeof(sockaddr.sa); #ifdef __IPV6__ } else { sockaddr.sa6.sin6_family = g_family; sockaddr.sa6.sin6_port = htons(g_udp_port); sockaddr.sa6.sin6_addr = in6addr_any; socklen = sizeof(sockaddr.sa6); #endif } if (bind(g_tcp_sockfd, (struct sockaddr *)&sockaddr, socklen) == -1) { lprintf(LOG_ERR, "could not bind TCP socket to port %d: %m\n", g_tcp_port); exit(EXIT_SYSCALL); } if (listen(g_tcp_sockfd, 128) == -1) { lprintf(LOG_ERR, "could not prepare TCP socket for listening: %m\n"); exit(EXIT_SYSCALL); } /* Handle incoming connect requests and incoming data */ while (!g_quit) { /* Sleep until we get a request or the timeout is over */ FD_ZERO(&rfds); FD_ZERO(&wfds); FD_SET(g_udp_sockfd, &rfds); FD_SET(g_tcp_sockfd, &rfds); nfds = (g_udp_sockfd > g_tcp_sockfd) ? g_udp_sockfd : g_tcp_sockfd; for (i = 0; i < g_tcp_client_list_length; i++) { if (g_tcp_client_list[i]->outgoing) { FD_SET(g_tcp_client_list[i]->sockfd, &wfds); } else { FD_SET(g_tcp_client_list[i]->sockfd, &rfds); } if (nfds < g_tcp_client_list[i]->sockfd) { nfds = g_tcp_client_list[i]->sockfd; } } if (select(nfds + 1, &rfds, &wfds, NULL, &tv_sleep) == -1) { if (g_quit) { break; } lprintf(LOG_ERR, "could not select from sockets: %m\n"); exit(EXIT_SYSCALL); } /* Determine whether to update the MIB and the next ticks to sleep */ ticks = ticks_since(&tv_last, &tv_now); if (ticks < 0 || ticks >= g_timeout) { lprintf(LOG_DEBUG, "updating the MIB (full)\n"); if (mib_update(1) == -1) { exit(EXIT_SYSCALL); } memcpy(&tv_last, &tv_now, sizeof (tv_now)); tv_sleep.tv_sec = g_timeout / 100; tv_sleep.tv_usec = (g_timeout % 100) * 10000; } else { lprintf(LOG_DEBUG, "updating the MIB (partial)\n"); if (mib_update(0) == -1) { exit(EXIT_SYSCALL); } tv_sleep.tv_sec = (g_timeout - ticks) / 100; tv_sleep.tv_usec = ((g_timeout - ticks) % 100) * 10000; } #ifdef DEBUG dump_mib(g_mib, g_mib_length); #endif /* Handle UDP packets, TCP packets and TCP connection connects */ if (FD_ISSET(g_udp_sockfd, &rfds)) { handle_udp_client(); } if (FD_ISSET(g_tcp_sockfd, &rfds)) { handle_tcp_connect(); } for (i = 0; i < g_tcp_client_list_length; i++) { if (g_tcp_client_list[i]->outgoing) { if (FD_ISSET(g_tcp_client_list[i]->sockfd, &wfds)) { handle_tcp_client_write(g_tcp_client_list[i]); } } else { if (FD_ISSET(g_tcp_client_list[i]->sockfd, &rfds)) { handle_tcp_client_read(g_tcp_client_list[i]); } } } /* If there was a TCP disconnect, remove the client from the list */ for (i = 0; i < g_tcp_client_list_length; i++) { if (g_tcp_client_list[i]->sockfd == -1) { g_tcp_client_list_length--; if (i < g_tcp_client_list_length) { free(g_tcp_client_list[i]); memmove(&g_tcp_client_list[i], &g_tcp_client_list[i + 1], (g_tcp_client_list_length - i) * sizeof (g_tcp_client_list[i])); } } } } /* We were killed, print a message and exit */ lprintf(LOG_INFO, "stopped\n"); //return EXIT_OK; }
static void manual_cmd_handler(int sig_no) { FILE *fp; char line[300], *t1=NULL, *t2=NULL, *t3=NULL, *t4=NULL; int num; char tmp_buf[100]; char cmd_rsp[MAX_HOST_CMD_LEN]; fp = fopen(CMD_FILE, "r"); if (fp == NULL) { DEBUG_ERR("manual cmd file empty!\n"); return; } fgets(line, sizeof(line), fp); fclose(fp); unlink(CMD_FILE); num = get_token(line, &t1, &t2, &t3, &t4); if (!strcmp(t1, DUMP_ALL_MIB)) { printf("\n------ Read/Write MIB ------\n"); sprintf(tmp_buf,"%s ",t2); dump_mib( 1, tmp_buf); } else if (num == 2 && !strcmp(t1, "getstainfo")) { printf("\n--------getstainfo---------- \n"); strcpy(cmd_rsp,t2); if(do_cmd(id_getstainfo,cmd_rsp,strlen(t2)+1, 0) < 0) DEBUG_ERR("getstainfo failed !\n"); else//ok print_stainfo(cmd_rsp); } else if (num == 2 && !strcmp(t1, "getassostanum")) { printf("\n--------getassostanum---------- \n"); strcpy(cmd_rsp,t2); if(do_cmd(id_getassostanum,cmd_rsp,strlen(t2)+1, 0) < 0) DEBUG_ERR("getassostanum failed !\n"); else printf("Associated statsion number = %d \n",(unsigned char)cmd_rsp[0]); } else if (num == 2 && !strcmp(t1, "getbssinfo")) { printf("\n--------getbssinfo---------- \n"); strcpy(cmd_rsp,t2); if(do_cmd(id_getbssinfo,cmd_rsp,strlen(t2)+1, 0) < 0) DEBUG_ERR("getbssinfo failed !\n"); else//ok print_bssinfo(cmd_rsp); } else if (num == 2 && !strcmp(t1, "set_mib")) { if(do_cmd(id_set_mib,t2,strlen(t2)+1, 0) < 0) DEBUG_ERR("set_mib failed : [%s]!\n", t2); else//ok printf("set_mib ok: [%s]\n", t2); } else if (num == 2 && !strcmp(t1, "get_mib")) { if(do_cmd(id_get_mib,t2,strlen(t2)+1, 0) < 0) DEBUG_ERR("get_mib failed : [%s]!\n", t2); else//ok printf("get_mib ok: [%s]\n", t2); //printf("get_mib [%s] :",t2); //dump_mib( 0, t2); } else if (num == 2 && !strcmp(t1, "sysinit")) { strcpy(tmp_buf,t2); if(do_cmd(id_sysinit,t2,strlen(t2)+1, 0) < 0) DEBUG_ERR("sysinit failed : [%s]!\n", tmp_buf); else//ok printf("sysinit ok: [%s]\n", tmp_buf); } else if (num == 2 && !strcmp(t1, "getlanstatus")) { strcpy(cmd_rsp,t2); if(do_cmd(id_getlanstatus,cmd_rsp,strlen(t2)+1, 0) < 0) DEBUG_ERR("getlanstatus failed : [%s]!\n", t2); else//ok { printf("getlanstatus ok: [%s]\n", t2); print_port_status(cmd_rsp); } } else if (num == 2 && !strcmp(t1, "getstats")) { strcpy(cmd_rsp,t2); if(do_cmd(id_getstats,cmd_rsp,strlen(t2)+1, 0) < 0) DEBUG_ERR("getstats failed : [%s]!\n", t2); else//ok { printf("getstats ok: [%s] \n", t2); print_port_stats(cmd_rsp); } } else { DEBUG_ERR("%s: invalid cmd! [num=%d, t1=%s, t2=%s, t3=%s]\n", __FUNCTION__, num, t1, t2, t3); } }