/*
- * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000,2009 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
- * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
*
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the
- * License may not be used to create, or enable the creation or
- * redistribution of, unlawful or unlicensed copies of an Apple operating
- * system, or to circumvent, violate, or enable the circumvention or
- * violation of, any terms of an Apple operating system software license
- * agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
* limitations under the License.
- *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1982, 1989, 1993
#include <net/if_dl.h>
#include <net/if_types.h>
#include <netinet/if_ether.h>
+#include <net/kpi_interface.h>
+#include <net/kpi_protocol.h>
#include <sys/socketvar.h>
#endif
-#if BRIDGE
-#include <net/bridge.h>
-#endif
-
/* #include "vlan.h" */
#if NVLAN > 0
#include <net/if_vlan_var.h>
#endif /* NVLAN > 0 */
-struct dl_es_at_entry
-{
- struct ifnet *ifp;
- int ref_count;
-};
-
-/* Local fuction declerations */
-int at_ether_input(struct mbuf *m, char *frame_header, struct ifnet *ifp,
- u_long protocol_family, int sync_ok);
-int ether_pre_output(struct ifnet *ifp, u_long protocol_family, struct mbuf **m0,
- const struct sockaddr *dst_netaddr, caddr_t route, char *type, char *edst);
-int ether_prmod_ioctl(u_long protocol_family, struct ifnet *ifp, u_long command,
- caddr_t data);
-int ether_attach_at(struct ifnet *ifp);
-void ether_detach_at(struct ifnet *ifp);
-
-
-/*
- * Temp static for protocol registration XXX
- */
-
-#define MAX_EN_COUNT 30
-
-static struct dl_es_at_entry en_at_array[MAX_EN_COUNT];
+#include <net/ether_if_module.h>
/*
* Process a received Ethernet packet;
* the packet is in the mbuf chain m without
* the ether header, which is provided separately.
*/
-int
-at_ether_input(
- struct mbuf *m,
- __unused char *frame_header,
- __unused struct ifnet *ifp,
- __unused u_long protocol_family,
- __unused int sync_ok)
-
+static errno_t
+ether_at_input(
+ __unused ifnet_t ifp,
+ __unused protocol_family_t protocol_family,
+ mbuf_t m,
+ __unused char *frame_header)
{
- /*
- * note: for AppleTalk we need to pass the enet header of the
- * packet up stack. To do so, we made sure in that the FULL packet
- * is copied in the mbuf by the mace driver, and only the m_data and
- * length have been shifted to make IP and the other guys happy.
- */
+ errno_t error;
+ /*
+ * note: for AppleTalk we need to pass the enet header of the
+ * packet up stack. To do so, we made sure in that the FULL packet
+ * is copied in the mbuf by the driver, and only the m_data and
+ * length have been shifted to make IP and the other guys happy.
+ */
m->m_data -= sizeof(struct ether_header);
m->m_len += sizeof(struct ether_header);
m->m_pkthdr.len += sizeof(struct ether_header);
- proto_input(PF_APPLETALK, m);
- return 0;
+ error = proto_input(PF_APPLETALK, m);
+
+ if (error)
+ m_freem(m);
+
+ return error;
}
-int
-ether_pre_output(
- struct ifnet *ifp,
- __unused u_long protocol_family,
- struct mbuf **m0,
- const struct sockaddr *dst_netaddr,
- __unused caddr_t route,
- char *type,
- char *edst)
+static errno_t
+ether_at_pre_output(
+ ifnet_t ifp,
+ __unused protocol_family_t protocol_family,
+ mbuf_t *m0,
+ const struct sockaddr *dst_netaddr,
+ __unused void *route,
+ char *type,
+ char *edst)
{
- register struct mbuf *m = *m0;
- register struct ether_header *eh;
- int hlen; /* link layer header lenght */
-
-
-
- if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
- return ENETDOWN;
+ struct mbuf *m = *m0;
+ const struct ether_header *eh;
+ int hlen; /* link layer header length */
- hlen = ETHER_HDR_LEN;
+ if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
+ return ENETDOWN;
- /*
- * Tell ether_frameout it's ok to loop packet unless negated below.
- */
- m->m_flags |= M_LOOP;
+ hlen = ETHER_HDR_LEN;
- switch (dst_netaddr->sa_family) {
- case AF_UNSPEC:
- m->m_flags &= ~M_LOOP;
- eh = (struct ether_header *)dst_netaddr->sa_data;
- (void)memcpy(edst, eh->ether_dhost, 6);
- *(u_short *)type = eh->ether_type;
- break;
+ /*
+ * Tell ether_frameout it's ok to loop packet unless negated below.
+ */
+ m->m_flags |= M_LOOP;
+
+ switch (dst_netaddr->sa_family) {
+ case AF_UNSPEC:
+ m->m_flags &= ~M_LOOP;
+ eh = (const struct ether_header *)dst_netaddr->sa_data;
+ (void)memcpy(edst, eh->ether_dhost, 6);
+ *(u_short *)type = eh->ether_type;
+ break;
-
- case AF_APPLETALK:
- {
- eh = (struct ether_header *)dst_netaddr->sa_data;
- bcopy((caddr_t)eh->ether_dhost, (caddr_t)edst, 6);
+ case AF_APPLETALK:
+ eh = (const struct ether_header *)dst_netaddr->sa_data;
+ (void)memcpy(edst, eh->ether_dhost, 6);
+ *(u_short *)type = htons(m->m_pkthdr.len);
+ break;
- *(u_short *)type = m->m_pkthdr.len;
- }
- break;
-
-
- default:
- kprintf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
- dst_netaddr->sa_family);
-
- return EAFNOSUPPORT;
- }
-
- return (0);
+ default:
+ printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
+ dst_netaddr->sa_family);
+ return EAFNOSUPPORT;
+ }
+
+ return (0);
}
-
-int
-ether_prmod_ioctl(
- __unused u_long protocol_family,
- struct ifnet *ifp,
- u_long command,
- caddr_t data)
+static errno_t
+ether_at_prmod_ioctl(
+ ifnet_t ifp,
+ __unused protocol_family_t protocol_family,
+ u_int32_t command,
+ void *data)
{
- struct ifreq *ifr = (struct ifreq *) data;
+ struct ifreq *ifr = data;
int error = 0;
switch (command) {
case SIOCSIFADDR:
if ((ifp->if_flags & IFF_RUNNING) == 0) {
ifnet_set_flags(ifp, IFF_UP, IFF_UP);
- dlil_ioctl(0, ifp, SIOCSIFFLAGS, (caddr_t) 0);
+ ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, NULL);
}
break;
case SIOCGIFADDR:
ifnet_lladdr_copy_bytes(ifp, ifr->ifr_addr.sa_data, ETHER_ADDR_LEN);
- break;
-
- case SIOCSIFMTU:
- /*
- * Set the interface MTU.
- */
- if (ifr->ifr_mtu > ETHERMTU) {
- error = EINVAL;
- } else {
- ifp->if_mtu = ifr->ifr_mtu;
- }
break;
default:
- return EOPNOTSUPP;
+ error = EOPNOTSUPP;
+ break;
}
-
-
return (error);
}
-int
+__private_extern__ errno_t
ether_attach_at(
- struct ifnet *ifp)
+ ifnet_t ifp,
+ __unused protocol_family_t proto_family)
{
- struct dlil_proto_reg_str reg;
- struct dlil_demux_desc desc;
- struct dlil_demux_desc desc2;
- int stat;
- int first_empty;
- int i;
+ struct ifnet_attach_proto_param proto;
+ struct ifnet_demux_desc demux[2];
u_int8_t atalk_snap[5] = {0x08, 0x00, 0x07, 0x80, 0x9b};
u_int8_t aarp_snap[5] = {0x00, 0x00, 0x00, 0x80, 0xf3};
-
- first_empty = MAX_EN_COUNT;
- for (i=0; i < MAX_EN_COUNT; i++) {
- if (en_at_array[i].ifp == 0)
- first_empty = i;
-
- if (en_at_array[i].ifp == ifp) {
- en_at_array[i].ref_count++;
- return 0;
- }
- }
-
- if (first_empty == MAX_EN_COUNT)
- return ENOMEM;
-
- bzero(®, sizeof(reg));
- bzero(&desc, sizeof(desc));
- bzero(&desc2, sizeof(desc2));
+ int error;
+
+ bzero(demux, sizeof(demux));
+ demux[0].type = DLIL_DESC_SNAP;
+ demux[0].data = atalk_snap;
+ demux[0].datalen = sizeof(atalk_snap);
+ demux[1].type = DLIL_DESC_SNAP;
+ demux[1].data = aarp_snap;
+ demux[1].datalen = sizeof(aarp_snap);
+
+ bzero(&proto, sizeof(proto));
+ proto.demux_list = demux;
+ proto.demux_count = sizeof(demux) / sizeof(demux[0]);
+ proto.input = ether_at_input;
+ proto.pre_output = ether_at_pre_output;
+ proto.ioctl = ether_at_prmod_ioctl;
- TAILQ_INIT(®.demux_desc_head);
- reg.interface_family = ifp->if_family;
- reg.unit_number = ifp->if_unit;
- reg.input = at_ether_input;
- reg.pre_output = ether_pre_output;
- reg.ioctl = ether_prmod_ioctl;
- reg.protocol_family = PF_APPLETALK;
-
- desc.type = DLIL_DESC_SNAP;
- desc.native_type = atalk_snap;
- desc.variants.native_type_length = sizeof(atalk_snap);
- TAILQ_INSERT_TAIL(®.demux_desc_head, &desc, next);
-
- desc2.type = DLIL_DESC_SNAP;
- desc2.native_type = aarp_snap;
- desc2.variants.native_type_length = sizeof(aarp_snap);
- TAILQ_INSERT_TAIL(®.demux_desc_head, &desc2, next);
-
- stat = dlil_attach_protocol(®);
- if (stat) {
- printf("WARNING: ether_attach_at can't attach at to interface\n");
- return stat;
+ error = ifnet_attach_protocol(ifp, PF_APPLETALK, &proto);
+ if (error && error != EEXIST) {
+ printf("WARNING: ether_attach_at failed to attach"
+ " AppleTalk to %s%d\n", ifp->if_name, ifp->if_unit);
}
+ return (error);
+}
- en_at_array[first_empty].ifp = ifp;
- en_at_array[first_empty].ref_count = 1;
-
- return 0;
-} /* ether_attach_at */
-
-
-void
-ether_detach_at(struct ifnet *ifp)
+__private_extern__ void
+ether_detach_at(
+ ifnet_t ifp,
+ __unused protocol_family_t proto_family)
{
- int i;
-
- for (i=0; i < MAX_EN_COUNT; i++) {
- if (en_at_array[i].ifp == ifp)
- break;
- }
-
- if (i < MAX_EN_COUNT) {
- if (en_at_array[i].ref_count > 1)
- en_at_array[i].ref_count--;
- else {
- if (en_at_array[i].ref_count == 1) {
- dlil_detach_protocol(ifp, PF_APPLETALK);
- en_at_array[i].ifp = 0;
- }
- }
- }
+ (void)ifnet_detach_protocol(ifp, PF_APPLETALK);
}