static inline void ipcs_table_refresh_wireless(struct nc_ipcs_table *tbl, int fd) { struct nc_ipcs_table_item *ipc = NULL; char iface_name[32]; uint8_t hwaddr[ETH_ALEN] = {0}; uint32_t src_ip = 0; int ret = -1; int i; if (tbl->wireless_enable == 0) { return ; } sprintf(iface_name, "%s.%d", tbl->iface_name, NC_WIRELESS_VID); ret = get_iface_addr(iface_name, hwaddr, ETH_ALEN, &src_ip); if (ret < 0) { return ; } if (tbl->wireless_enable) { for (i = 0; i < NC_WIRELESS_SZ; ++i) { ipc = &tbl->wireless_ipcs[i]; if (ipc->alive_sec < 0) { continue; } if (ipc->alive_sec == 0) { send_ipc_info(tbl, -1, ipc->mac, ipc->ip, 1); } else { if ((ipc->alive_sec & 0x1) == 0x1) { st_dbg("send to \n"); send_arp_req(fd, hwaddr, src_ip, ipc->ip, NULL, 0); } } } } }
static int recv_onvif_probematch( struct nc_ipcs_table *tbl, int arp_fd, int port_idx, char *probematch, int pm_len, struct sockaddr_in *addr ) { char iface_name[32]; uint8_t hwaddr[ETH_ALEN] = {0}; uint32_t src_ip = 0; uint32_t tgt_ip = addr->sin_addr.s_addr; struct sockaddr_ll hw_sa; int ret = -1; if (port_idx < 0) { sprintf(iface_name, "%s.%d", tbl->iface_name, NC_WIRELESS_VID); } else { sprintf(iface_name, "%s.%d", tbl->iface_name, NC_WIRE_VID_START + port_idx); } ret = get_iface_addr(iface_name, hwaddr, ETH_ALEN, &src_ip); if (ret < 0) { return -1; } memset(&hw_sa, 0, sizeof(hw_sa)); hw_sa.sll_family = AF_PACKET; hw_sa.sll_protocol = htons(ETH_P_ARP); hw_sa.sll_ifindex = if_nametoindex(iface_name); hw_sa.sll_halen = ETH_ALEN; memcpy(hw_sa.sll_addr, hwaddr, ETH_ALEN); return send_arp_req(arp_fd, hwaddr, src_ip, tgt_ip, &hw_sa, sizeof(hw_sa)); }
static inline void ipcs_table_refresh_wire(struct nc_ipcs_table *tbl, int *fds) { struct nc_ipcs_table_item *ipc = NULL; int i; for (i = 0; i < tbl->wire_cnt; ++i) { ipc = &tbl->wire_ipcs[i]; if (ipc->alive_sec < 0) { continue; } if (ipc->alive_sec == 0) { send_ipc_info(tbl, i, ipc->mac, ipc->ip, 1); } else { char iface_name[32]; uint8_t hwaddr[ETH_ALEN] = {0}; uint32_t src_ip = 0; int ret = -1; sprintf(iface_name, "%s.%d", tbl->iface_name, NC_WIRE_VID_START + i); ret = get_iface_addr(iface_name, hwaddr, ETH_ALEN, &src_ip); if (ret < 0) { continue; } send_arp_req(fds[i], hwaddr, src_ip, ipc->ip, NULL, 0); } } }
int main(int argc, char *argv[]) { unsigned int client; int nOptCh, nRes, nServerPort = SERVER_LISTEN_PORT; char * szRootDir = NULL; char * szPeerName; char szTemp[2048]; struct sockaddr_in server_addr ; memset( &server_addr, 0, sizeof( struct sockaddr_in ) ); // initialize language for i18n setlocale(LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); g_dwDebugLevel = DEFAULT_DEBUG_LEVEL; g_nDebugThreadMain = getpid(); g_bBeDaemon = false; g_bMustLogin = true; g_bUseSSL = true; g_uiNbClients = MAX_CLIENTS; #ifdef HAVE_GETOPT_H while ((nOptCh = getopt_long(argc, argv, optstring, long_options,NULL)) != EOF) #else while ((nOptCh = getopt(argc, argv, optstring)) != -1) #endif { switch (nOptCh) { case 'p': // listening port nServerPort = atoi(optarg); break; case 'N': // maximum number of clients g_uiNbClients = (unsigned int) atoi(optarg); break; case 'h': // help Usage(); case 'v': // version #ifdef HAVE_SSL printf(i18n("Partition Image Daemon version %s+SSL\n"), PACKAGE_VERSION); #else printf(i18n("Partition Image Daemon version %s\n"), PACKAGE_VERSION); #endif printf(i18n("(distributed under the GNU GPL 2)\n")); exit(0); case 'D': // daemonize g_bBeDaemon = true; break; case 'd': if (chdir(optarg) != 0) { printf(i18n("Directory %s: %s\n"), optarg, strerror(errno)); exit(-1); } break; case 'r': // change chroot if ((optarg) && (optarg[0])) szRootDir = strdup(optarg); break; case 'g': // debug level g_dwDebugLevel = atol(optarg); if (g_dwDebugLevel < 0 || g_dwDebugLevel > 10) g_dwDebugLevel = DEFAULT_DEBUG_LEVEL; break; case 'i': // compilation options formatCompilOptions(szTemp, sizeof(szTemp)); printf("%s\n", szTemp); return EXIT_SUCCESS; break; case 'L': // no login g_bMustLogin = false; break; case 'n': // no SSL g_bUseSSL = false; break; #ifdef __linux__ case 'I': // Bind the daemon to this interface... if ( ! get_iface_addr( &server_addr, optarg ) ) { printf(i18n("Bad network interface name: %s\n"), optarg ); exit( -1 ); } break; #endif default: break; } } if (szRootDir) { // showDebug(2, "about to chroot to %s\n", szRootDir); // g_privs->Root(); if (chdir(szRootDir) < 0) { // g_privs->User(); fprintf(g_fDebug, i18n("failed to chdir to %s: %s\n"), szRootDir, strerror(errno)); delete g_Window; g_Window = NULL; exit(1); } if (chroot(szRootDir) < 0) { // g_privs->User(); fprintf(g_fDebug, i18n("failed to chroot: %s\n"), strerror(errno)); delete g_Window; g_Window = NULL; exit(1); } if (chdir("/") < 0) { // g_privs->User(); fprintf(g_fDebug, i18n("failed to chdir to /: %s\n"), strerror(errno)); delete g_Window; g_Window = NULL; exit(1); } // g_privs->User(); // showDebug(1, "root changed to %s\n", szRootDir); free(szRootDir); szRootDir = NULL; } // Warn: no showDebug must have been called before this point Initialize(); #ifdef MUST_LOGIN if (g_bMustLogin) { if (CheckAccessFile(PARTIMAGED_USERS)) exit(1); } #endif #ifdef HAVE_SSL if (g_bUseSSL) { if ( CheckAccessFile(KEYF) || CheckAccessFile(CERTF) ) { exit(1); } } #endif // pthread_t is no longer needed since we fork for each client // but kept for try catch exceptions to deal with g_uiNbClients pthread_t threads[g_uiNbClients] __attribute__ ((unused)) ; // register signals signal(SIGTERM, catch_sigint); signal(SIGINT, catch_sigint); signal(SIGSEGV, catch_sigint); // segmentation fault signal(SIGCHLD, catch_sigchild); // dont ignore child exits if (g_bBeDaemon) { // fork - so i'm not the owner of the process group any more int pgrp; int i = fork(); if (i < 0) { showDebug(1, "can't fork: %s\n", strerror(errno)); exit(1); } if (i > 0) exit(0); // no need for the parent any more pgrp = setsid(); if (pgrp < 0) { showDebug(1, "can't daemonize: %s\n", strerror(errno)); exit(1); } /* FIXME: this will break 'socket' call close(fileno(stdin)); close(fileno(stdout)); close(fileno(stderr)); */ #ifdef HAVE_SETPGID setpgid(0, getpid()); #else # ifdef SETPGRP_VOID setpgrp(); # else setpgrp(0, getpid()); # endif #endif } try { g_Server = new CNetServer( server_addr.sin_addr.s_addr, nServerPort); } catch ( CExceptions * excep ) { showDebug(1, "fatal error: get exception %d\n", excep->GetExcept()); fclose(g_fDebug); exit(1); } // g_Window = new CPartimagedInterfaceDummy(); g_Window = new CPartimagedInterfaceNewt(); g_Window->Status(i18n("Waiting for client ...")); while (1) { showDebug(1, "infernal loop\n"); try { client = g_Server->AcceptClient(); } catch ( CExceptions * excep ) { showDebug(1, "*** excep catched\n"); switch (excep -> GetExcept()) { case ERR_ERRNO: showDebug(1, "accept failed with %s\n", strerror(excep->get_dwArg1())); continue; // jump to next client case ERR_TOOMANY: showDebug(3, "too many clients -> one refused\n"); if (!g_bBeDaemon) g_Window->Status(i18n("too much client connected")); else fprintf(stderr, i18n("partimaged: too much clients connected\n")); continue; // jump to next client case ERR_REFUSED: showDebug(1, "refused: banner or version\n"); // client is undefined->we can't show it // g_Window->SetState(client, "error !"); // g_Window->SetLocation(client, "(wrong banner)"); continue; // jump to next client default: showDebug(1, "other exception: %d\n", excep->GetExcept()); continue; // jump to next client } showDebug(1, "ARG: reached unexpected point\n"); continue; // we shouldn't reach this point but never knows } showDebug(1, "client %d arrived\n", client); g_Window->SetState(client, i18n("connected")); szPeerName = g_Server -> GetPeer(client); g_Window->SetHostname(client, szPeerName); free(szPeerName); nRes = g_Server->ValidatePass(client); if (nRes) { g_Window->SetState(client, i18n("error!")); g_Window->SetLocation(client, i18n("(wrong password)")); } else { int rv = fork(); if ( rv < 0 ) { showDebug(1, "Cannot fork() on incoming connection - %s\n", strerror(errno)); continue; } if ( ! rv ) partimaged(&client); // child process else { // Store child process PID if (!g_Server->SetClientPid(client, rv)) { showDebug(1, "Cannot store client PID for client: %d\n", client); } } } } // infernal loop showDebug(1, "end of partimaged-main\n"); while(1); delete g_Server; g_Server = NULL; delete g_Window; g_Window = NULL; fclose(g_fDebug); }
static int onvif_socket_create(const char *iface_name) { int fd = -1, n = 0; uint8_t hwaddr[ETH_ALEN] = {0}; struct in_addr sin_addr = {0}; struct ifreq ifr; char sip[INET_ADDRSTRLEN] = {0}; const char *sip_str = NULL; struct addrinfo hints; struct addrinfo *res = NULL; struct addrinfo *ressave = NULL; int val = 0; int ret = -1; ret = get_iface_addr(iface_name, hwaddr, ETH_ALEN, &sin_addr.s_addr); if (ret < 0) { st_err("get_iface_addr failed!\n"); return -1; } sip_str = inet_ntop(AF_INET, &sin_addr, sip, INET_ADDRSTRLEN); if (!sip_str) { st_err("inet_ntop error:%d!\n", errno); perror("inet_ntop"); return -1; } bzero(&hints, sizeof(hints)); hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; n = getaddrinfo(sip, NULL, &hints, &res); if (n != 0) { st_err("error for %s - %s: %s\n", iface_name, sip, gai_strerror(n)); return -1; } ressave = res; do { fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (fd < 0) { continue; } val = 1; ret = setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val) ); if( ret < 0 ) { st_err("ioctl error:%d!\n", errno); perror("ioctl"); goto sock_err; } memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, iface_name); ret = setsockopt( fd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&ifr, sizeof(ifr) ); if( ret < 0 ) { st_err("ioctl error:%d!\n", errno); perror("ioctl"); goto sock_err; } ret = bind(fd, res->ai_addr, res->ai_addrlen); if (ret == 0) { break; } sock_err: close(fd); } while ((res = res->ai_next) != NULL); if (res == NULL) { st_err("error for %s - %s\n", iface_name, sip); perror("\n"); goto error; } freeaddrinfo(ressave); return fd; error: if (ressave) { freeaddrinfo(ressave); } return -1; }