aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dns.c43
-rw-r--r--dns.h12
-rw-r--r--dns_example.c8
3 files changed, 56 insertions, 7 deletions
diff --git a/dns.c b/dns.c
index 53be937..4dd219d 100644
--- a/dns.c
+++ b/dns.c
@@ -174,6 +174,24 @@ static struct dns_answers *get_answers(char **reader, char *packet, int num)
*((unsigned short *) res->data) = pref;
memcpy(res->data + 2, name, strlen(name) + 1);
free(name);
+ } else if (res->type == dns_type_srv) {
+ char *name;
+ unsigned short priority;
+ unsigned short weight;
+ unsigned short port;
+ priority = ntohs(*((unsigned short *) *reader));
+ *reader += 2;
+ weight = ntohs(*((unsigned short *) *reader));
+ *reader += 2;
+ port = ntohs(*((unsigned short *) *reader));
+ *reader += 2;
+ name = read_name(reader, packet);
+ res->data = malloc(7 + strlen(name));
+ ((unsigned short *) res->data)[0] = priority;
+ ((unsigned short *) res->data)[1] = weight;
+ ((unsigned short *) res->data)[2] = port;
+ memcpy(res->data + 6, name, strlen(name) + 1);
+ free(name);
} else {
if (res->type == dns_type_txt) {
res->size--;
@@ -208,14 +226,35 @@ static struct dns_answers *get(int sock, struct sockaddr_in *a)
}
+char *dns_mx_server(void *data)
+{
+ return ((char *) data) + 2;
+}
+
int dns_mx_preference(void *data)
{
return *((unsigned short *) data);
}
-char *dns_mx_server(void *data)
+
+char *dns_srv_server(void *data)
{
- return ((char *) data) + 2;
+ return ((char *) data) + 6;
+}
+
+int dns_srv_port(void *data)
+{
+ return ((unsigned short *) data)[2];
+}
+
+int dns_srv_priority(void *data)
+{
+ return *((unsigned short *) data);
+}
+
+int dns_srv_weight(void *data)
+{
+ return ((unsigned short *) data)[1];
}
diff --git a/dns.h b/dns.h
index 208dda0..61478ae 100644
--- a/dns.h
+++ b/dns.h
@@ -6,7 +6,8 @@ enum { /* Some of DNS types: */
dns_type_a = 1,
dns_type_cname = 5,
dns_type_mx = 15,
- dns_type_txt = 16
+ dns_type_txt = 16,
+ dns_type_srv = 33
};
struct dns_answers {
@@ -20,12 +21,15 @@ struct dns_answers {
/* For CNAME & TXT data is just 'char *',
* For A data is 'unsigned char *' of size 4. */
-int dns_mx_preference(void *data);
char *dns_mx_server(void *data);
+int dns_mx_preference(void *data);
+char *dns_srv_server(void *data);
+int dns_srv_port(void *data);
+int dns_srv_priority(void *data);
+int dns_srv_weight(void *data);
-/* In case of error result is 0.
- * It's not the-best-effort attempt to get answer, just simple working one. */
+/* In case of error result is 0. */
struct dns_answers *dns_get(const char *server, const char *host, int query);
void dns_free(struct dns_answers *answers);
diff --git a/dns_example.c b/dns_example.c
index f6efeba..9f16dc0 100644
--- a/dns_example.c
+++ b/dns_example.c
@@ -10,12 +10,18 @@ int main()
for (cur = ans; cur; cur = cur->next) {
if (cur->type == dns_type_a) {
unsigned char *ip = cur->data;
- printf("IP of %s is %d.%d.%d.%d.\n",
+ printf("IP address of %s is %d.%d.%d.%d.\n",
cur->host, ip[0], ip[1], ip[2], ip[3]);
} else if (cur->type == dns_type_cname) {
printf("Cannonical name of %s is %s.\n", cur->host, cur->data);
} else if (cur->type == dns_type_txt) {
printf("Text from %s: %s\n", cur->host, cur->data);
+ } else if (cur->type == dns_type_srv) {
+ printf("Service %s is located at %s on port %d "
+ "with priority %d and weight %d.\n",
+ cur->host,
+ dns_srv_server(cur->data), dns_srv_port(cur->data),
+ dns_srv_priority(cur->data), dns_srv_weight(cur->data));
} else if (cur->type == dns_type_mx) {
printf("Mail exchange server for %s with preference %d is %s.\n",
cur->host,