misc/117339: loading routing management commands from file

Alter alter at alter.org.ua
Fri Oct 19 11:40:01 PDT 2007


>Number:         117339
>Category:       misc
>Synopsis:       loading routing management commands from file
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Fri Oct 19 18:40:01 UTC 2007
>Closed-Date:
>Last-Modified:
>Originator:     Alter
>Release:        FreeBSD 6.2-p5
>Organization:
AlterWare
>Environment:
FreeBSD alfa-inet.net 6.2-STABLE FreeBSD 6.2-STABLE #0: Thu Oct 18 12:19:24 EEST 2007     root at alfa-inet.net:/usr/src/sys/amd64/compile/JCAT_v1  amd64
>Description:
It is very inconvenient running 'route' multiple times to load or update numerous routes. Also, this affects system porformance. Also, sometimes it is necessary to ignore errors, appeared on processing of some requests.
>How-To-Repeat:

>Fix:
Proposed patch adds '-f' switch, which loads set of commands from file. So you can make multiple updates of routing table with single call to route. Each line of file contains single route command. For example:

route -f route.rules

Also adds '-i' switch to command line. When '-i' is used, all routing commands containing errors will be rejected, but correct commands will be applied. ROUTE shall not stop on the 1st invalid command. It is useful when loading routing rules from file.

Since 'route' invokes exit() (or alternatives) on errors, patch adds error status return to all functions instead of terminating process and necessary error handling.
Also, added reset of all global veriables, containing current command processing state, to initial values before each line processing.

