New approach to tunnel decoding.

remotes/origin/master-1.0.x
Victor Julien 17 years ago
parent 982542cde6
commit 28d9415e37

@ -95,14 +95,19 @@ void DecodeIPV4(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t len)
return(DecodeICMPV4(t, p, pkt + IPV4_GET_HLEN(p), len - IPV4_GET_HLEN(p)));
break;
case IPPROTO_IPV6:
//printf("DecodeIPV4: next layer is IPV6\n");
//printf("DecodeIPV4: we are p %p\n", p);
/* spawn off tunnel packet */
SetupTunnelPkt(t, p, pkt + IPV4_GET_HLEN(p), len - IPV4_GET_HLEN(p), IPV4_GET_IPPROTO(p));
/* this is now a tunnel packet */
SET_TUNNEL_PKT(p);
break;
{
//printf("DecodeIPV4: next layer is IPV6\n");
//printf("DecodeIPV4: we are p %p\n", p);
/* spawn off tunnel packet */
Packet *tp = TunnelPktSetup(t, p, pkt + IPV4_GET_HLEN(p), len - IPV4_GET_HLEN(p), IPV4_GET_IPPROTO(p));
/* send that to the Tunnel decoder */
DecodeTunnel(t, tp, tp->pkt, tp->pktlen);
/* the current packet is now a tunnel packet */
SET_TUNNEL_PKT(p);
break;
}
}
return;

@ -180,6 +180,9 @@ typedef struct _Packet
Port sp;
Port dp;
u_int8_t proto;
u_int8_t recursion_level;
/* XXX make sure we can't be attacked on when the tunneled packet
* has the exact same tuple as the lower levels */
struct timeval ts;
@ -192,18 +195,17 @@ typedef struct _Packet
/* tunnel packet ref count */
u_int8_t tpr_cnt;
pthread_mutex_t mutex_rtv_cnt;
/* tunnel stuff */
u_int8_t tunnel_proto;
/* tunnel XXX convert to bitfield*/
int tunnel_pkt;
char tunnel_pkt;
char tunnel_verdicted;
/* nfq stuff */
#ifdef NFQ
NFQPacketVars nfq_v;
#endif /* NFQ */
/* tunnel stuff */
u_int8_t tunnel_proto;
/* storage */
u_int8_t pkt[65536];
u_int16_t pktlen;
@ -295,22 +297,32 @@ typedef struct _Packet
#define REJECT_PACKET_DST(p) ((p)->root ? ((p)->root->action = ACTION_REJECT_DST) : ((p)->action = ACTION_REJECT_DST))
#define REJECT_PACKET_BOTH(p) ((p)->root ? ((p)->root->action = ACTION_REJECT_BOTH) : ((p)->action = ACTION_REJECT_BOTH))
#define INCR_PKT_RTV(p) \
#define TUNNEL_INCR_PKT_RTV(p) \
{ \
mutex_lock((p)->root ? &(p)->root->mutex_rtv_cnt : &(p)->mutex_rtv_cnt); \
((p)->root ? (p)->root->rtv_cnt++ : (p)->rtv_cnt++); \
mutex_unlock((p)->root ? &(p)->root->mutex_rtv_cnt : &(p)->mutex_rtv_cnt); \
}
#define INCR_PKT_TPR(p) \
#define TUNNEL_INCR_PKT_TPR(p) \
{ \
mutex_lock((p)->root ? &(p)->root->mutex_rtv_cnt : &(p)->mutex_rtv_cnt); \
((p)->root ? (p)->root->tpr_cnt++ : (p)->tpr_cnt++); \
mutex_unlock((p)->root ? &(p)->root->mutex_rtv_cnt : &(p)->mutex_rtv_cnt); \
}
#define TUNNEL_DECR_PKT_TPR(p) \
{ \
mutex_lock((p)->root ? &(p)->root->mutex_rtv_cnt : &(p)->mutex_rtv_cnt); \
((p)->root ? (p)->root->tpr_cnt-- : (p)->tpr_cnt--); \
mutex_unlock((p)->root ? &(p)->root->mutex_rtv_cnt : &(p)->mutex_rtv_cnt); \
}
#define TUNNEL_DECR_PKT_TPR_NOLOCK(p) \
{ \
((p)->root ? (p)->root->tpr_cnt-- : (p)->tpr_cnt--); \
}
#define PKT_RTV(p) ((p)->root ? (p)->root->rtv_cnt : (p)->rtv_cnt)
#define PKT_TPR(p) ((p)->root ? (p)->root->tpr_cnt : (p)->tpr_cnt)
#define TUNNEL_PKT_RTV(p) ((p)->root ? (p)->root->rtv_cnt : (p)->rtv_cnt)
#define TUNNEL_PKT_TPR(p) ((p)->root ? (p)->root->tpr_cnt : (p)->tpr_cnt)
#define IS_TUNNEL_ROOT_PKT(p) (((p)->root == NULL && (p)->tunnel_pkt == 1))
#define IS_TUNNEL_PKT(p) (((p)->tunnel_pkt == 1))
@ -328,7 +340,7 @@ void DecodeUDP(ThreadVars *, Packet *, u_int8_t *, u_int16_t);
void DecodeHTTP(ThreadVars *, Packet *, u_int8_t *, u_int16_t);
Packet *SetupPkt (void);
void SetupTunnelPkt(ThreadVars *, Packet *, u_int8_t *, u_int16_t, u_int8_t);
Packet *TunnelPktSetup(ThreadVars *, Packet *, u_int8_t *, u_int16_t, u_int8_t);
#define DECODER_SET_EVENT(p, e) ((p)->events[(e/8)] |= (1<<(e%8)))
#define DECODER_ISSET_EVENT(p, e) ((p)->events[(e/8)] & (1<<(e%8)))

