ref: 7d227ab829f8416de6d7fe2b3506efdbd67c8861
parent: 62f368cf3f37d4d049555317de2226aa3c9a91bb
author: Ralph Giles <giles@mozilla.com>
date: Tue Oct 2 12:57:30 EDT 2012
Add 'loopback' header parsing to the sniff mode. On darwin, pcap returns packets from the loopback device with a 4 byte 'family' number, instead of the dummy eth header we get on linux. Add support for parsing this instead. The build now needs to define either 'LOOP' or 'ETH' to control which is expected. I don't know if there's a way to ask pcap about this, but wireshark manages to handle it correctly. Also hardcode the sniff device to 'lo0' as required by darwin instead of linux 'lo'. That's where I'm currently testing.
--- a/src/opusrtp.c
+++ b/src/opusrtp.c
@@ -273,6 +273,11 @@
int type;
} eth_header;
+#define LOOP_HEADER_LEN 4
+typedef struct {
+ int family;
+} loop_header;
+
#define IP_HEADER_MIN 20
typedef struct {
int version;
@@ -329,6 +334,21 @@
return 0;
}
+/* used by the darwin loopback interface, at least */
+int parse_loop_header(const unsigned char *packet, int size, loop_header *loop)
+{
+ if (!packet || !loop) {
+ return -2;
+ }
+ if (size < LOOP_HEADER_LEN) {
+ fprintf(stderr, "Packet too short for loopback\n");
+ return -1;
+ }
+ loop->family = rbe32(packet);
+
+ return 0;
+}
+
int parse_ip_header(const unsigned char *packet, int size, ip_header *ip)
{
if (!packet || !ip) {
@@ -602,6 +622,7 @@
const unsigned char *packet;
int size;
eth_header eth;
+ loop_header loop;
ip_header ip;
udp_header udp;
rtp_header rtp;
@@ -611,6 +632,7 @@
packet = data;
size = header->caplen;
+#if ETH
if (parse_eth_header(packet, size, ð)) {
fprintf(stderr, "error parsing eth header\n");
return;
@@ -624,6 +646,15 @@
eth.dst[3], eth.dst[4], eth.dst[5]);
packet += ETH_HEADER_LEN;
size -= ETH_HEADER_LEN;
+#elif LOOP
+ if (parse_loop_header(packet, size, &loop)) {
+ fprintf(stderr, "error parsing loopback header\n");
+ return;
+ }
+ fprintf(stderr, " loopback family %d\n", loop.family);
+ packet += LOOP_HEADER_LEN;
+ size -= LOOP_HEADER_LEN;
+#endif
if (parse_ip_header(packet, size, &ip)) {
fprintf(stderr, "error parsing ip header\n");
@@ -790,7 +821,7 @@
case 0:
if (!strcmp(long_options[i].name, "sniff")) {
#ifdef HAVE_PCAP
- sniff("lo");
+ sniff("lo0");
return 0;
#else
fprintf(stderr, "pcap support disabled, sorry.\n");