Search code examples
csocketssetsockoptmulticastsocket

Extracting IP address from C sockets


Ok, I'm still new to using C sockets, but I was wondering if there is a way to extract the IP address adding running setsockopt? If you'll look at my code below, I have everything in my multicast sockets ready to send except for defining the variable mc_addr which is my IP address.

Am I doing anything wrong that's real noticeable? If so, feel free to let me know or offer your suggestions. Right now though, I'm mainly concerned about getting the variable mc_addr filled out.

I've never programmed in C before (just python, C++, and since the beginning of this summer, Objective-C) , so this is why I don't know EVERYTHING there is to know about the C language and am seeking help.

File.h

#define MYPORT 5673         /* port for our multicast socket */

int sock;                   /* socket descriptor */
char send_str[MAX_LEN];     /* string to send */
struct sockaddr_in mc_addr; /* socket address structure */
unsigned int send_len;      /* length of string to send */
char* mc_addr_str;          /* multicast IP address */
unsigned short mc_port;     /* multicast port */
unsigned char mc_ttl;       /* time to live (hop count) */

File.c

mc_port = MYPORT;
/* create a socket for sending to the multicast address  */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    NSLog(@"ERROR: broadcastMessage - socket() failed");
    return 1;
}

/* set the TTL (time to live/hop count) for the send */
if ((setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, 
        (void*) &mc_ttl, sizeof(mc_ttl))) < 0) {
    NSLog(@"ERROR: broadcastMessage - setsockopt() failed");
    return 1;
}

// define the IP address we will be using
mc_addr = // ???

/* construct a multicast address structure */
memset(&mc_addr, 0, sizeof(mc_addr));
mc_addr.sin_family      = AF_INET;
mc_addr.sin_addr.s_addr = inet_addr(mc_addr_str);
mc_addr.sin_port        = htons(mc_port);

/* clear send buffer */
memset(send_str, 0, sizeof(send_str));

while (fgets(send_str, MAX_LEN, stdin)) {
    send_len = strlen(send_str);

    /* send string to multicast address */
    if ((sendto(sock, send_str, send_len, 0, 
            (struct sockaddr *) &mc_addr, sizeof(mc_addr))) != send_len) {
        NSLog(@"ERROR: broadcastMessage - sendto() sent incorrect number of bytes");
        return 1;
    }

    /* clear send buffer */
    memset(send_str, 0, sizeof(send_str));
}

close(sock);
return 0;

Solution

  • Looks correct to me - where you have the "define the IP address we will be using" you should just set mc_addr_str (mc_addr itself is filled out with the code you already have there, based on mc_addr_str). Something like:

    mc_addr_str = "239.20.30.40";
    

    It's really up to you what multicast address you choose - the one I've put there I just picked out of the "Administratively scoped" range. Your clients and server just have to agree on it beforehand (or negotiate it some other way, like the clients contact the server unicast to ask what the multicast address they should subscribe to is).

    This site may help.