Thread: problem trying to compile beej sample program

  1. #1
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391

    problem trying to compile beej sample program

    Hey folks!

    I am trying to compile showip.c in section 5.1 of Beej's Networking Tutorial.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <winsock.h>
    
    #define INET6_ADDRSTRLEN 30  <=== I made 30 up to get rid of a compile error
    
    struct addrinfo {
    int ai_flags; // AI_PASSIVE, AI_CANONNAME, etc.
    int ai_family; // AF_INET, AF_INET6, AF_UNSPEC
    int ai_socktype; // SOCK_STREAM, SOCK_DGRAM
    int ai_protocol; // use 0 for "any"
    size_t ai_addrlen; // size of ai_addr in bytes
    struct sockaddr *ai_addr; // struct sockaddr_in or _in6
    char *ai_canonname; // full canonical hostname
    struct addrinfo *ai_next; // linked list, next node
    };
    
    // (IPv6 only--see struct sockaddr_in and struct in_addr for IPv4)
    struct sockaddr_in6 {
    u_int16_t sin6_family; // address family, AF_INET6
    u_int16_t sin6_port; // port number, Network Byte Order
    u_int32_t sin6_flowinfo; // IPv6 flow information
    struct in6_addr sin6_addr; // IPv6 address
    u_int32_t sin6_scope_id; // Scope ID
    };
    
    struct in6_addr {
    unsigned char s6_addr[16]; // IPv6 address
    };
    
    int main(int argc, char *argv[])
    {
    	struct addrinfo hints, *res, *p;
    	int status;
    	char ipstr[INET6_ADDRSTRLEN];
    
    	WSADATA wsaData; // if this doesn't work
    	//WSAData wsaData; // then try this instead
    	// MAKEWORD(1,1) for Winsock 1.1, MAKEWORD(2,0) for Winsock 2.0:
    	
    	if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0) {
    	fprintf(stderr, "WSAStartup failed.\n");
    	exit(1);
    	}
    
    	if (argc != 2) {
    	fprintf(stderr,"usage: showip hostname\n");
    	return 1;
    	}
    
    	memset(&hints, 0, sizeof hints);
    	hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
    	hints.ai_socktype = SOCK_STREAM;
    
    	if ((status = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) {
    	fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
    	return 2;
    	}
    
    	printf("IP addresses for %s:\n\n", argv[1]);
    
    	for(p = res;p != NULL; p = p->ai_next) {
    		void *addr;
    		char *ipver;
    
    		// get the pointer to the address itself,
    		// different fields in IPv4 and IPv6:
    		if (p->ai_family == AF_INET) { // IPv4
    			struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
    			addr = &(ipv4->sin_addr);
    			ipver = "IPv4";
    		} else { // IPv6
    			struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
    			addr = &(ipv6->sin6_addr);
    			ipver = "IPv6";
    		}
    
    	// convert the IP to a string and print it:
    	inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
    	printf(" %s: %s\n", ipver, ipstr);
    	}
    
    	freeaddrinfo(res); // free the linked list
    
    	return 0;
    }
    And here are the compiler errors:
    ------ Rebuild All started: Project: networking, Configuration: Debug Win32 ------
    Deleting intermediate and output files for project 'networking', configuration 'Debug|Win32'
    Compiling...
    networking.c
    c:\programs\networking\networking.c(20) : error C2016: C requires that a struct or union has at least one member
    c:\programs\networking\networking.c(20) : error C2061: syntax error : identifier 'u_int16_t'
    c:\programs\networking\networking.c(21) : error C2061: syntax error : identifier 'sin6_port'
    c:\programs\networking\networking.c(21) : error C2059: syntax error : ';'
    c:\programs\networking\networking.c(22) : error C2061: syntax error : identifier 'sin6_flowinfo'
    c:\programs\networking\networking.c(22) : error C2059: syntax error : ';'
    c:\programs\networking\networking.c(23) : error C2079: 'sin6_addr' uses undefined struct 'in6_addr'
    c:\programs\networking\networking.c(24) : error C2061: syntax error : identifier 'sin6_scope_id'
    c:\programs\networking\networking.c(24) : error C2059: syntax error : ';'
    c:\programs\networking\networking.c(25) : error C2059: syntax error : '}'
    c:\programs\networking\networking.c(55) : warning C4013: 'getaddrinfo' undefined; assuming extern returning int
    c:\programs\networking\networking.c(56) : warning C4013: 'gai_strerror' undefined; assuming extern returning int
    c:\programs\networking\networking.c(74) : error C2037: left of 'sin6_addr' specifies undefined struct/union 'sockaddr_in6'
    c:\programs\networking\networking.c(79) : warning C4013: 'inet_ntop' undefined; assuming extern returning int
    c:\programs\networking\networking.c(83) : warning C4013: 'freeaddrinfo' undefined; assuming extern returning int
    Build log was saved at "file://c:\programs\networking\Debug\BuildLog.htm"
    networking - 11 error(s), 4 warning(s)
    ========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
    I am using Win XP, I've added #include <winsock.h>, and I've added wsock32.lib to the project.

    I think there are more structures that need to be added to the program.

    Has anyone managed to compile the beej programs successfully in Win XP, using VC++? I would really like to liase with you.

    Thanks in advance.

    EDIT: I can see line numbers alongside the code in VC++ 2008. Is there a way to copy the code and the line numbers, so I can paste it into this thread? The line numbers help people to see where the errors are.

    EDIT #2: This program was written in linux, and here were the headers, which I removed and replaced with winsock.h, as per instructions:

    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    Last edited by happyclown; 02-25-2009 at 07:53 AM.
    OS: Linux Mint 13(Maya) LTS 64 bit.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    u_int16_t is in stdint.h, I think? In any event, you may have to use the Microsoft-specific 16-bit and 32-bit integer types.

    Edit: Wait, I think it's uint16_t in stdint.h. Either way, you should go to MSDN and see what it is for MS.

  3. #3
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Thanks tabstop.

    I'll give MSDN a go.

    I might also try to install cygwin or linux for use with this tutorial.
    OS: Linux Mint 13(Maya) LTS 64 bit.

  4. #4
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Well, I've managed to get gcc running in Cygwin, running in Win XP. And I also installed Notepad++ too!

    All the previous error messages from VC++ have gone, and are now replaced by fewer errors:

    networking.c:26: error: field `sin6_addr' has incomplete type
    networking.c: In function `main':
    networking.c:40: error: `WSADATA' undeclared (first use in this function)
    networking.c:40: error: (Each undeclared identifier is reported only once
    networking.c:40: error: for each function it appears in.)
    networking.c:40: error: parse error before "wsaData"
    networking.c:44: error: `wsaData' undeclared (first use in this function)
    So I don't think these errors have to do with trying to make a linux program work in XP, but rather error with the code itself?

    I am now using the original include files:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    The author had provided about 5 structures, but didn't put any into this particular piece of code(I don't know why not), so I put 3 in (above main, in the first post), to get rid of some error messages. I don't even know if I am supposed to do this.

    I don't know why the author is providing structures, and then not using them in the sample code.

    PS: Cygwin is an amazing program, if anyone is interested, here are instructions on how to install Cygwin, then GCC, then X Windows(which I have not done yet) on Windows XP.

    http://www2.warwick.ac.uk/fac/sci/mo.../cygwin/part1/

    EDIT: You can get Cygwin here:

    http://www.cygwin.com/

    The total download is about 300 Mb, and 1 hour for cygwin to install gcc(+lots of other programs you will never need ie. ruby, perl, python, libraries etc.) If you know exactly what you are doing, you can probably select what packages you need). It's like having a linux console in win XP.

    If you install X Windows, that might add a few more hundred megabytes.
    Last edited by happyclown; 02-26-2009 at 08:39 PM.
    OS: Linux Mint 13(Maya) LTS 64 bit.

  5. #5
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Well, I've gone through the tutorial up to this sample program, and there is no code or structure with "WSADATA" in it, which leads me to believe there may be a header with this structure, which has not been declared in the sample program.

    Time to fire up Google!
    OS: Linux Mint 13(Maya) LTS 64 bit.

  6. #6
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Code:
    WSADATA wsaData; // if this doesn't work
    //WSAData wsaData; // then try this instead
    // MAKEWORD(1,1) for Winsock 1.1, MAKEWORD(2,0) for Winsock 2.0:
    if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0) {
    fprintf(stderr, "WSAStartup failed.\n");
    exit(1);
    }
    Ok, I included the above code because I was using winsock.h, when compiling in XP, as per instructions. I forgot to remove it when I was using gcc in Cygwin!

    So after removing it, here is the gcc error message:

    Code:
    networking.c:26: error: field `sin6_addr' has incomplete type
    One last hurdle to go!

    *fingers crossed*
    OS: Linux Mint 13(Maya) LTS 64 bit.

  7. #7
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Well, a few hours on MSDN rewarded me with the correct #include files, which results in the program compiling in VC++ 2008 with no errors or warnings.

    Code:
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    
    int main(int argc, char *argv[])
    {
    
    	WSADATA wsaData; // if this doesn't work
    
    	struct addrinfo hints, *res, *p;
    	int status;
    	char ipstr[INET6_ADDRSTRLEN];
    	if (argc != 2) {
    	fprintf(stderr,"usage: showip hostname\n");
    	return 1;
    	}
    
    		//WSAData wsaData; // then try this instead
    	// MAKEWORD(1,1) for Winsock 1.1, MAKEWORD(2,0) for Winsock 2.0:
    	if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0) {
    	fprintf(stderr, "WSAStartup failed.\n");
    	exit(1);
    	}
    	
    	memset(&hints, 0, sizeof hints);
    	hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
    	hints.ai_socktype = SOCK_STREAM;
    	if ((status = getaddrinfo(argv[1], NULL, &hints, &res)) != 0) {
    	fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
    	return 2;
    	}
    	printf("IP addresses for %s:\n\n", argv[1]);
    	for(p = res;p != NULL; p = p->ai_next) {
    	void *addr;
    	char *ipver;
    	// get the pointer to the address itself,
    	// different fields in IPv4 and IPv6:
    	if (p->ai_family == AF_INET) { // IPv4
    	struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
    	addr = &(ipv4->sin_addr);
    	ipver = "IPv4";
    	} else { // IPv6
    	struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
    	addr = &(ipv6->sin6_addr);
    	ipver = "IPv6";
    	}
    	// convert the IP to a string and print it:
    	inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
    	printf(" %s: %s\n", ipver, ipstr);
    	}
    	freeaddrinfo(res); // free the linked list
    
    	WSACleanup();
    
    	return 0;
    }
    This is how it is supposed to work, quoted straight from the guide:
    Code:
    $ showip www.example.net
    IP addresses for www.example.net:
    IPv4: 192.0.2.88
    $ showip ipv6.example.com
    IP addresses for ipv6.example.com:
    IPv4: 192.0.2.101
    IPv6: 2001:db8:8c00:22::171
    But when I try to run it on my machine, a window with a white cross in a red circle pops up with the message:

    The procedure entry point inet_ntop could not be located in the dynamic link library WS2_32.dll
    A search on MSDN shows that inet_ntop is only supported by Vista and later, so [EDIT]: is there an equivalent function for XP?

    http://msdn.microsoft.com/en-us/libr...43(VS.85).aspx

    Time to fire up google again...

    EDIT: For those who don't know it, you need to link with ws2_32.lib for the program to compile.
    Last edited by happyclown; 02-28-2009 at 11:09 PM. Reason: added WSADATA wsaData; WSAStartup; WSACleanup(); as per author's instructions for Windows
    OS: Linux Mint 13(Maya) LTS 64 bit.

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Why not just implement it yourself? It's not the most complicated thing in the world...
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. problem with sample program
    By brabo in forum C Programming
    Replies: 10
    Last Post: 05-29-2008, 04:32 PM
  2. Replies: 4
    Last Post: 05-25-2008, 12:31 AM
  3. newbie: steps to create and compile c program in SUSE
    By gemini_shooter in forum Linux Programming
    Replies: 12
    Last Post: 06-22-2005, 06:35 PM
  4. Some Problem With My Program
    By Americano in forum C Programming
    Replies: 5
    Last Post: 10-18-2003, 01:58 AM
  5. Weird problem, please try compile
    By Nutshell in forum C Programming
    Replies: 2
    Last Post: 01-26-2003, 09:00 PM