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

📄 irdpd.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* We don't care about RIP packets when there are router adverts. */	if (now + MaxAdvertisementInterval < router_advert_valid) return;	udp_io_hdr= (udp_io_hdr_t *) rip_buf;	if (udp_io_hdr->uih_data_len != n - sizeof(*udp_io_hdr)) {		if (debug) printf("Bad sized route packet (discarded)\n");		return;	}	routeinfo= (routeinfo_t *) (rip_buf + sizeof(*udp_io_hdr)			+ udp_io_hdr->uih_ip_opt_len);	if (routeinfo->version != RIP_VERSION				|| routeinfo->command != RIP_REPLY) {		if (debug) {			printf("Route packet command %d, version %d ignored\n",				routeinfo->command, routeinfo->version);		}		return;	}	/* Look for a default route, the route to the gateway. */	end= (struct routedata *) (rip_buf + n);	default_dist= (u32_t) -1;	for (data= routeinfo->data; data < end; data++) {		if (ntohs(data->family) != AF_INET || data->ip_addr != 0)			continue;		default_dist= ntohl(data->metric);		if (default_dist >= 256) {			if (debug) printf("Strange metric %d\n", default_dist);		}	}	pref= default_dist >= 256 ? 1 : 512 - default_dist;	pref+= priority_offset;	/* Add the gateway to the table with the calculated preference. */	add_gateway(udp_io_hdr->uih_src_addr, pref);	if (debug) {		printf("Routing table after RIP packet from %s:\n",			addr2name(udp_io_hdr->uih_src_addr));		print_table();	}	/* Start advertizing. */	if (next_advert == NEVER) next_advert= IMMEDIATELY;}void irdp_incoming(ssize_t n)/* Look for router solicitations and router advertisements.  The solicitations * are probably from other irdpd daemons, we answer them if we do not expect * a real router to answer.  The advertisements cause this daemon to shut up. */{	ip_hdr_t *ip_hdr;	icmp_hdr_t *icmp_hdr;	int ip_hdr_len;	char *data;	int i;	int router;	ipaddr_t addr;	i32_t pref;	time_t valid;	ip_hdr= (ip_hdr_t *) irdp_buf;	ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2;	if (n < ip_hdr_len + 8) {		if (debug) printf("Bad sized ICMP (discarded)\n");		return;	}	icmp_hdr= (icmp_hdr_t *)(irdp_buf + ip_hdr_len);	/* Did I send it myself? */	if (ip_hdr->ih_src == my_ip_addr) return;	if ((htonl(ip_hdr->ih_src) & 0xFF000000L) == 0x7F000000L) return;	if (icmp_hdr->ih_type == ICMP_TYPE_ROUTE_SOL) {		/* Some other host is looking for a router.  Send a table		 * if there is no smart router around, we are not still		 * solicitating ourselves, and we are not told to be silent.		 */		if (sol_retries == 0 && table_size > 0				&& now > router_advert_valid && !silent) {			advertize(ip_hdr->ih_src);		}		return;	}	if (icmp_hdr->ih_type != ICMP_TYPE_ROUTER_ADVER) return;	/* Incoming router advertisement, the kind of packet the TCP/IP task	 * is very happy with.  No need to solicit further.	 */	sol_retries= 0;	/* Add router info to our table.  Also see if the packet came from	 * a router, and not another irdpd.  If it is from a router then we	 * go silent for the lifetime of the ICMP.	 */	router= 0;	data= (char *) icmp_hdr->ih_dun.uhd_data;	for (i= 0; i < icmp_hdr->ih_hun.ihh_ram.iram_na; i++) {		addr= * (ipaddr_t *) data;		data+= sizeof(ipaddr_t);		pref= htonl(* (i32_t *) data);		data+= sizeof(i32_t);		if (addr == ip_hdr->ih_src) {			/* The sender is in the routing table! */			router= 1;		}		add_gateway(addr, pref);	}	valid= now + ntohs(icmp_hdr->ih_hun.ihh_ram.iram_lt);	if (router) router_advert_valid= valid;	/* Restart advertizing close to the timeout of the advert.  (No more	 * irdpd adverts if the router stays alive.)	 */	if (router || next_advert > valid - DANGER)		next_advert= valid - DANGER;	if (debug) {		printf("Routing table after advert received from %s:\n",			addr2name(ip_hdr->ih_src));		print_table();		if (router) {			struct tm *tm= localtime(&router_advert_valid);			printf(			"This router advert is valid until %02d:%02d:%02d\n",				tm->tm_hour, tm->tm_min, tm->tm_sec);		}	}}void sig_handler(int sig)/* A signal changes the debug level. */{	switch (sig) {	case SIGUSR1:	debug++;		break;	case SIGUSR2:	debug= 0;		break;	}}void usage(void){	fprintf(stderr,"Usage: irdpd [-d] [-U udp-device] [-I ip-device] [-o priority-offset]\n");	exit(1);}int main(int argc, char **argv){	int i;	struct servent *service;	udpport_t route_port;	nwio_udpopt_t udpopt;	nwio_ipconf_t ipconf;	nwio_ipopt_t ipopt;	asynchio_t asyn;	time_t timeout;	struct timeval tv;	struct sigaction sa;	char *offset_arg, *offset_end;	long arg;	udp_device = ip_device = nil;	for (i = 1; i < argc && argv[i][0] == '-'; i++) {		char *p= argv[i] + 1;		if (p[0] == '-' && p[1] == 0) { i++; break; }		while (*p != 0) {			switch (*p++) {			case 'U':				if (udp_device != nil) usage();				if (*p == 0) {					if (++i == argc) usage();					p= argv[i];				}				udp_device= p;				p= "";				break;			case 'I':				if (ip_device != nil) usage();				if (*p == 0) {					if (++i == argc) usage();					p= argv[i];				}				ip_device= p;				p= "";				break;			case 'o':				if (offset_arg != nil) usage();				if (*p == 0) {					if (++i == argc) usage();					p= argv[i];				}				offset_arg= p;				p= "";				break;			case 'b':				bcast= 1;				break;			case 's':				silent= 1;				break;			case 'd':				debug= 1;				break;			default:				usage();			}		}	}	if (i != argc) usage();	/* Debug level signals. */	sa.sa_handler= sig_handler;	sigemptyset(&sa.sa_mask);	sa.sa_flags= 0;	sigaction(SIGUSR1, &sa, nil);	sigaction(SIGUSR2, &sa, nil);	if (udp_device == nil && (udp_device= getenv("UDP_DEVICE")) == nil)		udp_device= UDP_DEVICE;	if (ip_device == nil && (ip_device= getenv("IP_DEVICE")) == nil)		ip_device= IP_DEVICE;	if (offset_arg == nil) {		priority_offset= PRIO_OFF_DEF;	} else {		arg= strtol(offset_arg, &offset_end, 0);		if (*offset_end != 0 || (priority_offset= arg) != arg) usage();	}	if ((service= getservbyname("route", "udp")) == nil) {		fprintf(stderr,	"irdpd: unable to look up the port number for the 'route' service\n");		exit(1);	}	route_port= (udpport_t) service->s_port;	if ((rip_fd= open(udp_device, O_RDWR)) < 0) fatal(udp_device);	udpopt.nwuo_flags= NWUO_COPY | NWUO_LP_SET | NWUO_DI_LOC		| NWUO_EN_BROAD | NWUO_RP_SET | NWUO_RA_ANY | NWUO_RWDATALL		| NWUO_DI_IPOPT;	udpopt.nwuo_locport= route_port;	udpopt.nwuo_remport= route_port;	if (ioctl(rip_fd, NWIOSUDPOPT, &udpopt) < 0)		fatal("setting UDP options failed");	if ((irdp_fd= open(ip_device, O_RDWR)) < 0) fatal(ip_device);	if (ioctl(irdp_fd, NWIOGIPCONF, &ipconf) < 0)		fatal("can't get IP configuration");	my_ip_addr= ipconf.nwic_ipaddr;	ipopt.nwio_flags= NWIO_COPY | NWIO_EN_LOC | NWIO_EN_BROAD			| NWIO_REMANY | NWIO_PROTOSPEC			| NWIO_HDR_O_SPEC | NWIO_RWDATALL;	ipopt.nwio_tos= 0;	ipopt.nwio_ttl= 255;	ipopt.nwio_df= 0;	ipopt.nwio_hdropt.iho_opt_siz= 0;	ipopt.nwio_rem= HTONL(0xFFFFFFFFL);	ipopt.nwio_proto= IPPROTO_ICMP;	if (ioctl(irdp_fd, NWIOSIPOPT, &ipopt) < 0)		fatal("can't configure ICMP channel");	asyn_init(&asyn);	while (1) {		ssize_t r;		if (do_rip) {			/* Try a RIP read. */			r= asyn_read(&asyn, rip_fd, rip_buf, sizeof(rip_buf));			if (r < 0) {				if (errno == EIO) fatal(udp_device);				if (errno != EINPROGRESS) report(udp_device);			} else {				now= time(nil);				rip_incoming(r);			}		}		if (do_rdisc) {			/* Try an IRDP read. */			r= asyn_read(&asyn, irdp_fd, irdp_buf,							sizeof(irdp_buf));			if (r < 0) {				if (errno == EIO) fatal(ip_device);				if (errno != EINPROGRESS) report(ip_device);			} else {				now= time(nil);				irdp_incoming(r);			}		}		fflush(stdout);		/* Compute the next wakeup call. */		timeout= next_sol < next_advert ? next_sol : next_advert;		/* Wait for a RIP or IRDP packet or a timeout. */		tv.tv_sec= timeout;		tv.tv_usec= 0;		if (asyn_wait(&asyn, 0, timeout == NEVER ? nil : &tv) < 0) {			/* Timeout? */			if (errno != EINTR && errno != EAGAIN)				fatal("asyn_wait()");			now= time(nil);			time_functions();		}	}}

⌨️ 快捷键说明

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