HTTP Client ver 0.24
HTTP Client ver 0.23 - Shammerismの内容に、nslookup sample C version - 関数版 - Shammerismの関数を加えた。ようやく、IP アドレスでもホスト名でもアクセスできる状態になった。
#include <ctype.h> #include <err.h> #include <netdb.h> #include <regex.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> int is_valid_ipaddr(char v[]){ regex_t preg; int regcompresult, regexecresult; regcompresult = regcomp(&preg, "^([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]).([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]).([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]).([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$", REG_NOSUB | REG_EXTENDED | REG_NEWLINE); if( regcompresult == 0 ){ size_t nmatch = 0; regmatch_t pmatch[nmatch]; regexecresult = regexec(&preg, v, nmatch, pmatch, 0); if( regexecresult == 0 ){ printf("%s is valid IP address.\n", v); } else { printf("%s is not valid IP address.\n", v); } } return regexecresult; } char * get_ip_addr(char * hostname){ char temp[17] = {'0'}; struct addrinfo hints, *res, *res0; int error; void * ptr; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(hostname, NULL, &hints, &res0); if( error ) { errx(1, "%s", gai_strerror(error)); } int i = 0; for( res = res0 ; res ; res = res->ai_next ) { switch(res->ai_family) { case AF_INET: ptr = &(((struct sockaddr_in *)res->ai_addr)->sin_addr); inet_ntop(res->ai_family, ptr, temp, sizeof(temp)); break; case AF_INET6: // Don't use IPv6 address. // ptr = &(((struct sockaddr_in6 *)res->ai_addr)->sin6_addr); // inet_ntop(res->ai_family, ptr, temp, sizeof(temp)); continue; } i++; } freeaddrinfo(res0); char * ip = (char *)malloc(strlen(temp) + 1); strcpy(ip, temp); return ip; } void send_request(int sock, char * ipaddr) { send(sock, "GET / HTTP/1.1\r\n", strlen("GET / HTTP/1.1\r\n"), 0); send(sock, "Host: ", strlen("Host: "), 0); send(sock, ipaddr, strlen(ipaddr), 0); send(sock, "\r\n", strlen("\r\n"), 0); send(sock, "Connection: close\r\n", strlen("Connection: close\r\n"), 0); send(sock, "\r\n", strlen("\r\n"), 0); } void write_request(int sock, char * ipaddr){ char send_buf[256]; sprintf(send_buf, "GET / HTTP/1.1\r\n"); write(sock, send_buf, strlen(send_buf)); sprintf(send_buf, "Host: %s\r\n", ipaddr); write(sock, send_buf, strlen(send_buf)); sprintf(send_buf, "Connection: close\r\n"); write(sock, send_buf, strlen(send_buf)); sprintf(send_buf, "\r\n"); write(sock, send_buf, strlen(send_buf)); } void fprintf_request(FILE * fp, char * ipaddr){ // Buffering OFF -> _IONBF setvbuf(fp, NULL, _IONBF, 0); fprintf(fp, "GET / HTTP/1.1\r\n"); fprintf(fp, "Host: %s\r\n", ipaddr); fprintf(fp, "Connection: close\r\n"); fprintf(fp, "\r\n"); } void recv_response(int sock){ int bytes_read; char response[256]; while(1) { bzero(response, sizeof(response)); bytes_read = recv(sock, response, sizeof(response), 0); if( bytes_read > 0 ){ printf("%s", response); } else { break; } } } void read_response(int sock){ while (1) { char response[256]; int read_size; read_size = read(sock, response, sizeof(response)); if( read_size > 0 ){ // 1 means Standard out write(1, response, read_size); } else { break; } } } void fgets_response(FILE *fp){ while (1) { char response[256]; if ( fgets(response, sizeof(response), fp) == NULL ) { break; } printf("%s", response); } } int main(int argc, char* args[]){ if( argc == 2 ){ char* destination_ip; int valid_argument = is_valid_ipaddr(args[1]); if( valid_argument == 0 ) { destination_ip = args[1]; } else { destination_ip = get_ip_addr(args[1]); } // HTTP Client int sock; struct sockaddr_in destination_addr; unsigned short destination_port = 80; sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if( sock < 0 ){ printf("Socket open error.\n"); exit(1); } memset(&destination_addr, 0, sizeof(destination_addr)); destination_addr.sin_family = AF_INET; destination_addr.sin_addr.s_addr = inet_addr(destination_ip); destination_addr.sin_port = htons(destination_port); if( connect(sock, (struct sockaddr *)&destination_addr, sizeof(destination_addr)) < 0 ){ printf("Connect error, destination IP addr is %s.\n", destination_ip); exit(2); } write_request(sock, destination_ip); read_response(sock); close(sock); } else { printf("Usage: %s %s\n", args[0], "Destination_IP"); printf(" %s %s\n", args[0], "Destination_Hostname"); } return 0; }