Exemplo n.º 1
0
void
filt_bpfrdetach(struct knote *kn)
{
	dev_t dev = (dev_t)((u_long)kn->kn_hook);
	struct bpf_d *d;
	int s;

	d = bpfilter_lookup(minor(dev));
	s = splnet();
	SLIST_REMOVE(&d->bd_sel.si_note, kn, knote, kn_selnext);
	D_PUT(d);
	splx(s);
}
Exemplo n.º 2
0
/* ARGSUSED */
int
bpfclose(dev_t dev, int flag, int mode, struct proc *p)
{
    struct bpf_d *d;
    int s;

    d = bpfilter_lookup(minor(dev));
    s = splnet();
    if (d->bd_bif)
        bpf_detachd(d);
    bpf_wakeup(d);
    D_PUT(d);
    splx(s);

    return (0);
}
Exemplo n.º 3
0
/*
 *  bpfread - read next chunk of packets from buffers
 */
int
bpfread(dev_t dev, struct uio *uio, int ioflag)
{
    struct bpf_d *d;
    int error;
    int s;

    d = bpfilter_lookup(minor(dev));
    if (d->bd_bif == 0)
        return (ENXIO);

    /*
     * Restrict application to use a buffer the same size as
     * as kernel buffers.
     */
    if (uio->uio_resid != d->bd_bufsize)
        return (EINVAL);

    s = splnet();

    D_GET(d);

    /*
     * bd_rdStart is tagged when we start the read, iff there's a timeout.
     * we can then figure out when we're done reading.
     */
    if (d->bd_rtout != -1 && d->bd_rdStart == 0)
        d->bd_rdStart = ticks;
    else
        d->bd_rdStart = 0;

    /*
     * If the hold buffer is empty, then do a timed sleep, which
     * ends when the timeout expires or when enough packets
     * have arrived to fill the store buffer.
     */
    while (d->bd_hbuf == 0) {
        if (d->bd_bif == NULL) {
            /* interface is gone */
            if (d->bd_slen == 0) {
                D_PUT(d);
                splx(s);
                return (EIO);
            }
            ROTATE_BUFFERS(d);
            break;
        }
        if (d->bd_immediate && d->bd_slen != 0) {
            /*
             * A packet(s) either arrived since the previous
             * read or arrived while we were asleep.
             * Rotate the buffers and return what's here.
             */
            ROTATE_BUFFERS(d);
            break;
        }
        if ((d->bd_rtout != -1) ||
                (d->bd_rdStart + d->bd_rtout) < ticks) {
            error = tsleep((caddr_t)d, PRINET|PCATCH, "bpf",
                           d->bd_rtout);
        } else {
            if (d->bd_rtout == -1) {
                /* User requested non-blocking I/O */
                error = EWOULDBLOCK;
            } else
                error = 0;
        }
        if (error == EINTR || error == ERESTART) {
            D_PUT(d);
            splx(s);
            return (error);
        }
        if (error == EWOULDBLOCK) {
            /*
             * On a timeout, return what's in the buffer,
             * which may be nothing.  If there is something
             * in the store buffer, we can rotate the buffers.
             */
            if (d->bd_hbuf)
                /*
                 * We filled up the buffer in between
                 * getting the timeout and arriving
                 * here, so we don't need to rotate.
                 */
                break;

            if (d->bd_slen == 0) {
                D_PUT(d);
                splx(s);
                return (0);
            }
            ROTATE_BUFFERS(d);
            break;
        }
    }
    /*
     * At this point, we know we have something in the hold slot.
     */
    splx(s);

    /*
     * Move data from hold buffer into user space.
     * We know the entire buffer is transferred since
     * we checked above that the read buffer is bpf_bufsize bytes.
     */
    error = uiomove(d->bd_hbuf, d->bd_hlen, uio);

    s = splnet();
    d->bd_fbuf = d->bd_hbuf;
    d->bd_hbuf = 0;
    d->bd_hlen = 0;

    D_PUT(d);
    splx(s);

    return (error);
}