aebner
aebner

Reputation: 31

Problem with IP address as positional argument

I want to enter an IP address and a PORT number as positional arguments. Like this:

./client 127.0.0.1 12345

They pass, I check that they are correct (I solved this with two functions, whose arguments I passed as char *), and then I try to pass the IP address and PORT number to two variables. sin_port accepts the PORT number as a value, but s_addr doesn't accept the IP address (in principle). Like this:

int ret;
struct sockaddr_in servaddr;

servaddr.sin_addr.s_addr = inet_addr(argv[1]); //inet_addr accepts char*
servaddr.sin_port = htons (atoi(argv[2]));

// then

ret = connect (connSock, (struct sockaddr *) &servaddr, sizeof (servaddr));

And because of connect() the terminal don't do anything.

Any suggestions?

Thanks for answers!


Edit:

Here is the code of my client module:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>
#include <errno.h>

// ./clientTest (távoli IP) (port)

#define MAX_BUFFER 1024
// #define MY_PORT_NUM 62324 /* This can be changed to suit the need and should be same in server and client */

int valid_digit(char *str)
{
    while (*str) {
        if (*str >= '0' && *str <= '9')
            ++str;
        else
            return 0;
    }
    return 1;
} // ha a string csak számokat tartalmaz, akkor a visszatérési érték TRUE, egyébként FALSE


int valid_ip(char *ip)
{
    int i, num, dots = 0;
    char *ptr;

    if (ip == NULL)
        return 0;

    ptr = strtok(ip, ".");

    if (ptr == NULL)
        return 0;

    while (ptr) {

        if (!valid_digit(ptr))
            return 0;

        num = atoi(ptr);

        if (num >= 0 && num <= 255) {
            ptr = strtok(NULL, ".");
            if (ptr != NULL)
                ++dots;
        } else
            return 0;
    }

    if (dots != 3)
        return 0;

    return 1;
}

int valid_port(char *port)
{

    int num;

    if (port == NULL)
    {
        return 0;
    }

    if (!valid_digit(port))
    {
        return 0;
    }

    num = atoi(port);

    if (num < 0 || num > 65535)
    {
        return 0;
    }
    return 1;
}

int
main (int argc, char* argv[])
{

  if (argc > 1)
  {
    if (!valid_ip(argv[1]))
    {
      printf("HIBA: A megadott IP cím hibás!\n");
      return 0;
    }
    if (!valid_port(argv[2]))
    {
      printf("HIBA: A megadott PORT szám hibás!\n");
      return 0;
    }
  }



  int connSock, in, i, ret, flags;

  struct sockaddr_in servaddr;
  struct sctp_status status;

  char buffer[MAX_BUFFER + 1];
  int datalen = 0;

  connSock = socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP);

  if (connSock == -1)
  {
      printf("Socket creation failed\n");
      perror("socket()");
      exit(1);
  }

  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons (atoi(argv[2]));
  if (inet_aton(argv[1], &servaddr.sin_addr) != 1)
  {
    fputs("Invalid IP address", stderr);
    return 1;
  }

  if ((connect(connSock, (struct sockaddr *) &servaddr, sizeof (servaddr))) == -1)
  {
    perror("ERROR connecting");
    close(connSock);
    return 1;
  }
  else
  {
    ret = connect(connSock, (struct sockaddr *) &servaddr, sizeof (servaddr));
  }

  if (ret == -1)
  {
      printf("Connection failed\n");
      perror("connect()");
      close(connSock);
      exit(1);
  }

  printf("Enter data to send: ");
  fgets(buffer, MAX_BUFFER, stdin);

  buffer[strcspn(buffer, "\r\n")] = 0;
  datalen = strlen(buffer);

  ret = sctp_sendmsg (connSock, (void *) buffer, (size_t) datalen,
        NULL, 0, 0, 0, 0, 0, 0);
  if(ret == -1 )
  {
    printf("Error in sctp_sendmsg\n");
    perror("sctp_sendmsg()");
  }
  else
      printf("Successfully sent %d bytes data to server\n", ret);

  close (connSock);

  return 0;
}

I drew a conslusion from information what Wireshark provided: it seems like the IP address argument doesn't pass correctly to the program. From Wireshark:

09 39.287070587 192.168.0.104 0.0.0.127 SCTP 82 INIT 3

Where 0.0.0.127 is the destination IP.

If you want my server code, then tell me.

Upvotes: 0

Views: 467

Answers (2)

ensc
ensc

Reputation: 6984

Your valid_ip() functions alters argv[1] so that "127.0.0.1" becomes "127":

    ptr = strtok(ip, ".");

Use a prototype with const modifiers (e.g. int valid_port(char const *port)) and implement it so that it compiles without errors.

Upvotes: 0

Erlkoenig
Erlkoenig

Reputation: 2754

You have to set sin_family, i.e.:

servaddr.sin_family = AF_INET;

Also, use inet_aton instead of inet_addr as it allows proper error handling:

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>

int main (int argc, char* argv []) {
    if (argc < 3) {
        fprintf (stderr, "Usage: %s HOST PORT\n", argv [0]);
        return 1;
    }

    int connSock = socket(AF_INET, SOCK_STREAM, 0);
    if (connSock == -1) {
        perror ("Error creating TCP socket");
        return 1;
    }

    struct sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;

    if(inet_aton(argv[1], &servaddr.sin_addr) != 1) {
        fputs ("Invalid IP address", stderr);
        return 1;
    }
    servaddr.sin_port = htons (atoi(argv[2]));

    if (connect (connSock, (struct sockaddr *) &servaddr, sizeof (servaddr)) == -1) {
        perror ("Error connecting");
        close (connSock);
        return 1;
    }

    puts ("Connection successful.");

    close (connSock);
    return 0;
}

Upvotes: 1

Related Questions