summaryrefslogtreecommitdiffstats
path: root/libdnet-stripped/src/route-hpux.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdnet-stripped/src/route-hpux.c')
-rw-r--r--libdnet-stripped/src/route-hpux.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/libdnet-stripped/src/route-hpux.c b/libdnet-stripped/src/route-hpux.c
new file mode 100644
index 0000000..07e7f8c
--- /dev/null
+++ b/libdnet-stripped/src/route-hpux.c
@@ -0,0 +1,184 @@
+/*
+ * route-hpux.c
+ *
+ * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
+ *
+ * $Id: route-hpux.c 483 2004-01-14 04:52:11Z dugsong $
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/mib.h>
+#include <sys/socket.h>
+
+#include <net/route.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "dnet.h"
+
+#define ADDR_ISHOST(a) (((a)->addr_type == ADDR_TYPE_IP && \
+ (a)->addr_bits == IP_ADDR_BITS) || \
+ ((a)->addr_type == ADDR_TYPE_IP6 && \
+ (a)->addr_bits == IP6_ADDR_BITS))
+
+struct route_handle {
+ int fd;
+};
+
+route_t *
+route_open(void)
+{
+ route_t *r;
+
+ if ((r = calloc(1, sizeof(*r))) != NULL) {
+ if ((r->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ return (route_close(r));
+ }
+ return (r);
+}
+
+int
+route_add(route_t *r, const struct route_entry *entry)
+{
+ struct rtentry rt;
+ struct addr dst;
+
+ memset(&rt, 0, sizeof(rt));
+ rt.rt_flags = RTF_UP | RTF_GATEWAY;
+
+ if (ADDR_ISHOST(&entry->route_dst)) {
+ rt.rt_flags |= RTF_HOST;
+ memcpy(&dst, &entry->route_dst, sizeof(dst));
+ } else
+ addr_net(&entry->route_dst, &dst);
+
+ if (addr_ntos(&dst, &rt.rt_dst) < 0 ||
+ addr_ntos(&entry->route_gw, &rt.rt_gateway) < 0 ||
+ addr_btom(entry->route_dst.addr_bits, &rt.rt_subnetmask,
+ IP_ADDR_LEN) < 0)
+ return (-1);
+
+ return (ioctl(r->fd, SIOCADDRT, &rt));
+}
+
+int
+route_delete(route_t *r, const struct route_entry *entry)
+{
+ struct rtentry rt;
+ struct addr dst;
+
+ memset(&rt, 0, sizeof(rt));
+ rt.rt_flags = RTF_UP;
+
+ if (ADDR_ISHOST(&entry->route_dst)) {
+ rt.rt_flags |= RTF_HOST;
+ memcpy(&dst, &entry->route_dst, sizeof(dst));
+ } else
+ addr_net(&entry->route_dst, &dst);
+
+ if (addr_ntos(&dst, &rt.rt_dst) < 0 ||
+ addr_btom(entry->route_dst.addr_bits, &rt.rt_subnetmask,
+ IP_ADDR_LEN) < 0)
+ return (-1);
+
+ return (ioctl(r->fd, SIOCDELRT, &rt));
+}
+
+int
+route_get(route_t *r, struct route_entry *entry)
+{
+ struct rtreq rtr;
+
+ memset(&rtr, 0, sizeof(rtr));
+
+ /* XXX - gross hack for default route */
+ if (entry->route_dst.addr_ip == IP_ADDR_ANY) {
+ rtr.rtr_destaddr = htonl(0x60060606);
+ rtr.rtr_subnetmask = 0xffffffff;
+ } else {
+ memcpy(&rtr.rtr_destaddr, &entry->route_dst.addr_ip,
+ IP_ADDR_LEN);
+ if (entry->route_dst.addr_bits < IP_ADDR_BITS)
+ addr_btom(entry->route_dst.addr_bits,
+ &rtr.rtr_subnetmask, IP_ADDR_LEN);
+ }
+ if (ioctl(r->fd, SIOCGRTENTRY, &rtr) < 0)
+ return (-1);
+
+ if (rtr.rtr_gwayaddr == 0) {
+ errno = ESRCH;
+ return (-1);
+ }
+ entry->intf_name[0] = '\0';
+ entry->route_gw.addr_type = ADDR_TYPE_IP;
+ entry->route_gw.addr_bits = IP_ADDR_BITS;
+ memcpy(&entry->route_gw.addr_ip, &rtr.rtr_gwayaddr, IP_ADDR_LEN);
+ entry->metric = 0;
+
+ return (0);
+}
+
+#define MAX_RTENTRIES 256 /* XXX */
+
+int
+route_loop(route_t *r, route_handler callback, void *arg)
+{
+ struct nmparms nm;
+ struct route_entry entry;
+ mib_ipRouteEnt rtentries[MAX_RTENTRIES];
+ int fd, i, n, ret;
+
+ if ((fd = open_mib("/dev/ip", O_RDWR, 0 /* XXX */, 0)) < 0)
+ return (-1);
+
+ nm.objid = ID_ipRouteTable;
+ nm.buffer = rtentries;
+ n = sizeof(rtentries);
+ nm.len = &n;
+
+ if (get_mib_info(fd, &nm) < 0) {
+ close_mib(fd);
+ return (-1);
+ }
+ close_mib(fd);
+
+ n /= sizeof(*rtentries);
+ ret = 0;
+
+ for (i = 0; i < n; i++) {
+ if (rtentries[i].Type != NMDIRECT &&
+ rtentries[i].Type != NMREMOTE)
+ continue;
+
+ entry.intf_name[0] = '\0';
+ entry.route_dst.addr_type = entry.route_gw.addr_type = ADDR_TYPE_IP;
+ entry.route_dst.addr_bits = entry.route_gw.addr_bits = IP_ADDR_BITS;
+ entry.route_dst.addr_ip = rtentries[i].Dest;
+ addr_mtob(&rtentries[i].Mask, IP_ADDR_LEN,
+ &entry.route_dst.addr_bits);
+ entry.route_gw.addr_ip = rtentries[i].NextHop;
+ entry.metric = 0;
+
+ if ((ret = callback(&entry, arg)) != 0)
+ break;
+ }
+ return (ret);
+}
+
+route_t *
+route_close(route_t *r)
+{
+ if (r != NULL) {
+ if (r->fd >= 0)
+ close(r->fd);
+ free(r);
+ }
+ return (NULL);
+}