From fd6db06f5b12488381f1b5a3ff414ce2741cc68e Mon Sep 17 00:00:00 2001 From: Henry Stern Date: Thu, 27 Aug 2015 15:10:17 -0300 Subject: [PATCH 1/3] json io: add stubs for formatters and printers --- dnsdedupe.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++---- dnsnx.c | 16 +++-- newdomain.c | 48 +++++++++++---- 3 files changed, 206 insertions(+), 26 deletions(-) diff --git a/dnsdedupe.c b/dnsdedupe.c index bd65483..775ac33 100644 --- a/dnsdedupe.c +++ b/dnsdedupe.c @@ -33,6 +33,20 @@ static NMSG_MSGMOD_FIELD_PRINTER(dns_rdata_print); static NMSG_MSGMOD_FIELD_PRINTER(dns_message_print); static NMSG_MSGMOD_FIELD_PRINTER(time_print); +static NMSG_MSGMOD_FIELD_FORMATTER(dns_name_format); +static NMSG_MSGMOD_FIELD_FORMATTER(dns_type_format); +static NMSG_MSGMOD_FIELD_FORMATTER(dns_class_format); +static NMSG_MSGMOD_FIELD_FORMATTER(dns_rdata_format); +static NMSG_MSGMOD_FIELD_FORMATTER(dns_message_format); +static NMSG_MSGMOD_FIELD_FORMATTER(time_format); + +static NMSG_MSGMOD_FIELD_PARSER(dns_name_parse); +static NMSG_MSGMOD_FIELD_PARSER(dns_type_parse); +static NMSG_MSGMOD_FIELD_PARSER(dns_class_parse); +static NMSG_MSGMOD_FIELD_PARSER(dns_rdata_parse); +static NMSG_MSGMOD_FIELD_PARSER(dns_message_parse); +static NMSG_MSGMOD_FIELD_PARSER(time_parse); + /* Data. */ struct nmsg_msgmod_field dnsdedupe_fields[] = { @@ -47,22 +61,30 @@ struct nmsg_msgmod_field dnsdedupe_fields[] = { { .type = nmsg_msgmod_ft_uint32, .name = "time_first", - .print = time_print + .print = time_print, + .format = time_format, + .parse = time_parse }, { .type = nmsg_msgmod_ft_uint32, .name = "time_last", - .print = time_print + .print = time_print, + .format = time_format, + .parse = time_parse }, { .type = nmsg_msgmod_ft_uint32, .name = "zone_time_first", - .print = time_print + .print = time_print, + .format = time_format, + .parse = time_parse }, { .type = nmsg_msgmod_ft_uint32, .name = "zone_time_last", - .print = time_print + .print = time_print, + .format = time_format, + .parse = time_parse }, { .type = nmsg_msgmod_ft_ip, @@ -71,22 +93,30 @@ struct nmsg_msgmod_field dnsdedupe_fields[] = { { .type = nmsg_msgmod_ft_bytes, .name = "bailiwick", - .print = dns_name_print + .print = dns_name_print, + .format = dns_name_format, + .parse = dns_name_parse }, { .type = nmsg_msgmod_ft_bytes, .name = "rrname", - .print = dns_name_print + .print = dns_name_print, + .format = dns_name_format, + .parse = dns_name_parse }, { .type = nmsg_msgmod_ft_uint16, .name = "rrclass", - .print = dns_class_print + .print = dns_class_print, + .format = dns_class_format, + .parse = dns_class_parse }, { .type = nmsg_msgmod_ft_uint16, .name = "rrtype", - .print = dns_type_print + .print = dns_type_print, + .format = dns_type_format, + .parse = dns_type_parse }, { .type = nmsg_msgmod_ft_uint32, @@ -96,12 +126,16 @@ struct nmsg_msgmod_field dnsdedupe_fields[] = { .type = nmsg_msgmod_ft_bytes, .name = "rdata", .flags = NMSG_MSGMOD_FIELD_REPEATED, - .print = dns_rdata_print + .print = dns_rdata_print, + .format = dns_rdata_format, + .parse = dns_rdata_parse }, { .type = nmsg_msgmod_ft_bytes, .name = "response", - .print = dns_message_print + .print = dns_message_print, + .format = dns_message_format, + .parse = dns_message_parse }, NMSG_MSGMOD_FIELD_END }; @@ -147,6 +181,25 @@ time_print(nmsg_message_t msg, return (res); } +static nmsg_res +time_format(nmsg_message_t m, + struct nmsg_msgmod_field *field, + void *ptr, + struct nmsg_strbuf *sb, + const char *endline) { + return (nmsg_res_notimpl); +} + +static nmsg_res +time_parse(nmsg_message_t m, + struct nmsg_msgmod_field *field, + const char *value, + void **ptr, + size_t *len, + const char *endline) { + return (nmsg_res_notimpl); +} + static nmsg_res dns_name_print(nmsg_message_t msg, struct nmsg_msgmod_field *field, @@ -169,6 +222,25 @@ dns_name_print(nmsg_message_t msg, return (res); } +static nmsg_res +dns_name_format(nmsg_message_t m, + struct nmsg_msgmod_field *field, + void *ptr, + struct nmsg_strbuf *sb, + const char *endline) { + return (nmsg_res_notimpl); +} + +static nmsg_res +dns_name_parse(nmsg_message_t m, + struct nmsg_msgmod_field *field, + const char *value, + void **ptr, + size_t *len, + const char *endline) { + return (nmsg_res_notimpl); +} + static nmsg_res dns_type_print(nmsg_message_t msg, struct nmsg_msgmod_field *field, @@ -189,6 +261,25 @@ dns_type_print(nmsg_message_t msg, return (res); } +static nmsg_res +dns_type_format(nmsg_message_t m, + struct nmsg_msgmod_field *field, + void *ptr, + struct nmsg_strbuf *sb, + const char *endline) { + return (nmsg_res_notimpl); +} + +static nmsg_res +dns_type_parse(nmsg_message_t m, + struct nmsg_msgmod_field *field, + const char *value, + void **ptr, + size_t *len, + const char *endline) { + return (nmsg_res_notimpl); +} + static nmsg_res dns_class_print(nmsg_message_t msg, struct nmsg_msgmod_field *field, @@ -209,6 +300,25 @@ dns_class_print(nmsg_message_t msg, return (res); } +static nmsg_res +dns_class_format(nmsg_message_t m, + struct nmsg_msgmod_field *field, + void *ptr, + struct nmsg_strbuf *sb, + const char *endline) { + return (nmsg_res_notimpl); +} + +static nmsg_res +dns_class_parse(nmsg_message_t m, + struct nmsg_msgmod_field *field, + const char *value, + void **ptr, + size_t *len, + const char *endline) { + return (nmsg_res_notimpl); +} + static nmsg_res dns_rdata_print(nmsg_message_t msg, struct nmsg_msgmod_field *field __attribute__((unused)), @@ -247,6 +357,25 @@ dns_rdata_print(nmsg_message_t msg, return (res); } +static nmsg_res +dns_rdata_format(nmsg_message_t m, + struct nmsg_msgmod_field *field, + void *ptr, + struct nmsg_strbuf *sb, + const char *endline) { + return (nmsg_res_notimpl); +} + +static nmsg_res +dns_rdata_parse(nmsg_message_t m, + struct nmsg_msgmod_field *field, + const char *value, + void **ptr, + size_t *len, + const char *endline) { + return (nmsg_res_notimpl); +} + static nmsg_res dns_message_print(nmsg_message_t msg, struct nmsg_msgmod_field *field, @@ -281,3 +410,22 @@ dns_message_print(nmsg_message_t msg, nmsg_strbuf_append(sb, "%s: %s", field->name, endline); return (nmsg_res_success); } + +static nmsg_res +dns_message_format(nmsg_message_t m, + struct nmsg_msgmod_field *field, + void *ptr, + struct nmsg_strbuf *sb, + const char *endline) { + return (nmsg_res_notimpl); +} + +static nmsg_res +dns_message_parse(nmsg_message_t m, + struct nmsg_msgmod_field *field, + const char *value, + void **ptr, + size_t *len, + const char *endline) { + return (nmsg_res_notimpl); +} diff --git a/dnsnx.c b/dnsnx.c index 75aa523..0e520ff 100644 --- a/dnsnx.c +++ b/dnsnx.c @@ -30,17 +30,23 @@ struct nmsg_msgmod_field dnsnx_fields[] = { { .type = nmsg_msgmod_ft_bytes, .name = "qname", - .print = dns_name_print + .print = dns_name_print, + .format = dns_name_format, + .parse = dns_name_parse }, { .type = nmsg_msgmod_ft_uint16, .name = "qclass", - .print = dns_class_print + .print = dns_class_print, + .format = dns_class_format, + .parse = dns_class_parse }, { .type = nmsg_msgmod_ft_uint16, .name = "qtype", - .print = dns_type_print + .print = dns_type_print, + .format = dns_type_format, + .parse = dns_type_parse }, { .type = nmsg_msgmod_ft_ip, @@ -49,7 +55,9 @@ struct nmsg_msgmod_field dnsnx_fields[] = { { .type = nmsg_msgmod_ft_bytes, .name = "soa_rrname", - .print = dns_name_print + .print = dns_name_print, + .format = dns_name_format, + .parse = dns_name_parse }, { .type = nmsg_msgmod_ft_int64, diff --git a/newdomain.c b/newdomain.c index 83403b1..1376985 100644 --- a/newdomain.c +++ b/newdomain.c @@ -30,12 +30,16 @@ struct nmsg_msgmod_field newdomain_fields[] = { { .type = nmsg_msgmod_ft_bytes, .name = "domain", - .print = dns_name_print + .print = dns_name_print, + .format = dns_name_format, + .parse = dns_name_parse }, { .type = nmsg_msgmod_ft_uint32, .name = "time_seen", - .print = time_print + .print = time_print, + .format = time_format, + .parse = time_parse }, { .type = nmsg_msgmod_ft_enum, @@ -48,22 +52,30 @@ struct nmsg_msgmod_field newdomain_fields[] = { { .type = nmsg_msgmod_ft_uint32, .name = "time_first", - .print = time_print + .print = time_print, + .format = time_format, + .parse = time_parse }, { .type = nmsg_msgmod_ft_uint32, .name = "time_last", - .print = time_print + .print = time_print, + .format = time_format, + .parse = time_parse }, { .type = nmsg_msgmod_ft_uint32, .name = "zone_time_first", - .print = time_print + .print = time_print, + .format = time_format, + .parse = time_parse }, { .type = nmsg_msgmod_ft_uint32, .name = "zone_time_last", - .print = time_print + .print = time_print, + .format = time_format, + .parse = time_parse }, { .type = nmsg_msgmod_ft_ip, @@ -72,22 +84,30 @@ struct nmsg_msgmod_field newdomain_fields[] = { { .type = nmsg_msgmod_ft_bytes, .name = "bailiwick", - .print = dns_name_print + .print = dns_name_print, + .format = dns_name_format, + .parse = dns_name_parse }, { .type = nmsg_msgmod_ft_bytes, .name = "rrname", - .print = dns_name_print + .print = dns_name_print, + .format = dns_name_format, + .parse = dns_name_parse }, { .type = nmsg_msgmod_ft_uint16, .name = "rrclass", - .print = dns_class_print + .print = dns_class_print, + .format = dns_class_format, + .parse = dns_class_parse }, { .type = nmsg_msgmod_ft_uint16, .name = "rrtype", - .print = dns_type_print + .print = dns_type_print, + .format = dns_type_format, + .parse = dns_type_parse }, { .type = nmsg_msgmod_ft_uint32, @@ -97,12 +117,16 @@ struct nmsg_msgmod_field newdomain_fields[] = { .type = nmsg_msgmod_ft_bytes, .name = "rdata", .flags = NMSG_MSGMOD_FIELD_REPEATED, - .print = dns_rdata_print + .print = dns_rdata_print, + .format = dns_rdata_format, + .parse = dns_rdata_parse }, { .type = nmsg_msgmod_ft_bytes, .name = "response", - .print = dns_message_print + .print = dns_message_print, + .format = dns_message_format, + .parse = dns_message_parse }, { .type = nmsg_msgmod_ft_string, From a264d1724f9e3230f4578c829528e89eae0913fb Mon Sep 17 00:00:00 2001 From: Henry Stern Date: Wed, 2 Sep 2015 11:43:32 -0300 Subject: [PATCH 2/3] dnsdedupe: implement formatters and parsers --- configure.ac | 4 +- dnsdedupe.c | 223 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 209 insertions(+), 18 deletions(-) diff --git a/configure.ac b/configure.ac index f8d4e22..7609d6a 100644 --- a/configure.ac +++ b/configure.ac @@ -23,8 +23,8 @@ my_CFLAGS="-Wall \ -Wformat-security" AC_SUBST([my_CFLAGS]) -PKG_CHECK_MODULES([libnmsg], [libnmsg >= 0.9.0]) -PKG_CHECK_MODULES([libwdns], [libwdns]) +PKG_CHECK_MODULES([libnmsg], [libnmsg >= 0.10.0]) +PKG_CHECK_MODULES([libwdns], [libwdns >= 0.7.0]) PKG_CHECK_MODULES([libprotobuf_c], [libprotobuf-c >= 1.0.1]) AC_PATH_PROG([PROTOC_C], [protoc-c]) diff --git a/dnsdedupe.c b/dnsdedupe.c index 775ac33..11fa4d9 100644 --- a/dnsdedupe.c +++ b/dnsdedupe.c @@ -187,7 +187,23 @@ time_format(nmsg_message_t m, void *ptr, struct nmsg_strbuf *sb, const char *endline) { - return (nmsg_res_notimpl); + nmsg_res res = nmsg_res_failure; + time_t t; + struct tm gm; + + t = *((uint32_t *) ptr); + + if (gmtime_r(&t, &gm) != NULL) { + res = nmsg_strbuf_append(sb, "%d-%02d-%02d %02d:%02d:%02d", + 1900 + gm.tm_year, + 1 + gm.tm_mon, + gm.tm_mday, + gm.tm_hour, + gm.tm_min, + gm.tm_sec); + } + + return (res); } static nmsg_res @@ -196,8 +212,22 @@ time_parse(nmsg_message_t m, const char *value, void **ptr, size_t *len, - const char *endline) { - return (nmsg_res_notimpl); + const char *endline) +{ + time_t * t; + struct tm gm; + + if (!strptime(value, "%Y-%m-%d %T", &gm)) { + return (nmsg_res_parse_error); + } + + t = malloc(sizeof(*t)); + *t = timegm(&gm); + + *ptr = t; + *len = sizeof(*t); + + return (nmsg_res_success); } static nmsg_res @@ -227,8 +257,20 @@ dns_name_format(nmsg_message_t m, struct nmsg_msgmod_field *field, void *ptr, struct nmsg_strbuf *sb, - const char *endline) { - return (nmsg_res_notimpl); + const char *endline) +{ + ProtobufCBinaryData *rrname = ptr; + char name[WDNS_PRESLEN_NAME]; + nmsg_res res = nmsg_res_success; + + if (rrname->data != NULL && + rrname->len > 0 && + rrname->len <= WDNS_MAXLEN_NAME) + { + wdns_domain_to_str(rrname->data, rrname->len, name); + res = nmsg_strbuf_append(sb, "%s", name); + } + return (res); } static nmsg_res @@ -238,7 +280,29 @@ dns_name_parse(nmsg_message_t m, void **ptr, size_t *len, const char *endline) { - return (nmsg_res_notimpl); + + wdns_res res; + wdns_name_t *name; + + name = malloc(sizeof(*name)); + if (name == NULL) { + return (nmsg_res_memfail); + } + + res = wdns_str_to_name(value, name); + if (res != wdns_res_success) { + free (name); + return (nmsg_res_parse_error); + } + + wdns_downcase_name(name); + + *ptr = name->data; + *len = name->len; + + free(name); + + return (nmsg_res_success); } static nmsg_res @@ -267,17 +331,40 @@ dns_type_format(nmsg_message_t m, void *ptr, struct nmsg_strbuf *sb, const char *endline) { - return (nmsg_res_notimpl); + uint16_t rrtype; + const char *s; + nmsg_res res = nmsg_res_success; + + memcpy(&rrtype, ptr, sizeof(rrtype)); + s = wdns_rrtype_to_str(rrtype); + res = nmsg_strbuf_append(sb, "%s", s ? s : ""); + return (res); } static nmsg_res -dns_type_parse(nmsg_message_t m, +dns_type_parse(nmsg_message_t msg, struct nmsg_msgmod_field *field, const char *value, void **ptr, size_t *len, const char *endline) { - return (nmsg_res_notimpl); + uint16_t *rrtype; + + rrtype = malloc(sizeof(*rrtype)); + if (rrtype == NULL) { + return (nmsg_res_memfail); + } + + *rrtype = wdns_str_to_rrtype(value); + if (*rrtype == 0) { + free(rrtype); + return (nmsg_res_parse_error); + } + + *ptr = rrtype; + *len = sizeof(*rrtype); + + return (nmsg_res_success); } static nmsg_res @@ -306,7 +393,14 @@ dns_class_format(nmsg_message_t m, void *ptr, struct nmsg_strbuf *sb, const char *endline) { - return (nmsg_res_notimpl); + uint16_t rrclass; + const char *s; + nmsg_res res = nmsg_res_success; + + memcpy(&rrclass, ptr, sizeof(rrclass)); + s = wdns_rrclass_to_str(rrclass); + res = nmsg_strbuf_append(sb, "%s", s ? s : ""); + return (res); } static nmsg_res @@ -316,7 +410,24 @@ dns_class_parse(nmsg_message_t m, void **ptr, size_t *len, const char *endline) { - return (nmsg_res_notimpl); + uint16_t *rrclass; + + rrclass = malloc(sizeof(*rrclass)); + if (rrclass == NULL) { + return (nmsg_res_memfail); + } + + *rrclass = wdns_str_to_rrclass(value); + *rrclass = WDNS_CLASS_IN; + if (*rrclass == 0) { + free(rrclass); + return (nmsg_res_parse_error); + } + + *ptr = rrclass; + *len = sizeof(*rrclass); + + return (nmsg_res_success); } static nmsg_res @@ -358,12 +469,40 @@ dns_rdata_print(nmsg_message_t msg, } static nmsg_res -dns_rdata_format(nmsg_message_t m, +dns_rdata_format(nmsg_message_t msg, struct nmsg_msgmod_field *field, void *ptr, struct nmsg_strbuf *sb, const char *endline) { - return (nmsg_res_notimpl); + ProtobufCBinaryData *rdata = ptr; + nmsg_res res; + char *buf; + uint32_t *rrtype, *rrclass; + size_t len; + + res = nmsg_message_get_field(msg, "rrtype", 0, (void**) &rrtype, &len); + if (res != nmsg_res_success) { + return (nmsg_res_failure); + } + if (len != sizeof(uint32_t)) { + return (nmsg_res_failure); + } + + res = nmsg_message_get_field(msg, "rrclass", 0, (void**) &rrclass, &len); + if (res != nmsg_res_success) { + return (nmsg_res_failure); + } + if (len != sizeof(uint32_t)) { + return (nmsg_res_failure); + } + + buf = wdns_rdata_to_str(rdata->data, rdata->len, *rrtype, *rrclass); + if (buf == NULL) + return (nmsg_res_memfail); + + res = nmsg_strbuf_append(sb, "%s", buf); + free(buf); + return (res); } static nmsg_res @@ -373,7 +512,35 @@ dns_rdata_parse(nmsg_message_t m, void **ptr, size_t *len, const char *endline) { - return (nmsg_res_notimpl); + nmsg_res res; + wdns_res w_res; + uint32_t *rrtype, *rrclass; + size_t f_len; + + res = nmsg_message_get_field(m, "rrtype", 0, (void**) &rrtype, &f_len); + if (res != nmsg_res_success) { + return (nmsg_res_failure); + } + if (f_len != sizeof(uint32_t)) { + return (nmsg_res_failure); + } + + res = nmsg_message_get_field(m, "rrclass", 0, (void**) &rrclass, &f_len); + if (res != nmsg_res_success) { + return (nmsg_res_failure); + } + if (f_len != sizeof(uint32_t)) { + return (nmsg_res_failure); + } + + w_res = wdns_str_to_rdata(value, *rrtype, *rrclass, (uint8_t**)ptr, len); + if (w_res == wdns_res_parse_error) { + return (nmsg_res_parse_error); + } else if (w_res != wdns_res_success) { + return (nmsg_res_failure); + } + + return (nmsg_res_success); } static nmsg_res @@ -412,12 +579,36 @@ dns_message_print(nmsg_message_t msg, } static nmsg_res -dns_message_format(nmsg_message_t m, +dns_message_format(nmsg_message_t msg, struct nmsg_msgmod_field *field, void *ptr, struct nmsg_strbuf *sb, const char *endline) { - return (nmsg_res_notimpl); + nmsg_res res; + uint8_t *payload; + size_t payload_len; + + res = nmsg_message_get_field(msg, field->name, 0, (void **) &payload, &payload_len); + if (res == nmsg_res_success) { + wdns_message_t dns; + wdns_res wres; + + wres = wdns_parse_message(&dns, payload, payload_len); + if (wres == wdns_res_success) { + char *s; + + s = wdns_message_to_str(&dns); + if (s != NULL) { + nmsg_strbuf_append(sb, "%s", s); + free(s); + wdns_clear_message(&dns); + return (nmsg_res_success); + } + wdns_clear_message(&dns); + } + } + nmsg_strbuf_append(sb, ""); + return (nmsg_res_success); } static nmsg_res From c3d42c45eb3dfb50d771aa8282649f8d070d5cfd Mon Sep 17 00:00:00 2001 From: Henry Stern Date: Fri, 18 Sep 2015 00:04:47 -0300 Subject: [PATCH 3/3] json io: dnsdedupe don't downcase names when parsing --- configure.ac | 2 +- dnsdedupe.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 7609d6a..a10dad6 100644 --- a/configure.ac +++ b/configure.ac @@ -24,7 +24,7 @@ my_CFLAGS="-Wall \ AC_SUBST([my_CFLAGS]) PKG_CHECK_MODULES([libnmsg], [libnmsg >= 0.10.0]) -PKG_CHECK_MODULES([libwdns], [libwdns >= 0.7.0]) +PKG_CHECK_MODULES([libwdns], [libwdns >= 0.8.0]) PKG_CHECK_MODULES([libprotobuf_c], [libprotobuf-c >= 1.0.1]) AC_PATH_PROG([PROTOC_C], [protoc-c]) diff --git a/dnsdedupe.c b/dnsdedupe.c index 11fa4d9..b8f1c0a 100644 --- a/dnsdedupe.c +++ b/dnsdedupe.c @@ -289,14 +289,12 @@ dns_name_parse(nmsg_message_t m, return (nmsg_res_memfail); } - res = wdns_str_to_name(value, name); + res = wdns_str_to_name_case(value, name); if (res != wdns_res_success) { free (name); return (nmsg_res_parse_error); } - wdns_downcase_name(name); - *ptr = name->data; *len = name->len;