Example #1
0
void start_log_and_pid(const char *client_server, const char *pidfile)
{
	int pid_fd;
#if !defined(TCSUPPORT_CT) 
#ifdef TCSUPPORT_SYSLOG_ENHANCE
	char buf[32];

	memset(buf, 0, sizeof(buf));
	sprintf(buf, "TCSysLog %s", client_server);
#endif
#endif

	/* Make sure our syslog fd isn't overwritten */
	sanitize_fds();

	/* do some other misc startup stuff while we are here to save bytes */
	pid_fd = pidfile_acquire(pidfile);
	pidfile_write_release(pid_fd);

	/* equivelent of doing a fflush after every \n */
	setlinebuf(stdout);
#if !defined(TCSUPPORT_CT) 
#if !defined(TCSUPPORT_C1_SYSLOG) 
#ifdef TCSUPPORT_SYSLOG_ENHANCE
	openlog(buf, LOG_PID | LOG_CONS, LOG_LOCAL0);
#else
	openlog(client_server, LOG_PID | LOG_CONS, LOG_LOCAL0);
#endif
#endif
#endif
	udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
}
Example #2
0
static void background(void)
{
	int pid_fd;
	if (client_config.quit_after_lease) {
		exit_client(0);
	} else if (!client_config.foreground) {
		pid_fd = pidfile_acquire(client_config.pidfile); /* hold lock during fork. */
		switch(fork()) {
		case -1:
			perror("fork");
			exit_client(1);
			/*NOTREACHED*/
		case 0:
			// brcm
			setPid();
			break; /* child continues */
		default:
			exit(0); /* parent exits */
			/*NOTREACHED*/
		}
		close(0);
		close(1);
		close(2);
		setsid();
		client_config.foreground = 1; /* Do not fork again. */
		pidfile_write_release(pid_fd);
	}
}
Example #3
0
int main(int argc,char **argv)
{
    pid_t pid;
    int fd;

    init_flash_sem();

    printf("debug:~~~~~~~~~~~ start load default para!");
    if (strcmp(nvram_bufget(RT2860_NVRAM, "WebInit"),"1")) {
        if (strcmp(nvram_bufget(RT2860_NVRAM, "WebInit"),"1")) {
            if (strcmp(nvram_bufget(RT2860_NVRAM, "WebInit"),"1")) {
                printf("debug:load 2860 para!");
                loadDefault(2860);
                printf("debug:load 2860 para end!");
            }
        }
    }

#if defined CONFIG_INIC_MII || defined CONFIG_INIC_USB || defined CONFIG_INIC_PCI
    if (strcmp(nvram_bufget(RTINIC_NVRAM, "WebInit"),"1")) {
        loadDefault(2880);
    }
#endif

#if defined (CONFIG_RT2561_AP) || defined (CONFIG_RT2561_AP_MODULE)
    if (strcmp(nvram_bufget(RT2561_NVRAM, "WebInit"),"1")) {
        loadDefault(2561);
    }
#endif
    nvram_close(RT2860_NVRAM);
    nvram_close(RTINIC_NVRAM);
#if defined (CONFIG_RT2561_AP) || defined (CONFIG_RT2561_AP_MODULE)
    nvram_close(RT2561_NVRAM);
#endif

    printf("debug:load para end!");
//close wps key it used in wpsledpbc.c
//	if (initGpio() != 0)
//		exit(EXIT_FAILURE);

    printf("debug:set /var/run/nvramd.pid!");
    fd = pidfile_acquire("/var/run/nvramd.pid");
    pidfile_write_release(fd);

    printf("debug:set end /var/run/nvramd.pid!");
    printf("debug:nvram started!");
#ifdef CONFIG_RT2880_L2_MANAGE
    //start the management daemon (blocking)
    ramad_start();
#else
    while (1) {
        pause();
    }
#endif

    exit(EXIT_SUCCESS);
}
Example #4
0
File: dhcpc.c Project: foxwolf/yjd
static void background(void)
{
	int pid_fd;

	pid_fd = pidfile_acquire(client_config.pidfile); /* hold lock during fork. */
	while (pid_fd >= 0 && pid_fd < 3) pid_fd = dup(pid_fd); /* don't let daemon close it */
	if (daemon(0, 0) == -1) {
		perror("fork");
		exit_client(1);
	}
	client_config.foreground = 1; /* Do not fork again. */
	pidfile_write_release(pid_fd);
}
Example #5
0
void start_log_and_pid(const char *client_server, const char *pidfile)
{
	int pid_fd;

	/* Make sure our syslog fd isn't overwritten */
	sanitize_fds();

	/* do some other misc startup stuff while we are here to save bytes */
	pid_fd = pidfile_acquire(pidfile);
	pidfile_write_release(pid_fd);

	/* equivelent of doing a fflush after every \n */
	setlinebuf(stdout);

	udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
}
Example #6
0
void background(const char *pidfile)
{
#ifdef __uClinux__
	LOG(LOG_ERR, "Cannot background in uclinux (yet)");
#else /* __uClinux__ */
	int pid_fd;

	/* hold lock during fork. */
	pid_fd = pidfile_acquire(pidfile);
	if (daemon(0, 0) == -1) {
		perror("fork");
		exit(1);
	}
	daemonized++;
	pidfile_write_release(pid_fd);
#endif /* __uClinux__ */
}
Example #7
0
int main(int argc,char **argv)
{
    pid_t pid;
    int fd;

    if (initGpioIRQ(FACTORY_DEFAULT_GPIO) !=0)
    	exit(EXIT_FAILURE);
    	
    fd = pidfile_acquire("/var/run/buttond.pid");
    pidfile_write_release(fd);

    while (1) {
    	pause();
    }

    exit(EXIT_SUCCESS);
}
Example #8
0
File: hcd.c Project: jhbsz/cpe-1
int main(int argc, char *argv[])
{ 	
	int pid_fd, pid, scr;
	char tmpbuf[100];
	int chan;
	/* INBAND_HOST ---> */

	if (parse_argument(argc, argv) != 0) 
		return 0;

//	printf("%s,%d, ****************\n",__FUNCTION__,__LINE__);

	// create pid file
	pid_fd = pidfile_acquire(PID_FILE);
	if (pid_fd < 0) {
		printf("Create PID file failed!\n");
		return 0;
	}
	pidfile_write_release(pid_fd);

	DISPLAY_BANNER;
	

	// register signal handler
#ifdef CMD_LINE
	signal(SIGUSR2, manual_cmd_handler);	
#endif
    signal(SIGCHLD, sigchld_handler);

	chan = inband_open(INBAND_NETIF,NULL,ETH_P_RTK,INBAND_DEBUG);
	if(chan < 0)
	{
	   	printf(" inband_open failed!\n");
	   	return -1;
	} else
	   	hcd_inband_chan = chan;	   

	
	//event_channel = inband_open(INBAND_INTF,NULL,INBAND_EVENT_TYPE,INBAND_DEBUG);
	//if( event_channel < 0 )
	//	return -1;

	while(1){	
		inband_wait_event();   
	}	
}
Example #9
0
void udhcp_start_log_and_pid(const char *client_server, const char *pidfile)
{
	int pid_fd;

	/* Make sure our syslog fd isn't overwritten */
	sanitize_fds();

	/* do some other misc startup stuff while we are here to save bytes */
	pid_fd = pidfile_acquire(pidfile);
	pidfile_write_release(pid_fd);

	/* equivelent of doing a fflush after every \n */
	setlinebuf(stdout);

	if (ENABLE_FEATURE_UDHCP_SYSLOG)
		openlog(client_server, LOG_PID | LOG_CONS, LOG_LOCAL0);

	udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, BB_VER);
}
Example #10
0
File: dhcpc.c Project: foxwolf/yjd
int main(int argc, char *argv[])
#endif
{
	unsigned char *temp, *message;
	unsigned long t1 = 0, t2 = 0, xid = 0;
	unsigned long start = 0, lease;
	fd_set rfds;
	int retval;
	struct timeval tv;
	int c, len;
	struct dhcpMessage packet;
	struct in_addr temp_addr;
	int pid_fd;
	time_t now;
	int max_fd;
	int sig;

	static struct option arg_options[] = {
		{"clientid",	required_argument,	0, 'c'},
		{"foreground",	no_argument,		0, 'f'},
		{"background",	no_argument,		0, 'b'},
		{"hostname",	required_argument,	0, 'H'},
		{"hostname",    required_argument,      0, 'h'},
		{"interface",	required_argument,	0, 'i'},
		{"now", 	no_argument,		0, 'n'},
		{"pidfile",	required_argument,	0, 'p'},
		{"quit",	no_argument,		0, 'q'},
		{"request",	required_argument,	0, 'r'},
		{"script",	required_argument,	0, 's'},
		{"version",	no_argument,		0, 'v'},
		{"help",	no_argument,		0, '?'},
		{0, 0, 0, 0}
	};

	/* get options */
	while (1) {
		int option_index = 0;
		c = getopt_long(argc, argv, "c:fbH:h:i:np:qr:s:v", arg_options, &option_index);
		if (c == -1) break;
		
		switch (c) {
		case 'c':
			len = strlen(optarg) > 255 ? 255 : strlen(optarg);
			if (client_config.clientid) free(client_config.clientid);
			client_config.clientid = xmalloc(len + 2);
			client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
			client_config.clientid[OPT_LEN] = len;
			client_config.clientid[OPT_DATA] = '\0';
			strncpy(client_config.clientid + OPT_DATA, optarg, len);
			break;
		case 'f':
			client_config.foreground = 1;
			break;
		case 'b':
			client_config.background_if_no_lease = 1;
			break;
		case 'h':
		case 'H':
			len = strlen(optarg) > 255 ? 255 : strlen(optarg);
			if (client_config.hostname) free(client_config.hostname);
			client_config.hostname = xmalloc(len + 2);
			client_config.hostname[OPT_CODE] = DHCP_HOST_NAME;
			client_config.hostname[OPT_LEN] = len;
			strncpy(client_config.hostname + 2, optarg, len);
			break;
		case 'i':
			client_config.interface =  optarg;
			break;
		case 'n':
			client_config.abort_if_no_lease = 1;
			break;
		case 'p':
			client_config.pidfile = optarg;
			break;
		case 'q':
			client_config.quit_after_lease = 1;
			break;
		case 'r':
			requested_ip = inet_addr(optarg);
			break;
		case 's':
			client_config.script = optarg;
			break;
		case 'v':
			printf("udhcpcd, version %s\n\n", VERSION);
			exit_client(0);
			break;
		default:
			show_usage();
		}
	}

	OPEN_LOG("udhcpc");
	LOG(LOG_INFO, "udhcp client (v%s) started", VERSION);

	pid_fd = pidfile_acquire(client_config.pidfile);
	pidfile_write_release(pid_fd);

	if (read_interface(client_config.interface, &client_config.ifindex, 
			   NULL, client_config.arp) < 0)
		exit_client(1);
		
	if (!client_config.clientid) {
		client_config.clientid = xmalloc(6 + 3);
		client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
		client_config.clientid[OPT_LEN] = 7;
		client_config.clientid[OPT_DATA] = 1;
		memcpy(client_config.clientid + 3, client_config.arp, 6);
	}

	/* setup signal handlers */
	socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe);
	signal(SIGUSR1, signal_handler);
	signal(SIGUSR2, signal_handler);
	signal(SIGTERM, signal_handler);
	
	state = INIT_SELECTING;
	run_script(NULL, "deconfig");
	change_mode(LISTEN_RAW);

	for (;;) {

		tv.tv_sec = timeout - time(0);
		tv.tv_usec = 0;
		FD_ZERO(&rfds);

		if (listen_mode != LISTEN_NONE && fd < 0) {
			if (listen_mode == LISTEN_KERNEL)
				fd = listen_socket(INADDR_ANY, CLIENT_PORT, client_config.interface);
			else
				fd = raw_socket(client_config.ifindex);
			if (fd < 0) {
				LOG(LOG_ERR, "FATAL: couldn't listen on socket, %s", strerror(errno));
				exit_client(0);
			}
		}
		if (fd >= 0) FD_SET(fd, &rfds);
		FD_SET(signal_pipe[0], &rfds);		

		if (tv.tv_sec > 0) {
			DEBUG(LOG_INFO, "Waiting on select...\n");
			max_fd = signal_pipe[0] > fd ? signal_pipe[0] : fd;
			retval = select(max_fd + 1, &rfds, NULL, NULL, &tv);
		} else retval = 0; /* If we already timed out, fall through */

		now = time(0);
		if (retval == 0) {
			/* timeout dropped to zero */
			switch (state) {
			case INIT_SELECTING:
				if (packet_num < 3) {
					if (packet_num == 0)
						xid = random_xid();

					/* send discover packet */
					send_discover(xid, requested_ip); /* broadcast */
					
					timeout = now + ((packet_num == 2) ? 4 : 2);
					packet_num++;
				} else {
					if (client_config.background_if_no_lease) {
						LOG(LOG_INFO, "No lease, forking to background.");
						background();
					} else if (client_config.abort_if_no_lease) {
						LOG(LOG_INFO, "No lease, failing.");
						exit_client(1);
				  	}
					/* wait to try again */
					packet_num = 0;
					timeout = now + 60;
				}
				break;
			case RENEW_REQUESTED:
			case REQUESTING:
				if (packet_num < 3) {
					/* send request packet */
					if (state == RENEW_REQUESTED)
						send_renew(xid, server_addr, requested_ip); /* unicast */
					else send_selecting(xid, server_addr, requested_ip); /* broadcast */
					
					timeout = now + ((packet_num == 2) ? 10 : 2);
					packet_num++;
				} else {
					/* timed out, go back to init state */
					if (state == RENEW_REQUESTED) run_script(NULL, "deconfig");
					state = INIT_SELECTING;
					timeout = now;
					packet_num = 0;
					change_mode(LISTEN_RAW);
				}
				break;
			case BOUND:
				/* Lease is starting to run out, time to enter renewing state */
				state = RENEWING;
				change_mode(LISTEN_KERNEL);
				DEBUG(LOG_INFO, "Entering renew state");
				/* fall right through */
			case RENEWING:
				/* Either set a new T1, or enter REBINDING state */
				if ((t2 - t1) <= (lease / 14400 + 1)) {
					/* timed out, enter rebinding state */
					state = REBINDING;
					timeout = now + (t2 - t1);
					DEBUG(LOG_INFO, "Entering rebinding state");
				} else {
					/* send a request packet */
					send_renew(xid, server_addr, requested_ip); /* unicast */
					
					t1 = (t2 - t1) / 2 + t1;
					timeout = t1 + start;
				}
				break;
			case REBINDING:
				/* Either set a new T2, or enter INIT state */
				if ((lease - t2) <= (lease / 14400 + 1)) {
					/* timed out, enter init state */
					state = INIT_SELECTING;
					LOG(LOG_INFO, "Lease lost, entering init state");
					run_script(NULL, "deconfig");
					timeout = now;
					packet_num = 0;
					change_mode(LISTEN_RAW);
				} else {
					/* send a request packet */
					send_renew(xid, 0, requested_ip); /* broadcast */

					t2 = (lease - t2) / 2 + t2;
					timeout = t2 + start;
				}
				break;
			case RELEASED:
				/* yah, I know, *you* say it would never happen */
				timeout = 0x7fffffff;
				break;
			}
		} else if (retval > 0 && listen_mode != LISTEN_NONE && FD_ISSET(fd, &rfds)) {
			/* a packet is ready, read it */
			
			if (listen_mode == LISTEN_KERNEL)
				len = get_packet(&packet, fd);
			else len = get_raw_packet(&packet, fd);
			
			if (len == -1 && errno != EINTR) {
				DEBUG(LOG_INFO, "error on read, %s, reopening socket", strerror(errno));
				change_mode(listen_mode); /* just close and reopen */
			}
			if (len < 0) continue;
			
			if (packet.xid != xid) {
				DEBUG(LOG_INFO, "Ignoring XID %lx (our xid is %lx)",
					(unsigned long) packet.xid, xid);
				continue;
			}
			
			if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
				DEBUG(LOG_ERR, "couldnt get option from packet -- ignoring");
				continue;
			}
			
			switch (state) {
			case INIT_SELECTING:
				/* Must be a DHCPOFFER to one of our xid's */
				if (*message == DHCPOFFER) {
					if ((temp = get_option(&packet, DHCP_SERVER_ID))) {
						memcpy(&server_addr, temp, 4);
						xid = packet.xid;
						requested_ip = packet.yiaddr;
						
						/* enter requesting state */
						state = REQUESTING;
						timeout = now;
						packet_num = 0;
					} else {
						DEBUG(LOG_ERR, "No server ID in message");
					}
				}
				break;
			case RENEW_REQUESTED:
			case REQUESTING:
			case RENEWING:
			case REBINDING:
				if (*message == DHCPACK) {
					if (!(temp = get_option(&packet, DHCP_LEASE_TIME))) {
						LOG(LOG_ERR, "No lease time with ACK, using 1 hour lease");
						lease = 60 * 60;
					} else {
						memcpy(&lease, temp, 4);
						lease = ntohl(lease);
					}
						
					/* enter bound state */
					t1 = lease / 2;
					
					/* little fixed point for n * .875 */
					t2 = (lease * 0x7) >> 3;
					temp_addr.s_addr = packet.yiaddr;
					LOG(LOG_INFO, "Lease of %s obtained, lease time %ld", 
						inet_ntoa(temp_addr), lease);
					start = now;
					timeout = t1 + start;
					requested_ip = packet.yiaddr;
					run_script(&packet,
						   ((state == RENEWING || state == REBINDING) ? "renew" : "bound"));

					state = BOUND;
					change_mode(LISTEN_NONE);
					if (client_config.quit_after_lease) 
						exit_client(0);
					if (!client_config.foreground)
						background();

				} else if (*message == DHCPNAK) {
					/* return to init state */
					LOG(LOG_INFO, "Received DHCP NAK");
					run_script(&packet, "nak");
					if (state != REQUESTING)
						run_script(NULL, "deconfig");
					state = INIT_SELECTING;
					timeout = now;
					requested_ip = 0;
					packet_num = 0;
					change_mode(LISTEN_RAW);
					sleep(3); /* avoid excessive network traffic */
				}
				break;
			/* case BOUND, RELEASED: - ignore all packets */
			}	
		} else if (retval > 0 && FD_ISSET(signal_pipe[0], &rfds)) {
Example #11
0
int main(int argc, char *argv[])
{
	int i;
	char *iapp_fifo = "/var/iapp.fifo";
	char fifo_buf[30];
	int poll = 0; //david

	// destroy old process
	{
		FILE *fp;
		char line[20];
		pid_t pid;

		if((fp = fopen(pidfile, "r")) != NULL)
		{
			fgets(line, sizeof(line), fp);
			if(sscanf(line, "%d", &pid))
			{
				if(pid > 1)
					kill(pid, SIGTERM);
			}
			fclose(fp);
		}
	}

	setsid(); // david, requested from abocom

	// depend on arguments to decide link fifo
	for(i=1; i<argc; i++)
	{
		if(!strncmp("wlan", argv[i], strlen("wlan"))){
			if(wlan_num >= MAX_WLAN_INTF){
				printf("Only  %d Wlan interace is supported\n", MAX_WLAN_INTF);
				return -1;
			}
			strcpy(wlan_tbl[wlan_num], argv[i]);
			wlan_num++ ;
		}
// david ------------------------------------------------------
		else if(!strncmp("poll", argv[i], strlen("poll"))){
			poll = 1;
		}
//-------------------------------------------------------------
		else
		{
			printf("Usage: %s [wlan0] [wlan1] ... \n", argv[0]);
			return -1;
		}
	}

	if(wlan_num == 0){
		printf("At least one wlan interface should be binded\n");
		return -1 ;
	}

	/* parsing /var/iapp.pid or /var/auth*.pid , /var/autoconf*.conf */
	if(parsing_var_pid(RTLDListenerAuth, RTLDListenerAutoconf, RTLDListenerWscd) < 0){
		printf("parsing pid failed\n");
		return -1;
	}
	// david ------------------------------------------
	// delete old fifo and create filo
	{
		int pid_fd;

		pid_fd = pidfile_acquire(pidfile);
		if(daemon(0,1) == -1)
		{
			printf("fork iwcontrol error!\n");
			exit(1);
		}
		pidfile_write_release(pid_fd);
	}
	//---------------------------------------------------
	// init send buffer pid header
	iw_init_sendBuf(dlisten_SendBuf);

	// init fifo and socket
	if(link_auth){
		for(i=0 ; i < link_auth; i++){
			sprintf(fifo_buf, DAEMON_FIFO, RTLDListenerAuth[i].wlanName);
			iw_message(MESS_DBG_CONTROL,"open auth fifo %s\n", fifo_buf);
			iw_init_fifo(&RTLDListenerAuth[i], fifo_buf);
		}
	}
	if(link_iapp){
		iw_message(MESS_DBG_CONTROL,"open iapp fifo %s\n", iapp_fifo);
		iw_init_fifo(&RTLDListenerIapp, iapp_fifo);
	}

#ifdef AUTO_CONFIG
	if(link_autoconf){
		for(i=0 ; i < link_autoconf; i++){
			sprintf(fifo_buf, AUTOCONFIG_FIFO, RTLDListenerAutoconf[i].wlanName);
			iw_message(MESS_DBG_CONTROL,"open autoconfig fifo %s\n", fifo_buf);
			iw_init_fifo(&RTLDListenerAutoconf[i], fifo_buf);
		}
	}
#endif

#ifdef WIFI_SIMPLE_CONFIG
	if(link_wscd){
		for(i=0 ; i < link_wscd; i++){
			sprintf(fifo_buf, WSCD_FIFO, RTLDListenerWscd[i].wlanName);
			iw_message(MESS_DBG_CONTROL,"open wscd fifo %s\n", fifo_buf);
			iw_init_fifo(&RTLDListenerWscd[i], fifo_buf);
		}
	}
#endif

	RTLDListenerAuth[0].Iffd = get_info();
	if(RTLDListenerAuth[0].Iffd <= 0)
	{
		perror("Socket fd return 0");
		exit(0);
	}

	// infinite loop
#ifdef WLAN_CHR_MISC
	if (!poll)	// david
	{
		int fdflags, idx=0, wlan0_up=0, wlan1_up=0;
		char dev_name[20];
		for(i=0; i<wlan_num; i++)
		{
			if (strncmp("wlan0", wlan_tbl[i], 5) == 0) {
				if (wlan0_up)
					continue;
				else
					wlan0_up = 1;
				idx = 0;
			}

			if (strncmp("wlan1", wlan_tbl[i], 5) == 0) {
				if (wlan1_up)
					continue;
				else
					wlan1_up = 1;
				idx = 1;
			}
#if 0
			sprintf(dev_name, "/dev/wlchr");
#else
			sprintf(dev_name, "/dev/wl_chr%d", idx);
#endif

			if((wl_chr_fd = open(dev_name, O_RDWR, 0)) < 0)
			{
				printf("Warning: unable to open an wl_chr device.\n");
				exit(1);
			}

			signal(SIGIO, RequestEvent);

			fcntl(wl_chr_fd, F_SETOWN, getpid());
			fdflags = fcntl(wl_chr_fd, F_GETFL);
			fcntl(wl_chr_fd, F_SETFL, fdflags | FASYNC);
		}

		while(1)
			pause();
	}
#endif
	while( 1 )
	{
		RequestEvent(SIGIO);
		sleep(INTERVAL);
	}

	return 0;
}
Example #12
0
int main(int argc, char *argv[])
#endif
{
	char *temp, *message;
	unsigned long t1 = 0, t2 = 0, xid = 0;
	unsigned long start = 0, lease;
	fd_set rfds;
	int fd, retval;
	struct timeval tv;
	int c, len;
	struct ifreq ifr;
	struct dhcpMessage packet;
	struct in_addr temp_addr;
	int pid_fd;

	static struct option options[] = {
		{"clientid",	required_argument,	0, 'c'},
		{"foreground",	no_argument,		0, 'f'},
		{"hostname",	required_argument,	0, 'H'},
		{"help",	no_argument,		0, 'h'},
		{"interface",	required_argument,	0, 'i'},
		{"now", 	no_argument,		0, 'n'},
		{"pidfile",	required_argument,	0, 'p'},
		{"quit",	no_argument,		0, 'q'},
		{"request",	required_argument,	0, 'r'},
		{"script",	required_argument,	0, 's'},
		{"version",	no_argument,		0, 'v'},
		{0, 0, 0, 0}
	};

	/* get options */
	while (1) {
		int option_index = 0;
// brcm
		c = getopt_long(argc, argv, "c:fH:hi:np:qr:s:d:v", options, &option_index);
		if (c == -1) break;
		
		switch (c) {
		case 'c':
			len = strlen(optarg) > 255 ? 255 : strlen(optarg);
			if (client_config.clientid) free(client_config.clientid);
			client_config.clientid = malloc(len + 2);
			client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
			client_config.clientid[OPT_LEN] = len;
			strncpy(client_config.clientid + 2, optarg, len);
			break;
		case 'f':
			client_config.foreground = 1;
			break;
		case 'H':
			len = strlen(optarg) > 255 ? 255 : strlen(optarg);
			if (client_config.hostname) free(client_config.hostname);
			client_config.hostname = malloc(len + 2);
			client_config.hostname[OPT_CODE] = DHCP_HOST_NAME;
			client_config.hostname[OPT_LEN] = len;
			strncpy(client_config.hostname + 2, optarg, len);
			break;
		case 'h':
			print_usage();
			return 0;
		case 'i':
			client_config.interface =  optarg;
// brcm
			strcpy(session_path, optarg);
			break;
		case 'n':
			client_config.abort_if_no_lease = 1;
			break;
		case 'p':
			client_config.pidfile = optarg;
			break;
		case 'q':
			client_config.quit_after_lease = 1;
			break;
		case 'r':
			requested_ip = inet_addr(optarg);
			break;
// brcm
		case 'd':
			strcpy(vendor_class_id, optarg);
			break;
		case 's':
			client_config.script = optarg;
			break;
		case 'v':
			printf("udhcpcd, version %s\n\n", VERSION);
			break;
		}
	}

	// brcm
        if (strlen(session_path) > 0) {
	    sprintf(status_path, "%s/%s/%s", _PATH_WAN_DIR, session_path, _PATH_MSG);
	    sprintf(pid_path, "%s/%s/%s", _PATH_WAN_DIR, session_path, _PATH_PID);
	}

	OPEN_LOG("udhcpc");
	LOG(LOG_INFO, "udhcp client (v%s) started", VERSION);

	pid_fd = pidfile_acquire(client_config.pidfile);
	pidfile_write_release(pid_fd);

	if ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0) {
		strcpy(ifr.ifr_name, client_config.interface);
		if (ioctl(fd, SIOCGIFINDEX, &ifr) == 0) {
			DEBUG(LOG_INFO, "adapter index %d", ifr.ifr_ifindex);
			client_config.ifindex = ifr.ifr_ifindex;
		} else {
			LOG(LOG_ERR, "SIOCGIFINDEX failed! %s", strerror(errno));
			exit_client(1);
		}
		if (ioctl(fd, SIOCGIFHWADDR, &ifr) == 0) {
			memcpy(client_config.arp, ifr.ifr_hwaddr.sa_data, 6);
			DEBUG(LOG_INFO, "adapter hardware address %02x:%02x:%02x:%02x:%02x:%02x",
				client_config.arp[0], client_config.arp[1], client_config.arp[2], 
				client_config.arp[3], client_config.arp[4], client_config.arp[5]);
		} else {
			LOG(LOG_ERR, "SIOCGIFHWADDR failed! %s", strerror(errno));
			exit_client(1);
		}
	} else {
		LOG(LOG_ERR, "socket failed! %s", strerror(errno));
		exit_client(1);
	}
	close(fd);
	fd = -1;

	/* setup signal handlers */
	signal(SIGUSR1, renew_requested);
	signal(SIGUSR2, release_requested);
	signal(SIGTERM, terminate);
	
	state = INIT_SELECTING;
	// brcm
	// run_script(NULL, "deconfig");

	// brcm
	setStatus(0);

	for (;;) {

		// brcm
		if ((old_mode != listen_mode) || (fd == -1)) {
		    old_mode = listen_mode;
		
		    if (fd > 0) {
			    close(fd);
			    fd = -1;
		    }
		
		    if (listen_mode == LISTEN_RAW) {
			    if ((fd = raw_socket(client_config.ifindex)) < 0) {
				    LOG(LOG_ERR, "couldn't create raw socket -- au revoir");
				    exit_client(0);
			    }
		    }
		    else if (listen_mode == LISTEN_KERNEL) {
			    if ((fd = listen_socket(INADDR_ANY, CLIENT_PORT, client_config.interface)) < 0) {
				    LOG(LOG_ERR, "couldn't create server socket -- au revoir");
				    exit_client(0);
			    }			
		    } else 
			fd = -1;
		}

		tv.tv_sec = timeout - time(0);
		tv.tv_usec = 0;
		FD_ZERO(&rfds);
		if (listen_mode) FD_SET(fd, &rfds);
		
		if (tv.tv_sec > 0) {
			retval = select(fd + 1, &rfds, NULL, NULL, &tv);
		} else retval = 0; /* If we already timed out, fall through */
		
		if (retval == 0) {
			/* timeout dropped to zero */
			switch (state) {
			case INIT_SELECTING:
				// brcm
				setStatus(0);
				if (packet_num < 3) {
					if (packet_num == 0)
						xid = random_xid();

					/* send discover packet */
					send_discover(xid, requested_ip); /* broadcast */
					
					timeout = time(0) + ((packet_num == 2) ? 10 : 2);
					packet_num++;
				} else {
					if (client_config.abort_if_no_lease) {
						LOG(LOG_INFO,
						    "No lease, failing.");
						exit_client(1);
				  	}
					/* wait to try again */
					packet_num = 0;
					timeout = time(0) + 60;
				}
				break;
			case RENEW_REQUESTED:
			case REQUESTING:
				if (packet_num < 3) {
					/* send request packet */
					if (state == RENEW_REQUESTED)
						send_renew(xid, server_addr, requested_ip); /* unicast */
					else send_selecting(xid, server_addr, requested_ip); /* broadcast */
					
					timeout = time(0) + ((packet_num == 2) ? 10 : 2);
					packet_num++;
				} else {
					/* timed out, go back to init state */
					state = INIT_SELECTING;
					timeout = time(0);
					packet_num = 0;
					listen_mode = LISTEN_RAW;
					
				}
				break;
			case BOUND:
				/* Lease is starting to run out, time to enter renewing state */
				state = RENEWING;
				listen_mode = LISTEN_KERNEL;
				DEBUG(LOG_INFO, "Entering renew state");
				/* fall right through */
			case RENEWING:
				/* Either set a new T1, or enter REBINDING state */
				if ((t2 - t1) <= (lease / 14400 + 1)) {
					/* timed out, enter rebinding state */
					state = REBINDING;
					timeout = time(0) + (t2 - t1);
					DEBUG(LOG_INFO, "Entering rebinding state");
				} else {
					/* send a request packet */
					send_renew(xid, server_addr, requested_ip); /* unicast */
					
					t1 = (t2 - t1) / 2 + t1;
					timeout = t1 + start;
				}
				break;
			case REBINDING:
				/* Either set a new T2, or enter INIT state */
				if ((lease - t2) <= (lease / 14400 + 1)) {
					/* timed out, enter init state */
					state = INIT_SELECTING;
					LOG(LOG_INFO, "Lease lost, entering init state");
					run_script(NULL, "deconfig");
					timeout = time(0);
					packet_num = 0;
					listen_mode = LISTEN_RAW;
				} else {
					/* send a request packet */
					send_renew(xid, 0, requested_ip); /* broadcast */

					t2 = (lease - t2) / 2 + t2;
					timeout = t2 + start;
				}
				break;
			case RELEASED:
				/* yah, I know, *you* say it would never happen */
				timeout = 0xffffffff;
				break;
			}
		} else if (retval > 0 && listen_mode != LISTEN_NONE && FD_ISSET(fd, &rfds)) {
			/* a packet is ready, read it */
			
			if (listen_mode == LISTEN_KERNEL) {
				if (get_packet(&packet, fd) < 0) continue;
			} else {
				if (get_raw_packet(&packet, fd) < 0) continue;
			} 
			
			if (packet.xid != xid) {
				DEBUG(LOG_INFO, "Ignoring XID %lx (our xid is %lx)",
					(unsigned long) packet.xid, xid);
				continue;
			}
			
			if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
				DEBUG(LOG_ERR, "couldnt get option from packet -- ignoring");
				continue;
			}
			
			switch (state) {
			case INIT_SELECTING:
				/* Must be a DHCPOFFER to one of our xid's */
				if (*message == DHCPOFFER) {
					if ((temp = get_option(&packet, DHCP_SERVER_ID))) {
						memcpy(&server_addr, temp, 4);
						xid = packet.xid;
						requested_ip = packet.yiaddr;
						
						/* enter requesting state */
						state = REQUESTING;
						timeout = time(0);
						packet_num = 0;
					} else {
						DEBUG(LOG_ERR, "No server ID in message");
					}
				}
				break;
			case RENEW_REQUESTED:
			case REQUESTING:
			case RENEWING:
			case REBINDING:
				if (*message == DHCPACK) {
					if (!(temp = get_option(&packet, DHCP_LEASE_TIME))) {
						LOG(LOG_ERR, "No lease time with ACK, using 1 hour lease");
						lease = 60*60;
					} else {
						memcpy(&lease, temp, 4);
						lease = ntohl(lease);
					}
						
					/* enter bound state */
					t1 = lease / 2;
					
					/* little fixed point for n * .875 */
					t2 = (lease * 0x7) >> 3;
					temp_addr.s_addr = packet.yiaddr;
					LOG(LOG_INFO, "Lease of %s obtained, lease time %ld", 
						inet_ntoa(temp_addr), lease);
					start = time(0);
					timeout = t1 + start;
					requested_ip = packet.yiaddr;
					run_script(&packet,
						   ((state == RENEWING || state == REBINDING) ? "renew" : "bound"));

					state = BOUND;
					listen_mode = LISTEN_NONE;
					
					// brcm
					setStatus(1);
					background();
					
				} else if (*message == DHCPNAK) {
					/* return to init state */
					LOG(LOG_INFO, "Received DHCP NAK");
					if (state != REQUESTING)
						run_script(NULL, "deconfig");
					state = INIT_SELECTING;
					timeout = time(0);
					requested_ip = 0;
					packet_num = 0;
					listen_mode = LISTEN_RAW;

					// brcm
					setStatus(0);
				}
				break;
			case BOUND:
			case RELEASED:
				/* ignore all packets */
				break;
			}					
		} else if (retval == -1 && errno == EINTR) {
Example #13
0
int main(int argc, char *argv[])
{ 	
	int pid_fd, pid, scr;
	char tmpbuf[100];
	int chan;
	/* INBAND_HOST ---> */
	struct iwreq wrq;
	/* INBAND_HOST <--- */

	if (parse_argument(argc, argv) != 0) 
		return 0;

	// become daemon
	if (daemon(0,1) == -1) {
		printf("fork daemon error!\n");
		return 0;
	}

	// create pid file
	pid_fd = pidfile_acquire(PID_FILE);
	if (pid_fd < 0) {
		printf("Create PID file failed!\n");
		return 0;
	}
	pidfile_write_release(pid_fd);

	DISPLAY_BANNER;
	
	// initialize mib
	init_config_mib();

	// register signal handler
#ifdef CMD_LINE
	signal(SIGUSR2, manual_cmd_handler);	
#endif
     signal(SIGCHLD, sigchld_handler);

        // open mdio driver
#ifdef RTK_NFBI_AP_HCM
        mdio_fd = open(DEV_NAME, O_RDWR);
        if (!mdio_fd) {
                printf("open driver failed!\n");
                return 1;
        }
#endif
	  init_bridge();
	  bring_up_lan();
	  bring_up_br();
      sleep(1);
	   chan = inband_open(INBAND_NETIF,NULL,ETH_P_RTK,INBAND_DEBUG);
	   if(chan < 0)
	   {
	   	printf(" inband_open failed!\n");
	   	return -1;
	    }
	   else
	   	hcd_inband_chan = chan;	   

	// Set daemon pid to driver. 
	// When this ioctl is set, driver will set AllSoftwareReady bit to 'CPU System Status' Register
	pid =  getpid();
#ifdef RTK_NFBI_AP_HCM
	if (do_mdio_ioctl(id_set_host_pid, (void *)&pid)) //mark_issue , if it is need then mdio_open must be done 
		return 1;
#endif
	ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
	if (ioctl_sock < 0) {
		perror("socket[PF_INET,SOCK_DGRAM]");
		return -1;
	}

	/* INBAND_HOST ---> */
  	/* Get wireless name */
	memset(wrq.ifr_ifrn.ifrn_name, 0, sizeof wrq.ifr_ifrn.ifrn_name);
  	strncpy(wrq.ifr_ifrn.ifrn_name, "wlan0", IFNAMSIZ);

	pid = getpid();
	wrq.u.data.pointer = (caddr_t)&pid;
	wrq.u.data.length = sizeof(pid_t);

  	if(ioctl(ioctl_sock, SIOCSAPPPID, &wrq) < 0)
	{
    	// If no wireless name : no wireless extensions
		return(-1);
	}
	event_channel = inband_open(INBAND_INTF,INBAND_HOST,INBAND_EVENT_TYPE,INBAND_DEBUG);
	if( event_channel < 0 )
		return -1;
	signal(SIGIO, notify_host);
	/* INBAND_HOST <--- */

	//init_system(INIT_ALL); //mark_debug
	while(1){		
	inband_wait_event();   
	}	
}
Example #14
0
int main(int argc, char *argv[])
#endif
{	
	fd_set rfds;
	struct timeval tv;
	int server_socket = -1;
	int bytes, retval;
	struct dhcpMessage packet;
	unsigned char *state;
	unsigned char *server_id, *requested, *hostname;
	u_int32_t server_id_align, requested_align;
	unsigned long timeout_end;
	struct option_set *option;
	struct dhcpOfferedAddr *lease;
	int pid_fd;
	int max_sock;
	int sig;

	/* DD-WRT (belanger) : ignore signals until we're ready */
	signal(SIGUSR1, SIG_IGN);
	signal(SIGUSR2, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	signal(SIGTERM, SIG_IGN);

	OPEN_LOG("udhcpd");
	LOG(LOG_INFO, "udhcp server (v%s) started", VERSION);

	memset(&server_config, 0, sizeof(struct server_config_t));

	if (argc < 2)
		read_config(DHCPD_CONF_FILE);
	else 
		read_config(argv[1]);

	pid_fd = pidfile_acquire(server_config.pidfile);
	pidfile_write_release(pid_fd);

	if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
		memcpy(&server_config.lease, option->data + 2, 4);
		server_config.lease = ntohl(server_config.lease);
	}
	else server_config.lease = LEASE_TIME;

	leases = malloc(sizeof(struct dhcpOfferedAddr) * server_config.max_leases);
	memset(leases, 0, sizeof(struct dhcpOfferedAddr) * server_config.max_leases);
	read_leases(server_config.lease_file);
	read_statics(server_config.statics_file);

	/* DD-WRT (belanger) : write leases now */
	write_leases();

	if (read_interface(server_config.interface, &server_config.ifindex,
			   &server_config.server, server_config.arp) < 0)
		exit_server(1);

#ifndef DEBUGGING
	pid_fd = pidfile_acquire(server_config.pidfile); /* hold lock during fork. */
	if (daemon(0, 0) == -1) {
		perror("fork");
		exit_server(1);
	}
	pidfile_write_release(pid_fd);
#endif


	socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe);
	signal(SIGUSR1, signal_handler);
	signal(SIGUSR2, signal_handler);
	signal(SIGTERM, signal_handler);
	signal(SIGHUP, signal_handler);

	timeout_end = get_time(0) + server_config.auto_time;
	while(1) { /* loop until universe collapses */

		if (server_socket < 0)
			if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
				LOG(LOG_ERR, "FATAL: couldn't create server socket, %s", strerror(errno));
				exit_server(0);
			}			

		FD_ZERO(&rfds);
		FD_SET(server_socket, &rfds);
		FD_SET(signal_pipe[0], &rfds);
		if (server_config.auto_time) {
			tv.tv_sec = timeout_end - get_time(0);
			tv.tv_usec = 0;
		}
		if (!server_config.auto_time || tv.tv_sec > 0) {
			max_sock = server_socket > signal_pipe[0] ? server_socket : signal_pipe[0];
			retval = select(max_sock + 1, &rfds, NULL, NULL, 
					server_config.auto_time ? &tv : NULL);
		} 
		else 
			retval = 0; /* If we already timed out, fall through */

		if (retval == 0) {
			write_leases();
			timeout_end = get_time(0) + server_config.auto_time;
			continue;
		} 
		else if (retval < 0 && errno != EINTR) {
			DEBUG(LOG_INFO, "error on select");
			continue;
		}
		
		if (FD_ISSET(signal_pipe[0], &rfds)) {
			if (read(signal_pipe[0], &sig, sizeof(sig)) < 0)
				continue; /* probably just EINTR */
			switch (sig) {
			case SIGUSR1:
				LOG(LOG_INFO, "Received a SIGUSR1");
				write_leases();
				/* why not just reset the timeout, eh */
				timeout_end = get_time(0) + server_config.auto_time;
				continue;
			case SIGUSR2:
				LOG(LOG_INFO, "Received a SIGUSR2");
				delete_leases();
				continue;
			case SIGHUP:
				LOG(LOG_INFO, "Received a SIGHUP");
				read_leases(server_config.lease_file);
				read_statics(server_config.statics_file);
				continue;
			case SIGTERM:
				LOG(LOG_INFO, "Received a SIGTERM");
				exit_server(0);
			}
		}

		if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
			if (bytes == -1 && errno != EINTR) {
				DEBUG(LOG_INFO, "error on read, %s, reopening socket", strerror(errno));
				close(server_socket);
				server_socket = -1;
			}
			continue;
		}

		if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
			DEBUG(LOG_ERR, "couldn't get option from packet, ignoring");
			continue;
		}

		hostname = get_option(&packet, DHCP_HOST_NAME);

		/* ADDME: look for a static lease */
		    
		/* If a hostname is supplied, and that hostname is a static lease, and that
		   static lease has an FF:FF:FF:FF:FF:FF MAC address, then use that entry. */
		if ( NULL == hostname ||
		     NULL == (lease = find_lease_by_hostname(hostname)) || 
		     (lease->expires != EXPIRES_NEVER) ||
		     0 != memcmp(lease->chaddr, MAC_BCAST_ADDR, strlen(MAC_BCAST_ADDR))) {
		  
		  /* Otherwise, look up the table using the supplied MAC address. */
		  lease = find_lease_by_chaddr(packet.chaddr);

		}

		switch (state[0]) {
		case DHCPDISCOVER:
			LOG(LOG_INFO,"received DISCOVER from %02x:%02x:%02x:%02x:%02x:%02x",
			    packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			    packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);	// modify by honor
			
			if (sendOffer(&packet, lease) < 0) {
				LOG(LOG_ERR, "send OFFER failed");
			}
			break;			
 		case DHCPREQUEST:
			requested = get_option(&packet, DHCP_REQUESTED_IP);
			server_id = get_option(&packet, DHCP_SERVER_ID);

			if (requested) memcpy(&requested_align, requested, 4);
			if (server_id) memcpy(&server_id_align, server_id, 4);
		
			if (requested) {
			  struct in_addr addr;
			  addr.s_addr = requested_align;
			  LOG(LOG_INFO, "received REQUEST for %s from %02x:%02x:%02x:%02x:%02x:%02x",
			      inet_ntoa(addr),
			      packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			      packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);
			}
			else {
			  LOG(LOG_INFO, "received REQUEST from %02x:%02x:%02x:%02x:%02x:%02x",
			      packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			      packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);
			}

			if (lease) { /*ADDME: or static lease */
				if (server_id) {
					/* SELECTING State */
					DEBUG(LOG_INFO, "server_id = %08x", ntohl(server_id_align));
					if (server_id_align == server_config.server && requested && 
					    requested_align == lease->yiaddr) {
						sendACK(&packet, lease->yiaddr);
					}
					else
						sendNAK(&packet); //Sveasoft - shouldn't we let them know we don't like the request?
				} 
				else {
					if (requested) {
						/* INIT-REBOOT State */
						if (lease->yiaddr == requested_align)
							sendACK(&packet, lease->yiaddr);
						else 
							sendNAK(&packet);
					} else {
						/* RENEWING or REBINDING State */
						if (lease->yiaddr == packet.ciaddr)
							sendACK(&packet, lease->yiaddr);
//						else if (!packet.ciaddr)
							/* Accept an invalid request in RENEWING state,
							   where the ciaddr should be set, but is not. */
							/* e.g. Linksys Print Server */
//							sendACK(&packet, lease->yiaddr); //note: let's not support broken stuff - Sveasoft 2005-01-19
						else {
							/* don't know what to do!!!! */
							sendNAK(&packet);
						}
					}						
				}
				if (lease->expires != EXPIRES_NEVER) {
					/* Don't change hostname of static leases */
					if (hostname) {
						bytes = hostname[-1];
						if (bytes >= (int) sizeof(lease->hostname))
							bytes = sizeof(lease->hostname) - 1;
						strncpy(lease->hostname, hostname, bytes);
							lease->hostname[bytes] = '\0';
					} else
						lease->hostname[0] = '\0';
				}
			
			/* what to do if we have no record of the client */
			} 
			else if (server_id) {
				/* SELECTING State */
				sendNAK(&packet);       // by honor

			} 
			else if (requested) {
				/* INIT-REBOOT State */
				if ((lease = find_lease_by_yiaddr(requested_align))) {
					if (lease_expired(lease)) {
						/* probably best if we drop this lease */
						memset(lease->chaddr, 0, 16);
					/* make some contention for this address */
					} 
					else 
						sendNAK(&packet);
				} 
				else if (requested_align < server_config.start || 
					 requested_align > server_config.end) {
					sendNAK(&packet);
				} 
				else {
					sendNAK(&packet);
				}

			} 
			else if (packet.ciaddr) {

				/* RENEWING or REBINDING State */
				sendNAK(&packet);
			}
			break;
		case DHCPDECLINE:
			LOG(LOG_INFO,"received DECLINE from %02x:%02x:%02x:%02x:%02x:%02x",
			    packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			    packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);	// modify by honor
			if (lease && lease->expires != EXPIRES_NEVER) {
				memset(lease->chaddr, 0, 16);
				lease->expires = get_time(0) + server_config.decline_time;
			}			
			break;
		case DHCPRELEASE:
			LOG(LOG_INFO,"received RELEASE from %02x:%02x:%02x:%02x:%02x:%02x",
			    packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			    packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);	// modify by honor
			if (lease && lease->expires != EXPIRES_NEVER) 
				lease->expires = get_time(0);
			break;
		case DHCPINFORM:
			LOG(LOG_INFO,"received INFORM from %02x:%02x:%02x:%02x:%02x:%02x",
			    packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			    packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);	// modify by honor
			send_inform(&packet);
			break;	
		default:
			LOG(LOG_WARNING, "unsupported DHCP message (%02x) -- ignoring", state[0]);
		}
	}

	return 0;
}
Example #15
0
int main(int argc, char *argv[])
#endif
{	
	fd_set rfds;
	struct timeval tv;
	int server_socket = -1;
	int bytes, retval;
	struct dhcpMessage packet;
	unsigned char *state;
	unsigned char *server_id, *requested, *hostname;
	u_int32_t server_id_align, requested_align;
	unsigned long timeout_end;
	struct option_set *option;
	struct dhcpOfferedAddr *lease;
	int pid_fd;
	int max_sock;
	int sig;
	
	OPEN_LOG("udhcpd");
	LOG(LOG_INFO, "udhcp server (v%s) started", VERSION);

	memset(&server_config, 0, sizeof(struct server_config_t));
	
	if (argc < 2)
		read_config(DHCPD_CONF_FILE);
	else read_config(argv[1]);

	pid_fd = pidfile_acquire(server_config.pidfile);
	pidfile_write_release(pid_fd);

	if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
		memcpy(&server_config.lease, option->data + 2, 4);
		server_config.lease = ntohl(server_config.lease);
	}
	else server_config.lease = LEASE_TIME;
	
	leases = malloc(sizeof(struct dhcpOfferedAddr) * server_config.max_leases);
	memset(leases, 0, sizeof(struct dhcpOfferedAddr) * server_config.max_leases);

	// Added by Joey to load static lease
	if (argc>=3)
	{
		load_leases(argv[2]);
	}

	read_leases(server_config.lease_file);

	if (read_interface(server_config.interface, &server_config.ifindex,
			   &server_config.server, server_config.arp) < 0)
		exit_server(1);

