用C语言兑现已知hostname返回DNS header和IP地址
用C语言实现已知hostname返回DNS header和IP地址
// standard includes
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
// networking includes
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#define STUDENT_SPECIFY 0
#define DNS_IP "8.8.8.8"
char* resolve_name(char* hostname);
void retrieve_data(char* inetaddr, char* hostname, char* requestpath);
void convert_host_format(unsigned char* dns, unsigned char* host);
void hexdump(char* data, int sz);
int main(int argc, char** argv) {
if (argc != 2) err(1, "Example: %s www.ietf.org/rfc/rfc1149.txt", argv[0]);
char path[80];
strcpy(path, strchr(argv[1], '/'));
char host[80];
strcpy(host, strtok(argv[1], "/"));
char* host_ip = resolve_name(host);
retrieve_data(host_ip, host, path);
printf("\n\n");
return 0;
}
void convert_host_format(unsigned char* dns, unsigned char* host) {
int lock = 0, i;
strcat((char*) host, ".");
for (i = 0; i < (int) strlen((char*) host); i++) {
if (host[i] == '.') {
*dns++ = i - lock;
for (; lock < i; lock++) {
*dns++ = host[lock];
}
lock++; //or lock=i+1;
}
}
*dns++ = '\0';
}
void hexdump(char* data, int sz) {
int i;
for (i = 0; i < sz; i++) {
printf("%02hhx", *(data + i));
if ((i+1) % 16 == 0) {
printf("\n");
} else if (i != (sz - 1)) {
printf(":");
}
}
}
#define STRING ""
#define VALUE 0
char* resolve_name(char* hostname) {
int socketid;
struct sockaddr_in socket_info;
char* return_ip = malloc(sizeof(char) * 18);
if ((socketid = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) err(1, "socket(2) failed");
// configure the socket_info
memset((char *) &socket_info, 0, sizeof(socket_info));
socket_info.sin_family = AF_INET;
socket_info.sin_port = htons(53);
if (inet_aton(DNS_IP, &socket_info.sin_addr) == 0) err(1, "inet_aton(3) failed");
char buffer[2046]; // input and output buffer
// header
uint16_t header[6] = { // [NB:1]
VALUE, // 2 byte ID: this is arbitrary
VALUE, // flags
VALUE, // number of questions
VALUE, // number of answers
VALUE, // number of nameservers
VALUE // number of additional records
};
char converted_name[80];
convert_host_format(converted_name, hostname);