Skip to content

Instantly share code, notes, and snippets.

@blacklion

blacklion/rx.c Secret

Created June 17, 2019 17:38
Show Gist options
  • Save blacklion/072537283e91d39638438c9456b29292 to your computer and use it in GitHub Desktop.
Save blacklion/072537283e91d39638438c9456b29292 to your computer and use it in GitHub Desktop.
Simple net/radix.c client code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "radix.h"
typedef struct _flow_key {
uint8_t len;
uint8_t pad[2];
uint8_t proto;
in_addr_t src;
uint32_t sport;
in_addr_t dst;
uint32_t dport;
} flow_key;
typedef struct _table_node {
struct radix_node rn[2];
flow_key key;
flow_key msk;
uint32_t value;
} table_node;
#define KEY_LEN(v) *((uint8_t *)&(v))
#define KEY_LEN_FLOW (sizeof(flow_key))
#define OFF_LEN_FLOW (8 * offsetof(flow_key, proto))
static void add_to_tree(struct radix_node_head *head, uint8_t proto, const char *src, uint16_t sport, const char *dst, uint16_t dport, uint32_t value)
{
table_node *val = calloc(sizeof(sizeof *val), 1);
val->value = value;
KEY_LEN(val->key) = KEY_LEN_FLOW;
KEY_LEN(val->msk) = KEY_LEN_FLOW;
if (proto != 0) {
val->key.proto = proto;
val->msk.proto = (uint8_t)(~0);
}
if (src != NULL) {
val->key.src = inet_addr(src);
val->msk.src = (in_addr_t)(~0);
}
if (sport != 0) {
val->key.sport = sport;
val->msk.sport = (uint32_t)(~0);
}
if (dst != NULL) {
val->key.dst = inet_addr(dst);
val->msk.dst = (in_addr_t)(~0);
}
if (dport != 0) {
val->key.dport = dport;
val->msk.dport = (uint32_t)(~0);
}
if (head->rnh_addaddr(&val->key, &val->msk, &head->rh, val->rn) != val->rn) {
fprintf(stderr, "Can not add value %u\n", value);
}
}
static void find_in_tree(struct radix_node_head *head, uint8_t proto, const char *src, uint16_t sport, const char *dst, uint16_t dport)
{
table_node *val;
flow_key key;
memset(&key, 0, sizeof(key));
KEY_LEN(key) = KEY_LEN_FLOW;
key.proto = proto;
key.src = inet_addr(src);
key.sport = sport;
key.dst = inet_addr(dst);
key.dport = dport;
val = (table_node *)head->rnh_matchaddr(&key, &head->rh);
if (val != NULL) {
printf("%u %s:%u %s:%u -> %u\n", proto, src, sport, dst, dport, val->value);
} else {
printf("%u %s:%u %s:%u -> NOT FOUND\n", proto, src, sport, dst, dport);
}
}
int main(int argc, char *argv[])
{
struct radix_node_head *head;
rn_inithead((void**)&head, OFF_LEN_FLOW);
/* Put something simple */
add_to_tree(head, 0, NULL, 0, "192.168.134.1", 22, 42);
add_to_tree(head, 0, "10.0.0.1", 0, "192.168.134.1", 22, 43);
add_to_tree(head, 10, NULL, 0, "192.168.134.1", 22, 44);
add_to_tree(head, 10, "10.0.0.1", 0, "192.168.134.1", 22, 45);
add_to_tree(head, 0, "10.0.0.1", 1234, "192.168.134.1", 22, 46);
find_in_tree(head, 10, "10.0.0.1", 1234, "192.168.134.1", 22);
rn_detachhead((void**)&head);
return (0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment