lib/eggdrop/dns.c File Reference

#include <eggdrop/eggdrop.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>

Go to the source code of this file.

Data Structures

struct  dns_answer_t
struct  dns_query
struct  dns_header_t
struct  dns_rr_t
struct  dns_server
struct  dns_host_t
struct  dns_cache_t

Defines

#define DO_IPV4

Typedefs

typedef struct dns_query dns_query_t
typedef struct dns_server dns_server_t

Functions

static int make_header (char *buf, int id)
static int cut_host (const char *host, char *query)
static int reverse_ip (const char *host, char *reverse)
static void read_resolv (char *fname)
static void read_hosts (char *fname)
static void get_dns_idx ()
static int cache_find (const char *)
static int dns_on_read (void *client_data, int idx, char *buf, int len)
static int dns_on_eof (void *client_data, int idx, int err, const char *errmsg)
static const char * dns_next_server ()
static void parse_reply (char *response, int nbytes)
static void answer_init (dns_answer_t *answer)
static void answer_add (dns_answer_t *answer, const char *what)
static void answer_free (dns_answer_t *answer)
void egg_dns_send (char *query, int len)
int egg_dns_lookup (const char *host, int timeout, dns_callback_t callback, void *client_data, event_owner_t *owner)
int egg_dns_reverse (const char *ip, int timeout, dns_callback_t callback, void *client_data, event_owner_t *owner)
static int cache_expired (int id)
static void cache_del (int id)
static void cache_add (const char *query, dns_answer_t *answer)
void expire_queries ()
int egg_dns_init ()
int egg_dns_shutdown (void)
static void add_server (char *ip)
static void add_host (char *host, char *ip)
static int read_thing (char *buf, char *ip)
int egg_dns_cancel (int id, int issue_callback)
int egg_dns_cancel_by_owner (egg_module_t *module, void *script)
static int skip_name (unsigned char *ptr)

Variables

static const char rcsid [] = "$Id: dns.c,v 1.21 2007-09-13 22:20:55 sven Exp $"
static int query_id = 1
static dns_header_t _dns_header = {0}
static dns_query_tquery_head = NULL
static dns_host_thosts = NULL
static int nhosts = 0
static dns_cache_tcache = NULL
static int ncache = 0
static dns_server_tservers = NULL
static int nservers = 0
static int cur_server = -1
static char separators [] = " ,\t\r\n"
static int dns_idx = -1
static const char * dns_ip = NULL
static sockbuf_handler_t dns_handler


Define Documentation

#define DO_IPV4

Definition at line 32 of file dns.c.


Typedef Documentation

typedef struct dns_query dns_query_t

typedef struct dns_server dns_server_t


Function Documentation

static void add_host ( char *  host,
char *  ip 
) [static]

Definition at line 448 of file dns.c.

References dns_host_t::host, dns_host_t::ip, and nhosts.

Referenced by read_hosts().

00449 {
00450   hosts = realloc(hosts, (nhosts+1)*sizeof(*hosts));
00451   hosts[nhosts].host = strdup(host);
00452   hosts[nhosts].ip = strdup(ip);
00453   nhosts++;
00454 }

static void add_server ( char *  ip  )  [static]

Definition at line 441 of file dns.c.

References dns_server::ip, and nservers.

Referenced by read_resolv().

00442 {
00443   servers = realloc(servers, (nservers+1)*sizeof(*servers));
00444   servers[nservers].ip = strdup(ip);
00445   nservers++;
00446 }

static void answer_add ( dns_answer_t answer,
const char *  what 
) [static]

Definition at line 126 of file dns.c.

References dns_answer_t::len, dns_answer_t::list, and NULL.

Referenced by cache_add(), egg_dns_lookup(), egg_dns_reverse(), and parse_reply().

00127 {
00128   answer->list = realloc(answer->list, sizeof(*answer->list) * (answer->len+2));
00129   answer->list[answer->len] = strdup(what);
00130   answer->len++;
00131   answer->list[answer->len] = NULL;
00132 }

static void answer_free ( dns_answer_t answer  )  [static]

Definition at line 134 of file dns.c.

References dns_answer_t::len, and dns_answer_t::list.

Referenced by cache_del(), egg_dns_lookup(), egg_dns_reverse(), and parse_reply().

00135 {
00136   int i;
00137   for (i = 0; i < answer->len; i++) free(answer->list[i]);
00138   if (answer->list) free(answer->list);
00139 }

