summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1998-06-12 03:48:19 +0000
committerjulian <julian@FreeBSD.org>1998-06-12 03:48:19 +0000
commit1ee51dd89f8fa0c587541ec9a5d0e0a307a1319e (patch)
tree3dce44767d7ec68b96b40dff02a52db6b71dbeb0 /sys/net
parenteaeb937aa0099bbc5920c2a03369e096418c7518 (diff)
downloadFreeBSD-src-1ee51dd89f8fa0c587541ec9a5d0e0a307a1319e.zip
FreeBSD-src-1ee51dd89f8fa0c587541ec9a5d0e0a307a1319e.tar.gz
Go through the loopback code with a broom..
Remove lots'o'hacks. looutput is now static. Other callers who want to use loopback to allow shortcutting should call the special entrypoint for this, if_simloop(), which is specifically designed for this purpose. Using looutput for this purpose was problematic, particularly with bpf and trying to keep track of whether one should be using the charateristics of the loopback interface or the interface (e.g. if_ethersubr.c) that was requesting the loopback. There was a whole class of errors due to this mis-use each of which had hacks to cover them up. Consists largly of hack removal :-)
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_ethersubr.c132
-rw-r--r--sys/net/if_fddisubr.c90
-rw-r--r--sys/net/if_loop.c89
-rw-r--r--sys/net/if_var.h6
4 files changed, 130 insertions, 187 deletions
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index d5fba1b..4e440cf 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93
- * $Id: if_ethersubr.c,v 1.47 1998/03/30 09:51:39 phk Exp $
+ * $Id: if_ethersubr.c,v 1.48 1998/05/19 14:04:02 dg Exp $
*/
#include "opt_atalk.h"
@@ -130,13 +130,9 @@ ether_output(ifp, m0, dst, rt0)
u_char edst[6];
register struct mbuf *m = m0;
register struct rtentry *rt;
- struct mbuf *mcopy = (struct mbuf *)0;
register struct ether_header *eh;
- int off, len = m->m_pkthdr.len;
+ int off, len = m->m_pkthdr.len, loop_copy = 0;
struct arpcom *ac = (struct arpcom *)ifp;
-#ifdef NETATALK
- struct at_ifaddr *aa;
-#endif NETATALK
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
senderr(ENETDOWN);
@@ -166,86 +162,33 @@ ether_output(ifp, m0, dst, rt0)
senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
}
switch (dst->sa_family) {
-
#ifdef INET
case AF_INET:
if (!arpresolve(ac, rt, m, dst, edst, rt0))
return (0); /* if not yet resolved */
- /* If broadcasting on a simplex interface, loopback a copy */
- if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
- mcopy = m_copy(m, 0, (int)M_COPYALL);
off = m->m_pkthdr.len - m->m_len;
type = htons(ETHERTYPE_IP);
break;
#endif
#ifdef IPX
case AF_IPX:
- {
- struct ifaddr *ia;
-
type = htons(ETHERTYPE_IPX);
bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host),
(caddr_t)edst, sizeof (edst));
-
- for(ia = ifp->if_addrhead.tqh_first; ia != 0;
- ia = ia->ifa_link.tqe_next) {
- if(ia->ifa_addr->sa_family == AF_IPX &&
- !bcmp((caddr_t)edst,
- (caddr_t)&((struct ipx_ifaddr *)ia)->ia_addr.sipx_addr.x_host,
- sizeof(edst)) )
- return (looutput(ifp, m, dst, rt));
- }
-
- /* If broadcasting on a simplex interface, loopback a copy */
- if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
- mcopy = m_copy(m, 0, (int)M_COPYALL);
break;
- }
#endif
#ifdef NETATALK
case AF_APPLETALK:
- {
- struct sockaddr_at *sat = (struct sockaddr_at *)dst;
-
- /*
- * super hack..
- * Most of this loopback code should move into the appletalk
- * code, but it's here for now.. remember to move it! [JRE]
- * This may not get the same interface we started with,
- * fix asap. XXX
- */
- aa = at_ifawithnet( sat );
- if (aa == NULL) {
- goto bad;
- }
- if( aa->aa_ifa.ifa_ifp != ifp ) {
- (*aa->aa_ifa.ifa_ifp->if_output)(aa->aa_ifa.ifa_ifp,
- m,dst,rt);
- }
- if (((sat->sat_addr.s_net == ATADDR_ANYNET)
- && (sat->sat_addr.s_node == ATADDR_ANYNODE))
- || ((sat->sat_addr.s_net == aa->aa_addr.sat_addr.s_net )
- && (sat->sat_addr.s_node == aa->aa_addr.sat_addr.s_node))) {
- (void) looutput(ifp, m, dst, rt);
- return(0);
- }
+ {
+ struct at_ifaddr *aa;
- if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) {
-#ifdef NETATALKDEBUG
- extern char *prsockaddr(struct sockaddr *);
- printf("aarpresolv: failed for %s\n", prsockaddr(dst));
-#endif /* NETATALKDEBUG */
- return (0);
- }
-
- /*
- * If broadcasting on a simplex interface, loopback a copy
- */
- if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
- mcopy = m_copy(m, 0, (int)M_COPYALL);
+ if ((aa = at_ifawithnet((struct sockaddr_at *)dst)) == NULL) {
+ goto bad;
}
+ if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst))
+ return (0);
/*
- * In the phase 2 case, we need to prepend an mbuf for the llc header.
+ * In the phase 2 case, need to prepend an mbuf for the llc header.
* Since we must preserve the value of m, which is passed to us by
* value, we m_copy() the first mbuf, and use it for our llc header.
*/
@@ -264,6 +207,7 @@ ether_output(ifp, m0, dst, rt0)
type = htons(ETHERTYPE_AT);
}
break;
+ }
#endif NETATALK
#ifdef NS
case AF_NS:
@@ -312,10 +256,6 @@ ether_output(ifp, m0, dst, rt0)
IF_ENQUEUE(inq, m2);
splx(s);
}
- /* If broadcasting on a simplex interface, loopback a copy */
- if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)){
- mcopy = m_copy(m, 0, (int)M_COPYALL);
- }
break;
#endif /* NS */
#ifdef ISO
@@ -334,17 +274,6 @@ ether_output(ifp, m0, dst, rt0)
/* If broadcasting on a simplex interface, loopback a copy */
if (*edst & 1)
m->m_flags |= (M_BCAST|M_MCAST);
- if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
- (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
- M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
- if (mcopy) {
- eh = mtod(mcopy, struct ether_header *);
- bcopy((caddr_t)edst,
- (caddr_t)eh->ether_dhost, sizeof (edst));
- bcopy((caddr_t)ac->ac_enaddr,
- (caddr_t)eh->ether_shost, sizeof (edst));
- }
- }
M_PREPEND(m, 3, M_DONTWAIT);
if (m == NULL)
return (0);
@@ -370,20 +299,10 @@ ether_output(ifp, m0, dst, rt0)
if (sdl && sdl->sdl_family == AF_LINK
&& sdl->sdl_alen > 0) {
- bcopy(LLADDR(sdl), (char *)edst,
- sizeof(edst));
+ bcopy(LLADDR(sdl), (char *)edst, sizeof(edst));
} else goto bad; /* Not a link interface ? Funny ... */
- if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
- (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
- M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
- if (mcopy) {
- eh = mtod(mcopy, struct ether_header *);
- bcopy((caddr_t)edst,
- (caddr_t)eh->ether_dhost, sizeof (edst));
- bcopy((caddr_t)ac->ac_enaddr,
- (caddr_t)eh->ether_shost, sizeof (edst));
- }
- }
+ if (*edst & 1)
+ loop_copy = 1;
type = htons(m->m_pkthdr.len);
#ifdef LLC_DEBUG
{
@@ -414,9 +333,6 @@ ether_output(ifp, m0, dst, rt0)
senderr(EAFNOSUPPORT);
}
-
- if (mcopy)
- (void) looutput(ifp, mcopy, dst, rt);
/*
* Add local net header. If no space in first mbuf,
* allocate another.
@@ -430,6 +346,28 @@ ether_output(ifp, m0, dst, rt0)
(void)memcpy(eh->ether_dhost, edst, sizeof (edst));
(void)memcpy(eh->ether_shost, ac->ac_enaddr,
sizeof(eh->ether_shost));
+
+ /*
+ * If a simplex interface, and the packet is being sent to our
+ * Ethernet address or a broadcast address, loopback a copy.
+ * XXX To make a simplex device behave exactly like a duplex
+ * device, we should copy in the case of sending to our own
+ * ethernet address (thus letting the original actually appear
+ * on the wire). However, we don't do that here for security
+ * reasons and compatibility with the original behavior.
+ */
+ if (ifp->if_flags & IFF_SIMPLEX) {
+ if ((m->m_flags & M_BCAST) || loop_copy) {
+ struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
+
+ (void) if_simloop(ifp, n, dst, ETHER_HDR_LEN);
+ } else if (bcmp(eh->ether_dhost,
+ eh->ether_shost, ETHER_ADDR_LEN) == 0) {
+ (void) if_simloop(ifp, m, dst, ETHER_HDR_LEN);
+ return(0); /* XXX */
+ }
+ }
+
s = splimp();
/*
* Queue message on interface, and start output if interface
diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c
index 2450abb..ee4e847 100644
--- a/sys/net/if_fddisubr.c
+++ b/sys/net/if_fddisubr.c
@@ -33,7 +33,7 @@
* SUCH DAMAGE.
*
* from: if_ethersubr.c,v 1.5 1994/12/13 22:31:45 wollman Exp
- * $Id: if_fddisubr.c,v 1.29 1998/05/20 14:08:43 dufault Exp $
+ * $Id: if_fddisubr.c,v 1.30 1998/05/21 00:33:16 dg Exp $
*/
#include "opt_atalk.h"
@@ -139,12 +139,11 @@ fddi_output(ifp, m0, dst, rt0)
struct rtentry *rt0;
{
u_int16_t type;
- int s, error = 0;
+ int s, loop_copy = 0, error = 0;
u_char edst[6];
register struct mbuf *m = m0;
register struct rtentry *rt;
register struct fddi_header *fh;
- struct mbuf *mcopy = (struct mbuf *)0;
struct arpcom *ac = (struct arpcom *)ifp;
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
@@ -186,47 +185,22 @@ fddi_output(ifp, m0, dst, rt0)
if (!arpresolve(ac, m, &((struct sockaddr_in *)dst)->sin_addr, edst, &usetrailers))
return (0); /* if not yet resolved */
#endif
- /* If broadcasting on a simplex interface, loopback a copy */
- if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
- mcopy = m_copy(m, 0, (int)M_COPYALL);
type = htons(ETHERTYPE_IP);
break;
}
#endif
#ifdef IPX
case AF_IPX:
- {
- struct ifaddr *ia;
-
type = htons(ETHERTYPE_IPX);
bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host),
(caddr_t)edst, sizeof (edst));
-
- for(ia = ifp->if_addrhead.tqh_first; ia != 0;
- ia = ia->ifa_link.tqe_next) {
- if(ia->ifa_addr->sa_family == AF_IPX &&
- !bcmp((caddr_t)edst,
- (caddr_t)&((struct ipx_ifaddr *)ia)->ia_addr.sipx_addr.x_host,
- sizeof(edst)) )
- return (looutput(ifp, m, dst, rt));
- }
-
- /* If broadcasting on a simplex interface, loopback a copy */
- if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
- mcopy = m_copy(m, 0, (int)M_COPYALL);
break;
- }
#endif
#ifdef NETATALK
case AF_APPLETALK: {
struct at_ifaddr *aa;
- if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) {
-#ifdef NETATALKDEBUG
- extern char *prsockaddr(struct sockaddr *);
- printf("aarpresolv: failed for %s\n", prsockaddr(dst));
-#endif
+ if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst))
return (0);
- }
/*
* ifaddr is the first thing in at_ifaddr
*/
@@ -261,11 +235,6 @@ fddi_output(ifp, m0, dst, rt0)
type = htons(ETHERTYPE_NS);
bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
(caddr_t)edst, sizeof (edst));
- if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst)))
- return (looutput(ifp, m, dst, rt));
- /* If broadcasting on a simplex interface, loopback a copy */
- if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
- mcopy = m_copy(m, 0, (int)M_COPYALL);
break;
#endif
#ifdef ISO
@@ -284,17 +253,6 @@ fddi_output(ifp, m0, dst, rt0)
/* If broadcasting on a simplex interface, loopback a copy */
if (*edst & 1)
m->m_flags |= (M_BCAST|M_MCAST);
- if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
- (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
- M_PREPEND(mcopy, sizeof (*fh), M_DONTWAIT);
- if (mcopy) {
- fh = mtod(mcopy, struct fddi_header *);
- bcopy((caddr_t)edst,
- (caddr_t)fh->fddi_dhost, sizeof (edst));
- bcopy((caddr_t)ac->ac_enaddr,
- (caddr_t)fh->fddi_shost, sizeof (edst));
- }
- }
M_PREPEND(m, 3, M_DONTWAIT);
if (m == NULL)
return (0);
@@ -320,18 +278,8 @@ fddi_output(ifp, m0, dst, rt0)
if (sdl && sdl->sdl_family != AF_LINK && sdl->sdl_alen <= 0)
goto bad; /* Not a link interface ? Funny ... */
bcopy(LLADDR(sdl), (char *)edst, sizeof(edst));
- if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
- (mcopy = m_copy(m, 0, (int)M_COPYALL))) {
- M_PREPEND(mcopy, sizeof (*fh), M_DONTWAIT);
- if (mcopy) {
- fh = mtod(mcopy, struct fddi_header *);
- bcopy((caddr_t)edst,
- (caddr_t)fh->fddi_dhost, sizeof (edst));
- bcopy((caddr_t)ac->ac_enaddr,
- (caddr_t)fh->fddi_shost, sizeof (edst));
- fh->fddi_fc = FDDIFC_LLC_ASYNC|FDDIFC_LLC_PRIO4;
- }
- }
+ if (*edst & 1)
+ loop_copy = 1;
type = 0;
#ifdef LLC_DEBUG
{
@@ -402,9 +350,6 @@ fddi_output(ifp, m0, dst, rt0)
senderr(EAFNOSUPPORT);
}
-
- if (mcopy)
- (void) looutput(ifp, mcopy, dst, rt);
if (type != 0) {
register struct llc *l;
M_PREPEND(m, sizeof (struct llc), M_DONTWAIT);
@@ -417,6 +362,7 @@ fddi_output(ifp, m0, dst, rt0)
(void)memcpy((caddr_t) &l->llc_snap.ether_type, (caddr_t) &type,
sizeof(u_int16_t));
}
+
/*
* Add local net header. If no space in first mbuf,
* allocate another.
@@ -430,6 +376,30 @@ fddi_output(ifp, m0, dst, rt0)
queue_it:
(void)memcpy((caddr_t)fh->fddi_shost, (caddr_t)ac->ac_enaddr,
sizeof(fh->fddi_shost));
+
+ /*
+ * If a simplex interface, and the packet is being sent to our
+ * Ethernet address or a broadcast address, loopback a copy.
+ * XXX To make a simplex device behave exactly like a duplex
+ * device, we should copy in the case of sending to our own
+ * ethernet address (thus letting the original actually appear
+ * on the wire). However, we don't do that here for security
+ * reasons and compatibility with the original behavior.
+ */
+ if (ifp->if_flags & IFF_SIMPLEX) {
+ if ((m->m_flags & M_BCAST) || loop_copy) {
+ struct mbuf *n = m_copy(m, 0, (int)M_COPYALL);
+
+ (void) if_simloop(ifp,
+ n, dst, sizeof(struct fddi_header));
+ } else if (bcmp(fh->fddi_dhost,
+ fh->fddi_shost, sizeof(fh->fddi_shost)) == 0) {
+ (void) if_simloop(ifp,
+ m, dst, sizeof(struct fddi_header));
+ return(0); /* XXX */
+ }
+ }
+
s = splimp();
/*
* Queue message on interface, and start output if interface
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index f594525..c6f3832 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)if_loop.c 8.1 (Berkeley) 6/10/93
- * $Id: if_loop.c,v 1.31 1998/04/30 19:37:00 phk Exp $
+ * $Id: if_loop.c,v 1.32 1998/06/07 17:12:03 dfr Exp $
*/
/*
@@ -83,6 +83,9 @@
#endif NETATALK
#include "bpfilter.h"
+#if NBPFILTER > 0
+#include <net/bpfdesc.h>
+#endif
static int loioctl __P((struct ifnet *, u_long, caddr_t));
static void lortrequest __P((int, struct rtentry *, struct sockaddr *));
@@ -90,6 +93,9 @@ static void lortrequest __P((int, struct rtentry *, struct sockaddr *));
static void loopattach __P((void *));
PSEUDO_SET(loopattach, if_loop);
+static int looutput __P((struct ifnet *ifp,
+ struct mbuf *m, struct sockaddr *dst, struct rtentry *rt));
+
#ifdef TINY_LOMTU
#define LOMTU (1024+512)
#else
@@ -121,18 +127,50 @@ loopattach(dummy)
}
}
-int
+static int
looutput(ifp, m, dst, rt)
struct ifnet *ifp;
register struct mbuf *m;
struct sockaddr *dst;
register struct rtentry *rt;
{
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("looutput no HDR");
+
+ if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
+ m_freem(m);
+ return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
+ rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+ }
+ ifp->if_opackets++;
+ ifp->if_obytes += m->m_pkthdr.len;
+ return(if_simloop(ifp, m, dst, 0));
+}
+
+/*
+ * if_simloop()
+ *
+ * This function is to support software emulation of hardware loopback,
+ * i.e., for interfaces with the IFF_SIMPLEX attribute. Since they can't
+ * hear their own broadcasts, we create a copy of the packet that we
+ * would normally receive via a hardware loopback.
+ *
+ * This function expects the packet to include the media header of length hlen.
+ */
+
+int
+if_simloop(ifp, m, dst, hlen)
+ struct ifnet *ifp;
+ register struct mbuf *m;
+ struct sockaddr *dst;
+ int hlen;
+{
int s, isr;
register struct ifqueue *ifq = 0;
if ((m->m_flags & M_PKTHDR) == 0)
- panic("looutput no HDR");
+ panic("%s: no HDR", __FUNCTION__);
+ m->m_pkthdr.rcvif = ifp;
#if NBPFILTER > 0
/* BPF write needs to be handled specially */
if (dst->sa_family == AF_UNSPEC) {
@@ -143,34 +181,31 @@ looutput(ifp, m, dst, rt)
}
if (ifp->if_bpf) {
- /*
- * We need to prepend the address family as
- * a four byte field. Cons up a dummy header
- * to pacify bpf. This is safe because bpf
- * will only read from the mbuf (i.e., it won't
- * try to free it or keep a pointer a to it).
- */
- struct mbuf m0;
+ struct mbuf m0, *n = m;
u_int af = dst->sa_family;
- m0.m_next = m;
- m0.m_len = 4;
- m0.m_data = (char *)&af;
-
- bpf_mtap(ifp, &m0);
+ if (ifp->if_bpf->bif_dlt == DLT_NULL) {
+ /*
+ * We need to prepend the address family as
+ * a four byte field. Cons up a dummy header
+ * to pacify bpf. This is safe because bpf
+ * will only read from the mbuf (i.e., it won't
+ * try to free it or keep a pointer a to it).
+ */
+ m0.m_next = m;
+ m0.m_len = 4;
+ m0.m_data = (char *)&af;
+ n = &m0;
+ }
+ bpf_mtap(ifp, n);
}
#endif
- m->m_pkthdr.rcvif = ifp;
- if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
- m_freem(m);
- return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
- rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
- }
- ifp->if_opackets++;
- ifp->if_obytes += m->m_pkthdr.len;
- switch (dst->sa_family) {
+ /* Strip away media header */
+ if (hlen > 0)
+ m_adj(m, hlen);
+ switch (dst->sa_family) {
#ifdef INET
case AF_INET:
ifq = &ipintrq;
@@ -202,8 +237,8 @@ looutput(ifp, m, dst, rt)
break;
#endif NETATALK
default:
- printf("lo%d: can't handle af%d\n", ifp->if_unit,
- dst->sa_family);
+ printf("%s: can't handle af=%d\n",
+ __FUNCTION__, dst->sa_family);
m_freem(m);
return (EAFNOSUPPORT);
}
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index f01dac3..0feaf23 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* From: @(#)if.h 8.1 (Berkeley) 6/10/93
- * $Id: if_var.h,v 1.7 1998/04/15 17:46:44 bde Exp $
+ * $Id: if_var.h,v 1.8 1998/06/07 17:12:06 dfr Exp $
*/
#ifndef _NET_IF_VAR_H_
@@ -326,9 +326,9 @@ void ifafree __P((struct ifaddr *));
struct ifmultiaddr *ifmaof_ifpforaddr __P((struct sockaddr *,
struct ifnet *));
+int if_simloop __P((struct ifnet *ifp, struct mbuf *m,
+ struct sockaddr *dst, int hlen));
-int looutput __P((struct ifnet *,
- struct mbuf *, struct sockaddr *, struct rtentry *));
#endif /* KERNEL */
OpenPOWER on IntegriCloud