1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * nl-list-caches.c	List registered cache types
4  *
5  *	This library is free software; you can redistribute it and/or
6  *	modify it under the terms of the GNU Lesser General Public
7  *	License as published by the Free Software Foundation version 2.1
8  *	of the License.
9  *
10  * Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
11  */
12 
13 #include <netlink-private/netlink.h>
14 #include <netlink/cli/utils.h>
15 
print_usage(void)16 static void print_usage(void)
17 {
18 	fprintf(stderr, "Usage: nl-list-caches\n");
19 	exit(1);
20 }
21 
id_attr_list(struct nl_object_ops * ops,char * buf,size_t len)22 static char *id_attr_list(struct nl_object_ops *ops, char *buf, size_t len)
23 {
24 	if (ops->oo_attrs2str != NULL)
25 		return ops->oo_attrs2str(ops->oo_id_attrs, buf, len);
26 	else {
27 		memset(buf, 0, len);
28 		return buf;
29 	}
30 }
31 
print(struct nl_cache_ops * ops,void * arg)32 static void print(struct nl_cache_ops *ops, void *arg)
33 {
34 	char buf[64];
35 
36 	printf("%s:\n" \
37 	       "    hdrsize: %d bytes\n" \
38 	       "    protocol: %s\n" \
39 	       "    request-update: %s\n" \
40 	       "    msg-parser: %s\n",
41 	       ops->co_name, ops->co_hdrsize,
42 	       nl_nlfamily2str(ops->co_protocol, buf, sizeof(buf)),
43 	       ops->co_request_update ? "yes" : "no",
44 	       ops->co_msg_parser ? "yes" : "no");
45 
46 	if (ops->co_obj_ops) {
47 		struct nl_object_ops *obj_ops = ops->co_obj_ops;
48 		const char *dump_names[NL_DUMP_MAX+1] = {
49 			"brief",
50 			"detailed",
51 			"stats",
52 		};
53 		int i;
54 
55 		printf("    cacheable object:\n" \
56 		       "        name: %s:\n" \
57 		       "        size: %zu bytes\n" \
58 		       "        constructor: %s\n" \
59 		       "        free-data: %s\n" \
60 		       "        clone: %s\n" \
61 		       "        compare: %s\n" \
62 		       "        id attributes: %s\n" \
63 		       "        dump: ",
64 		       obj_ops->oo_name, obj_ops->oo_size,
65 		       obj_ops->oo_constructor ? "yes" : "no",
66 		       obj_ops->oo_free_data ? "yes" : "no",
67 		       obj_ops->oo_clone ? "yes" : "no",
68 		       obj_ops->oo_compare ? "yes" : "no",
69 		       id_attr_list(obj_ops, buf, sizeof(buf)));
70 
71 		for (i = 0; i <= NL_DUMP_MAX; i++)
72 			if (obj_ops->oo_dump[i])
73 				printf("%s%s",
74 				i == 0 ? "" : ", ",
75 				dump_names[i]);
76 
77 		printf("\n");
78 	}
79 
80 	if (ops->co_genl) {
81 		struct genl_ops *genl_ops = ops->co_genl;
82 
83 		printf("    genl:\n" \
84 		       "        name: %s\n" \
85 		       "        user-hdr: %d\n" \
86 		       "        id: %d\n",
87 		       genl_ops->o_name, genl_ops->o_hdrsize, genl_ops->o_id);
88 
89 		if (genl_ops->o_ncmds) {
90 			int i;
91 
92 			printf("        cmds:\n");
93 
94 			for (i = 0; i < genl_ops->o_ncmds; i++) {
95 				struct genl_cmd *cmd = &genl_ops->o_cmds[i];
96 
97 				printf("            %s:\n"
98 				       "                id: %d\n" \
99 				       "                maxattr: %d\n" \
100 				       "                msg-parser: %s\n" \
101 				       "                attr-policy: %s\n",
102 				       cmd->c_name, cmd->c_id, cmd->c_maxattr,
103 				       cmd->c_msg_parser ? "yes" : "no",
104 				       cmd->c_attr_policy ? "yes" : "no");
105 			}
106 		}
107 	}
108 }
109 
main(int argc,char * argv[])110 int main(int argc, char *argv[])
111 {
112 	if (argc > 1 && !strcasecmp(argv[1], "-h"))
113 		print_usage();
114 
115 	nl_cache_ops_foreach(print, NULL);
116 
117 	return 0;
118 }
119