static void answer_init ( dns_answer_t answer  )  [static]

Definition at line 121 of file dns.c.

Referenced by cache_add(), egg_dns_lookup(), and egg_dns_reverse().

00122 {
00123   memset(answer, 0, sizeof(*answer));
00124 }

static void cache_add ( const char *  query,
dns_answer_t answer 
) [static]

Definition at line 359 of file dns.c.

References answer_add(), answer_init(), dns_cache_t::expiretime, ncache, NULL, dns_cache_t::query, and timer_get_now_sec().

Referenced by parse_reply().

00360 {
00361   int i;
00362 
00363   cache = (dns_cache_t *) realloc(cache, (ncache+1)*sizeof(*cache));
00364   cache[ncache].query = strdup(query);
00365   answer_init(&cache[ncache].answer);
00366   for (i = 0; i < answer->len; i++)
00367     answer_add(&cache[ncache].answer, answer->list[i]);
00368   cache[ncache].expiretime = timer_get_now_sec(NULL) + answer->ttl;
00369   ncache++;
00370 }

static void cache_del ( int  id  )  [static]

Definition at line 345 of file dns.c.

References answer_free(), dns_cache_t::expiretime, and ncache.

Referenced by expire_queries().

00346 {
00347   answer_free(&cache[id].answer);
00348   free(cache[id].query);
00349   cache[id].expiretime = 0;
00350 
00351   ncache--;
00352 
00353   if (id < ncache) memcpy(&cache[id], &cache[ncache], sizeof(dns_cache_t));
00354   else memset(&cache[id], 0, sizeof(dns_cache_t));
00355 
00356   cache = (dns_cache_t *) realloc(cache, (ncache+1)*sizeof(*cache));
00357 }

static int cache_expired ( int  id  )  [static]

Definition at line 339 of file dns.c.

References NULL, and timer_get_now_sec().

Referenced by expire_queries().

00340 {
00341   if (cache[id].expiretime && (timer_get_now_sec(NULL) >= cache[id].expiretime))  return(1);
00342   return (0);
00343 }

static int cache_find ( const char *  query  )  [static]

Definition at line 372 of file dns.c.

References ncache.

Referenced by egg_dns_lookup(), and egg_dns_reverse().

00373 {
00374   int i;
00375 
00376   for (i = 0; i < ncache; i++)
00377   if (!strcasecmp(cache[i].query, query)) return (i);
00378 
00379   return (-1);
00380 }

static int cut_host ( const char *  host,
char *  query 
) [static]

Definition at line 512 of file dns.c.

Referenced by egg_dns_lookup(), and egg_dns_reverse().

00513 {
00514   char *period, *orig;
00515   int len;
00516 
00517   orig = query;
00518   while ((period = strchr(host, '.'))) {
00519     len = period - host;
00520     if (len > 63) return(-1);
00521     *query++ = len;
00522     memcpy(query, host, len);
00523     query += len;
00524     host = period+1;
00525   }
00526   len = strlen(host);
00527   if (len) {
00528     *query++ = len;
00529     memcpy(query, host, len);
00530     query += len;
00531   }
00532   *query++ = 0;
00533   return(query-orig);
00534 }

static const char * dns_next_server (  )  [static]

Definition at line 433 of file dns.c.

References cur_server, and nservers.

Referenced by get_dns_idx().

00434 {
00435   if (!servers || nservers < 1) return("127.0.0.1");
00436   cur_server++;
00437   if (cur_server >= nservers) cur_server = 0;
00438   return(servers[cur_server].ip);
00439 }

static int dns_on_eof ( void *  client_data,
int  idx,
int  err,
const char *  errmsg 
) [static]

Definition at line 331 of file dns.c.

References dns_idx, dns_ip, NULL, and sockbuf_delete().

00332 {
00333   sockbuf_delete(idx);
00334   dns_idx = -1;
00335   dns_ip = NULL;
00336   return(0);
00337 }

static int dns_on_read ( void *  client_data,
int  idx,
char *  buf,
int  len 
) [static]

Definition at line 325 of file dns.c.

References parse_reply().

00326 {
00327   parse_reply(buf, len);
00328   return(0);
00329 }

int egg_dns_cancel ( int  id,
int  issue_callback 
)

Definition at line 557 of file dns.c.

