0

I am trying to copy an IP address from a string to struct sockaddr_in but somehow there's some error popping up.

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
    char *buf = "128.10.25.102:30015";
    char ip[30];
    struct sockaddr_in s1_addport;
    int i = 0;

    while (buf[i] != ':') i++;
    strncpy(ip, &buf[0], i);
    ip[strlen(ip)] = '\0';

    printf("ip: %s, strlen:%zu\n",ip,strlen(ip));
    inet_aton(ip,&s1_addport.sin_addr);
    printf("Server IP: %s\n",inet_ntoa(s1_addport.sin_addr));
    return 0;
}

The output of the above code shows:

ip: 128.10.25.102, strlen:13  
Server IP: 0.0.0.0

There is some error in copying the value from ip string which I am unable to figure out. What could be the reason?

zwol
  • 135,547
  • 38
  • 252
  • 361
re3el
  • 735
  • 2
  • 12
  • 28
  • What error is popping up? – cadaniluk Oct 23 '16 at 15:59
  • Have you tried using `inet_pton` instead of `inet_aton`? – Charles Oct 23 '16 at 16:00
  • no error is popped. server_IP is shown as 0.0.0.0 instead of 128.10.25.102. Sorry for the confusion – re3el Oct 23 '16 at 16:00
  • What is the real name of the variable? `s1_addport` or `s3_addport`? – mch Oct 23 '16 at 16:00
  • yeah. i tried inet_pton as well. same error! – re3el Oct 23 '16 at 16:00
  • edited the question. It's s3_addport – re3el Oct 23 '16 at 16:01
  • i just tried `inet_aton(ip, &(s3_addport.sin_addr));`. Not working again – re3el Oct 23 '16 at 16:03
  • 1
    If I flesh this code out to a complete, compilable test program, I cannot reproduce the problem. I note that one of the changes I had to make was changing `s3_addport` to `s1_addport` in two places. It is likely that your _real_ code has similar typos, such that you are writing the address to one `sockaddr_in` and then reading it back from a different one. – zwol Oct 23 '16 at 16:03
  • Also, you _really_ should be using [`getaddrinfo`](https://linux.die.net/man/3/getaddrinfo), which handles IPv6 seamlessly, does DNS lookups, completely fills in sockaddr structures for you, and insulates you from the pointer-aliasing headaches involved with manual operations on `sockaddr_*`, instead of these legacy functions. – zwol Oct 23 '16 at 16:04
  • @zwol could you post your code? I would like to check how `ip` string got initialized. thanks – re3el Oct 23 '16 at 16:04
  • 1
    @re3el http://pastebin.com/zCk8jtY7 – zwol Oct 23 '16 at 16:07
  • @c650 `&(foo.bar)` and `&foo.bar` have exactly the same behavior. – zwol Oct 23 '16 at 16:08
  • @zwol: I am using the below code for ip. Is there anything wrong with this? http://pastebin.com/rPi52XCN – re3el Oct 23 '16 at 16:18

1 Answers1

3

This is the problem in your pastebin code:

ip[strlen(ip)]='\0';

(Trying to append null terminator but using strlen, which itself depends on a null terminator to be present).

Here is the fix:

....
while(buf[i]!=':')
    i++;
strncpy(ip,&buf[0],i);
ip[i]='\0';
puts(ip);
....
FractalSpace
  • 5,577
  • 3
  • 42
  • 47