Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

route-hpux.c

Go to the documentation of this file.
00001 /*
00002  * route-hpux.c
00003  *
00004  * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
00005  *
00006  * $Id: route-hpux.c,v 1.11 2004/01/14 04:52:11 dugsong Exp $
00007  */
00008 
00009 #include "config.h"
00010 
00011 #include <sys/types.h>
00012 #include <sys/ioctl.h>
00013 #include <sys/mib.h>
00014 #include <sys/socket.h>
00015 
00016 #include <net/route.h>
00017 
00018 #include <errno.h>
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <unistd.h>
00023 
00024 #include "dnet.h"
00025 
00026 #define ADDR_ISHOST(a)  (((a)->addr_type == ADDR_TYPE_IP &&     \
00027                           (a)->addr_bits == IP_ADDR_BITS) ||    \
00028                          ((a)->addr_type == ADDR_TYPE_IP6 &&    \
00029                           (a)->addr_bits == IP6_ADDR_BITS))
00030 
00031 struct route_handle {
00032         int     fd;
00033 };
00034 
00035 route_t *
00036 route_open(void)
00037 {
00038         route_t *r;
00039 
00040         if ((r = calloc(1, sizeof(*r))) != NULL) {
00041                 if ((r->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
00042                         return (route_close(r));
00043         }
00044         return (r);
00045 }
00046 
00047 int
00048 route_add(route_t *r, const struct route_entry *entry)
00049 {
00050         struct rtentry rt;
00051         struct addr dst;
00052         
00053         memset(&rt, 0, sizeof(rt));
00054         rt.rt_flags = RTF_UP | RTF_GATEWAY;
00055 
00056         if (ADDR_ISHOST(&entry->route_dst)) {
00057                 rt.rt_flags |= RTF_HOST;
00058                 memcpy(&dst, &entry->route_dst, sizeof(dst));
00059         } else
00060                 addr_net(&entry->route_dst, &dst);
00061 
00062         if (addr_ntos(&dst, &rt.rt_dst) < 0 ||
00063             addr_ntos(&entry->route_gw, &rt.rt_gateway) < 0 ||
00064             addr_btom(entry->route_dst.addr_bits, &rt.rt_subnetmask,
00065                 IP_ADDR_LEN) < 0)
00066                 return (-1);
00067         
00068         return (ioctl(r->fd, SIOCADDRT, &rt));
00069 }
00070 
00071 int
00072 route_delete(route_t *r, const struct route_entry *entry)
00073 {
00074         struct rtentry rt;
00075         struct addr dst;
00076 
00077         memset(&rt, 0, sizeof(rt));
00078         rt.rt_flags = RTF_UP;
00079         
00080         if (ADDR_ISHOST(&entry->route_dst)) {
00081                 rt.rt_flags |= RTF_HOST;
00082                 memcpy(&dst, &entry->route_dst, sizeof(dst));
00083         } else
00084                 addr_net(&entry->route_dst, &dst);
00085         
00086         if (addr_ntos(&dst, &rt.rt_dst) < 0 ||
00087             addr_btom(entry->route_dst.addr_bits, &rt.rt_subnetmask,
00088                 IP_ADDR_LEN) < 0)
00089                 return (-1);
00090         
00091         return (ioctl(r->fd, SIOCDELRT, &rt));
00092 }
00093 
00094 int
00095 route_get(route_t *r, struct route_entry *entry)
00096 {
00097         struct rtreq rtr;
00098 
00099         memset(&rtr, 0, sizeof(rtr));
00100 
00101         /* XXX - gross hack for default route */
00102         if (entry->route_dst.addr_ip == IP_ADDR_ANY) {
00103                 rtr.rtr_destaddr = htonl(0x60060606);
00104                 rtr.rtr_subnetmask = 0xffffffff;
00105         } else {
00106                 memcpy(&rtr.rtr_destaddr, &entry->route_dst.addr_ip,
00107                     IP_ADDR_LEN);
00108                 if (entry->route_dst.addr_bits < IP_ADDR_BITS)
00109                         addr_btom(entry->route_dst.addr_bits,
00110                             &rtr.rtr_subnetmask, IP_ADDR_LEN);
00111         }
00112         if (ioctl(r->fd, SIOCGRTENTRY, &rtr) < 0)
00113                 return (-1);
00114 
00115         if (rtr.rtr_gwayaddr == 0) {
00116                 errno = ESRCH;
00117                 return (-1);
00118         }
00119         entry->route_gw.addr_type = ADDR_TYPE_IP;
00120         entry->route_gw.addr_bits = IP_ADDR_BITS;
00121         memcpy(&entry->route_gw.addr_ip, &rtr.rtr_gwayaddr, IP_ADDR_LEN);
00122         
00123         return (0);
00124 }
00125 
00126 #define MAX_RTENTRIES   256     /* XXX */
00127 
00128 int
00129 route_loop(route_t *r, route_handler callback, void *arg)
00130 {
00131         struct nmparms nm;
00132         struct route_entry entry;
00133         mib_ipRouteEnt rtentries[MAX_RTENTRIES];
00134         int fd, i, n, ret;
00135         
00136         if ((fd = open_mib("/dev/ip", O_RDWR, 0 /* XXX */, 0)) < 0)
00137                 return (-1);
00138         
00139         nm.objid = ID_ipRouteTable;
00140         nm.buffer = rtentries;
00141         n = sizeof(rtentries);
00142         nm.len = &n;
00143         
00144         if (get_mib_info(fd, &nm) < 0) {
00145                 close_mib(fd);
00146                 return (-1);
00147         }
00148         close_mib(fd);
00149 
00150         entry.route_dst.addr_type = entry.route_gw.addr_type = ADDR_TYPE_IP;
00151         entry.route_dst.addr_bits = entry.route_gw.addr_bits = IP_ADDR_BITS;
00152         n /= sizeof(*rtentries);
00153         ret = 0;
00154         
00155         for (i = 0; i < n; i++) {
00156                 if (rtentries[i].Type != NMDIRECT &&
00157                     rtentries[i].Type != NMREMOTE)
00158                         continue;
00159                 
00160                 entry.route_dst.addr_ip = rtentries[i].Dest;
00161                 addr_mtob(&rtentries[i].Mask, IP_ADDR_LEN,
00162                     &entry.route_dst.addr_bits);
00163                 entry.route_gw.addr_ip = rtentries[i].NextHop;
00164 
00165                 if ((ret = callback(&entry, arg)) != 0)
00166                         break;
00167         }
00168         return (ret);
00169 }
00170 
00171 route_t *
00172 route_close(route_t *r)
00173 {
00174         if (r != NULL) {
00175                 if (r->fd >= 0)
00176                         close(r->fd);
00177                 free(r);
00178         }
00179         return (NULL);
00180 }

Generated on Sun May 14 14:51:12 2006 by  doxygen 1.4.2