/* * XXX Figure out the way to bind a specific adapter to a socket. */ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) { PMIB_IFTABLE Table = (PMIB_IFTABLE) malloc(sizeof(MIB_IFTABLE)); DWORD Error, Size = sizeof(MIB_IFTABLE); PDHCP_ADAPTER Adapter = NULL; HANDLE AdapterStateChangedEvent = (HANDLE)Context; struct interface_info *ifi = NULL; struct protocol *proto; int i, AdapterCount = 0, Broadcast; /* FIXME: Kill this thread when the service is stopped */ do { DH_DbgPrint(MID_TRACE,("Getting Adapter List...\n")); while( (Error = GetIfTable(Table, &Size, 0 )) == ERROR_INSUFFICIENT_BUFFER ) { DH_DbgPrint(MID_TRACE,("Error %d, New Buffer Size: %d\n", Error, Size)); free( Table ); Table = (PMIB_IFTABLE) malloc( Size ); } if( Error != NO_ERROR ) { /* HACK: We are waiting until TCP/IP starts */ Sleep(2000); continue; } DH_DbgPrint(MID_TRACE,("Got Adapter List (%d entries)\n", Table->dwNumEntries)); for( i = Table->dwNumEntries - 1; i >= 0; i-- ) { DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n", Table->table[i].dwIndex)); ApiLock(); if ((Adapter = AdapterFindByHardwareAddress(Table->table[i].bPhysAddr, Table->table[i].dwPhysAddrLen))) { proto = find_protocol_by_adapter(&Adapter->DhclientInfo); /* This is an existing adapter */ if (InterfaceConnected(&Table->table[i])) { /* We're still active so we stay in the list */ ifi = &Adapter->DhclientInfo; /* This is a hack because IP helper API sucks */ if (IsReconnectHackNeeded(Adapter, &Table->table[i])) { /* This handles a disconnect/reconnect */ if (proto) remove_protocol(proto); Adapter->DhclientInfo.client->state = S_INIT; /* These are already invalid since the media state change */ Adapter->RouterMib.dwForwardNextHop = 0; Adapter->NteContext = 0; add_protocol(Adapter->DhclientInfo.name, Adapter->DhclientInfo.rfdesc, got_one, &Adapter->DhclientInfo); state_init(&Adapter->DhclientInfo); SetEvent(AdapterStateChangedEvent); } } else { if (proto) remove_protocol(proto); /* We've lost our link so out we go */ RemoveEntryList(&Adapter->ListEntry); free(Adapter); } ApiUnlock(); continue; } ApiUnlock(); Adapter = (DHCP_ADAPTER*) calloc( sizeof( DHCP_ADAPTER ) + Table->table[i].dwMtu, 1 ); if( Adapter && Table->table[i].dwType == MIB_IF_TYPE_ETHERNET && InterfaceConnected(&Table->table[i])) { memcpy( &Adapter->IfMib, &Table->table[i], sizeof(Adapter->IfMib) ); Adapter->DhclientInfo.client = &Adapter->DhclientState; Adapter->DhclientInfo.rbuf = Adapter->recv_buf; Adapter->DhclientInfo.rbuf_max = Table->table[i].dwMtu; Adapter->DhclientInfo.rbuf_len = Adapter->DhclientInfo.rbuf_offset = 0; memcpy(Adapter->DhclientInfo.hw_address.haddr, Adapter->IfMib.bPhysAddr, Adapter->IfMib.dwPhysAddrLen); Adapter->DhclientInfo.hw_address.hlen = Adapter->IfMib.dwPhysAddrLen; /* I'm not sure where else to set this, but some DHCP servers won't take a zero. We checked the hardware type earlier in the if statement. */ Adapter->DhclientInfo.hw_address.htype = HTYPE_ETHER; if( DhcpSocket == INVALID_SOCKET ) { DhcpSocket = Adapter->DhclientInfo.rfdesc = Adapter->DhclientInfo.wfdesc = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); if (DhcpSocket != INVALID_SOCKET) { /* Allow broadcast on this socket */ Broadcast = 1; setsockopt(DhcpSocket, SOL_SOCKET, SO_BROADCAST, (const char *)&Broadcast, sizeof(Broadcast)); Adapter->ListenAddr.sin_family = AF_INET; Adapter->ListenAddr.sin_port = htons(LOCAL_PORT); Adapter->BindStatus = (bind( Adapter->DhclientInfo.rfdesc, (struct sockaddr *)&Adapter->ListenAddr, sizeof(Adapter->ListenAddr) ) == 0) ? 0 : WSAGetLastError(); } else { error("socket() failed: %d\n", WSAGetLastError()); } } else { Adapter->DhclientInfo.rfdesc = Adapter->DhclientInfo.wfdesc = DhcpSocket; } Adapter->DhclientConfig.timeout = DHCP_PANIC_TIMEOUT; Adapter->DhclientConfig.initial_interval = DHCP_DISCOVER_INTERVAL; Adapter->DhclientConfig.retry_interval = DHCP_DISCOVER_INTERVAL; Adapter->DhclientConfig.select_interval = 1; Adapter->DhclientConfig.reboot_timeout = DHCP_REBOOT_TIMEOUT; Adapter->DhclientConfig.backoff_cutoff = DHCP_BACKOFF_MAX; Adapter->DhclientState.interval = Adapter->DhclientConfig.retry_interval; if( PrepareAdapterForService( Adapter ) ) { Adapter->DhclientInfo.next = ifi; ifi = &Adapter->DhclientInfo; read_client_conf(&Adapter->DhclientInfo); if (Adapter->DhclientInfo.client->state == S_INIT) { add_protocol(Adapter->DhclientInfo.name, Adapter->DhclientInfo.rfdesc, got_one, &Adapter->DhclientInfo); state_init(&Adapter->DhclientInfo); } ApiLock(); InsertTailList( &AdapterList, &Adapter->ListEntry ); AdapterCount++; SetEvent(AdapterStateChangedEvent); ApiUnlock(); } else { free( Adapter ); Adapter = 0; } } else { free( Adapter ); Adapter = 0; } if( !Adapter ) DH_DbgPrint(MID_TRACE,("Adapter %d was rejected\n", Table->table[i].dwIndex)); } #if 0 Error = NotifyAddrChange(NULL, NULL); if (Error != NO_ERROR) break; #else Sleep(3000); #endif } while (TRUE); DbgPrint("DHCPCSVC: Adapter discovery thread is terminating! (Error: %d)\n", Error); if( Table ) free( Table ); return Error; }
/* * Main program for daemon. */ int main (int argc, char **argv) { int opt; int result = -1; struct stat st; /* check options.chroot_directory */ FILE *fd; /* Check *.pem files */ char *command = NULL; char *cat = NULL; char *server = NULL; char buf[SIZE]; char **c = NULL; int i = 0; char **arg = NULL; /* Use when creuvux is run with option from command line */ int arg_inc = 0; int mode_script = -1; /* if mode_script = 1, script mode is enable */ char *zErrMsg = 0; int rc = -1; /* Ensure that standart files descriptor 0, 1 and 2 are open or directed to /dev/null */ crv_sanitise_stdfd(); /* Initialize configuration options to their default values. */ initialize_client_options(&options); while ((opt = getopt(argc, argv, "f:c:hv")) != -1) { switch(opt) { case 'h': /* Print Help */ fprintf(stdout, "%s\n", "Help:"); usage (NULL); exit(EXIT_SUCCESS); case 'v': /* Print version */ fprintf (stderr, "%s%s\n", "creuvux version ", CREUVUX_VERSION); fprintf (stderr, "%s\n", "Before reporting bugs ([email protected]) please check " "the development CHANGELOG to make sure it hasn't already " "been fixed in devel."); exit(1); case 'f': /* Config File */ crv_free(options.config); options.config = crv_strdup(optarg); break; case 'c': /* Get command */ mode_script = 1; if (NULL == (c = malloc (SIZE * sizeof *c))) exit(EXIT_FAILURE); for (i = 2; argv[i]; i++) c[i-2] = crv_strdup(argv[i]); for (i = 0; c[i]; i++) printf("-> %s\n", c[i]); break; case '?': default: usage(NULL); exit(EXIT_FAILURE); } } argc -= optind; argv += optind; /* Read configuration file and set options */ result = read_client_conf (options.config); if (result == -1) return (-1); /* Check if passphrase isn't NULL */ if (options.passphrase == NULL) { fprintf(stdout, "%s", "Enter your passphrase:"); fflush(stdin); get_passwd (); fprintf(stdout, "%s", "\n"); } /* if (optind < argc) { fprintf( stderr, "%s%s\n", "Extra argument ", argv[optind]); exit(1); } */ /* * Check Configuration */ /* Check upload_directory */ if ((stat(options.download_directory, &st) == -1) || (S_ISDIR(st.st_mode) == 0)) { fprintf( stderr, "Missing download directory: %s\n", options.download_directory); exit(1); } /* Check config directory */ if ((stat(options.path, &st) == -1) || (S_ISDIR(st.st_mode) == 0)) { fprintf( stderr, "Option CREUVUX_PATH is missing: %s\n", options.path); exit(1); } result = crv_chdir(options.path); if (result == -1) { fprintf( stderr, "%s%s%s\n", "main(): crv_chdir(", options.path,") failed"); exit(1); } /* Check existence of tmp directory */ if ((stat( "./tmp", &st) == -1) || (S_ISDIR(st.st_mode) == 0)) { fprintf( stderr, "Directory %stmp/ is missing\n", options.tmp_directory); exit(1); } /* Check server.pem */ fd = crv_fopen("client.pem", "r"); if (fd == NULL) { fprintf( stderr, "%s\n", "Missing server.pem."); return (-1); } fclose(fd); /* Check rootcert.pem */ fd = crv_fopen("rootcert.pem", "r"); if (fd == NULL) { fprintf( stderr, "%s\n", "Missing rootcert.pem"); return (-1); } fclose(fd); /* ignore SIGPIPE */ signal (SIGPIPE, SIG_IGN); options.gui = 0; welcom(); if (options.debug == 1) { fprintf(stderr, "%s\n", "#################"); fprintf(stderr, "%s\n", "# MODE DEBUG ON #"); fprintf(stderr, "%s\n", "#################"); fprintf(stderr, "# | \n"); fprintf(stderr, "# |-> CREUVUX_PATH :'%s'\n", options.path); fprintf(stderr, "# |-> CREUVUX_SEC :'%d'\n", options.sec); fprintf(stderr, "# |-> CREUVUX_PWD :'%s'\n", options.passphrase); fprintf(stderr, "# |-> CREUVUX_DATA :'%s'\n", options.download_directory); fprintf(stderr, "# |-> LISTING_DIR :'%s'\n", options.listing_directory); fprintf(stderr, "# |-> TMP_DIR :'%s'\n", options.tmp_directory); if ( options.address_family == AF_INET) fprintf(stderr, "%s", "# |-> CREUVUX_ADDR :'IPv4'\n"); else if ( options.address_family == AF_INET6) fprintf(stderr, "%s", "# |-> CREUVUX_ADDR :'IPv6'\n"); if (options.compression == 1) fprintf(stderr, "%s", "# |-> CREUVUX_COMPRESSION :'Yes'\n"); else if (options.compression == -1) fprintf(stderr, "%s", "# |-> CREUVUX_COMPRESSION :'No'\n"); fprintf(stderr, "%s\n\n", "#################"); } /* * Deux fonctions: * -> Envoie de fichiers * -> Téléchargement de fichiers */ // Download /* fprintf(stdout, "File: %s\n", c[i]); char *sha1 = NULL; sha1 = crv_sha1(c[i]); printf("Sha1 (%s) = %s\n", c[i], sha1); upload(c[i]); //Get("/home/creuvard/file.crv"); */ server = give_server(); if (server == NULL) { fprintf(stderr, "%s\n", "You must choose server id"); return; } cat = choice_cat(); if (cat == NULL) { fprintf(stderr, "%s", "Creuvux fail to fetch categories list"); return (-1); } fprintf(stdout, "Catégorie: %s\n", cat); for (i = 0; c[i]; i++) { printf("-> %s\n", c[i]); upload(c[i], cat, server); printf("DEBUG avant fin loop\n"); } printf("DEBUG (avant fin main function\n"); // Send //upload(c[i]); Free_options(); return (0); }