1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2015 Joyent, Inc. All rights reserved.
  25  */
  26 
  27 #include <sys/types.h>
  28 #include <sys/param.h>
  29 #include <sys/systm.h>
  30 #include <sys/stropts.h>
  31 #include <sys/socket.h>
  32 #include <sys/socketvar.h>
  33 #include <sys/socket_proto.h>
  34 #include <sys/sockio.h>
  35 #include <sys/strsun.h>
  36 #include <sys/kstat.h>
  37 #include <sys/modctl.h>
  38 #include <sys/policy.h>
  39 #include <sys/priv_const.h>
  40 #include <sys/tihdr.h>
  41 #include <sys/zone.h>
  42 #include <sys/time.h>
  43 #include <sys/ethernet.h>
  44 #include <sys/llc1.h>
  45 #include <fs/sockfs/sockcommon.h>
  46 #include <net/if.h>
  47 #include <inet/ip_arp.h>
  48 
  49 #include <sys/dls.h>
  50 #include <sys/mac.h>
  51 #include <sys/mac_client.h>
  52 #include <sys/mac_provider.h>
  53 #include <sys/mac_client_priv.h>
  54 
  55 #include <netpacket/packet.h>
  56 
  57 static void pfp_close(mac_handle_t, mac_client_handle_t);
  58 static int pfp_dl_to_arphrd(int);
  59 static int pfp_getpacket_sockopt(sock_lower_handle_t, int, void *,
  60     socklen_t *);
  61 static int pfp_ifreq_getlinkid(intptr_t, struct ifreq *, datalink_id_t *, int);
  62 static int pfp_lifreq_getlinkid(intptr_t, struct lifreq *, datalink_id_t *,
  63     int);
  64 static int pfp_open_index(int, mac_handle_t *, mac_client_handle_t *,
  65     cred_t *);
  66 static void pfp_packet(void *, mac_resource_handle_t, mblk_t *, boolean_t);
  67 static void pfp_release_bpf(struct pfpsock *);
  68 static int pfp_set_promisc(struct pfpsock *, mac_client_promisc_type_t);
  69 static int pfp_setsocket_sockopt(sock_lower_handle_t, int, const void *,
  70     socklen_t);
  71 static int pfp_setpacket_sockopt(sock_lower_handle_t, int, const void *,
  72     socklen_t);
  73 
  74 /*
  75  * PFP sockfs operations
  76  * Most are currently no-ops because they have no meaning for a connectionless
  77  * socket.
  78  */
  79 static void sdpfp_activate(sock_lower_handle_t, sock_upper_handle_t,
  80     sock_upcalls_t *, int, struct cred *);
  81 static int sdpfp_bind(sock_lower_handle_t, struct sockaddr *, socklen_t,
  82     struct cred *);
  83 static int sdpfp_close(sock_lower_handle_t, int, struct cred *);
  84 static void sdpfp_clr_flowctrl(sock_lower_handle_t);
  85 static int sdpfp_getsockopt(sock_lower_handle_t, int, int, void *,
  86     socklen_t *, struct cred *);
  87 static int sdpfp_ioctl(sock_lower_handle_t, int, intptr_t, int, int32_t *,
  88     struct cred *);
  89 static int sdpfp_senduio(sock_lower_handle_t, struct uio *, struct nmsghdr *,
  90     struct cred *);
  91 static int sdpfp_setsockopt(sock_lower_handle_t, int, int, const void *,
  92     socklen_t, struct cred *);
  93 
  94 static sock_lower_handle_t sockpfp_create(int, int, int, sock_downcalls_t **,
  95     uint_t *, int *, int, cred_t *);
  96 
  97 static int sockpfp_init(void);
  98 static void sockpfp_fini(void);
  99 
 100 static kstat_t *pfp_ksp;
 101 static pfp_kstats_t ks_stats;
 102 static pfp_kstats_t pfp_kstats = {
 103         /*
 104          * Each one of these kstats is a different return path in handling
 105          * a packet received from the mac layer.
 106          */
 107         { "recvMacHeaderFail",  KSTAT_DATA_UINT64 },
 108         { "recvBadProtocol",    KSTAT_DATA_UINT64 },
 109         { "recvAllocbFail",     KSTAT_DATA_UINT64 },
 110         { "recvOk",             KSTAT_DATA_UINT64 },
 111         { "recvFail",           KSTAT_DATA_UINT64 },
 112         { "recvFiltered",       KSTAT_DATA_UINT64 },
 113         { "recvFlowControl",    KSTAT_DATA_UINT64 },
 114         /*
 115          * A global set of counters is maintained to track the behaviour
 116          * of the system (kernel & applications) in sending packets.
 117          */
 118         { "sendUnbound",        KSTAT_DATA_UINT64 },
 119         { "sendFailed",         KSTAT_DATA_UINT64 },
 120         { "sendTooBig",         KSTAT_DATA_UINT64 },
 121         { "sendAllocFail",      KSTAT_DATA_UINT64 },
 122         { "sendUiomoveFail",    KSTAT_DATA_UINT64 },
 123         { "sendNoMemory",       KSTAT_DATA_UINT64 },
 124         { "sendOpenFail",       KSTAT_DATA_UINT64 },
 125         { "sendWrongFamily",    KSTAT_DATA_UINT64 },
 126         { "sendShortMsg",       KSTAT_DATA_UINT64 },
 127         { "sendOk",             KSTAT_DATA_UINT64 }
 128 };
 129 
 130 sock_downcalls_t pfp_downcalls = {
 131         sdpfp_activate,
 132         sock_accept_notsupp,
 133         sdpfp_bind,
 134         sock_listen_notsupp,
 135         sock_connect_notsupp,
 136         sock_getpeername_notsupp,
 137         sock_getsockname_notsupp,
 138         sdpfp_getsockopt,
 139         sdpfp_setsockopt,
 140         sock_send_notsupp,
 141         sdpfp_senduio,
 142         NULL,
 143         sock_poll_notsupp,
 144         sock_shutdown_notsupp,
 145         sdpfp_clr_flowctrl,
 146         sdpfp_ioctl,
 147         sdpfp_close,
 148 };
 149 
 150 static smod_reg_t sinfo = {
 151         SOCKMOD_VERSION,
 152         "sockpfp",
 153         SOCK_UC_VERSION,
 154         SOCK_DC_VERSION,
 155         sockpfp_create,
 156         NULL
 157 };
 158 
 159 static int accepted_protos[3][2] = {
 160         { ETH_P_ALL,    0 },
 161         { ETH_P_802_2,  LLC_SNAP_SAP },
 162         { ETH_P_803_3,  0 },
 163 };
 164 
 165 /*
 166  * This sets an upper bound on the size of the receive buffer for a PF_PACKET
 167  * socket. More properly, this should be controlled through ipadm, ala TCP, UDP,
 168  * SCTP, etc. Until that's done, this provides a hard cap of 4 MB and allows an
 169  * opportunity for it to be changed, should it be needed.
 170  */
 171 int sockmod_pfp_rcvbuf_max = 1024 * 1024 * 4;
 172 
 173 /*
 174  * Module linkage information for the kernel.
 175  */
 176 static struct modlsockmod modlsockmod = {
 177         &mod_sockmodops, "PF Packet socket module", &sinfo
 178 };
 179 
 180 static struct modlinkage modlinkage = {
 181         MODREV_1,
 182         { &modlsockmod, NULL }
 183 };
 184 
 185 int
 186 _init(void)
 187 {
 188         int error;
 189 
 190         error = sockpfp_init();
 191         if (error != 0)
 192                 return (error);
 193 
 194         error = mod_install(&modlinkage);
 195         if (error != 0)
 196                 sockpfp_fini();
 197 
 198         return (error);
 199 }
 200 
 201 int
 202 _fini(void)
 203 {
 204         int error;
 205 
 206         error = mod_remove(&modlinkage);
 207         if (error == 0)
 208                 sockpfp_fini();
 209 
 210         return (error);
 211 }
 212 
 213 int
 214 _info(struct modinfo *modinfop)
 215 {
 216         return (mod_info(&modlinkage, modinfop));
 217 }
 218 
 219 /*
 220  * sockpfp_init: called as part of the initialisation of the module when
 221  * loaded into the kernel.
 222  *
 223  * Being able to create and record the kstats data in the kernel is not
 224  * considered to be vital to the operation of this kernel module, thus
 225  * its failure is tolerated.
 226  */
 227 static int
 228 sockpfp_init(void)
 229 {
 230         (void) memset(&ks_stats, 0, sizeof (ks_stats));
 231 
 232         (void) memcpy(&ks_stats, &pfp_kstats, sizeof (pfp_kstats));
 233 
 234         pfp_ksp = kstat_create("pfpacket", 0, "global", "misc",
 235             KSTAT_TYPE_NAMED, sizeof (pfp_kstats) / sizeof (kstat_named_t),
 236             KSTAT_FLAG_VIRTUAL);
 237         if (pfp_ksp != NULL) {
 238                 pfp_ksp->ks_data = &ks_stats;
 239                 kstat_install(pfp_ksp);
 240         }
 241 
 242         return (0);
 243 }
 244 
 245 /*
 246  * sockpfp_fini: called when the operating system wants to unload the
 247  * socket module from the kernel.
 248  */
 249 static void
 250 sockpfp_fini(void)
 251 {
 252         if (pfp_ksp != NULL)
 253                 kstat_delete(pfp_ksp);
 254 }
 255 
 256 /*
 257  * Due to sockets being created read-write by default, all PF_PACKET sockets
 258  * therefore require the NET_RAWACCESS priviliege, even if the socket is only
 259  * being used for reading packets from.
 260  *
 261  * This create function enforces this module only being used with PF_PACKET
 262  * sockets and the policy that we support via the config file in sock2path.d:
 263  * PF_PACKET sockets must be either SOCK_DGRAM or SOCK_RAW.
 264  */
 265 /* ARGSUSED */
 266 static sock_lower_handle_t
 267 sockpfp_create(int family, int type, int proto,
 268     sock_downcalls_t **sock_downcalls, uint_t *smodep, int *errorp,
 269     int sflags, cred_t *cred)
 270 {
 271         struct pfpsock *ps;
 272         int kmflags;
 273         int newproto;
 274         int i;
 275 
 276         if (secpolicy_net_rawaccess(cred) != 0) {
 277                 *errorp = EACCES;
 278                 return (NULL);
 279         }
 280 
 281         if (family != AF_PACKET) {
 282                 *errorp = EAFNOSUPPORT;
 283                 return (NULL);
 284         }
 285 
 286         if ((type != SOCK_RAW) && (type != SOCK_DGRAM)) {
 287                 *errorp = ESOCKTNOSUPPORT;
 288                 return (NULL);
 289         }
 290 
 291         /*
 292          * First check to see if the protocol number passed in via the socket
 293          * creation should be mapped to a different number for internal use.
 294          */
 295         for (i = 0, newproto = -1;
 296             i < sizeof (accepted_protos)/ sizeof (accepted_protos[0]); i++) {
 297                 if (accepted_protos[i][0] == proto) {
 298                         newproto = accepted_protos[i][1];
 299                         break;
 300                 }
 301         }
 302 
 303         /*
 304          * If the mapping of the protocol that was under 0x800 failed to find
 305          * a local equivalent then fail the socket creation. If the protocol
 306          * for the socket is over 0x800 and it was not found in the mapping
 307          * table above, then use the value as is.
 308          */
 309         if (newproto == -1) {
 310                 if (proto < 0x800) {
 311                         *errorp = ENOPROTOOPT;
 312                         return (NULL);
 313                 }
 314                 newproto = proto;
 315         }
 316         proto = newproto;
 317 
 318         kmflags = (sflags & SOCKET_NOSLEEP) ? KM_NOSLEEP : KM_SLEEP;
 319         ps = kmem_zalloc(sizeof (*ps), kmflags);
 320         if (ps == NULL) {
 321                 *errorp = ENOMEM;
 322                 return (NULL);
 323         }
 324 
 325         ps->ps_type = type;
 326         ps->ps_proto = proto;
 327         rw_init(&ps->ps_bpflock, NULL, RW_DRIVER, NULL);
 328         mutex_init(&ps->ps_lock, NULL, MUTEX_DRIVER, NULL);
 329 
 330         *sock_downcalls = &pfp_downcalls;
 331         /*
 332          * Setting this causes bytes from a packet that do not fit into the
 333          * destination user buffer to be discarded. Thus the API is one
 334          * packet per receive and callers are required to use a buffer large
 335          * enough for the biggest packet that the interface can provide.
 336          */
 337         *smodep = SM_ATOMIC;
 338 
 339         return ((sock_lower_handle_t)ps);
 340 }
 341 
 342 /* ************************************************************************* */
 343 
 344 /*
 345  * pfp_packet is the callback function that is given to the mac layer for
 346  * PF_PACKET to receive packets with. One packet at a time is passed into
 347  * this function from the mac layer. Each packet is a private copy given
 348  * to PF_PACKET to modify or free as it wishes and does not harm the original
 349  * packet from which it was cloned.
 350  */
 351 /* ARGSUSED */
 352 static void
 353 pfp_packet(void *arg, mac_resource_handle_t mrh, mblk_t *mp, boolean_t flag)
 354 {
 355         struct T_unitdata_ind *tunit;
 356         struct sockaddr_ll *sll;
 357         struct sockaddr_ll *sol;
 358         mac_header_info_t hdr;
 359         struct pfpsock *ps;
 360         size_t tusz;
 361         mblk_t *mp0;
 362         int error;
 363 
 364         if (mp == NULL)
 365                 return;
 366 
 367         ps = arg;
 368         if (ps->ps_flow_ctrld) {
 369                 ps->ps_flow_ctrl_drops++;
 370                 ps->ps_stats.tp_drops++;
 371                 ks_stats.kp_recv_flow_cntrld.value.ui64++;
 372                 freemsg(mp);
 373                 return;
 374         }
 375 
 376         if (mac_header_info(ps->ps_mh, mp, &hdr) != 0) {
 377                 /*
 378                  * Can't decode the packet header information so drop it.
 379                  */
 380                 ps->ps_stats.tp_drops++;
 381                 ks_stats.kp_recv_mac_hdr_fail.value.ui64++;
 382                 freemsg(mp);
 383                 return;
 384         }
 385 
 386         if (mac_type(ps->ps_mh) == DL_ETHER &&
 387             hdr.mhi_bindsap == ETHERTYPE_VLAN) {
 388                 struct ether_vlan_header *evhp;
 389                 struct ether_vlan_header evh;
 390 
 391                 hdr.mhi_hdrsize = sizeof (struct ether_vlan_header);
 392                 hdr.mhi_istagged = B_TRUE;
 393 
 394                 if (MBLKL(mp) >= sizeof (*evhp)) {
 395                         evhp = (struct ether_vlan_header *)mp->b_rptr;
 396                 } else {
 397                         int sz = sizeof (*evhp);
 398                         char *s = (char *)&evh;
 399                         mblk_t *tmp;
 400                         int len;
 401 
 402                         for (tmp = mp; sz > 0 && tmp != NULL;
 403                             tmp = tmp->b_cont) {
 404                                 len = min(sz, MBLKL(tmp));
 405                                 bcopy(tmp->b_rptr, s, len);
 406                                 sz -= len;
 407                         }
 408                         evhp = &evh;
 409                 }
 410                 hdr.mhi_tci = ntohs(evhp->ether_tci);
 411                 hdr.mhi_bindsap = ntohs(evhp->ether_type);
 412         }
 413 
 414         if ((ps->ps_proto != 0) && (ps->ps_proto != hdr.mhi_bindsap)) {
 415                 /*
 416                  * The packet is not of interest to this socket so
 417                  * drop it on the floor. Here the SAP is being used
 418                  * as a very course filter.
 419                  */
 420                 ps->ps_stats.tp_drops++;
 421                 ks_stats.kp_recv_bad_proto.value.ui64++;
 422                 freemsg(mp);
 423                 return;
 424         }
 425 
 426         /*
 427          * This field is not often set, even for ethernet,
 428          * by mac_header_info, so compute it if it is 0.
 429          */
 430         if (hdr.mhi_pktsize == 0)
 431                 hdr.mhi_pktsize = msgdsize(mp);
 432 
 433         /*
 434          * If a BPF filter is present, pass the raw packet into that.
 435          * A failed match will result in zero being returned, indicating
 436          * that this socket is not interested in the packet.
 437          */
 438         if (ps->ps_bpf.bf_len != 0) {
 439                 uchar_t *buffer;
 440                 int buflen;
 441 
 442                 buflen = MBLKL(mp);
 443                 if (hdr.mhi_pktsize == buflen) {
 444                         buffer = mp->b_rptr;
 445                 } else {
 446                         buflen = 0;
 447                         buffer = (uchar_t *)mp;
 448                 }
 449                 rw_enter(&ps->ps_bpflock, RW_READER);
 450                 if (bpf_filter(ps->ps_bpf.bf_insns, buffer,
 451                     hdr.mhi_pktsize, buflen) == 0) {
 452                         rw_exit(&ps->ps_bpflock);
 453                         ps->ps_stats.tp_drops++;
 454                         ks_stats.kp_recv_filtered.value.ui64++;
 455                         freemsg(mp);
 456                         return;
 457                 }
 458                 rw_exit(&ps->ps_bpflock);
 459         }
 460 
 461         if (ps->ps_type == SOCK_DGRAM) {
 462                 /*
 463                  * SOCK_DGRAM socket expect a "layer 3" packet, so advance
 464                  * past the link layer header.
 465                  */
 466                 mp->b_rptr += hdr.mhi_hdrsize;
 467                 hdr.mhi_pktsize -= hdr.mhi_hdrsize;
 468         }
 469 
 470         tusz = sizeof (struct T_unitdata_ind) + sizeof (struct sockaddr_ll);
 471         if (ps->ps_auxdata) {
 472                 tusz += _TPI_ALIGN_TOPT(sizeof (struct tpacket_auxdata));
 473                 tusz += _TPI_ALIGN_TOPT(sizeof (struct T_opthdr));
 474         }
 475 
 476         /*
 477          * It is tempting to think that this could be optimised by having
 478          * the base mblk_t allocated and hung off the pfpsock structure,
 479          * except that then another one would need to be allocated for the
 480          * sockaddr_ll that is included. Even creating a template to copy
 481          * from is of questionable value, as read-write from one structure
 482          * to the other is going to be slower than all of the initialisation.
 483          */
 484         mp0 = allocb(tusz, BPRI_HI);
 485         if (mp0 == NULL) {
 486                 ps->ps_stats.tp_drops++;
 487                 ks_stats.kp_recv_alloc_fail.value.ui64++;
 488                 freemsg(mp);
 489                 return;
 490         }
 491 
 492         (void) memset(mp0->b_rptr, 0, tusz);
 493 
 494         mp0->b_datap->db_type = M_PROTO;
 495         mp0->b_wptr = mp0->b_rptr + tusz;
 496 
 497         tunit = (struct T_unitdata_ind *)mp0->b_rptr;
 498         tunit->PRIM_type = T_UNITDATA_IND;
 499         tunit->SRC_length = sizeof (struct sockaddr);
 500         tunit->SRC_offset = sizeof (*tunit);
 501 
 502         sol = &ps->ps_sock;
 503         sll = (struct sockaddr_ll *)(mp0->b_rptr + sizeof (*tunit));
 504         sll->sll_ifindex = sol->sll_ifindex;
 505         sll->sll_hatype = (uint16_t)hdr.mhi_origsap;
 506         sll->sll_halen = sol->sll_halen;
 507         if (hdr.mhi_saddr != NULL)
 508                 (void) memcpy(sll->sll_addr, hdr.mhi_saddr, sll->sll_halen);
 509 
 510         switch (hdr.mhi_dsttype) {
 511         case MAC_ADDRTYPE_MULTICAST :
 512                 sll->sll_pkttype = PACKET_MULTICAST;
 513                 break;
 514         case MAC_ADDRTYPE_BROADCAST :
 515                 sll->sll_pkttype = PACKET_BROADCAST;
 516                 break;
 517         case MAC_ADDRTYPE_UNICAST :
 518                 if (memcmp(sol->sll_addr, hdr.mhi_daddr, sol->sll_halen) == 0)
 519                         sll->sll_pkttype = PACKET_HOST;
 520                 else
 521                         sll->sll_pkttype = PACKET_OTHERHOST;
 522                 break;
 523         }
 524 
 525         if (ps->ps_auxdata) {
 526                 struct tpacket_auxdata *aux;
 527                 struct T_opthdr *topt;
 528 
 529                 tunit->OPT_offset = _TPI_ALIGN_TOPT(tunit->SRC_offset +
 530                     sizeof (struct sockaddr_ll));
 531                 tunit->OPT_length = _TPI_ALIGN_TOPT(sizeof (struct T_opthdr)) +
 532                     _TPI_ALIGN_TOPT(sizeof (struct tpacket_auxdata));
 533 
 534                 topt = (struct T_opthdr *)(mp0->b_rptr + tunit->OPT_offset);
 535                 aux = (struct tpacket_auxdata *)
 536                     ((char *)topt + _TPI_ALIGN_TOPT(sizeof (*topt)));
 537 
 538                 topt->len = tunit->OPT_length;
 539                 topt->level = SOL_PACKET;
 540                 topt->name = PACKET_AUXDATA;
 541                 topt->status = 0;
 542                 /*
 543                  * libpcap doesn't seem to use any other field,
 544                  * so it isn't clear how they should be filled in.
 545                  */
 546                 aux->tp_vlan_vci = hdr.mhi_tci;
 547         }
 548 
 549         linkb(mp0, mp);
 550 
 551         (void) gethrestime(&ps->ps_timestamp);
 552 
 553         ps->ps_upcalls->su_recv(ps->ps_upper, mp0, hdr.mhi_pktsize, 0,
 554             &error, NULL);
 555 
 556         if (error == 0) {
 557                 ps->ps_stats.tp_packets++;
 558                 ks_stats.kp_recv_ok.value.ui64++;
 559         } else {
 560                 mutex_enter(&ps->ps_lock);
 561                 if (error == ENOSPC) {
 562                         ps->ps_upcalls->su_recv(ps->ps_upper, NULL, 0, 0,
 563                             &error, NULL);
 564                         if (error == ENOSPC)
 565                                 ps->ps_flow_ctrld = B_TRUE;
 566                 }
 567                 mutex_exit(&ps->ps_lock);
 568                 ps->ps_stats.tp_drops++;
 569                 ks_stats.kp_recv_fail.value.ui64++;
 570         }
 571 }
 572 
 573 /*
 574  * Bind a PF_PACKET socket to a network interface.
 575  *
 576  * The default operation of this bind() is to place the socket (and thus the
 577  * network interface) into promiscuous mode. It is then up to the application
 578  * to turn that down by issuing the relevant ioctls, if desired.
 579  */
 580 static int
 581 sdpfp_bind(sock_lower_handle_t handle, struct sockaddr *addr,
 582     socklen_t addrlen, struct cred *cred)
 583 {
 584         struct sockaddr_ll *addr_ll, *sol;
 585         mac_client_handle_t mch;
 586         struct pfpsock *ps;
 587         mac_handle_t mh;
 588         int error;
 589 
 590         ps = (struct pfpsock *)handle;
 591         if (ps->ps_bound)
 592                 return (EINVAL);
 593 
 594         if (addrlen < sizeof (struct sockaddr_ll) || addr == NULL)
 595                 return (EINVAL);
 596 
 597         addr_ll = (struct sockaddr_ll *)addr;
 598 
 599         error = pfp_open_index(addr_ll->sll_ifindex, &mh, &mch, cred);
 600         if (error != 0)
 601                 return (error);
 602         /*
 603          * Ensure that each socket is only bound once.
 604          */
 605         mutex_enter(&ps->ps_lock);
 606         if (ps->ps_mh != 0) {
 607                 mutex_exit(&ps->ps_lock);
 608                 pfp_close(mh, mch);
 609                 return (EADDRINUSE);
 610         }
 611         ps->ps_mh = mh;
 612         ps->ps_mch = mch;
 613         mutex_exit(&ps->ps_lock);
 614 
 615         /*
 616          * Cache all of the information from bind so that it's in an easy
 617          * place to get at when packets are received.
 618          */
 619         sol = &ps->ps_sock;
 620         sol->sll_family = AF_PACKET;
 621         sol->sll_ifindex = addr_ll->sll_ifindex;
 622         sol->sll_protocol = addr_ll->sll_protocol;
 623         sol->sll_halen = mac_addr_len(ps->ps_mh);
 624         mac_unicast_primary_get(ps->ps_mh, sol->sll_addr);
 625         mac_sdu_get(ps->ps_mh, NULL, &ps->ps_max_sdu);
 626         ps->ps_linkid = addr_ll->sll_ifindex;
 627 
 628         error = mac_promisc_add(ps->ps_mch, MAC_CLIENT_PROMISC_ALL,
 629             pfp_packet, ps, &ps->ps_phd, MAC_PROMISC_FLAGS_VLAN_TAG_STRIP);
 630         if (error == 0) {
 631                 ps->ps_promisc = MAC_CLIENT_PROMISC_ALL;
 632                 ps->ps_bound = B_TRUE;
 633         }
 634 
 635         return (error);
 636 }
 637 
 638 /* ARGSUSED */
 639 static void
 640 sdpfp_activate(sock_lower_handle_t lower, sock_upper_handle_t upper,
 641     sock_upcalls_t *upcalls, int flags, cred_t *cred)
 642 {
 643         struct pfpsock *ps;
 644 
 645         ps = (struct pfpsock *)lower;
 646         ps->ps_upper = upper;
 647         ps->ps_upcalls = upcalls;
 648 }
 649 
 650 /*
 651  * This module only implements getting socket options for the new socket
 652  * option level (SOL_PACKET) that it introduces. All other requests are
 653  * passed back to the sockfs layer.
 654  */
 655 /* ARGSUSED */
 656 static int
 657 sdpfp_getsockopt(sock_lower_handle_t handle, int level, int option_name,
 658     void *optval, socklen_t *optlenp, struct cred *cred)
 659 {
 660         struct pfpsock *ps;
 661         int error = 0;
 662 
 663         ps = (struct pfpsock *)handle;
 664 
 665         switch (level) {
 666         case SOL_PACKET :
 667                 error = pfp_getpacket_sockopt(handle, option_name, optval,
 668                     optlenp);
 669                 break;
 670 
 671         case SOL_SOCKET :
 672                 if (option_name == SO_RCVBUF) {
 673                         if (*optlenp < sizeof (int32_t))
 674                                 return (EINVAL);
 675                         *((int32_t *)optval) = ps->ps_rcvbuf;
 676                         *optlenp = sizeof (int32_t);
 677                 } else {
 678                         error = ENOPROTOOPT;
 679                 }
 680                 break;
 681 
 682         default :
 683                 /*
 684                  * If sockfs code receives this error in return from the
 685                  * getsockopt downcall it handles the option locally, if
 686                  * it can.
 687                  */
 688                 error = ENOPROTOOPT;
 689                 break;
 690         }
 691 
 692         return (error);
 693 }
 694 
 695 /*
 696  * PF_PACKET supports setting socket options at only two levels:
 697  * SOL_SOCKET and SOL_PACKET.
 698  */
 699 /* ARGSUSED */
 700 static int
 701 sdpfp_setsockopt(sock_lower_handle_t handle, int level, int option_name,
 702     const void *optval, socklen_t optlen, struct cred *cred)
 703 {
 704         int error = 0;
 705 
 706         switch (level) {
 707         case SOL_SOCKET :
 708                 error = pfp_setsocket_sockopt(handle, option_name, optval,
 709                     optlen);
 710                 break;
 711         case SOL_PACKET :
 712                 error = pfp_setpacket_sockopt(handle, option_name, optval,
 713                     optlen);
 714                 break;
 715         default :
 716                 error = EINVAL;
 717                 break;
 718         }
 719 
 720         return (error);
 721 }
 722 
 723 /*
 724  * This function is incredibly inefficient for sending any packet that
 725  * comes with a msghdr asking to be sent to an interface to which the
 726  * socket has not been bound. Some possibilities here are keeping a
 727  * cache of all open mac's and mac_client's, for the purpose of sending,
 728  * and closing them after some amount of inactivity. Clearly, applications
 729  * should not be written to use one socket for multiple interfaces if
 730  * performance is desired with the code as is.
 731  */
 732 /* ARGSUSED */
 733 static int
 734 sdpfp_senduio(sock_lower_handle_t handle, struct uio *uiop,
 735     struct nmsghdr *msg, struct cred *cred)
 736 {
 737         struct sockaddr_ll *sol;
 738         mac_client_handle_t mch;
 739         struct pfpsock *ps;
 740         boolean_t new_open;
 741         mac_handle_t mh;
 742         size_t mpsize;
 743         uint_t maxsdu;
 744         mblk_t *mp0;
 745         mblk_t *mp;
 746         int error;
 747 
 748         mp = NULL;
 749         mp0 = NULL;
 750         new_open = B_FALSE;
 751         ps = (struct pfpsock *)handle;
 752         mh = ps->ps_mh;
 753         mch = ps->ps_mch;
 754         maxsdu = ps->ps_max_sdu;
 755 
 756         sol = (struct sockaddr_ll *)msg->msg_name;
 757         if (sol == NULL) {
 758                 /*
 759                  * If no sockaddr_ll has been provided with the send call,
 760                  * use the one constructed when the socket was bound to an
 761                  * interface and fail if it hasn't been bound.
 762                  */
 763                 if (!ps->ps_bound) {
 764                         ks_stats.kp_send_unbound.value.ui64++;
 765                         return (EPROTO);
 766                 }
 767                 sol = &ps->ps_sock;
 768         } else {
 769                 /*
 770                  * Verify the sockaddr_ll message passed down before using
 771                  * it to send a packet out with. If it refers to an interface
 772                  * that has not been bound, it is necessary to open it.
 773                  */
 774                 struct sockaddr_ll *sll;
 775 
 776                 if (msg->msg_namelen < sizeof (struct sockaddr_ll)) {
 777                         ks_stats.kp_send_short_msg.value.ui64++;
 778                         return (EINVAL);
 779                 }
 780 
 781                 if (sol->sll_family != AF_PACKET) {
 782                         ks_stats.kp_send_wrong_family.value.ui64++;
 783                         return (EAFNOSUPPORT);
 784                 }
 785 
 786                 sll = &ps->ps_sock;
 787                 if (sol->sll_ifindex != sll->sll_ifindex) {
 788                         error = pfp_open_index(sol->sll_ifindex, &mh, &mch,
 789                             cred);
 790                         if (error != 0) {
 791                                 ks_stats.kp_send_open_fail.value.ui64++;
 792                                 return (error);
 793                         }
 794                         mac_sdu_get(mh, NULL, &maxsdu);
 795                         new_open = B_TRUE;
 796                 }
 797         }
 798 
 799         mpsize = uiop->uio_resid;
 800         if (mpsize > maxsdu) {
 801                 ks_stats.kp_send_too_big.value.ui64++;
 802                 error = EMSGSIZE;
 803                 goto done;
 804         }
 805 
 806         if ((mp = allocb(mpsize, BPRI_HI)) == NULL) {
 807                 ks_stats.kp_send_alloc_fail.value.ui64++;
 808                 error = ENOBUFS;
 809                 goto done;
 810         }
 811 
 812         mp->b_wptr = mp->b_rptr + mpsize;
 813         error = uiomove(mp->b_rptr, mpsize, UIO_WRITE, uiop);
 814         if (error != 0) {
 815                 ks_stats.kp_send_uiomove_fail.value.ui64++;
 816                 goto done;
 817         }
 818 
 819         if (ps->ps_type == SOCK_DGRAM) {
 820                 mp0 = mac_header(mh, sol->sll_addr, sol->sll_protocol, mp, 0);
 821                 if (mp0 == NULL) {
 822                         ks_stats.kp_send_no_memory.value.ui64++;
 823                         error = ENOBUFS;
 824                         goto done;
 825                 }
 826                 linkb(mp0, mp);
 827                 mp = mp0;
 828         }
 829 
 830         /*
 831          * As this is sending datagrams and no promise is made about
 832          * how or if a packet will be sent/delivered, no effort is to
 833          * be expended in recovering from a situation where the packet
 834          * cannot be sent - it is just dropped.
 835          */
 836         error = mac_tx(mch, mp, 0, MAC_DROP_ON_NO_DESC, NULL);
 837         if (error == 0) {
 838                 mp = NULL;
 839                 ks_stats.kp_send_ok.value.ui64++;
 840         } else {
 841                 ks_stats.kp_send_failed.value.ui64++;
 842         }
 843 
 844 done:
 845 
 846         if (new_open) {
 847                 ASSERT(mch != ps->ps_mch);
 848                 ASSERT(mh != ps->ps_mh);
 849                 pfp_close(mh, mch);
 850         }
 851         if (mp != NULL)
 852                 freemsg(mp);
 853 
 854         return (error);
 855 
 856 }
 857 
 858 /*
 859  * There's no use of a lock here, or at the bottom of pfp_packet() where
 860  * ps_flow_ctrld is set to true, because in a situation where these two
 861  * are racing to set the flag one way or the other, the end result is
 862  * going to be ultimately determined by the scheduler anyway - which of
 863  * the two threads gets the lock first? In such an operational environment,
 864  * we've got packets arriving too fast to be delt with so packets are going
 865  * to be dropped. Grabbing a lock just makes the drop more expensive.
 866  */
 867 static void
 868 sdpfp_clr_flowctrl(sock_lower_handle_t handle)
 869 {
 870         struct pfpsock *ps;
 871 
 872         ps = (struct pfpsock *)handle;
 873 
 874         mutex_enter(&ps->ps_lock);
 875         ps->ps_flow_ctrld = B_FALSE;
 876         mutex_exit(&ps->ps_lock);
 877 }
 878 
 879 /*
 880  * The implementation of this ioctl() handler is intended to function
 881  * in the absence of a bind() being made before it is called. Thus the
 882  * function calls mac_open() itself to provide a handle
 883  * This function is structured like this:
 884  * - determine the linkid for the interface being targetted
 885  * - open the interface with said linkid
 886  * - perform ioctl
 887  * - copy results back to caller
 888  *
 889  * The ioctls that interact with interface flags have been implented below
 890  * to assume that the interface is always up and running (IFF_RUNNING) and
 891  * to use the state of this socket to determine whether or not the network
 892  * interface is in promiscuous mode. Thus an ioctl to get the interface flags
 893  * of an interface that has been put in promiscuous mode by another socket
 894  * (in the same program or different), will not report that status.
 895  */
 896 /* ARGSUSED */
 897 static int
 898 sdpfp_ioctl(sock_lower_handle_t handle, int cmd, intptr_t arg, int mod,
 899     int32_t *rval, struct cred *cr)
 900 {
 901         struct timeval tival;
 902         mac_client_promisc_type_t mtype;
 903         struct sockaddr_dl *sock;
 904         datalink_id_t linkid;
 905         struct lifreq lifreq;
 906         struct ifreq ifreq;
 907         struct pfpsock *ps;
 908         mac_handle_t mh;
 909         int error;
 910 
 911         ps = (struct pfpsock *)handle;
 912 
 913         switch (cmd) {
 914         /*
 915          * ioctls that work on "struct lifreq"
 916          */
 917         case SIOCSLIFFLAGS :
 918         case SIOCGLIFINDEX :
 919         case SIOCGLIFFLAGS :
 920         case SIOCGLIFMTU :
 921         case SIOCGLIFHWADDR :
 922                 error = pfp_lifreq_getlinkid(arg, &lifreq, &linkid, mod);
 923                 if (error != 0)
 924                         return (error);
 925                 break;
 926 
 927         /*
 928          * ioctls that work on "struct ifreq".
 929          * Not all of these have a "struct lifreq" partner, for example
 930          * SIOCGIFHWADDR, for the simple reason that the logical interface
 931          * does not have a hardware address.
 932          */
 933         case SIOCSIFFLAGS :
 934         case SIOCGIFINDEX :
 935         case SIOCGIFFLAGS :
 936         case SIOCGIFMTU :
 937         case SIOCGIFHWADDR :
 938                 error = pfp_ifreq_getlinkid(arg, &ifreq, &linkid, mod);
 939                 if (error != 0)
 940                         return (error);
 941                 break;
 942 
 943         case SIOCGSTAMP :
 944                 tival.tv_sec = (time_t)ps->ps_timestamp.tv_sec;
 945                 tival.tv_usec = ps->ps_timestamp.tv_nsec / 1000;
 946                 if (get_udatamodel() == DATAMODEL_NATIVE) {
 947                         error = ddi_copyout(&tival, (void *)arg,
 948                             sizeof (tival), mod);
 949                 }
 950 #ifdef _SYSCALL32_IMPL
 951                 else {
 952                         struct timeval32 tv32;
 953                         TIMEVAL_TO_TIMEVAL32(&tv32, &tival);
 954                         error = ddi_copyout(&tv32, (void *)arg,
 955                             sizeof (tv32), mod);
 956                 }
 957 #endif
 958                 return (error);
 959         }
 960 
 961         error =  mac_open_by_linkid(linkid, &mh);
 962         if (error != 0)
 963                 return (error);
 964 
 965         switch (cmd) {
 966         case SIOCGLIFINDEX :
 967                 lifreq.lifr_index = linkid;
 968                 break;
 969 
 970         case SIOCGIFINDEX :
 971                 ifreq.ifr_index = linkid;
 972                 break;
 973 
 974         case SIOCGIFFLAGS :
 975                 ifreq.ifr_flags = IFF_RUNNING;
 976                 if (ps->ps_promisc == MAC_CLIENT_PROMISC_ALL)
 977                         ifreq.ifr_flags |= IFF_PROMISC;
 978                 break;
 979 
 980         case SIOCGLIFFLAGS :
 981                 lifreq.lifr_flags = IFF_RUNNING;
 982                 if (ps->ps_promisc == MAC_CLIENT_PROMISC_ALL)
 983                         lifreq.lifr_flags |= IFF_PROMISC;
 984                 break;
 985 
 986         case SIOCSIFFLAGS :
 987                 if (linkid != ps->ps_linkid) {
 988                         error = EINVAL;
 989                 } else {
 990                         if ((ifreq.ifr_flags & IFF_PROMISC) != 0)
 991                                 mtype = MAC_CLIENT_PROMISC_ALL;
 992                         else
 993                                 mtype = MAC_CLIENT_PROMISC_FILTERED;
 994                         error = pfp_set_promisc(ps, mtype);
 995                 }
 996                 break;
 997 
 998         case SIOCSLIFFLAGS :
 999                 if (linkid != ps->ps_linkid) {
1000                         error = EINVAL;
1001                 } else {
1002                         if ((lifreq.lifr_flags & IFF_PROMISC) != 0)
1003                                 mtype = MAC_CLIENT_PROMISC_ALL;
1004                         else
1005                                 mtype = MAC_CLIENT_PROMISC_FILTERED;
1006                         error = pfp_set_promisc(ps, mtype);
1007                 }
1008                 break;
1009 
1010         case SIOCGIFMTU :
1011                 mac_sdu_get(mh, NULL, &ifreq.ifr_mtu);
1012                 break;
1013 
1014         case SIOCGLIFMTU :
1015                 mac_sdu_get(mh, NULL, &lifreq.lifr_mtu);
1016                 break;
1017 
1018         case SIOCGIFHWADDR :
1019                 if (mac_addr_len(mh) > sizeof (ifreq.ifr_addr.sa_data)) {
1020                         error = EPFNOSUPPORT;
1021                         break;
1022                 }
1023 
1024                 if (mac_addr_len(mh) == 0) {
1025                         (void) memset(ifreq.ifr_addr.sa_data, 0,
1026                             sizeof (ifreq.ifr_addr.sa_data));
1027                 } else {
1028                         mac_unicast_primary_get(mh,
1029                             (uint8_t *)ifreq.ifr_addr.sa_data);
1030                 }
1031 
1032                 /*
1033                  * The behaviour here in setting sa_family is consistent
1034                  * with what applications such as tcpdump would expect
1035                  * for a Linux PF_PACKET socket.
1036                  */
1037                 ifreq.ifr_addr.sa_family = pfp_dl_to_arphrd(mac_type(mh));
1038                 break;
1039 
1040         case SIOCGLIFHWADDR :
1041                 lifreq.lifr_type = 0;
1042                 sock = (struct sockaddr_dl *)&lifreq.lifr_addr;
1043 
1044                 if (mac_addr_len(mh) > sizeof (sock->sdl_data)) {
1045                         error = EPFNOSUPPORT;
1046                         break;
1047                 }
1048 
1049                 /*
1050                  * Fill in the sockaddr_dl with link layer details. Of note,
1051                  * the index is returned as 0 for a couple of reasons:
1052                  * (1) there is no public API that uses or requires it
1053                  * (2) the MAC index is currently 32bits and sdl_index is 16.
1054                  */
1055                 sock->sdl_family = AF_LINK;
1056                 sock->sdl_index = 0;
1057                 sock->sdl_type = mac_type(mh);
1058                 sock->sdl_nlen = 0;
1059                 sock->sdl_alen = mac_addr_len(mh);
1060                 sock->sdl_slen = 0;
1061                 if (mac_addr_len(mh) == 0) {
1062                         (void) memset(sock->sdl_data, 0,
1063                             sizeof (sock->sdl_data));
1064                 } else {
1065                         mac_unicast_primary_get(mh, (uint8_t *)sock->sdl_data);
1066                 }
1067                 break;
1068 
1069         default :
1070                 break;
1071         }
1072 
1073         mac_close(mh);
1074 
1075         if (error == 0) {
1076                 /*
1077                  * Only the "GET" ioctls need to copy data back to userace.
1078                  */
1079                 switch (cmd) {
1080                 case SIOCGLIFINDEX :
1081                 case SIOCGLIFFLAGS :
1082                 case SIOCGLIFMTU :
1083                 case SIOCGLIFHWADDR :
1084                         error = ddi_copyout(&lifreq, (void *)arg,
1085                             sizeof (lifreq), mod);
1086                         break;
1087 
1088                 case SIOCGIFINDEX :
1089                 case SIOCGIFFLAGS :
1090                 case SIOCGIFMTU :
1091                 case SIOCGIFHWADDR :
1092                         error = ddi_copyout(&ifreq, (void *)arg,
1093                             sizeof (ifreq), mod);
1094                         break;
1095                 default :
1096                         break;
1097                 }
1098         }
1099 
1100         return (error);
1101 }
1102 
1103 /*
1104  * Closing the socket requires that all open references to network
1105  * interfaces be closed.
1106  */
1107 /* ARGSUSED */
1108 static int
1109 sdpfp_close(sock_lower_handle_t handle, int flag, struct cred *cr)
1110 {
1111         struct pfpsock *ps = (struct pfpsock *)handle;
1112 
1113         if (ps->ps_phd != 0) {
1114                 mac_promisc_remove(ps->ps_phd);
1115                 ps->ps_phd = 0;
1116         }
1117 
1118         if (ps->ps_mch != 0) {
1119                 mac_client_close(ps->ps_mch, 0);
1120                 ps->ps_mch = 0;
1121         }
1122 
1123         if (ps->ps_mh != 0) {
1124                 mac_close(ps->ps_mh);
1125                 ps->ps_mh = 0;
1126         }
1127 
1128         kmem_free(ps, sizeof (*ps));
1129 
1130         return (0);
1131 }
1132 
1133 /* ************************************************************************* */
1134 
1135 /*
1136  * Given a pointer (arg) to a "struct ifreq" (potentially in user space),
1137  * determine the linkid for the interface name stored in that structure.
1138  * name is used as a buffer so that we can ensure a trailing \0 is appended
1139  * to the name safely.
1140  */
1141 static int
1142 pfp_ifreq_getlinkid(intptr_t arg, struct ifreq *ifreqp,
1143     datalink_id_t *linkidp, int mode)
1144 {
1145         char name[IFNAMSIZ + 1];
1146         int error;
1147 
1148         if (ddi_copyin((void *)arg, ifreqp, sizeof (*ifreqp), mode) != 0)
1149                 return (EFAULT);
1150 
1151         (void) strlcpy(name, ifreqp->ifr_name, sizeof (name));
1152 
1153         error = dls_mgmt_get_linkid(name, linkidp);
1154         if (error != 0)
1155                 error = dls_devnet_macname2linkid(name, linkidp);
1156 
1157         return (error);
1158 }
1159 
1160 /*
1161  * Given a pointer (arg) to a "struct lifreq" (potentially in user space),
1162  * determine the linkid for the interface name stored in that structure.
1163  * name is used as a buffer so that we can ensure a trailing \0 is appended
1164  * to the name safely.
1165  */
1166 static int
1167 pfp_lifreq_getlinkid(intptr_t arg, struct lifreq *lifreqp,
1168     datalink_id_t *linkidp, int mode)
1169 {
1170         char name[LIFNAMSIZ + 1];
1171         int error;
1172 
1173         if (ddi_copyin((void *)arg, lifreqp, sizeof (*lifreqp), mode) != 0)
1174                 return (EFAULT);
1175 
1176         (void) strlcpy(name, lifreqp->lifr_name, sizeof (name));
1177 
1178         error = dls_mgmt_get_linkid(name, linkidp);
1179         if (error != 0)
1180                 error = dls_devnet_macname2linkid(name, linkidp);
1181 
1182         return (error);
1183 }
1184 
1185 /*
1186  * Although there are several new SOL_PACKET options that can be set and
1187  * are specific to this implementation of PF_PACKET, the current API does
1188  * not support doing a get on them to retrieve accompanying status. Thus
1189  * it is only currently possible to use SOL_PACKET with getsockopt to
1190  * retrieve statistical information. This remains consistant with the
1191  * Linux API at the time of writing.
1192  */
1193 static int
1194 pfp_getpacket_sockopt(sock_lower_handle_t handle, int option_name,
1195     void *optval, socklen_t *optlenp)
1196 {
1197         struct pfpsock *ps;
1198         struct tpacket_stats_short tpss;
1199         int error = 0;
1200 
1201         ps = (struct pfpsock *)handle;
1202 
1203         switch (option_name) {
1204         case PACKET_STATISTICS :
1205                 if (*optlenp < sizeof (ps->ps_stats)) {
1206                         error = EINVAL;
1207                         break;
1208                 }
1209                 *optlenp = sizeof (ps->ps_stats);
1210                 bcopy(&ps->ps_stats, optval, sizeof (ps->ps_stats));
1211                 break;
1212         case PACKET_STATISTICS_SHORT :
1213                 if (*optlenp < sizeof (tpss)) {
1214                         error = EINVAL;
1215                         break;
1216                 }
1217                 *optlenp = sizeof (tpss);
1218                 tpss.tp_packets = ps->ps_stats.tp_packets;
1219                 tpss.tp_drops = ps->ps_stats.tp_drops;
1220                 bcopy(&tpss, optval, sizeof (tpss));
1221                 break;
1222         default :
1223                 error = EINVAL;
1224                 break;
1225         }
1226 
1227         return (error);
1228 }
1229 
1230 /*
1231  * The SOL_PACKET level for socket options supports three options,
1232  * PACKET_ADD_MEMBERSHIP, PACKET_DROP_MEMBERSHIP and PACKET_AUXDATA.
1233  * This function is responsible for mapping the two socket options
1234  * that manage multicast membership into the appropriate internal
1235  * function calls to bring the option into effect. Whilst direct
1236  * changes to the multicast membership (ADD/DROP) groups is handled
1237  * by calls directly into the mac module, changes to the promiscuos
1238  * mode are vectored through pfp_set_promisc() so that the logic for
1239  * managing the promiscuous mode is in one place.
1240  */
1241 /* ARGSUSED */
1242 static int
1243 pfp_setpacket_sockopt(sock_lower_handle_t handle, int option_name,
1244     const void *optval, socklen_t optlen)
1245 {
1246         struct packet_mreq mreq;
1247         struct pfpsock *ps;
1248         int error = 0;
1249         int opt;
1250 
1251         ps = (struct pfpsock *)handle;
1252         if (!ps->ps_bound)
1253                 return (EPROTO);
1254 
1255         if ((option_name == PACKET_ADD_MEMBERSHIP) ||
1256             (option_name == PACKET_DROP_MEMBERSHIP)) {
1257                 if (!ps->ps_bound)
1258                         return (EPROTO);
1259                 bcopy(optval, &mreq, sizeof (mreq));
1260                 if (ps->ps_linkid != mreq.mr_ifindex)
1261                         return (EINVAL);
1262         }
1263 
1264         switch (option_name) {
1265         case PACKET_ADD_MEMBERSHIP :
1266                 switch (mreq.mr_type) {
1267                 case PACKET_MR_MULTICAST :
1268                         if (mreq.mr_alen != ps->ps_sock.sll_halen)
1269                                 return (EINVAL);
1270 
1271                         error = mac_multicast_add(ps->ps_mch, mreq.mr_address);
1272                         break;
1273 
1274                 case PACKET_MR_PROMISC :
1275                         error = pfp_set_promisc(ps, MAC_CLIENT_PROMISC_ALL);
1276                         break;
1277 
1278                 case PACKET_MR_ALLMULTI :
1279                         error = pfp_set_promisc(ps, MAC_CLIENT_PROMISC_MULTI);
1280                         break;
1281                 }
1282                 break;
1283 
1284         case PACKET_DROP_MEMBERSHIP :
1285                 switch (mreq.mr_type) {
1286                 case PACKET_MR_MULTICAST :
1287                         if (mreq.mr_alen != ps->ps_sock.sll_halen)
1288                                 return (EINVAL);
1289 
1290                         mac_multicast_remove(ps->ps_mch, mreq.mr_address);
1291                         break;
1292 
1293                 case PACKET_MR_PROMISC :
1294                         if (ps->ps_promisc != MAC_CLIENT_PROMISC_ALL)
1295                                 return (EINVAL);
1296                         error = pfp_set_promisc(ps,
1297                             MAC_CLIENT_PROMISC_FILTERED);
1298                         break;
1299 
1300                 case PACKET_MR_ALLMULTI :
1301                         if (ps->ps_promisc != MAC_CLIENT_PROMISC_MULTI)
1302                                 return (EINVAL);
1303                         error = pfp_set_promisc(ps,
1304                             MAC_CLIENT_PROMISC_FILTERED);
1305                         break;
1306                 }
1307                 break;
1308 
1309         case PACKET_AUXDATA :
1310                 if (optlen == sizeof (int)) {
1311                         opt = *(int *)optval;
1312                         ps->ps_auxdata = (opt != 0);
1313                 } else {
1314                         error = EINVAL;
1315                 }
1316                 break;
1317         default :
1318                 error = EINVAL;
1319                 break;
1320         }
1321 
1322         return (error);
1323 }
1324 
1325 /*
1326  * There are only two special setsockopt's for SOL_SOCKET with PF_PACKET:
1327  * SO_ATTACH_FILTER and SO_DETACH_FILTER.
1328  *
1329  * Both of these setsockopt values are candidates for being handled by the
1330  * socket layer itself in future, however this requires understanding how
1331  * they would interact with all other sockets.
1332  */
1333 static int
1334 pfp_setsocket_sockopt(sock_lower_handle_t handle, int option_name,
1335     const void *optval, socklen_t optlen)
1336 {
1337         struct bpf_program prog;
1338         struct bpf_insn *fcode;
1339         struct pfpsock *ps;
1340         struct sock_proto_props sopp;
1341         int error = 0;
1342         int size;
1343 
1344         ps = (struct pfpsock *)handle;
1345 
1346         switch (option_name) {
1347         case SO_ATTACH_FILTER :
1348 #ifdef _LP64
1349                 if (optlen == sizeof (struct bpf_program32)) {
1350                         struct bpf_program32 prog32;
1351 
1352                         bcopy(optval, &prog32, sizeof (prog32));
1353                         prog.bf_len = prog32.bf_len;
1354                         prog.bf_insns = (void *)(uint64_t)prog32.bf_insns;
1355                 } else
1356 #endif
1357                 if (optlen == sizeof (struct bpf_program)) {
1358                         bcopy(optval, &prog, sizeof (prog));
1359                 } else if (optlen != sizeof (struct bpf_program)) {
1360                         return (EINVAL);
1361                 }
1362                 if (prog.bf_len > BPF_MAXINSNS)
1363                         return (EINVAL);
1364 
1365                 size = prog.bf_len * sizeof (*prog.bf_insns);
1366                 fcode = kmem_alloc(size, KM_SLEEP);
1367                 if (ddi_copyin(prog.bf_insns, fcode, size, 0) != 0) {
1368                         kmem_free(fcode, size);
1369                         return (EFAULT);
1370                 }
1371 
1372                 if (bpf_validate(fcode, (int)prog.bf_len)) {
1373                         rw_enter(&ps->ps_bpflock, RW_WRITER);
1374                         pfp_release_bpf(ps);
1375                         ps->ps_bpf.bf_insns = fcode;
1376                         ps->ps_bpf.bf_len = size;
1377                         rw_exit(&ps->ps_bpflock);
1378 
1379                         return (0);
1380                 }
1381                 kmem_free(fcode, size);
1382                 error = EINVAL;
1383                 break;
1384 
1385         case SO_DETACH_FILTER :
1386                 pfp_release_bpf(ps);
1387                 break;
1388 
1389         case SO_RCVBUF :
1390                 size = *(int32_t *)optval;
1391                 if (size > sockmod_pfp_rcvbuf_max || size < 0)
1392                         return (ENOBUFS);
1393                 sopp.sopp_flags = SOCKOPT_RCVHIWAT;
1394                 sopp.sopp_rxhiwat = size;
1395                 ps->ps_upcalls->su_set_proto_props(ps->ps_upper, &sopp);
1396                 ps->ps_rcvbuf = size;
1397                 break;
1398 
1399         default :
1400                 error = ENOPROTOOPT;
1401                 break;
1402         }
1403 
1404         return (error);
1405 }
1406 
1407 /*
1408  * pfp_open_index is an internal function used to open a MAC device by
1409  * its index. Both a mac_handle_t and mac_client_handle_t are acquired
1410  * because some of the interfaces provided by the mac layer require either
1411  * only the mac_handle_t or both it and mac_handle_t.
1412  *
1413  * Whilst inside the kernel we can access data structures supporting any
1414  * zone, access to interfaces from non-global zones is restricted to those
1415  * interfaces (if any) that are exclusively assigned to a zone.
1416  */
1417 static int
1418 pfp_open_index(int index, mac_handle_t *mhp, mac_client_handle_t *mcip,
1419     cred_t *cred)
1420 {
1421         mac_client_handle_t mch;
1422         zoneid_t ifzoneid;
1423         mac_handle_t mh;
1424         zoneid_t zoneid;
1425         int error;
1426 
1427         mh = 0;
1428         mch = 0;
1429         error = mac_open_by_linkid(index, &mh);
1430         if (error != 0)
1431                 goto bad_open;
1432 
1433         error = mac_client_open(mh, &mch, NULL,
1434             MAC_OPEN_FLAGS_USE_DATALINK_NAME);
1435         if (error != 0)
1436                 goto bad_open;
1437 
1438         zoneid = crgetzoneid(cred);
1439         if (zoneid != GLOBAL_ZONEID) {
1440                 mac_perim_handle_t perim;
1441 
1442                 mac_perim_enter_by_mh(mh, &perim);
1443                 error = dls_link_getzid(mac_name(mh), &ifzoneid);
1444                 mac_perim_exit(perim);
1445                 if (error != 0)
1446                         goto bad_open;
1447                 if (ifzoneid != zoneid) {
1448                         error = EACCES;
1449                         goto bad_open;
1450                 }
1451         }
1452 
1453         *mcip = mch;
1454         *mhp = mh;
1455 
1456         return (0);
1457 bad_open:
1458         if (mch != 0)
1459                 mac_client_close(mch, 0);
1460         if (mh != 0)
1461                 mac_close(mh);
1462         return (error);
1463 }
1464 
1465 static void
1466 pfp_close(mac_handle_t mh, mac_client_handle_t mch)
1467 {
1468         mac_client_close(mch, 0);
1469         mac_close(mh);
1470 }
1471 
1472 /*
1473  * The purpose of this function is to provide a single place where we free
1474  * the loaded BPF program and reset all pointers/counters associated with
1475  * it.
1476  */
1477 static void
1478 pfp_release_bpf(struct pfpsock *ps)
1479 {
1480         if (ps->ps_bpf.bf_len != 0) {
1481                 kmem_free(ps->ps_bpf.bf_insns, ps->ps_bpf.bf_len);
1482                 ps->ps_bpf.bf_len = 0;
1483                 ps->ps_bpf.bf_insns = NULL;
1484         }
1485 }
1486 
1487 /*
1488  * Set the promiscuous mode of a network interface.
1489  * This function only calls the mac layer when there is a change to the
1490  * status of a network interface's promiscous mode. Tracking of how many
1491  * sockets have the network interface in promiscuous mode, and thus the
1492  * control over the physical device's status, is left to the mac layer.
1493  */
1494 static int
1495 pfp_set_promisc(struct pfpsock *ps, mac_client_promisc_type_t turnon)
1496 {
1497         int error = 0;
1498         int flags;
1499 
1500         /*
1501          * There are 4 combinations of turnon/ps_promisc.
1502          * This if handles 2 (both false, both true) and the if() below
1503          * handles the remaining one - when change is required.
1504          */
1505         if (turnon == ps->ps_promisc)
1506                 return (error);
1507 
1508         if (ps->ps_phd != 0) {
1509                 mac_promisc_remove(ps->ps_phd);
1510                 ps->ps_phd = 0;
1511 
1512                 /*
1513                  * ps_promisc is set here in case the call to mac_promisc_add
1514                  * fails: leaving it to indicate that the interface is still
1515                  * in some sort of promiscuous mode is false.
1516                  */
1517                 if (ps->ps_promisc != MAC_CLIENT_PROMISC_FILTERED) {
1518                         ps->ps_promisc = MAC_CLIENT_PROMISC_FILTERED;
1519                         flags = MAC_PROMISC_FLAGS_NO_PHYS;
1520                 } else {
1521                         flags = 0;
1522                 }
1523                 flags |= MAC_PROMISC_FLAGS_VLAN_TAG_STRIP;
1524         }
1525 
1526         error = mac_promisc_add(ps->ps_mch, turnon, pfp_packet, ps,
1527             &ps->ps_phd, flags);
1528         if (error == 0)
1529                 ps->ps_promisc = turnon;
1530 
1531         return (error);
1532 }
1533 
1534 /*
1535  * This table maps the MAC types in Solaris to the ARPHRD_* values used
1536  * on Linux. This is used with the SIOCGIFHWADDR/SIOCGLIFHWADDR ioctl.
1537  *
1538  * The symbols in this table are *not* pulled in from <net/if_arp.h>,
1539  * they are pulled from <netpacket/packet.h>, thus it acts as a source
1540  * of supplementary information to the ARP table.
1541  */
1542 static uint_t arphrd_to_dl[][2] = {
1543         { ARPHRD_IEEE80211,     DL_WIFI },
1544         { ARPHRD_TUNNEL,        DL_IPV4 },
1545         { ARPHRD_TUNNEL,        DL_IPV6 },
1546         { ARPHRD_TUNNEL,        DL_6TO4 },
1547         { ARPHRD_AX25,          DL_X25 },
1548         { ARPHRD_ATM,           DL_ATM },
1549         { 0,                    0 }
1550 };
1551 
1552 static int
1553 pfp_dl_to_arphrd(int dltype)
1554 {
1555         int i;
1556 
1557         for (i = 0; arphrd_to_dl[i][0] != 0; i++)
1558                 if (arphrd_to_dl[i][1] == dltype)
1559                         return (arphrd_to_dl[i][0]);
1560         return (arp_hw_type(dltype));
1561 }