References dns_query::callback, dns_query::client_data, dns_query::id, dns_query::next, NULL, event_owner_b::on_delete, dns_query::owner, and dns_query::query.

Referenced by egg_connect_timeout(), egg_on_delete(), and kill_session().

00558 {
00559   dns_query_t *q, *prev;
00560 
00561   prev = NULL;
00562   for (q = query_head; q; q = q->next) {
00563     if (q->id == id) break;
00564     prev = q;
00565   }
00566   if (!q) return(-1);
00567   if (prev) prev->next = q->next;
00568   else query_head = q->next;
00569 
00570   if (issue_callback) q->callback(q->client_data, q->query, NULL);
00571   if (q->owner && q->owner->on_delete) q->owner->on_delete(q->owner, q->client_data);
00572   free(q);
00573   return(0);
00574 }

int egg_dns_cancel_by_owner ( egg_module_t module,
void *  script 
)

Definition at line 576 of file dns.c.

References dns_query::client_data, event_owner_b::client_data, event_owner_b::module, dns_query::next, NULL, event_owner_b::on_delete, and dns_query::owner.

Referenced by script_remove_events_by_owner().

00577 {
00578   int removed = 0;
00579   dns_query_t *q, *prev= NULL, *next;
00580 
00581   for (q = query_head; q; q = next) {
00582     next = q->next;
00583     if (!q->owner || q->owner->module != module || (script && q->owner->client_data != script)) {
00584       prev = q;
00585       continue;
00586     }
00587     if (prev) prev->next = q->next;
00588     else query_head = q->next;
00589     ++removed;
00590 
00591     if (q->owner && q->owner->on_delete) q->owner->on_delete(q->owner, q->client_data);
00592     free(q);
00593   }
00594   return removed;
00595 }

int egg_dns_init ( void   ) 

Definition at line 398 of file dns.c.

References expire_queries(), dns_header_t::flags, read_hosts(), read_resolv(), and timer_create_secs().

Referenced by egg_net_init().

00399 {
00400   _dns_header.flags = htons(1 << 8 | 1 << 7);
00401   read_resolv("/etc/resolv.conf");
00402   read_resolv(".resolv.conf");
00403   read_hosts("/etc/hosts");
00404   read_hosts(".hosts");
00405   timer_create_secs(1, "dns_check_expires", (Function) expire_queries);
00406   return(0);
00407 }

int egg_dns_lookup ( const char *  host,
int  timeout,
dns_callback_t  callback,
void *  client_data,
event_owner_t owner 
)

Definition at line 173 of file dns.c.

References dns_cache_t::answer, answer_add(), answer_free(), answer_init(), cache_find(), dns_query::callback, dns_query::client_data, cut_host(), egg_dns_send(), dns_query::id, dns_answer_t::len, dns_answer_t::list, make_header(), dns_query::next, nhosts, event_owner_b::on_delete, dns_query::owner, dns_query::query, query_id, dns_query::remaining, shuffleArray(), and socket_valid_ip().

Referenced by dcc_dns_set(), egg_client(), and script_dns_lookup().

