Link to home
Start Free TrialLog in
Avatar of Kevin_R
Kevin_R

asked on

inet-aton and Visual C 6

Can anyone help me out with this.

We've been trying to compile a piece of code we wrote (me and a few freinds) and when we try to build it we get the following error.

mkaddr.obj : error LNK2001: unresolved external symbol _inet_aton

Anyone know how to cure this ?

Thanks

Kevin
Avatar of grg99
grg99

_inet_aton converts 123.321.122.134 to binary format, it's in some internet related library most probably.

Use whatever library listing utility you have , like "LIB", or "TDUMP" to look thru the libraries for that name.

Another way, write your own inet_aton, it's only about 2 lines if you use sscanf().

Avatar of Kevin_R

ASKER

You wouldnt havd the code for that would you ?
There is no inet_aton() function (although there is an inet_ntoa() ) on Windows, which I assume you are using based on the link error.

Use inet_addr() instead. This functions is in the ws2_32.lib library, include winsock2.h .

From MSDN:

inet_addr

The inet_addr function converts a string containing an (Ipv4) Internet Protocol dotted address into a proper address for the IN_ADDR structure.

unsigned long inet_addr(
  const char* cp
);

Parameters
cp [in] Null-terminated character string representing a number expressed in the Internet standard ".'' (dotted) notation.

Return Values
If no error occurs, inet_addr returns an unsigned long value containing a suitable binary representation of the Internet address given. If the string in the cp parameter does not contain a legitimate Internet address, for example if a portion of an "a.b.c.d" address exceeds 255, then inet_addr returns the value INADDR_NONE.

See this:

http://publib16.boulder.ibm.com/pseries/en_US/libs/basetrf1/inet_aton.htm

The library needed is libc.a

U have to include:
#include <arpa/inet.h>
But not doing this would give u a compilation error.
> You wouldnt havd the code for that would you ?

Here's a stab at it:

int inet_aton(const char *ipaddr) {
  int a, b, c, d;
  int num = sscanf(ipaddr, "%d.%d.%d.%d", &a, &b, &c, &d);

  if (num != 4) return INADDR_NONE;
  if ((a < 0 || a > 255) ||
      (b < 0 || b > 255) ||
      (c < 0 || c > 255) ||
      (d < 0 || d > 255) )
      return INADDR_NONE;

  return a << 24 | b << 16 | c << 8 | d;
}

This puts it in network order.
Avatar of Kevin_R

ASKER

Ok, narrowed ir down using inet_addr
Seems the code cant bind to a socket using the code

    /*
     * Create a UDP socket to use :
     */
    s = socket(AF_INET,SOCK_DGRAM,0);
    if ( s == -1 )
        bail("socket()");

also declaring winsock2.h as an include creates over 60 errors !!
On Windows, you must call WSAStartup() first, are you calling this?

Here is a function I use to do this:

int wsaStartup() {
  WSADATA wsaData;
  WORD wVersionRequested;
  int err;
  wVersionRequested = MAKEWORD( 2, 0 );
  err = WSAStartup( wVersionRequested, &wsaData );
  return err;
}

Avatar of Kevin_R

ASKER

No Im not, I'll give it a try, I knew there was a WSAshutdown tho :s
Avatar of Kevin_R

ASKER

Ok, I've added it and the error ha gone but now it just says "press any key to continue" on pressing the program closes, so it still isnt runnint correclty
Avatar of Kevin_R

ASKER

Ok, here's the code we have, it isnt really that much but we're totally stumped.  The code compiles great on Linux but windows just wont take it !
Most of the Linux Headers are commented out tho !

/* mkaddr.c
 *
 * Make a socket address :
 */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <winsock.h>
/*
 * Create an AF_INET Address:
 *
 * ARGUMENTS:
 *  1.  addr    Ptr to area
 *              were address is
 *              to be placed.
 *  2.  addrlen Ptr to int that
 *              will hold the final
 *              address length.
 *  3.  str_addr The input string
 *              format hostname, and
 *              port.
 *  4.  protocol The input string
 *              indicating the
 *              protocol being used.
 *              NULL implies "tcp".
 * RETURNS:
 *  0   Success.
 *  -1  Bad host part.
 *  -2  Bad port part.
 *
 * NOTES:
 *  "*" for the host portion of the
 *  address implies INADDR_ANY.
 *
 *  "*" for the port portion will
 *  imply zero for the port (assign
 *  a port number.)
 *
 * EXAMPLES:
 *  "www.lwn.net:80"
 *  "localhost:telnet"
 *  "*:21"
 *  "*:*"
 *  "ftp.redhat.com:ftp"
 *  "sunsite.unc.edu"
 *  "sunsite.unc.edu:*"
 */
