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

📄 main.c

📁 klibc精简化的c程序库
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <errno.h>#include <poll.h>#include <limits.h>#include <setjmp.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <time.h>#include <arpa/inet.h>#include <sys/types.h>#include <sys/time.h>#include <dirent.h>#include <fcntl.h>#include <unistd.h>		/* for getopts */#include <net/if_arp.h>#include "ipconfig.h"#include "netdev.h"#include "bootp_packet.h"#include "bootp_proto.h"#include "dhcp_proto.h"#include "packet.h"static const char sysfs_class_net[] = "/sys/class/net";static const char *progname;static jmp_buf abort_buf;static char do_not_config;static unsigned int default_caps = CAP_DHCP | CAP_BOOTP | CAP_RARP;static int loop_timeout = -1;static int configured;static int bringup_first = 0;/* DHCP vendor class identifier */char vendor_class_identifier[260];int vendor_class_identifier_len;struct state {	int state;	int restart_state;	time_t expire;	int retry_period;	struct netdev *dev;	struct state *next;};static inline const char *my_inet_ntoa(uint32_t addr){	struct in_addr a;	a.s_addr = addr;	return inet_ntoa(a);}static void print_device_config(struct netdev *dev){	printf("IP-Config: %s complete (from %s):\n", dev->name,	       my_inet_ntoa(dev->serverid ? dev->serverid : dev->ip_server));	printf(" address: %-16s ", my_inet_ntoa(dev->ip_addr));	printf("broadcast: %-16s ", my_inet_ntoa(dev->ip_broadcast));	printf("netmask: %-16s\n", my_inet_ntoa(dev->ip_netmask));	printf(" gateway: %-16s ", my_inet_ntoa(dev->ip_gateway));	printf("dns0     : %-16s ", my_inet_ntoa(dev->ip_nameserver[0]));	printf("dns1   : %-16s\n", my_inet_ntoa(dev->ip_nameserver[1]));	if (dev->hostname[0])		printf(" host   : %-64s\n", dev->hostname);	if (dev->dnsdomainname[0])		printf(" domain : %-64s\n", dev->dnsdomainname);	if (dev->nisdomainname[0])		printf(" nisdomain: %-64s\n", dev->nisdomainname);	printf(" rootserver: %s ", my_inet_ntoa(dev->ip_server));	printf("rootpath: %s\n", dev->bootpath);	printf(" filename  : %s\n", dev->filename);}static void configure_device(struct netdev *dev){	if (do_not_config)		return;	if (netdev_setmtu(dev))		printf("IP-Config: failed to set MTU on %s to %u\n",		       dev->name, dev->mtu);	if (netdev_setaddress(dev))		printf("IP-Config: failed to set addresses on %s\n", dev->name);	if (netdev_setdefaultroute(dev))		printf("IP-Config: failed to set default route on %s\n",		       dev->name);	if (dev->hostname[0] &&			sethostname(dev->hostname, strlen(dev->hostname)))		printf("IP-Config: failed to set hostname '%s' from %s\n",			dev->hostname, dev->name);}static void dump_device_config(struct netdev *dev){	char fn[40];	FILE *f;	snprintf(fn, sizeof(fn), "/tmp/net-%s.conf", dev->name);	f = fopen(fn, "w");	if (f) {		fprintf(f, "DEVICE=%s\n", dev->name);		fprintf(f, "IPV4ADDR=%s\n", my_inet_ntoa(dev->ip_addr));		fprintf(f, "IPV4BROADCAST=%s\n",			my_inet_ntoa(dev->ip_broadcast));		fprintf(f, "IPV4NETMASK=%s\n", my_inet_ntoa(dev->ip_netmask));		fprintf(f, "IPV4GATEWAY=%s\n", my_inet_ntoa(dev->ip_gateway));		fprintf(f, "IPV4DNS0=%s\n",			my_inet_ntoa(dev->ip_nameserver[0]));		fprintf(f, "IPV4DNS1=%s\n",			my_inet_ntoa(dev->ip_nameserver[1]));		fprintf(f, "HOSTNAME=%s\n", dev->hostname);		fprintf(f, "DNSDOMAIN=%s\n", dev->dnsdomainname);		fprintf(f, "NISDOMAIN=%s\n", dev->nisdomainname);		fprintf(f, "ROOTSERVER=%s\n", my_inet_ntoa(dev->ip_server));		fprintf(f, "ROOTPATH=%s\n", dev->bootpath);		fprintf(f, "filename=\"%s\"\n", dev->filename);		fclose(f);	}}static uint32_t inet_class_netmask(uint32_t ip){	ip = ntohl(ip);	if (IN_CLASSA(ip))		return htonl(IN_CLASSA_NET);	if (IN_CLASSB(ip))		return htonl(IN_CLASSB_NET);	if (IN_CLASSC(ip))		return htonl(IN_CLASSC_NET);	return INADDR_ANY;}static void postprocess_device(struct netdev *dev){	if (dev->ip_netmask == INADDR_ANY) {		dev->ip_netmask = inet_class_netmask(dev->ip_addr);		printf("IP-Config: %s guessed netmask %s\n",		       dev->name, my_inet_ntoa(dev->ip_netmask));	}	if (dev->ip_broadcast == INADDR_ANY) {		dev->ip_broadcast =		    (dev->ip_addr & dev->ip_netmask) | ~dev->ip_netmask;		printf("IP-Config: %s guessed broadcast address %s\n",		       dev->name, my_inet_ntoa(dev->ip_broadcast));	}	if (dev->ip_nameserver[0] == INADDR_ANY) {		dev->ip_nameserver[0] = dev->ip_server;		printf("IP-Config: %s guessed nameserver address %s\n",		       dev->name, my_inet_ntoa(dev->ip_nameserver[0]));	}}static void complete_device(struct netdev *dev){	postprocess_device(dev);	configure_device(dev);	dump_device_config(dev);	print_device_config(dev);	++configured;	dev->next = ifaces;	ifaces = dev;}static int process_receive_event(struct state *s, time_t now){	int handled = 1;	switch (s->state) {	case DEVST_BOOTP:		s->restart_state = DEVST_BOOTP;		switch (bootp_recv_reply(s->dev)) {		case -1:			s->state = DEVST_ERROR;			break;		case 1:			s->state = DEVST_COMPLETE;			DEBUG(("\n   bootp reply\n"));			break;		}		break;	case DEVST_DHCPDISC:		s->restart_state = DEVST_DHCPDISC;		switch (dhcp_recv_offer(s->dev)) {		case -1:			s->state = DEVST_ERROR;			break;		case 1:	/* Offer received */			s->state = DEVST_DHCPREQ;			dhcp_send_request(s->dev);			break;		}		break;	case DEVST_DHCPREQ:		s->restart_state = DEVST_DHCPDISC;		switch (dhcp_recv_ack(s->dev)) {		case -1:	/* error */			s->state = DEVST_ERROR;			break;		case 1:	/* ACK received */			s->state = DEVST_COMPLETE;			break;		case 2:	/* NAK received */			s->state = DEVST_DHCPDISC;			break;		}		break;	}	switch (s->state) {	case DEVST_COMPLETE:		complete_device(s->dev);		break;	case DEVST_ERROR:		/* error occurred, try again in 10 seconds */		s->expire = now + 10;	default:		DEBUG(("\n"));		handled = 0;		break;	}	return handled;}static void process_timeout_event(struct state *s, time_t now){	int ret = 0;	/*	 * Is the link up?  If not, try again in 1 second.	 */	if (!netdev_running(s->dev)) {		s->expire = now + 1;		s->state = s->restart_state;		return;	}	/*	 * If we had an error, restore a sane state to	 * restart from.	 */	if (s->state == DEVST_ERROR)		s->state = s->restart_state;	/*	 * Now send a packet depending on our state.	 */	switch (s->state) {	case DEVST_BOOTP:		ret = bootp_send_request(s->dev);		s->restart_state = DEVST_BOOTP;		break;	case DEVST_DHCPDISC:		ret = dhcp_send_discover(s->dev);		s->restart_state = DEVST_DHCPDISC;		break;	case DEVST_DHCPREQ:		ret = dhcp_send_request(s->dev);		s->restart_state = DEVST_DHCPDISC;		break;	}	if (ret == -1) {		s->state = DEVST_ERROR;		s->expire = now + 10;	} else {		s->expire = now + s->retry_period;		s->retry_period *= 2;		if (s->retry_period > 60)			s->retry_period = 60;	}}static struct state *slist;struct netdev *ifaces;static int do_pkt_recv(int pkt_fd, time_t now){	int ifindex, ret;	struct state *s;	ret = packet_peek(&ifindex);	if (ret < 0)		goto bail;	for (s = slist; s; s = s->next) {		if (s->dev->ifindex == ifindex) {			ret |= process_receive_event(s, now);			break;		}	}      bail:	return ret;}static int loop(void){#define NR_FDS	1	struct pollfd fds[NR_FDS];	struct state *s;	int pkt_fd;	int nr = 0;	struct timeval now, prev;	time_t start;	pkt_fd = packet_open();	if (pkt_fd == -1) {		perror("packet_open");		return -1;	}	fds[0].fd = pkt_fd;	fds[0].events = POLLRDNORM;	gettimeofday(&now, NULL);	start = now.tv_sec;	while (1) {		int timeout = 60;		int pending = 0;		int done = 0;		int timeout_ms;		int x;		for (s = slist; s; s = s->next) {			DEBUG(("%s: state = %d\n", s->dev->name, s->state));			if (s->state == DEVST_COMPLETE) {				done++;				continue;			}			pending++;			if (s->expire - now.tv_sec <= 0) {				DEBUG(("timeout\n"));				process_timeout_event(s, now.tv_sec);			}			if (timeout > s->expire - now.tv_sec)				timeout = s->expire - now.tv_sec;		}		if (pending == 0 || (bringup_first && done))			break;		timeout_ms = timeout * 1000;		for (x = 0; x < 2; x++) {			int delta_ms;			if (timeout_ms <= 0)				timeout_ms = 100;			nr = poll(fds, NR_FDS, timeout_ms);			prev = now;			gettimeofday(&now, NULL);			if ((fds[0].revents & POLLRDNORM)) {				nr = do_pkt_recv(pkt_fd, now.tv_sec);				if (nr == 1)					break;				else if (nr == 0)					packet_discard();			}			if (loop_timeout >= 0 &&			    now.tv_sec - start >= loop_timeout) {				printf("IP-Config: no response after %d "				       "secs - giving up\n", loop_timeout);				goto bail;			}			delta_ms = (now.tv_sec - prev.tv_sec) * 1000;			delta_ms += (now.tv_usec - prev.tv_usec) / 1000;			DEBUG(("Delta: %d ms\n", delta_ms));			timeout_ms -= delta_ms;		}	}

⌨️ 快捷键说明

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