00174 {
00175   char buf[512];
00176   dns_query_t *q;
00177   int i, len, cache_id;
00178 
00179   if (socket_valid_ip(host)) {
00180     /* If it's already an ip, we're done. */
00181     dns_answer_t answer;
00182 
00183     answer_init(&answer);
00184     answer_add(&answer, host);
00185     callback(client_data, host, answer.list);
00186     answer_free(&answer);
00187     if (owner && owner->on_delete) owner->on_delete(owner, client_data);
00188     return(-1);
00189   }
00190   
00191   /* Search our cache for the same query */
00192   cache_id = cache_find(host);
00193   if (cache_id >= 0) {
00194     shuffleArray(cache[cache_id].answer.list, cache[cache_id].answer.len);
00195     callback(client_data, host, cache[cache_id].answer.list);
00196     if (owner && owner->on_delete) owner->on_delete(owner, client_data);
00197     return(-1);
00198   }
00199 
00200   /* Ok, now see if it's in our host cache. */
00201   for (i = 0; i < nhosts; i++) {
00202     if (!strcasecmp(host, hosts[i].host)) {
00203       dns_answer_t answer;
00204 
00205       answer_init(&answer);
00206       answer_add(&answer, hosts[i].ip);
00207       callback(client_data, host, answer.list);
00208       answer_free(&answer);
00209       if (owner && owner->on_delete) owner->on_delete(owner, client_data);
00210       return(-1);
00211     }
00212   }
00213 
00214   /* Allocate our query struct. */
00215   q = calloc(1, sizeof(*q));
00216   q->id = query_id;
00217   query_id++;
00218   q->query = strdup(host);
00219   q->callback = callback;
00220   q->client_data = client_data;
00221   q->owner = owner;
00222   q->next = query_head;
00223   query_head = q;
00224 
00225   /* Send the ipv4 query. */
00226   q->remaining = 1;
00227   len = make_header(buf, q->id);
00228   len += cut_host(host, buf + len);
00229   buf[len] = 0; len++; buf[len] = 1; len++;
00230   buf[len] = 0; len++; buf[len] = 1; len++;
00231 
00232   egg_dns_send(buf, len);
00233 
00234 #ifdef IPV6
00235   /* Now send the ipv6 query. */
00236   q->remaining++;
00237   len = make_header(buf, q->id);
00238   len += cut_host(host, buf + len);
00239   buf[len] = 0; len++; buf[len] = 28; len++;
00240   buf[len] = 0; len++; buf[len] = 1; len++;
00241 
00242   egg_dns_send(buf, len);
00243 #endif
00244 
00245   return(q->id);
00246 }

int egg_dns_reverse ( const char *  ip,
int  timeout,
dns_callback_t  callback,
void *  client_data,
event_owner_t owner 
)

Definition at line 251 of file dns.c.

References dns_cache_t::answer, answer_add(), answer_free(), answer_init(), cache_find(), dns_query::callback, dns_query::client_data, cut_host(), egg_dns_send(), dns_query::id, dns_answer_t::len, dns_answer_t::list, make_header(), dns_query::next, nhosts, NULL, event_owner_b::on_delete, dns_query::owner, dns_query::query, query_id, reverse_ip(), shuffleArray(), socket_ipv6_to_dots(), and socket_valid_ip().

Referenced by dcc_on_connect(), irc_on_newclient(), script_dns_reverse(), and telnet_on_newclient().

00252 {
00253   dns_query_t *q;
00254   char buf[512], *reversed_ip;
00255   int i, len, cache_id;
00256 
00257   if (!socket_valid_ip(ip)) {
00258     /* If it's not a valid ip, don't even make the request. */
00259     callback(client_data, ip, NULL);
00260     if (owner && owner->on_delete) owner->on_delete(owner, client_data);
00261     return(-1);
00262   }
00263 
00264   /* Ok, see if we have it in our host cache. */
00265   for (i = 0; i < nhosts; i++) {
00266     if (!strcasecmp(hosts[i].ip, ip)) {
00267       dns_answer_t answer;
00268 
00269       answer_init(&answer);
00270       answer_add(&answer, hosts[i].host);
00271       callback(client_data, ip, answer.list);
00272       answer_free(&answer);
00273       if (owner && owner->on_delete) owner->on_delete(owner, client_data);
00274       return(-1);
00275     }
00276   }
00277 
00278   /* Search our cache for the same query */
00279   cache_id = cache_find(ip);
00280   if (cache_id >= 0) {
00281     shuffleArray(cache[cache_id].answer.list, cache[cache_id].answer.len);
00282     callback(client_data, ip, cache[cache_id].answer.list);
00283     if (owner && owner->on_delete) owner->on_delete(owner, client_data);
00284     return(-1);
00285   }
00286 
00287   /* We need to transform the ip address into the proper form
00288    * for reverse lookup. */
00289   if (strchr(ip, ':')) {
00290     char temp[64];
00291 
00292     socket_ipv6_to_dots(ip, temp);
00293     reversed_ip = malloc(strlen(temp) + 10);
00294     reverse_ip(temp, reversed_ip);
00295     strcat(reversed_ip, ".ip6.arpa");
00296   }
00297   else {
00298     reversed_ip = malloc(strlen(ip) + 14);
00299     reverse_ip(ip, reversed_ip);
00300     strcat(reversed_ip, ".in-addr.arpa");
00301   }
00302 
00303   len = make_header(buf, query_id);
00304   len += cut_host(reversed_ip, buf + len);
00305   buf[len] = 0; len++; buf[len] = 12; len++;
00306   buf[len] = 0; len++; buf[len] = 1; len++;
00307 
00308   free(reversed_ip);
00309 
00310   q = calloc(1, sizeof(*q));
00311   q->id = query_id;
00312   query_id++;
00313   q->query = strdup(ip);
00314   q->callback = callback;
00315   q->client_data = client_data;
00316   q->owner = owner;
00317   q->next = query_head;
00318   query_head = q;
00319 
00320   egg_dns_send(buf, len);
00321 
00322   return(q->id);
00323 }

