X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/8f7f273fa4ce32e983f4437a7efa89d75062a2f9..5e10b16d95550d4656d8b594f3cbb6a3892db688:/package/wprobe/src/kernel/wprobe-core.c diff --git a/package/wprobe/src/kernel/wprobe-core.c b/package/wprobe/src/kernel/wprobe-core.c index d8f5a16f6..cf0c74aba 100644 --- a/package/wprobe/src/kernel/wprobe-core.c +++ b/package/wprobe/src/kernel/wprobe-core.c @@ -31,7 +31,10 @@ #define static #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) -#define list_for_each_rcu __list_for_each_rcu +#define list_for_each_rcu(pos, head) \ +for (pos = rcu_dereference((head)->next); \ +prefetch(pos->next), pos != (head); \ +pos = rcu_dereference(pos->next)) #endif #define WPROBE_MIN_INTERVAL 100 /* minimum measurement interval in msecs */ @@ -203,6 +206,7 @@ wprobe_get_dev(struct nlattr *attr) int wprobe_add_frame(struct wprobe_iface *dev, const struct wprobe_wlan_hdr *hdr, void *data, int len) { + struct wprobe_wlan_hdr *new_hdr; struct wprobe_filter *f; struct sk_buff *skb; unsigned long flags; @@ -221,7 +225,10 @@ wprobe_add_frame(struct wprobe_iface *dev, const struct wprobe_wlan_hdr *hdr, vo if (len + skb->len > WPROBE_MAX_FRAME_SIZE) len = WPROBE_MAX_FRAME_SIZE - skb->len; - memcpy(skb_put(skb, f->hdrlen), hdr, sizeof(struct wprobe_wlan_hdr)); + new_hdr = (struct wprobe_wlan_hdr *) skb_put(skb, f->hdrlen); + memcpy(new_hdr, hdr, sizeof(struct wprobe_wlan_hdr)); + new_hdr->len = cpu_to_be16(new_hdr->len); + memcpy(skb_put(skb, len), data, len); for(i = 0; i < f->n_groups; i++) { @@ -236,8 +243,13 @@ wprobe_add_frame(struct wprobe_iface *dev, const struct wprobe_wlan_hdr *hdr, vo def = j; continue; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) + if (sk_run_filter(skb, fi->filter) == 0) + continue; +#else if (sk_run_filter(skb, fi->filter, fi->hdr.n_items) == 0) continue; +#endif found = true; break; @@ -844,6 +856,7 @@ wprobe_check_filter(void *data, int datalen, int gs) hdr->name[31] = 0; cur_is = be32_to_cpu(hdr->n_items); + hdr->n_items = cur_is; is += cur_is; for (j = 0; j < cur_is; j++) { struct sock_filter *sf; @@ -854,11 +867,13 @@ wprobe_check_filter(void *data, int datalen, int gs) if (data > end) goto overrun; - if (hdr->n_items > 1024) + hdr->name[31] = 0; + n_items = be32_to_cpu(hdr->n_items); + hdr->n_items = n_items; + + if (n_items > 1024) goto overrun; - hdr->name[31] = 0; - hdr->n_items = n_items = be32_to_cpu(hdr->n_items); sf = data; if (n_items > 0) { for (k = 0; k < n_items; k++) { @@ -968,7 +983,7 @@ wprobe_set_filter(struct wprobe_iface *dev, void *data, int len) for (j = 0; j < g->n_items; j++) { hdr = data; f->items[cur_is++] = data; - data += sizeof(*hdr) + be32_to_cpu(hdr->n_items) * sizeof(struct sock_filter); + data += sizeof(*hdr) + hdr->n_items * sizeof(struct sock_filter); } } rcu_assign_pointer(dev->active_filter, f);