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

📄 irdpd.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	irdpd 1.8 - Internet router discovery protocol daemon. *							Author: Kees J. Bot *								28 May 1994 * Activily solicitate or passively look for routers. * Based heavily on its forerunners, the irdp_sol and rip2icmp daemons by * Philip Homburg. */#define nil 0#include <sys/types.h>#include <errno.h>#include <fcntl.h>#include <stddef.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <limits.h>#include <unistd.h>#include <signal.h>#include <sys/ioctl.h>#include <sys/asynchio.h>#include <net/hton.h>#include <net/netlib.h>#include <net/gen/in.h>#include <net/gen/ip_hdr.h>#include <net/gen/icmp.h>#include <net/gen/icmp_hdr.h>#include <net/gen/ip_io.h>#include <net/gen/inet.h>#include <net/gen/netdb.h>#include <net/gen/oneCsum.h>#include <net/gen/socket.h>#include <net/gen/udp.h>#include <net/gen/udp_hdr.h>#include <net/gen/udp_io.h>#define MAX_RETRIES		    5	/* # router solicitations. */#define TIMEOUT			    4	/* Secs between solicitate retries. */#define DEST_TO 	      (10*60)	/* 10 minutes */#define NEW_ROUTE	       (5*60)	/* 5 minutes */#define DANGER		       (2*60)	/* Nearing a advert timeout? */#define DEAD_TO		    (24L*60*60)	/* 24 hours */#define DEAD_PREF	    0x80000000L	/* from RFC 1236 */#define MaxAdvertisementInterval  450	/* 7.5 minutes */#define LifeTime		(4 * MaxAdvertisementInterval)#define PRIO_OFF_DEF		-1024#define RIP_VERSION		    1#define RIP_REPLY		    2/* It's now or never. */#define IMMEDIATELY	((time_t) ((time_t) -1 < 0 ? LONG_MIN : 0))#define NEVER		((time_t) ((time_t) -1 < 0 ? LONG_MAX : ULONG_MAX))#if !DEBUG/* Unless doing serious debugging. */#define gethostbyaddr(addr, len, type)	((struct hostent *) nil)#endif#if !__minix_vmd/* Standard Minix needs to choose between router discovery and RIP info. */int do_rdisc= 1;int do_rip= 0;#else/* VMD Minix can do both at once. */#define do_rdisc 1#define do_rip 1#endifint rip_fd;			/* For incoming RIP packet. */int irdp_fd;			/* Receive or transmit IRDP packets. */char *udp_device;		/* UDP device to use. */char *ip_device;		/* IP device to use. */int priority_offset;		/* Offset to make my routes less preferred. */int bcast= 0;			/* Broadcast adverts to all. */int silent= 0;			/* Don't react to solicitations. */int debug= 0;char rip_buf[8192];		/* Incoming RIP packet buffer. */char irdp_buf[1024];		/* IRDP buffer. */typedef struct routeinfo{	u8_t		command;	u8_t		version;	u16_t		zero1;	struct routedata {		u16_t	family;		u16_t	zero2;		u32_t	ip_addr;		u32_t	zero3, zero4;		u32_t	metric;	} data[1];} routeinfo_t;typedef struct table{	ipaddr_t	tab_gw;	i32_t		tab_pref;	time_t		tab_time;} table_t;table_t *table;			/* Collected table of routing info. */size_t table_size;ipaddr_t my_ip_addr;		/* IP address of the local host. */int sol_retries= MAX_RETRIES;time_t next_sol= IMMEDIATELY;time_t next_advert= NEVER;time_t router_advert_valid= IMMEDIATELY;time_t now;void report(const char *label)/* irdpd: /dev/hd0: Device went up in flames */{	fprintf(stderr, "irdpd: %s: %s\n", label, strerror(errno));}void fatal(const char *label)/* irdpd: /dev/house: Taking this with it */{	report(label);	exit(1);}char *addr2name(ipaddr_t host)/* Translate an IP address to a printable name. */{#if DEBUG	struct hostent *hostent;	hostent= gethostbyaddr((char *) &host, sizeof(host), AF_INET);	return hostent == nil ? inet_ntoa(host) : hostent->h_name;#else	return inet_ntoa(host);#endif}void print_table(void)/* Show the collected routing table. */{	int i;	table_t *ptab;	struct tm *tm;	for (i= 0, ptab= table; i < table_size; i++, ptab++) {		if (ptab->tab_time < now - DEAD_TO) continue;		tm= localtime(&ptab->tab_time);		printf("%-40s %6ld %02d:%02d:%02d\n",			addr2name(ptab->tab_gw),			(long) ptab->tab_pref,			tm->tm_hour, tm->tm_min, tm->tm_sec);	}}void advertize(ipaddr_t host)/* Send a router advert to a host. */{	char *buf, *data;	ip_hdr_t *ip_hdr;	icmp_hdr_t *icmp_hdr;	int i;	table_t *ptab;	buf= malloc(sizeof(*ip_hdr) + offsetof(icmp_hdr_t, ih_dun.uhd_data)			+ table_size * (sizeof(ipaddr_t) + sizeof(u32_t)));	if (buf == nil) fatal("heap error");	ip_hdr= (ip_hdr_t *) buf;	icmp_hdr= (icmp_hdr_t *) (ip_hdr + 1);	ip_hdr->ih_vers_ihl= 0x45;	ip_hdr->ih_dst= host;	icmp_hdr->ih_type= ICMP_TYPE_ROUTER_ADVER;	icmp_hdr->ih_code= 0;	icmp_hdr->ih_hun.ihh_ram.iram_na= 0;	icmp_hdr->ih_hun.ihh_ram.iram_aes= 2;	icmp_hdr->ih_hun.ihh_ram.iram_lt= htons(LifeTime);	data= (char *) icmp_hdr->ih_dun.uhd_data;	/* Collect gateway entries from the table. */	for (i= 0, ptab= table; i < table_size; i++, ptab++) {		if (ptab->tab_time < now - DEAD_TO) continue;		icmp_hdr->ih_hun.ihh_ram.iram_na++;		if (ptab->tab_time < now - DEST_TO) ptab->tab_pref= DEAD_PREF;		* (ipaddr_t *) data= ptab->tab_gw;		data+= sizeof(ipaddr_t);		* (i32_t *) data= htonl(ptab->tab_pref);		data+= sizeof(i32_t);	}	icmp_hdr->ih_chksum= 0;	icmp_hdr->ih_chksum= ~oneC_sum(0, icmp_hdr, data - (char *) icmp_hdr);	if (icmp_hdr->ih_hun.ihh_ram.iram_na > 0) {		/* Send routing info. */		if (debug) {			printf("Routing table send to %s:\n", addr2name(host));			print_table();		}		if (write(irdp_fd, buf, data - buf) < 0) {			(errno == EIO ? fatal : report)(ip_device);		}	}	free(buf);}void time_functions(void)/* Perform time dependend functions: router solicitation, router advert. */{	if (now >= next_sol) {		char buf[sizeof(ip_hdr_t) + 8];		ip_hdr_t *ip_hdr;		icmp_hdr_t *icmp_hdr;		if (sol_retries == 0) {			/* Stop solicitating. */			next_sol= NEVER;#if !__minix_vmd			/* Switch to RIP if no router responded. */			if (table_size == 0) {				do_rip= 1;				do_rdisc= 0;			}#endif			return;		}		/* Broadcast a router solicitation to find a router. */		ip_hdr= (ip_hdr_t *) buf;		icmp_hdr= (icmp_hdr_t *) (ip_hdr + 1);		ip_hdr->ih_vers_ihl= 0x45;		ip_hdr->ih_dst= HTONL(0xFFFFFFFFL);		icmp_hdr->ih_type= ICMP_TYPE_ROUTE_SOL;		icmp_hdr->ih_code= 0;		icmp_hdr->ih_chksum= 0;		icmp_hdr->ih_hun.ihh_unused= 0;		icmp_hdr->ih_chksum= ~oneC_sum(0, icmp_hdr, 8);		if (debug) printf("Broadcasting router solicitation\n");		if (write(irdp_fd, buf, sizeof(buf)) < 0)			fatal("sending router solicitation failed");		/* Schedule the next packet. */		next_sol= now + TIMEOUT;		sol_retries--;	}	if (now >= next_advert) {		/* Advertize routes to the local host (normally), or		 * broadcast them (to keep bad hosts up.)		 */		advertize(bcast ? HTONL(0xFFFFFFFFL) : HTONL(0x7F000001L));		next_advert= now + MaxAdvertisementInterval;#if !__minix_vmd		/* Make sure we are listening to RIP now. */		do_rip= 1;		do_rdisc= 0;#endif	}}void add_gateway(ipaddr_t host, i32_t pref)/* Add a router with given address and preference to the routing table. */{	table_t *oldest, *ptab;	int i;	/* Look for the host, or select the oldest entry. */	oldest= nil;	for (i= 0, ptab= table; i < table_size; i++, ptab++) {		if (ptab->tab_gw == host) break;		if (oldest == nil || ptab->tab_time < oldest->tab_time)			oldest= ptab;	}	/* Don't evict the oldest if it is still valid. */	if (oldest != nil && oldest->tab_time >= now - DEST_TO) oldest= nil;	/* Expand the table? */	if (i == table_size && oldest == nil) {		table_size++;		table= realloc(table, table_size * sizeof(*table));		if (table == nil) fatal("heap error");		oldest= &table[table_size - 1];	}	if (oldest != nil) {		ptab= oldest;		ptab->tab_gw= host;		ptab->tab_pref= DEAD_PREF;	}	/* Replace an entry if the new one looks more promising. */	if (pref >= ptab->tab_pref || ptab->tab_time <= now - NEW_ROUTE) {		ptab->tab_pref= pref;		ptab->tab_time= now;	}}void rip_incoming(ssize_t n)/* Use a RIP packet to add to the router table.  (RIP packets are really for * between routers, but often it is the only information around.) */{	udp_io_hdr_t *udp_io_hdr;	u32_t default_dist;	i32_t pref;	routeinfo_t *routeinfo;	struct routedata *data, *end;

⌨️ 快捷键说明

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