Patch (or it's updates) is located here:
http://alter.org.ua/soft/fbsd/route/route-file_ie.patch.gz
Page ot the patch:
http://alter.org.ua/soft/fbsd/route/



Patch attached with submission follows:

*** route.orig.c	Thu Sep  6 14:58:28 2007
--- route.c	Thu Sep  6 18:31:25 2007
***************
*** 63,68 ****
--- 63,69 ----
  #include <paths.h>
  #include <stdio.h>
  #include <stdlib.h>
+ #include <stdarg.h>
  #include <string.h>
  #include <sysexits.h>
  #include <unistd.h>
***************
*** 92,107 ****
  typedef union sockunion *sup;
  int	pid, rtm_addrs;
  int	s;
! int	forcehost, forcenet, doflush, nflag, af, qflag, tflag, keyword();
! int	iflag, verbose, aflen = sizeof (struct sockaddr_in);
  int	locking, lockrest, debugonly;
  struct	rt_metrics rt_metrics;
  u_long  rtm_inits;
  uid_t	uid;
  int	atalk_aton(const char *, struct at_addr *);
  char	*atalk_ntoa(struct at_addr);
  const char	*routename(), *netname();
! void	flushroutes(), newroute(), monitor(), sockaddr(), sodump(), bprintf();
  void	print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(), mask_addr();
  #ifdef INET6
  static int inet6_makenetandmask(struct sockaddr_in6 *, char *);
--- 93,112 ----
  typedef union sockunion *sup;
  int	pid, rtm_addrs;
  int	s;
! int	forcehost, forcenet, doflush, nflag, af, qflag, tflag, ignore_errors, keyword();
! int	iflag, verbose;
! int     aflen = sizeof (struct sockaddr_in);
  int	locking, lockrest, debugonly;
  struct	rt_metrics rt_metrics;
  u_long  rtm_inits;
  uid_t	uid;
+ char* file;
+ 
  int	atalk_aton(const char *, struct at_addr *);
  char	*atalk_ntoa(struct at_addr);
  const char	*routename(), *netname();
! int	flushroutes(), newroute(), monitor();
! void    sockaddr(), sodump(), bprintf();
  void	print_getmsg(), print_rtmsg(), pmsg_common(), pmsg_addrs(), mask_addr();
  #ifdef INET6
  static int inet6_makenetandmask(struct sockaddr_in6 *, char *);
***************
*** 110,140 ****
  int	prefixlen();
  extern	char *iso_ntoa();
  
! void usage(const char *) __dead2;
  
! void
  usage(cp)
  	const char *cp;
  {
  	if (cp)
  		warnx("bad keyword: %s", cp);
  	(void) fprintf(stderr,
! 	    "usage: route [-dnqtv] command [[modifiers] args]\n");
! 	exit(EX_USAGE);
  	/* NOTREACHED */
  }
  
  int
! main(argc, argv)
  	int argc;
  	char **argv;
  {
  	int ch;
  
! 	if (argc < 2)
! 		usage((char *)NULL);
  
! 	while ((ch = getopt(argc, argv, "nqdtv")) != -1)
  		switch(ch) {
  		case 'n':
  			nflag = 1;
--- 115,191 ----
  int	prefixlen();
  extern	char *iso_ntoa();
  
! int my_errx(int code, char* fmt, ...)
! {
!     va_list args;
!     va_start(args, fmt);
! 
!     if(!ignore_errors)
!         verrx(code, fmt, args);
  
!     vwarnx(fmt, args);
! 
!     va_end(args);
!     return code;
! }
! 
! int my_err(int code, char* fmt, ...)
! {
!     va_list args;
!     va_start(args, fmt);
! 
!     if(!ignore_errors)
!         verr(code, fmt, args);
! 
!     vwarn(fmt, args);
! 
!     va_end(args);
!     return code;
! }
! 
! int usage(const char *);
! 
! int
  usage(cp)
  	const char *cp;
  {
  	if (cp)
  		warnx("bad keyword: %s", cp);
  	(void) fprintf(stderr,
! 	    "usage: route [-dnqtvi] command [[modifiers] args]\n");
! 	(void) fprintf(stderr,
! 	    "   or: route [-dnqtvi] -f <filename>\n");
! 	if(!ignore_errors) {
! 	    exit(EX_USAGE);
! 	}
! 	return(EX_USAGE);
  	/* NOTREACHED */
  }
  
  int
! main_cmd(argc, argv)
  	int argc;
  	char **argv;
  {
  	int ch;
  
!         /* reset internal states */
! 	pid = getpid();
! 	uid = geteuid();
  
! 	rtm_addrs = 0;
!         forcehost = 0;
!         forcenet = 0;
!         doflush = 0;
!         af = 0;
!         iflag = 0;
!         aflen = sizeof (struct sockaddr_in);
!         locking = 0;
!         lockrest = 0;
!         memset(&rt_metrics, 0, sizeof(rt_metrics));
!         rtm_inits = 0;
! 
! 	while ((ch = getopt(argc, argv, "nqdtvi")) != -1) {
  		switch(ch) {
  		case 'n':
  			nflag = 1;
***************
*** 151,171 ****
  		case 'd':
  			debugonly = 1;
  			break;
  		case '?':
  		default:
! 			usage((char *)NULL);
  		}
  	argc -= optind;
  	argv += optind;
  
- 	pid = getpid();
- 	uid = geteuid();
- 	if (tflag)
- 		s = open(_PATH_DEVNULL, O_WRONLY, 0);
- 	else
- 		s = socket(PF_ROUTE, SOCK_RAW, 0);
- 	if (s < 0)
- 		err(EX_OSERR, "socket");
  	if (*argv)
  		switch (keyword(*argv)) {
  		case K_GET:
--- 202,221 ----
  		case 'd':
  			debugonly = 1;
  			break;
+ 		case 'i':
+ 			ignore_errors = 1;
+ 			break;
  		case '?':
  		default:
! 		        if(!ignore_errors) {
! 			    return usage((char *)NULL);
! 			}
  		}
+ 	}
+ 
  	argc -= optind;
  	argv += optind;
  
  	if (*argv)
  		switch (keyword(*argv)) {
  		case K_GET:
***************
*** 175,182 ****
  		case K_CHANGE:
  		case K_ADD:
  		case K_DELETE:
! 			newroute(argc, argv);
! 			/* NOTREACHED */
  
  		case K_MONITOR:
  			monitor();
--- 225,231 ----
  		case K_CHANGE:
  		case K_ADD:
  		case K_DELETE:
! 			return newroute(argc, argv);
  
  		case K_MONITOR:
  			monitor();
***************
*** 184,201 ****
  
  		case K_FLUSH:
  			flushroutes(argc, argv);
! 			exit(0);
! 			/* NOTREACHED */
  		}
! 	usage(*argv);
! 	/* NOTREACHED */
  }
  
  /*
   * Purge all entries in the routing tables not
   * associated with network interfaces.
   */
! void
  flushroutes(argc, argv)
  	int argc;
  	char *argv[];
--- 233,407 ----
  
  		case K_FLUSH:
  			flushroutes(argc, argv);
! 			return(0);
  		}
! 	return usage(*argv);
! 	//return EX_USAGE;
! }
! 
! /*
!  * Free a the (locally allocated) copy of command line arguments.
!  */
! static void
! free_args(int ac, char **av)
! {
! 	int i;
! 
! 	for (i=0; i < ac; i++)
! 		free(av[i]);
! 	free(av);
! }
! 
! 
! static void
! route_readfile()
! {
! #define MAX_ARGS	32
! #define WHITESP		" \t\f\v\n\r"
! 	char	buf[BUFSIZ];
! 	int	lineno=0;
! 	FILE	*f = NULL;
! 
! 	int ac;
! 	char **av;
! 
! 	if ((f = fopen(file, "r")) == NULL)
! 		err(EX_UNAVAILABLE, "fopen: %s", file);
! 
!     	sprintf(buf, "r ");
! 
! 	while (fgets(buf, BUFSIZ, f)) {		/* read commands */
! 		char linename[20];
! 
! 		int l;
! 		int copy;		/* 1 if we need to copy, 0 otherwise */
! 		int i, j;
! 
! 		lineno++;
! 		sprintf(linename, "Line %d\n", lineno);
! 		setprogname(linename); /* XXX */
! 		//printf(linename);
! 
! 		buf[BUFSIZ-1] = '\0';
! 		l = strlen(buf);
! 		copy = 0;		/* 1 if we need to copy, 0 otherwise */
! 		
! 		for (i = j = 0; i < l; i++) {
! 			if (buf[i] == '#')	/* comment marker */
! 				break;
! 			if (copy) {
! 				buf[j++] = buf[i];
! 				copy = !index("," WHITESP, buf[i]);
! 			} else {
! 				copy = !index(WHITESP, buf[i]);
! 				if (copy)
! 					buf[j++] = buf[i];
! 			}
! 		}
! 		if (!copy && j > 0)	/* last char was a 'blank', remove it */
! 			j--;
! 		l = j;			/* the new argument length */
! 		buf[j++] = '\0';
! 		if (l == 0)		/* empty string! */
! 			continue;
! 
! 		/*
! 		 * First, count number of arguments. Because of the previous
! 		 * processing, this is just the number of blanks plus 1.
! 		 */
! 		for (i = 0, ac = 1; i < l; i++)
! 			if (index(WHITESP, buf[i]) != NULL)
! 				ac++;
! 
! 		av = calloc(ac, sizeof(char *));
! 
! 		/*
! 		 * Second, copy arguments from cmd[] to av[]. For each one,
! 		 * j is the initial character, i is the one past the end.
! 		 */
! 		for (ac = 0, i = j = 0; i < l; i++)
! 			if (index(WHITESP, buf[i]) != NULL || i == l-1) {
! 				if (i == l-1)
! 					i++;
! 				av[ac] = calloc(i-j+1, 1);
! 				bcopy(buf+j, av[ac], i-j);
! 				ac++;
! 				j = i + 1;
! 			}
! 
!             	optreset = 1;
!             	optind = 0;
! 		main_cmd(ac, av);
!         	/* Free memory allocated in the argument parsing. */
!         	free_args(ac, av);
! 	}
! 	fclose(f);
! }
! 
! int
! main(argc, argv)
! 	int argc;
! 	char **argv;
! {
! 	int ch;
! 
! 	if (argc < 2)
! 		exit(usage((char *)NULL));
! 
! 	while ((ch = getopt(argc, argv, "nqdtvif:")) != -1)
! 		switch(ch) {
! 		case 'n':
! 			nflag = 1;
! 			break;
! 		case 'q':
! 			qflag = 1;
! 			break;
! 		case 'v':
! 			verbose = 1;
! 			break;
! 		case 't':
! 			tflag = 1;
! 			break;
! 		case 'd':
! 			debugonly = 1;
! 			break;
! 		case 'i':
! 			ignore_errors = 1;
! 			break;
! 		case 'f':
! 			file = optarg;
! 			break;
! 		case '?':
! 		default:
! 			exit(usage((char *)NULL));
! 		}
! 
! 	argc -= optind;
! 	argv += optind;
! 
! 	if (tflag)
! 		s = open(_PATH_DEVNULL, O_WRONLY, 0);
! 	else
! 		s = socket(PF_ROUTE, SOCK_RAW, 0);
! 	if (s < 0)
! 		my_err(EX_OSERR, "socket");
! 
! 	if(!file) {
!         	if (*argv) {
!                 	optind = optreset = 0;
!         	        exit(main_cmd(argc, argv));
!         	}
! 	} else {
! 	        route_readfile();
! 	}
! 	exit(EX_OK);
  }
  
  /*
   * Purge all entries in the routing tables not
   * associated with network interfaces.
   */
! int
  flushroutes(argc, argv)
  	int argc;
  	char *argv[];
***************
*** 206,212 ****
  	struct rt_msghdr *rtm;
  
  	if (uid && !debugonly) {
! 		errx(EX_NOPERM, "must be root to alter routing table");
  	}
  	shutdown(s, SHUT_RD); /* Don't want to read back our messages */
  	if (argc > 1) {
--- 412,418 ----
  	struct rt_msghdr *rtm;
  
  	if (uid && !debugonly) {
! 		return my_errx(EX_NOPERM, "must be root to alter routing table");
  	}
  	shutdown(s, SHUT_RD); /* Don't want to read back our messages */
  	if (argc > 1) {
***************
*** 230,236 ****
  			default:
  				goto bad;
  		} else
! bad:			usage(*argv);
  	}
  retry:
  	mib[0] = CTL_NET;
--- 436,442 ----
  			default:
  				goto bad;
  		} else
