Exemple #1
0
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;
}
Exemple #2
0
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);
	}
}