Я пытаюсь отправить заголовок DNS и вопрос в сокет UDP.Я уже вызвал следующую команду для установления соединения: socket(PF_INET, SOCK_DGRAM, 0)
, inet_aton(temp, &servAddr.sin_addr)
с использованием порта 53 и connect(sock, (const sockaddr*) &servAddr, sizeof(servAddr))
.
У меня проблема с написанием сообщения, которое включает в себя заголовок и вопрос DNS-запроса.Пока что моя структура заголовка DNS выглядит следующим образом:
struct DNS_Header {
uint16_t id;
struct {
uint8_t rd: 1; // recursion desired
uint8_t tc: 1; // message was truncated
uint8_t aa: 1; // authoritative answer
uint8_t opcode: 4; // query type
// 0 a standard query (QUERY); 1 an inverse query (IQUERY);
// 2 a server status request (STATUS);
// 3 - 15 reserved for futre use
uint8_t qr: 1; // query(0) or response (1)
uint8_t rcode: 4; // response code
// 0: No error condition; 1:Format error; 2:Server failure;
// 3: Name Error (authoritative server, name doesn't exist)
// 4: Not implemented; 5: Refused
uint8_t z: 3; // reserved for future use. Must be zero
uint8_t ra: 1; // recursion
} flags;
uint16_t gdcount;
uint16_t ancount;
uint16_t nscount;
uint16_t arcount;
};
Я создаю заголовок запроса DNS:
packetHeader.id = htons(1337);
packetHeader.flags.rd = 0;
packetHeader.flags.tc = 0;
packetHeader.flags.aa = 0;
packetHeader.flags.opcode = htons(0);
packetHeader.flags.qr = 0;
packetHeader.flags.rcode = htons(0);
packetHeader.flags.z = htons(0);
packetHeader.flags.ra = 0;
packetHeader.gdcount = htons(1);
packetHeader.ancount = htons(0);
packetHeader.nscount = htons(0);
packetHeader.arcount = htons(0);
Я знаю, что мне нужно изменить имя хоста на метку / данныеформат для части имени вопроса DNS.Я сделал это следующим образом:
static const char* const hex = "0123456789ABCDEF";
hostname.push_back(' ');
int len = hostname.length();
int segCount = 0;
std::vector<std::string> storage;
std::string temp = "";
for (int i = 0; i < len; i++) {
if (hostname[i] == '.' || hostname[i] == ' ') {
storage.push_back(std::to_string(0));
storage.push_back(std::to_string(segCount));
storage.push_back(temp);
// reset
segCount = 0;
temp = "";
continue;
}
const unsigned char c = hostname[i];
std::cout << c << " : " << hex[c >> 4] << " " << hex[c & 15] << std::endl;
temp.push_back(hex[c >> 4]);
temp.push_back(hex[c & 15]);
segCount ++;
continue;
}
storage.push_back(std::to_string(0));
storage.push_back(std::to_string(0));
for (int i = 0; i < storage.size(); i++) { qname_labelFormat.append(storage[i]); }
std::cout << "The hex representation of qname TOTAL: " << qname_labelFormat << std::endl
Я собрал все вместе для запроса DNS-запроса, используя структуру DNS_Question.Эта структура не включает имя вопроса DNS-запроса.Я храню имя в переменной: qname_lableFormat
.Посмотрите структуру Вопроса DNS-запроса ниже:
struct DNS_Question {
uint16_t qtype;
uint16_t qclass;
};
Чтобы заполнить структуру DNS_Question, я сделал это следующим образом:
int queryTypeNum = 0;
if (queryType == "A") { queryTypeNum = 1; }
if (queryType == "NS") { queryTypeNum = 2; }
if (queryType == "CNAME") { queryTypeNum = 5; }
if (queryType == "SOA") { queryTypeNum = 6; }
if (queryType == "WKS") { queryTypeNum = 11; }
if (queryType == "PTR") { queryTypeNum = 12; }
if (queryType == "MX") { queryTypeNum = 15; }
if (queryType == "SRV") { queryTypeNum = 33; }
if (queryType == "AAAA") { queryTypeNum = 28; }
if (queryType == "") { queryTypeNum = 1; }
packetQuestion.qtype = htons(queryTypeNum);
std::cout << "QType value set to: " << queryTypeNum << std::endl;
packetQuestion.qclass = htons(1);
После того, как я все это сделал, я используюсокет write(int fd, const void *buf, size_t count);
Я считаю, что именно здесь происходит моя ошибка.Об ошибках не сообщается, но когда я вызываю команду read(int fd, void *buf, size_t count);
, ничего не принимается.Моя команда записи приведена ниже.
int size = sizeof(struct DNS_Header);
size += sizeof(struct DNS_Question);
char *message [size];
int totalSize = 0;
int stringSize = qname_labelFormat.length() + 1;
char* temp = {0};
temp = (char*)qname_labelFormat.c_str();
std::memcpy(message, (struct DNS_Header*)&packetHeader, sizeof(packetHeader));
totalSize = sizeof(struct DNS_Header);
std::memcpy(message + totalSize, (char*)temp, sizeof(qname_labelFormat));
totalSize += sizeof(qname_labelFormat);
std::memcpy(message + totalSize, (struct DNS_Question*)&packetQuestion, sizeof(packetQuestion));
totalSize += sizeof(packetQuestion);
int bytesSent = 0;
if ((bytesSent = write(sock, message, totalSize)) < 0) {
logger->printLog ("write Failed");
std::string error = strerror(errno);
logger->printLog(error);
}
else {
logger->printLog ("write was successful");
}
Если кто-то сможет помочь, я буду очень признателен.