Beispiel #1
0
int main(int argc, char* argv[])
{
	int dummy;
	char cmd;
	double counter;

	dummy = (argc == INT_MAX - 1) ? argv[argc-1][0] : 1;

	if (argc == 3) {
		cmd = argv[1][1];
		counter = strtod(argv[2], NULL);
		if (counter < 0 || counter > UINT32_MAX)
			counter = 1;
	} else {
		cmd = 'j';
		counter = 1;
		usage(argv[0]);
	}

	if (!bpf_validate(insns, sizeof(insns) / sizeof(insns[0])))
		errx(EXIT_FAILURE, "Not valid bpf program");

	switch (cmd) {
	case 'j':
		test_bpfjit(counter, test_pkt, sizeof(test_pkt), dummy);
		break;
	case 'b':
		test_bpf_filter(counter, dummy);
		break;
	case 'c':
		test_c(counter, test_pkt, sizeof(test_pkt), dummy);
	}

	return EXIT_SUCCESS;
}
Beispiel #2
0
int main(int argc, char *argv[]){
  
  struct bpf_insn ins_buffer[N];

  klee_make_symbolic(ins_buffer, N * sizeof(ins_buffer[0]), "lol");
  return bpf_validate(ins_buffer, N);
}
Beispiel #3
0
/*
 * Make a copy of a BPF program and put it in the "fcode" member of
 * a "pcap_t".
 *
 * If we fail to allocate memory for the copy, fill in the "errbuf"
 * member of the "pcap_t" with an error message, and return -1;
 * otherwise, return 0.
 */
int
install_bpf_program(pcap_t *p, struct bpf_program *fp)
{
	size_t prog_size;

	/*
	 * Validate the program.
	 */
	if (!bpf_validate(fp->bf_insns, fp->bf_len)) {
		snprintf(p->errbuf, sizeof(p->errbuf),
			"BPF program is not valid");
		return (-1);
	}

	/*
	 * Free up any already installed program.
	 */
	pcap_freecode(&p->fcode);

	prog_size = sizeof(*fp->bf_insns) * fp->bf_len;
	p->fcode.bf_len = fp->bf_len;
	p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size);
	if (p->fcode.bf_insns == NULL) {
		snprintf(p->errbuf, sizeof(p->errbuf),
			 "malloc: %s", pcap_strerror(errno));
		return (-1);
	}
	memcpy(p->fcode.bf_insns, fp->bf_insns, prog_size);
	return (0);
}
Beispiel #4
0
int bsf_filter(bsf_t *bsf_desc, in_addr_t clt_ip, in_port_t clt_port, in_addr_t svr_ip, in_port_t svr_port)
{
	unsigned char dummy_packet[BSF_SNAP_LEN];
	
	
	populate_packet(dummy_packet, clt_ip, clt_port, svr_ip, svr_port);
	//validate the bpf program
	if (bsf_desc->flags && BSF_FLAG_VALIDATE == BSF_FLAG_VALIDATE)
	{
		//validate the BPF:
		if (bpf_validate(bsf_desc->bpf_prog->bf_insns, bsf_desc->bpf_prog->bf_len) == 0)
		{
			//validation failed
			return BSF_RESULT_ERROR;
		} 	
	}
	
	if (bpf_filter(bsf_desc->bpf_prog->bf_insns, dummy_packet, BSF_SNAP_LEN, BSF_SNAP_LEN) == BSF_SNAP_LEN)
	{
		return BSF_RESULT_PASS;
	} else
	{
		return BSF_RESULT_FAIL;
	}
	
	
}
Beispiel #5
0
int daemon_unpackapplyfilter(pcap_t *fp, unsigned int *nread, int *plen, char *errbuf)
{
struct rpcap_filter filter;
struct rpcap_filterbpf_insn insn;
struct bpf_insn *bf_insn;
struct bpf_program bf_prog;
unsigned int i;


	if ( ( *nread+= sock_recv(fp->rmt_sockctrl, (char *) &filter, sizeof(struct rpcap_filter), errbuf)) == -1)
	{
		// to avoid blocking on the sock_discard()
		*plen= *nread;
		return -1;
	}

	bf_prog.bf_len= ntohl(filter.nitems);

	if (ntohs(filter.filtertype) != RPCAP_UPDATEFILTER_BPF)
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Only BPF/NPF filters are currently supported");
		return -1;
	}

	bf_insn= (struct bpf_insn *) malloc ( sizeof(struct bpf_insn) * bf_prog.bf_len);
	if (bf_insn == NULL)
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
		return -1;
	}

	bf_prog.bf_insns= bf_insn;

	for (i= 0; i < bf_prog.bf_len; i++)
	{
		if ( ( *nread+= sock_recv(fp->rmt_sockctrl, (char *) &insn, sizeof(struct rpcap_filterbpf_insn), errbuf)) == -1)
			return -1;

		bf_insn->code= ntohs(insn.code);
		bf_insn->jf= insn.jf;
		bf_insn->jt= insn.jt;
		bf_insn->k= ntohl(insn.k);

		bf_insn++;
	}

	if (bpf_validate(bf_prog.bf_insns, bf_prog.bf_len) == 0)
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "The filter contains bogus instructions");
		return -1;
    }

	if (pcap_setfilter(fp, &bf_prog) )
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "RPCAP error: %s", fp->errbuf);
		return -1;
    }

	return 0;
}
Beispiel #6
0
void bpf_parse_rules(char *rulefile, struct sock_fprog *bpf)
{
	int ret;
	char buff[256];
	struct sock_filter sf_single = { 0x06, 0, 0, 0xFFFFFFFF };
	FILE *fp;

	if (rulefile == NULL) {
		bpf->len = 1;
		bpf->filter = xmalloc(sizeof(sf_single));
		fmemcpy(&bpf->filter[0], &sf_single, sizeof(sf_single));
		return;
	}

	fp = fopen(rulefile, "r");
	if (!fp)
		panic("Cannot read BPF rule file!\n");

	fmemset(buff, 0, sizeof(buff));
	while (fgets(buff, sizeof(buff), fp) != NULL) {
		buff[sizeof(buff) - 1] = 0;
		if (buff[0] != '{') {
			fmemset(buff, 0, sizeof(buff));
			continue;
		}

		fmemset(&sf_single, 0, sizeof(sf_single));
		ret = sscanf(buff, "{ 0x%x, %u, %u, 0x%08x },",
			     (unsigned int *) &sf_single.code,
			     (unsigned int *) &sf_single.jt,
			     (unsigned int *) &sf_single.jf,
			     (unsigned int *) &sf_single.k);
		if (ret != 4)
			panic("BPF syntax error!\n");

		bpf->len++;
		bpf->filter = xrealloc(bpf->filter, 1,
				       bpf->len * sizeof(sf_single));

		fmemcpy(&bpf->filter[bpf->len - 1], &sf_single,
		       sizeof(sf_single));
		fmemset(buff, 0, sizeof(buff));
	}

	fclose(fp);

	if (bpf_validate(bpf) == 0)
		panic("This is not a valid BPF program!\n");
}
Beispiel #7
0
/*
 * Set d's packet filter program to fp.  If this file already has a filter,
 * free it and replace it.  Returns EINVAL for bogus requests.
 */
