4 #include <libubox/utils.h>
5 #include <libubox/blobmsg.h>
6 #include "udebug-pcap.h"
9 static char pcap_buf
[65536];
10 static struct pcap_block_hdr
*pcap_hdr
= (struct pcap_block_hdr
*)pcap_buf
;
12 struct pcap_block_hdr
{
43 #define PCAPNG_BTYPE_SHB 0x0a0d0d0a
44 #define PCAPNG_BTYPE_IDB 1
45 #define PCAPNG_BTYPE_EPB 6
47 #define PCAPNG_ENDIAN 0x1a2b3c4d
50 pcap_block_start(uint32_t type
, uint32_t len
)
52 struct pcap_block_hdr
*b
= pcap_hdr
;
55 b
->len
= len
+ sizeof(*b
);
56 memset(b
+ 1, 0, len
);
62 pcap_block_append(int len
)
64 struct pcap_block_hdr
*b
= pcap_hdr
;
65 void *data
= &pcap_buf
[b
->len
];
74 pcap_opt_append(int id
, int len
)
76 struct pcap_opt_hdr
*opt
;
79 opt
= pcap_block_append(sizeof(*opt
) + len
);
87 pcap_opt_str_add(int id
, const char *val
)
94 len
= strlen(val
) + 1;
95 memcpy(pcap_opt_append(id
, len
), val
, len
);
99 pcap_opt_u8_add(uint16_t id
, uint8_t val
)
101 *(uint8_t *)pcap_opt_append(id
, 1) = val
;
107 pcap_block_append(4);
110 static uint32_t __pcap_block_align(int offset
, int val
)
112 struct pcap_block_hdr
*b
= pcap_hdr
;
113 uint32_t cur_len
= b
->len
- offset
;
114 uint32_t aligned_len
= (cur_len
+ (val
- 1)) & ~(val
- 1);
115 uint32_t pad
= aligned_len
- cur_len
;
118 pcap_block_append(pad
);
123 static uint32_t pcap_block_align(int val
)
125 return __pcap_block_align(0, val
);
131 struct pcap_block_hdr
*b
= (struct pcap_block_hdr
*)pcap_buf
;
135 len
= (uint32_t *)&pcap_buf
[b
->len
];
143 int pcap_init(struct pcap_context
*p
, struct pcap_meta
*meta
)
145 struct pcap_shb_hdr
*shb
;
147 shb
= pcap_block_start(PCAPNG_BTYPE_SHB
, sizeof(*shb
));
148 shb
->endian
= PCAPNG_ENDIAN
;
150 shb
->section_len
= ~0ULL;
151 pcap_opt_str_add(2, meta
->hw
);
152 pcap_opt_str_add(3, meta
->os
);
153 pcap_opt_str_add(4, meta
->app
);
160 int pcap_interface_init(struct pcap_context
*p
, uint32_t *id
,
161 struct pcap_interface_meta
*meta
)
163 struct pcap_idb_hdr
*idb
;
166 idb
= pcap_block_start(PCAPNG_BTYPE_IDB
, sizeof(*idb
));
167 idb
->link_type
= meta
->link_type
;
168 idb
->snap_len
= 0xffff;
169 pcap_opt_str_add(2, meta
->name
);
170 pcap_opt_str_add(3, meta
->description
);
171 pcap_opt_u8_add(9, meta
->time_res
);
178 void pcap_packet_init(uint32_t iface
, uint64_t ts
)
180 struct pcap_epb_hdr
*epb
;
182 epb
= pcap_block_start(PCAPNG_BTYPE_EPB
, sizeof(*epb
));
184 epb
->ts_hi
= ts
>> 32;
185 epb
->ts_lo
= (uint32_t)ts
;
188 void *pcap_packet_append(const void *data
, size_t len
)
192 buf
= pcap_block_append(len
);
194 memcpy(buf
, data
, len
);
199 void pcap_packet_done(void)
201 struct pcap_epb_hdr
*epb
= (struct pcap_epb_hdr
*)&pcap_hdr
[1];
204 len
= pcap_hdr
->len
- sizeof(*pcap_hdr
) - sizeof(*epb
);
205 epb
->cap_len
= epb
->pkt_len
= len
;
210 int pcap_interface_rbuf_init(struct pcap_context
*p
, struct udebug_remote_buf
*rb
)
212 const struct udebug_packet_info
*meta
= rb
->meta
;
213 struct pcap_interface_meta if_meta
= {
215 .name
= meta
->attr
[UDEBUG_META_IFACE_NAME
],
216 .description
= meta
->attr
[UDEBUG_META_IFACE_DESC
],
219 if (rb
->buf
.hdr
->format
== UDEBUG_FORMAT_PACKET
)
220 if_meta
.link_type
= rb
->buf
.hdr
->sub_format
;
221 else if (rb
->buf
.hdr
->format
== UDEBUG_FORMAT_STRING
)
222 if_meta
.link_type
= 147;
224 return pcap_interface_init(p
, &rb
->pcap_iface
, &if_meta
);
227 int pcap_snapshot_packet_init(struct udebug
*ctx
, struct udebug_iter
*it
)
229 struct udebug_remote_buf
*rb
;
230 struct udebug_snapshot
*s
= it
->s
;
232 rb
= udebug_remote_buf_get(ctx
, s
->rbuf_idx
);
236 pcap_packet_init(rb
->pcap_iface
, it
->timestamp
);
239 case UDEBUG_FORMAT_PACKET
:
240 case UDEBUG_FORMAT_STRING
:
241 pcap_packet_append(it
->data
, it
->len
);
243 case UDEBUG_FORMAT_BLOBMSG
:
254 void pcap_block_write_file(FILE *f
)
256 fwrite(pcap_buf
, pcap_hdr
->len
, 1, f
);
260 void *pcap_block_get(size_t *len
)
262 *len
= pcap_hdr
->len
;