+struct ifaddr *
+ifa_ifwithroute(flags, dst, gateway)
+int flags;
+struct sockaddr *dst, *gateway;
+{
+ struct ifaddr *ifa;
+ if ((flags & RTF_GATEWAY) == 0) {
+ /*
+ * If we are adding a route to an interface,
+ * and the interface is a pt to pt link
+ * we should search for the destination
+ * as our clue to the interface. Otherwise
+ * we can use the local address.
+ */
+ ifa = 0;
+ if (flags & RTF_HOST)
+ ifa = ifa_ifwithdstaddr(dst);
+ if (ifa == 0)
+ ifa = ifa_ifwithaddr(gateway);
+ } else {
+ /*
+ * If we are adding a route to a remote net
+ * or host, the gateway may still be on the
+ * other end of a pt to pt link.
+ */
+ ifa = ifa_ifwithdstaddr(gateway);
+ }
+ if (ifa == 0)
+ ifa = ifa_ifwithnet(gateway);
+ return (ifa);
+}
+
+#define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
+
+rtrequest(req, dst, gateway, netmask, flags, ret_nrt)
+ int req, flags;
+ struct sockaddr *dst, *gateway, *netmask;
+ struct rtentry **ret_nrt;
+{
+ int s = splnet(), len, error = 0;
+ register struct rtentry *rt;
+ register struct radix_node *rn;
+ register struct radix_node_head *rnh;
+ struct ifaddr *ifa, *ifa_ifwithdstaddr();
+ struct sockaddr *ndst;
+ u_char af = dst->sa_family;
+#define senderr(x) { error = x ; goto bad; }
+
+ if (rtinits_done == 0)
+ rtinitheads();
+ for (rnh = radix_node_head; rnh && (af != rnh->rnh_af); )
+ rnh = rnh->rnh_next;
+ if (rnh == 0)
+ senderr(ESRCH);
+ if (flags & RTF_HOST)
+ netmask = 0;
+ switch (req) {
+ case RTM_DELETE:
+ if (ret_nrt && (rt = *ret_nrt)) {
+ RTFREE(rt);
+ *ret_nrt = 0;
+ }
+ if ((rn = rn_delete((caddr_t)dst, (caddr_t)netmask,
+ rnh->rnh_treetop)) == 0)
+ senderr(ESRCH);
+ if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
+ panic ("rtrequest delete");
+ rt = (struct rtentry *)rn;