int
bpf_setf(struct bpf_d *d, struct bpf_program *fp, int wf)
{
    struct bpf_insn *fcode, *old;
    u_int flen, size;
    int s;

    old = wf ? d->bd_wfilter : d->bd_rfilter;
    if (fp->bf_insns == 0) {
        if (fp->bf_len != 0)
            return (EINVAL);
        s = splnet();
        if (wf)
            d->bd_wfilter = 0;
        else
            d->bd_rfilter = 0;
        bpf_reset_d(d);
        splx(s);
        if (old != 0)
            free((caddr_t)old, M_DEVBUF);
        return (0);
    }
    flen = fp->bf_len;
    if (flen > BPF_MAXINSNS)
        return (EINVAL);

    size = flen * sizeof(*fp->bf_insns);
    fcode = (struct bpf_insn *)malloc(size, M_DEVBUF, M_WAITOK);
    if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 &&
            bpf_validate(fcode, (int)flen)) {
        s = splnet();
        if (wf)
            d->bd_wfilter = fcode;
        else
            d->bd_rfilter = fcode;
        bpf_reset_d(d);
        splx(s);
        if (old != 0)
            free((caddr_t)old, M_DEVBUF);

        return (0);
    }
    free((caddr_t)fcode, M_DEVBUF);
    return (EINVAL);
}
Beispiel #8
0
/*
 * Set d's packet filter program to fp.  If this file already has a filter,
 * free it and replace it.  Returns EINVAL for bogus requests.
 */
static int
bpf_setf(struct bpf_d *d, u_int bf_len, user_addr_t bf_insns)
{
	struct bpf_insn *fcode, *old;
	u_int flen, size;

	old = d->bd_filter;
	if (bf_insns == USER_ADDR_NULL) {
		if (bf_len != 0)
			return (EINVAL);
		d->bd_filter = NULL;
		reset_d(d);
		if (old != 0)
			FREE((caddr_t)old, M_DEVBUF);
		return (0);
	}
	flen = bf_len;
	if (flen > BPF_MAXINSNS)
		return (EINVAL);

	size = flen * sizeof(struct bpf_insn);
	fcode = (struct bpf_insn *) _MALLOC(size, M_DEVBUF, M_WAIT);
#ifdef __APPLE__
	if (fcode == NULL)
		return (ENOBUFS);
#endif
	if (copyin(bf_insns, (caddr_t)fcode, size) == 0 &&
	    bpf_validate(fcode, (int)flen)) {
		d->bd_filter = fcode;
		reset_d(d);
		if (old != 0)
			FREE((caddr_t)old, M_DEVBUF);

		return (0);
	}
	FREE((caddr_t)fcode, M_DEVBUF);
	return (EINVAL);
}
Beispiel #9
0
/*
 * Ioctl routine for generic ppp devices.
 */
