/*
- * Copyright (c) 2000-2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2013 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_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
* 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,
* 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_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
-#include <kern/lock.h>
+#include <net/dlil.h>
#include <net/if.h>
#include <net/route.h>
#include <net/if_llc.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/kpi_protocol.h>
-
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/if_ether.h>
struct ether_addr *macaddr);
#define _ip_copy(dst, src) \
- (*(dst) = *(src))
+ bcopy(src, dst, sizeof (struct in_addr))
static void
ether_inet_arp_input(struct ifnet *ifp, struct mbuf *m)
bzero(&sender_ip, sizeof (sender_ip));
sender_ip.sin_len = sizeof (sender_ip);
sender_ip.sin_family = AF_INET;
- _ip_copy(&sender_ip.sin_addr, (const struct in_addr *)ea->arp_spa);
+ _ip_copy(&sender_ip.sin_addr, ea->arp_spa);
target_ip = sender_ip;
- _ip_copy(&target_ip.sin_addr, (const struct in_addr *)ea->arp_tpa);
+ _ip_copy(&target_ip.sin_addr, ea->arp_tpa);
bzero(&sender_hw, sizeof (sender_hw));
sender_hw.sdl_len = sizeof (sender_hw);
struct sockaddr_dl ll_dest;
result = arp_lookup_ip(ifp,
- (const struct sockaddr_in *)dst_netaddr, &ll_dest,
- sizeof (ll_dest), (route_t)route, *m0);
+ (const struct sockaddr_in *)(uintptr_t)(size_t)dst_netaddr,
+ &ll_dest, sizeof (ll_dest), (route_t)route, *m0);
if (result == 0) {
+ u_int16_t ethertype_ip = htons(ETHERTYPE_IP);
+
bcopy(LLADDR(&ll_dest), edst, ETHER_ADDR_LEN);
- *(u_int16_t *)type = htons(ETHERTYPE_IP);
+ bcopy(ðertype_ip, type, sizeof (ethertype_ip));
}
- break;
+ break;
}
case pseudo_AF_HDRCMPLT:
case AF_UNSPEC:
m->m_flags &= ~M_LOOP;
- eh = (const struct ether_header *)dst_netaddr->sa_data;
+ eh = (const struct ether_header *)(uintptr_t)(size_t)
+ dst_netaddr->sa_data;
(void) memcpy(edst, eh->ether_dhost, 6);
- *(u_short *)type = eh->ether_type;
+ bcopy(&eh->ether_type, type, sizeof (u_short));
break;
default:
- printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
+ printf("%s: can't handle af%d\n", if_name(ifp),
dst_netaddr->sa_family);
result = EAFNOSUPPORT;
{
static const size_t minsize =
offsetof(struct sockaddr_dl, sdl_data[0]) + ETHER_ADDR_LEN;
- const struct sockaddr_in *sin = (const struct sockaddr_in *)proto_addr;
+ const struct sockaddr_in *sin =
+ (const struct sockaddr_in *)(uintptr_t)(size_t)proto_addr;
if (proto_addr->sa_family != AF_INET)
return (EAFNOSUPPORT);
u_long command, void *data)
{
#pragma unused(protocol_family)
- ifaddr_t ifa = data;
- struct ifreq *ifr = data;
int error = 0;
switch (command) {
- case SIOCSIFADDR:
- case SIOCAIFADDR:
+ case SIOCSIFADDR: /* struct ifaddr pointer */
+ case SIOCAIFADDR: { /* struct ifaddr pointer */
+ /*
+ * Note: caller of ifnet_ioctl() passes in pointer to
+ * struct ifaddr as parameter to SIOC{A,S}IFADDR, for
+ * legacy reasons.
+ */
+ struct ifaddr *ifa = data;
+
if (!(ifnet_flags(ifp) & IFF_RUNNING)) {
ifnet_set_flags(ifp, IFF_UP, IFF_UP);
ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, NULL);
break;
inet_arp_init_ifaddr(ifp, ifa);
+
+ if (command != SIOCSIFADDR)
+ break;
+
/*
* Register new IP and MAC addresses with the kernel
* debugger if the interface is the same as was registered
* Do this only for the first address of the interface
* and not for aliases.
*/
- if (command == SIOCSIFADDR &&
- ((kdp_get_interface() != 0 &&
+ if ((kdp_get_interface() != 0 &&
kdp_get_interface() == ifp->if_softc) ||
- (kdp_get_interface() == 0 && ifp->if_unit == 0)))
+ (kdp_get_interface() == 0 && ifp->if_unit == 0))
kdp_set_ip_and_mac_addresses(&(IA_SIN(ifa)->sin_addr),
- ifnet_lladdr(ifp));
+ (struct ether_addr *)IF_LLADDR(ifp));
break;
+ }
- case SIOCGIFADDR:
- ifnet_lladdr_copy_bytes(ifp, ifr->ifr_addr.sa_data,
+ case SIOCGIFADDR: { /* struct ifreq */
+ struct ifreq *ifr = data;
+ ifnet_guarded_lladdr_copy_bytes(ifp, ifr->ifr_addr.sa_data,
ETHER_ADDR_LEN);
break;
+ }
default:
error = EOPNOTSUPP;
struct ether_header *eh;
struct ether_arp *ea;
const struct sockaddr_in *sender_ip =
- (const struct sockaddr_in *)sender_proto;
- const struct sockaddr_in *target_ip =
- (const struct sockaddr_in *)target_proto;
+ (const struct sockaddr_in *)(uintptr_t)(size_t)sender_proto;
+ const struct sockaddr_inarp *target_ip =
+ (const struct sockaddr_inarp *)(uintptr_t)(size_t)target_proto;
char *datap;
if (target_ip == NULL)
IFA_LOCK(ifa);
if (ifa->ifa_addr != NULL &&
ifa->ifa_addr->sa_family == AF_INET) {
- bcopy(&((struct sockaddr_in *)ifa->ifa_addr)->
- sin_addr, ea->arp_spa, sizeof(ea->arp_spa));
+ bcopy(&((struct sockaddr_in *)(void *)
+ ifa->ifa_addr)->sin_addr, ea->arp_spa,
+ sizeof (ea->arp_spa));
IFA_UNLOCK(ifa);
break;
}
bzero(ea->arp_tha, sizeof (ea->arp_tha));
bcopy(etherbroadcastaddr, eh->ether_dhost,
sizeof (eh->ether_dhost));
+ m->m_flags |= M_BCAST;
} else {
bcopy(CONST_LLADDR(target_hw), ea->arp_tha,
sizeof (ea->arp_tha));
bcopy(CONST_LLADDR(target_hw), eh->ether_dhost,
sizeof (eh->ether_dhost));
+
+ if (bcmp(eh->ether_dhost, etherbroadcastaddr,
+ ETHER_ADDR_LEN) == 0)
+ m->m_flags |= M_BCAST;
}
/* Target IP */
bcopy(&target_ip->sin_addr, ea->arp_tpa, sizeof (ea->arp_tpa));
+ /*
+ * PKTF_{INET,INET6}_RESOLVE_RTR are mutually exclusive, so make
+ * sure only one of them is set (just in case.)
+ */
+ m->m_pkthdr.pkt_flags &= ~(PKTF_INET6_RESOLVE | PKTF_RESOLVE_RTR);
+ m->m_pkthdr.pkt_flags |= PKTF_INET_RESOLVE;
+ /*
+ * If this is an ARP request for a (default) router, mark
+ * the packet accordingly so that the driver can find out,
+ * in case it needs to perform driver-specific action(s).
+ */
+ if (arpop == ARPOP_REQUEST && (target_ip->sin_other & SIN_ROUTER))
+ m->m_pkthdr.pkt_flags |= PKTF_RESOLVE_RTR;
+
+ if (ifp->if_eflags & IFEF_TXSTART) {
+ /*
+ * Use control service class if the interface
+ * supports transmit-start model
+ */
+ (void) m_set_service_class(m, MBUF_SC_CTL);
+ }
+
ifnet_output_raw(ifp, PF_INET, m);
return (0);
error = ifnet_attach_protocol_v2(ifp, proto_family, &proto);
if (error && error != EEXIST) {
- printf("WARNING: %s can't attach ip to %s%d\n", __func__,
- ifp->if_name, ifp->if_unit);
+ printf("WARNING: %s can't attach ip to %s\n", __func__,
+ if_name(ifp));
}
return (error);
}