4 #include <libubox/utils.h>
5 #include <libubox/blobmsg.h>
6 #include <libubox/udebug.h>
7 #include <libubox/udebug-proto.h>
8 #include "udebug-pcap.h"
10 static char pcap_buf
[65536];
11 static struct pcap_block_hdr
*pcap_hdr
= (struct pcap_block_hdr
*)pcap_buf
;
13 struct pcap_block_hdr
{
44 #define PCAPNG_BTYPE_SHB 0x0a0d0d0a
45 #define PCAPNG_BTYPE_IDB 1
46 #define PCAPNG_BTYPE_EPB 6
48 #define PCAPNG_ENDIAN 0x1a2b3c4d
51 pcap_block_start(uint32_t type
, uint32_t len
)
53 struct pcap_block_hdr
*b
= pcap_hdr
;
56 b
->len
= len
+ sizeof(*b
);
57 memset(b
+ 1, 0, len
);
63 pcap_block_append(int len
)
65 struct pcap_block_hdr
*b
= pcap_hdr
;
66 void *data
= &pcap_buf
[b
->len
];
75 pcap_opt_append(int id
, int len
)
77 struct pcap_opt_hdr
*opt
;
80 opt
= pcap_block_append(sizeof(*opt
) + len
);
88 pcap_opt_str_add(int id
, const char *val
)
95 len
= strlen(val
) + 1;
96 memcpy(pcap_opt_append(id
, len
), val
, len
);
100 pcap_opt_u8_add(uint16_t id
, uint8_t val
)
102 *(uint8_t *)pcap_opt_append(id
, 1) = val
;
108 pcap_block_append(4);
111 static uint32_t __pcap_block_align(int offset
, int val
)
113 struct pcap_block_hdr
*b
= pcap_hdr
;
114 uint32_t cur_len
= b
->len
- offset
;
115 uint32_t aligned_len
= (cur_len
+ (val
- 1)) & ~(val
- 1);
116 uint32_t pad
= aligned_len
- cur_len
;
119 pcap_block_append(pad
);
124 static uint32_t pcap_block_align(int val
)
126 return __pcap_block_align(0, val
);
132 struct pcap_block_hdr
*b
= (struct pcap_block_hdr
*)pcap_buf
;
136 len
= (uint32_t *)&pcap_buf
[b
->len
];
144 int pcap_init(struct pcap_context
*p
, struct pcap_meta
*meta
)
146 struct pcap_shb_hdr
*shb
;
148 shb
= pcap_block_start(PCAPNG_BTYPE_SHB
, sizeof(*shb
));
149 shb
->endian
= PCAPNG_ENDIAN
;
151 shb
->section_len
= ~0ULL;
152 pcap_opt_str_add(2, meta
->hw
);
153 pcap_opt_str_add(3, meta
->os
);
154 pcap_opt_str_add(4, meta
->app
);
161 int pcap_interface_init(struct pcap_context
*p
, uint32_t *id
,
162 struct pcap_interface_meta
*meta
)
164 struct pcap_idb_hdr
*idb
;
167 idb
= pcap_block_start(PCAPNG_BTYPE_IDB
, sizeof(*idb
));
168 idb
->link_type
= meta
->link_type
;
169 idb
->snap_len
= 0xffff;
170 pcap_opt_str_add(2, meta
->name
);
171 pcap_opt_str_add(3, meta
->description
);
172 pcap_opt_u8_add(9, meta
->time_res
);
179 void pcap_packet_init(uint32_t iface
, uint64_t ts
)
181 struct pcap_epb_hdr
*epb
;
183 epb
= pcap_block_start(PCAPNG_BTYPE_EPB
, sizeof(*epb
));
185 epb
->ts_hi
= ts
>> 32;
186 epb
->ts_lo
= (uint32_t)ts
;
189 void *pcap_packet_append(const void *data
, size_t len
)
193 buf
= pcap_block_append(len
);
195 memcpy(buf
, data
, len
);
200 void pcap_packet_done(void)
202 struct pcap_epb_hdr
*epb
= (struct pcap_epb_hdr
*)&pcap_hdr
[1];
205 len
= pcap_hdr
->len
- sizeof(*pcap_hdr
) - sizeof(*epb
);
206 epb
->cap_len
= epb
->pkt_len
= len
;
211 int pcap_interface_rbuf_init(struct pcap_context
*p
, struct udebug_remote_buf
*rb
)
213 const struct udebug_packet_info
*meta
= rb
->meta
;
214 struct pcap_interface_meta if_meta
= {
216 .name
= meta
->attr
[UDEBUG_META_IFACE_NAME
],
217 .description
= meta
->attr
[UDEBUG_META_IFACE_DESC
],
220 if (rb
->buf
.hdr
->format
== UDEBUG_FORMAT_PACKET
)
221 if_meta
.link_type
= rb
->buf
.hdr
->sub_format
;
222 else if (rb
->buf
.hdr
->format
== UDEBUG_FORMAT_STRING
)
223 if_meta
.link_type
= 147;
225 return pcap_interface_init(p
, &rb
->pcap_iface
, &if_meta
);
228 int pcap_snapshot_packet_init(struct udebug
*ctx
, struct udebug_iter
*it
)
230 struct udebug_remote_buf
*rb
;
231 struct udebug_snapshot
*s
= it
->s
;
233 rb
= udebug_remote_buf_get(ctx
, s
->rbuf_idx
);
237 pcap_packet_init(rb
->pcap_iface
, it
->timestamp
);
240 case UDEBUG_FORMAT_PACKET
:
241 case UDEBUG_FORMAT_STRING
:
242 pcap_packet_append(it
->data
, it
->len
);
244 case UDEBUG_FORMAT_BLOBMSG
:
255 void pcap_block_write_file(FILE *f
)
257 fwrite(pcap_buf
, pcap_hdr
->len
, 1, f
);
261 void *pcap_block_get(size_t *len
)
263 *len
= pcap_hdr
->len
;