diff options
author | Vadim Kochan <vadim4j@gmail.com> | 2016-01-26 22:24:59 +0200 |
---|---|---|
committer | Tobias Klauser <tklauser@distanz.ch> | 2016-01-28 16:04:39 +0100 |
commit | e476a36e65cd8508c6473a19e497fb04487e2214 (patch) | |
tree | fda95e71b99c875684d84e103ee5e510e1a5016f /trafgen_proto.h | |
parent | bc412cb595d8a06ae47ffc90602a25ecbde81e0d (diff) |
trafgen: Add basic protocol generation logic
Add new trafgen_proto.c module with basic protocol header fields
generation logic. This will allow to support protocol specific keywords
in the trafgen configuration language.
Each protocol must implement struct proto_hdr and register it to the
global proto list.
Protocol headers consist of a set of fields, and each field must be
described via struct proto_field by specifying unique id, length and
offset (relative to the header start). Fields smaller than 8 bits can be
described via left shift & mask.
The following callbacks are invoked to perform special actions to build
the header during parsing:
1) header_init - required fields must be added to the packet and
initialized with default values.
2) header_finish - it is invoked when header is specified, all user
specified fields are set.
3) packet_finish - callback is invoked from upper to lower header
to calculate fields depending on upper layers such as total
length or checksum.
The protocol generation API provides convenience protocol field
setters/getters to to be used in the parser while crafting the packet.
Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
[tk: wordsmithing on commit message, minor variable type changes]
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Diffstat (limited to 'trafgen_proto.h')
-rw-r--r-- | trafgen_proto.h | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/trafgen_proto.h b/trafgen_proto.h new file mode 100644 index 0000000..8f1f201 --- /dev/null +++ b/trafgen_proto.h @@ -0,0 +1,97 @@ +#ifndef TRAFGEN_PROTO_I_H +#define TRAFGEN_PROTO_I_H + +#include <stddef.h> +#include <stdint.h> +#include <stdbool.h> + +struct proto_ctx { + const char *dev; +}; + +enum proto_id { + PROTO_NONE, + PROTO_ETH, + PROTO_ARP, + PROTO_IP4, + PROTO_IP6, + PROTO_UDP, + PROTO_TCP, +}; + +enum proto_layer { + PROTO_L0, /* invalid layer */ + PROTO_L2, + PROTO_L3, + PROTO_L4, +}; + +struct proto_field { + uint32_t id; + size_t len; + uint32_t shift; + uint32_t mask; + uint16_t offset; + + bool is_set; + uint16_t pkt_offset; +}; + +struct proto_hdr { + enum proto_id id; + enum proto_layer layer; + + struct proto_hdr *next; + struct proto_ctx *ctx; + uint16_t pkt_offset; + struct proto_field *fields; + size_t fields_count; + + void (*header_init)(struct proto_hdr *hdr); + void (*header_finish)(struct proto_hdr *hdr); + void (*packet_finish)(struct proto_hdr *hdr); +}; + +extern void protos_init(const char *dev); +extern void proto_header_register(struct proto_hdr *hdr); + +extern void proto_header_init(enum proto_id pid); +extern void proto_header_finish(struct proto_hdr *hdr); +extern void proto_packet_finish(void); +extern void proto_lower_default_add(enum proto_id pid); + +extern struct proto_hdr *proto_current_header(void); +extern struct proto_hdr *proto_lower_header(struct proto_hdr *hdr); +extern uint8_t *proto_header_ptr(struct proto_hdr *hdr); + +extern void proto_header_fields_add(struct proto_hdr *hdr, + struct proto_field *fields, size_t count); + +extern bool proto_field_is_set(struct proto_hdr *hdr, uint32_t fid); +extern void proto_field_set_bytes(struct proto_hdr *hdr, uint32_t fid, + uint8_t *bytes); +extern void proto_field_set_u8(struct proto_hdr *hdr, uint32_t fid, uint8_t val); +extern uint8_t proto_field_get_u8(struct proto_hdr *hdr, uint32_t fid); +extern void proto_field_set_u16(struct proto_hdr *hdr, uint32_t fid, uint16_t val); +extern uint16_t proto_field_get_u16(struct proto_hdr *hdr, uint32_t fid); +extern void proto_field_set_u32(struct proto_hdr *hdr, uint32_t fid, uint32_t val); +extern uint32_t proto_field_get_u32(struct proto_hdr *hdr, uint32_t fid); + +extern void proto_field_set_default_bytes(struct proto_hdr *hdr, uint32_t fid, + uint8_t *bytes); +extern void proto_field_set_default_u8(struct proto_hdr *hdr, uint32_t fid, + uint8_t val); +extern void proto_field_set_default_u16(struct proto_hdr *hdr, uint32_t fid, + uint16_t val); +extern void proto_field_set_default_u32(struct proto_hdr *hdr, uint32_t fid, + uint32_t val); + +extern void proto_field_set_be16(struct proto_hdr *hdr, uint32_t fid, uint16_t val); +extern void proto_field_set_be32(struct proto_hdr *hdr, uint32_t fid, uint32_t val); + +extern void proto_field_set_default_be16(struct proto_hdr *hdr, uint32_t fid, + uint16_t val); +extern void proto_field_set_default_be32(struct proto_hdr *hdr, uint32_t fid, + uint32_t val); + +#endif /* TRAFGEN_PROTO_I_H */ |