Callback from pcap_loop used to validate packets in the file */
| 225 | |
| 226 | /* Callback from pcap_loop used to validate packets in the file */ |
| 227 | static void |
| 228 | parse_pcap_packet(u_char *user, const struct pcap_pkthdr *h, |
| 229 | const u_char *bytes) |
| 230 | { |
| 231 | struct pkt_print_ctx *ctx = (struct pkt_print_ctx *)user; |
| 232 | const struct rte_ether_hdr *eh; |
| 233 | const struct rte_ipv4_hdr *ip; |
| 234 | uint64_t ns; |
| 235 | |
| 236 | eh = (const struct rte_ether_hdr *)bytes; |
| 237 | ip = (const struct rte_ipv4_hdr *)(eh + 1); |
| 238 | |
| 239 | ctx->count += 1; |
| 240 | |
| 241 | /* The pcap library is misleading in reporting timestamp. |
| 242 | * packet header struct gives timestamp as a timeval (ie. usec); |
| 243 | * but the file is open in nanonsecond mode therefore |
| 244 | * the timestamp is really in timespec (ie. nanoseconds). |
| 245 | */ |
| 246 | ns = h->ts.tv_sec * NS_PER_S + h->ts.tv_usec; |
| 247 | if (ns < ctx->start_ns || ns > ctx->end_ns) { |
| 248 | char tstart[128], tend[128]; |
| 249 | |
| 250 | fmt_time(tstart, sizeof(tstart), ctx->start_ns); |
| 251 | fmt_time(tend, sizeof(tend), ctx->end_ns); |
| 252 | fprintf(stderr, "Timestamp out of range [%s .. %s]\n", |
| 253 | tstart, tend); |
| 254 | goto error; |
| 255 | } |
| 256 | |
| 257 | if (!rte_is_broadcast_ether_addr(&eh->dst_addr)) { |
| 258 | fprintf(stderr, "Destination is not broadcast\n"); |
| 259 | goto error; |
| 260 | } |
| 261 | |
| 262 | if (rte_ipv4_cksum(ip) != 0) { |
| 263 | fprintf(stderr, "Bad IPv4 checksum\n"); |
| 264 | goto error; |
| 265 | } |
| 266 | |
| 267 | return; /* packet is normal */ |
| 268 | |
| 269 | error: |
| 270 | print_packet(ns, eh, h->len); |
| 271 | |
| 272 | /* Stop parsing at first error */ |
| 273 | pcap_breakloop(ctx->pcap); |
| 274 | } |
| 275 | |
| 276 | static uint64_t |
| 277 | current_timestamp(void) |
nothing calls this directly
no test coverage detected