132 lines
3.6 KiB
C
132 lines
3.6 KiB
C
#include "dablooms.h"
|
|
#include "packet_dabloom.h"
|
|
#include "packet_internal.h"
|
|
|
|
struct packet_key
|
|
{
|
|
// TCP or UDP
|
|
uint32_t seq; // network order
|
|
uint32_t ack; // network order
|
|
uint16_t src_port; // network order
|
|
uint16_t dst_port; // network order
|
|
uint16_t l4_checksum; // network order
|
|
|
|
// IPv4
|
|
uint16_t ip_id; // network order
|
|
uint32_t src_addr; // network order
|
|
uint32_t dst_addr; // network order
|
|
} __attribute__((__packed__));
|
|
|
|
struct packet_dabloom
|
|
{
|
|
struct expiry_dablooms_handle *dablooms;
|
|
};
|
|
|
|
/******************************************************************************
|
|
* Private API
|
|
******************************************************************************/
|
|
|
|
// return 0: success
|
|
// reutrn -1: error
|
|
static inline int packet_key_get(const struct packet *packet, struct packet_key *key)
|
|
{
|
|
const struct layer_internal *ip_layer = packet_get_innermost_layer(packet, LAYER_PROTO_IPV4);
|
|
const struct layer_internal *tcp_layer = packet_get_innermost_layer(packet, LAYER_PROTO_TCP);
|
|
const struct layer_internal *udp_layer = packet_get_innermost_layer(packet, LAYER_PROTO_UDP);
|
|
if (ip_layer == NULL || (tcp_layer == NULL && udp_layer == NULL))
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
memset(key, 0, sizeof(struct packet_key));
|
|
|
|
const struct ip *iphdr = (const struct ip *)ip_layer->hdr_ptr;
|
|
key->ip_id = iphdr->ip_id;
|
|
key->src_addr = iphdr->ip_src.s_addr;
|
|
key->dst_addr = iphdr->ip_dst.s_addr;
|
|
|
|
if (tcp_layer)
|
|
{
|
|
const struct tcphdr *tcphdr = (const struct tcphdr *)tcp_layer->hdr_ptr;
|
|
key->seq = tcphdr->th_seq;
|
|
key->ack = tcphdr->th_ack;
|
|
key->src_port = tcphdr->th_sport;
|
|
key->dst_port = tcphdr->th_dport;
|
|
key->l4_checksum = tcphdr->th_sum;
|
|
}
|
|
else
|
|
{
|
|
const struct udphdr *udphdr = (const struct udphdr *)udp_layer->hdr_ptr;
|
|
key->src_port = udphdr->uh_sport;
|
|
key->dst_port = udphdr->uh_dport;
|
|
key->l4_checksum = udphdr->uh_sum;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* Public API
|
|
******************************************************************************/
|
|
|
|
struct packet_dabloom *packet_dabloom_new(uint32_t capacity, uint32_t timeout, double error_rate, uint64_t now)
|
|
{
|
|
struct packet_dabloom *pkt_dab = (struct packet_dabloom *)calloc(1, sizeof(struct packet_dabloom));
|
|
if (pkt_dab == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pkt_dab->dablooms = expiry_dablooms_new(capacity, error_rate, now, timeout);
|
|
if (pkt_dab->dablooms == NULL)
|
|
{
|
|
free(pkt_dab);
|
|
return NULL;
|
|
}
|
|
|
|
return pkt_dab;
|
|
}
|
|
|
|
void packet_dabloom_free(struct packet_dabloom *pkt_dab)
|
|
{
|
|
if (pkt_dab)
|
|
{
|
|
if (pkt_dab->dablooms)
|
|
{
|
|
expiry_dablooms_free(pkt_dab->dablooms);
|
|
pkt_dab->dablooms = NULL;
|
|
}
|
|
free(pkt_dab);
|
|
pkt_dab = NULL;
|
|
}
|
|
}
|
|
|
|
// return 1: found
|
|
// reutrn 0: no found
|
|
int packet_dabloom_lookup(struct packet_dabloom *pkt_dab, const struct packet *packet, uint64_t now)
|
|
{
|
|
struct packet_key key;
|
|
if (packet_key_get(packet, &key) == -1)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (expiry_dablooms_search(pkt_dab->dablooms, (const char *)&key, sizeof(struct packet_key), now) == 1)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void packet_dabloom_add(struct packet_dabloom *pkt_dab, const struct packet *packet, uint64_t now)
|
|
{
|
|
struct packet_key key;
|
|
if (packet_key_get(packet, &key) == -1)
|
|
{
|
|
return;
|
|
}
|
|
|
|
expiry_dablooms_add(pkt_dab->dablooms, (const char *)&key, sizeof(struct packet_key), now);
|
|
}
|