/* ARGSUSED1 */ static int dropen(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp) { struct drstate *dsp; if (sflag != MODOPEN) { /* must be a pushed module */ return (EINVAL); } if (secpolicy_net_rawaccess(crp) != 0) { return (EPERM); } if (q->q_ptr != NULL) { return (0); /* already open */ } dsp = kmem_zalloc(sizeof (*dsp), KM_SLEEP); dsp->dr_major = getmajor(*devp); mutex_init(&dsp->dr_lock, NULL, MUTEX_DEFAULT, NULL); q->q_ptr = OTHERQ(q)->q_ptr = dsp; qprocson(q); ddi_assoc_queue_with_devi(q, NULL); return (0); }
/* ARGSUSED */ static sock_lower_handle_t sockpfp_create(int family, int type, int proto, sock_downcalls_t **sock_downcalls, uint_t *smodep, int *errorp, int sflags, cred_t *cred) { struct pfpsock *ps; int kmflags; if (secpolicy_net_rawaccess(cred) != 0) { *errorp = EACCES; return (NULL); } if (family != AF_PACKET) { *errorp = EAFNOSUPPORT; return (NULL); } if ((type != SOCK_RAW) && (type != SOCK_DGRAM)) { *errorp = ESOCKTNOSUPPORT; return (NULL); } kmflags = (sflags & SOCKET_NOSLEEP) ? KM_NOSLEEP : KM_SLEEP; ps = kmem_zalloc(sizeof (*ps), kmflags); if (ps == NULL) { *errorp = ENOMEM; return (NULL); } ps->ps_type = type; ps->ps_proto = proto; rw_init(&ps->ps_bpflock, NULL, RW_DRIVER, NULL); mutex_init(&ps->ps_lock, NULL, MUTEX_DRIVER, NULL); *sock_downcalls = &pfp_downcalls; /* * Setting this causes bytes from a packet that do not fit into the * destination user buffer to be discarded. Thus the API is one * packet per receive and callers are required to use a buffer large * enough for the biggest packet that the interface can provide. */ *smodep = SM_ATOMIC; return ((sock_lower_handle_t)ps); }
/* ARGSUSED */ static sock_lower_handle_t sockpfp_create(int family, int type, int proto, sock_downcalls_t **sock_downcalls, uint_t *smodep, int *errorp, int sflags, cred_t *cred) { struct pfpsock *ps; int kmflags; int newproto; int i; if (secpolicy_net_rawaccess(cred) != 0) { *errorp = EACCES; return (NULL); } if (family != AF_PACKET) { *errorp = EAFNOSUPPORT; return (NULL); } if ((type != SOCK_RAW) && (type != SOCK_DGRAM)) { *errorp = ESOCKTNOSUPPORT; return (NULL); } /* * First check to see if the protocol number passed in via the socket * creation should be mapped to a different number for internal use. */ for (i = 0, newproto = -1; i < sizeof (accepted_protos)/ sizeof (accepted_protos[0]); i++) { if (accepted_protos[i][0] == proto) { newproto = accepted_protos[i][1]; break; } } /* * If the mapping of the protocol that was under 0x800 failed to find * a local equivalent then fail the socket creation. If the protocol * for the socket is over 0x800 and it was not found in the mapping * table above, then use the value as is. */ if (newproto == -1) { if (proto < 0x800) { *errorp = ENOPROTOOPT; return (NULL); } newproto = proto; } proto = newproto; kmflags = (sflags & SOCKET_NOSLEEP) ? KM_NOSLEEP : KM_SLEEP; ps = kmem_zalloc(sizeof (*ps), kmflags); if (ps == NULL) { *errorp = ENOMEM; return (NULL); } ps->ps_type = type; ps->ps_proto = proto; rw_init(&ps->ps_bpflock, NULL, RW_DRIVER, NULL); mutex_init(&ps->ps_lock, NULL, MUTEX_DRIVER, NULL); *sock_downcalls = &pfp_downcalls; /* * Setting this causes bytes from a packet that do not fit into the * destination user buffer to be discarded. Thus the API is one * packet per receive and callers are required to use a buffer large * enough for the biggest packet that the interface can provide. */ *smodep = SM_ATOMIC; return ((sock_lower_handle_t)ps); }