summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Leblond <eric@inl.fr>2008-07-29 12:08:19 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2008-07-29 12:08:19 +0200
commit6fcfeb97f7c28b75ee28d91663176ab5ff23414e (patch)
tree25580510e9dcb92ecbfbdb2a09cfa9cee1952881
parent2d4c60fed7c0179450d07523ac023fcec391e634 (diff)
MAC2STR: add support for the new RAW MAC keys
This patch modifies MAC2STR to use the new MAC keys that gives us more accurate information to parse the link layer header. This patch also does some probing based on the header and field size in the case of ULOG (since we do not have enough information to perform accurate parsing). Signed-off-by: Eric Leblond <eric@inl.fr> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--filter/ulogd_filter_MAC2STR.c174
1 files changed, 152 insertions, 22 deletions
diff --git a/filter/ulogd_filter_MAC2STR.c b/filter/ulogd_filter_MAC2STR.c
index 0035886..cecd3e2 100644
--- a/filter/ulogd_filter_MAC2STR.c
+++ b/filter/ulogd_filter_MAC2STR.c
@@ -26,67 +26,197 @@
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
#include <ulogd/ulogd.h>
-#define IPADDR_LENGTH 128
-
enum input_keys {
+ KEY_RAW_TYPE,
+ KEY_OOB_PROTOCOL,
KEY_RAW_MAC,
KEY_RAW_MACLEN,
+ KEY_RAW_MAC_SADDR,
+ KEY_RAW_MAC_ADDRLEN,
};
enum output_keys {
+ KEY_MAC_TYPE,
+ KEY_MAC_PROTOCOL,
KEY_MAC_SADDR,
+ KEY_MAC_DADDR,
+ KEY_MAC_ADDR,
};
static struct ulogd_key mac2str_inp[] = {
+ [KEY_RAW_TYPE] = {
+ .type = ULOGD_RET_UINT16,
+ .flags = ULOGD_RETF_NONE|ULOGD_KEYF_OPTIONAL,
+ .name = "raw.type",
+ },
+ [KEY_OOB_PROTOCOL] = {
+ .type = ULOGD_RET_UINT16,
+ .flags = ULOGD_RETF_NONE,
+ .name = "oob.protocol",
+ },
[KEY_RAW_MAC] = {
.type = ULOGD_RET_RAW,
- .flags = ULOGD_RETF_NONE,
+ .flags = ULOGD_RETF_NONE|ULOGD_KEYF_OPTIONAL,
.name = "raw.mac",
},
[KEY_RAW_MACLEN] = {
.type = ULOGD_RET_UINT16,
- .flags = ULOGD_RETF_NONE,
+ .flags = ULOGD_RETF_NONE|ULOGD_KEYF_OPTIONAL,
.name = "raw.mac_len",
},
-
+ [KEY_RAW_MAC_SADDR] = {
+ .type = ULOGD_RET_RAW,
+ .flags = ULOGD_RETF_NONE|ULOGD_KEYF_OPTIONAL,
+ .name = "raw.mac.saddr",
+ },
+ [KEY_RAW_MAC_ADDRLEN] = {
+ .type = ULOGD_RET_UINT16,
+ .flags = ULOGD_RETF_NONE|ULOGD_KEYF_OPTIONAL,
+ .name = "raw.mac.addrlen",
+ },
};
static struct ulogd_key mac2str_keys[] = {
- {
+ [KEY_MAC_TYPE] = {
+ .type = ULOGD_RET_UINT16,
+ .flags = ULOGD_RETF_NONE,
+ .name = "raw.type",
+ },
+ [KEY_MAC_PROTOCOL] = {
+ .type = ULOGD_RET_UINT16,
+ .flags = ULOGD_RETF_NONE,
+ .name = "oob.protocol",
+ },
+ [KEY_MAC_SADDR] = {
.type = ULOGD_RET_STRING,
.flags = ULOGD_RETF_FREE,
.name = "mac.saddr.str",
},
+ [KEY_MAC_DADDR] = {
+ .type = ULOGD_RET_STRING,
+ .flags = ULOGD_RETF_FREE,
+ .name = "mac.daddr.str",
+ },
+ [KEY_MAC_ADDR] = {
+ .type = ULOGD_RET_STRING,
+ .flags = ULOGD_RETF_FREE,
+ .name = "mac.str",
+ },
};
+static int parse_mac2str(struct ulogd_key *ret, unsigned char *mac,
+ int okey, int len)
+{
+ char *mac_str = calloc(len/sizeof(char)*3, sizeof(char));
+ char *buf_cur = mac_str;
+ int i;
+
+ if (mac_str == NULL)
+ return ULOGD_IRET_ERR;
+
+ for (i = 0; i < len; i++)
+ buf_cur += sprintf(buf_cur, "%02x%c", mac[i],
+ i == len - 1 ? 0 : ':');
+
+ ret[okey].u.value.ptr = mac_str;
+ ret[okey].flags |= ULOGD_RETF_VALID;
+
+ return ULOGD_IRET_OK;
+}
+
+static int parse_ethernet(struct ulogd_key *ret, struct ulogd_key *inp)
+{
+ int fret;
+ if (!pp_is_valid(inp, KEY_RAW_MAC_SADDR)) {
+ fret = parse_mac2str(ret,
+ GET_VALUE(inp, KEY_RAW_MAC).ptr
+ + ETH_ALEN,
+ KEY_MAC_SADDR, ETH_ALEN);
+ if (fret != ULOGD_IRET_OK)
+ return fret;
+ }
+ fret = parse_mac2str(ret, GET_VALUE(inp, KEY_RAW_MAC).ptr,
+ KEY_MAC_DADDR, ETH_ALEN);
+ if (fret != ULOGD_IRET_OK)
+ return fret;
+
+ ret[KEY_MAC_PROTOCOL].u.value.ui16 =
+ ntohs(*(u_int16_t *) (GET_VALUE(inp, KEY_RAW_MAC).ptr
+ + 2 * ETH_ALEN));
+ ret[KEY_MAC_PROTOCOL].flags |= ULOGD_RETF_VALID;
+
+ return ULOGD_IRET_OK;
+}
+
static int interp_mac2str(struct ulogd_pluginstance *pi)
{
struct ulogd_key *ret = pi->output.keys;
struct ulogd_key *inp = pi->input.keys;
+ u_int16_t type = 0;
+
+ if (pp_is_valid(inp, KEY_OOB_PROTOCOL)) {
+ ret[KEY_MAC_PROTOCOL].u.value.ui16 =
+ GET_VALUE(inp, KEY_OOB_PROTOCOL).ui16;
+ ret[KEY_MAC_PROTOCOL].flags |= ULOGD_RETF_VALID;
+ }
+
+ if (pp_is_valid(inp, KEY_RAW_MAC_SADDR)) {
+ int fret;
+ fret = parse_mac2str(ret,
+ GET_VALUE(inp, KEY_RAW_MAC_SADDR).ptr,
+ KEY_MAC_SADDR,
+ GET_VALUE(inp, KEY_RAW_MAC_ADDRLEN).ui16);
+ if (fret != ULOGD_IRET_OK)
+ return fret;
+ }
- if (pp_is_valid(inp, KEY_RAW_MAC)) {
- unsigned char *mac = (unsigned char *) GET_VALUE(inp, KEY_RAW_MAC).ptr;
- int len = GET_VALUE(inp, KEY_RAW_MACLEN).ui16;
- char *mac_str = calloc(len/sizeof(char)*3, sizeof(char));
- char *buf_cur = mac_str;
- int i;
-
- if (mac_str == NULL)
- return ULOGD_IRET_ERR;
-
- for (i = 0; i < len; i++)
- buf_cur += sprintf(buf_cur, "%02x%c", mac[i],
- i == len - 1 ? 0 : ':');
-
- ret[KEY_MAC_SADDR].u.value.ptr = mac_str;
- ret[KEY_MAC_SADDR].flags |= ULOGD_RETF_VALID;
+ if (!pp_is_valid(inp, KEY_RAW_MAC)) {
+ if (GET_VALUE(inp, KEY_RAW_MAC_ADDRLEN).ui16 == ETH_ALEN) {
+ ret[KEY_MAC_TYPE].u.value.ui16 = ARPHRD_ETHER;
+ ret[KEY_MAC_TYPE].flags |= ULOGD_RETF_VALID;
+ } else {
+ ret[KEY_MAC_TYPE].u.value.ui16 = ARPHRD_VOID;
+ ret[KEY_MAC_TYPE].flags |= ULOGD_RETF_VALID;
+ }
+ return ULOGD_IRET_OK;
}
+ if (pp_is_valid(inp, KEY_RAW_TYPE)) {
+ /* NFLOG with Linux >= 2.6.27 case */
+ ret[KEY_MAC_TYPE].u.value.ui16 = type =
+ GET_VALUE(inp, KEY_RAW_TYPE).ui16;
+ ret[KEY_MAC_TYPE].flags |= ULOGD_RETF_VALID;
+ } else {
+ /* ULOG case, treat ethernet encapsulation */
+ if (GET_VALUE(inp, KEY_RAW_MACLEN).ui16 == ETH_HLEN) {
+ ret[KEY_MAC_TYPE].u.value.ui16 = type = ARPHRD_ETHER;
+ ret[KEY_MAC_TYPE].flags |= ULOGD_RETF_VALID;
+ } else {
+ ret[KEY_MAC_TYPE].u.value.ui16 = type = ARPHRD_VOID;
+ ret[KEY_MAC_TYPE].flags |= ULOGD_RETF_VALID;
+ }
+ }
+
+ switch (type) {
+ case ARPHRD_ETHER:
+ parse_ethernet(ret, inp);
+ default:
+ /* convert raw header to string */
+ return parse_mac2str(ret,
+ GET_VALUE(inp, KEY_RAW_MAC).ptr,
+ KEY_MAC_ADDR,
+ GET_VALUE(inp,
+ KEY_RAW_MACLEN).ui16);
+ }
return ULOGD_IRET_OK;
}
+
+
static struct ulogd_plugin mac2str_pluging = {
.name = "MAC2STR",
.input = {