int
mkaddr(void *addr,
  int *addrlen,
  char *str_addr,
  char *protocol) {

    char *inp_addr = strdup(str_addr);
    char *host_part = strtok(inp_addr,":");
    char *port_part = strtok(NULL,"\n");
    struct sockaddr_in *ap =
        (struct sockaddr_in *) addr;
    struct hostent *hp = NULL;
    struct servent *sp = NULL;
    char *cp;
    long lv;

    /*
     * Set input defaults :
     */
    if ( !host_part )
        host_part = "*";
    if ( !port_part )
        port_part = "*";
    if ( !protocol )
        protocol = "tcp";

    /*
     * Initialize the address structure :
     */
    memset(ap,0,*addrlen);
    ap->sin_family = AF_INET;
    ap->sin_port = 0;
    ap->sin_addr.s_addr = INADDR_ANY;

    /*
     * Fill in the host address :
     */
    if ( strcmp(host_part,"*") == 0 )
        ;   /* Leave as INADDR_ANY */
    else if ( isdigit(*host_part) ) {
        /*
         * Numeric IP address :
         */
        if ( !inet_addr(host_part,&ap->sin_addr) )
            return -1;
    } else {
        /*
         * Assume a host name :
         */
        hp = gethostbyname(
            host_part);
        if ( !hp )
            return -1;
        if ( hp->h_addrtype != AF_INET )
            return -1;
        ap->sin_addr =
            * (struct in_addr *)
            hp->h_addr_list[0];
    }

    /*
     * Process an optional port # :
     */
    if ( !strcmp(port_part,"*") )
        ; /* Leave as wild (zero) */
    else if ( isdigit(*port_part) ) {
        /*
         * Process numeric port # :
         */
        lv = strtol(port_part,&cp,10);
        if ( cp != NULL && *cp )
            return -2;
        if ( lv < 0L || lv >= 32768 )
            return -2;
        ap->sin_port = htons(
            (short)lv);
    } else {
        /*
         * Lookup the service :
         */
        sp = getservbyname(
            port_part,
            protocol);
        if ( !sp )
            return -2;
        ap->sin_port =
            (short) sp->s_port;
    }

    /* Return address length */
    *addrlen = sizeof *ap;

    free(inp_addr);
    return 0;
}





/* gquotes.c:
 *
 * Get datagram stock market
 * quotes from UDP broadcast :
 */
#include <stdio.h>
//#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <winsock.h>
#include <socket.h>
//#include <signal.h>
//#include <sys/types.h>
//#include <sys/socket.h>
//#include <netinet/in.h>
//#include <arpa/inet.h>

#ifndef TRUE
#define TRUE    1
#define FALSE   0
#endif

extern int mkaddr(
    void *addr,
    int *addrlen,
    char *str_addr,
    char *protocol);

/*
 * This function reports the error and
 * exits back to the shell :
 */
static void
bail(const char *on_what) {
    fputs(strerror(errno),stderr);
    fputs(": ",stderr);
    fputs(on_what,stderr);
    fputc('\n',stderr);
    exit(1);
}

