Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F166305344
D26078.id75852.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D26078.id75852.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D26078: Add libroute and basic librarification of route utility
Attached
Detach File
Event Timeline
Log In to Comment