int
pppioctl(struct ppp_softc *sc, u_long cmd, caddr_t data,
    int flag, struct ucred *cred)
{
    int error, flags, mru, npx;
    u_int nb;
    struct ppp_option_data *odp;
    struct compressor **cp;
    struct npioctl *npi;
    time_t t;
#ifdef PPP_FILTER
    struct bpf_program *bp, *nbp;
    struct bpf_insn *newcode, *oldcode;
    int newcodelen;
#endif /* PPP_FILTER */
#ifdef	PPP_COMPRESS
    u_char ccp_option[CCP_MAX_OPTION_LENGTH];
#endif

    switch (cmd) {
    case FIONREAD:
	*(int *)data = sc->sc_inq.ifq_len;
	break;

    case PPPIOCGUNIT:
	*(int *)data = sc->sc_if.if_dunit;
	break;

    case PPPIOCGFLAGS:
	*(u_int *)data = sc->sc_flags;
	break;

    case PPPIOCSFLAGS:
	if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0)
	    return (error);
	flags = *(int *)data & SC_MASK;
	crit_enter();
#ifdef PPP_COMPRESS
	if (sc->sc_flags & SC_CCP_OPEN && !(flags & SC_CCP_OPEN))
	    ppp_ccp_closed(sc);
#endif
	sc->sc_flags = (sc->sc_flags & ~SC_MASK) | flags;
	crit_exit();
	break;

    case PPPIOCSMRU:
	if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0)
	    return (error);
	mru = *(int *)data;
	if (mru >= PPP_MRU && mru <= PPP_MAXMRU)
	    sc->sc_mru = mru;
	break;

    case PPPIOCGMRU:
	*(int *)data = sc->sc_mru;
	break;

#ifdef VJC
    case PPPIOCSMAXCID:
	if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0)
	    return (error);
	if (sc->sc_comp) {
	    crit_enter();
	    sl_compress_init(sc->sc_comp, *(int *)data);
	    crit_exit();
	}
	break;
#endif

    case PPPIOCXFERUNIT:
	if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0)
	    return (error);
	sc->sc_xfer = curthread;
	break;

#ifdef PPP_COMPRESS
    case PPPIOCSCOMPRESS:
	if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0)
	    return (error);
	odp = (struct ppp_option_data *) data;
	nb = odp->length;
	if (nb > sizeof(ccp_option))
	    nb = sizeof(ccp_option);
	if ((error = copyin(odp->ptr, ccp_option, nb)) != 0)
	    return (error);
	if (ccp_option[1] < 2)	/* preliminary check on the length byte */
	    return (EINVAL);
	for (cp = ppp_compressors; *cp != NULL; ++cp)
	    if ((*cp)->compress_proto == ccp_option[0]) {
		/*
		 * Found a handler for the protocol - try to allocate
		 * a compressor or decompressor.
		 */
		error = 0;
		if (odp->transmit) {
		    crit_enter();
		    if (sc->sc_xc_state != NULL)
			(*sc->sc_xcomp->comp_free)(sc->sc_xc_state);
		    sc->sc_xcomp = *cp;
		    sc->sc_xc_state = (*cp)->comp_alloc(ccp_option, nb);
		    if (sc->sc_xc_state == NULL) {
			if (sc->sc_flags & SC_DEBUG)
			    kprintf("%s: comp_alloc failed\n",
			       sc->sc_if.if_xname);
			error = ENOBUFS;
		    }
		    sc->sc_flags &= ~SC_COMP_RUN;
		    crit_exit();
		} else {
		    crit_enter();
		    if (sc->sc_rc_state != NULL)
			(*sc->sc_rcomp->decomp_free)(sc->sc_rc_state);
		    sc->sc_rcomp = *cp;
		    sc->sc_rc_state = (*cp)->decomp_alloc(ccp_option, nb);
		    if (sc->sc_rc_state == NULL) {
			if (sc->sc_flags & SC_DEBUG)
			    kprintf("%s: decomp_alloc failed\n",
			       sc->sc_if.if_xname);
			error = ENOBUFS;
		    }
		    sc->sc_flags &= ~SC_DECOMP_RUN;
		    crit_exit();
		}
		return (error);
	    }
	if (sc->sc_flags & SC_DEBUG)
	    kprintf("%s: no compressor for [%x %x %x], %x\n",
		   sc->sc_if.if_xname, ccp_option[0], ccp_option[1],
		   ccp_option[2], nb);
	return (EINVAL);	/* no handler found */
