Page MenuHomeFreeBSD

D26078.id75852.diff
No OneTemporary

D26078.id75852.diff

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,20 @@
+# $FreeBSD$
+
+PACKAGE= lib${LIB}
+LIB= route
+INTERNALLIB= true
+
+SHLIBDIR?= /lib
+SHLIB_MAJOR= 1
+SRCS= libroute.c
+
+# If libroute become public uncomment those two lines
+#INCSDIR= ${INCLUDEDIR}
+#INCS= libroute.h
+
+#MAN= libroute.3
+
+CFLAGS+= -I${.CURDIR}
+NO_WCAST_ALIGN= yes
+
+.include <bsd.lib.mk>
Index: lib/libroute/Makefile.depend
===================================================================
--- /dev/null
+++ lib/libroute/Makefile.depend
@@ -0,0 +1,13 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+ include \
+ include/xlocale \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
Index: lib/libroute/libroute.h
===================================================================
--- /dev/null
+++ lib/libroute/libroute.h
@@ -0,0 +1,73 @@
+/*
+ * 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 <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/if_dl.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <ctype.h>
+#include <paths.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ifaddrs.h>
+
+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_fillso(rt_handle *h, int, struct sockaddr*);
+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*);
+struct sockaddr* str_to_sockaddr(char *);
+void libroute_setfib(rt_handle *, int);
+
+void fill_rtmsg(rt_handle*, struct rt_msg_t*, int, int);
+
+struct sockaddr* str_to_sockaddr6(char *);
+
Index: lib/libroute/libroute.c
===================================================================
--- /dev/null
+++ lib/libroute/libroute.c
@@ -0,0 +1,235 @@
+/*
+ * 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 "libroute.h"
+
+struct rt_handle_t {
+ int fib;
+ int s;
+ struct sockaddr_storage so[RTAX_MAX];
+ int rtm_addrs;
+};
+
+rt_handle *
+libroute_open(int fib)
+{
+ rt_handle *h;
+ h = calloc(1, sizeof(*h));
+
+ if (h == NULL)
+ return (NULL);
+
+ h->fib = fib;
+ h->s = socket(PF_ROUTE, SOCK_RAW, 0);
+ setsockopt(h->s, SOL_SOCKET, SO_SETFIB, (void *)&(h->fib),sizeof(h->fib));
+
+ return (h);
+}
+
+void
+libroute_setfib(rt_handle *h, int fib)
+{
+ h->fib = fib;
+}
+
+struct sockaddr*
+str_to_sockaddr(char * str)
+{
+ struct sockaddr* sa;
+ struct sockaddr_in *sin;
+ sa = calloc(1, sizeof(*sa));
+
+ sa->sa_family = AF_INET;
+ sa->sa_len = sizeof(struct sockaddr_in);
+ sin = (struct sockaddr_in *)(void *)sa;
+ inet_aton(str, &sin->sin_addr);
+ return sa;
+}
+
+struct sockaddr*
+str_to_sockaddr6(char *str)
+{
+ struct sockaddr* sa;
+ struct addrinfo hints, *res;
+ int ecode;
+
+ sa = calloc(1, sizeof(*sa));
+ 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;
+ ecode = getaddrinfo(str, NULL, &hints, &res);
+
+ memcpy(sa, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+
+ return sa;
+}
+
+void
+libroute_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 rlen, l;
+ libroute_fillso(h, RTAX_DST, sa_dest);
+
+ if(sa_gateway != NULL){
+ libroute_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);
+ l = (rtmsg->m_rtm).rtm_msglen;
+
+ if((rlen = write(h->s, (char *)rtmsg, l)) < 0){
+ return 1;
+ }
+
+ if (operation == RTM_GET) {
+ l = read(h->s, (char *)rtmsg, sizeof(*rtmsg));
+ }
+ return 0;
+}
+
+int
+libroute_add(rt_handle *h, struct sockaddr* dest, struct sockaddr* gateway){
+ struct rt_msg_t rtmsg;
+ memset(&rtmsg, 0, sizeof(struct rt_msg_t));
+ int flags;
+
+ // we need to handle flags according to the operation
+ flags = RTF_STATIC;
+ flags |= RTF_UP;
+ flags |= RTF_HOST;
+ flags |= RTF_GATEWAY;
+
+ int error = libroute_modify(h, &rtmsg, dest, gateway, RTM_ADD, flags);
+ return error;
+}
+
+int
+libroute_change(rt_handle *h, struct sockaddr* dest, struct sockaddr* gateway){
+ struct rt_msg_t rtmsg;
+ memset(&rtmsg, 0, sizeof(struct rt_msg_t));
+ int flags;
+
+ // we need to handle flags according to the operation
+ flags = RTF_STATIC;
+ flags |= RTF_UP;
+ flags |= RTF_HOST;
+ flags |= RTF_GATEWAY;
+
+ int error = libroute_modify(h, &rtmsg, dest, gateway, RTM_CHANGE, flags);
+ return error;
+}
+
+int
+libroute_del(rt_handle *h, struct sockaddr* dest){
+ struct rt_msg_t rtmsg;
+ memset(&rtmsg, 0, sizeof(struct rt_msg_t));
+ int flags;
+
+ // we need to handle flags according to the operation
+ flags = RTF_STATIC;
+ flags |= RTF_UP;
+ flags |= RTF_HOST;
+ flags |= RTF_GATEWAY;
+ flags |= RTF_PINNED;
+ int error = libroute_modify(h, &rtmsg, dest, NULL, RTM_DELETE, flags);
+ return error;
+}
+
+int
+libroute_get(rt_handle *h, struct sockaddr* dest){
+ struct rt_msg_t rtmsg;
+ memset(&rtmsg, 0, sizeof(struct rt_msg_t));
+ int flags;
+
+ // we need to handle flags according to the operation
+ flags = RTF_STATIC;
+ flags |= RTF_UP;
+ flags |= RTF_HOST;
+ int error = libroute_modify(h, &rtmsg, dest, NULL, RTM_GET, flags);
+ return error;
+}
+
+void
+fill_rtmsg(rt_handle *h, struct rt_msg_t *rtmsg_t, int operation, int flags)
+{
+ rt_msg_t* rtmsg = rtmsg_t;
+ 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: 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 <time.h>
#include <unistd.h>
#include <ifaddrs.h>
+#include <libroute.h>
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,10 @@
static void
newroute(int argc, char **argv)
{
+ rt_handle *h = libroute_open(defaultfib);
+ struct rt_msg_t rtmsg_local;
+ int operation;
+
struct sigaction sa;
struct hostent *hp;
struct fibl *fl;
@@ -1009,12 +1006,28 @@
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;
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);
+ }
}
if (*cmd == 'g' || *cmd == 's')
exit(error);
@@ -1096,21 +1109,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 +1492,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 \
@@ -576,6 +577,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.

File Metadata

Mime Type
text/plain
Expires
Thu, Aug 13, 7:12 PM (2 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36675100
Default Alt Text
D26078.id75852.diff (15 KB)

Event Timeline