@ -3,8 +3,47 @@
#include "vips.h"
#include "decode.h"
#include "packet-queue.h"
#include "threads.h"
void PacketEnqueue (PacketQueue *q, Packet *p) {
if (IS_TUNNEL_PKT(p)) {
/* get a lock */
pthread_mutex_t *m = p->root ? &p->root->mutex_rtv_cnt : &p->mutex_rtv_cnt;
mutex_lock(m);
if (IS_TUNNEL_ROOT_PKT(p)) {
if (TUNNEL_PKT_TPR(p) == 0) {
/* if this packet is the root and there are no
* more tunnel packets, enqueue it */
/* fall through */
} else {
/* if this is the root and there are more tunnel
* packets, don't add this. It's still referenced
* by the tunnel packets, and we will enqueue it
* when we handle them */
p->tunnel_verdicted = 1;
mutex_unlock(m);
return;
}
} else {
if (p->root->tunnel_verdicted == 1 && TUNNEL_PKT_TPR(p) == 1) {
/* the root is ready and we are the last tunnel packet,
* lets enqueue them both. */
TUNNEL_DECR_PKT_TPR_NOLOCK(p);
/* handle the root */
PacketEnqueue(q,p->root);
/* fall through */
} else {
TUNNEL_DECR_PKT_TPR_NOLOCK(p);
/* fall through */
}
}
mutex_unlock(m);
}
/* more packets in queue */
if (q->top != NULL) {
p->next = q->top;

@ -67,12 +67,13 @@ void NFQSetupPkt (Packet *p, void *data)
struct nfq_data *tb = (struct nfq_data *)data;
int ret;
char *pktdata;
struct nfqnl_msg_packet_hdr *ph;
p->nfq_v.ph = nfq_get_msg_packet_hdr(tb);
if (p->nfq_v.ph != NULL) {
p->nfq_v.id = ntohl(p->nfq_v.ph->packet_id);
ph = nfq_get_msg_packet_hdr(tb);
if (ph != NULL) {
p->nfq_v.id = ntohl(ph->packet_id);
//p->nfq_v.hw_protocol = ntohs(p->nfq_v.ph->hw_protocol);
p->nfq_v.hw_protocol = p->nfq_v.ph->hw_protocol;
p->nfq_v.hw_protocol = ph->hw_protocol;
}
p->nfq_v.mark = nfq_get_nfmark(tb);
p->nfq_v.ifi = nfq_get_indev(tb);
@ -265,7 +266,8 @@ int VerdictNFQThreadDeinit(ThreadVars *tv, void *data) {
void NFQRecvPkt(NFQThreadVars *t) {
int rv, ret;
char buf[70000];
/* XXX what happens on rv == 0? */
/* XXX what happens on rv == 0? */
rv = recv(t->fd, buf, sizeof(buf), 0);
if (rv < 0) {
if (errno == EINTR || errno == EWOULDBLOCK) {
@ -306,14 +308,14 @@ void NFQSetVerdict(NFQThreadVars *t, Packet *p) {
int ret;
u_int32_t verdict;
if(p->action == ACTION_ALERT){
if (p->action == ACTION_ALERT) {
verdict = NF_ACCEPT;
} else if(p->action == ACTION_PASS){
} else if (p->action == ACTION_PASS) {
verdict = NF_ACCEPT;
} else if(p->action == ACTION_DROP){
} else if (p->action == ACTION_DROP) {
verdict = NF_DROP;
} else if(p->action == ACTION_REJECT||p->action == ACTION_REJECT_DST||
p->action == ACTION_REJECT_BOTH){
} else if (p->action == ACTION_REJECT || p->action == ACTION_REJECT_DST ||
p->action == ACTION_REJECT_BOTH){
verdict = NF_DROP;
} else {
/* a verdict we don't know about, drop to be sure */
@ -331,7 +333,28 @@ void NFQSetVerdict(NFQThreadVars *t, Packet *p) {
int VerdictNFQ(ThreadVars *tv, Packet *p, void *data) {
NFQThreadVars *ntv = (NFQThreadVars *)data;
NFQSetVerdict(ntv, p);
/* if this is a tunnel packet we check if we are ready to verdict
* already. */
if (IS_TUNNEL_PKT(p)) {
char verdict = 1;
pthread_mutex_t *m = p->root ? &p->root->mutex_rtv_cnt : &p->mutex_rtv_cnt;
mutex_lock(m);
/* if there are more tunnel packets than ready to verdict packets,
* we won't verdict this one */
if ((TUNNEL_PKT_TPR(p)+1) > TUNNEL_PKT_RTV(p)) {
verdict = 0;
}
mutex_unlock(m);
/* don't verdict if we are not ready */
if (verdict == 1) {
NFQSetVerdict(ntv, p);
}
} else {
/* no tunnel, verdict normally */
NFQSetVerdict(ntv, p);
}
return 0;
}

@ -14,11 +14,11 @@
typedef struct _NFQPacketVars
{
struct nfqnl_msg_packet_hdr *ph;
int id; /* this nfq packets id */
u_int32_t mark;
u_int32_t ifi;
u_int32_t ifo;
int id;
u_int16_t hw_protocol;
} NFQPacketVars;

@ -90,12 +90,13 @@ Packet *SetupPkt (void)
return p;
}
void SetupTunnelPkt(ThreadVars *t, Packet *parent, u_int8_t *pkt, u_int16_t len, u_int8_t proto)
Packet *TunnelPktSetup(ThreadVars *t, Packet *parent, u_int8_t *pkt, u_int16_t len, u_int8_t proto)
{
/* get us a packet */
mutex_lock(&packet_q.mutex_q);
Packet *p = PacketDequeue(&packet_q);
mutex_unlock(&packet_q.mutex_q);
CLEAR_PACKET(p);
/* set the root ptr to the lowest layer */
@ -109,24 +110,10 @@ void SetupTunnelPkt(ThreadVars *t, Packet *parent, u_int8_t *pkt, u_int16_t len,
p->pktlen = len;
memcpy(&p->pkt, pkt, len);
/* copy queue id's */
/* XXX review how to insert tunnel packets into the queue decoders use */
p->pickup_q_id = parent->pickup_q_id;
p->verdict_q_id = parent->verdict_q_id;
/* set tunnel flags */
SET_TUNNEL_PKT(p);
INCR_PKT_TPR(p);
/* enqueue the packet in the pickup_q */
PacketQueue *pq = &trans_q[p->pickup_q_id];
/* lock mutex and add the packet to the queue */
mutex_lock(&pq->mutex_q);
PacketEnqueue(pq, p);
pthread_cond_signal(&pq->cond_q);
mutex_unlock(&pq->mutex_q);
return;
TUNNEL_INCR_PKT_TPR(p);
return p;
}
/* this function should only be called for tunnel packets
@ -146,6 +133,7 @@ void SetupTunnelPkt(ThreadVars *t, Packet *parent, u_int8_t *pkt, u_int16_t len,
* one.
*
*/
#if 0
static Packet * VerdictTunnelPacket(Packet *p) {
char verdict = 1;
Packet *vp = NULL;
@ -189,44 +177,8 @@ static Packet * VerdictTunnelPacket(Packet *p) {
mutex_unlock(&packet_q.mutex_q);
return vp;
}
#endif
#if 0
void *DecoderThread(void *td) {
ThreadVars *th_v = (ThreadVars *)td;
int run = 1;
u_int32_t cnt = 0;
printf("DecoderThread[%d] started...\n", th_v->tid);
while(run) {
Packet *p = th_v->tmqh_in(th_v);
if (p == NULL) {
if (threadflags & VIPS_KILLDECODE)
run = 0;
} else {
#ifdef COUNTERS
cnt++;
#endif /* COUNTERS */
if ((IS_TUNNEL_PKT(p))) {
DecodeTunnel(th_v, p, p->pkt, p->pktlen);
}
else {
#ifdef NFQ
DecodeNFQ(th_v, p);
#endif /* NFQ */
}
/* lock mutex and add the packet to the queue */
th_v->tmqh_out(th_v,p);
}
}
printf("DecoderThread[%d] cnt %u\n", th_v->tid, cnt);
printf("DecoderThread[%d] ended...\n", th_v->tid);
pthread_exit((void *) 0);
}
void *DetectThread(void *td) {
ThreadVars *th_v = (ThreadVars *)td;
int run = 1;
@ -268,7 +220,6 @@ void *DetectThread(void *td) {
}
#endif
//ThreadVars th_v[NUM_THREADS];
int main(int argc, char **argv)
{

Loading…
Cancel
Save