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 <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2022-03-23 13:14:38 +10:30
parent 7147fea2ff
commit b19f3a5e7f
3 changed files with 56 additions and 32 deletions

View File

@@ -11,20 +11,46 @@
#include <wire/peer_printgen.h> #include <wire/peer_printgen.h>
#endif #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[]) int main(int argc, char *argv[])
{ {
const u8 *m; const u8 *m;
bool onion = false; bool (*printtlv)(const char *fieldname, const u8 **cursor, size_t *plen) = NULL;
char *tlv_name = NULL; bool (*printwire)(const u8 *msg) = printpeer_wire_message;
bool ok = true; bool ok = true;
setup_locale(); 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"); "Decode an error message instead of a peer message");
opt_register_arg("--tlv", opt_set_charp, opt_show_charp, opt_register_arg("--tlv", opt_set_tlvname, NULL, &printtlv,
&tlv_name, "Decode a TLV of this type instead of a peer message");
"Deocde a TLV of this type instead of a peer message");
opt_register_noarg("--help|-h", opt_usage_and_exit, opt_register_noarg("--help|-h", opt_usage_and_exit,
"[<hexmsg>]" "[<hexmsg>]"
"Decode a lightning spec wire message from hex, or a series of messages from stdin", "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) if (!m)
errx(1, "'%s' is not valid hex", argv[1]); errx(1, "'%s' is not valid hex", argv[1]);
if (onion) if (printtlv) {
if (tlv_name) size_t len = tal_bytelen(m);
ok &= printonion_wire_tlv_message(tlv_name, m); ok &= printtlv("", &m, &len);
else } else {
ok &= printonion_wire_message(m); ok &= printwire(m);
else if (tlv_name) }
ok &= printpeer_wire_tlv_message(tlv_name, m);
else
ok &= printpeer_wire_message(m);
} else { } else {
u8 *f = grab_fd(NULL, STDIN_FILENO); u8 *f = grab_fd(NULL, STDIN_FILENO);
size_t off = 0; size_t off = 0;
@@ -69,15 +92,12 @@ int main(int argc, char *argv[])
break; break;
} }
m = tal_dup_arr(f, u8, f + off, be16_to_cpu(len), 0); m = tal_dup_arr(f, u8, f + off, be16_to_cpu(len), 0);
if (onion) if (printtlv) {
if (tlv_name) size_t len = tal_bytelen(m);
ok &= printonion_wire_tlv_message(tlv_name, m); ok &= printtlv("", &m, &len);
else } else {
ok &= printonion_wire_message(m); ok &= printwire(m);
else if (tlv_name) }
ok &= printpeer_wire_tlv_message(tlv_name, m);
else
ok &= printpeer_wire_message(m);
off += be16_to_cpu(len); off += be16_to_cpu(len);
tal_free(m); tal_free(m);
} }

View File

@@ -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); bool printwire_${subtype.name}(const char *fieldname, const u8 **cursor, size_t *plen);
% endfor % endfor
% endif % 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} */ #endif /* LIGHTNING_${idem} */

View File

@@ -126,13 +126,9 @@ bool printwire_${tlv.name}(const char *fieldname, const u8 **cursor, size_t *ple
} }
% endfor % endfor
% if bool(tlvs): const struct tlv_print${options.enum_name}_byname tlvs_print${options.enum_name}_byname[] = {
bool print${options.enum_name}_tlv_message(const char *tlv_name, const u8 *msg) {
size_t len = tal_count(msg);
% for tlv in tlvs.values(): % for tlv in tlvs.values():
if (strcmp(tlv_name, "${tlv.name}") == 0) { "${tlv.name}", printwire_${tlv.name} },
return printwire_${tlv.name}(tlv_name, &msg, &len);
% endfor % endfor
return false; { NULL, NULL }
} };
% endif