From b19f3a5e7f4c1748dbd2ffcf738c65c937721408 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 23 Mar 2022 13:14:38 +1030 Subject: [PATCH] devtools/decodemsg: don't require --onion for onion tlvs, fail if unknown tlvname. Generate a table, let decodemsg sort it out. Do more up-front work in argparsing too. Signed-off-by: Rusty Russell --- devtools/decodemsg.c | 68 +++++++++++++++++++++------------ tools/gen/print_header_template | 8 ++++ tools/gen/print_impl_template | 12 ++---- 3 files changed, 56 insertions(+), 32 deletions(-) diff --git a/devtools/decodemsg.c b/devtools/decodemsg.c index 1824c7f7e..b1e7205ad 100644 --- a/devtools/decodemsg.c +++ b/devtools/decodemsg.c @@ -11,20 +11,46 @@ #include #endif +static char *opt_set_tlvname(const char *arg, + bool (**printwire)(const char *fieldname, + const u8 **cursor, + size_t *plen)) +{ + for (size_t i = 0; tlvs_printpeer_wire_byname[i].name; i++) { + if (streq(arg, tlvs_printpeer_wire_byname[i].name)) { + *printwire = tlvs_printpeer_wire_byname[i].print; + return NULL; + } + } + + for (size_t i = 0; tlvs_printonion_wire_byname[i].name; i++) { + if (streq(arg, tlvs_printonion_wire_byname[i].name)) { + *printwire = tlvs_printonion_wire_byname[i].print; + return NULL; + } + } + return "Unknown tlv name"; +} + +static char *opt_set_onionprint(bool (**printwire)(const u8 *msg)) +{ + *printwire = printonion_wire_message; + return NULL; +} + int main(int argc, char *argv[]) { const u8 *m; - bool onion = false; - char *tlv_name = NULL; + bool (*printtlv)(const char *fieldname, const u8 **cursor, size_t *plen) = NULL; + bool (*printwire)(const u8 *msg) = printpeer_wire_message; bool ok = true; setup_locale(); - opt_register_noarg("--onion", opt_set_bool, &onion, + opt_register_noarg("--onion", opt_set_onionprint, &printwire, "Decode an error message instead of a peer message"); - opt_register_arg("--tlv", opt_set_charp, opt_show_charp, - &tlv_name, - "Deocde a TLV of this type instead of a peer message"); + opt_register_arg("--tlv", opt_set_tlvname, NULL, &printtlv, + "Decode a TLV of this type instead of a peer message"); opt_register_noarg("--help|-h", opt_usage_and_exit, "[]" "Decode a lightning spec wire message from hex, or a series of messages from stdin", @@ -40,15 +66,12 @@ int main(int argc, char *argv[]) if (!m) errx(1, "'%s' is not valid hex", argv[1]); - if (onion) - if (tlv_name) - ok &= printonion_wire_tlv_message(tlv_name, m); - else - ok &= printonion_wire_message(m); - else if (tlv_name) - ok &= printpeer_wire_tlv_message(tlv_name, m); - else - ok &= printpeer_wire_message(m); + if (printtlv) { + size_t len = tal_bytelen(m); + ok &= printtlv("", &m, &len); + } else { + ok &= printwire(m); + } } else { u8 *f = grab_fd(NULL, STDIN_FILENO); size_t off = 0; @@ -69,15 +92,12 @@ int main(int argc, char *argv[]) break; } m = tal_dup_arr(f, u8, f + off, be16_to_cpu(len), 0); - if (onion) - if (tlv_name) - ok &= printonion_wire_tlv_message(tlv_name, m); - else - ok &= printonion_wire_message(m); - else if (tlv_name) - ok &= printpeer_wire_tlv_message(tlv_name, m); - else - ok &= printpeer_wire_message(m); + if (printtlv) { + size_t len = tal_bytelen(m); + ok &= printtlv("", &m, &len); + } else { + ok &= printwire(m); + } off += be16_to_cpu(len); tal_free(m); } diff --git a/tools/gen/print_header_template b/tools/gen/print_header_template index ba09bc127..4b2f87a26 100644 --- a/tools/gen/print_header_template +++ b/tools/gen/print_header_template @@ -27,4 +27,12 @@ bool printwire_${tlv.name}(const char *fieldname, const u8 **cursor, size_t *ple bool printwire_${subtype.name}(const char *fieldname, const u8 **cursor, size_t *plen); % endfor % endif + +/* NULL-terminated map of TLV names -> print functions */ +struct tlv_print${options.enum_name}_byname { + const char *name; + bool (*print)(const char *fieldname, const u8 **cursor, size_t *plen); +}; +extern const struct tlv_print${options.enum_name}_byname tlvs_print${options.enum_name}_byname[]; + #endif /* LIGHTNING_${idem} */ diff --git a/tools/gen/print_impl_template b/tools/gen/print_impl_template index b4ad9d930..3da32dd53 100644 --- a/tools/gen/print_impl_template +++ b/tools/gen/print_impl_template @@ -126,13 +126,9 @@ bool printwire_${tlv.name}(const char *fieldname, const u8 **cursor, size_t *ple } % endfor -% if bool(tlvs): -bool print${options.enum_name}_tlv_message(const char *tlv_name, const u8 *msg) { - size_t len = tal_count(msg); +const struct tlv_print${options.enum_name}_byname tlvs_print${options.enum_name}_byname[] = { % for tlv in tlvs.values(): - if (strcmp(tlv_name, "${tlv.name}") == 0) - return printwire_${tlv.name}(tlv_name, &msg, &len); + { "${tlv.name}", printwire_${tlv.name} }, % endfor - return false; -} -% endif + { NULL, NULL } +};