! bad:			return usage(*argv);
  	}
  retry:
  	mib[0] = CTL_NET;
***************
*** 240,248 ****
  	mib[4] = NET_RT_DUMP;
  	mib[5] = 0;		/* no flags */
  	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
! 		err(EX_OSERR, "route-sysctl-estimate");
  	if ((buf = malloc(needed)) == NULL)
! 		errx(EX_OSERR, "malloc failed");
  	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
  		if (errno == ENOMEM && count++ < 10) {
  			warnx("Routing table grew, retrying");  
--- 446,454 ----
  	mib[4] = NET_RT_DUMP;
  	mib[5] = 0;		/* no flags */
  	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
! 		return my_err(EX_OSERR, "route-sysctl-estimate");
  	if ((buf = malloc(needed)) == NULL)
! 		return my_errx(EX_OSERR, "malloc failed");
  	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
  		if (errno == ENOMEM && count++ < 10) {
  			warnx("Routing table grew, retrying");  
***************
*** 250,256 ****
  			free(buf);
  			goto retry;
  		}
! 		err(EX_OSERR, "route-sysctl-get");
  	}
  	lim = buf + needed;
  	if (verbose)
--- 456,462 ----
  			free(buf);
  			goto retry;
  		}
! 		return my_err(EX_OSERR, "route-sysctl-get");
  	}
  	lim = buf + needed;
  	if (verbose)
