[netsniff-ng] Re: [PATCH v2 11/16] trafgen: parser: Add syntax to generate ARP header fields
On 2016-01-26 at 09:47:32 +0100, Vadim Kochanwrote: > On Tue, Jan 26, 2016 at 10:25 AM, Tobias Klauser wrote: > > On 2016-01-26 at 00:11:53 +0100, Vadim Kochan wrote: > >> Add syntax to generate ARP header fields: > >> > >> { arp(op=req, sip=1.1.1.1, smac=11:22:33:44:55:66) } > >> { arp() } > >> > >> Signed-off-by: Vadim Kochan > >> --- > >> > >> %% > >> > >> @@ -107,7 +109,16 @@ mac > >> ({mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}) > >> "saddr"|"sa" { return K_SADDR; } > >> "prot"[o]? { return K_PROT; } > >> > > > > Shouldn't we allow to specify htype, ptype, hlen and plen as well (as a > > user might want to set non-conforming values)? > > > Well meanwhile it was easier to implement for me the Ethernet-IPv4 > form of ARP (which is more generic and > used by masezahn too if I am not mistaken), and it looks a little > tricky to allow full-flexible ARP header crafting. > I'd like to add such ability on later work, if I will not dig into > mac80211 headers ... :-) Ok, I see :-) But htpye/ptype should still be possible without having dynamic header length, no? > >> +"sha"|"smac" { return K_SHA; } > >> +"spa"|"sip" { return K_SPA; } > >> +"tha"|"tmac" { return K_THA; } > >> +"tpa"|"tip" { return K_TPA; } > >> +"req"{ return K_REQ; } > > > > Please add "request" as well. > > > Sure. > > >> ; > >> > >> +arp_proto > >> + : arp '(' arp_param_list ')' { } > >> + ; > >> + > >> +arp_param_list > >> + : { } > >> + | arp_field { } > >> + | arp_field delimiter arp_param_list { } > >> + ; > >> + > >> +arp_field > >> + : K_OPER skip_white '=' skip_white K_REQ > >> + { proto_field_set_be16(hdr, ARP_OPER, ARPOP_REQUEST); } > >> + | K_OPER skip_white '=' skip_white K_RESP > >> + { proto_field_set_be16(hdr, ARP_OPER, ARPOP_REPLY); } > > > > Would be nice to allow numeric values here as well (again, to be able to > > specify values not conforming to the standard). > > > > Right I will change it to the form: > > arp(request, ...) > arp(reply, ...) > arp(op=) Looks good. > Not sure if the following is also will be needed considering above's forms: > > arp(op=request) I'd keep it in for consistency reasons. -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] Synchronize file creation between netsniff-ng processes possible?
Hi everyone! I've googled a bit but not found any good answer to my question. Maybe you can help me out? Currently I'm running five netsniff processes capturing data from five different interfaces. It works really well with the limiting factor SSD write speed, not netsniff itself. To make post processing easier, it would be nice if all log files were the same size and each set of files had the same start time. It seems like netsniff only checks file size / time when a packet is received so the start time within a set of files drift more or less depending on the busload. Any ideas on how to synchronize the processes? Best regards Erik -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] Re: [PATCH v2 15/16] trafgen: parser: Add syntax to build UDP header
On 2016-01-26 at 00:11:57 +0100, Vadim Kochanwrote: > Added trafgen syntax to set UDP header fields: > > { udp(sport=111, dport=222) } > > Signed-off-by: Vadim Kochan > --- > trafgen_lexer.l | 4 > trafgen_parser.y | 29 + > 2 files changed, 33 insertions(+) > > diff --git a/trafgen_lexer.l b/trafgen_lexer.l > index 26876b4..98afc91 100644 > --- a/trafgen_lexer.l > +++ b/trafgen_lexer.l > @@ -131,9 +131,13 @@ ip_addr ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+) > "df" { return K_DF; } > "mf" { return K_MF; } > > +"sp"|"sport" { return K_SPORT; } > +"dp"|"dport" { return K_DPORT; } What about the length and checksum fields? -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] Re: [PATCH v2 11/16] trafgen: parser: Add syntax to generate ARP header fields
On Tue, Jan 26, 2016 at 10:25 AM, Tobias Klauserwrote: > On 2016-01-26 at 00:11:53 +0100, Vadim Kochan wrote: >> Add syntax to generate ARP header fields: >> >> { arp(op=req, sip=1.1.1.1, smac=11:22:33:44:55:66) } >> { arp() } >> >> Signed-off-by: Vadim Kochan >> --- >> >> %% >> >> @@ -107,7 +109,16 @@ mac >> ({mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}) >> "saddr"|"sa" { return K_SADDR; } >> "prot"[o]? { return K_PROT; } >> > > Shouldn't we allow to specify htype, ptype, hlen and plen as well (as a > user might want to set non-conforming values)? > Well meanwhile it was easier to implement for me the Ethernet-IPv4 form of ARP (which is more generic and used by masezahn too if I am not mistaken), and it looks a little tricky to allow full-flexible ARP header crafting. I'd like to add such ability on later work, if I will not dig into mac80211 headers ... :-) >> +"sha"|"smac" { return K_SHA; } >> +"spa"|"sip" { return K_SPA; } >> +"tha"|"tmac" { return K_THA; } >> +"tpa"|"tip" { return K_TPA; } >> +"req"{ return K_REQ; } > > Please add "request" as well. > Sure. >> ; >> >> +arp_proto >> + : arp '(' arp_param_list ')' { } >> + ; >> + >> +arp_param_list >> + : { } >> + | arp_field { } >> + | arp_field delimiter arp_param_list { } >> + ; >> + >> +arp_field >> + : K_OPER skip_white '=' skip_white K_REQ >> + { proto_field_set_be16(hdr, ARP_OPER, ARPOP_REQUEST); } >> + | K_OPER skip_white '=' skip_white K_RESP >> + { proto_field_set_be16(hdr, ARP_OPER, ARPOP_REPLY); } > > Would be nice to allow numeric values here as well (again, to be able to > specify values not conforming to the standard). > Right I will change it to the form: arp(request, ...) arp(reply, ...) arp(op=) Not sure if the following is also will be needed considering above's forms: arp(op=request) >> -- >> 2.6.3 >> -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] Re: [PATCH v2 03/16] trafgen: Add basic proto generation logic
On 2016-01-26 at 00:11:45 +0100, Vadim Kochanwrote: [...] > +void proto_header_init(enum proto_id pid) > +{ > + struct proto_hdr *hdr = proto_header_by_id(pid); > + struct proto_hdr *new; > + > + if (headers_count >= PROTO_MAX_LAYERS) > + panic("Too much proto headers\n"); > + > + new = malloc(sizeof(*new)); Use xmalloc here, as we would otherwise dereference NULL. -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] [PATCH v3 08/16] trafgen: parser: Add syntax to generate Ethernet header
Add syntax for generating Ethernet header fields like: { eth(prot=0x0800, da=11:22:33:44:55:66), fill(0xff, 60) } { eth(prot=0x0800) } { eth() } It is important that proto_init is called before fields will be filled to initialize the specified proto with header fields. Signed-off-by: Vadim Kochan--- trafgen_lexer.l | 15 +++ trafgen_parser.y | 57 +++- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/trafgen_lexer.l b/trafgen_lexer.l index 6c27b0c..ac4fec1 100644 --- a/trafgen_lexer.l +++ b/trafgen_lexer.l @@ -19,6 +19,7 @@ #include "trafgen_parser.tab.h" #include "xmalloc.h" #include "built_in.h" +#include "str.h" extern void yyerror(const char *); @@ -75,6 +76,9 @@ number_bin([0]?[b][0-1]+) number_dec (([0])|([1-9][0-9]*)) number_ascii ([a-zA-Z]) +mac_hex([a-fA-F0-9]+) +mac({mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}) + %% "cpu" { return K_CPU; } @@ -99,6 +103,12 @@ number_ascii([a-zA-Z]) "const32"|"c32"{ return K_CONST32; } "const64"|"c64"{ return K_CONST64; } +"daddr"|"da" { return K_DADDR; } +"saddr"|"sa" { return K_SADDR; } +"prot"[o]? { return K_PROT; } + +"eth" { return K_ETH; } + [ ]*"-"[ ]*{ return '-'; } [ ]*"+"[ ]*{ return '+'; } [ ]*"*"[ ]*{ return '*'; } @@ -117,6 +127,7 @@ number_ascii([a-zA-Z]) "]"{ return ']'; } ","{ return ','; } ":"{ return ':'; } +"="{ return '='; } "\n" { yylineno++; } @@ -146,6 +157,10 @@ number_ascii ([a-zA-Z]) {number_ascii} { yylval.number = (uint8_t) (*yytext); return number; } +{mac} { if (str2mac(yytext, yylval.bytes)) + panic("Failed to parse MAC addres %s\n", yytext); + return mac; } + "'\\x"[a-fA-F0-9]{2}"'" { yylval.number = strtol(yytext + 3, NULL, 16); return number; } diff --git a/trafgen_parser.y b/trafgen_parser.y index 4725f7c..df1b1a6 100644 --- a/trafgen_parser.y +++ b/trafgen_parser.y @@ -21,6 +21,8 @@ #include "xmalloc.h" #include "trafgen_parser.tab.h" #include "trafgen_conf.h" +#include "trafgen_proto.h" +#include "trafgen_l2.h" #include "built_in.h" #include "die.h" #include "str.h" @@ -59,6 +61,8 @@ extern size_t dlen; static int our_cpu, min_cpu = -1, max_cpu = -1; +static struct proto_hdr *hdr; + static inline int test_ignore(void) { if (min_cpu < 0 && max_cpu < 0) @@ -324,22 +328,33 @@ static void set_dynamic_incdec(uint8_t start, uint8_t stop, uint8_t stepping, __setup_new_counter(>cnt[packetdc_last], start, stop, stepping, type); } +static void proto_add(enum proto_id pid) +{ + proto_header_init(pid); + hdr = proto_current_header(); +} + %} %union { long long int number; + uint8_t bytes[256]; char *str; } %token K_COMMENT K_FILL K_RND K_SEQINC K_SEQDEC K_DRND K_DINC K_DDEC K_WHITE %token K_CPU K_CSUMIP K_CSUMUDP K_CSUMTCP K_CSUMUDP6 K_CSUMTCP6 K_CONST8 K_CONST16 K_CONST32 K_CONST64 +%token K_DADDR K_SADDR K_PROT +%token K_ETH + %token ',' '{' '}' '(' ')' '[' ']' ':' '-' '+' '*' '/' '%' '&' '|' '<' '>' '^' -%token number string +%token number string mac %type number expression %type string +%type mac %left '-' '+' '*' '/' '%' '&' '|' '<' '>' '^' @@ -372,9 +387,16 @@ noenforce_white | delimiter_nowhite { } ; +skip_white + : { } + | K_WHITE { } + ; packet : '{' noenforce_white payload noenforce_white '}' { min_cpu = max_cpu = -1; + + proto_packet_finish(); + realloc_packet(); } | K_CPU '(' number cpu_delim number ')' ':' noenforce_white '{' noenforce_white payload noenforce_white '}' { @@ -388,10 +410,15 @@ packet max_cpu = tmp; } + proto_packet_finish(); + realloc_packet(); } | K_CPU '(' number ')' ':' noenforce_white '{' noenforce_white payload noenforce_white '}' { min_cpu = max_cpu = $3; + + proto_packet_finish(); + realloc_packet(); } ; @@ -422,6 +449,7 @@ elem | ddec { } | csum { } | const { } + | proto { proto_header_finish(hdr); } | inline_comment { } ; @@ -536,6 +564,33 @@ ddec { set_dynamic_incdec($3, $5, $7, TYPE_DEC); } ; +proto + : eth_proto { } + ; + +eth_proto + : eth '(' eth_param_list ')' { } + ; + +eth + : K_ETH { proto_add(PROTO_ETH); } + ; + +eth_param_list + : { } + | eth_field { } + | eth_field delimiter eth_param_list { } +
[netsniff-ng] [PATCH v3 07/16] str: Add str2mac helper function
Add func for convert string to MAC address. Signed-off-by: Vadim Kochan--- str.c | 25 + str.h | 1 + 2 files changed, 26 insertions(+) diff --git a/str.c b/str.c index e4d8722..a3421b0 100644 --- a/str.c +++ b/str.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "str.h" #include "die.h" @@ -129,3 +130,27 @@ void argv_free(char **argv) free(tmp); } + +int str2mac(const char *str, uint8_t *mac) +{ + int i, count; + unsigned int tmp[6]; + + if (!str) + return -1; + + count = sscanf(str, "%02X:%02X:%02X:%02X:%02X:%02X", + [0], [1], [2], [3], [4], [5]); + + if (count != 6) + count = sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + [0], [1], [2], [3], [4], [5]); + + if (count != 6) + return -1; + + for (i = 0; i < 6; i++) + mac[i] = (uint8_t)tmp[i]; + + return 0; +} diff --git a/str.h b/str.h index 3ffb2b9..21051ad 100644 --- a/str.h +++ b/str.h @@ -11,5 +11,6 @@ extern noinline void *xmemset(void *s, int c, size_t n); extern char *argv2str(int startind, int argc, char **argv); extern char **argv_insert(char **argv, size_t *count, const char *str); extern void argv_free(char **argv); +extern int str2mac(const char *str, uint8_t *mac); #endif /* STR_H */ -- 2.6.3 -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] [PATCH v3 11/16] trafgen: parser: Add syntax to generate ARP header fields
Add syntax to generate ARP header fields: { arp(op=req, sip=1.1.1.1, smac=11:22:33:44:55:66) } { arp() } Signed-off-by: Vadim Kochan--- trafgen_lexer.l | 17 + trafgen_parser.y | 48 +++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/trafgen_lexer.l b/trafgen_lexer.l index ac4fec1..7db0d5a 100644 --- a/trafgen_lexer.l +++ b/trafgen_lexer.l @@ -15,6 +15,7 @@ #include #include #include +#include #include "trafgen_parser.tab.h" #include "xmalloc.h" @@ -78,6 +79,7 @@ number_ascii ([a-zA-Z]) mac_hex([a-fA-F0-9]+) mac({mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}) +ip_addr([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+) %% @@ -107,7 +109,18 @@ mac ({mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}) "saddr"|"sa" { return K_SADDR; } "prot"[o]? { return K_PROT; } +"sha"|"smac" { return K_SHA; } +"spa"|"sip"{ return K_SPA; } +"tha"|"tmac" { return K_THA; } +"tpa"|"tip"{ return K_TPA; } +"req"|"request"{ return K_REQUEST; } +"reply"{ return K_REPLY; } +"op"|"oper"{ return K_OPER; } +"htype"{ return K_HTYPE; } +"ptype"{ return K_PTYPE; } + "eth" { return K_ETH; } +"arp" { return K_ARP; } [ ]*"-"[ ]*{ return '-'; } [ ]*"+"[ ]*{ return '+'; } @@ -161,6 +174,10 @@ mac ({mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}:{mac_hex}) panic("Failed to parse MAC addres %s\n", yytext); return mac; } +{ip_addr} { if (inet_pton(AF_INET, yytext, _addr) != 1) + panic("Failed to parse IPv4 address %s\n", yytext); + return ip_addr; }; + "'\\x"[a-fA-F0-9]{2}"'" { yylval.number = strtol(yytext + 3, NULL, 16); return number; } diff --git a/trafgen_parser.y b/trafgen_parser.y index df1b1a6..16f9025 100644 --- a/trafgen_parser.y +++ b/trafgen_parser.y @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include "xmalloc.h" #include "trafgen_parser.tab.h" @@ -337,6 +339,7 @@ static void proto_add(enum proto_id pid) %} %union { + struct in_addr ip_addr; long long int number; uint8_t bytes[256]; char *str; @@ -346,15 +349,19 @@ static void proto_add(enum proto_id pid) %token K_CPU K_CSUMIP K_CSUMUDP K_CSUMTCP K_CSUMUDP6 K_CSUMTCP6 K_CONST8 K_CONST16 K_CONST32 K_CONST64 %token K_DADDR K_SADDR K_PROT +%token K_OPER K_SHA K_SPA K_THA K_TPA K_REQUEST K_REPLY K_PTYPE K_HTYPE + %token K_ETH +%token K_ARP %token ',' '{' '}' '(' ')' '[' ']' ':' '-' '+' '*' '/' '%' '&' '|' '<' '>' '^' -%token number string mac +%token number string mac ip_addr %type number expression %type string %type mac +%type ip_addr %left '-' '+' '*' '/' '%' '&' '|' '<' '>' '^' @@ -566,6 +573,7 @@ ddec proto : eth_proto { } + | arp_proto { } ; eth_proto @@ -591,6 +599,44 @@ eth_field { proto_field_set_be16(hdr, ETH_PROTO_ID, $5); } ; +arp_proto + : arp '(' arp_param_list ')' { } + ; + +arp_param_list + : { } + | arp_field { } + | arp_field delimiter arp_param_list { } + ; + +arp_field + : K_OPER skip_white '=' skip_white K_REQUEST + { proto_field_set_be16(hdr, ARP_OPER, ARPOP_REQUEST); } + | K_OPER skip_white '=' skip_white K_REPLY + { proto_field_set_be16(hdr, ARP_OPER, ARPOP_REPLY); } + | K_OPER skip_white '=' skip_white number + { proto_field_set_be16(hdr, ARP_OPER, $5); } + | K_REQUEST + { proto_field_set_be16(hdr, ARP_OPER, ARPOP_REQUEST); } + | K_REPLY + { proto_field_set_be16(hdr, ARP_OPER, ARPOP_REPLY); } + | K_HTYPE skip_white '=' skip_white number + { proto_field_set_be16(hdr, ARP_HTYPE, $5); } + | K_PTYPE skip_white '=' skip_white number + { proto_field_set_be16(hdr, ARP_PTYPE, $5); } + | K_SHA skip_white '=' skip_white mac + { proto_field_set_bytes(hdr, ARP_SHA, $5); } + | K_THA skip_white '=' skip_white mac + { proto_field_set_bytes(hdr, ARP_THA, $5); } + | K_SPA skip_white '=' skip_white ip_addr + { proto_field_set_u32(hdr, ARP_SPA, $5.s_addr); } + | K_TPA skip_white '=' skip_white ip_addr + { proto_field_set_u32(hdr, ARP_TPA, $5.s_addr); } + ; +arp + : K_ARP { proto_add(PROTO_ARP); } + ; + %% static void finalize_packet(void) -- 2.6.3 -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] [PATCH v3 05/16] trafgen: proto: Add func for set device mac to field
Add helper function for easy set device's MAC address to proto field which may be used by Ethernet & ARP protos generation. Signed-off-by: Vadim Kochan--- trafgen_proto.c | 31 +++ trafgen_proto.h | 3 +++ 2 files changed, 34 insertions(+) diff --git a/trafgen_proto.c b/trafgen_proto.c index fce2441..bb03a9d 100644 --- a/trafgen_proto.c +++ b/trafgen_proto.c @@ -5,7 +5,9 @@ #include #include +#include +#include "dev.h" #include "xmalloc.h" #include "trafgen_conf.h" #include "trafgen_proto.h" @@ -295,6 +297,35 @@ void proto_field_set_default_be32(struct proto_hdr *hdr, uint32_t fid, uint32_t __proto_field_set_bytes(hdr, fid, (uint8_t *), true, true); } +static void __proto_field_set_dev_mac(struct proto_hdr *hdr, uint32_t fid, + bool is_default) +{ + uint8_t mac[ETH_ALEN]; + int ret; + + if (proto_field_is_set(hdr, fid)) + return; + + if (!hdr->ctx->dev) + panic("Device is not specified\n"); + + ret = device_hw_address(hdr->ctx->dev, mac); + if (ret < 0) + panic("Could not get device hw adress\n"); + + __proto_field_set_bytes(hdr, fid, mac, is_default, false); +} + +void proto_field_set_dev_mac(struct proto_hdr *hdr, uint32_t fid) +{ + __proto_field_set_dev_mac(hdr, fid, false); +} + +void proto_field_set_default_dev_mac(struct proto_hdr *hdr, uint32_t fid) +{ + __proto_field_set_dev_mac(hdr, fid, true); +} + void protos_init(char *dev) { struct proto_hdr *p; diff --git a/trafgen_proto.h b/trafgen_proto.h index c727b61..4041c27 100644 --- a/trafgen_proto.h +++ b/trafgen_proto.h @@ -93,4 +93,7 @@ extern void proto_field_set_default_be16(struct proto_hdr *hdr, uint32_t fid, extern void proto_field_set_default_be32(struct proto_hdr *hdr, uint32_t fid, uint32_t val); +extern void proto_field_set_dev_mac(struct proto_hdr *hdr, uint32_t fid); +extern void proto_field_set_default_dev_mac(struct proto_hdr *hdr, uint32_t fid); + #endif /* TRAFGEN_PROTO_I_H */ -- 2.6.3 -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] [PATCH v3 04/16] dev: Add func to get device's hw address
Add device_hw_address func to get device's MAC address. Signed-off-by: Vadim Kochan--- dev.c | 23 +++ dev.h | 1 + 2 files changed, 24 insertions(+) diff --git a/dev.c b/dev.c index cf8d643..ad7b917 100644 --- a/dev.c +++ b/dev.c @@ -124,6 +124,29 @@ int device_address(const char *ifname, int af, struct sockaddr_storage *ss) return ret; } +int device_hw_address(const char *ifname, uint8_t *addr) +{ + int ret, sock; + struct ifreq ifr; + + if (unlikely(!addr)) + return -EINVAL; + if (!strncmp("any", ifname, strlen("any"))) + return -EINVAL; + + sock = af_socket(AF_INET); + + memset(, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + + ret = ioctl(sock, SIOCGIFHWADDR, ); + if (likely(!ret)) + memcpy(addr, _hwaddr.sa_data[0], IFHWADDRLEN); + + close(sock); + return ret; +} + size_t device_mtu(const char *ifname) { size_t mtu = 0; diff --git a/dev.h b/dev.h index a9e4ccf..077e08f 100644 --- a/dev.h +++ b/dev.h @@ -7,6 +7,7 @@ extern size_t device_mtu(const char *ifname); extern int device_address(const char *ifname, int af, struct sockaddr_storage *ss); extern int __device_ifindex(const char *ifname); +extern int device_hw_address(const char *ifname, uint8_t *addr); extern int device_ifindex(const char *ifname); extern int device_type(const char *ifname); extern short device_get_flags(const char *ifname); -- 2.6.3 -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] [PATCH v3 06/16] trafgen: l2: Add Ethernet proto header generation
Add trafgen_l2.c module for generating L2 related headers. Add Ethernet header generating. By default source MAC address is used from the specified output device. Signed-off-by: Vadim Kochan--- trafgen/Makefile | 1 + trafgen_l2.c | 32 trafgen_l2.h | 12 trafgen_proto.c | 3 +++ 4 files changed, 48 insertions(+) create mode 100644 trafgen_l2.c create mode 100644 trafgen_l2.h diff --git a/trafgen/Makefile b/trafgen/Makefile index 2ea684f..1c95118 100644 --- a/trafgen/Makefile +++ b/trafgen/Makefile @@ -20,6 +20,7 @@ trafgen-objs =xmalloc.o \ sysctl.o \ cpp.o \ trafgen_proto.o \ + trafgen_l2.o \ trafgen_lexer.yy.o \ trafgen_parser.tab.o \ trafgen.o diff --git a/trafgen_l2.c b/trafgen_l2.c new file mode 100644 index 000..1082049 --- /dev/null +++ b/trafgen_l2.c @@ -0,0 +1,32 @@ +/* + * netsniff-ng - the packet sniffing beast + * Subject to the GPL, version 2. + */ + +#include "built_in.h" +#include "trafgen_l2.h" +#include "trafgen_proto.h" + +struct proto_field eth_fields[] = { + { .id = ETH_DST_ADDR, .len = 6, }, + { .id = ETH_SRC_ADDR, .len = 6, .offset = 6 }, + { .id = ETH_PROTO_ID, .len = 2, .offset = 12 }, +}; + +static void eth_header_init(struct proto_hdr *hdr) +{ + proto_header_fields_add(hdr, eth_fields, array_size(eth_fields)); + + proto_field_set_default_dev_mac(hdr, ETH_SRC_ADDR); +} + +static struct proto_hdr eth_hdr = { + .id = PROTO_ETH, + .layer = PROTO_L2, + .header_init= eth_header_init, +}; + +void protos_l2_init(void) +{ + proto_header_register(_hdr); +} diff --git a/trafgen_l2.h b/trafgen_l2.h new file mode 100644 index 000..75d3d33 --- /dev/null +++ b/trafgen_l2.h @@ -0,0 +1,12 @@ +#ifndef TRAFGEN_L2_I_H +#define TRAFGEN_L2_I_H + +enum eth_field { + ETH_DST_ADDR, + ETH_SRC_ADDR, + ETH_PROTO_ID, +}; + +extern void protos_l2_init(void); + +#endif /* TRAFGEN_L2_I_H */ diff --git a/trafgen_proto.c b/trafgen_proto.c index bb03a9d..c374213 100644 --- a/trafgen_proto.c +++ b/trafgen_proto.c @@ -10,6 +10,7 @@ #include "dev.h" #include "xmalloc.h" #include "trafgen_conf.h" +#include "trafgen_l2.h" #include "trafgen_proto.h" #define field_shift_and_mask(f, v) (((v) << (f)->shift) & \ @@ -332,6 +333,8 @@ void protos_init(char *dev) ctx.dev = dev; + protos_l2_init(); + for (p = registered; p; p = p->next) p->ctx = } -- 2.6.3 -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] [PATCH v3 03/16] trafgen: Add basic proto generation logic
Add new trafgen_proto.c module with basic proto header fields generation logic. Each proto must implement proto_hdr struct and register it to the global proto list. Proto header consist from set of fields, and each field must be described via proto_field struct by specifying unique id, len, offset (relative to the header). Small fields ( < 8 bits) can be described via left shift & mask. Few callbacks are invoked to perform special actions to build the header: 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 such things like total len, checksum. Proto generation API provides easy proto field setters/getters to easy craft the packet via parser. Signed-off-by: Vadim Kochan--- trafgen.c| 3 + trafgen/Makefile | 1 + trafgen_proto.c | 332 +++ trafgen_proto.h | 96 4 files changed, 432 insertions(+) create mode 100644 trafgen_proto.c create mode 100644 trafgen_proto.h diff --git a/trafgen.c b/trafgen.c index c74a973..949f909 100644 --- a/trafgen.c +++ b/trafgen.c @@ -54,6 +54,7 @@ #include "timer.h" #include "ring_tx.h" #include "csum.h" +#include "trafgen_proto.h" #ifndef timeval_to_timespec #define timeval_to_timespec(tv, ts) { \ @@ -1215,6 +1216,8 @@ int main(int argc, char **argv) register_signal(SIGTERM, signal_handler); register_signal(SIGHUP, signal_handler); + protos_init(ctx.device); + if (prio_high) { set_proc_prio(-20); set_sched_status(SCHED_FIFO, sched_get_priority_max(SCHED_FIFO)); diff --git a/trafgen/Makefile b/trafgen/Makefile index bc256b2..2ea684f 100644 --- a/trafgen/Makefile +++ b/trafgen/Makefile @@ -19,6 +19,7 @@ trafgen-objs =xmalloc.o \ timer.o \ sysctl.o \ cpp.o \ + trafgen_proto.o \ trafgen_lexer.yy.o \ trafgen_parser.tab.o \ trafgen.o diff --git a/trafgen_proto.c b/trafgen_proto.c new file mode 100644 index 000..fce2441 --- /dev/null +++ b/trafgen_proto.c @@ -0,0 +1,332 @@ +/* + * netsniff-ng - the packet sniffing beast + * Subject to the GPL, version 2. + */ + +#include +#include + +#include "xmalloc.h" +#include "trafgen_conf.h" +#include "trafgen_proto.h" + +#define field_shift_and_mask(f, v) (((v) << (f)->shift) & \ + ((f)->mask ? (f)->mask : (0x))) + +#define field_unmask_and_unshift(f, v) (((v) & \ + ((f)->mask ? (f)->mask : (0x))) >> (f)->shift) + +static struct proto_ctx ctx; + +#define PROTO_MAX_LAYERS 16 + +static struct proto_hdr *headers[PROTO_MAX_LAYERS]; +static uint32_t headers_count; + +static struct proto_hdr *registered; + +struct proto_hdr *proto_current_header(void) +{ + if (headers_count > 0) + return headers[headers_count - 1]; + + panic("No header was added\n"); +} + +struct proto_hdr *proto_lower_header(struct proto_hdr *hdr) +{ + struct proto_hdr *lower = NULL; + uint32_t i; + + if (headers_count == 0) + return NULL; + + for (i = 1, lower = headers[0]; i < headers_count; i++) { + if (headers[i] == hdr) + return headers[i - 1]; + } + + return lower; +} + +uint8_t *proto_header_ptr(struct proto_hdr *hdr) +{ + return _packet()->payload[hdr->pkt_offset]; +} + +static struct proto_hdr *proto_header_by_id(enum proto_id id) +{ + struct proto_hdr *p = registered; + + for (; p; p = p->next) + if (p->id == id) + return p; + + panic("Can't lookup proto by id %u\n", id); +} + +void proto_header_register(struct proto_hdr *hdr) +{ + hdr->next = registered; + registered = hdr; + + hdr->fields = NULL; + hdr->fields_count = 0; +} + +static void proto_fields_realloc(struct proto_hdr *hdr, size_t count) +{ + hdr->fields = xrealloc(hdr->fields, count * sizeof(*hdr->fields)); + hdr->fields_count = count; +} + +void proto_header_fields_add(struct proto_hdr *hdr, struct proto_field *fields, +size_t count) +{ + struct packet *pkt = current_packet(); + struct proto_field *f; + int i; + + if (!hdr->fields) + hdr->pkt_offset = pkt->len; + + proto_fields_realloc(hdr, hdr->fields_count + count); + + for (i = 0; count >= 1; count--, i++) { + f = >fields[hdr->fields_count - count]; + + f->id = fields[i].id; + f->len = fields[i].len; + f->is_set = false; + f->shift = fields[i].shift; + f->mask =
[netsniff-ng] [PATCH v3 14/16] trafgen: l4: Add UDP header generation logic
Add trafgen_l4.c module with implementation of UDP header fields gneration. UDP proto generation logic automaticaly sets by default IPPROTO_UDP to the lower proto if it is IPv4, also cscum is calculated if it is not set by user. Signed-off-by: Vadim Kochan--- trafgen/Makefile | 1 + trafgen_l4.c | 71 trafgen_l4.h | 14 +++ trafgen_proto.c | 2 ++ 4 files changed, 88 insertions(+) create mode 100644 trafgen_l4.c create mode 100644 trafgen_l4.h diff --git a/trafgen/Makefile b/trafgen/Makefile index 4f342ca..3f78f07 100644 --- a/trafgen/Makefile +++ b/trafgen/Makefile @@ -22,6 +22,7 @@ trafgen-objs =xmalloc.o \ trafgen_proto.o \ trafgen_l2.o \ trafgen_l3.o \ + trafgen_l4.o \ trafgen_lexer.yy.o \ trafgen_parser.tab.o \ trafgen.o diff --git a/trafgen_l4.c b/trafgen_l4.c new file mode 100644 index 000..286e54a --- /dev/null +++ b/trafgen_l4.c @@ -0,0 +1,71 @@ +/* + * netsniff-ng - the packet sniffing beast + * Subject to the GPL, version 2. + */ + +#include +#include + +#include "die.h" +#include "csum.h" +#include "built_in.h" +#include "trafgen_l3.h" +#include "trafgen_l4.h" +#include "trafgen_conf.h" +#include "trafgen_proto.h" + +static struct proto_field udp_fields[] = { + { .id = UDP_SPORT, .len = 2, .offset = 0 }, + { .id = UDP_DPORT, .len = 2, .offset = 2 }, + { .id = UDP_LEN,.len = 2, .offset = 4 }, + { .id = UDP_CSUM, .len = 2, .offset = 6 }, +}; + +static void udp_header_init(struct proto_hdr *hdr) +{ + struct proto_hdr *lower; + + proto_lower_default_add(PROTO_IP4); + + lower = proto_current_header(); + + if (lower->id == PROTO_IP4) + proto_field_set_default_u8(lower, IP4_PROTO, IPPROTO_UDP); + + proto_header_fields_add(hdr, udp_fields, array_size(udp_fields)); +} + +static void udp_packet_finish(struct proto_hdr *hdr) +{ + struct proto_hdr *lower = proto_lower_header(hdr); + struct packet *pkt = current_packet(); + uint16_t total_len; + uint16_t csum; + + total_len = pkt->len - hdr->pkt_offset; + proto_field_set_default_be16(hdr, UDP_LEN, total_len); + + if (proto_field_is_set(hdr, UDP_CSUM)) + return; + + if (!lower || lower->id != PROTO_IP4) + return; + + total_len = proto_field_get_u16(hdr, UDP_LEN); + csum = p4_csum((void *) proto_header_ptr(lower), proto_header_ptr(hdr), + total_len, IPPROTO_UDP); + + proto_field_set_be16(hdr, UDP_CSUM, bswap_16(csum)); +} + +static struct proto_hdr udp_hdr = { + .id = PROTO_UDP, + .layer = PROTO_L4, + .header_init= udp_header_init, + .packet_finish = udp_packet_finish, +}; + +void protos_l4_init(void) +{ + proto_header_register(_hdr); +} diff --git a/trafgen_l4.h b/trafgen_l4.h new file mode 100644 index 000..1a60ea5 --- /dev/null +++ b/trafgen_l4.h @@ -0,0 +1,14 @@ +#ifndef TRAFGEN_L4_I_H +#define TRAFGEN_L4_I_H + +enum udp_field { + UDP_SPORT, + UDP_DPORT, + UDP_LEN, + UDP_CSUM, +}; + +extern void protos_l4_init(void); + +#endif /* TRAFGEN_L4_I_H */ + diff --git a/trafgen_proto.c b/trafgen_proto.c index 3599721..0712411 100644 --- a/trafgen_proto.c +++ b/trafgen_proto.c @@ -13,6 +13,7 @@ #include "trafgen_conf.h" #include "trafgen_l2.h" #include "trafgen_l3.h" +#include "trafgen_l4.h" #include "trafgen_proto.h" #define field_shift_and_mask(f, v) (((v) << (f)->shift) & \ @@ -368,6 +369,7 @@ void protos_init(char *dev) protos_l2_init(); protos_l3_init(); + protos_l4_init(); for (p = registered; p; p = p->next) p->ctx = -- 2.6.3 -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] [PATCH v3 15/16] trafgen: parser: Add syntax to build UDP header
Added trafgen syntax to set UDP header fields: { udp(sport=111, dport=222) } Signed-off-by: Vadim Kochan--- trafgen_lexer.l | 4 trafgen_parser.y | 29 + 2 files changed, 33 insertions(+) diff --git a/trafgen_lexer.l b/trafgen_lexer.l index e6007f7..f040a83 100644 --- a/trafgen_lexer.l +++ b/trafgen_lexer.l @@ -133,9 +133,13 @@ ip_addr([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+) "df" { return K_DF; } "mf" { return K_MF; } +"sp"|"sport" { return K_SPORT; } +"dp"|"dport" { return K_DPORT; } + "eth" { return K_ETH; } "arp" { return K_ARP; } "ip4"|"ipv4" { return K_IP4; } +"udp" { return K_UDP; } [ ]*"-"[ ]*{ return '-'; } [ ]*"+"[ ]*{ return '+'; } diff --git a/trafgen_parser.y b/trafgen_parser.y index ebc4054..9ec09b1 100644 --- a/trafgen_parser.y +++ b/trafgen_parser.y @@ -26,6 +26,7 @@ #include "trafgen_proto.h" #include "trafgen_l2.h" #include "trafgen_l3.h" +#include "trafgen_l4.h" #include "built_in.h" #include "die.h" #include "str.h" @@ -352,10 +353,12 @@ static void proto_add(enum proto_id pid) %token K_DADDR K_SADDR K_PROT %token K_OPER K_SHA K_SPA K_THA K_TPA K_REQUEST K_REPLY K_PTYPE K_HTYPE %token K_TTL K_DSCP K_ECN K_TOS K_LEN K_ID K_FLAGS K_FRAG K_IHL K_VER K_CSUM K_DF K_MF +%token K_SPORT K_DPORT %token K_ETH %token K_ARP %token K_IP4 +%token K_UDP %token ',' '{' '}' '(' ')' '[' ']' ':' '-' '+' '*' '/' '%' '&' '|' '<' '>' '^' @@ -578,6 +581,7 @@ proto : eth_proto { } | arp_proto { } | ip4_proto { } + | udp_proto { } ; eth_proto @@ -688,6 +692,31 @@ ip4 : K_IP4 { proto_add(PROTO_IP4); } ; +udp_proto + : udp '(' udp_param_list ')' { } + ; + +udp_param_list + : { } + | udp_field { } + | udp_field delimiter udp_param_list { } + ; + +udp_field + : K_SPORT skip_white '=' skip_white number + { proto_field_set_be16(hdr, UDP_SPORT, $5); } + | K_DPORT skip_white '=' skip_white number + { proto_field_set_be16(hdr, UDP_DPORT, $5); } + | K_LEN skip_white '=' skip_white number + { proto_field_set_be16(hdr, UDP_LEN, $5); } + | K_CSUM skip_white '=' skip_white number + { proto_field_set_be16(hdr, UDP_CSUM, $5); } + ; + +udp + : K_UDP { proto_add(PROTO_UDP); } + ; + %% static void finalize_packet(void) -- 2.6.3 -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] [PATCH v3 16/16] trafgen: man: Add help for Ethernet, ARP, IPv4, UDP headers
Add description (basic syntax, proto header fields) for newer added proto headers: Ethernet, ARP, IPv4, UDP. Signed-off-by: Vadim Kochan--- trafgen.8 | 186 ++ 1 file changed, 186 insertions(+) diff --git a/trafgen.8 b/trafgen.8 index ce82a5b..58d08e0 100644 --- a/trafgen.8 +++ b/trafgen.8 @@ -271,6 +271,192 @@ configuration, e.g. const16(0xaa) will result in ''00 aa''. Within c*() functions, it is possible to do some arithmetics: -,+,*,/,%,&,|,<<,>>,^ E.g. const161<<8)+0x32)|0b110)*2) will be evaluated to ''02 6c''. .PP +IV) Proto header functions, fill protocol header with specified parameters. +The protocol header follows the generic syntax: +.in +8 +.sp +(=,=,...,,...) +.sp +.in -8 +.in +4 +If parameter is not specified then the default value will be used (usually 0). +Proto parameters might be set in any order, the offset of each parameter is strictly +defined. +.sp +All required lower layer headers will be filled automatically in case if they +were not specified by the user. The headers will be filled in the order as they +were specified. Each header will be filled with some mimimum required set of fields. +.in -4 +.sp +.in +4 +Supported proto headers: +.sp + +.in +4 +.I Ethernet +: +.B eth(da=, sa=, prot[o]=) +.sp +.in +15 +.B da|daddr +- set destination MAC address (default 00:00:00:00:00:00). +.sp +.B sa|saddr +- set source MAC address (default device's MAC address). +.sp +.B prot|proto +- set Ethernet type/proro number (default 0). +.in -15 +.in -4 + +.in +4 +.I ARP +: +.B arp(htype=, ptype=, op= , req, reply, +.B smac=, sip=, tmac=, tip=) +.sp +.in +15 +.B htype +- set ARP HW type (default Ethernet). +.sp +.B ptype +- set ARP proto type (default IPv4). +.sp +.B op +- set ARP operation type (request/reply) (default request). +.sp +.B req|request +- set ARP Request operation type. +.sp +.B reply +- set ARP Reply operation type. +.sp +.B smac|sha +- set sender HW (MAC) address (default device's MAC address). +.sp +.B sip|spa +- set sender proto (IPv4) address (default device's IPv4 address). +.sp +.B tmac|tha +- set target HW (MAC) address (default 00:00:00:00:00:00). +.sp +.B tip|tpa +- set target proto (IPv4) address (default device's IPv4 address). +.in -15 +.sp +.in +4 +By default ARP Announcement request packet is filled, Ethernet destination MAC +set to broadcast. +.in -4 +.in -4 + +.in +4 +.I IPv4 +: +.B ip4|ipv4(ihl=, ver=, len=, csum=, +.B ttl=, tos=, dscp=, ecn=, +.in +15 +.B id=, flags=, frag=, df, mf, da=, sa=, +.B prot[o]=) +.in -15 +.sp +.in +15 +.B ver|version +- set version field (default 4). +.sp +.B ihl +- set header length in the numbers of 4 bytes (default 5). +.sp +.B tos +- set TOS (Type Of Service) field (default 0). +.sp +.B dscp +- set DSCP (DiffServ) field (default 0). +.sp +.B ecn +- set ECN field (default 0). +.sp +.B len|length +- set total length of header and data (calculated by default). +.sp +.B id +- set IPv4 datagram identificator (default 0). +.sp +.B flags +- set IPv4 flags value (DF,MF) (default 0). +.sp +.B df +- set DF (dont fragment) flag (default 0). +.sp +.B mf +- set MF (more fragment) flag (default 0). +.sp +.B frag +- set fragment offset field in numbers of 8 bytes (default 0). +.sp +.B ttl +- set TTL (time to live) field (default 0). +.sp +.B csum +- set header checksum field (calculated by default). +.sp +.B sa|saddr +- set source IPv4 address (default device's IPv4 address). +.sp +.B da|daddr +- set destination IPv4 address (default 0.0.0.0). +.sp +.B prot|proto +- set IPv4 proro number (default 0). +.in -15 +.sp +.in +4 +By default if lower header is Ethernet - ether type is set to IPv4, +if lower header is IPv4 - proto is set to value 0x4 (IP-in-IP). +.in -4 +.in -4 + +.in +4 +.I UDP +: +.B udp(sp=, dp=, len=, csum=) +.sp +.in +15 +.B sp|sport +- set source UDP port (default 0). +.sp +.B dp|dport +- set destination UDP port (default 0). +.sp +.B len|length +- set length field of UDP header and data (calculated by default). +.sp +.B csum +- set checksum field calculated on IPv4 pseudo header (calculated by default). +.sp +.in -15 +.in +4 +By default if lower header is IPv4 - proto is set to UDP. +.in -4 +.in -4 + +Example of UDP Echo packet: +.sp +.in +4 +{ +.in +4 +eth(da=11:22:33:44:55:66), +.sp +udp(dp=7), +.sp +"Hello world" +.in -4 +} +.in -4 + +.in -4 + +.PP Furthermore, there are two types of comments in trafgen configuration files: .PP 1. Multi-line C-style comments:/* put comment here */ -- 2.6.3 -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] [PATCH v3 10/16] trafgen: l2: Add ARP header generation logic
Add ARP proto header fields generation via src mac, src ip, dst mac, dst ip & operaion. By default Ethernet proto will be initialized, and ARP Announcement request is filled. Signed-off-by: Vadim Kochan--- trafgen_l2.c | 52 trafgen_l2.h | 12 2 files changed, 64 insertions(+) diff --git a/trafgen_l2.c b/trafgen_l2.c index 1082049..a95ba91 100644 --- a/trafgen_l2.c +++ b/trafgen_l2.c @@ -3,10 +3,15 @@ * Subject to the GPL, version 2. */ +#include +#include + #include "built_in.h" #include "trafgen_l2.h" #include "trafgen_proto.h" +#define ETH_BCAST { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } + struct proto_field eth_fields[] = { { .id = ETH_DST_ADDR, .len = 6, }, { .id = ETH_SRC_ADDR, .len = 6, .offset = 6 }, @@ -26,7 +31,54 @@ static struct proto_hdr eth_hdr = { .header_init= eth_header_init, }; +static struct proto_field arp_fields[] = { + { .id = ARP_HTYPE, .len = 2 }, + { .id = ARP_PTYPE, .len = 2, .offset = 2 }, + { .id = ARP_HLEN, .len = 1, .offset = 4 }, + { .id = ARP_PLEN, .len = 1, .offset = 5 }, + { .id = ARP_OPER, .len = 2, .offset = 6 }, + { .id = ARP_SHA, .len = 6, .offset = 8 }, + { .id = ARP_SPA, .len = 4, .offset = 14 }, + { .id = ARP_THA, .len = 6, .offset = 18 }, + { .id = ARP_TPA, .len = 4, .offset = 24 }, +}; + +static void arp_header_init(struct proto_hdr *hdr) +{ + struct proto_hdr *lower; + + proto_lower_default_add(PROTO_ETH); + + lower = proto_current_header(); + + if (lower->id == PROTO_ETH) { + uint8_t bcast[6] = ETH_BCAST; + + proto_field_set_default_bytes(lower, ETH_DST_ADDR, bcast); + proto_field_set_default_be16(lower, ETH_PROTO_ID, ETH_P_ARP); + } + + proto_header_fields_add(hdr, arp_fields, array_size(arp_fields)); + + /* Generate Announce request by default */ + proto_field_set_default_be16(hdr, ARP_HTYPE, ARPHRD_ETHER); + proto_field_set_default_be16(hdr, ARP_PTYPE, ETH_P_IP); + proto_field_set_default_u8(hdr, ARP_HLEN, 6); + proto_field_set_default_u8(hdr, ARP_PLEN, 4); + proto_field_set_default_be16(hdr, ARP_OPER, ARPOP_REQUEST); + proto_field_set_default_dev_mac(hdr, ARP_SHA); + proto_field_set_default_dev_ipv4(hdr, ARP_SPA); + proto_field_set_default_dev_ipv4(hdr, ARP_TPA); +} + +static struct proto_hdr arp_hdr = { + .id = PROTO_ARP, + .layer = PROTO_L2, + .header_init= arp_header_init, +}; + void protos_l2_init(void) { proto_header_register(_hdr); + proto_header_register(_hdr); } diff --git a/trafgen_l2.h b/trafgen_l2.h index 75d3d33..63cef2f 100644 --- a/trafgen_l2.h +++ b/trafgen_l2.h @@ -7,6 +7,18 @@ enum eth_field { ETH_PROTO_ID, }; +enum arp_field { + ARP_HTYPE, + ARP_PTYPE, + ARP_HLEN, + ARP_PLEN, + ARP_OPER, + ARP_SHA, + ARP_SPA, + ARP_THA, + ARP_TPA, +}; + extern void protos_l2_init(void); #endif /* TRAFGEN_L2_I_H */ -- 2.6.3 -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] [PATCH v3 01/16] trafgen: Export set_fill func
Make public set_fill func to be used by proto generation code. Signed-off-by: Vadim Kochan--- trafgen_conf.h | 2 ++ trafgen_parser.y | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/trafgen_conf.h b/trafgen_conf.h index b171798..887fa3d 100644 --- a/trafgen_conf.h +++ b/trafgen_conf.h @@ -60,4 +60,6 @@ extern void compile_packets(char *file, bool verbose, unsigned int cpu, bool invoke_cpp, char *const cpp_argv[]); extern void cleanup_packets(void); +extern void set_fill(uint8_t val, size_t len); + #endif /* TRAFGEN_CONF */ diff --git a/trafgen_parser.y b/trafgen_parser.y index 79a8439..49ee577 100644 --- a/trafgen_parser.y +++ b/trafgen_parser.y @@ -157,7 +157,7 @@ static void set_multi_byte(uint8_t *s, size_t len) set_byte(s[i]); } -static void set_fill(uint8_t val, size_t len) +void set_fill(uint8_t val, size_t len) { size_t i; struct packet *pkt = [packet_last]; -- 2.6.3 -- You received this message because you are subscribed to the Google Groups "netsniff-ng" group. To unsubscribe from this group and stop receiving emails from it, send an email to netsniff-ng+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[netsniff-ng] [PATCH v3 12/16] trafgen: l3: Add IPv4 header generation backend
Add L3 module for implement L3 layer protos generation. Implemented generating of IPv4 header with all fields except options. By default IPv4 address of output device is used as src ip address. On finish (after packet is specified) - total len & checksum is calculated. Meanwhile Ethernet proto is initialized as default underlying proto. Signed-off-by: Vadim Kochan--- trafgen/Makefile | 1 + trafgen_l3.c | 82 trafgen_l3.h | 26 ++ trafgen_proto.c | 2 ++ 4 files changed, 111 insertions(+) create mode 100644 trafgen_l3.c create mode 100644 trafgen_l3.h diff --git a/trafgen/Makefile b/trafgen/Makefile index 1c95118..4f342ca 100644 --- a/trafgen/Makefile +++ b/trafgen/Makefile @@ -21,6 +21,7 @@ trafgen-objs =xmalloc.o \ cpp.o \ trafgen_proto.o \ trafgen_l2.o \ + trafgen_l3.o \ trafgen_lexer.yy.o \ trafgen_parser.tab.o \ trafgen.o diff --git a/trafgen_l3.c b/trafgen_l3.c new file mode 100644 index 000..dd45395 --- /dev/null +++ b/trafgen_l3.c @@ -0,0 +1,82 @@ +/* + * netsniff-ng - the packet sniffing beast + * Subject to the GPL, version 2. + */ + +#include + +#include "csum.h" +#include "built_in.h" +#include "trafgen_l2.h" +#include "trafgen_l3.h" +#include "trafgen_proto.h" +#include "trafgen_conf.h" + +static struct proto_field ipv4_fields[] = { + { .id = IP4_VER, .len = 1, .offset = 0, .shift = 4, .mask = 0xf0 }, + { .id = IP4_IHL, .len = 1, .offset = 0, .shift = 0, .mask = 0x0f }, + { .id = IP4_DSCP, .len = 1, .offset = 1, .shift = 2, .mask = 0xfc }, + { .id = IP4_ECN, .len = 1, .offset = 1, .shift = 0, .mask = 0x03 }, + { .id = IP4_TOS, .len = 1, .offset = 1 }, + { .id = IP4_LEN, .len = 2, .offset = 2 }, + { .id = IP4_ID,.len = 2, .offset = 4 }, + { .id = IP4_FLAGS, .len = 2, .offset = 6, .shift = 13, .mask = 0xe000 }, + { .id = IP4_MF,.len = 2, .offset = 6, .shift = 13, .mask = 0x2000 }, + { .id = IP4_DF,.len = 2, .offset = 6, .shift = 14, .mask = 0x4000 }, + { .id = IP4_FRAG_OFFS, .len = 2, .offset = 6, .shift = 0, .mask = 0x1fff }, + { .id = IP4_TTL, .len = 1, .offset = 8 }, + { .id = IP4_PROTO, .len = 1, .offset = 9 }, + { .id = IP4_CSUM, .len = 2, .offset = 10 }, + { .id = IP4_SADDR, .len = 4, .offset = 12 }, + { .id = IP4_DADDR, .len = 4, .offset = 16 }, +}; + +static void ipv4_header_init(struct proto_hdr *hdr) +{ + struct proto_hdr *lower; + + proto_lower_default_add(PROTO_ETH); + + lower = proto_current_header(); + + if (lower->id == PROTO_ETH) + proto_field_set_default_be16(lower, ETH_PROTO_ID, ETH_P_IP); + else if (lower->id == PROTO_IP4) + proto_field_set_default_u8(lower, IP4_PROTO, IPPROTO_IPIP); + + proto_header_fields_add(hdr, ipv4_fields, array_size(ipv4_fields)); + + proto_field_set_default_u8(hdr, IP4_VER, 4); + proto_field_set_default_u8(hdr, IP4_IHL, 5); + proto_field_set_default_dev_ipv4(hdr, IP4_SADDR); +} + +static void ipv4_packet_finish(struct proto_hdr *hdr) +{ + struct packet *pkt = current_packet(); + uint16_t total_len; + + total_len = pkt->len - hdr->pkt_offset; + proto_field_set_default_be16(hdr, IP4_LEN, total_len); + + if (!proto_field_is_set(hdr, IP4_CSUM)) { + uint16_t csum; + uint8_t ihl; + + ihl = proto_field_get_u8(hdr, IP4_IHL); + csum = htons(calc_csum(>payload[hdr->pkt_offset], ihl * 4)); + proto_field_set_u16(hdr, IP4_CSUM, bswap_16(csum)); + } +} + +static struct proto_hdr ipv4_hdr = { + .id = PROTO_IP4, + .layer = PROTO_L3, + .header_init= ipv4_header_init, + .packet_finish = ipv4_packet_finish, +}; + +void protos_l3_init(void) +{ + proto_header_register(_hdr); +} diff --git a/trafgen_l3.h b/trafgen_l3.h new file mode 100644 index 000..d215d09 --- /dev/null +++ b/trafgen_l3.h @@ -0,0 +1,26 @@ +#ifndef TRAFGEN_L3_I_H +#define TRAFGEN_L3_I_H + +enum ip4_field { + IP4_VER, + IP4_IHL, + IP4_DSCP, + IP4_ECN, + IP4_TOS, + IP4_LEN, + IP4_ID, + IP4_FLAGS, + IP4_FRAG_OFFS, + IP4_TTL, + IP4_PROTO, + IP4_CSUM, + IP4_SADDR, + IP4_DADDR, + IP4_DF, + IP4_MF, +}; + +extern void protos_l3_init(void); + +#endif /* TRAFGEN_L2_I_H */ + diff --git a/trafgen_proto.c b/trafgen_proto.c index 58538ff..3599721 100644 --- a/trafgen_proto.c +++ b/trafgen_proto.c @@ -12,6 +12,7 @@ #include "xmalloc.h" #include "trafgen_conf.h" #include "trafgen_l2.h" +#include "trafgen_l3.h" #include "trafgen_proto.h" #define