void egg_dns_send ( char *  query,
int  len 
)

Definition at line 161 of file dns.c.

References dns_idx, get_dns_idx(), and sockbuf_write().

Referenced by egg_dns_lookup(), and egg_dns_reverse().

00162 {
00163   if (dns_idx < 0) {
00164     get_dns_idx();
00165     if (dns_idx < 0) return;
00166   }
00167   sockbuf_write(dns_idx, query, len);
00168 }

int egg_dns_shutdown ( void   ) 

Definition at line 409 of file dns.c.

References nhosts, nservers, and NULL.

Referenced by egg_net_shutdown().

00410 {
00411   int i;
00412 
00413   if (nservers > 0) {
00414     for (i = 0; i < nservers; i++) {
00415       if (servers[i].ip) free(servers[i].ip);
00416     }
00417     free(servers); servers = NULL;
00418     nservers = 0;
00419   }
00420   
00421   if (nhosts > 0) {
00422     for (i = 0; i < nhosts; i++) {
00423       if (hosts[i].host) free(hosts[i].host);
00424       if (hosts[i].ip) free(hosts[i].ip);
00425     }
00426     free(hosts); hosts = NULL;
00427     nhosts = 0;
00428   }
00429 
00430   return (0);
00431 }

void expire_queries (  ) 

Definition at line 383 of file dns.c.

References cache_del(), cache_expired(), and ncache.

Referenced by egg_dns_init().

00384 {
00385   int cache_id = 0;
00386 
00387   for (cache_id = 0; cache_id < ncache; cache_id++) {
00388     if (cache_expired(cache_id)) {
00389       cache_del(cache_id);
00390       if (cache_id == ncache)  break;
00391       cache_id--;
00392     }
00393   }
00394 }

static void get_dns_idx (  )  [static]

Definition at line 141 of file dns.c.

References dns_idx, dns_ip, dns_next_server(), DNS_PORT, NULL, sockbuf_new(), sockbuf_set_handler(), sockbuf_set_sock(), SOCKET_CLIENT, socket_create(), SOCKET_NONBLOCK, and SOCKET_UDP.

Referenced by egg_dns_send().

00142 {
00143   int i, sock;
00144 
00145   sock = -1;
00146   for (i = 0; i < 5; i++) {
00147     if (!dns_ip) dns_ip = dns_next_server();
00148     sock = socket_create(dns_ip, DNS_PORT, NULL, 0, SOCKET_CLIENT | SOCKET_NONBLOCK | SOCKET_UDP);
00149     if (sock < 0) {
00150       /* Try the next server. */
00151       dns_ip = NULL;
00152     }
00153     else break;
00154   }
00155   if (i == 5) return;
00156   dns_idx = sockbuf_new();
00157   sockbuf_set_handler(dns_idx, &dns_handler, NULL, NULL);
00158   sockbuf_set_sock(dns_idx, sock, 0);
00159 }

static int make_header ( char *  buf,
int  id 
) [static]

Definition at line 504 of file dns.c.

References dns_header_t::id, and dns_header_t::question_count.

Referenced by egg_dns_lookup(), and egg_dns_reverse().

00505 {
00506   _dns_header.question_count = htons(1);
00507   _dns_header.id = htons(id);
00508   memcpy(buf, &_dns_header, 12);
00509   return(12);
00510 }

static void parse_reply ( char *  response,
int  nbytes 
) [static]

Definition at line 614 of file dns.c.

References dns_query::answer, answer_add(), dns_header_t::answer_count, answer_free(), cache_add(), dns_query::callback, dns_query::client_data, dns_header_t::flags, dns_query::id, dns_header_t::id, dns_answer_t::list, dns_query::next, NULL, event_owner_b::on_delete, dns_query::owner, dns_query::query, dns_header_t::question_count, dns_rr_t::rdlength, dns_query::remaining, skip_name(), dns_answer_t::ttl, dns_rr_t::ttl, and dns_rr_t::type.

