Game Development Community

Local IP and Broadcast

by Lally Singh · in Technical Issues · 04/03/2006 (1:41 pm) · 5 replies

Hi all, two questions for you:
1. How would I get the local IP address programmatically? It'll be during startup, so I don't mind being a little slow about it (e.g. having the console eval()).
2. How do I send a broadcast packet? I just want to cover the local network with it. Also, any pointers for how to deal with a machine with several network interfaces (1 for clients, another for other servers), would be great.

Thanks in advance!
-ls

#1
05/31/2006 (8:50 am)
Lally (and anyone else),

I'm also having problems grabbing the local IP address programmatically. I've created a class deriving from the base class NetEvent. I'm now overriding the abstract NetEvent empty virtual base methods 'void pack(NetConnection*,BitStream*)' and 'unpack(NetConnection*,BitStream*).

Ideally, I'd like to know a simple way to grab my local IP address from within both of these methods.

This is how I'm currently getting the host address: conn->getNetAddress().
Now how do I get my local address?????


Thanks,

Franklin
#2
05/31/2006 (2:25 pm)
Nothing in the source code I could find. So, I wrote my own.

This isn't production code, just some API experimentation for POSIX, but it's not hard to fix up.
Tested on Mac & Linux.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/route.h>
#include <netinet/in.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <arpa/inet.h>

int max (int a, int b) { return a>b?a:b; }

void
all_addrs () {
    struct ifconf topbuf;
    int len, lastlen = -1;
    topbuf.ifc_len = len = 16 * sizeof (struct ifreq);
    topbuf.ifc_buf = 0;
    int sock = ::socket (AF_INET, SOCK_DGRAM, 0);
    while (topbuf.ifc_len != lastlen) {
        printf ("trying with length %d...", len);
        lastlen = topbuf.ifc_len;
        if (topbuf.ifc_buf)
            free (topbuf.ifc_buf);
        topbuf.ifc_buf = (char *) malloc (len); 
        topbuf.ifc_len = len;
        if (ioctl(sock, SIOCGIFCONF, &topbuf) < 0) {
            perror ("all_addrs-ioctl");
            exit (2);
        }
        printf ("got %d bytes\n", topbuf.ifc_len);
        len *= 2;
    }
    
    // start printing out the data we've gotten.
    for (char * p = topbuf.ifc_buf; 
         p < (topbuf.ifc_len + topbuf.ifc_buf); /* */ ) {
        struct ifreq * ifr = (struct ifreq *) p;
        len = max (sizeof (struct sockaddr), ifr->ifr_addr.sa_len);
        p += sizeof (ifr->ifr_name) + len;
        if (ifr->ifr_addr.sa_family != AF_INET)
            continue;

        char namebuf[64];
        char *cp = strchr(ifr->ifr_name, ':');
        if (cp) *cp = 0;
        strncpy (namebuf, ifr->ifr_name, sizeof (ifr->ifr_name));
        printf ("Interface %s\n", namebuf);

        ifreq copy = *ifr;
        ioctl (sock, SIOCGIFFLAGS, &copy);
        if (copy.ifr_flags & IFF_UP)
            printf ("\tInterface is UP\n");
        else
            continue;

        ioctl (sock, SIOCGIFADDR, &copy);
        struct sockaddr_in * brd = (struct sockaddr_in *) &copy.ifr_addr;
        printf ("\tAddress: %s\n", inet_ntoa (brd->sin_addr));
        if (ntohl(brd->sin_addr.s_addr) == 0x7F000001) 
            printf ("\t(loopback)\n");
        if (copy.ifr_flags &  IFF_BROADCAST) {
            ioctl (sock, SIOCGIFBRDADDR, &copy);
            brd = (struct sockaddr_in *) &copy.ifr_broadaddr;
            printf ("\tBroadcast address: %s\n",
                inet_ntoa(brd->sin_addr));
        }
        ioctl (sock, SIOCGIFNETMASK, &copy);
        printf ("\tNetmask: %s\n", inet_ntoa(brd->sin_addr));
    }
    
    ::close (sock);
    free(topbuf.ifc_buf);
}

int main () {
    all_addrs ();
}
#3
05/31/2006 (2:38 pm)
I should probably note that I wrote this a few months ago, and don't remember if this is the _exact_ version that worked on both mac & linux. This works (for sure) on mac -- just tested it a second ago. The box I usually ssh into for Linux testing is offline right now (new building, no network yet).

Good luck!
#4
06/21/2006 (1:50 am)
:lally(and everybody else)
i am a skilled at c++ programming but this is my first foray in to game development especially networking.want to start with a single player prototype with no network connection and servers.just a single player game.where to start with.need to know the network part of the engine throughly.need to know where to start off and how.any help is welcome.thank u in advance
#5
06/21/2006 (8:31 am)
Ryan:
An intro to Torque's networking model: http://www.garagegames.com/articles/networking1/
Torque's networking stack is documented here: http://opentnl.sourceforge.net/doxytree/

For learning how to do some network programming, try
_Unix Network Programming, Vol. 1: The Sockets Networking API_ by W. Richard Stevens.