***************
*** 274,280 ****
  		rtm->rtm_seq = seqno;
  		rlen = write(s, next, rtm->rtm_msglen);
  		if (rlen < 0 && errno == EPERM)
! 			err(1, "write to routing socket");
  		if (rlen < (int)rtm->rtm_msglen) {
  			warn("write to routing socket");
  			(void) printf("got only %d for rlen\n", rlen);
--- 480,486 ----
  		rtm->rtm_seq = seqno;
  		rlen = write(s, next, rtm->rtm_msglen);
  		if (rlen < 0 && errno == EPERM)
! 			return my_err(1, "write to routing socket");
  		if (rlen < (int)rtm->rtm_msglen) {
  			warn("write to routing socket");
  			(void) printf("got only %d for rlen\n", rlen);
***************
*** 296,301 ****
--- 502,508 ----
  			(void) printf("done\n");
  		}
  	}
+ 	return EX_OK;
  }
  
  const char *
***************
*** 556,562 ****
  	*valp = atoi(value);
  }
  
! void
  newroute(argc, argv)
  	int argc;
  	char **argv;
--- 763,769 ----
  	*valp = atoi(value);
  }
  
! int
  newroute(argc, argv)
  	int argc;
  	char **argv;
***************
*** 565,573 ****
  	int ishost = 0, proxy = 0, ret, attempts, oerrno, flags = RTF_STATIC;
  	int key;
  	struct hostent *hp = 0;
  
  	if (uid) {
! 		errx(EX_NOPERM, "must be root to alter routing table");
  	}
  	cmd = argv[0];
  	if (*cmd != 'g')
