Skip to content

Commit

Permalink
Add IPv4 CIDR support and clean up code.
Browse files Browse the repository at this point in the history
  • Loading branch information
gamemann committed Aug 13, 2024
1 parent 1ce17dd commit 91138f1
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 92 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ The following table quickly explains the data types used within the configuratio
| enabled | bool | `false` | Whether the rule is enabled or not. |
| action | uint | `0` | The value of `0` drops or blocks the packet while `1` allows/passes the packet through. |
| block_time | uint | `1` | The amount of seconds to block the source IP for if matched. |
| src_ip | string | `NULL` | The source IPv4 address to match (e.g. `10.50.0.3`). |
| dst_ip | string | `NULL` | The destination IPv4 address to match (e.g. `10.50.0.4`) |
| src_ip | string | `NULL` | The source IPv4 address to match (e.g. `10.50.0.3`). CIDRs are also supported (e.g. `10.50.0.0/24`)! |
| dst_ip | string | `NULL` | The destination IPv4 address to match (e.g. `10.50.0.4`). CIDRs are also supported (e.g. `10.50.0.0/24`)! |
| src_ip6 | string | `NULL` | The source IPv6 address to match (e.g. `fe80::18c4:dfff:fe70:d8a6`). |
| dst_ip6 | string | `NULL` | The destination IPv6 address to match (e.g. `fe80::ac21:14ff:fe4b:3a6d`). |
| min_ttl | byte | `NULL` | The minimum TTL (time-to-live) to match. |
Expand Down
2 changes: 1 addition & 1 deletion src/cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const struct option opts[] =
*
* @return Void
*/
void parsecommandline(struct cmdline *cmd, int argc, char *argv[])
void ParseCommandLine(struct cmdline *cmd, int argc, char *argv[])
{
int c;

Expand Down
2 changes: 1 addition & 1 deletion src/cmdline.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ struct cmdline
unsigned int help : 1;
};

void parsecommandline(struct cmdline *cmd, int argc, char *argv[]);
void ParseCommandLine(struct cmdline *cmd, int argc, char *argv[]);
29 changes: 18 additions & 11 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "xdpfw.h"
#include "config.h"
#include "utils.h"

FILE *file;

Expand All @@ -18,7 +19,7 @@ FILE *file;
*
* @return Void
*/
void setcfgdefaults(struct config *cfg)
void SetCfgDefaults(struct config *cfg)
{
cfg->updatetime = 0;
cfg->interface = NULL;
Expand All @@ -30,13 +31,13 @@ void setcfgdefaults(struct config *cfg)
cfg->filters[i].id = 0;
cfg->filters[i].enabled = 0;
cfg->filters[i].action = 0;
cfg->filters[i].srcip = 0;
cfg->filters[i].dstip = 0;
cfg->filters[i].src_ip = 0;
cfg->filters[i].dst_ip = 0;

for (__u8 j = 0; j < 4; j++)
{
cfg->filters[i].srcip6[j] = 0;
cfg->filters[i].dstip6[j] = 0;
cfg->filters[i].src_ip6[j] = 0;
cfg->filters[i].dst_ip6[j] = 0;
}

cfg->filters[i].do_min_len = 0;
Expand Down Expand Up @@ -91,7 +92,7 @@ void setcfgdefaults(struct config *cfg)
*
* @return 0 on success or 1 on error.
*/
int opencfg(const char *filename)
int OpenCfg(const char *filename)
{
// Close any existing files.
if (file != NULL)
Expand All @@ -118,7 +119,7 @@ int opencfg(const char *filename)
*
* @return 0 on success or 1/-1 on error.
*/
int readcfg(struct config *cfg)
int ReadCfg(struct config *cfg)
{
// Not sure why this would be set to NULL after checking for it in OpenConfig(), but just for safety.
if (file == NULL)
Expand Down Expand Up @@ -232,15 +233,21 @@ int readcfg(struct config *cfg)

if (config_setting_lookup_string(filter, "src_ip", &sip))
{
cfg->filters[i].srcip = inet_addr(sip);
struct ip ip = ParseIp(sip);

cfg->filters[i].src_ip = ip.ip;
cfg->filters[i].src_cidr = ip.cidr;
}

// Destination IP (not required).
const char *dip;

if (config_setting_lookup_string(filter, "dst_ip", &dip))
{
cfg->filters[i].dstip = inet_addr(dip);
struct ip ip = ParseIp(dip);

cfg->filters[i].dst_ip = ip.ip;
cfg->filters[i].dst_cidr = ip.cidr;
}

// Source IP (IPv6) (not required).
Expand All @@ -254,7 +261,7 @@ int readcfg(struct config *cfg)

for (__u8 j = 0; j < 4; j++)
{
cfg->filters[i].srcip6[j] = in.__in6_u.__u6_addr32[j];
cfg->filters[i].src_ip6[j] = in.__in6_u.__u6_addr32[j];
}
}

Expand All @@ -269,7 +276,7 @@ int readcfg(struct config *cfg)

for (__u8 j = 0; j < 4; j++)
{
cfg->filters[i].dstip6[j] = in.__in6_u.__u6_addr32[j];
cfg->filters[i].dst_ip6[j] = in.__in6_u.__u6_addr32[j];
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ struct config
struct filter filters[MAX_FILTERS];
};

void setcfgdefaults(struct config *cfg);
int opencfg(const char *filename);
int readcfg(struct config *cfg);
void SetCfgDefaults(struct config *cfg);
int OpenCfg(const char *filename);
int ReadCfg(struct config *cfg);
42 changes: 42 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once

#include <linux/types.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>

struct ip
{
__u32 ip;
__u32 cidr;
};

/**
* Parses an IP string with CIDR support. Stores IP in network byte order in ip.ip and CIDR in ip.cidr.
*
* @param ip The IP string.
*
* @return Returns an IP structure with IP and CIDR.
*/
struct ip ParseIp(const char *ip)
{
struct ip ret = {0};
ret.cidr = 32;

char *token = strtok((char *) ip, "/");

if (token)
{
ret.ip = inet_addr(token);

token = strtok(NULL, "/");

if (token)
{
ret.cidr = (unsigned int) strtoul(token, NULL, 10);
}
}

return ret;
}
17 changes: 17 additions & 0 deletions src/xdp_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include "xdpfw.h"

/**
* Checks if an IP is within a specific CIDR range.
*
* @param src_ip The source/main IP to check against.
* @param net_ip The network IP.
* @param cidr The CIDR range.
*
* @return 1 on yes, 0 on no.
*/
static __always_inline __u8 IsIpInRange(__u32 src_ip, __u32 net_ip, __u8 cidr)
{
return !((src_ip ^ net_ip) & htonl(0xFFFFFFFFu << (32 - cidr)));
}
Loading

0 comments on commit 91138f1

Please sign in to comment.