*
* @APPLE_LICENSE_HEADER_START@
*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ * 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. 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
+ * This 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.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#include <sys/sysctl.h>
#include <net/if.h>
-#include <net/netisr.h>
#include <net/route.h>
#include <net/if_llc.h>
#include <net/if_dl.h>
#include <net/if_vlan_var.h>
#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;
+ 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
* 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;
+at_ether_input(
+ struct mbuf *m,
+ __unused char *frame_header,
+ __unused struct ifnet *ifp,
+ __unused u_long protocol_family,
+ __unused int sync_ok)
{
- 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;
- }
-
-
- if (inq == 0)
- return ENOENT;
+ /*
+ * 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(struct ether_header);
+ m->m_len += sizeof(struct ether_header);
+ m->m_pkthdr.len += sizeof(struct ether_header);
+ proto_input(PF_APPLETALK, m);
- s = splimp();
- if (IF_QFULL(inq)) {
- IF_DROP(inq);
- m_freem(m);
- splx(s);
- return EJUSTRETURN;
- } else
- IF_ENQUEUE(inq, m);
- splx(s);
return 0;
-#else
- return ENOENT;
-#endif /* NETAT */
}
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;
+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)
{
- 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);
int
-ether_prmod_ioctl(dl_tag, ifp, command, data)
- u_long dl_tag;
- struct ifnet *ifp;
- int command;
- caddr_t data;
+ether_prmod_ioctl(
+ __unused u_long protocol_family,
+ struct ifnet *ifp,
+ u_long command,
+ caddr_t data)
{
- struct ifaddr *ifa = (struct ifaddr *) data;
struct ifreq *ifr = (struct ifreq *) 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;
+ ifnet_set_flags(ifp, IFF_UP, IFF_UP);
dlil_ioctl(0, ifp, SIOCSIFFLAGS, (caddr_t) 0);
}
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);
- }
+ ifnet_lladdr_copy_bytes(ifp, ifr->ifr_addr.sa_data, ETHER_ADDR_LEN);
break;
case SIOCSIFMTU:
return EOPNOTSUPP;
}
- (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)
+int
+ether_attach_at(
+ struct ifnet *ifp)
{
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;
-
+ 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++;
- *at_dl_tag = *aarp_dl_tag = en_at_array[i].dl_tag;
- return;
- }
+ 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;
-
- 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;
+ if (first_empty == MAX_EN_COUNT)
+ return ENOMEM;
+
+ bzero(®, sizeof(reg));
+ bzero(&desc, sizeof(desc));
+ bzero(&desc2, sizeof(desc2));
+
+ 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;
+ }
+ 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)
{
- 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;
- }
- }
- }
+ 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;
+ }
+ }
+ }
}