--- 772,781 ----
  	int ishost = 0, proxy = 0, ret, attempts, oerrno, flags = RTF_STATIC;
  	int key;
  	struct hostent *hp = 0;
+ 	int pflen;
  
  	if (uid) {
! 		return my_errx(EX_NOPERM, "must be root to alter routing table");
  	}
  	cmd = argv[0];
  	if (*cmd != 'g')
***************
*** 642,683 ****
  				break;
  			case K_IFA:
  				if (!--argc)
! 					usage((char *)NULL);
! 				(void) getaddr(RTA_IFA, *++argv, 0);
  				break;
  			case K_IFP:
  				if (!--argc)
! 					usage((char *)NULL);
! 				(void) getaddr(RTA_IFP, *++argv, 0);
  				break;
  			case K_GENMASK:
  				if (!--argc)
! 					usage((char *)NULL);
! 				(void) getaddr(RTA_GENMASK, *++argv, 0);
  				break;
  			case K_GATEWAY:
  				if (!--argc)
! 					usage((char *)NULL);
! 				(void) getaddr(RTA_GATEWAY, *++argv, 0);
  				break;
  			case K_DST:
  				if (!--argc)
! 					usage((char *)NULL);
  				ishost = getaddr(RTA_DST, *++argv, &hp);
  				dest = *argv;
  				break;
  			case K_NETMASK:
  				if (!--argc)
! 					usage((char *)NULL);
! 				(void) getaddr(RTA_NETMASK, *++argv, 0);
  				/* FALLTHROUGH */
  			case K_NET:
  				forcenet++;
  				break;
  			case K_PREFIXLEN:
  				if (!--argc)
