/[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.2 - (show annotations) (download) (as text)
Sat Jun 1 03:50:14 2002 UTC (16 years, 9 months ago) by stdarg
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +3 -2 lines
File MIME type: text/x-chdr
* dns resolving seems to work now, even for strange replies like irc.dal.net and www.lycos.com

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 result[0] = 0;
158 /* Read in the answer. */
159 ptr += skip_name(ptr, end);
160 memcpy(&reply, ptr, 10);
161 reply.type = ntohs(reply.type);
162 reply.rdlength = ntohs(reply.rdlength);
163 ptr += 10;
164 if (reply.type == 1) {
165 printf("ipv4 reply\n");
166 inet_ntop(AF_INET, ptr, result, 512);
167 }
168 else if (reply.type == 28) {
169 printf("ipv6 reply\n");
170 inet_ntop(AF_INET6, ptr, result, 512);
171 }
172 else if (reply.type == 12) {
173 char *placeholder;
174 int len, dot;
175
176 printf("reverse-lookup reply\n");
177 placeholder = ptr;
178 result[0] = 0;
179 while ((len = *ptr++) != 0) {
180 if (len > 63) ptr++;
181 else {
182 dot = ptr[len];
183 ptr[len] = 0;
184 strcat(result, ptr);
185 strcat(result, ".");
186 ptr[len] = dot;
187 ptr += len;
188 }
189 }
190 if (strlen(result)) result[strlen(result)-1] = 0;
191 ptr = placeholder;
192 }
193 else {
194 printf("unknown reply: %d (%d bytes)\n", reply.type, reply.rdlength);
195 //return(-1);
196 }
197 ptr += reply.rdlength;
198 printf("result: %s\n", result);
199 }
200 }
201
202 main (int argc, char *argv[])
203 {
204 unsigned char query[512], response[512], *ptr, buf[512];
205 int i, len, sock;
206 struct sockaddr_in server;
207 dns_header_t header;
208 dns_rr_t reply;
209 unsigned long addr;
210
211 if (argc != 4) {
212 printf("usage: %s <dns ip> <host> <type>\n", argv[0]);
213 printf(" <type> can be 1 (ipv4), 2 (ipv4), or 3 (reverse lookup)\n");
214 return(0);
215 }
216
217 server.sin_family = AF_INET;
218 server.sin_port = htons(53);
219 server.sin_addr.s_addr = inet_addr(argv[1]);
220
221 dns_init();
222 len = make_query(argv[2], atoi(argv[3]), query);
223
224 sock = socket(AF_INET, SOCK_DGRAM, 0);
225
226 if (sock < 0) {
227 perror("socket");
228 return(1);
229 }
230
231 connect(sock, &server, sizeof(server));
232 write(sock, query, len);
233 len = read(sock, response, 512);
234 parse_reply(response, len);
235 }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23