⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcpc.c

📁 该模块功能可以实现DHCP
💻 C
📖 第 1 页 / 共 2 页
字号:
		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);	}	/* 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(SIGUSR2, signal_handler);	signal(SIGTERM, signal_handler);		state = INIT_SELECTING;	run_script(NULL, "deconfig");	change_mode(LISTEN_RAW);	for (;;) {		tv.tv_sec = timeout - get_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 = get_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 + 5;	// change wait time from 60 to 5 seconds , by honor				}				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);				change_mode(LISTEN_RAW);	// Some DHCP server send broadcast ACK after they receive a REQUEST during RENEWING state, by honor				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;					if (state != RENEWING && state !=REBINDING)						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)) {			if (read(signal_pipe[0], &sig, sizeof(sig)) < 0) {				DEBUG(LOG_ERR, "Could not read signal: %s", 					strerror(errno));				continue; /* probably just EINTR */			}			switch (sig) {			case SIGUSR1: 				perform_renew();				break;			case SIGUSR2:				perform_release();				break;			case SIGTERM:				LOG(LOG_INFO, "Received SIGTERM");				exit_client(0);			}		} else if (retval == -1 && errno == EINTR) {			/* a signal was caught */				} else {			/* An error occured */			DEBUG(LOG_ERR, "Error on select");		}			}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -