rendered paste body/* secondclient.c: second generation practise C networking program. * this time in two parts, client and server. */#include <inttypes.h>#include <errno.h>#include <netdb.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/types.h>#define MAXLEN 512void usage(char *);void inline printv6ip( const struct sockaddr *const addr) ;void inline printv4ip( const struct sockaddr *const addr) ;//by the dark prince may this code run smoothlyint main(int argc, char *argv[]){ int sockfd, nbuf; //sockfd: our socket file descriptor //nbuf: a return variable for our send and receive functions. int ai_ret; //addrinfo return variable in_port_t port; //port address, to be cast to short at the appropriate time char buf[MAXLEN]; //main buffer for trasnfering. struct addrinfo hints; //hints struct for telling getaddrinfo wha its conditions are struct addrinfo *addri_res, *addri_rp; //addri_res: result pointer which getaddrinfo returns //addri_rp: the pointer used when interacting with addrinfo data struct sockaddr_in srvin; //our trusty socket address. NOTE: not used in code, dispose? //initialization block addri_res = NULL; addri_rp = NULL; bzero(&srvin, sizeof(struct sockaddr_in)); if(argc != 3) { //check for the right number of arguments usage(argv[0]); } //NOTE: host and port are handled by the getaddrinfo function. //fill in the hints. memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; //either ip4 or ip6 hints.ai_socktype = SOCK_STREAM; //TCP likely hints.ai_protocol = PF_UNSPEC; //effectively 0, either ip4 or ip6 if( (ai_ret = getaddrinfo(argv[1], argv[2], &hints, &addri_res)) != 0 ){ fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(ai_ret)); freeaddrinfo(addri_res); exit(1); } //check if the result is null. bail if it is. if( addri_res->ai_addr == NULL ) { printf("No resolved address.\n"); freeaddrinfo(addri_res); exit(0); } //initialize the working pointer and loop through all the results for(addri_rp = addri_res; addri_rp != NULL; addri_rp = addri_rp->ai_next){ //check addr family, print out relevant ip addres if( addri_rp->ai_family == AF_INET ) { puts("Address Family: IPv4"); printv4ip( addri_rp->ai_addr ); struct sockaddr_in *psock = (struct sockaddr_in *) addri_rp->ai_addr; printf("Port: %hu\n", htons(psock->sin_port)); } else if ( addri_rp->ai_family == AF_INET6 ) { puts("Address Family: IPv6"); printv6ip( addri_rp->ai_addr); struct sockaddr_in6 *psock = (struct sockaddr_in6 *) addri_rp->ai_addr; printf("Port: %hu\n", htons(psock->sin6_port)); } else { printf("Address Family: Other\n"); } //check socket type if( addri_rp->ai_socktype == SOCK_STREAM ) { puts("Socket Type: Stream"); } else if( addri_rp->ai_socktype == SOCK_DGRAM ) { puts("Socket Type: Datagram"); } else if( addri_rp->ai_socktype == SOCK_RAW ) { puts("Socket Type: Raw"); } else if( addri_rp->ai_socktype == SOCK_SEQPACKET ) { puts("Socket Type: Sequential" ); } else if( addri_rp->ai_socktype == SOCK_RDM ) { puts("Socket Type: Reliable Datagram" ); } else { puts("Socket Type: Unknown"); } //check protocol type if( addri_rp->ai_protocol == PF_UNIX ) { puts("Protocol: Unix Domain"); } else if( addri_rp->ai_protocol == PF_INET ) { puts("Protocol: IPv4"); } else if( addri_rp->ai_protocol == PF_INET6 ) { puts("Protocol: IPv6"); } else if( addri_rp->ai_protocol == PF_IPX ) { puts("Protocol: IPX"); } else if( addri_rp->ai_protocol == PF_NETLINK ) { puts("Protocol: Kernel User Interface Device"); } else if( addri_rp->ai_protocol == PF_X25 ) { puts("Protocol: X25"); } else if( addri_rp->ai_protocol == PF_APPLETALK ) { puts("Protocol: AppleTalk"); } else if( addri_rp->ai_protocol == PF_PACKET ) { puts("Protocol: Low Level Packet"); } else if( addri_rp->ai_protocol == PF_UNSPEC ) { puts("Protocol: IPv*"); } else if( addri_rp->ai_protocol == PF_NETROM ) { puts("Protocol: Amateur Radio NetROM"); } else { printf("Protocol: %d\n", addri_rp->ai_protocol); } //NOTE: oddly returns NetROM, figure out why, and possibly dispose of block. printf("Creating socket... "); if( (sockfd = socket(addri_rp->ai_family, addri_rp->ai_socktype, addri_rp->ai_protocol) ) == -1 ) { printf("Failed.\n"); exit(1); } printf("Successful\n"); printf("Connecting... "); ai_ret = 0; if( ( ai_ret = connect(sockfd, addri_rp->ai_addr, addri_rp->ai_addrlen)) != -1) { puts("Success.\n"); break; } else { printf("Failed\n"); perror(strerror(errno)); close(sockfd); } } //clean up time ^_^ freeaddrinfo(addri_res); close(sockfd); return 0;}void usage(char *prog) { printf("%s host\n", prog); exit(1);}void inline printv4ip( const struct sockaddr *const addr) { //takes the given sockaddr pointer, turns it into a sockaddr_in pointer, //grabs the sin_addr member from it, and grabs the submember s_addr, //and changes i to its pointer before turning it into an unsigned char to //assign to the pointer var. uint8_t *const poctet = (uint8_t *) &(((struct sockaddr_in *) addr)->sin_addr.s_addr); printf("Address: %hhu.%hhu.%hhu.%hhu\n",*poctet, *(poctet + 1), *(poctet + 2), *(poctet + 3)); return;} void inline printv6ip( const struct sockaddr *const addr) { //see large comment for similar line in printv4ip uint16_t *const poct = (uint16_t *) &( ( (struct sockaddr_in6 *) addr)->sin6_addr.s6_addr); printf("Address: %hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx\n", *poct, *(poct + 1),*(poct + 2),*(poct + 3),*(poct + 4),*(poct + 5),*(poct + 6),*(poct + 7)); return;}