link librt if needed for shm_open
[project/libubox.git] / udebug.h
1 /*
2 * udebug - debug ring buffer library
3 *
4 * Copyright (C) 2023 Felix Fietkau <nbd@nbd.name>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 #ifndef __UDEBUG_RINGBUF_H
19 #define __UDEBUG_RINGBUF_H
20
21 #include <sys/types.h>
22 #include <stdint.h>
23 #include <stdarg.h>
24
25 #include "list.h"
26 #include "uloop.h"
27 #include "avl.h"
28
29 #define UDEBUG_SOCK_NAME "/var/run/udebug.sock"
30
31 enum udebug_format {
32 UDEBUG_FORMAT_PACKET,
33 UDEBUG_FORMAT_STRING,
34 UDEBUG_FORMAT_BLOBMSG,
35 };
36
37 enum {
38 UDEBUG_DLT_ETHERNET = 1,
39 UDEBUG_DLT_PPP = 50,
40 UDEBUG_DLT_RAW_IP = 101,
41 UDEBUG_DLT_IEEE_802_11 = 105,
42 UDEBUG_DLT_IEEE_802_11_RADIOTAP = 127,
43 UDEBUG_DLT_NETLINK = 253,
44 };
45
46 enum udebug_meta_type {
47 UDEBUG_META_IFACE_NAME,
48 UDEBUG_META_IFACE_DESC,
49 __UDEBUG_META_MAX
50 };
51
52 #define UDEBUG_TS_MSEC 1000ULL
53 #define UDEBUG_TS_SEC (1000ULL * UDEBUG_TS_MSEC)
54
55 struct udebug;
56 struct udebug_hdr;
57
58 struct udebug_buf_flag {
59 const char *name;
60 uint64_t mask;
61 };
62
63 struct udebug_buf_meta {
64 const char *name;
65 enum udebug_format format;
66 uint32_t sub_format; /* linktype for UDEBUG_FORMAT_PACKET */
67 const struct udebug_buf_flag *flags;
68 unsigned int n_flags;
69 };
70
71 struct udebug_buf {
72 struct udebug *ctx;
73 const struct udebug_buf_meta *meta;
74 uint32_t id;
75
76 struct list_head list;
77
78 struct udebug_hdr *hdr;
79 void *data;
80 size_t data_size;
81 size_t head_size;
82 size_t ring_size;
83 int fd;
84 };
85
86 struct udebug_packet_info {
87 const char *attr[__UDEBUG_META_MAX];
88 };
89
90 struct udebug_remote_buf {
91 struct avl_node node;
92 struct udebug_buf buf;
93 bool poll;
94 uint32_t head;
95
96 /* provided by user */
97 uint32_t pcap_iface;
98 void *priv;
99 const struct udebug_packet_info *meta;
100 };
101
102 struct udebug {
103 struct list_head local_rings;
104 struct avl_tree remote_rings;
105 uint32_t next_id;
106 struct uloop_fd fd;
107 int poll_handle;
108 char *socket_path;
109 struct uloop_timeout reconnect;
110
111 /* filled by user */
112 void (*notify_cb)(struct udebug *ctx, struct udebug_remote_buf *rb);
113 };
114
115 struct udebug_ptr {
116 uint32_t start;
117 uint32_t len;
118 uint64_t timestamp;
119 };
120
121 struct udebug_snapshot {
122 struct udebug_ptr *entries;
123 unsigned int n_entries;
124 unsigned int dropped;
125 void *data;
126 size_t data_size;
127
128 uint32_t iter_idx;
129
130 enum udebug_format format;
131 uint32_t sub_format;
132
133 uint32_t rbuf_idx;
134 };
135
136 struct udebug_iter {
137 struct udebug_snapshot **list;
138 size_t n;
139
140 struct udebug_snapshot *s;
141 unsigned int s_idx;
142
143 uint64_t timestamp;
144 void *data;
145 size_t len;
146 };
147
148 uint64_t udebug_timestamp(void);
149
150 void udebug_entry_init_ts(struct udebug_buf *buf, uint64_t timestamp);
151 static inline void udebug_entry_init(struct udebug_buf *buf)
152 {
153 udebug_entry_init_ts(buf, udebug_timestamp());
154 }
155 void *udebug_entry_append(struct udebug_buf *buf, const void *data, uint32_t len);
156 int udebug_entry_printf(struct udebug_buf *buf, const char *fmt, ...)
157 __attribute__ ((format (printf, 2, 3)));
158 int udebug_entry_vprintf(struct udebug_buf *buf, const char *fmt, va_list ap)
159 __attribute__ ((format (printf, 2, 0)));
160 void udebug_entry_add(struct udebug_buf *buf);
161
162 int udebug_buf_init(struct udebug_buf *buf, size_t entries, size_t size);
163 int udebug_buf_add(struct udebug *ctx, struct udebug_buf *buf,
164 const struct udebug_buf_meta *meta);
165 uint64_t udebug_buf_flags(struct udebug_buf *buf);
166 void udebug_buf_free(struct udebug_buf *buf);
167
168 struct udebug_remote_buf *udebug_remote_buf_get(struct udebug *ctx, uint32_t id);
169 int udebug_remote_buf_map(struct udebug *ctx, struct udebug_remote_buf *rb, uint32_t id);
170 void udebug_remote_buf_unmap(struct udebug *ctx, struct udebug_remote_buf *rb);
171 int udebug_remote_buf_set_poll(struct udebug *ctx, struct udebug_remote_buf *rb, bool val);
172 void udebug_remote_buf_set_flags(struct udebug_remote_buf *rb, uint64_t mask, uint64_t set);
173 struct udebug_snapshot *udebug_remote_buf_snapshot(struct udebug_remote_buf *rb);
174 bool udebug_snapshot_get_entry(struct udebug_snapshot *s, struct udebug_iter *it, unsigned int entry);
175
176 void udebug_remote_buf_set_start_time(struct udebug_remote_buf *rb, uint64_t ts);
177 void udebug_remote_buf_set_start_offset(struct udebug_remote_buf *rb, uint32_t idx);
178
179 void udebug_iter_start(struct udebug_iter *it, struct udebug_snapshot **s, size_t n);
180 bool udebug_iter_next(struct udebug_iter *it);
181
182 void udebug_init(struct udebug *ctx);
183 int udebug_connect(struct udebug *ctx, const char *path);
184 void udebug_auto_connect(struct udebug *ctx, const char *path);
185 void udebug_add_uloop(struct udebug *ctx);
186 void udebug_poll(struct udebug *ctx);
187 void udebug_free(struct udebug *ctx);
188
189 static inline bool udebug_is_connected(struct udebug *ctx)
190 {
191 return ctx->fd.fd >= 0;
192 }
193
194 int udebug_id_cmp(const void *k1, const void *k2, void *ptr);
195
196 #endif