int
main(int argc,char **argv) {
    int z;
    int x;
    struct sockaddr_in adr;     /* AF_INET */
    int len_inet;               /* length  */
    int s;                       /* Socket */
    char dgram[512];        /* Recv buffer */
    static int so_reuseaddr = TRUE;
    static char
        *bc_addr = "192.168.10.255:9097";

    int      MAClen=0,IPlen=0;
    char MAC1[80],IP1[80],temp1[80];
    char *IPPtr,*MACPtr;

      int wsaStartup();{
            WSADATA wsaData;
            WORD wVersionRequested;
            int err;
            wVersionRequested = MAKEWORD (2 , 0);
            err = WSAStartup( wVersionRequested, &wsaData);
            return err;
      }

    /*
     * Use a server address from the command
     * line, if one has been provided.
     * Otherwise, this program will default
     * to using the arbitrary address
     * 127.0.0.23 :
     */
    if ( argc > 1 )
        /* Broadcast address : */
        bc_addr = argv[1];

    /*
     * Create a UDP socket to use :
     */
    s = socket(AF_INET,SOCK_DGRAM,0);
    if ( s == -1 )
        bail("socket()");

    /*
     * Form the broadcast address :
     */
    len_inet = sizeof adr;

    z = mkaddr(&adr,
        &len_inet,
        bc_addr,
        "udp");

    if ( z == -1 )
        bail("Bad broadcast address");
printf("address formed sizeof = %d\n",sizeof adr);

    /*
     * Allow multiple listeners on the
     * broadcast address :
     */
    z = setsockopt(s,
        SOL_SOCKET,
        SO_REUSEADDR,
        &so_reuseaddr,
        sizeof so_reuseaddr);
   
    if ( z == -1 )
       bail("setsockopt(SO_REUSEADDR)");

    /*
     * Bind our socket to the broadcast address:
     */
    z = bind(s,
        (struct sockaddr *)&adr,
        len_inet);

    if ( z == -1 )
        bail("bind(2)");

    for (;;) {
for(z=0;z<512;z++)
{

dgram[z]=0x0;
 
}
      z=0;
for(z=0;z<80;z++)
{
IP1[z]=0x0;
MAC1[z]=0x0;
temp1[z]=0x0;
}
         /*
         * Wait for a broadcast message :
         */
        z = recvfrom(s,            /* Socket */
            dgram,       /* Receiving buffer */
            sizeof dgram,/* Max rcv buf size */
            0,          /* Flags: no options */
            (struct sockaddr *)&adr, /* Addr */
            &x);       /* Addr len, in & out */

//printf(" dgram =\n%s",dgram);
      IPPtr=strstr(dgram,"[");
      *IPPtr++;
      strxfrm(temp1,IPPtr,80);
      strxfrm(IP1,IPPtr,8);
      

      MACPtr=strstr(temp1,"[");
      *MACPtr++;
      strxfrm(MAC1,MACPtr,12);


      printf("\nIP ADDRESS :%s\n",IP1);
      printf("MAC ADDRESS :%s\n",MAC1);
        if ( z <  -1)
            bail("recvfrom(2)"); /* else err */

      fwrite(dgram,93,1,stdout);
       putchar('\n');

      fflush(stdout);
    }

    return 0;
}
1. You are getting the "press any key to continue" because wsastartup is not being called .....

remove this part and declare your wsaStartup outside main and call it from within main

int wsaStartup();{
          WSADATA wsaData;
          WORD wVersionRequested;
          int err;
          wVersionRequested = MAKEWORD (2 , 0);
          err = WSAStartup( wVersionRequested, &wsaData);
          return err;
     }
becomes ....

int wsaStartup(){
          WSADATA wsaData;
          ............................
     }
and
int
main(int argc,char **argv) {
........................
char *IPPtr,*MACPtr;
wsaStartup ();
........................
}

2. before using strstr, strxfrm, etc on dgram make sure strlen(dgram) != 0
3. if you are using MSVC make sure you remove /GZ flag


Avatar of Kevin_R

ASKER

Ok the below is where the problems seem to occur

    /*
     * Create a UDP socket to use :
     */
    s = socket(AF_INET,SOCK_DGRAM,0);
    if ( s == -1 )
        bail("socket()");

    /*
     * Form the broadcast address :
     */
    len_inet = sizeof adr;

    z = mkaddr(&adr,
        &len_inet,
        bc_addr,
        "udp");

    if ( z == -1 )
        bail("Bad broadcast address");
printf("address formed sizeof = %d\n",sizeof adr);




The port that s is set to is 1992 and the broadvast address is set to 192.168.10.255 however it always exits at the "Bad Broadcast Address" part.

We're getting really frustrated now, worked on this for 3 days solid and cant understand why it isnt working !
I tried compiling and that part seems to work fine, what is the value of z before it fails ?
Avatar of Kevin_R

ASKER

The value is -1 which is why it fails.  However ive discovered in the mkaddr.c file this

* Numeric IP address :
         */


        if ( !inet_addr(host_part,&ap->sin_addr) )   <------------------------------------      If this line is messed with, the value of z changes to 1 or 0 therefore im guessing this line is the problem, I guess the conversion isnt happening correctly ?!?!
           



return -1;
    } else {
        /*
         * Assume a host name :
         */
        hp = gethostbyname(
            host_part);
        if ( !hp )
            return -1;
        if ( hp->h_addrtype != AF_INET )
            return -1;
        ap->sin_addr =
            * (struct in_addr *)
            hp->h_addr_list[0];
ASKER CERTIFIED SOLUTION
Avatar of Netminder
Netminder

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial