diff options
-rw-r--r-- | sys/net/if_ethersubr.c | 143 | ||||
-rw-r--r-- | sys/net/if_fddisubr.c | 49 | ||||
-rw-r--r-- | sys/net/if_loop.c | 30 |
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; |