shithub: opus-tools

Download patch

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, &eth)) {
     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");