1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-06 22:49:02 +00:00

Update libpcap to 1.7.3, partially addressing #34

This commit is contained in:
dmiller
2015-05-01 20:24:47 +00:00
parent d8c13c49e1
commit 4bbef7d69b
196 changed files with 9965 additions and 7133 deletions

View File

@@ -38,11 +38,6 @@
* @(#)bpf.c 7.5 (Berkeley) 7/15/91
*/
#if !(defined(lint) || defined(KERNEL) || defined(_KERNEL))
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/bpf/net/bpf_filter.c,v 1.46 2008-01-02 04:16:46 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -200,23 +195,39 @@ m_xhalf(m, k, err)
}
#endif
#ifdef __linux__
#include <linux/types.h>
#include <linux/if_packet.h>
#include <linux/filter.h>
#endif
enum {
BPF_S_ANC_NONE,
BPF_S_ANC_VLAN_TAG,
BPF_S_ANC_VLAN_TAG_PRESENT,
};
/*
* Execute the filter program starting at pc on the packet p
* wirelen is the length of the original packet
* buflen is the amount of data present
* aux_data is auxiliary data, currently used only when interpreting
* filters intended for the Linux kernel in cases where the kernel
* rejects the filter; it contains VLAN tag information
* For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0,
* in all other cases, p is a pointer to a buffer and buflen is its size.
*/
u_int
bpf_filter(pc, p, wirelen, buflen)
bpf_filter_with_aux_data(pc, p, wirelen, buflen, aux_data)
register const struct bpf_insn *pc;
register const u_char *p;
u_int wirelen;
register u_int buflen;
register const struct bpf_aux_data *aux_data;
{
register u_int32 A, X;
register int k;
int32 mem[BPF_MEMWORDS];
register bpf_u_int32 k;
u_int32 mem[BPF_MEMWORDS];
#if defined(KERNEL) || defined(_KERNEL)
struct mbuf *m, *n;
int merr, len;
@@ -255,7 +266,7 @@ bpf_filter(pc, p, wirelen, buflen)
case BPF_LD|BPF_W|BPF_ABS:
k = pc->k;
if (k + sizeof(int32) > buflen) {
if (k > buflen || sizeof(int32_t) > buflen - k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
@@ -272,7 +283,7 @@ bpf_filter(pc, p, wirelen, buflen)
case BPF_LD|BPF_H|BPF_ABS:
k = pc->k;
if (k + sizeof(short) > buflen) {
if (k > buflen || sizeof(int16_t) > buflen - k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
@@ -288,22 +299,50 @@ bpf_filter(pc, p, wirelen, buflen)
continue;
case BPF_LD|BPF_B|BPF_ABS:
k = pc->k;
if (k >= buflen) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
n = m;
MINDEX(len, n, k);
A = mtod(n, u_char *)[k];
continue;
#else
return 0;
#endif
}
A = p[k];
continue;
{
#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
int code = BPF_S_ANC_NONE;
#define ANCILLARY(CODE) case SKF_AD_OFF + SKF_AD_##CODE: \
code = BPF_S_ANC_##CODE; \
if (!aux_data) \
return 0; \
break;
switch (pc->k) {
ANCILLARY(VLAN_TAG);
ANCILLARY(VLAN_TAG_PRESENT);
default :
#endif
k = pc->k;
if (k >= buflen) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
n = m;
MINDEX(len, n, k);
A = mtod(n, u_char *)[k];
continue;
#else
return 0;
#endif
}
A = p[k];
#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
}
switch (code) {
case BPF_S_ANC_VLAN_TAG:
if (aux_data)
A = aux_data->vlan_tag;
break;
case BPF_S_ANC_VLAN_TAG_PRESENT:
if (aux_data)
A = aux_data->vlan_tag_present;
break;
}
#endif
continue;
}
case BPF_LD|BPF_W|BPF_LEN:
A = wirelen;
continue;
@@ -314,7 +353,8 @@ bpf_filter(pc, p, wirelen, buflen)
case BPF_LD|BPF_W|BPF_IND:
k = X + pc->k;
if (k + sizeof(int32) > buflen) {
if (pc->k > buflen || X > buflen - pc->k ||
sizeof(int32_t) > buflen - k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
@@ -331,7 +371,8 @@ bpf_filter(pc, p, wirelen, buflen)
case BPF_LD|BPF_H|BPF_IND:
k = X + pc->k;
if (k + sizeof(short) > buflen) {
if (X > buflen || pc->k > buflen - X ||
sizeof(int16_t) > buflen - k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
@@ -348,7 +389,7 @@ bpf_filter(pc, p, wirelen, buflen)
case BPF_LD|BPF_B|BPF_IND:
k = X + pc->k;
if (k >= buflen) {
if (pc->k >= buflen || X >= buflen - pc->k) {
#if defined(KERNEL) || defined(_KERNEL)
if (m == NULL)
return 0;
@@ -469,6 +510,12 @@ bpf_filter(pc, p, wirelen, buflen)
A /= X;
continue;
case BPF_ALU|BPF_MOD|BPF_X:
if (X == 0)
return 0;
A %= X;
continue;
case BPF_ALU|BPF_AND|BPF_X:
A &= X;
continue;
@@ -477,6 +524,10 @@ bpf_filter(pc, p, wirelen, buflen)
A |= X;
continue;
case BPF_ALU|BPF_XOR|BPF_X:
A ^= X;
continue;
case BPF_ALU|BPF_LSH|BPF_X:
A <<= X;
continue;
@@ -501,6 +552,10 @@ bpf_filter(pc, p, wirelen, buflen)
A /= pc->k;
continue;
case BPF_ALU|BPF_MOD|BPF_K:
A %= pc->k;
continue;
case BPF_ALU|BPF_AND|BPF_K:
A &= pc->k;
continue;
@@ -509,6 +564,10 @@ bpf_filter(pc, p, wirelen, buflen)
A |= pc->k;
continue;
case BPF_ALU|BPF_XOR|BPF_K:
A ^= pc->k;
continue;
case BPF_ALU|BPF_LSH|BPF_K:
A <<= pc->k;
continue;
@@ -532,6 +591,17 @@ bpf_filter(pc, p, wirelen, buflen)
}
}
u_int
bpf_filter(pc, p, wirelen, buflen)
register const struct bpf_insn *pc;
register const u_char *p;
u_int wirelen;
register u_int buflen;
{
return bpf_filter_with_aux_data(pc, p, wirelen, buflen, NULL);
}
/*
* Return true if the 'fcode' is a valid filter program.
* The constraints are that each jump be forward and to a valid
@@ -611,13 +681,16 @@ bpf_validate(f, len)
case BPF_MUL:
case BPF_OR:
case BPF_AND:
case BPF_XOR:
case BPF_LSH:
case BPF_RSH:
case BPF_NEG:
break;
case BPF_DIV:
case BPF_MOD:
/*
* Check for constant division by 0.
* Check for constant division or modulus
* by 0.
*/
if (BPF_SRC(p->code) == BPF_K && p->k == 0)
return 0;