udebug.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. #include <sys/types.h>
  21. #include <stdint.h>
  22. #include <stdarg.h>
  23. #include "list.h"
  24. #include "uloop.h"
  25. #include "avl.h"
  26. #define UDEBUG_SOCK_NAME "/var/run/udebug.sock"
  27. enum udebug_format {
  28. UDEBUG_FORMAT_PACKET,
  29. UDEBUG_FORMAT_STRING,
  30. UDEBUG_FORMAT_BLOBMSG,
  31. };
  32. enum {
  33. UDEBUG_DLT_ETHERNET = 1,
  34. UDEBUG_DLT_PPP = 50,
  35. UDEBUG_DLT_RAW_IP = 101,
  36. UDEBUG_DLT_IEEE_802_11 = 105,
  37. UDEBUG_DLT_IEEE_802_11_RADIOTAP = 127,
  38. UDEBUG_DLT_NETLINK = 253,
  39. };
  40. enum udebug_meta_type {
  41. UDEBUG_META_IFACE_NAME,
  42. UDEBUG_META_IFACE_DESC,
  43. __UDEBUG_META_MAX
  44. };
  45. #define UDEBUG_TS_MSEC 1000ULL
  46. #define UDEBUG_TS_SEC (1000ULL * UDEBUG_TS_MSEC)
  47. struct udebug;
  48. struct udebug_hdr;
  49. struct udebug_buf_flag {
  50. const char *name;
  51. uint64_t mask;
  52. };
  53. struct udebug_buf_meta {
  54. const char *name;
  55. enum udebug_format format;
  56. uint32_t sub_format; /* linktype for UDEBUG_FORMAT_PACKET */
  57. const struct udebug_buf_flag *flags;
  58. unsigned int n_flags;
  59. };
  60. struct udebug_buf {
  61. struct udebug *ctx;
  62. const struct udebug_buf_meta *meta;
  63. uint32_t id;
  64. struct list_head list;
  65. struct udebug_hdr *hdr;
  66. void *data;
  67. size_t data_size;
  68. size_t head_size;
  69. size_t ring_size;
  70. int fd;
  71. };
  72. struct udebug_packet_info {
  73. const char *attr[__UDEBUG_META_MAX];
  74. };
  75. struct udebug_remote_buf {
  76. struct avl_node node;
  77. struct udebug_buf buf;
  78. bool poll;
  79. uint32_t head;
  80. /* provided by user */
  81. uint32_t pcap_iface;
  82. void *priv;
  83. const struct udebug_packet_info *meta;
  84. };
  85. struct udebug {
  86. struct list_head local_rings;
  87. struct avl_tree remote_rings;
  88. uint32_t next_id;
  89. struct uloop_fd fd;
  90. int poll_handle;
  91. char *socket_path;
  92. struct uloop_timeout reconnect;
  93. /* filled by user */
  94. void (*notify_cb)(struct udebug *ctx, struct udebug_remote_buf *rb);
  95. };
  96. struct udebug_ptr {
  97. uint32_t start;
  98. uint32_t len;
  99. uint64_t timestamp;
  100. };
  101. struct udebug_snapshot {
  102. struct udebug_ptr *entries;
  103. unsigned int n_entries;
  104. unsigned int dropped;
  105. void *data;
  106. size_t data_size;
  107. uint32_t iter_idx;
  108. enum udebug_format format;
  109. uint32_t sub_format;
  110. uint32_t rbuf_idx;
  111. };
  112. struct udebug_iter {
  113. struct udebug_snapshot **list;
  114. size_t n;
  115. struct udebug_snapshot *s;
  116. unsigned int s_idx;
  117. uint64_t timestamp;
  118. void *data;
  119. size_t len;
  120. };
  121. uint64_t udebug_timestamp(void);
  122. void udebug_entry_init_ts(struct udebug_buf *buf, uint64_t timestamp);
  123. static inline void udebug_entry_init(struct udebug_buf *buf)
  124. {
  125. udebug_entry_init_ts(buf, udebug_timestamp());
  126. }
  127. void *udebug_entry_append(struct udebug_buf *buf, const void *data, uint32_t len);
  128. int udebug_entry_printf(struct udebug_buf *buf, const char *fmt, ...)
  129. __attribute__ ((format (printf, 2, 3)));
  130. int udebug_entry_vprintf(struct udebug_buf *buf, const char *fmt, va_list ap)
  131. __attribute__ ((format (printf, 2, 0)));
  132. uint16_t udebug_entry_trim(struct udebug_buf *buf, uint16_t len);
  133. void udebug_entry_set_length(struct udebug_buf *buf, uint16_t len);
  134. void udebug_entry_add(struct udebug_buf *buf);
  135. int udebug_buf_init(struct udebug_buf *buf, size_t entries, size_t size);
  136. int udebug_buf_add(struct udebug *ctx, struct udebug_buf *buf,
  137. const struct udebug_buf_meta *meta);
  138. uint64_t udebug_buf_flags(struct udebug_buf *buf);
  139. void udebug_buf_free(struct udebug_buf *buf);
  140. static inline bool udebug_buf_valid(struct udebug_buf *buf)
  141. {
  142. return buf->hdr;
  143. }
  144. struct udebug_remote_buf *udebug_remote_buf_get(struct udebug *ctx, uint32_t id);
  145. int udebug_remote_buf_map(struct udebug *ctx, struct udebug_remote_buf *rb, uint32_t id);
  146. void udebug_remote_buf_unmap(struct udebug *ctx, struct udebug_remote_buf *rb);
  147. int udebug_remote_buf_set_poll(struct udebug *ctx, struct udebug_remote_buf *rb, bool val);
  148. void udebug_remote_buf_set_flags(struct udebug_remote_buf *rb, uint64_t mask, uint64_t set);
  149. struct udebug_snapshot *udebug_remote_buf_snapshot(struct udebug_remote_buf *rb);
  150. bool udebug_snapshot_get_entry(struct udebug_snapshot *s, struct udebug_iter *it, unsigned int entry);
  151. void udebug_remote_buf_set_start_time(struct udebug_remote_buf *rb, uint64_t ts);
  152. void udebug_remote_buf_set_start_offset(struct udebug_remote_buf *rb, uint32_t idx);
  153. void udebug_iter_start(struct udebug_iter *it, struct udebug_snapshot **s, size_t n);
  154. bool udebug_iter_next(struct udebug_iter *it);
  155. void udebug_init(struct udebug *ctx);
  156. int udebug_connect(struct udebug *ctx, const char *path);
  157. void udebug_auto_connect(struct udebug *ctx, const char *path);
  158. void udebug_add_uloop(struct udebug *ctx);
  159. void udebug_poll(struct udebug *ctx);
  160. void udebug_free(struct udebug *ctx);
  161. static inline bool udebug_is_connected(struct udebug *ctx)
  162. {
  163. return ctx->fd.fd >= 0;
  164. }
  165. int udebug_id_cmp(const void *k1, const void *k2, void *ptr);
  166. #endif