! 					usage((char *)NULL);
! 				if (prefixlen(*++argv) == -1) {
  					forcenet = 0;
  					ishost = 1;
  				} else {
--- 850,902 ----
  				break;
  			case K_IFA:
  				if (!--argc)
! 					return usage((char *)NULL);
! 				if(getaddr(RTA_IFA, *++argv, 0) == -1)
! 				        return 1;
  				break;
  			case K_IFP:
  				if (!--argc)
! 					return usage((char *)NULL);
! 				if(getaddr(RTA_IFP, *++argv, 0) == -1)
! 				        return 1;
  				break;
  			case K_GENMASK:
  				if (!--argc)
! 					return usage((char *)NULL);
! 				if(getaddr(RTA_GENMASK, *++argv, 0) == -1)
! 				        return 1;
  				break;
  			case K_GATEWAY:
  				if (!--argc)
! 					return usage((char *)NULL);
! 				if(getaddr(RTA_GATEWAY, *++argv, 0) == -1)
! 				        return 1;
  				break;
  			case K_DST:
  				if (!--argc)
! 					return usage((char *)NULL);
  				ishost = getaddr(RTA_DST, *++argv, &hp);
+ 				if(ishost == -1)
+ 				        return -1;
  				dest = *argv;
  				break;
  			case K_NETMASK:
  				if (!--argc)
! 					return usage((char *)NULL);
! 				if(getaddr(RTA_NETMASK, *++argv, 0) == -1)
! 				        return -1;
  				/* FALLTHROUGH */
  			case K_NET:
  				forcenet++;
  				break;
  			case K_PREFIXLEN:
  				if (!--argc)
! 					return usage((char *)NULL);
! 				pflen = prefixlen(*++argv);
! 				if (pflen == -2) {
! 				        return 0;
! 				} else
! 				if (pflen == -1) {
  					forcenet = 0;
  					ishost = 1;
  				} else {
***************
*** 694,714 ****
  			case K_RTT:
  			case K_RTTVAR:
  				if (!--argc)
! 					usage((char *)NULL);
  				set_metric(*++argv, key);
  				break;
  			default:
! 				usage(1+*argv);
  			}
  		} else {
  			if ((rtm_addrs & RTA_DST) == 0) {
  				dest = *argv;
  				ishost = getaddr(RTA_DST, *argv, &hp);
  			} else if ((rtm_addrs & RTA_GATEWAY) == 0) {
  				gateway = *argv;
! 				(void) getaddr(RTA_GATEWAY, *argv, &hp);
  			} else {
! 				(void) getaddr(RTA_NETMASK, *argv, 0);
  				forcenet = 1;
  			}
  		}
--- 913,937 ----
  			case K_RTT:
  			case K_RTTVAR:
  				if (!--argc)
! 					return usage((char *)NULL);
  				set_metric(*++argv, key);
  				break;
  			default:
! 				return usage(1+*argv);
  			}
  		} else {
  			if ((rtm_addrs & RTA_DST) == 0) {
  				dest = *argv;
  				ishost = getaddr(RTA_DST, *argv, &hp);
+ 				if(ishost == -1)
+ 				        return -1;
  			} else if ((rtm_addrs & RTA_GATEWAY) == 0) {
  				gateway = *argv;
! 				if(getaddr(RTA_GATEWAY, *argv, &hp) == -1)
! 				        return -1;
  			} else {
! 				if(getaddr(RTA_NETMASK, *argv, 0) == -1)
! 				        return -1;
  				forcenet = 1;
  			}
  		}
***************
*** 747,753 ****
  			break;
  	}
  	if (*cmd == 'g')
! 		exit(0);
  	if (!qflag) {
  		oerrno = errno;
  		(void) printf("%s %s %s", cmd, ishost? "host" : "net", dest);
--- 970,976 ----
  			break;
  	}
  	if (*cmd == 'g')
! 		return 0;
  	if (!qflag) {
  		oerrno = errno;
  		(void) printf("%s %s %s", cmd, ishost? "host" : "net", dest);
***************
*** 784,790 ****
  			(void) printf(": %s\n", err);
  		}
  	}
! 	exit(ret != 0);
  }
  
  void
--- 1007,1013 ----
  			(void) printf(": %s\n", err);
  		}
  	}
! 	return(ret != 0);
  }
  
  void
***************
*** 858,864 ****
  	if (!plen || strcmp(plen, "128") == 0)
  		return 1;
  	rtm_addrs |= RTA_NETMASK;
! 	(void)prefixlen(plen);
  	return 0;
  }
  #endif
