summaryrefslogtreecommitdiffstats
path: root/sys/net/if_ethersubr.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/if_ethersubr.c')
-rw-r--r--sys/net/if_ethersubr.c90
1 files changed, 68 insertions, 22 deletions
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index d6046be..dc55d54 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -56,11 +56,15 @@
#include <net/if_dl.h>
#include <net/if_types.h>
-#ifdef INET
+#if defined(INET) || defined(INET6)
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/if_ether.h>
#endif
+#ifdef INET6
+#include <netinet6/nd6.h>
+#include <netinet6/in6_ifattach.h>
+#endif
#ifdef IPX
#include <netipx/ipx.h>
@@ -112,7 +116,7 @@ extern u_char aarp_org_code[3];
#include <net/if_vlan_var.h>
#endif /* NVLAN > 0 */
-static int ether_resolvemulti __P((struct ifnet *, struct sockaddr **,
+static int ether_resolvemulti __P((struct ifnet *, struct sockaddr **,
struct sockaddr *));
u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
#define senderr(e) do { error = (e); goto bad;} while (0)
@@ -146,7 +150,7 @@ static struct ng_type typestruct = {
ngether_connect,
ngether_rcvdata,
ngether_rcvdata,
- ngether_disconnect
+ ngether_disconnect
};
#define AC2NG(AC) ((node_p)((AC)->ac_ng))
@@ -214,6 +218,17 @@ ether_output(ifp, m0, dst, rt0)
type = htons(ETHERTYPE_IP);
break;
#endif
+#ifdef INET6
+ case AF_INET6:
+ if (!nd6_storelladdr(&ac->ac_if, rt, m, dst, (u_char *)edst)) {
+ /* this must be impossible, so we bark */
+ printf("nd6_storelladdr failed\n");
+ return(0);
+ }
+ off = m->m_pkthdr.len - m->m_len;
+ type = htons(ETHERTYPE_IPV6);
+ break;
+#endif
#ifdef IPX
case AF_IPX:
type = htons(ETHERTYPE_IPX);
@@ -530,6 +545,12 @@ ether_input(ifp, eh, m)
inq = &ipxintrq;
break;
#endif
+#ifdef INET6
+ case ETHERTYPE_IPV6:
+ schednetisr(NETISR_IPV6);
+ inq = &ip6intrq;
+ break;
+#endif
#ifdef NS
case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */
schednetisr(NETISR_NS);
@@ -741,6 +762,9 @@ ether_ifattach(ifp)
#ifdef NETGRAPH
ngether_init(ifp);
#endif /* NETGRAPH */
+#ifdef INET6
+ in6_ifattach_getifid(ifp);
+#endif
}
SYSCTL_DECL(_net_link);
@@ -778,7 +802,7 @@ ether_ioctl(ifp, command, data)
if (ipx_nullhost(*ina))
ina->x_host =
- *(union ipx_host *)
+ *(union ipx_host *)
ac->ac_enaddr;
else {
bcopy((caddr_t) ina->x_host.c_host,
@@ -856,11 +880,14 @@ ether_resolvemulti(ifp, llsa, sa)
{
struct sockaddr_dl *sdl;
struct sockaddr_in *sin;
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+#endif
u_char *e_addr;
switch(sa->sa_family) {
case AF_LINK:
- /*
+ /*
* No mapping needed. Just check that it's a valid MC address.
*/
sdl = (struct sockaddr_dl *)sa;
@@ -889,9 +916,28 @@ ether_resolvemulti(ifp, llsa, sa)
*llsa = (struct sockaddr *)sdl;
return 0;
#endif
+#ifdef INET6
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)sa;
+ if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
+ return EADDRNOTAVAIL;
+ MALLOC(sdl, struct sockaddr_dl *, sizeof *sdl, M_IFMADDR,
+ M_WAITOK);
+ sdl->sdl_len = sizeof *sdl;
+ sdl->sdl_family = AF_LINK;
+ sdl->sdl_index = ifp->if_index;
+ sdl->sdl_type = IFT_ETHER;
+ sdl->sdl_nlen = 0;
+ sdl->sdl_alen = ETHER_ADDR_LEN;
+ sdl->sdl_slen = 0;
+ e_addr = LLADDR(sdl);
+ ETHER_MAP_IPV6_MULTICAST(&sin6->sin6_addr, e_addr);
+ *llsa = (struct sockaddr *)sdl;
+ return 0;
+#endif
default:
- /*
+ /*
* Well, the text isn't quite right, but it's the name
* that counts...
*/
@@ -976,8 +1022,8 @@ ngether_constructor(node_p *nodep)
/*
* Give our ok for a hook to be added...
- *
- * Allow one hook at a time (rawdata).
+ *
+ * Allow one hook at a time (rawdata).
* It can eiteh rdivert everything or only unclaimed packets.
*/
static int
@@ -1014,10 +1060,10 @@ ngether_rcvmsg(node_p node,
ifp = node->private;
switch (msg->header.typecookie) {
- case NGM_ETHER_COOKIE:
+ case NGM_ETHER_COOKIE:
error = EINVAL;
break;
- case NGM_GENERIC_COOKIE:
+ case NGM_GENERIC_COOKIE:
switch(msg->header.cmd) {
case NGM_TEXT_STATUS: {
char *arg;
@@ -1025,10 +1071,10 @@ ngether_rcvmsg(node_p node,
int resplen = sizeof(struct ng_mesg) + 512;
MALLOC(*resp, struct ng_mesg *, resplen,
M_NETGRAPH, M_NOWAIT);
- if (*resp == NULL) {
+ if (*resp == NULL) {
error = ENOMEM;
break;
- }
+ }
bzero(*resp, resplen);
arg = (*resp)->data;
@@ -1135,10 +1181,10 @@ bad:
* pass an mbuf out to the connected hook
* More complicated than just an m_prepend, as it tries to save later nodes
* from needing to do lots of m_pullups.
- */
+ */
static void
ngether_send(struct arpcom *ac, struct ether_header *eh, struct mbuf *m)
-{
+{
int room;
node_p node = AC2NG(ac);
struct ether_header *eh2;
@@ -1150,15 +1196,15 @@ ngether_send(struct arpcom *ac, struct ether_header *eh, struct mbuf *m)
eh2 = mtod(m, struct ether_header *) - 1;
if ( eh == eh2) {
/*
- * This is the case so just move the markers back to
+ * This is the case so just move the markers back to
* re-include it. We lucked out.
* This allows us to avoid a yucky m_pullup
* in later nodes if it works.
- */
- m->m_len += sizeof(*eh);
+ */
+ m->m_len += sizeof(*eh);
m->m_data -= sizeof(*eh);
m->m_pkthdr.len += sizeof(*eh);
- } else {
+ } else {
/*
* Alternatively there may be room even though
* it is stored somewhere else. If so, copy it in.
@@ -1170,7 +1216,7 @@ ngether_send(struct arpcom *ac, struct ether_header *eh, struct mbuf *m)
* that fall into these cases. So we are not optimising
* contorted cases.
*/
-
+
if (m->m_flags & M_EXT) {
room = (mtod(m, caddr_t) - m->m_ext.ext_buf);
if (room > m->m_ext.ext_size) /* garbage */
@@ -1178,14 +1224,14 @@ ngether_send(struct arpcom *ac, struct ether_header *eh, struct mbuf *m)
} else {
room = (mtod(m, caddr_t) - m->m_pktdat);
}
- if (room > sizeof (*eh)) {
+ if (room > sizeof (*eh)) {
/* we have room, just copy it and adjust */
m->m_len += sizeof(*eh);
m->m_data -= sizeof(*eh);
m->m_pkthdr.len += sizeof(*eh);
} else {
/*
- * Doing anything more is likely to get more
+ * Doing anything more is likely to get more
* expensive than it's worth..
* it's probable that everything else is in one
* big lump. The next node will do an m_pullup()
@@ -1230,7 +1276,7 @@ ngether_connect(hook_p hook)
/*
* notify on hook disconnection (destruction)
*
- * For this type, removal of the last lins no effect. The interface can run
+ * For this type, removal of the last lins no effect. The interface can run
* independently.
* Since we have no per-hook information, this is rather simple.
*/
OpenPOWER on IntegriCloud