#endif /* PPP_COMPRESS */

    case PPPIOCGNPMODE:
    case PPPIOCSNPMODE:
	npi = (struct npioctl *) data;
	switch (npi->protocol) {
	case PPP_IP:
	    npx = NP_IP;
	    break;
	default:
	    return EINVAL;
	}
	if (cmd == PPPIOCGNPMODE) {
	    npi->mode = sc->sc_npmode[npx];
	} else {
	    if ((error = priv_check_cred(cred, PRIV_ROOT, 0)) != 0)
		return (error);
	    if (npi->mode != sc->sc_npmode[npx]) {
		crit_enter();
		sc->sc_npmode[npx] = npi->mode;
		if (npi->mode != NPMODE_QUEUE) {
		    ppp_requeue(sc);
		    (*sc->sc_start)(sc);
		}
		crit_exit();
	    }
	}
	break;

    case PPPIOCGIDLE:
	crit_enter();
	t = time_uptime;
	((struct ppp_idle *)data)->xmit_idle = t - sc->sc_last_sent;
	((struct ppp_idle *)data)->recv_idle = t - sc->sc_last_recv;
	crit_exit();
	break;

#ifdef PPP_FILTER
    case PPPIOCSPASS:
    case PPPIOCSACTIVE:
	nbp = (struct bpf_program *) data;
	if ((unsigned) nbp->bf_len > BPF_MAXINSNS)
	    return EINVAL;
	newcodelen = nbp->bf_len * sizeof(struct bpf_insn);
	if (newcodelen != 0) {
	    newcode = kmalloc(newcodelen, M_DEVBUF, M_WAITOK);
	    if ((error = copyin((caddr_t)nbp->bf_insns, (caddr_t)newcode,
			       newcodelen)) != 0) {
		kfree(newcode, M_DEVBUF);
		return error;
	    }
	    if (!bpf_validate(newcode, nbp->bf_len)) {
		kfree(newcode, M_DEVBUF);
		return EINVAL;
	    }
	} else
	    newcode = NULL;
	bp = (cmd == PPPIOCSPASS)? &sc->sc_pass_filt: &sc->sc_active_filt;
	oldcode = bp->bf_insns;
	crit_enter();
	bp->bf_len = nbp->bf_len;
	bp->bf_insns = newcode;
	crit_exit();
	if (oldcode != NULL)
	    kfree(oldcode, M_DEVBUF);
	break;
#endif

    default:
	return (ENOIOCTL);
    }
    return (0);
}
/*
 * There are only two special setsockopt's for SOL_SOCKET with PF_PACKET:
 * SO_ATTACH_FILTER and SO_DETACH_FILTER. All other setsockopt requests
 * that are for SOL_SOCKET are passed back to the socket layer for its
 * generic implementation.
 *
 * Both of these setsockopt values are candidates for being handled by the
 * socket layer itself in future, however this requires understanding how
 * they would interact with all other sockets.
 */
