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
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
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.
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.
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.
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.
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 !!
Seems the code cant bind to a socket using the code
/*
* Create a UDP socket to use :
*/
s = socket(AF_INET,SOCK_DGRAM,
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;
}
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;
}
ASKER
No Im not, I'll give it a try, I knew there was a WSAshutdown tho :s
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
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),stde rr);
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_REUSEA DDR)");
/*
* 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;
}
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->
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),stde
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,
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_REUSEA
/*
* 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
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
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 !
/*
* Create a UDP socket to use :
*/
s = socket(AF_INET,SOCK_DGRAM,
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 ?
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];
* Numeric IP address :
*/
if ( !inet_addr(host_part,&ap->
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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().