--- 1081,1088 ----
  	if (!plen || strcmp(plen, "128") == 0)
  		return 1;
  	rtm_addrs |= RTA_NETMASK;
! 	if(prefixlen(plen) == -2)
! 	        return -1;
  	return 0;
  }
  #endif
***************
*** 866,871 ****
--- 1090,1096 ----
  /*
   * Interpret an argument as a network address of some kind,
   * returning 1 if a host address, 0 if a network address.
+  * Or -1 on error
   */
  int
  getaddr(which, s, hpp)
***************
*** 896,903 ****
  			struct ifaddrs *ifap, *ifa;
  			struct sockaddr_dl *sdl = NULL;
  
! 			if (getifaddrs(&ifap))
! 				err(1, "getifaddrs");
  
  			for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
  				if (ifa->ifa_addr->sa_family != AF_LINK)
--- 1121,1130 ----
  			struct ifaddrs *ifap, *ifa;
  			struct sockaddr_dl *sdl = NULL;
  
! 			if (getifaddrs(&ifap)) {
! 				my_err(1, "getifaddrs");
! 				return -1;
! 			}
  
  			for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
  				if (ifa->ifa_addr->sa_family != AF_LINK)
***************
*** 937,943 ****
  		su = &so_ifa;
  		break;
  	default:
! 		usage("internal error");
  		/*NOTREACHED*/
  	}
  	su->sa.sa_len = aflen;
--- 1164,1170 ----
  		su = &so_ifa;
  		break;
  	default:
! 		return usage("internal error");
  		/*NOTREACHED*/
  	}
  	su->sa.sa_len = aflen;
***************
*** 952,958 ****
  #if 0
  			bzero(su, sizeof(*su));	/* for readability */
  #endif
! 			(void) getaddr(RTA_NETMASK, s, 0);
  			break;
  #if 0
  		case RTA_NETMASK:
--- 1179,1186 ----
  #if 0
  			bzero(su, sizeof(*su));	/* for readability */
  #endif
! 			if(getaddr(RTA_NETMASK, s, 0) == -1)
! 			        return -1;
  			break;
  #if 0
  		case RTA_NETMASK:
***************
*** 980,986 ****
  		    res->ai_addrlen != sizeof(su->sin6)) {
  			(void) fprintf(stderr, "%s: %s\n", s,
  			    gai_strerror(ecode));
! 			exit(1);
  		}
  		memcpy(&su->sin6, res->ai_addr, sizeof(su->sin6));
  #ifdef __KAME__
--- 1208,1215 ----
  		    res->ai_addrlen != sizeof(su->sin6)) {
  			(void) fprintf(stderr, "%s: %s\n", s,
  			    gai_strerror(ecode));
! 			my_err(1, "");
! 			return -1;
  		}
  		memcpy(&su->sin6, res->ai_addr, sizeof(su->sin6));
  #ifdef __KAME__
***************
*** 1002,1009 ****
  #endif /* INET6 */
  
  	case AF_APPLETALK:
! 		if (!atalk_aton(s, &su->sat.sat_addr))
! 			errx(EX_NOHOST, "bad address: %s", s);
  		rtm_addrs |= RTA_NETMASK;
  		return(forcehost || su->sat.sat_addr.s_node != 0);
  
--- 1231,1240 ----
  #endif /* INET6 */
  
  	case AF_APPLETALK:
! 		if (!atalk_aton(s, &su->sat.sat_addr)) {
! 			my_errx(EX_NOHOST, "bad address: %s", s);
! 			return -1;
! 		}
  		rtm_addrs |= RTA_NETMASK;
  		return(forcehost || su->sat.sat_addr.s_node != 0);
  
***************
*** 1062,1068 ****
  		    MIN(hp->h_length, sizeof(su->sin.sin_addr)));
  		return (1);
  	}
! 	errx(EX_NOHOST, "bad address: %s", s);
  }
  
  int