static int
pfp_setsocket_sockopt(sock_lower_handle_t handle, int option_name,
    const void *optval, socklen_t optlen)
{
	struct bpf_program prog;
	struct bpf_insn *fcode;
	struct pfpsock *ps;
	int error = 0;
	int size;

	ps = (struct pfpsock *)handle;

	switch (option_name) {
	case SO_ATTACH_FILTER :
#ifdef _LP64
		if (optlen == sizeof (struct bpf_program32)) {
			struct bpf_program32 prog32;

			bcopy(optval, &prog32, sizeof (prog32));
			prog.bf_len = prog32.bf_len;
			prog.bf_insns = (void *)(uint64_t)prog32.bf_insns;
		} else
#endif
		if (optlen == sizeof (struct bpf_program)) {
			bcopy(optval, &prog, sizeof (prog));
		} else if (optlen != sizeof (struct bpf_program)) {
			return (EINVAL);
		}

		size = prog.bf_len * sizeof (*prog.bf_insns);
		fcode = kmem_alloc(size, KM_SLEEP);
		if (ddi_copyin(prog.bf_insns, fcode, size, 0) != 0) {
			kmem_free(fcode, size);
			return (EFAULT);
		}

		if (bpf_validate(fcode, (int)prog.bf_len)) {
			rw_enter(&ps->ps_bpflock, RW_WRITER);
			pfp_release_bpf(ps);
			ps->ps_bpf.bf_insns = fcode;
			ps->ps_bpf.bf_len = size;
			rw_exit(&ps->ps_bpflock);

			return (0);
		}
		kmem_free(fcode, size);
		error = EINVAL;
		break;

	case SO_DETACH_FILTER :
		pfp_release_bpf(ps);
		break;
	default :
		/*
		 * If sockfs code receives this error in return from the
		 * getsockopt downcall it handles the option locally, if
		 * it can. This implements SO_RCVBUF, etc.
		 */
		error = ENOPROTOOPT;
		break;
	}

	return (error);
}
Beispiel #11
0
/*!
  \brief Sets the bpf packet filter.
  \param pWanAdapter Pointer to a WAN_ADAPTER structure.
  \param FilterCode Pointer to the BPF filtering code that will be associated with this capture or monitoring 
  instance and that will be executed on every incoming packet.
  \param Length Length, in bytes, of the BPF filter code.
  \return This function returns TRUE if the filter is set successfully, FALSE if an error occurs 
   or if the filter program is not accepted after a safeness check.  This API
   performs the check in order to avoid unexpected behavior due to buggy or malicious filters, and it rejects non
   conformant filters.

  For more information, see the documentation of PacketSetBpf
*/
BOOLEAN WanPacketSetBpfFilter(PWAN_ADAPTER pWanAdapter, PUCHAR FilterCode, DWORD Length)
{
	PUCHAR	NewFilterCode = NULL;
	DWORD NumberOfInstructions;	
	DWORD Counter;
	struct bpf_insn *InitializationCode;
	struct time_conv TimeConv;
	if ( Length < 0)
		return FALSE;

	EnterCriticalSection(&pWanAdapter->CriticalSection);
	if (Length > 0)
	{
		NumberOfInstructions = Length/sizeof(struct bpf_insn);
		for(Counter = 0; 
			Counter < NumberOfInstructions && ((struct bpf_insn*)FilterCode)[Counter].code != BPF_SEPARATION ;
			Counter++);

		if ( Counter != NumberOfInstructions &&
			NumberOfInstructions != Counter + 1 &&
			((struct bpf_insn*)FilterCode)[Counter].code == BPF_SEPARATION )
		{
			//we need to initialize the TME
			InitializationCode = &((struct bpf_insn*)FilterCode)[Counter+1];
			
			//FIXME, just an hack, this structure is never used here.		
			TimeConv.start[0].tv_sec = 0;
			TimeConv.start[0].tv_usec = 0;
			
			if ( bpf_filter_init(InitializationCode,
				&pWanAdapter->MemEx,
				&pWanAdapter->Tme,
				&TimeConv) != INIT_OK )
			{
				LeaveCriticalSection(&pWanAdapter->CriticalSection);
				return FALSE;
			}
		}

		NumberOfInstructions = Counter;

		if ( bpf_validate((struct bpf_insn*)FilterCode, Counter, pWanAdapter->MemEx.size) == 0)
		{
			//filter not validated
			//FIXME: the machine has been initialized(?), but the operative code is wrong. 
			//we have to reset the machine!
			//something like: reallocate the mem_ex, and reset the tme_core
			LeaveCriticalSection(&pWanAdapter->CriticalSection);
			return FALSE;
		}


		NewFilterCode = (PUCHAR)GlobalAlloc( GMEM_FIXED, Counter * sizeof(struct bpf_insn) );
		if (NewFilterCode == NULL)
		{
			LeaveCriticalSection(&pWanAdapter->CriticalSection);
			return FALSE;
		}
	
		RtlCopyMemory(NewFilterCode, FilterCode, Counter * sizeof(struct bpf_insn));
	}

	if ( pWanAdapter->FilterCode != NULL )
		GlobalFree(pWanAdapter->FilterCode);

	pWanAdapter->FilterCode = (struct bpf_insn*)NewFilterCode;
	//we reset all the ring buffer related counters.
	pWanAdapter->C = 0;
	pWanAdapter->P = 0;
	pWanAdapter->Free = pWanAdapter->Size;
	pWanAdapter->Accepted = 0;
	pWanAdapter->Dropped = 0;
	pWanAdapter->Received = 0;
	pWanAdapter->Nbytes.QuadPart = 0;
	pWanAdapter->Npackets.QuadPart = 0;

	LeaveCriticalSection(&pWanAdapter->CriticalSection);

	return TRUE;
}
Beispiel #12
0
BOOL PKT_IOControl (DWORD dwContext, DWORD dwCode, PBYTE pBufIn,
					DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)
{
	BOOL			bRet = TRUE;
	PWCHAR			bpf_prog;
	PNDIS_STRING	pstrAName;
	POPEN_INSTANCE	pOpenInst = NULL;
	PUCHAR			pTempBuf;
	ULONG			nValue;

	// if the context is different then return false
	if (dwContext != PKT_FILE_HANDLE) {
		SAFE_SET (pdwActualOut, 0);
		return FALSE;
	}

	// if the code is not to open the adapter then there
	// should be an open instance of the adapter
	if (dwCode != PIOC_OPEN_ADAPTER &&
		dwCode != PIOC_GET_MACNAME) {

		// get the open instance handle
		pOpenInst = g_pDeviceExtension->pOpenInstance;
		if (pOpenInst == NULL) {
			return FALSE;
		}
	}

	switch (dwCode) {

	// open the adapter message
	case PIOC_OPEN_ADAPTER:

		// get the adapter NDIS name
		pstrAName = PKTGetNDISAdapterName ((PWCHAR)pBufIn, dwLenIn);
		if (pstrAName == NULL) {
			return FALSE;
		}

		// open the adapter
		if (! PKTOpenAdapter (pstrAName)) {
			bRet = FALSE;
		}
	break;

	// close the adapter message
	case PIOC_CLOSE_ADAPTER:
		bRet = PKTCloseAdapter (pOpenInst);
	break;

	// function to set new bpf filter
	case PIOC_SETF:

		// free the previous buffer if selected
		if (pOpenInst->bpfprogram != NULL) {
			NdisFreeMemory (pOpenInst->bpfprogram, pOpenInst->bpfprogramlen, 0);
			pOpenInst->bpfprogram = NULL;
			pOpenInst->bpfprogramlen = 0;
		}


		// get the pointer to the new program
		bpf_prog = (PWCHAR) pBufIn;

		// before accepting the program we must check that it's valid
		// otherwise, a bogus program could easily crash the driver
		pOpenInst->bpfprogramlen = dwLenIn;
		if (bpf_validate ((struct bpf_insn*)bpf_prog, 
			pOpenInst->bpfprogramlen/sizeof(struct bpf_insn)) == 0) {
			pOpenInst->bpfprogramlen = 0;
			pOpenInst->bpfprogram = NULL; 
			return FALSE; // filter not accepted
		}

		// allocate the memory to contain the new filter program*/
		if (NdisAllocateMemory(&pOpenInst->bpfprogram, pOpenInst->bpfprogramlen,
			0, NDIS_ADDR_M1) == NDIS_STATUS_FAILURE) {
			pOpenInst->bpfprogramlen = 0;
			pOpenInst->bpfprogram = NULL; 
			return FALSE;
		}

		// copy the program in the new buffer
		NdisMoveMemory (pOpenInst->bpfprogram, bpf_prog, pOpenInst->bpfprogramlen);

		// reset the buffer that could contain packets that don't match the filter
		pOpenInst->Bhead	= 0;
		pOpenInst->Btail	= 0;
		pOpenInst->BLastByte= 0;

		// return the accepted buffer len
		SAFE_SET(pdwActualOut, pOpenInst->bpfprogramlen);
	break;


	// function to set the internal buffer size
	case PIOC_SET_BUFFER_SIZE:

		// get the size to allocate
		nValue = ((PULONG)pBufIn)[0];

		// free the old buffer
		if (pOpenInst->Buffer != NULL) {
			NdisFreeMemory (pOpenInst->Buffer, pOpenInst->BufSize, 0);
		}

		pOpenInst->Buffer = NULL;

		// allocate the new buffer
		if (nValue > 0) {
			NdisAllocateMemory ((PVOID*)&pTempBuf, nValue, 0, NDIS_ADDR_M1);
			if (pTempBuf == NULL) {
				pOpenInst->BufSize = 0;
				return FALSE;
			}
			
			pOpenInst->Buffer = pTempBuf;
		}
			
		pOpenInst->Bhead	= 0;
		pOpenInst->Btail	= 0;
		pOpenInst->BLastByte= 0;
		pOpenInst->BufSize	= (UINT)nValue;

		SAFE_SET(pdwActualOut, nValue);
		
	break;


	// for sharing the event from the user
	case PIOC_EVNAME:
		if (pBufOut == NULL || dwLenOut < 32) {
			SAFE_SET(pdwActualOut, 0);
			bRet = FALSE;
		} else {
			wcscpy ((PWCHAR)pBufOut, SH_EVENT_NAME);
			SAFE_SET (pdwActualOut, wcslen (SH_EVENT_NAME));
		}

	break;


	// set read timeout function
	case PIOC_SRTIMEOUT:
		pOpenInst->TimeOut = ((PULONG)pBufIn)[0];
		SAFE_SET(pdwActualOut, pOpenInst->TimeOut);
	break;

	
	// resets the adapter instance
	case PIOC_RESET:
		bRet = PKTReset (pOpenInst);
	break;


	// requests of different type
	case PIOC_SETOID:
	case PIOC_QUERYOID:
		return PKTRequest (pOpenInst, dwCode, pBufIn, dwLenIn, pBufOut, dwLenOut, pdwActualOut);
	break;


	// read packets
	case PIOC_READ_PACKET:
		return PKTRead (pOpenInst, pBufOut, dwLenOut, pdwActualOut);
	break;


	// write packets
	case PIOC_WRITE_PACKET:
		return PKTWrite (pOpenInst, pBufIn, dwLenIn, pdwActualOut);
	break;


	// read mac name
	case PIOC_GET_MACNAME:
		*pdwActualOut = PKTGetMacNameList ((PWCHAR)pBufOut, dwLenOut);
	break;


	// minimum number of bytes to copy
	case PIOC_SMINTOCOPY:
		pOpenInst->MinToCopy = ((PULONG)pBufIn)[0];
		SAFE_SET(pdwActualOut, 0);
	break;


	// unknown function code. set out length to 0 and return true
	default:
		bRet = FALSE;
		SAFE_SET(pdwActualOut, 0);
	break;
	}

	return bRet;
}
Beispiel #13
0
int
main(int argc, char **argv)
{
	char *cp;
	int op;
	int dflag;
	char *infile;
	int Oflag;
	long snaplen;
	int dlt;
	bpf_u_int32 netmask = PCAP_NETMASK_UNKNOWN;
	char *cmdbuf;
	pcap_t *pd;
	struct bpf_program fcode;

#ifdef WIN32
	if(wsockinit() != 0) return 1;
#endif /* WIN32 */

	dflag = 1;
	infile = NULL;
	Oflag = 1;
	snaplen = 68;
  
	if ((cp = strrchr(argv[0], '/')) != NULL)
		program_name = cp + 1;
	else
		program_name = argv[0];

	opterr = 0;
	while ((op = getopt(argc, argv, "dF:m:Os:")) != -1) {
		switch (op) {

		case 'd':
			++dflag;
			break;

		case 'F':
			infile = optarg;
			break;

		case 'O':
			Oflag = 0;
			break;

		case 'm': {
			in_addr_t addr;

			addr = inet_addr(optarg);
			if (addr == INADDR_NONE)
				error("invalid netmask %s", optarg);
			netmask = addr;
			break;
		}

		case 's': {
			char *end;

			snaplen = strtol(optarg, &end, 0);
			if (optarg == end || *end != '\0'
			    || snaplen < 0 || snaplen > 65535)
				error("invalid snaplen %s", optarg);
			else if (snaplen == 0)
				snaplen = 65535;
			break;
		}

		default:
			usage();
			/* NOTREACHED */
		}
	}

	if (optind >= argc) {
		usage();
		/* NOTREACHED */
	}

	dlt = pcap_datalink_name_to_val(argv[optind]);
	if (dlt < 0)
		error("invalid data link type %s", argv[optind]);
	
	if (infile)
		cmdbuf = read_infile(infile);
	else
		cmdbuf = copy_argv(&argv[optind+1]);

	pd = pcap_open_dead(dlt, snaplen);
	if (pd == NULL)
		error("Can't open fake pcap_t");

	if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
		error("%s", pcap_geterr(pd));
	if (!bpf_validate(fcode.bf_insns, fcode.bf_len))
		warn("Filter doesn't pass validation");
	bpf_dump(&fcode, dflag);
	pcap_close(pd);
	exit(0);
}
Beispiel #14
0
int
main(int argc, char **argv)
{
	char *cp;
	int op;
#ifndef BDEBUG
	int dflag;
#endif
	char *infile;
	int Oflag;
	long snaplen;
	char *p;
	int dlt;
	int have_fcode = 0;
	bpf_u_int32 netmask = PCAP_NETMASK_UNKNOWN;
	char *cmdbuf;
	pcap_t *pd;
	struct bpf_program fcode;

#ifdef _WIN32
	if (pcap_wsockinit() != 0)
		return 1;
#endif /* _WIN32 */

#ifndef BDEBUG
	dflag = 1;
#else
	/* if optimizer debugging is enabled, output DOT graph
	 * `dflag=4' is equivalent to -dddd to follow -d/-dd/-ddd
	 * convention in tcpdump command line
	 */
	dflag = 4;
#endif
	infile = NULL;
	Oflag = 1;
	snaplen = 68;

	if ((cp = strrchr(argv[0], '/')) != NULL)
		program_name = cp + 1;
	else
		program_name = argv[0];

	opterr = 0;
	while ((op = getopt(argc, argv, "dF:m:Os:")) != -1) {
		switch (op) {

		case 'd':
			++dflag;
			break;

		case 'F':
			infile = optarg;
			break;

		case 'O':
			Oflag = 0;
			break;

		case 'm': {
			bpf_u_int32 addr;

			switch (inet_pton(AF_INET, optarg, &addr)) {

			case 0:                        
				error("invalid netmask %s", optarg);
				break;

			case -1:
				error("invalid netmask %s: %s", optarg,
				    pcap_strerror(errno));
				break;

			case 1:
				netmask = addr;
				break;
			}
			break;
		}

		case 's': {
			char *end;

			snaplen = strtol(optarg, &end, 0);
			if (optarg == end || *end != '\0'
			    || snaplen < 0 || snaplen > 65535)
				error("invalid snaplen %s", optarg);
			else if (snaplen == 0)
				snaplen = 65535;
			break;
		}

		default:
			usage();
			/* NOTREACHED */
		}
	}

	if (optind >= argc) {
		usage();
		/* NOTREACHED */
	}

	dlt = pcap_datalink_name_to_val(argv[optind]);
	if (dlt < 0) {
		dlt = (int)strtol(argv[optind], &p, 10);
		if (p == argv[optind] || *p != '\0')
			error("invalid data link type %s", argv[optind]);
	}

	if (infile)
		cmdbuf = read_infile(infile);
	else
		cmdbuf = copy_argv(&argv[optind+1]);

	pd = pcap_open_dead(dlt, snaplen);
	if (pd == NULL)
		error("Can't open fake pcap_t");

	if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
		error("%s", pcap_geterr(pd));

	have_fcode = 1;
	if (!bpf_validate(fcode.bf_insns, fcode.bf_len))
		warn("Filter doesn't pass validation");

#ifdef BDEBUG
	if (cmdbuf != NULL) {
		// replace line feed with space
		for (cp = cmdbuf; *cp != '\0'; ++cp) {
			if (*cp == '\r' || *cp == '\n') {
				*cp = ' ';
			}
		}
		// only show machine code if BDEBUG defined, since dflag > 3
		printf("machine codes for filter: %s\n", cmdbuf);
	} else
		printf("machine codes for empty filter:\n");
#endif

	bpf_dump(&fcode, dflag);
	free(cmdbuf);
	if (have_fcode)
		pcap_freecode (&fcode);
	pcap_close(pd);
	exit(0);
}
Beispiel #15
0
/*
 * There are only two special setsockopt's for SOL_SOCKET with PF_PACKET:
 * SO_ATTACH_FILTER and SO_DETACH_FILTER.
 *
 * Both of these setsockopt values are candidates for being handled by the
 * socket layer itself in future, however this requires understanding how
 * they would interact with all other sockets.
 */
