Beispiel #1
0
/* 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);
}
Beispiel #3
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;
	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);
}