--- 1293,1300 ----
  		    MIN(hp->h_length, sizeof(su->sin.sin_addr)));
  		return (1);
  	}
! 	my_errx(EX_NOHOST, "bad address: %s", s);
! 	return -1;
  }
  
  int
***************
*** 1087,1099 ****
  		break;
  	default:
  		(void) fprintf(stderr, "prefixlen not supported in this af\n");
! 		exit(1);
  		/*NOTREACHED*/
  	}
  
  	if (len < 0 || max < len) {
  		(void) fprintf(stderr, "%s: bad value\n", s);
! 		exit(1);
  	}
  	
  	q = len >> 3;
--- 1319,1331 ----
  		break;
  	default:
  		(void) fprintf(stderr, "prefixlen not supported in this af\n");
! 		return -2;
  		/*NOTREACHED*/
  	}
  
  	if (len < 0 || max < len) {
  		(void) fprintf(stderr, "%s: bad value\n", s);
! 		return -2;
  	}
  	
  	q = len >> 3;
***************
*** 1111,1117 ****
  		return len;
  }
  
! void
  interfaces()
  {
  	size_t needed;
--- 1343,1349 ----
  		return len;
  }
  
! int
  interfaces()
  {
  	size_t needed;
***************
*** 1127,1133 ****
  	mib[4] = NET_RT_IFLIST;
  	mib[5] = 0;		/* no flags */
  	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
! 		err(EX_OSERR, "route-sysctl-estimate");
  	if ((buf = malloc(needed)) == NULL)
  		errx(EX_OSERR, "malloc failed");
  	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
--- 1359,1365 ----
  	mib[4] = NET_RT_IFLIST;
  	mib[5] = 0;		/* no flags */
  	if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
! 		return my_err(EX_OSERR, "route-sysctl-estimate");
  	if ((buf = malloc(needed)) == NULL)
  		errx(EX_OSERR, "malloc failed");
  	if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
***************
*** 1137,1152 ****
  			free(buf);
  			goto retry2;
  		}
! 		err(EX_OSERR, "actual retrieval of interface table");
  	}
  	lim = buf + needed;
  	for (next = buf; next < lim; next += rtm->rtm_msglen) {
  		rtm = (struct rt_msghdr *)next;
  		print_rtmsg(rtm, rtm->rtm_msglen);
  	}
  }
  
! void
  monitor()
  {
  	int n;
--- 1369,1385 ----
  			free(buf);
  			goto retry2;
  		}
! 		return my_err(EX_OSERR, "actual retrieval of interface table");
  	}
  	lim = buf + needed;
  	for (next = buf; next < lim; next += rtm->rtm_msglen) {
  		rtm = (struct rt_msghdr *)next;
  		print_rtmsg(rtm, rtm->rtm_msglen);
  	}
+ 	return EX_OK;
  }
  
! int
  monitor()
  {
  	int n;
***************
*** 1154,1161 ****
  
  	verbose = 1;
  	if (debugonly) {
! 		interfaces();
! 		exit(0);
  	}
  	for(;;) {
  		time_t now;
--- 1387,1393 ----
  
  	verbose = 1;
  	if (debugonly) {
! 		return interfaces();
  	}
  	for(;;) {
  		time_t now;
***************
*** 1224,1231 ****
  	if (debugonly)
  		return (0);
  	if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) {
! 		if (errno == EPERM)
! 			err(1, "writing to routing socket");
  		warn("writing to routing socket");
  		return (-1);
  	}
--- 1456,1465 ----
  	if (debugonly)
  		return (0);
  	if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) {
! 		if (errno == EPERM) {
! 			my_err(1, "writing to routing socket");
! 			return -1;
! 		}
  		warn("writing to routing socket");
  		return (-1);
  	}
***************
*** 1552,1557 ****
--- 1786,1792 ----
  	}
  	if (gotsome)
  		(void) putc('>', fp);
+ 	return;
  }
  
  int


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list