static int
pfp_setsocket_sockopt(sock_lower_handle_t handle, int option_name,
    const void *optval, socklen_t optlen)
{
	struct bpf_program prog;
	struct bpf_insn *fcode;
	struct pfpsock *ps;
	struct sock_proto_props sopp;
	int error = 0;
	int size;

	ps = (struct pfpsock *)handle;

	switch (option_name) {
	case SO_ATTACH_FILTER :
#ifdef _LP64
		if (optlen == sizeof (struct bpf_program32)) {
			struct bpf_program32 prog32;

			bcopy(optval, &prog32, sizeof (prog32));
			prog.bf_len = prog32.bf_len;
			prog.bf_insns = (void *)(uint64_t)prog32.bf_insns;
		} else
#endif
		if (optlen == sizeof (struct bpf_program)) {
			bcopy(optval, &prog, sizeof (prog));
		} else if (optlen != sizeof (struct bpf_program)) {
			return (EINVAL);
		}
		if (prog.bf_len > BPF_MAXINSNS)
			return (EINVAL);

		size = prog.bf_len * sizeof (*prog.bf_insns);
		fcode = kmem_alloc(size, KM_SLEEP);
		if (ddi_copyin(prog.bf_insns, fcode, size, 0) != 0) {
			kmem_free(fcode, size);
			return (EFAULT);
		}

		if (bpf_validate(fcode, (int)prog.bf_len)) {
			rw_enter(&ps->ps_bpflock, RW_WRITER);
			pfp_release_bpf(ps);
			ps->ps_bpf.bf_insns = fcode;
			ps->ps_bpf.bf_len = size;
			rw_exit(&ps->ps_bpflock);

			return (0);
		}
		kmem_free(fcode, size);
		error = EINVAL;
		break;

	case SO_DETACH_FILTER :
		pfp_release_bpf(ps);
		break;

	case SO_RCVBUF :
		size = *(int32_t *)optval;
		if (size > sockmod_pfp_rcvbuf_max || size < 0)
			return (ENOBUFS);
		sopp.sopp_flags = SOCKOPT_RCVHIWAT;
		sopp.sopp_rxhiwat = size;
		ps->ps_upcalls->su_set_proto_props(ps->ps_upper, &sopp);
		ps->ps_rcvbuf = size;
		break;

	default :
		error = ENOPROTOOPT;
		break;
	}

	return (error);
}
Beispiel #16
0
int
main(void)
{
#ifndef BPF_JIT_COMPILER
	u_int	i;
#endif
	u_int   ret;
	int     sig;
#ifdef BPF_VALIDATE
	int	valid;
#endif

	/* Try to catch all signals */
	for (sig = SIGHUP; sig <= SIGUSR2; sig++)
		signal(sig, sig_handler);

#ifdef BPF_VALIDATE
	valid = bpf_validate(pc, nins);
	if (valid != 0 && invalid != 0) {
		if (verbose > 1)
			printf("Validated invalid instruction(s):\t");
		if (verbose > 0)
			printf("FAILED\n");
		return (FAILED);
	} else if (valid == 0 && invalid == 0) {
		if (verbose > 1)
			printf("Invalidated valid instruction(s):\t");
		if (verbose > 0)
			printf("FAILED\n");
		return (FAILED);
	} else if (invalid != 0) {
		if (verbose > 1)
			printf("Expected and invalidated:\t");
		if (verbose > 0)
			printf("PASSED\n");
		return (PASSED);
	}
#endif

#ifdef BPF_JIT_COMPILER
	ret = bpf_compile_and_filter();
#else
	for (i = 0; i < BPF_NRUNS; i++)
		ret = bpf_filter(nins != 0 ? pc : NULL, pkt, wirelen, buflen);
#endif
	if (expect_signal != 0) {
		if (verbose > 1)
			printf("Expected signal %d but got none:\t",
			    expect_signal);
		if (verbose > 0)
			printf("FAILED\n");
		return (FAILED);
	}
	if (ret != expect) {
		if (verbose > 1)
			printf("Expected 0x%x but got 0x%x:\t", expect, ret);
		if (verbose > 0)
			printf("FAILED\n");
		return (FAILED);
	}
	if (verbose > 1)
		printf("Expected and got 0x%x:\t", ret);
	if (verbose > 0)
		printf("PASSED\n");

	return (PASSED);
}