#ifndef DEBUGGING
	pid_fd = pidfile_acquire(server_config.pidfile); /* hold lock during fork. */
	if (daemon(0, 0) == -1) {
		perror("fork");
		exit_server(1);
	}
	pidfile_write_release(pid_fd);
#endif

	/* ensure that stdin/stdout/stderr are never returned by pipe() */
	if (fcntl(STDIN_FILENO, F_GETFL) == -1)
		(void) open("/dev/null", O_RDONLY);
	if (fcntl(STDOUT_FILENO, F_GETFL) == -1)
		(void) open("/dev/null", O_WRONLY);
	if (fcntl(STDERR_FILENO, F_GETFL) == -1)
		(void) open("/dev/null", O_WRONLY);

	/* setup signal handlers */
	pipe(signal_pipe);
	signal(SIGUSR1, signal_handler);
	signal(SIGTERM, signal_handler);

	timeout_end = uptime() + server_config.auto_time;
	while(1) { /* loop until universe collapses */

		if (server_socket < 0)
			if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
				LOG(LOG_ERR, "FATAL: couldn't create server socket, %s", strerror(errno));
				exit_server(0);
			}			

		FD_ZERO(&rfds);
		FD_SET(server_socket, &rfds);
		FD_SET(signal_pipe[0], &rfds);
		if (server_config.auto_time) {
			tv.tv_sec = timeout_end - uptime();
			tv.tv_usec = 0;
		}
		if (!server_config.auto_time || tv.tv_sec > 0) {
			max_sock = server_socket > signal_pipe[0] ? server_socket : signal_pipe[0];
			retval = select(max_sock + 1, &rfds, NULL, NULL, 
					server_config.auto_time ? &tv : NULL);
		} else retval = 0; /* If we already timed out, fall through */

		if (retval == 0) {
			write_leases();
			timeout_end = uptime() + server_config.auto_time;
			continue;
		} else if (retval < 0 && errno != EINTR) {
			DEBUG(LOG_INFO, "error on select");
			continue;
		}
		
		if (FD_ISSET(signal_pipe[0], &rfds)) {
			if (read(signal_pipe[0], &sig, sizeof(sig)) < 0)
				continue; /* probably just EINTR */
			switch (sig) {
			case SIGUSR1:
				LOG(LOG_INFO, "Received a SIGUSR1");
				write_leases();
				/* why not just reset the timeout, eh */
				timeout_end = uptime() + server_config.auto_time;
				continue;
			case SIGTERM:
				LOG(LOG_INFO, "Received a SIGTERM");
				exit_server(0);
			}
		}

		if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
			if (bytes == -1 && errno != EINTR) {
				DEBUG(LOG_INFO, "error on read, %s, reopening socket", strerror(errno));
				close(server_socket);
				server_socket = -1;
			}
			continue;
		}

		if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
			DEBUG(LOG_ERR, "couldn't get option from packet, ignoring");
			continue;
		}
		
		server_id = get_option(&packet, DHCP_SERVER_ID);
		if (server_id) {
			memcpy(&server_id_align, server_id, 4);
			if (server_id_align != server_config.server) {
				/* client talks to somebody else */
				DEBUG(LOG_INFO,"server ID %08x doesn't match, ignoring", ntohl(server_id_align));
				continue;
			}
		}

		/* ADDME: look for a static lease */
		lease = find_lease_by_chaddr(packet.chaddr);
		switch (state[0]) {
		case DHCPDISCOVER:
			DEBUG(LOG_INFO,"received DISCOVER");
			
			if (sendOffer(&packet) < 0) {
				LOG(LOG_ERR, "send OFFER failed");
			}
			break;			
 		case DHCPREQUEST:
			DEBUG(LOG_INFO, "received REQUEST");

			requested = get_option(&packet, DHCP_REQUESTED_IP);
			hostname = get_option(&packet, DHCP_HOST_NAME);

			if (requested) memcpy(&requested_align, requested, 4);
		
			if (lease) { /*ADDME: or static lease */
				if (server_id) {
					/* SELECTING State */
					if (requested && 
					    requested_align == lease->yiaddr) {
						sendACK(&packet, lease->yiaddr);
					}
				} else {
					if (requested) {
						/* INIT-REBOOT State */
						if (lease->yiaddr == requested_align)
							sendACK(&packet, lease->yiaddr);
						else sendNAK(&packet);
					} else {
						/* RENEWING or REBINDING State */
						if (lease->yiaddr == packet.ciaddr)
							sendACK(&packet, lease->yiaddr);
						else {
							/* don't know what to do!!!! */
							sendNAK(&packet);
						}
					}						
				}
				if (hostname) {
					bytes = hostname[-1];
					if (bytes >= (int) sizeof(lease->hostname))
						bytes = sizeof(lease->hostname) - 1;
					strncpy(lease->hostname, hostname, bytes);
					lease->hostname[bytes] = '\0';

					if (!is_valid_hostname(lease->hostname))
						lease->hostname[0] = '\0';

				} else
					lease->hostname[0] = '\0';
			
			/* what to do if we have no record of the client */
			} else if (server_id) {
				/* SELECTING State */
				if (requested)
					sendNAK(&packet);

			} else if (requested) {
				/* INIT-REBOOT State */
				if ((lease = find_lease_by_yiaddr(requested_align))) {
					if (lease_expired(lease)) {
						/* probably best if we drop this lease */
						memset(lease->chaddr, 0, 16);
					/* make some contention for this address */
					} else sendNAK(&packet);
				} else if (requested_align < server_config.start || 
					   requested_align > server_config.end) {
					sendNAK(&packet);
				} else {
					sendNAK(&packet);
				}
			} else if (packet.ciaddr) {
				/* RENEWING or REBINDING State */
				sendNAK(&packet);
			}
			break;
		case DHCPDECLINE:
			DEBUG(LOG_INFO,"received DECLINE");
			if (lease) {
				memset(lease->chaddr, 0, 16);
				lease->expires = uptime() + server_config.decline_time;
			}			
			break;
		case DHCPRELEASE:
			DEBUG(LOG_INFO,"received RELEASE");
			if (lease) lease->expires = uptime();
			break;
		case DHCPINFORM:
			DEBUG(LOG_INFO,"received INFORM");
			send_inform(&packet);
			break;	
		default:
			LOG(LOG_WARNING, "unsupported DHCP message (%02x) -- ignoring", state[0]);
		}
	}

	return 0;
}