/[cvs]/eggdrop1.9/testcode/dns.c
ViewVC logotype

Contents of /eggdrop1.9/testcode/dns.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download) (as text)
Thu Apr 25 04:24:42 2002 UTC (17 years, 11 months ago) by stdarg
Branch: MAIN
File MIME type: text/x-chdr
* Some simple dns resolution code

1 #include <stdio.h>
2 #include <string.h>
3 #include <sys/socket.h>
4 #include <netinet/in.h>
5 #include "my_socket.h"
6
7 typedef struct {
8 char *host;
9 char *ip;
10 int expiration;
11 } dns_entry_t;
12
13 typedef struct {
14 unsigned short id;
15 unsigned short flags;
16 unsigned short question_count;
17 unsigned short answer_count;
18 unsigned short ns_count;
19 unsigned short ar_count;
20 } dns_header_t;
21
22 typedef struct {
23 /* char name[]; */
24 unsigned short type;
25 unsigned short class;
26 int ttl;
27 unsigned short rdlength;
28 /* char rdata[]; */
29 } dns_rr_t;
30
31 static int query_id = 1;
32 static dns_header_t _dns_header = {0};
33 static dns_entry_t *dns_cache = NULL;
34 static int dns_cache_len;
35
36 /* Read in ~/.hosts and /etc/hosts and ~/.resolv.conf and /etc/resolv.conf */
37 int dns_init()
38 {
39 _dns_header.flags = htons(1 << 8 | 1 << 7);
40 _dns_header.question_count = htons(1);
41 return(0);
42 }
43
44 static char *search_cache_by_host(char *host)
45 {
46 int i;
47 for (i = 0; i < dns_cache_len; i++) {
48 if (!strcasecmp(dns_cache[i].host, host)) return(dns_cache[i].ip);
49 }
50 return(NULL);
51 }
52
53 static char *search_cache_by_ip(char *ip)
54 {
55 int i;
56 for (i = 0; i < dns_cache_len; i++) {
57 if (!strcasecmp(dns_cache[i].ip, ip)) return(dns_cache[i].host);
58 }
59 return(NULL);
60 }
61
62 static void add_cache_entry(char *host, char *ip)
63 {
64 dns_cache = (dns_entry_t *)realloc(dns_cache, (dns_cache_len+1) * sizeof(dns_entry_t));
65 dns_cache[dns_cache_len].host = strdup(host);
66 dns_cache[dns_cache_len].ip = strdup(ip);
67 dns_cache_len++;
68 }
69
70 static int make_header(char *buf, int id)
71 {
72 _dns_header.id = htons(id);
73 memcpy(buf, &_dns_header, 12);
74 return(12);
75 }
76
77 static int cut_host(char *host, char *query)
78 {
79 char *period, *orig;
80 int len;
81
82 orig = query;
83 while (period = strchr(host, '.')) {
84 len = period - host;
85 if (len > 63) return(-1);
86 *query++ = len;
87 memcpy(query, host, len);
88 query += len;
89 host = period+1;
90 }
91 len = strlen(host);
92 if (len) {
93 *query++ = len;
94 memcpy(query, host, len);
95 query += len;
96 }
97 *query++ = 0;
98 return(query-orig);
99 }
100
101 static int make_query(char *host, int type, unsigned char *buf)
102 {
103 int len = 0;
104 int ns_type = 0;
105
106 if (type == 1) ns_type = 1; /* IPv4 */
107 else if (type == 2) ns_type = 28; /* IPv6 */
108 else if (type == 3) ns_type = 12; /* PTR (reverse lookup) */
109 else return(0);
110
111 len = make_header(buf, query_id++);
112 len += cut_host(host, buf + len);
113 buf[len] = 0; len++; buf[len] = ns_type; len++;
114 buf[len] = 0; len++; buf[len] = 1; len++;
115 return(len);
116 }
117
118 static int skip_name(unsigned char *ptr, char *end)
119 {
120 int len;
121 unsigned char *start = ptr;
122
123 while ((len = *ptr++) > 0) {
124 if (len > 63) {
125 ptr++;
126 break;
127 }
128 else {
129 ptr += len;
130 }
131 }
132 return(ptr - start);
133 }
134
135 static int parse_reply(unsigned char *response, int nbytes)
136 {
137 dns_header_t header;
138 dns_rr_t reply;
139 char result[512];
140 unsigned char *ptr, *end;
141 int i;
142
143 ptr = response;
144 memcpy(&header, ptr, 12);
145 ptr += 12;
146
147 header.id = ntohs(header.id);
148 header.question_count = ntohs(header.question_count);
149 header.answer_count = ntohs(header.answer_count);
150
151 /* Pass over the question. */
152 ptr += skip_name(ptr, end);
153 ptr += 4;
154 /* End of question. */
155
156 for (i = 0; i < header.answer_count; i++) {
157 /* Read in the answer. */
158 ptr += skip_name(ptr, end);
159 memcpy(&reply, ptr, 10);
160 reply.type = ntohs(reply.type);
161 reply.rdlength = ntohs(reply.rdlength);
162 ptr += 10;
163 if (reply.type == 1) {
164 printf("ipv4 reply\n");
165 inet_ntop(AF_INET, ptr, result, 512);
166 }
167 else if (reply.type == 28) {
168 printf("ipv6 reply\n");
169 inet_ntop(AF_INET6, ptr, result, 512);
170 }
171 else if (reply.type == 12) {
172 char *placeholder;
173 int len, dot;
174
175 printf("reverse-lookup reply\n");
176 placeholder = ptr;
177 result[0] = 0;
178 while ((len = *ptr++) != 0) {
179 if (len > 63) ptr++;
180 else {
181 dot = ptr[len];
182 ptr[len] = 0;
183 strcat(result, ptr);
184 strcat(result, ".");
185 ptr[len] = dot;
186 ptr += len;
187 }
188 }
189 if (strlen(result)) result[strlen(result)-1] = 0;
190 ptr = placeholder;
191 }
192 else {
193 printf("unknown reply\n");
194 return(-1);
195 }
196 ptr += reply.rdlength;
197 printf("result: %s\n", result);
198 }
199 }
200
201 main (int argc, char *argv[])
202 {
203 unsigned char query[512], response[512], *ptr, buf[512];
204 int i, len, sock;
205 struct sockaddr_in server;
206 dns_header_t header;
207 dns_rr_t reply;
208 unsigned long addr;
209
210 if (argc != 4) {
211 printf("usage: %s <dns ip> <host> <type>\n", argv[0]);
212 printf(" <type> can be 1 (ipv4), 2 (ipv4), or 3 (reverse lookup)\n");
213 return(0);
214 }
215
216 server.sin_family = AF_INET;
217 server.sin_port = htons(53);
218 server.sin_addr.s_addr = inet_addr(argv[1]);
219
220 dns_init();
221 len = make_query(argv[2], atoi(argv[3]), query);
222
223 sock = socket(AF_INET, SOCK_DGRAM, 0);
224
225 if (sock < 0) {
226 perror("socket");
227 return(1);
228 }
229
230 connect(sock, &server, sizeof(server));
231 write(sock, query, len);
232 len = read(sock, response, 512);
233 parse_reply(response, len);
234 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23