Referenced by dns_on_read().

00615 {
00616   dns_header_t header;
00617   dns_rr_t reply;
00618   dns_query_t *q, *prev;
00619   char result[512];
00620   unsigned char *ptr;
00621   int i;
00622 
00623   ptr = (unsigned char *)response;
00624   memcpy(&header, ptr, 12);
00625   ptr += 12;
00626 
00627   header.id = ntohs(header.id);
00628   header.flags = ntohs(header.flags);
00629   header.question_count = ntohs(header.question_count);
00630   header.answer_count = ntohs(header.answer_count);
00631 
00632   /* Find our copy of the query. */
00633   prev = NULL;
00634   for (q = query_head; q; q = q->next) {
00635     if (q->id == header.id) break;
00636     prev = q;
00637   }
00638   if (!q) return;
00639 
00640   /* Pass over the questions. */
00641   for (i = 0; i < header.question_count; i++) {
00642     ptr += skip_name(ptr);
00643     ptr += 4;
00644   }
00645   /* End of questions. */
00646 
00647   for (i = 0; i < header.answer_count; i++) {
00648     result[0] = 0;
00649     /* Read in the answer. */
00650     ptr += skip_name(ptr);
00651     memcpy(&reply, ptr, 10);
00652     reply.type = ntohs(reply.type);
00653     reply.rdlength = ntohs(reply.rdlength);
00654     reply.ttl = ntohl(reply.ttl);
00655     /* Cache the lowest ttl */
00656     if (reply.ttl && ((!q->answer.ttl) || (q->answer.ttl > reply.ttl))) q->answer.ttl = reply.ttl;
00657 
00658     ptr += 10;
00659     #ifdef DO_IPV4
00660     if (reply.type == 1) {
00661       /*fprintf(fp, "ipv4 reply\n");*/
00662       inet_ntop(AF_INET, ptr, result, 512);
00663       answer_add(&q->answer, result);
00664     }
00665     #endif
00666     #ifdef DO_IPV6
00667     if (reply.type == 28) {
00668       /*fprintf(fp, "ipv6 reply\n");*/
00669       inet_ntop(AF_INET6, ptr, result, 512);
00670       answer_add(&q->answer, result);
00671     }
00672     #endif
00673     if (reply.type == 12) {
00674       unsigned char *placeholder;
00675       int len, dot;
00676 
00677       /*fprintf(fp, "reverse-lookup reply\n");*/
00678       placeholder = ptr;
00679       result[0] = 0;
00680       while ((len = *ptr++) != 0) {
00681         if (len > 63) {
00682           ptr++;
00683           break;
00684         }
00685         else {
00686           dot = ptr[len];
00687           ptr[len] = 0;
00688           strcat(result, (char *) ptr);
00689           strcat(result, ".");
00690           ptr[len] = dot;
00691           ptr += len;
00692         }
00693       }
00694       if (strlen(result)) {
00695         result[strlen(result)-1] = 0;
00696         answer_add(&q->answer, result);
00697       }
00698       ptr = placeholder;
00699     }
00700     ptr += reply.rdlength;
00701   }
00702 
00703   q->remaining--;
00704   /* Don't continue if we haven't gotten all expected replies. */
00705   if (q->remaining > 0) return;
00706 
00707   /* Ok, we have, so now issue the callback with the answers. */
00708   if (prev) prev->next = q->next;
00709   else query_head = q->next;
00710 
00711   cache_add(q->query, &q->answer);
00712 
00713   q->callback(q->client_data, q->query, q->answer.list);
00714   if (q->owner && q->owner->on_delete) q->owner->on_delete(q->owner, q->client_data);
00715   answer_free(&q->answer);
00716   free(q->query);
00717   free(q);
00718 }

static void read_hosts ( char *  fname  )  [static]

Definition at line 484 of file dns.c.

References add_host(), and read_thing().

Referenced by egg_dns_init().

00485 {
00486   FILE *fp;
00487   char buf[512], ip[512], host[512];
00488   int skip, n;
00489 
00490   fp = fopen(fname, "r");
00491   if (!fp) return;
00492   while (fgets(buf, sizeof(buf), fp)) {
00493     if (strchr(buf, '#')) continue;
00494     skip = read_thing(buf, ip);
00495     if (!strlen(ip)) continue;
00496     while ((n = read_thing(buf+skip, host))) {
00497       skip += n;
00498       if (strlen(host)) add_host(host, ip);
00499     }
00500   }
00501   fclose(fp);
00502 }

