Issue information

Issue ID
#765
Status
Confirmed
Severity
Low
Started
Hercules Elf Bot
Jan 7, 2008 22:21
Last Post
Hercules Elf Bot
Jan 7, 2008 22:21
Confirmation
N/A

Hercules Elf Bot - Jan 7, 2008 22:21

Originally posted by [b]theultramage[/b]
http://www.eathena.ws/board/index.php?autocom=bugtracker&showbug=765

A long time ago, I reported that the code that executes at startup - to enumerate the machine's network interfaces - reads random junk instead of what it should.

I investigated that in detail yesterday. And came up with this.
CODE
==1915== Conditional jump or move depends on uninitialised value(s)
==1915==    at 0x8056D1E: socket_getips (socket.c:1180)
==1915==    by 0x8056D91: socket_init (socket.c:1225)
==1915==    by 0x805523C: main (core.c:244)

Memory dump reveals the following:
CODE
66 78 70 30 00 00 00 00 00 00 00 00 00 00 00 00
  38 (16 bytes)
  12 (AF_LINK)
  01 00 06 04 06 00 66 78 70 30 00 30 05 08 5B 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

66 78 70 30 00 00 00 00 00 00 00 00 00 00 00 00
  1C (28 bytes)
  1C (AF_INET6)
  00 00 00 00 00 00 FE 80 00 01 00 00 00 00 02 30 05 FF FE 08 5B 60 00 00 00 00

66 78 70 30 00 00 00 00 00 00 00 00 00 00 00 00
  10 (16 bytes)
  02 (AF_INET)
  00 00 C0 A8 00 01 00 00 00 00 00 00 00 00

72 6C 30 00 00 00 00 00 00 00 00 00 00 00 00 00
  38 (16 bytes)
  12 (AF_LINK)
  02 00 06 03 06 00 72 6C 30 00 E0 4C C4 31 93 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

72 6C 30 00 00 00 00 00 00 00 00 00 00 00 00 00
  1C (28 bytes)
  1C (AF_INET6)
  00 00 00 00 00 00 FE 80 00 02 00 00 00 00 02 E0 4C FF FE C4 31 93 00 00 00 00

72 6C 30 00 00 00 00 00 00 00 00 00 00 00 00 00
  10 (16 bytes)
  02 (AF_INET)
  00 00 0A 14 06 1E 00 00 00 00 00 00 00 00

6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00
  38 (16 bytes)
  12 (AF_LINK)
  03 00 18 03 00 00 6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00
  1C (28 bytes)
  1C (AF_INET6)
  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00

6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00
  1C (28 bytes)
  1C (AF_INET6)
  00 00 00 00 00 00 FE 80 00 03 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00

6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00
  10 (16 bytes)
  02 (AF_INET)
  00 00 7F 00 00 01 00 00 00 00 00 00 00 00


struct    ifreq {
    char    ifr_name[IFNAMSIZ];        /* if name, e.g. "en0" */
    union {
        struct    sockaddr ifru_addr;
        struct    sockaddr ifru_dstaddr;
        struct    sockaddr ifru_broadaddr;
        short    ifru_flags[2];
        short    ifru_index;
        int    ifru_metric;
        int    ifru_mtu;
        int    ifru_phys;
        int    ifru_media;
        caddr_t    ifru_data;
        int    ifru_cap[2];
    } ifr_ifru;

struct sockaddr {
    unsigned char    sa_len;        /* total length */
    sa_family_t    sa_family;    /* address family */
    char        sa_data[14];    /* actually longer; address value */
};


Problem: the eathena code assumes that the individual ifreq structures have the same size and can be iterated over like an array.
On FreeBSD, they have variable-size (but use a dummy sockaddr structure) and are packed together. Thus you need to process one to know where the next begins. Not sure if this is standardized behavior... looks more like kernel-specific stuff. I'd use the Windows approach myself (gethostname + gethostbyname)...

PS: the valgrind 'uninitialized memory' error message goes away if you memset() the buffer first.