summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/net/if_ethersubr.c143
-rw-r--r--sys/net/if_fddisubr.c49
-rw-r--r--sys/net/if_loop.c30
3 files changed, 196 insertions, 26 deletions
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index f9cdd7988e0..34d489de121 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ethersubr.c,v 1.26 1998/07/07 19:26:18 ryker Exp $ */
+/* $OpenBSD: if_ethersubr.c,v 1.27 1999/01/08 00:56:45 deraadt Exp $ */
/* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */
/*
@@ -36,6 +36,18 @@
* @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93
*/
+/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -101,6 +113,11 @@ extern u_char aarp_org_code[ 3 ];
#include <sys/socketvar.h>
#endif
+#ifdef INET6
+#include <netinet6/in6.h>
+#include <netinet6/in6_var.h>
+#endif /* INET6 */
+
u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
#define senderr(e) { error = (e); goto bad;}
@@ -133,10 +150,10 @@ ether_ioctl(ifp, arp, cmd, data)
if (ipx_nullhost(*ina))
ina->ipx_host =
- *(union ipx_host *)(arp->ac_enaddr);
+ *(union ipx_host *)(arp->ac_enaddr);
else
- bcopy (ina->ipx_host.c_host,
- arp->ac_enaddr, sizeof(arp->ac_enaddr));
+ bcopy(ina->ipx_host.c_host,
+ arp->ac_enaddr, sizeof(arp->ac_enaddr));
break;
}
#endif /* IPX */
@@ -153,10 +170,10 @@ ether_ioctl(ifp, arp, cmd, data)
if (ns_nullhost(*ina))
ina->x_host =
- *(union ns_host *)(arp->ac_enaddr);
+ *(union ns_host *)(arp->ac_enaddr);
else
bcopy(ina->x_host.c_host,
- arp->ac_enaddr, sizeof(arp->ac_enaddr));
+ arp->ac_enaddr, sizeof(arp->ac_enaddr));
break;
}
#endif /* NS */
@@ -197,7 +214,7 @@ ether_output(ifp, m0, dst, rt0)
if ((rt->rt_flags & RTF_UP) == 0) {
if ((rt0 = rt = rtalloc1(dst, 1)) != NULL)
rt->rt_refcnt--;
- else
+ else
senderr(EHOSTUNREACH);
}
if (rt->rt_flags & RTF_GATEWAY) {
@@ -251,6 +268,28 @@ ether_output(ifp, m0, dst, rt0)
mcopy = m_copy(m, 0, (int)M_COPYALL);
break;
#endif
+#ifdef INET6
+ case AF_INET6:
+ /*
+ * The bottom line here is to either queue the outgoing packet
+ * in the discovery engine, or fill in edst with something
+ * that'll work.
+ */
+ if (m->m_flags & M_MCAST) {
+ /*
+ * If multicast dest., then use IPv6 -> Ethernet
+ * mcast mapping. Really simple.
+ */
+ ETHER_MAP_IN6_MULTICAST(((struct sockaddr_in6 *)dst)->sin6_addr,
+ edst);
+ } else {
+ /* Do unicast neighbor discovery stuff. */
+ if (!ipv6_discov_resolve(ifp, rt, m, dst, edst))
+ return 0;
+ }
+ etype = htons(ETHERTYPE_IPV6);
+ break;
+#endif /* INET6 */
#ifdef NETATALK
case AF_APPLETALK: {
struct at_ifaddr *aa;
@@ -323,10 +362,9 @@ ether_output(ifp, m0, dst, rt0)
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));
+ bcopy(edst, eh->ether_dhost, sizeof (edst));
+ bcopy(ac->ac_enaddr, eh->ether_shost,
+ sizeof (edst));
}
}
M_PREPEND(m, 3, M_DONTWAIT);
@@ -349,7 +387,7 @@ ether_output(ifp, m0, dst, rt0)
#endif /* ISO */
/* case AF_NSAP: */
case AF_CCITT: {
- register struct sockaddr_dl *sdl =
+ register struct sockaddr_dl *sdl =
(struct sockaddr_dl *) rt -> rt_gateway;
if (sdl && sdl->sdl_family == AF_LINK
@@ -362,10 +400,9 @@ ether_output(ifp, m0, dst, rt0)
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));
+ bcopy(edst, eh->ether_dhost, sizeof (edst));
+ bcopy(ac->ac_enaddr, eh->ether_shost,
+ sizeof (edst));
}
}
etype = htons(m->m_pkthdr.len);
@@ -377,7 +414,7 @@ ether_output(ifp, m0, dst, rt0)
printf("ether_output: sending LLC2 pkt to: ");
for (i=0; i<6; i++)
printf("%x ", edst[i] & 0xff);
- printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n",
+ printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n",
m->m_pkthdr.len, l->llc_dsap & 0xff, l->llc_ssap &0xff,
l->llc_control & 0xff);
@@ -497,6 +534,15 @@ decapsulate:
return;
#endif
+#ifdef INET6
+ /*
+ * Schedule IPv6 software interrupt for incoming IPv6 packet.
+ */
+ case ETHERTYPE_IPV6:
+ schednetisr(NETISR_IPV6);
+ inq = &ipv6intrq;
+ break;
+#endif /* INET6 */
#ifdef IPX
case ETHERTYPE_IPX:
schednetisr(NETISR_IPX);
@@ -574,7 +620,7 @@ decapsulate:
}
goto dropanyway;
#ifdef ISO
- case LLC_ISO_LSAP:
+ case LLC_ISO_LSAP:
switch (l->llc_control) {
case LLC_UI:
/* LLC_UI_P forbidden in class 1 service */
@@ -599,7 +645,7 @@ decapsulate:
break;
}
goto dropanyway;
-
+
case LLC_XID:
case LLC_XID_P:
if(m->m_len < 6)
@@ -620,14 +666,14 @@ decapsulate:
l->llc_dsap = l->llc_ssap;
l->llc_ssap = c;
if (m->m_flags & (M_BCAST | M_MCAST))
- bcopy((caddr_t)ac->ac_enaddr,
- (caddr_t)eh->ether_dhost, 6);
+ bcopy(ac->ac_enaddr,
+ eh->ether_dhost, 6);
sa.sa_family = AF_UNSPEC;
sa.sa_len = sizeof(sa);
eh2 = (struct ether_header *)sa.sa_data;
for (i = 0; i < 6; i++) {
eh2->ether_shost[i] = c = eh->ether_dhost[i];
- eh2->ether_dhost[i] =
+ eh2->ether_dhost[i] =
eh->ether_dhost[i] = eh->ether_shost[i];
eh->ether_shost[i] = c;
}
@@ -715,7 +761,7 @@ ether_ifattach(ifp)
sdl->sdl_type = IFT_ETHER;
sdl->sdl_alen = ifp->if_addrlen;
bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
- LLADDR(sdl), ifp->if_addrlen);
+ LLADDR(sdl), ifp->if_addrlen);
break;
}
LIST_INIT(&((struct arpcom *)ifp)->ac_multiaddrs);
@@ -723,6 +769,12 @@ ether_ifattach(ifp)
u_char ether_ipmulticast_min[6] = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
u_char ether_ipmulticast_max[6] = { 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
+
+#ifdef INET6
+u_char ether_ipv6multicast_min[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 };
+u_char ether_ipv6multicast_max[6] = { 0x33, 0x33, 0xff, 0xff, 0xff, 0xff };
+#endif /* INET6 */
+
/*
* Add an Ethernet multicast address or range of addresses to the list for a
* given interface.
@@ -734,6 +786,9 @@ ether_addmulti(ifr, ac)
{
register struct ether_multi *enm;
struct sockaddr_in *sin;
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+#endif /* INET6 */
u_char addrlo[6];
u_char addrhi[6];
int s = splimp();
@@ -763,6 +818,23 @@ ether_addmulti(ifr, ac)
}
break;
#endif
+#ifdef INET6
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)&(ifr->ifr_addr);
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ /*
+ * An unspecified IPv6 address means listen to all
+ * of the IPv6 multicast addresses on this Ethernet.
+ * (Multicast routers like this.)
+ */
+ bcopy(ether_ipv6multicast_min, addrlo, ETHER_ADDR_LEN);
+ bcopy(ether_ipv6multicast_max, addrhi, ETHER_ADDR_LEN);
+ } else {
+ ETHER_MAP_IN6_MULTICAST(sin6->sin6_addr, addrlo);
+ bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
+ }
+ break;
+#endif /* INET6 */
default:
splx(s);
@@ -821,6 +893,9 @@ ether_delmulti(ifr, ac)
{
register struct ether_multi *enm;
struct sockaddr_in *sin;
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+#endif /* INET6 */
u_char addrlo[6];
u_char addrhi[6];
int s = splimp();
@@ -850,6 +925,28 @@ ether_delmulti(ifr, ac)
}
break;
#endif
+#ifdef INET6
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)&(ifr->ifr_addr);
+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
+ /*
+ * An unspecified IPv6 address means stop listening to
+ * all IPv6 multicast addresses on this Ethernet.'
+ *
+ * (This might not be healthy, given IPv6's reliance on
+ * multicast for things like neighbor discovery.
+ * Perhaps initializing all-nodes, solicited nodes, and
+ * possibly all-routers for this interface afterwards
+ * is not a bad idea.)
+ */
+ bcopy(ether_ipv6multicast_min, addrlo, ETHER_ADDR_LEN);
+ bcopy(ether_ipv6multicast_max, addrhi, ETHER_ADDR_LEN);
+ } else {
+ ETHER_MAP_IN6_MULTICAST(sin6->sin6_addr, addrlo);
+ bcopy(addrlo, addrhi, ETHER_ADDR_LEN);
+ }
+ break;
+#endif /* INET6 */
default:
splx(s);
diff --git a/sys/net/if_fddisubr.c b/sys/net/if_fddisubr.c
index dde9ec09330..164c6976304 100644
--- a/sys/net/if_fddisubr.c
+++ b/sys/net/if_fddisubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_fddisubr.c,v 1.17 1998/07/08 22:22:51 ryker Exp $ */
+/* $OpenBSD: if_fddisubr.c,v 1.18 1999/01/08 00:56:45 deraadt Exp $ */
/* $NetBSD: if_fddisubr.c,v 1.5 1996/05/07 23:20:21 christos Exp $ */
/*
@@ -38,6 +38,18 @@
* @(#)if_fddisubr.c 8.1 (Berkeley) 6/10/93
*/
+/*
+%%% portions-copyright-nrl-97
+Portions of this software are Copyright 1997-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -95,6 +107,11 @@
#include <netccitt/dll.h>
#include <netccitt/llc_var.h>
+#ifdef INET6
+#include <netinet6/in6.h>
+#include <netinet6/in6_var.h>
+#endif /* INET6 */
+
#if defined(CCITT)
extern struct ifqueue pkintrq;
#endif
@@ -175,6 +192,28 @@ fddi_output(ifp, m0, dst, rt0)
type = htons(ETHERTYPE_IP);
break;
#endif
+#ifdef INET6
+ case AF_INET6:
+ /*
+ * The bottom line here is to either queue the outgoing packet
+ * in the discovery engine, or fill in edst with something
+ * that'll work.
+ */
+ if (m->m_flags & M_MCAST) {
+ /*
+ * If multicast dest., then use IPv6 -> Ethernet mcast
+ * mapping. Really simple.
+ */
+ ETHER_MAP_IN6_MULTICAST(((struct sockaddr_in6 *)dst)->sin6_addr,
+ edst);
+ } else {
+ /* Do unicast neighbor discovery stuff. */
+ if (!ipv6_discov_resolve(ifp, rt, m, dst, edst))
+ return 0;
+ }
+ type = htons(ETHERTYPE_IPV6);
+ break;
+#endif /* INET6 */
#ifdef IPX
case AF_IPX:
type = htons(ETHERTYPE_IPX);
@@ -426,7 +465,7 @@ fddi_input(ifp, fh, m)
l = mtod(m, struct llc *);
switch (l->llc_dsap) {
-#if defined(INET) || defined(IPX) || defined(NS) || defined(DECNET)
+#if defined(INET) || defined(IPX) || defined(NS) || defined(DECNET) || defined(INET6)
case LLC_SNAP_LSAP:
{
u_int16_t etype;
@@ -450,6 +489,12 @@ fddi_input(ifp, fh, m)
inq = &arpintrq;
break;
#endif
+#ifdef INET6
+ case ETHERTYPE_IPV6:
+ schednetisr(NETISR_IPV6);
+ inq = &ipv6intrq;
+ break;
+#endif /* INET6 */
#ifdef IPX
case ETHERTYPE_IPX:
schednetisr(NETISR_IPX);
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c
index 5a5de07700a..57dbd3fe733 100644
--- a/sys/net/if_loop.c
+++ b/sys/net/if_loop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_loop.c,v 1.10 1998/06/26 09:14:37 deraadt Exp $ */
+/* $OpenBSD: if_loop.c,v 1.11 1999/01/08 00:56:45 deraadt Exp $ */
/* $NetBSD: if_loop.c,v 1.15 1996/05/07 02:40:33 thorpej Exp $ */
/*
@@ -37,6 +37,18 @@
*/
/*
+%%% portions-copyright-nrl-95
+Portions of this software are Copyright 1995-1998 by Randall Atkinson,
+Ronald Lee, Daniel McDonald, Bao Phan, and Chris Winters. All Rights
+Reserved. All rights under this copyright have been assigned to the US
+Naval Research Laboratory (NRL). The NRL Copyright Notice and License
+Agreement Version 1.1 (January 17, 1995) applies to these portions of the
+software.
+You should have received a copy of the license with this software. If you
+didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>.
+*/
+
+/*
* Loopback interface driver for protocol testing and timing.
*/
@@ -91,6 +103,11 @@
#include <net/bpf.h>
#endif
+#ifdef INET6
+#include <netinet6/in6.h>
+#include <netinet6/in6_var.h>
+#endif /* INET6 */
+
#define LOMTU (32768)
struct ifnet loif[NLOOP];
@@ -174,6 +191,12 @@ looutput(ifp, m, dst, rt)
isr = NETISR_IP;
break;
#endif
+#ifdef INET6
+ case AF_INET6:
+ ifq = &ipv6intrq;
+ isr = NETISR_IPV6;
+ break;
+#endif /* INET6 */
#ifdef NS
case AF_NS:
ifq = &nsintrq;
@@ -271,6 +294,11 @@ loioctl(ifp, cmd, data)
break;
#endif
+#ifdef INET6
+ case AF_INET6:
+ break;
+#endif /* INET6 */
+
default:
error = EAFNOSUPPORT;
break;