mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-02-21 02:29:06 +00:00
make sure response size assert applies in the empty response case; cleanup; add more comments
This commit is contained in:
parent
ff0a825356
commit
faeb5fa2e1
@ -622,7 +622,10 @@ struct R_DATA
|
|||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
#define POP_STRUCT(vartype, varname, data, len) \
|
/** Create local variable varname of type vartype,
|
||||||
|
* fill it from the buffer data, observing its length len,
|
||||||
|
* and adjust data and len to reflect the remaining data */
|
||||||
|
#define POP_DATA(vartype, varname, data, len) \
|
||||||
assert(len >= sizeof(vartype)); \
|
assert(len >= sizeof(vartype)); \
|
||||||
vartype varname; \
|
vartype varname; \
|
||||||
memcpy(&varname, data, sizeof(vartype)); \
|
memcpy(&varname, data, sizeof(vartype)); \
|
||||||
@ -630,10 +633,30 @@ struct R_DATA
|
|||||||
len -= sizeof(vartype)
|
len -= sizeof(vartype)
|
||||||
|
|
||||||
|
|
||||||
|
/** Create local const char * varname pointing
|
||||||
|
* to the C string in the buffer data, observing its length len,
|
||||||
|
* and adjust data and len to reflect the remaining data */
|
||||||
|
#define POP_STR(varname, data, len) \
|
||||||
|
const char * varname; \
|
||||||
|
{ \
|
||||||
|
int pop_str_len = strnlen(data, len); \
|
||||||
|
if (pop_str_len == len) { \
|
||||||
|
varname = NULL; \
|
||||||
|
} else { \
|
||||||
|
varname = data; \
|
||||||
|
} \
|
||||||
|
data += pop_str_len + 1; \
|
||||||
|
len -= pop_str_len + 1; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void inject_udp_packet_to_guest(struct socket * so, struct sockaddr_in addr, caddr_t packet_data, int packet_len) {
|
static void inject_udp_packet_to_guest(struct socket * so, struct sockaddr_in addr, caddr_t packet_data, int packet_len) {
|
||||||
struct mbuf *m;
|
struct mbuf *m;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
/** This is like sorecvfrom(), but just adds a packet with the
|
||||||
|
* supplied data instead of reading the packet to add from the socket */
|
||||||
|
|
||||||
if (!(m = m_get())) return;
|
if (!(m = m_get())) return;
|
||||||
m->m_data += if_maxlinkhdr;
|
m->m_data += if_maxlinkhdr;
|
||||||
|
|
||||||
@ -654,7 +677,7 @@ static void inject_udp_packet_to_guest(struct socket * so, struct sockaddr_in ad
|
|||||||
|
|
||||||
/* Decode hostname from the format used in DNS
|
/* Decode hostname from the format used in DNS
|
||||||
e.g. "\009something\004else\003com" for "something.else.com." */
|
e.g. "\009something\004else\003com" for "something.else.com." */
|
||||||
static char * decode_dns_name(char * data) {
|
static char * decode_dns_name(const char * data) {
|
||||||
|
|
||||||
int query_str_len = strlen(data);
|
int query_str_len = strlen(data);
|
||||||
char * decoded_name_str = malloc(query_str_len + 1);
|
char * decoded_name_str = malloc(query_str_len + 1);
|
||||||
@ -699,7 +722,7 @@ static bool resolve_dns_request(struct socket * so, struct sockaddr_in addr, cad
|
|||||||
const caddr_t packet = data;
|
const caddr_t packet = data;
|
||||||
const int packet_len = len;
|
const int packet_len = len;
|
||||||
|
|
||||||
POP_STRUCT(struct DNS_HEADER, h, data, len);
|
POP_DATA(struct DNS_HEADER, h, data, len);
|
||||||
|
|
||||||
if (h.qr != 0) {
|
if (h.qr != 0) {
|
||||||
D("DNS packet is not a request\n");
|
D("DNS packet is not a request\n");
|
||||||
@ -726,9 +749,9 @@ static bool resolve_dns_request(struct socket * so, struct sockaddr_in addr, cad
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * original_query_str = data;
|
POP_STR(original_query_str, data, len);
|
||||||
int query_str_len = strnlen(data, len);
|
if (original_query_str == NULL) {
|
||||||
if (query_str_len == len) { // went off end of packet
|
// went off end of packet
|
||||||
D("Unterminated DNS query string\n");
|
D("Unterminated DNS query string\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -741,10 +764,7 @@ static bool resolve_dns_request(struct socket * so, struct sockaddr_in addr, cad
|
|||||||
|
|
||||||
D("DNS host query for %s\n", decoded_name_str);
|
D("DNS host query for %s\n", decoded_name_str);
|
||||||
|
|
||||||
data += query_str_len + 1;
|
POP_DATA(struct QUESTION, qinfo, data, len);
|
||||||
len -= query_str_len + 1;
|
|
||||||
|
|
||||||
POP_STRUCT(struct QUESTION, qinfo, data, len);
|
|
||||||
|
|
||||||
if (ntohs(qinfo.qtype) != 1 /* type A */ || ntohs(qinfo.qclass) != 1 /* class IN */ ) {
|
if (ntohs(qinfo.qtype) != 1 /* type A */ || ntohs(qinfo.qclass) != 1 /* class IN */ ) {
|
||||||
D("DNS host query for %s: Request isn't the supported type (INET A query)\n", decoded_name_str);
|
D("DNS host query for %s: Request isn't the supported type (INET A query)\n", decoded_name_str);
|
||||||
@ -837,9 +857,10 @@ static bool resolve_dns_request(struct socket * so, struct sockaddr_in addr, cad
|
|||||||
memcpy(response_packet + response_pos, cur_addr, sizeof(struct in_addr));
|
memcpy(response_packet + response_pos, cur_addr, sizeof(struct in_addr));
|
||||||
response_pos += sizeof(struct in_addr);
|
response_pos += sizeof(struct in_addr);
|
||||||
}
|
}
|
||||||
assert(response_pos == response_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(response_pos == response_size);
|
||||||
|
|
||||||
D("DNS host query for %s: Injecting DNS response directly to guest\n", decoded_name_str);
|
D("DNS host query for %s: Injecting DNS response directly to guest\n", decoded_name_str);
|
||||||
inject_udp_packet_to_guest(so, addr, response_packet, response_size);
|
inject_udp_packet_to_guest(so, addr, response_packet, response_size);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user