static void read_resolv ( char *  fname  )  [static]

Definition at line 468 of file dns.c.

References add_server(), and read_thing().

Referenced by egg_dns_init().

00469 {
00470   FILE *fp;
00471   char buf[512], ip[512];
00472 
00473   fp = fopen(fname, "r");
00474   if (!fp) return;
00475   while (fgets(buf, sizeof(buf), fp)) {
00476     if (!strncasecmp(buf, "nameserver", 10)) {
00477       read_thing(buf+10, ip);
00478       if (strlen(ip)) add_server(ip);
00479     }
00480   }
00481   fclose(fp);
00482 }

static int read_thing ( char *  buf,
char *  ip 
) [static]

Definition at line 456 of file dns.c.

References separators.

Referenced by read_hosts(), and read_resolv().

00457 {
00458   int skip, len;
00459 
00460   skip = strspn(buf, separators);
00461   buf += skip;
00462   len = strcspn(buf, separators);
00463   memcpy(ip, buf, len);
00464   ip[len] = 0;
00465   return(skip + len);
00466 }

static int reverse_ip ( const char *  host,
char *  reverse 
) [static]

Definition at line 536 of file dns.c.

Referenced by egg_dns_reverse().

00537 {
00538   char *period;
00539   int offset, len;
00540 
00541   period = strchr(host, '.');
00542   if (!period) {
00543     len = strlen(host);
00544     memcpy(reverse, host, len);
00545     return(len);
00546   }
00547   else {
00548     len = period - host;
00549     offset = reverse_ip(host+len+1, reverse);
00550     reverse[offset++] = '.';
00551     memcpy(reverse+offset, host, len);
00552     reverse[offset+len] = 0;
00553     return(offset+len);
00554   }
00555 }

static int skip_name ( unsigned char *  ptr  )  [static]

Definition at line 597 of file dns.c.

References start.

Referenced by parse_reply().

00598 {
00599   int len;
00600   unsigned char *start = ptr;
00601 
00602   while ((len = *ptr++) > 0) {
00603     if (len > 63) {
00604       ptr++;
00605       break;
00606     }
00607     else {
00608       ptr += len;
00609     }
00610   }
00611   return(ptr - start);
00612 }


Variable Documentation

dns_header_t _dns_header = {0} [static]

Definition at line 88 of file dns.c.

dns_cache_t* cache = NULL [static]

int cur_server = -1 [static]

Definition at line 96 of file dns.c.

Referenced by dns_next_server().

Initial value:

 {
  "dns",
  NULL, dns_on_eof, NULL,
  dns_on_read, NULL
}

Definition at line 115 of file dns.c.

int dns_idx = -1 [static]

Definition at line 100 of file dns.c.

Referenced by dns_on_eof(), egg_dns_send(), and get_dns_idx().

const char* dns_ip = NULL [static]

Definition at line 101 of file dns.c.

Referenced by dns_on_eof(), and get_dns_idx().

dns_host_t* hosts = NULL [static]

Definition at line 90 of file dns.c.

int ncache = 0 [static]

Definition at line 93 of file dns.c.

Referenced by cache_add(), cache_del(), cache_find(), and expire_queries().

int nhosts = 0 [static]

Definition at line 91 of file dns.c.

Referenced by add_host(), egg_dns_lookup(), egg_dns_reverse(), and egg_dns_shutdown().

int nservers = 0 [static]

Definition at line 95 of file dns.c.

Referenced by add_server(), dns_next_server(), and egg_dns_shutdown().

dns_query_t* query_head = NULL [static]

Definition at line 89 of file dns.c.

int query_id = 1 [static]

Definition at line 87 of file dns.c.

Referenced by egg_dns_lookup(), and egg_dns_reverse().

const char rcsid[] = "$Id: dns.c,v 1.21 2007-09-13 22:20:55 sven Exp $" [static]

Definition at line 21 of file dns.c.

char separators[] = " ,\t\r\n" [static]

Definition at line 98 of file dns.c.

Referenced by read_thing().

dns_server_t* servers = NULL [static]

Definition at line 94 of file dns.c.


Generated on Sun Nov 30 18:43:34 2008 for eggdrop1.9 by  doxygen 1.5.6