#ifndef NFTABLES_PROTO_H
#define NFTABLES_PROTO_H
#include <nftables.h>
#include <datatype.h>
#include <linux/netfilter/nf_tables.h>
/**
* enum proto_bases - protocol bases
*
* @PROTO_BASE_INVALID: uninitialised, does not happen
* @PROTO_BASE_LL_HDR: link layer header
* @PROTO_BASE_NETWORK_HDR: network layer header
* @PROTO_BASE_TRANSPORT_HDR: transport layer header
*/
enum proto_bases {
PROTO_BASE_INVALID,
PROTO_BASE_LL_HDR,
PROTO_BASE_NETWORK_HDR,
PROTO_BASE_TRANSPORT_HDR,
__PROTO_BASE_MAX
};
#define PROTO_BASE_MAX (__PROTO_BASE_MAX - 1)
extern const char *proto_base_names[];
extern const char *proto_base_tokens[];
/**
* struct proto_hdr_template - protocol header field description
*
* @token: parser token describing the header field
* @dtype: data type of the header field
* @offset: offset of the header field from base
* @len: length of header field
* @meta_key: special case: meta expression key
*/
struct proto_hdr_template {
const char *token;
const struct datatype *dtype;
uint16_t offset;
uint16_t len;
enum byteorder byteorder;
enum nft_meta_keys meta_key;
};
#define PROTO_HDR_TEMPLATE(__token, __dtype, __byteorder, __offset, __len)\
{ \
.token = (__token), \
.dtype = (__dtype), \
.byteorder = (__byteorder), \
.offset = (__offset), \
.len = (__len), \
}
#define PROTO_META_TEMPLATE(__token, __dtype, __key, __len) \
{ \
.token = (__token), \
.dtype = (__dtype), \
.meta_key = (__key), \
.len = (__len), \
}
#define PROTO_UPPER_MAX 16
#define PROTO_HDRS_MAX 20
/**
* struct proto_desc - protocol header description
*
* @name: protocol name
* @base: header base
* @checksum_key: key of template containing checksum
* @protocol_key: key of template containing upper layer protocol description
* @length: total size of the header, in bits
* @protocols: link to upper layer protocol descriptions indexed by protocol value
* @templates: header templates
* @pseudohdr: header fields that are part of upper layer checksum pseudoheader
*/
struct proto_desc {
const char *name;
enum proto_bases base;
unsigned int checksum_key;
unsigned int protocol_key;
unsigned int length;
struct {
unsigned int num;
const struct proto_desc *desc;
} protocols[PROTO_UPPER_MAX];
struct proto_hdr_template templates[PROTO_HDRS_MAX];
struct {
uint8_t order[PROTO_HDRS_MAX];
uint32_t filter;
} format;
unsigned int pseudohdr[PROTO_HDRS_MAX];
};
#define PROTO_LINK(__num, __desc) { .num = (__num), .desc = (__desc), }
/**
* struct hook_proto_desc - description of protocol constraints imposed by hook family
*
* @base: protocol base of packets
* @desc: protocol description of packets
*/
struct hook_proto_desc {
enum proto_bases base;
const struct proto_desc *desc;
};
#define HOOK_PROTO_DESC(__base, __desc) { .base = (__base), .desc = (__desc), }
extern const struct hook_proto_desc hook_proto_desc[];
/**
* struct dev_proto_desc - description of device LL protocol
*
* @desc: protocol description
* @type: arphrd value
*/
struct dev_proto_desc {
const struct proto_desc *desc;
uint16_t type;
};
#define DEV_PROTO_DESC(__type, __desc) { .type = (__type), .desc = (__desc), }
extern int proto_dev_type(const struct proto_desc *desc, uint16_t *res);
extern const struct proto_desc *proto_dev_desc(uint16_t type);
/**
* struct proto_ctx - protocol context
*
* debug_mask: display debugging information
* @family: hook family
* @location: location of the relational expression defining the context
* @desc: protocol description for this layer
* @offset: offset from the base, for stacked headers (eg 8*14 for vlan on top of ether)
*
* The location of the context is the location of the relational expression
* defining it, either directly through a protocol match or indirectly
* through a dependency.
*/
struct proto_ctx {
unsigned int debug_mask;
unsigned int family;
struct {
struct location location;
const struct proto_desc *desc;
unsigned int offset;
} protocol[PROTO_BASE_MAX + 1];
};
extern void proto_ctx_init(struct proto_ctx *ctx, unsigned int family,
unsigned int debug_mask);
extern void proto_ctx_update(struct proto_ctx *ctx, enum proto_bases base,
const struct location *loc,
const struct proto_desc *desc);
extern const struct proto_desc *proto_find_upper(const struct proto_desc *base,
unsigned int num);
extern int proto_find_num(const struct proto_desc *base,
const struct proto_desc *desc);
enum eth_hdr_fields {
ETHHDR_INVALID,
ETHHDR_DADDR,
ETHHDR_SADDR,
ETHHDR_TYPE,
};
enum vlan_hdr_fields {
VLANHDR_INVALID,
VLANHDR_PCP,
VLANHDR_CFI,
VLANHDR_VID,
VLANHDR_TYPE,
};
enum arp_hdr_fields {
ARPHDR_INVALID,
ARPHDR_HRD,
ARPHDR_PRO,
ARPHDR_HLN,
ARPHDR_PLN,
ARPHDR_OP,
ARPHDR_SADDR_ETHER,
ARPHDR_DADDR_ETHER,
ARPHDR_SADDR_IP,
ARPHDR_DADDR_IP,
};
enum ip_hdr_fields {
IPHDR_INVALID,
IPHDR_VERSION,
IPHDR_HDRLENGTH,
IPHDR_DSCP,
IPHDR_ECN,
IPHDR_LENGTH,
IPHDR_ID,
IPHDR_FRAG_OFF,
IPHDR_TTL,
IPHDR_PROTOCOL,
IPHDR_CHECKSUM,
IPHDR_SADDR,
IPHDR_DADDR,
};
enum icmp_hdr_fields {
ICMPHDR_INVALID,
ICMPHDR_TYPE,
ICMPHDR_CODE,
ICMPHDR_CHECKSUM,
ICMPHDR_ID,
ICMPHDR_SEQ,
ICMPHDR_GATEWAY,
ICMPHDR_MTU,
};
enum igmp_hdr_fields {
IGMPHDR_INVALID,
IGMPHDR_TYPE,
IGMPHDR_CHECKSUM,
IGMPHDR_MRT,
IGMPHDR_GROUP,
};
enum icmp6_hdr_fields {
ICMP6HDR_INVALID,
ICMP6HDR_TYPE,
ICMP6HDR_CODE,
ICMP6HDR_CHECKSUM,
ICMP6HDR_PPTR,
ICMP6HDR_MTU,
ICMP6HDR_ID,
ICMP6HDR_SEQ,
ICMP6HDR_MAXDELAY,
};
enum ip6_hdr_fields {
IP6HDR_INVALID,
IP6HDR_VERSION,
IP6HDR_DSCP,
IP6HDR_ECN,
IP6HDR_FLOWLABEL,
IP6HDR_LENGTH,
IP6HDR_NEXTHDR,
IP6HDR_HOPLIMIT,
IP6HDR_SADDR,
IP6HDR_DADDR,
IP6HDR_PROTOCOL,
};
enum ah_hdr_fields {
AHHDR_INVALID,
AHHDR_NEXTHDR,
AHHDR_HDRLENGTH,
AHHDR_RESERVED,
AHHDR_SPI,
AHHDR_SEQUENCE,
};
enum esp_hdr_fields {
ESPHDR_INVALID,
ESPHDR_SPI,
ESPHDR_SEQUENCE,
};
enum comp_hdr_fields {
COMPHDR_INVALID,
COMPHDR_NEXTHDR,
COMPHDR_FLAGS,
COMPHDR_CPI,
};
enum udp_hdr_fields {
UDPHDR_INVALID,
UDPHDR_SPORT,
UDPHDR_DPORT,
UDPHDR_LENGTH,
UDPHDR_CSUMCOV = UDPHDR_LENGTH,
UDPHDR_CHECKSUM,
};
enum tcp_hdr_fields {
TCPHDR_INVALID,
TCPHDR_UNSPEC = TCPHDR_INVALID,
TCPHDR_SPORT,
TCPHDR_DPORT,
TCPHDR_SEQ,
TCPHDR_ACKSEQ,
TCPHDR_DOFF,
TCPHDR_RESERVED,
TCPHDR_FLAGS,
TCPHDR_WINDOW,
TCPHDR_CHECKSUM,
TCPHDR_URGPTR,
};
enum dccp_hdr_fields {
DCCPHDR_INVALID,
DCCPHDR_SPORT,
DCCPHDR_DPORT,
DCCPHDR_TYPE,
};
enum sctp_hdr_fields {
SCTPHDR_INVALID,
SCTPHDR_SPORT,
SCTPHDR_DPORT,
SCTPHDR_VTAG,
SCTPHDR_CHECKSUM,
};
enum th_hdr_fields {
THDR_INVALID,
THDR_SPORT,
THDR_DPORT,
};
extern const struct proto_desc proto_icmp;
extern const struct proto_desc proto_igmp;
extern const struct proto_desc proto_ah;
extern const struct proto_desc proto_esp;
extern const struct proto_desc proto_comp;
extern const struct proto_desc proto_udp;
extern const struct proto_desc proto_udplite;
extern const struct proto_desc proto_tcp;
extern const struct proto_desc proto_dccp;
extern const struct proto_desc proto_sctp;
extern const struct proto_desc proto_th;
extern const struct proto_desc proto_icmp6;
extern const struct proto_desc proto_ip;
extern const struct proto_desc proto_ip6;
extern const struct proto_desc proto_inet;
extern const struct proto_desc proto_inet_service;
extern const struct proto_desc proto_arp;
extern const struct proto_desc proto_vlan;
extern const struct proto_desc proto_eth;
extern const struct proto_desc proto_netdev;
extern const struct proto_desc proto_unknown;
extern const struct proto_hdr_template proto_unknown_template;
extern const struct datatype icmp_type_type;
extern const struct datatype tcp_flag_type;
extern const struct datatype dccp_pkttype_type;
extern const struct datatype arpop_type;
extern const struct datatype icmp6_type_type;
extern const struct datatype dscp_type;
extern const struct datatype ecn_type;
#endif /* NFTABLES_PROTO_H */