Index: lib/Makefile =================================================================== --- lib/Makefile +++ lib/Makefile @@ -78,6 +78,7 @@ libproc \ libprocstat \ libregex \ + libroute \ librpcsvc \ librss \ librt \ Index: lib/libroute/Makefile =================================================================== --- /dev/null +++ lib/libroute/Makefile @@ -0,0 +1,16 @@ +# $FreeBSD$ + +PACKAGE= lib${LIB} +LIB= route +INTERNALLIB= true + +SHLIBDIR?= /lib +SHLIB_MAJOR= 1 +SRCS= libroute.c + +MAN= libroute.3 + +CFLAGS+= -I${.CURDIR} +NO_WCAST_ALIGN= yes + +.include Index: lib/libroute/libroute.h =================================================================== --- /dev/null +++ lib/libroute/libroute.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020 Ahsan Barkati + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct rt_msg_t { + struct rt_msghdr m_rtm; + char m_space[512]; +} rt_msg_t; + +typedef struct rt_handle_t rt_handle; + +rt_handle* libroute_open(int); +void libroute_close(rt_handle*); +int libroute_modify(rt_handle*, struct rt_msg_t*, struct sockaddr*, struct sockaddr*, int, int); +int libroute_add(rt_handle*, struct sockaddr*, struct sockaddr*); +int libroute_change(rt_handle*, struct sockaddr*, struct sockaddr*); +int libroute_del(rt_handle*, struct sockaddr*); +int libroute_get(rt_handle*, struct sockaddr*); +int libroute_setfib(rt_handle *, int); +int libroute_errno(rt_handle *); +struct sockaddr* str_to_sockaddr(rt_handle *h, char *); +struct sockaddr* str_to_sockaddr6(rt_handle *h, char *); + Index: lib/libroute/libroute.3 =================================================================== --- /dev/null +++ lib/libroute/libroute.3 @@ -0,0 +1,182 @@ +.\" +.\" Copyright (c) 2020 Ahsan Barkati +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 20, 2020 +.Dt LIBROUTE 3 +.Os +.Sh NAME +.Nm libroute +.Nd library for route management +.Sh LIBRARY +.Lb libroute +.Sh SYNOPSIS +.In libroute.h +.Ft rt_handle* +.Fn libroute_open "int fib" +.Ft int +.Fn libroute_setfib "rt_handle *h" "int fib" +.Ft int +.Fn libroute_modify "rt_handle *h" "struct rt_msg_t *rtmsg" "struct sockaddr* \ +sa_dest" "struct sockaddr* sa_gateway" "int operation" "int flags" +.Ft int +.Fn libroute_add "rt_handle *h" "struct sockaddr* dest" "struct sockaddr* \ +gateway" +.Ft int +.Fn libroute_change "rt_handle *h" "struct sockaddr* dest" "struct sockaddr* \ +gateway" +.Ft int +.Fn libroute_delete "rt_handle *h" "struct sockaddr* dest" +.Ft int +.Fn libroute_get "rt_handle *h" "struct sockaddr* dest" +.Ft int +.Fn libroute_errno "rt_handle *h" +.Ft void +.Fn libroute_close "rt_handle *h" +.Sh DESCRIPTION +The +.Nm libroute 3 +provides various APIs for configuration and management of routes. +It provides the user a handle which can be configured for particular FIB. +All the operations are carried out by making use of this handle. +.Pp +The +.Fn libroute_open +is the function for the initialization of the handle. +Its argument +.Fa fib +is an integer value which specifies the FIB number on which the handle will operate. +This function opens a socket of domain PF_ROUTE and type SOCK_RAW. +It also sets the socket option with the specified FIB number and returns the handle structure. +.Pp +The +.Fn libroute_setfib +function provides with a method to specify the FIB number for the handle +.Fa h . +It sets the FIB in the handle as specified by the +.Fa fib +argument. +It is useful for changing the FIB of the handle at any required point of time. +.Pp +The +.Fn libroute_modify +function is the primary function which is responsible for the modification made in the FIB table. +The kind of operation is specified by the integer value, +.Fa operation . +This function forms the route message for the given +.Fa dest , +.Fa gateway +and +.Fa flags +and uses the write() syscall to write the message to the socket. +This function is also resonsible for reading from the kernel for the get operation. +The message is read in the +.Fa rtmsg +structure +.Pp +The +.Fn libroute_add , +.Fn libroute_change +and the +.Fn libroute_delete +function are used to add a new route, change and existing route and delete a route respectively. +The +.Fa dest +and +.Fa gateway +are the sockaddr structures for the destination and the gateway for the route. +.Pp +The +.Fn libroute_get +reads the route for the given +.Fa dest +from the kernel. +The message is read in the +.Fa rtmsg +structure. [Work in Progress] It is planned that this function will return the +response in the form of a structure. +.Pp +The +.Fn libroute_errno +function returns the error number, from the given handle +.Fa h , +if any. +.Pp +The +.Fn libroute_close +function is used to close the handle session. +It frees the memory held by the handle structure. +.Sh RETURN VALUES +The +.Fn libroute_open +returns the rt_handle structure. +.Fn libroute_modify , +.Fn libroute_add , +.Fn libroute_change , +.Fn libroute_delete , +and +.Fn libroute_setfib , +returns 0 for a successful execution and -1 for any error. +If the return value is -1, then the corresponding error code can be accessed using +.Fn libroute_errno . +The return value of +.Fn libroute_errno +is an integer value, representing the error code. +.Pp +.Sh EXAMPLES +The following example shows how to add a new route using libroute: +.Bd -literal +#include + +rt_handle *handle; +struct sockaddr *sa_dest, *sa_gateway; +int error; + +handle = libroute_open(0); + +if (handle == NULL) + err(1, "libroute_open failed"); + +sa_dest = str_to_sockaddr("192.168.2.2"); +sa_gateway = str_to_sockaddr("192.168.2.6"); + +error = libroute_add(handle, sa_dest, sa_gateway); +if(error == -1 ){ + err(1, "Failed to add route); +} + +libroute_close(handle); +.Ed +.Pp +The following example shows how to delete an existing route: +.Bd -literal + +error = libroute_delete(handle, sa_dest); +if(error == -1 ){ + err(1, "Failed to delete route); +} +.Ed +.Pp + Index: lib/libroute/libroute.c =================================================================== --- /dev/null +++ lib/libroute/libroute.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2020 Ahsan Barkati + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include "libroute.h" + +static void fill_rtmsg(rt_handle*, struct rt_msg_t*, int, int); +static void fillso(rt_handle *, int, struct sockaddr*); + +struct rt_handle_t { + int fib; + int s; + struct sockaddr_storage so[RTAX_MAX]; + int rtm_addrs; + int errcode; +}; + +rt_handle * +libroute_open(int fib) +{ + rt_handle *h; + h = calloc(1, sizeof(*h)); + if (h == NULL) { + h->errcode = errno; + return NULL; + } + h->s = socket(PF_ROUTE, SOCK_RAW, 0); + if (h->s == -1){ + h->errcode = errno; + } + if (libroute_setfib(h, fib)) { + h->errcode = errno; + } + if (h->errcode) { + free(h); + return (NULL); + } + return (h); +} + +void libroute_close(rt_handle *h) +{ + free(h); +} + + +int +libroute_errno(rt_handle *h) +{ + return (h->errcode); +} + + +int +libroute_setfib(rt_handle *h, int fib) +{ + h->fib = fib; + if (setsockopt(h->s, SOL_SOCKET, SO_SETFIB, (void *)&(h->fib), + sizeof(h->fib)) == -1) { + h->errcode = errno; + return (-1); + } + return (0); +} + +struct sockaddr* +str_to_sockaddr(rt_handle *h, char *str) +{ + struct sockaddr* sa; + struct sockaddr_in *sin; + sa = calloc(1, sizeof(*sa)); + if (sa == NULL) { + h->errcode = errno; + return (NULL); + } + + sa->sa_family = AF_INET; + sa->sa_len = sizeof(struct sockaddr_in); + sin = (struct sockaddr_in *)(void *)sa; + if (inet_aton(str, &sin->sin_addr) == 0) { + free(sa); + return (NULL); + } + return (sa); +} + +struct sockaddr* +str_to_sockaddr6(rt_handle *h, char *str) +{ + struct sockaddr* sa; + struct addrinfo hints, *res; + + sa = calloc(1, sizeof(*sa)); + if (sa == NULL) { + h->errcode = errno; + return (NULL); + } + sa->sa_family = AF_INET6; + sa->sa_len = sizeof(struct sockaddr_in6); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = sa->sa_family; + hints.ai_socktype = SOCK_DGRAM; + if (getaddrinfo(str, NULL, &hints, &res)) { + free(sa); + return (NULL); + } + memcpy(sa, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + return (sa); +} + +static void +fillso(rt_handle *h, int idx, struct sockaddr* sa_in) +{ + struct sockaddr *sa; + h->rtm_addrs |= (1 << idx); + sa = (struct sockaddr *)&(h->so[idx]); + memcpy(sa, sa_in, sa_in->sa_len); + return; +} + +int +libroute_modify(rt_handle *h, struct rt_msg_t *rtmsg, struct sockaddr* sa_dest, + struct sockaddr* sa_gateway, int operation, int flags) +{ + int result, len; + fillso(h, RTAX_DST, sa_dest); + + if (sa_gateway != NULL) { + fillso(h, RTAX_GATEWAY, sa_gateway); + } + + if (operation == RTM_GET) { + if (h->so[RTAX_IFP].ss_family == 0) { + h->so[RTAX_IFP].ss_family = AF_LINK; + h->so[RTAX_IFP].ss_len = sizeof(struct sockaddr_dl); + h->rtm_addrs |= RTA_IFP; + } + } + + fill_rtmsg(h, rtmsg, operation, flags); + len = (rtmsg->m_rtm).rtm_msglen; + + if ((result = write(h->s, (char *)rtmsg, len)) < 0) { + h->errcode = errno; + return (-1); + } + + if (operation == RTM_GET) { + if (( result = read(h->s, (char *)rtmsg, sizeof(*rtmsg))) < 0 ) { + h->errcode = errno; + return (-1); + } + } + + return (0); +} + +int +libroute_add(rt_handle *h, struct sockaddr* dest, struct sockaddr* gateway){ + struct rt_msg_t rtmsg; + int flags; + + memset(&rtmsg, 0, sizeof(struct rt_msg_t)); + flags = RTF_STATIC; + flags |= RTF_UP; + flags |= RTF_HOST; + flags |= RTF_GATEWAY; + + return (libroute_modify(h, &rtmsg, dest, gateway, RTM_ADD, flags)); +} + +int +libroute_change(rt_handle *h, struct sockaddr* dest, struct sockaddr* gateway){ + struct rt_msg_t rtmsg; + int flags; + + memset(&rtmsg, 0, sizeof(struct rt_msg_t)); + flags = RTF_STATIC; + flags |= RTF_UP; + flags |= RTF_HOST; + flags |= RTF_GATEWAY; + + return (libroute_modify(h, &rtmsg, dest, gateway, RTM_CHANGE, flags)); +} + +int +libroute_del(rt_handle *h, struct sockaddr* dest){ + struct rt_msg_t rtmsg; + int flags; + + memset(&rtmsg, 0, sizeof(struct rt_msg_t)); + flags = RTF_STATIC; + flags |= RTF_UP; + flags |= RTF_HOST; + flags |= RTF_GATEWAY; + return (libroute_modify(h, &rtmsg, dest, NULL, RTM_DELETE, flags)); +} + +int +libroute_get(rt_handle *h, struct sockaddr* dest){ + struct rt_msg_t rtmsg; + int flags; + + memset(&rtmsg, 0, sizeof(struct rt_msg_t)); + flags = RTF_STATIC; + flags |= RTF_UP; + flags |= RTF_HOST; + return (libroute_modify(h, &rtmsg, dest, NULL, RTM_GET, flags)); +} + +static void +fill_rtmsg(rt_handle *h, struct rt_msg_t *routemsg, int operation, int flags) +{ + rt_msg_t *rtmsg = routemsg; + char *cp = rtmsg->m_space; + int l, rtm_seq = 0; + struct sockaddr_storage *so = h->so; + static struct rt_metrics rt_metrics; + static u_long rtm_inits; + + memset(rtmsg, 0, sizeof(struct rt_msg_t)); + +#define NEXTADDR(w, u) \ + if ((h->rtm_addrs) & (w)) { \ + l = SA_SIZE(&(u)); \ + memmove(cp, (char *)&(u), l); \ + cp += l; \ + } + +#define rtm rtmsg->m_rtm + rtm.rtm_type = operation; + rtm.rtm_flags = flags; + rtm.rtm_version = RTM_VERSION; + rtm.rtm_seq = ++rtm_seq; + rtm.rtm_addrs = h->rtm_addrs; + rtm.rtm_rmx = rt_metrics; + rtm.rtm_inits = rtm_inits; + + NEXTADDR(RTA_DST, so[RTAX_DST]); + NEXTADDR(RTA_GATEWAY, so[RTAX_GATEWAY]); + NEXTADDR(RTA_NETMASK, so[RTAX_NETMASK]); + NEXTADDR(RTA_GENMASK, so[RTAX_GENMASK]); + NEXTADDR(RTA_IFP, so[RTAX_IFP]); + NEXTADDR(RTA_IFA, so[RTAX_IFA]); + rtm.rtm_msglen = l = cp - (char *)rtmsg; +#undef rtm + return; +} \ No newline at end of file Index: rescue/rescue/Makefile =================================================================== --- rescue/rescue/Makefile +++ rescue/rescue/Makefile @@ -227,6 +227,9 @@ CRUNCH_LIBS+= ${OBJTOP}/lib/libifconfig/libifconfig.a CRUNCH_BUILDOPTS+= CRUNCH_CFLAGS+=-I${OBJTOP}/lib/libifconfig +CRUNCH_LIBS+= ${OBJTOP}/lib/libroute/libroute.a +CRUNCH_BUILDOPTS+= CRUNCH_CFLAGS+=-I${OBJTOP}/lib/libroute + .if ${MK_ISCSI} != "no" CRUNCH_PROGS_usr.bin+= iscsictl CRUNCH_PROGS_usr.sbin+= iscsid Index: sbin/route/Makefile =================================================================== --- sbin/route/Makefile +++ sbin/route/Makefile @@ -10,6 +10,9 @@ WARNS?= 3 CLEANFILES+=keywords.h +CFLAGS+= -I${SRCTOP}/lib/libroute +LIBADD+= route + CFLAGS+= -DNS .if ${MK_INET_SUPPORT} != "no" CFLAGS+= -DINET Index: sbin/route/route.c =================================================================== --- sbin/route/route.c +++ sbin/route/route.c @@ -73,6 +73,7 @@ #include #include #include +#include struct fibl { TAILQ_ENTRY(fibl) fl_next; @@ -103,15 +104,9 @@ static int numfibs; static char domain[MAXHOSTNAMELEN + 1]; static bool domain_initialized; -static int rtm_seq; static char rt_line[NI_MAXHOST]; static char net_line[MAXHOSTNAMELEN + 1]; -static struct { - struct rt_msghdr m_rtm; - char m_space[512]; -} m_rtmsg; - static TAILQ_HEAD(fibl_head_t, fibl) fibl_head; static void printb(int, const char *); @@ -130,14 +125,12 @@ static void monitor(int, char*[]); static const char *netname(struct sockaddr *); static void newroute(int, char **); -static int newroute_fib(int, char *, int); static void pmsg_addrs(char *, int, size_t); static void pmsg_common(struct rt_msghdr *, size_t); static int prefixlen(const char *); static void print_getmsg(struct rt_msghdr *, int, int); static void print_rtmsg(struct rt_msghdr *, size_t); static const char *routename(struct sockaddr *); -static int rtmsg(int, int, int); static void set_metric(char *, int); static int set_sofib(int); static void sockaddr(char *, struct sockaddr *, size_t); @@ -790,6 +783,9 @@ static void newroute(int argc, char **argv) { + rt_handle *h; + struct rt_msg_t rtmsg_local; + int operation; struct sigaction sa; struct hostent *hp; struct fibl *fl; @@ -1009,13 +1005,37 @@ if (error) errx(EX_OSERR, "fiboptlist_csv failed."); } + + + if (cmd[0] == 'a') + operation = RTM_ADD; + else if (cmd[0] == 'c') + operation = RTM_CHANGE; + else if (cmd[0] == 'g' || cmd[0] == 's') + operation = RTM_GET; + else + operation = RTM_DELETE; + error = 0; + h = libroute_open(defaultfib); + if(h == NULL){ + errx(EX_OSERR, "Failed to open libroute handle"); + } TAILQ_FOREACH(fl, &fibl_head, fl_next) { - fl->fl_error = newroute_fib(fl->fl_num, cmd, flags); + libroute_setfib(h, fl->fl_num); + fl->fl_error = libroute_modify(h, &rtmsg_local, + (struct sockaddr *)&so[RTAX_DST], + (struct sockaddr *)&so[RTAX_GATEWAY], operation, flags); if (fl->fl_error) fl->fl_errno = errno; error += fl->fl_error; + + if(operation == RTM_GET && fl->fl_error == 0){ + print_getmsg(&rtmsg_local.m_rtm, rtmsg_local.m_rtm.rtm_msglen, + fl->fl_num); + } } + libroute_close(h); if (*cmd == 'g' || *cmd == 's') exit(error); @@ -1096,21 +1116,6 @@ exit(error); } -static int -newroute_fib(int fib, char *cmd, int flags) -{ - int error; - - error = set_sofib(fib); - if (error) { - warn("fib number %d is ignored", fib); - return (error); - } - - error = rtmsg(*cmd, flags, fib); - return (error); -} - #ifdef INET static void inet_makenetandmask(u_long net, struct sockaddr_in *sin, @@ -1494,97 +1499,6 @@ } } -static int -rtmsg(int cmd, int flags, int fib) -{ - int rlen; - char *cp = m_rtmsg.m_space; - int l; - -#define NEXTADDR(w, u) \ - if (rtm_addrs & (w)) { \ - l = SA_SIZE(&(u)); \ - memmove(cp, (char *)&(u), l); \ - cp += l; \ - if (verbose) \ - sodump((struct sockaddr *)&(u), #w); \ - } - - errno = 0; - memset(&m_rtmsg, 0, sizeof(m_rtmsg)); - if (cmd == 'a') - cmd = RTM_ADD; - else if (cmd == 'c') - cmd = RTM_CHANGE; - else if (cmd == 'g' || cmd == 's') { - cmd = RTM_GET; - if (so[RTAX_IFP].ss_family == 0) { - so[RTAX_IFP].ss_family = AF_LINK; - so[RTAX_IFP].ss_len = sizeof(struct sockaddr_dl); - rtm_addrs |= RTA_IFP; - } - } else { - cmd = RTM_DELETE; - flags |= RTF_PINNED; - } -#define rtm m_rtmsg.m_rtm - rtm.rtm_type = cmd; - rtm.rtm_flags = flags; - rtm.rtm_version = RTM_VERSION; - rtm.rtm_seq = ++rtm_seq; - rtm.rtm_addrs = rtm_addrs; - rtm.rtm_rmx = rt_metrics; - rtm.rtm_inits = rtm_inits; - - NEXTADDR(RTA_DST, so[RTAX_DST]); - NEXTADDR(RTA_GATEWAY, so[RTAX_GATEWAY]); - NEXTADDR(RTA_NETMASK, so[RTAX_NETMASK]); - NEXTADDR(RTA_GENMASK, so[RTAX_GENMASK]); - NEXTADDR(RTA_IFP, so[RTAX_IFP]); - NEXTADDR(RTA_IFA, so[RTAX_IFA]); - rtm.rtm_msglen = l = cp - (char *)&m_rtmsg; - if (verbose) - print_rtmsg(&rtm, l); - if (debugonly) - return (0); - if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) { - switch (errno) { - case EPERM: - err(1, "writing to routing socket"); - break; - case ESRCH: - warnx("route has not been found"); - break; - case EEXIST: - /* Handled by newroute() */ - break; - default: - warn("writing to routing socket"); - } - return (-1); - } - if (cmd == RTM_GET) { - stop_read = 0; - alarm(READ_TIMEOUT); - do { - l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg)); - } while (l > 0 && stop_read == 0 && - (rtm.rtm_type != RTM_GET || rtm.rtm_seq != rtm_seq || - rtm.rtm_pid != pid)); - if (stop_read != 0) { - warnx("read from routing socket timed out"); - return (-1); - } else - alarm(0); - if (l < 0) - warn("read from routing socket"); - else - print_getmsg(&rtm, l, fib); - } -#undef rtm - return (0); -} - static const char *const msgtypes[] = { "", "RTM_ADD: Add Route", Index: share/mk/src.libnames.mk =================================================================== --- share/mk/src.libnames.mk +++ share/mk/src.libnames.mk @@ -58,6 +58,7 @@ parse \ pe \ pmcstat \ + route \ sl \ sm \ smdb \ @@ -577,6 +578,9 @@ LIBC_NOSSP_PICDIR= ${_LIB_OBJTOP}/lib/libc LIBC_NOSSP_PIC?= ${LIBC_NOSSP_PICDIR}/libc_nossp_pic.a +LIBROUTEDIR= ${_LIB_OBJTOP}/lib/libroute +LIBROUTE?= ${LIBROUTEDIR}/libroute${PIE_SUFFIX}.a + # Define a directory for each library. This is useful for adding -L in when # not using a --sysroot or for meta mode bootstrapping when there is no # Makefile.depend. These are sorted by directory.