_diff -r Makefile.orig Makefile 8c8,9 < SRCS= bootparamd.c main.c ${GENSRCS} --- > > SRCS= multinet.c bootparamd.c main.c ${GENSRCS} 11c12,13 < CFLAGS+= -DTFTP_DIR=\"/tftpboot\" -I. --- > CFLAGS+= -DTFTP_DIR=\"/tftpboot\" -I. > Only in bootparamd.new: Makefile.inc diff -r bootparamd.8.orig bootparamd.8 13a14,15 > .Op Fl R Ar router/netmask > .Op Fl F Ar router file 47a50,53 > .It Fl R Ar router/netbits > Specify an alternate router for a given subnet. > .It Fl F Ar router_file > Specify a file from which to load alternate router/netbit pairs. 65a72,98 > > If you expect to use bootparamd on multiple networks, you can specify multiple > gateways using -R, followed by the router to use, slash, and the number of bits > in the netmask. As an example: > > bootparamd -r 1.2.3.4 -R 10.1.1.1/24 > > will cause bootparamd to use 1.2.3.4 as the default router for any unmatched > networks, but will use 10.1.1.1 when a client on the 10.1.1.0/24 network > requests parameters. Note that the client making the request must resolve to > an IP address, either via gethostname(3) or inet_aton(3) for pattern matching. > > You may specify -R as many times as needed. > > Using -F, you may also specify a file from which to read routing information. > Similar to the -R option, each line of the file should specify a router and the > number of bits in the netmask. For example: > > 10.1.1.1/25 > 10.1.1.129/25 > 10.1.2.1/24 > > Comments in this file may be specified by using a semi-colon or hash character > at the start of the comment. > > Multiple -F values may be specified, if needed. > diff -r bootparamd.c.orig bootparamd.c 42a43 > int get_router_for_client __P((char *, in_addr_t)); 81a83 > route_addr = get_router_for_client(res.client_name, route_addr); 117c119 < char *where, *index(); --- > char *where; 130c132,135 < if (! he ) goto failed; --- > if (! he ) { > if (debug) warnx("bad hostname %s", getfile->client_name); > goto failed; > } 135a141,146 > if (debug) warnx("matched: %s",buffer); > res.server_name = ""; > res.server_path = ""; > res.server_address.address_type = IP_ADDR_TYPE; > bzero(&res.server_address.bp_address_u.ip_addr,4); > 142,145d152 < he = gethostbyname(hostname); < if ( !he ) goto failed; < bcopy( he->h_addr, &res.server_address.bp_address_u.ip_addr, 4); < res.server_name = hostname; 147,155c154,169 < res.server_address.address_type = IP_ADDR_TYPE; < } < else { /* special for dump, answer with null strings */ < if (!strcmp(getfile->file_id, "dump")) { < res.server_name = ""; < res.server_path = ""; < res.server_address.address_type = IP_ADDR_TYPE; < bzero(&res.server_address.bp_address_u.ip_addr,4); < } else goto failed; --- > if (hostname[0]) { > he = gethostbyname(hostname); > if ( !he ) { > if (debug) warnx("invalid hostname %s", hostname); > goto failed; > } > bcopy( he->h_addr, &res.server_address.bp_address_u.ip_addr, 4); > res.server_name = hostname; > } > } else { > /* XXX allow "dump" keyword with no value. Why? no idea. > Fail otherwise. */ > if (strcmp(getfile->file_id, "dump")) { > if (debug) warnx("invalid value for keyword %s", getfile->file_id); > goto failed; > } 158c172 < fprintf(stderr, "returning server:%s path:%s address: %d.%d.%d.%d\n", --- > fprintf(stderr, "returning server:\"%s\" path:\"%s\" address: %d.%d.%d.%d\n", diff -r main.c.orig main.c 51,52c51 < < while ((c = getopt(argc, argv,"dsr:f:")) != -1) --- > while ((c = getopt(argc, argv,"dsr:f:R:F:")) != -1) 56a56,67 > case 'R': > { > if (!(add_router(optarg))) > errx(1,"Unable to add router/netmask %s",optarg); > break; > } > case 'F': > { > if (!(add_routers_from_file(optarg))) > errx(1,"Unable to load routers/netmasks from file %s",optarg); > break; > } diff -r multinet.c.orig multinet.c 0a1,145 > /* > > This code is not copyright, and is placed in the public domain. Feel free to > use and modify. Please send modifications and/or suggestions + bug fixes to > > Brian McGovern > > */ > > #include > #include > #include > #include > #include > #include > #include > #include > #include > > extern int debug; > extern int dolog; > > > struct router_list > { > struct in_addr router, > netmask; > struct router_list *next; > } *router_list = NULL;; > > struct in_addr get_address_for_client(char *client) > { > struct hostent *host = gethostbyname(client); > struct in_addr tmp = {0}; > if (host) > memcpy(&tmp.s_addr, host->h_addr, sizeof(tmp.s_addr)); > else > { > if (!(inet_aton(client,&tmp))) > tmp.s_addr = 0; > } > return tmp; > } > > struct in_addr get_netmask_from_bits(char *numbits) > { > struct in_addr tmp = {0}; > long bits = 0; > errno = 0; > bits = strtol(numbits, (char **)NULL, 10); > if ((!(errno)) && ((bits < 32) && (bits > 0))) > tmp.s_addr = htonl((~0) << (32 - bits)); > return tmp; > } > > in_addr_t get_router_for_client(char *client, in_addr_t default_router) > { > struct router_list *ptr = router_list; > struct in_addr address = {0}; > in_addr_t return_address = 0; > if (!router_list) > return default_router; > address = get_address_for_client(client); > while (ptr) > { > if ((address.s_addr & ptr->netmask.s_addr) == (ptr->router.s_addr & ptr->netmask.s_addr)) > { > return_address = ptr->router.s_addr; > return return_address; > } > ptr = ptr->next; > } > return default_router; > } > > int add_router(char *routermask) > { > struct router_list *ptr = router_list; > struct in_addr router_addr = {0}, > netmask_addr = {0}; > char *tmpstr = NULL, > *netbits = NULL, > *router = NULL; > > > tmpstr = netbits = strdup(routermask); > > if (!tmpstr) > return 0; > > router = strsep(&netbits,"/\0"); > router_addr = get_address_for_client(router); > netmask_addr = get_netmask_from_bits(netbits); > > free(tmpstr); > > if ((!router_addr.s_addr) || (!netmask_addr.s_addr)) > return 0; > > if (!ptr) > ptr = router_list = (struct router_list *)calloc(1,sizeof(struct router_list)); > else > { > while (ptr->next != NULL) > ptr = ptr->next; > ptr->next = (struct router_list *)calloc(1,sizeof(struct router_list)); > ptr = ptr->next; > } > if (!ptr) > { > return 0; > } > ptr->router = router_addr; > ptr->netmask = netmask_addr; > return 1; > } > > int add_routers_from_file(char *filename) > { > #define BUFSIZE 512 > unsigned char buffer[BUFSIZE] = {0}, > *ptr = NULL; > FILE *fh = fopen(filename,"r"); > int retval = 1, > fileline = 0; > > if (!fh) > return 0; > while (fgets(buffer, BUFSIZE, fh)) > { > fileline++; > if (ptr = strpbrk(buffer,"#;\n")) > *ptr = 0; > if ((strlen(buffer) > 2) && (add_router(buffer) == 0)) > { > if (debug) > fprintf(stderr,"Unable to add router/netmask %s from line %d of file %s\n",buffer,fileline,filename); > if (dolog) > syslog(LOG_NOTICE,"Unable to add router/netmask %s from line %d of file %s\n",buffer,fileline,filename); > retval = 0; > } > } > fclose(fh); > return retval; > }