X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/de355530ae67247cbd0da700edb3a2a1dae884c2..b7266188b87f3620ec3f9f717e57194a7dd989fe:/bsd/net/ether_at_pr_module.c diff --git a/bsd/net/ether_at_pr_module.c b/bsd/net/ether_at_pr_module.c index d811b9c33..1adcbe27e 100644 --- a/bsd/net/ether_at_pr_module.c +++ b/bsd/net/ether_at_pr_module.c @@ -1,23 +1,29 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000,2009 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * 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 Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * 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 OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * 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_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * Copyright (c) 1982, 1989, 1993 @@ -65,12 +71,13 @@ #include #include -#include #include #include #include #include #include +#include +#include #include @@ -81,388 +88,168 @@ extern struct ifqueue atalkintrq; #endif -#if BRIDGE -#include -#endif - /* #include "vlan.h" */ #if NVLAN > 0 #include #endif /* NVLAN > 0 */ -static -u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - -#define IFP2AC(IFP) ((struct arpcom *)IFP) - - -struct dl_es_at_entry -{ - struct ifnet *ifp; - u_long dl_tag; - int ref_count; -}; - - -/* - * Temp static for protocol registration XXX - */ - -#define MAX_EN_COUNT 30 - -static struct dl_es_at_entry en_at_array[MAX_EN_COUNT]; +#include /* * 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(m, frame_header, ifp, dl_tag, sync_ok) - struct mbuf *m; - char *frame_header; - struct ifnet *ifp; - u_long dl_tag; - 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) { - register struct ether_header *eh = (struct ether_header *) frame_header; - register struct ifqueue *inq=0; - u_short ether_type; - int s; - u_int16_t ptype = -1; - unsigned char buf[18]; - -#if NETAT - register struct llc *l; -#endif - - if ((ifp->if_flags & IFF_UP) == 0) { - m_freem(m); - return EJUSTRETURN; - } - - ifp->if_lastchange = time; - - if (eh->ether_dhost[0] & 1) { - if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost, - sizeof(etherbroadcastaddr)) == 0) - m->m_flags |= M_BCAST; - else - m->m_flags |= M_MCAST; - } - if (m->m_flags & (M_BCAST|M_MCAST)) - ifp->if_imcasts++; - - ether_type = ntohs(eh->ether_type); - -#if NVLAN > 0 - if (ether_type == vlan_proto) { - if (vlan_input(eh, m) < 0) - ifp->if_data.ifi_noproto++; - return EJUSTRETURN; - } -#endif /* NVLAN > 0 */ - - if (ether_type > ETHERMTU) - return ENOENT; - -#if NETAT - l = mtod(m, struct llc *); - - switch (l->llc_dsap) { - case LLC_SNAP_LSAP: - - /* Temporary hack: check for AppleTalk and AARP packets */ - /* WARNING we're checking only on the "ether_type" (the 2 bytes - * of the SNAP header. This shouldn't be a big deal, - * AppleTalk pat_input is making sure we have the right packets - * because it needs to discrimante AARP from EtherTalk packets. - */ - - if (l->llc_ssap == LLC_SNAP_LSAP && - l->llc_un.type_snap.control == 0x03) { - -#ifdef APPLETALK_DEBUG - printf("new_ether_input: SNAP Cntrol type=0x%x Src=%s\n", - l->llc_un.type_snap.ether_type, - ether_sprintf(buf, &eh->ether_shost)); - printf(" Dst=%s\n", - ether_sprintf(buf, &eh->ether_dhost)); -#endif /* APPLETALK_DEBUG */ - - if ((l->llc_un.type_snap.ether_type == 0x809B) || - (l->llc_un.type_snap.ether_type == 0x80F3)) { - - - /* - * 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. - */ - - m->m_data -= sizeof(*eh); - m->m_len += sizeof(*eh); - m->m_pkthdr.len += sizeof(*eh); -#ifdef APPLETALK_DEBUG - l == (struct llc *)(eh+1); - if (l->llc_un.type_snap.ether_type == 0x80F3) { - kprintf("new_ether_input: RCV AppleTalk type=0x%x Src=%s\n", - l->llc_un.type_snap.ether_type, - ether_sprintf(buf, &eh->ether_shost)); - kprintf(" Dst=%s\n", - ether_sprintf(buf, &eh->ether_dhost)); - } -#endif /* APPLETALK_DEBUG */ - schednetisr(NETISR_APPLETALK); - inq = &atalkintrq ; - - break; - } - } - - break; - - - default: - return ENOENT; - } - + 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. + */ - if (inq == 0) - return ENOENT; + m->m_data -= sizeof(struct ether_header); + m->m_len += sizeof(struct ether_header); + m->m_pkthdr.len += sizeof(struct ether_header); - s = splimp(); - if (IF_QFULL(inq)) { - IF_DROP(inq); + error = proto_input(PF_APPLETALK, m); + + if (error) m_freem(m); - splx(s); - return EJUSTRETURN; - } else - IF_ENQUEUE(inq, m); - splx(s); - return 0; -#else - return ENOENT; -#endif /* NETAT */ + + return error; } -int -ether_pre_output(ifp, m0, dst_netaddr, route, type, edst, dl_tag ) - struct ifnet *ifp; - struct mbuf **m0; - struct sockaddr *dst_netaddr; - caddr_t route; - char *type; - char *edst; - u_long dl_tag; +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) { - int s; - register struct mbuf *m = *m0; - register struct rtentry *rt; - register struct ether_header *eh; - int off, len = m->m_pkthdr.len; - int hlen; /* link layer header lenght */ - struct arpcom *ac = IFP2AC(ifp); + struct mbuf *m = *m0; + const struct ether_header *eh; + int hlen; /* link layer header length */ + if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) + return ENETDOWN; + hlen = ETHER_HDR_LEN; - if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) - return ENETDOWN; - - hlen = ETHER_HDR_LEN; - - /* - * 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 = (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(dl_tag, ifp, command, data) - u_long dl_tag; - struct ifnet *ifp; - int 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 ifaddr *ifa = (struct ifaddr *) data; - struct ifreq *ifr = (struct ifreq *) data; + struct ifreq *ifr = data; int error = 0; - boolean_t funnel_state; - struct arpcom *ac = (struct arpcom *) ifp; - struct sockaddr_dl *sdl; - struct sockaddr_in *sin; - u_char *e_addr; - - - funnel_state = thread_funnel_set(network_flock, TRUE); switch (command) { case SIOCSIFADDR: if ((ifp->if_flags & IFF_RUNNING) == 0) { - ifp->if_flags |= IFF_UP; - dlil_ioctl(0, ifp, SIOCSIFFLAGS, (caddr_t) 0); + ifnet_set_flags(ifp, IFF_UP, IFF_UP); + ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, NULL); } break; case SIOCGIFADDR: - { - struct sockaddr *sa; - - sa = (struct sockaddr *) & ifr->ifr_data; - bcopy(IFP2AC(ifp)->ac_enaddr, - (caddr_t) sa->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; - } + ifnet_lladdr_copy_bytes(ifp, ifr->ifr_addr.sa_data, ETHER_ADDR_LEN); break; default: - return EOPNOTSUPP; + error = EOPNOTSUPP; + break; } - - (void) thread_funnel_set(network_flock, funnel_state); - return (error); } -void -ether_attach_at(struct ifnet *ifp, u_long *at_dl_tag, u_long *aarp_dl_tag) +__private_extern__ errno_t +ether_attach_at( + 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; - u_short native = 0; /* 802.2 frames use a length here */ - int stat; - int first_empty; - int i; - - - 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++; - *at_dl_tag = *aarp_dl_tag = en_at_array[i].dl_tag; - return; + 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}; + 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; + + 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); } - } - - if (first_empty == MAX_EN_COUNT) - return; - - TAILQ_INIT(®.demux_desc_head); - desc.type = DLIL_DESC_802_2_SNAP; - desc.variants.desc_802_2_SNAP.dsap = LLC_SNAP_LSAP; - desc.variants.desc_802_2_SNAP.ssap = LLC_SNAP_LSAP; - desc.variants.desc_802_2_SNAP.control_code = 0x03; - desc.variants.desc_802_2_SNAP.org[0] = 0x08; - desc.variants.desc_802_2_SNAP.org[1] = 0x00; - desc.variants.desc_802_2_SNAP.org[2] = 0x07; - desc.variants.desc_802_2_SNAP.protocol_type = 0x809B; - desc.native_type = NULL; - TAILQ_INSERT_TAIL(®.demux_desc_head, &desc, next); - reg.interface_family = ifp->if_family; - reg.unit_number = ifp->if_unit; - reg.input = at_ether_input; - reg.pre_output = ether_pre_output; - reg.event = 0; - reg.offer = 0; - reg.ioctl = ether_prmod_ioctl; - reg.default_proto = 0; - reg.protocol_family = PF_APPLETALK; - - desc2 = desc; - desc2.variants.desc_802_2_SNAP.protocol_type = 0x80F3; - desc2.variants.desc_802_2_SNAP.org[0] = 0; - desc2.variants.desc_802_2_SNAP.org[1] = 0; - desc2.variants.desc_802_2_SNAP.org[2] = 0; - - TAILQ_INSERT_TAIL(®.demux_desc_head, &desc2, next); - - stat = dlil_attach_protocol(®, at_dl_tag); - if (stat) { - printf("WARNING: ether_attach_at can't attach at to interface\n"); - return; - } - - *aarp_dl_tag = *at_dl_tag; - - en_at_array[first_empty].ifp = ifp; - en_at_array[first_empty].dl_tag = *at_dl_tag; - en_at_array[first_empty].ref_count = 1; - -} /* ether_attach_at */ - + return (error); +} -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(en_at_array[i].dl_tag); - en_at_array[i].ifp = 0; - } - } - } + (void)ifnet_detach_protocol(ifp, PF_APPLETALK); }