#1
  1. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95

    print out hex mac address


    i thought this would be simple, and maybe it is, but i cant figure this out. i have a 6 byte MAC address stored in network byte order. its stored as a u_char array. it is a member of this structure:
    Code:
    struct ethhdr 
    {
            unsigned char   h_dest[ETH_ALEN];       /* destination eth addr */
            unsigned char   h_source[ETH_ALEN];     /* source ether addr    */
            unsigned short  h_proto;                /* packet type ID field */
    };
    all im trying to do is print out the MAC address, the byte order i can take of. currently i am using this ugly hackish way to print it out:
    Code:
    //get MAC addresses
                    eth = (struct ethhdr *)recvbuf;
                    unsigned int x = *(unsigned int *)recvbuf;
                    unsigned short y = *(unsigned short *) (recvbuf + 4);
                     printf("%08x%04x\n", ntohl(x), ntohs(y));
    which gives me this:
    0030bd26707f
    which is correct but is there an easier way to accomplish this?

    what i want to do is like this:
    Code:
    printf("h_dest %12x\nh_source %12x\nh_proto %u\n",
                                    eth->h_dest, eth->h_source, ntohs(eth->h_proto));
    but i cannot find format specifiers to accomplish this. the problem is that the %X format specifies an unsigned integer type which is 4 bytes. if i do it as a long integer then it will be 8 bytes, but surely there must be a way. anyone else?
    Last edited by infamous41md; August 20th, 2003 at 03:05 PM.
  2. #2
  3. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,645
    Rep Power
    4248
    Use an union perhaps? All you need to do is assign the value to one member of the union and read off the other member. Note that the following code is possibly non-portable to systems where sizeof(short) != 16 bits, but this could be remedied with an #ifdef or two. Tested on FreeBSD 4.8-Release with gcc 2.95.3
    Code:
    #include <stdio.h>
    #include <string.h>
    
    typedef union {
      unsigned short s[3];
      unsigned char c[6];
    } Converter;
    
    int main(void) {
      Converter conv;
    
      /* Assign to conv.c. You probably need to use network byte order in your case. */
      strncpy(conv.c, "123456", 6); 
      /* Read from conv.s */
      printf("%04x%04x%04x\n", conv.s[0], conv.s[1], conv.s[2]);
      return 0;
    }
    Up the Irons
    What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
    "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
    Down with Sharon Osbourne

    "I wouldn't hire a butcher to fix my car. I also wouldn't hire a marketing firm to build my website." - Nilpo
  4. #3
  5. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    i ended up doing this:
    Code:
    //get MAC addresses
                    snprintf(s_mac, 13, "%08x%04x", ntohl( ( * (unsigned int *) (recvbuf))),
                                                    ntohs( ( * (unsigned short *) (recvbuf + 4))));
                    snprintf(d_mac, 13, "%08x%04x", ntohl( ( * (unsigned int *) (recvbuf + 6))),
                                                    ntohs( ( * (unsigned short *) (recvbuf + 10))));
    edit: i wasnt very familiar with unions as i learned C via C++ but that seems like a better solution if i want to use that value later, thnx.
    Last edited by infamous41md; August 20th, 2003 at 09:24 PM.
  6. #4
  7. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    well as much as i loved my ugly way of doing it, there are a set of functions in the ntoa_ aton_ family. they can be found in the
    /usr/include/netinet/ether.h file. prototype:
    Code:
    char *
           ether_ntoa(const struct ether_addr *addr);
    
    usage:
          snprintf(s_mac, MACLEN, "%s", ether_ntoa(eth->h_source) );
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Cool.

    Though unfortunately there doesn't appear to be any support for it in Winsock. I grep'ed for ether_ntoa in the include files for MinGW's gcc and in VC++6 and did not find it. However, it is in my Red Hat 7's includes just where you describe it.

IMN logo majestic logo threadwatch logo seochat tools logo