title: libpcap get MAC from AF_LINK sockaddr_dl (OSX)
body: <p>I am trying to obtain the MAC addresses of all of my interface on OSX using C.  The common ways to obtain it Linux dont work on BSD - from everything I have seen, you must obtain the interfaces and look for the ones that are of type AF_LINK.  My problem is that the LLADDR(sockaddr_dl) gives me a whole bunch of data (which includes my MAC) and I dont know what format the data is in.  For example; the following code will output:</p>
  
  <blockquote>
    <p>Device: en1 
    link sdl_alen: 101 mac:
    31:<strong>f8:1e:df:d6:22:1d</strong>:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:b0:06:10:00:01:00:00:00:c0:02:10:00:01:00:00:00:00:00:00:00:00:00:00:00:40
    :03:10:00:01:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:03:00:6c:6f:30:00:00:00:00:00:00:00:00:00:00:00:00:00:70:03:10:00:01:00:00:00:e0:
    02:10:00:01:00:00:</p>
  </blockquote>
  
  <p>My MAC is bolded.  It seems that this is the format all of the time, but I would be a lot more comfortable if I could cast LLADDR(sockaddr_dl) to something.  In the net/if_dl.h, LLADDR is defied as:</p>
  
  <pre><code>#define LLADDR(s) ((caddr_t)((s)-&gt;sdl_data + (s)-&gt;sdl_nlen))
  </code></pre>
  
  <p>which, as far as I can tell, is saying that the results are of type (void *) - no help.  </p>
  
  <p>Other posts like: </p>
  
  <p><a href="https://stackoverflow.com/questions/3964494/having-a-problem-figuring-out-how-to-get-ethernet-interface-info-on-mac-os-x-usin">Having a problem figuring out how to get Ethernet interface info on Mac OS X using ioctl/SIOCGIFADDR/SIOCGIFCONF?</a></p>
  
  <p>seem to think they have it figured out, but if you look through the code, you can see it will not work due to sdl_alen not being 6.</p>
  
  <pre><code>int main() {
      pcap_if_t *alldevs;
      pcap_if_t *d;
      pcap_addr_t *alladdrs;
      pcap_addr_t *a;
  
      struct sockaddr_dl* link;
  
      char eb[PCAP_ERRBUF_SIZE];
      char *addr_buf[40];
  
      if (pcap_findalldevs(&amp;alldevs, eb) == -1) {
          printf("no devs found\n");
          return(-1);
      }
  
      for (d = alldevs; d != NULL; d = d-&gt;next) {
          printf("Device: %s\n", d-&gt;name);
          alladdrs = d-&gt;addresses;
          for (a = alladdrs; a != NULL; a = a-&gt;next) {
              if(a-&gt;addr-&gt;sa_family == AF_LINK &amp;&amp; a-&gt;addr-&gt;sa_data != NULL){
                  // MAC ADDRESS
                  //struct sockaddr_dl *sdl = (struct sockaddr_dl *) a-&gt;addr-&gt;sa_data;
                  link = (struct sockaddr_dl*)a-&gt;addr-&gt;sa_data;
  
                  char mac[link-&gt;sdl_alen];
                  caddr_t macaddr = LLADDR(link);
  
                  memcpy(mac, LLADDR(link), link-&gt;sdl_alen);
                  printf("link sdl_alen: %i\n", link-&gt;sdl_alen);
                  int i;
                  printf("mac: ");
                  for(i = 0; i&lt;link-&gt;sdl_alen; i++){
                      printf("%02x:", (unsigned char)mac[i]);
                  }
                  printf("\n");
              }
          }
      }
  }
  </code></pre>