alias_dns.c revision ce228314445e73573b71dc62adb4954f8225059a
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync#ifndef RT_OS_WINDOWS
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync# include <netdb.h>
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync#endif
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync# include <iprt/ctype.h>
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync# include <iprt/assert.h>
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync# include <slirp.h>
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync# include "alias.h"
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync# include "alias_local.h"
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync# include "alias_mod.h"
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync#define DNS_CONTROL_PORT_NUMBER 53
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync/* see RFC 1035(4.1.1) */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncunion dnsmsg_header
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync{
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync struct {
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t id;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t rd:1;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t tc:1;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t aa:1;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t opcode:4;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t qr:1;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t rcode:4;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t Z:3;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t ra:1;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t qdcount;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t ancount;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t nscount;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t arcount;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync } X;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t raw[5];
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync};
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstruct dnsmsg_answer
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync{
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t name;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t type;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t class;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t ttl[2];
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t rdata_len;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint8_t rdata[1]; /*depends on value at rdata_len */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync};
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync/* see RFC 1035(4.1) */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic int dns_alias_handler(PNATState pData, int type);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic void cstr2qstr(char *cstr, char *qstr);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic void qstr2cstr(char *qstr, char *cstr);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic int
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncfingerprint(struct libalias *la, struct ip *pip, struct alias_data *ah)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync{
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync return (-1);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync fprintf(stderr, "NAT:%s: ah(dport: %hd, sport: %hd) oaddr:%R[IP4] aaddr:%R[IP4]\n",
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync __FUNCTION__, ntohs(*ah->dport), ntohs(*ah->sport),
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync &ah->oaddr, &ah->aaddr);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync if ( (ntohs(*ah->dport) == DNS_CONTROL_PORT_NUMBER
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync || ntohs(*ah->sport) == DNS_CONTROL_PORT_NUMBER)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync && (ah->oaddr->s_addr == htonl(ntohl(la->special_addr.s_addr)|CTL_DNS)))
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync return (0);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync return (-1);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync}
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic void doanswer(struct libalias *la, union dnsmsg_header *hdr,char *qname, struct ip *pip, struct hostent *h)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync{
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync int i;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync if (h == NULL)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync {
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync hdr->X.qr = 1; /*response*/
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync hdr->X.aa = 1;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync hdr->X.rd = 1;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync hdr->X.rcode = 3;
a2544ef163bb615c50680a75e0958e2eb801727avboxsync }
a2544ef163bb615c50680a75e0958e2eb801727avboxsync else
a2544ef163bb615c50680a75e0958e2eb801727avboxsync {
a2544ef163bb615c50680a75e0958e2eb801727avboxsync /*!!! We need to be sure that */
a2544ef163bb615c50680a75e0958e2eb801727avboxsync struct mbuf *m = NULL;
a2544ef163bb615c50680a75e0958e2eb801727avboxsync char *query;
a2544ef163bb615c50680a75e0958e2eb801727avboxsync char *answers;
a2544ef163bb615c50680a75e0958e2eb801727avboxsync uint16_t off;
a2544ef163bb615c50680a75e0958e2eb801727avboxsync char **cstr;
a2544ef163bb615c50680a75e0958e2eb801727avboxsync char *c;
a2544ef163bb615c50680a75e0958e2eb801727avboxsync uint16_t packet_len = 0;
a2544ef163bb615c50680a75e0958e2eb801727avboxsync uint16_t addr_off = (uint16_t)~0;
a2544ef163bb615c50680a75e0958e2eb801727avboxsync
a2544ef163bb615c50680a75e0958e2eb801727avboxsync m = dtom(la->pData, hdr);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync Assert((m));
a2544ef163bb615c50680a75e0958e2eb801727avboxsync
a2544ef163bb615c50680a75e0958e2eb801727avboxsync#if 0
a2544ef163bb615c50680a75e0958e2eb801727avboxsync /*here is no compressed names+answers + new query*/
a2544ef163bb615c50680a75e0958e2eb801727avboxsync m_inc(m, h->h_length * sizeof(struct dnsmsg_answer) + strlen(qname) + 2 * sizeof(uint16_t));
a2544ef163bb615c50680a75e0958e2eb801727avboxsync#endif
a2544ef163bb615c50680a75e0958e2eb801727avboxsync packet_len = (pip->ip_hl << 2) + sizeof(struct udphdr) + sizeof(union dnsmsg_header)
a2544ef163bb615c50680a75e0958e2eb801727avboxsync + strlen(qname) + 2 * sizeof(uint16_t); /* ip + udp + header + query */
a2544ef163bb615c50680a75e0958e2eb801727avboxsync fprintf(stderr,"got %d addresses for target:%s (m_len: %d)\n", h->h_length, h->h_name, m->m_len);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync query = (char *)&hdr[1];
a2544ef163bb615c50680a75e0958e2eb801727avboxsync
a2544ef163bb615c50680a75e0958e2eb801727avboxsync strcpy(query, qname);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync query += strlen(qname);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync query ++;
a2544ef163bb615c50680a75e0958e2eb801727avboxsync
a2544ef163bb615c50680a75e0958e2eb801727avboxsync *(uint16_t *)query = htons(1);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync ((uint16_t *)query)[1] = htons(1);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync answers = (char *)&((uint16_t *)query)[2];
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync off = (char *)&hdr[1] - (char *)hdr;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync off |= (0x3 << 14);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync /*add aliases */
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync cstr = h->h_aliases;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync while(*cstr)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync {
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync uint16_t len;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync struct dnsmsg_answer *ans = answers;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync ans->name = htons(off);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync ans->type = htons(5); /*CNAME*/
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync ans->class = htons(1);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync *(uint32_t *)ans->ttl = htonl(3600); /* 1h */
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync c = (addr_off == (uint16_t)~0?h->h_name : *cstr);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync len = strlen(c) + 2;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync ans->rdata_len = htons(len);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync ans->rdata[len - 1] = 0;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync cstr2qstr(c, ans->rdata);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync off = (char *)&ans->rdata - (char *)hdr;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync off |= (0x3 << 14);
dce1a38a7e4bfc36180d68e76bae78acc26c9565vboxsync if (addr_off == (uint16_t)~0)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync addr_off = off;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync answers = (char *)&ans[1] + len - 2; /* note: 1 symbol already counted */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync packet_len += sizeof(struct dnsmsg_answer) + len - 2;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync hdr->X.ancount++;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync cstr++;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync }
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync /*add addresses */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync for(i = 0; i < h->h_length && h->h_addr_list[i] != NULL; ++i)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync {
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync struct dnsmsg_answer *ans = (struct dnsmsg_answer *)answers;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync ans->name = htons(off);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync ans->type = htons(1);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync ans->class = htons(1);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync *(uint32_t *)ans->ttl = htonl(3600); /* 1h */
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync ans->rdata_len = htons(4); /* IPv4 */
a2544ef163bb615c50680a75e0958e2eb801727avboxsync *(uint32_t *)ans->rdata = *(uint32_t *)h->h_addr_list[i];
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync answers = (char *)&ans[1] + 2;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync packet_len += sizeof(struct dnsmsg_answer) + 3;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync hdr->X.ancount++;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync }
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync hdr->X.qr = 1; /*response*/
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync hdr->X.aa = 1;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync hdr->X.rd = 1;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync hdr->X.ra = 1;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync hdr->X.rcode = 0;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync HTONS(hdr->X.ancount);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync /*don't forget update m_len*/
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync m->m_len = packet_len;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync pip->ip_len = htons(m->m_len);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync }
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync}
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncstatic int
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsyncprotohandler(struct libalias *la, struct ip *pip, struct alias_data *ah)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync{
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync int i;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync /*Parse dns request */
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync char *qw_qname = NULL;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync uint16_t *qw_qtype = NULL;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync uint16_t *qw_qclass = NULL;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync struct hostent *h = NULL;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync char *cname[255]; /* ??? */
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync struct udphdr *udp = NULL;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync union dnsmsg_header *hdr = NULL;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync udp = ((char *)pip) + (pip->ip_hl << 2);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync hdr = (union dnsmsg_header *)&udp[1];
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync if (hdr->X.qr == 1)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync return 0; /* this is respose*/
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync qw_qname = (char *)&hdr[1];
a2544ef163bb615c50680a75e0958e2eb801727avboxsync Assert((ntohs(hdr->X.qdcount) == 1));
a2544ef163bb615c50680a75e0958e2eb801727avboxsync
a2544ef163bb615c50680a75e0958e2eb801727avboxsync for (i = 0; i < ntohs(hdr->X.qdcount); ++i)
a2544ef163bb615c50680a75e0958e2eb801727avboxsync {
a2544ef163bb615c50680a75e0958e2eb801727avboxsync qw_qtype = (uint16_t *)(qw_qname + strlen(qw_qname) + 1);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync qw_qclass = &qw_qtype[1];
a2544ef163bb615c50680a75e0958e2eb801727avboxsync fprintf(stderr, "qname:%s qtype:%hd qclass:%hd\n",
a2544ef163bb615c50680a75e0958e2eb801727avboxsync qw_qname, ntohs(*qw_qtype), ntohs(*qw_qclass));
a2544ef163bb615c50680a75e0958e2eb801727avboxsync }
a2544ef163bb615c50680a75e0958e2eb801727avboxsync qstr2cstr(qw_qname, cname);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync h = gethostbyname(cname);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync fprintf(stderr, "cname:%s\n", cname);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync doanswer(la, hdr, qw_qname, pip, h);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync /*we've chenged size and conten of udp, to avoid double csum calcualtion
a2544ef163bb615c50680a75e0958e2eb801727avboxsync *will assign to zero
a2544ef163bb615c50680a75e0958e2eb801727avboxsync */
a2544ef163bb615c50680a75e0958e2eb801727avboxsync udp->uh_sum = 0;
a2544ef163bb615c50680a75e0958e2eb801727avboxsync udp->uh_ulen = ntohs(htons(pip->ip_len) - (pip->ip_hl << 2));
a2544ef163bb615c50680a75e0958e2eb801727avboxsync pip->ip_sum = 0;
a2544ef163bb615c50680a75e0958e2eb801727avboxsync pip->ip_sum = LibAliasInternetChecksum(la, (char *)pip, pip->ip_hl << 2);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync return (0);
a2544ef163bb615c50680a75e0958e2eb801727avboxsync}
a2544ef163bb615c50680a75e0958e2eb801727avboxsync/*
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * qstr is z-string with -dot- replaced with \count to next -dot-
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * e.g. ya.ru is \02ya\02ru
a2544ef163bb615c50680a75e0958e2eb801727avboxsync * Note: it's assumed that caller allocates buffer for cstr
a2544ef163bb615c50680a75e0958e2eb801727avboxsync */
a2544ef163bb615c50680a75e0958e2eb801727avboxsyncstatic void qstr2cstr(char *qname, char *cname)
a2544ef163bb615c50680a75e0958e2eb801727avboxsync{
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync char *q = qname;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync char *c = cname;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync while(*q != 0)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync {
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync if (isalpha(*q) || isdigit(*q))
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync {
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync *c = *q;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync c++;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync }
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync else if (c != &cname[0])
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync {
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync *c = '.';
a2544ef163bb615c50680a75e0958e2eb801727avboxsync c++;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync }
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync q++;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync }
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync q = 0;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync}
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync/*
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync *
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync */
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsyncstatic void cstr2qstr(char *cstr, char *qstr)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync{
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync char *c, *pc, *q;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync c = cstr;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync q = qstr;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync while(*c != 0)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync {
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync /* a the begining or at -dot- position */
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync if (*c == '.' || (c == cstr && q == qstr))
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync {
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync if (c != cstr) c++;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync pc = strchr(c, '.');
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync *q = pc != NULL ? (pc - c) : strlen(c);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync q++;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync continue;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync }
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync (*q) = (*c); /*direct copy*/
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync q++;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync c++;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync }
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync q = 0;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync}
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncint
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsyncdns_alias_load(PNATState pData)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync{
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync return dns_alias_handler(pData, MOD_LOAD);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync}
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsyncint
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsyncdns_alias_unload(PNATState pData)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync{
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync return dns_alias_handler(pData, MOD_UNLOAD);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync}
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync#define handlers pData->dns_module
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsyncstatic int
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsyncdns_alias_handler(PNATState pData, int type)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync{
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync int error;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync if (handlers == NULL)
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync handlers = RTMemAllocZ(2 * sizeof(struct proto_handler));
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync handlers[0].pri = 20;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync handlers[0].dir = IN;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync handlers[0].proto = UDP;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync handlers[0].fingerprint = &fingerprint;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync handlers[0].protohandler = &protohandler;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync handlers[1].pri = EOH;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync switch (type) {
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync case MOD_LOAD:
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync error = 0;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync LibAliasAttachHandlers(pData, handlers);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync break;
432f4382a4f933a320e4e251fa738d3cfab5af9cvboxsync case MOD_UNLOAD:
a2544ef163bb615c50680a75e0958e2eb801727avboxsync error = 0;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync LibAliasDetachHandlers(pData, handlers);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync RTMemFree(handlers);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync handlers = NULL;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync break;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync default:
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync error = EINVAL;
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync }
a2544ef163bb615c50680a75e0958e2eb801727avboxsync return (error);
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync}
8e9d8c088aac57bedb558d3164bb681a582e4474vboxsync