Changeset 25353 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Dec 14, 2009 10:08:50 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/libalias/alias_dns.c
r25301 r25353 1 /* $Id$ */ 2 /** @file 3 * libalias helper for using the host resolver instead of dnsproxy. 4 */ 5 6 /* 7 * Copyright (C) 2009 Sun Microsystems, Inc. 8 * 9 * This file is part of VirtualBox Open Source Edition (OSE), as 10 * available from http://www.virtualbox.org. This file is free software; 11 * you can redistribute it and/or modify it under the terms of the GNU 12 * General Public License (GPL) as published by the Free Software 13 * Foundation, in version 2 as it comes in the "COPYING" file of the 14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the 15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. 16 * 17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa 18 * Clara, CA 95054 USA or visit http://www.sun.com if you need 19 * additional information or have any questions. 20 */ 21 1 22 #ifndef RT_OS_WINDOWS 2 23 # include <netdb.h> 3 24 #endif 4 # 5 # 6 # 7 # 8 # 9 # 10 # 11 # 25 #include <iprt/ctype.h> 26 #include <iprt/assert.h> 27 #include <slirp.h> 28 #include "alias.h" 29 #include "alias_local.h" 30 #include "alias_mod.h" 31 #define isdigit(ch) RT_C_IS_DIGIT(ch) 32 #define isalpha(ch) RT_C_IS_ALPHA(ch) 12 33 13 34 #define DNS_CONTROL_PORT_NUMBER 53 … … 15 36 union dnsmsg_header 16 37 { 17 struct { 18 #ifndef VBOX 19 uint16_t id; 20 uint16_t rd:1; 21 uint16_t tc:1; 22 uint16_t aa:1; 23 uint16_t opcode:4; 24 uint16_t qr:1; 25 uint16_t rcode:4; 26 uint16_t Z:3; 27 uint16_t ra:1; 28 #else 38 struct 39 { 29 40 unsigned id:16; 30 41 unsigned rd:1; … … 36 47 unsigned Z:3; 37 48 unsigned ra:1; 38 #endif39 49 uint16_t qdcount; 40 50 uint16_t ancount; … … 42 52 uint16_t arcount; 43 53 } X; 44 uint16_t raw[ 5];54 uint16_t raw[6]; 45 55 }; 46 56 AssertCompileSize(union dnsmsg_header, 12); … … 53 63 uint16_t ttl[2]; 54 64 uint16_t rdata_len; 55 uint8_t rdata[1]; /*depends on value at rdata_len */65 uint8_t rdata[1]; /* depends on value at rdata_len */ 56 66 }; 57 67 58 68 /* see RFC 1035(4.1) */ 59 69 static int dns_alias_handler(PNATState pData, int type); 60 static void cstr2qstr(char *cstr, char *qstr);61 static void qstr2cstr(char *qstr, char *cstr);70 static void CStr2QStr(const char *pcszStr, char *pszQStr, size_t cQStr); 71 static void QStr2CStr(const char *pcszQStr, char *pszStr, size_t cStr); 62 72 63 73 static int … … 65 75 { 66 76 67 if (ah->dport == NULL || ah->sport == NULL || ah->lnk == NULL) 68 return (-1); 77 if (!ah->dport || !ah->sport || !ah->lnk) 78 return -1; 79 69 80 fprintf(stderr, "NAT:%s: ah(dport: %hd, sport: %hd) oaddr:%R[IP4] aaddr:%R[IP4]\n", 70 81 __FUNCTION__, ntohs(*ah->dport), ntohs(*ah->sport), 71 82 &ah->oaddr, &ah->aaddr); 83 72 84 if ( (ntohs(*ah->dport) == DNS_CONTROL_PORT_NUMBER 73 85 || ntohs(*ah->sport) == DNS_CONTROL_PORT_NUMBER) 74 86 && (ah->oaddr->s_addr == htonl(ntohl(la->pData->special_addr.s_addr)|CTL_DNS))) 75 return (0); 76 return (-1); 87 return 0; 88 89 return -1; 77 90 } 78 91 … … 80 93 { 81 94 int i; 82 if (h == NULL) 83 { 84 hdr->X.qr = 1; /*response*/ 95 96 if (!h) 97 { 98 hdr->X.qr = 1; /* response */ 85 99 hdr->X.aa = 1; 86 100 hdr->X.rd = 1; … … 98 112 99 113 #if 0 100 /* here is no compressed names+answers + new query*/114 /* here is no compressed names+answers + new query */ 101 115 m_inc(m, h->h_length * sizeof(struct dnsmsg_answer) + strlen(qname) + 2 * sizeof(uint16_t)); 102 116 #endif 103 packet_len = (pip->ip_hl << 2) + sizeof(struct udphdr) + sizeof(union dnsmsg_header) 104 + strlen(qname) + 2 * sizeof(uint16_t); /* ip + udp + header + query */ 117 packet_len = (pip->ip_hl << 2) 118 + sizeof(struct udphdr) 119 + sizeof(union dnsmsg_header) 120 + strlen(qname) 121 + 2 * sizeof(uint16_t); /* ip + udp + header + query */ 105 122 query = (char *)&hdr[1]; 106 123 107 124 strcpy(query, qname); 108 query += strlen(qname); 109 query ++; 110 125 query += strlen(qname) + 1; 126 111 127 *(uint16_t *)query = htons(1); 112 128 ((uint16_t *)query)[1] = htons(1); … … 115 131 off = (char *)&hdr[1] - (char *)hdr; 116 132 off |= (0x3 << 14); 117 /*add aliases */ 118 cstr = h->h_aliases;119 while(*cstr)133 134 /* add aliases */ 135 for (cstr = h->h_aliases; *cstr; cstr++) 120 136 { 121 137 uint16_t len; 122 138 struct dnsmsg_answer *ans = (struct dnsmsg_answer *)answers; 123 139 ans->name = htons(off); 124 ans->type = htons(5); /* CNAME*/140 ans->type = htons(5); /* CNAME */ 125 141 ans->class = htons(1); 126 142 *(uint32_t *)ans->ttl = htonl(3600); /* 1h */ 127 c = (addr_off == (uint16_t)~0 ?h->h_name : *cstr);143 c = (addr_off == (uint16_t)~0 ? h->h_name : *cstr); 128 144 len = strlen(c) + 2; 129 145 ans->rdata_len = htons(len); 130 146 ans->rdata[len - 1] = 0; 131 cstr2qstr(c, (char *)ans->rdata);147 CStr2QStr(c, (char *)ans->rdata, len); 132 148 off = (char *)&ans->rdata - (char *)hdr; 133 149 off |= (0x3 << 14); … … 137 153 packet_len += sizeof(struct dnsmsg_answer) + len - 2; 138 154 hdr->X.ancount++; 139 cstr++; 140 } 141 /*add addresses */ 155 } 156 /* add addresses */ 142 157 143 158 for(i = 0; i < h->h_length && h->h_addr_list[i] != NULL; ++i) … … 155 170 hdr->X.ancount++; 156 171 } 157 hdr->X.qr = 1; /* response*/172 hdr->X.qr = 1; /* response */ 158 173 hdr->X.aa = 1; 159 174 hdr->X.rd = 1; … … 161 176 hdr->X.rcode = 0; 162 177 HTONS(hdr->X.ancount); 163 /* don't forget update m_len*/178 /* don't forget update m_len */ 164 179 pip->ip_len = htons(packet_len); 165 180 } … … 169 184 { 170 185 int i; 171 /* Parse dns request */186 /* Parse dns request */ 172 187 char *qw_qname = NULL; 173 188 uint16_t *qw_qtype = NULL; 174 189 uint16_t *qw_qclass = NULL; 175 190 struct hostent *h = NULL; 176 char *cname[255]; /* ??? */191 char cname[255]; 177 192 178 193 struct udphdr *udp = NULL; … … 182 197 183 198 if (hdr->X.qr == 1) 184 return 0; /* this is respose */199 return 0; /* this is respose */ 185 200 186 201 qw_qname = (char *)&hdr[1]; … … 194 209 qw_qname, ntohs(*qw_qtype), ntohs(*qw_qclass)); 195 210 } 196 qstr2cstr(qw_qname, (char *)cname); 197 h = gethostbyname((char *)cname); 211 212 QStr2CStr(qw_qname, cname, sizeof(cname)); 213 h = gethostbyname(cname); 198 214 fprintf(stderr, "cname:%s\n", cname); 199 215 doanswer(la, hdr, qw_qname, pip, h); 200 /*we've chenged size and conten of udp, to avoid double csum calcualtion 201 *will assign to zero 216 217 /* 218 * We have changed the size and the content of udp, to avoid double csum calculation 219 * will assign to zero 202 220 */ 203 221 udp->uh_sum = 0; … … 205 223 pip->ip_sum = 0; 206 224 pip->ip_sum = LibAliasInternetChecksum(la, (uint16_t *)pip, pip->ip_hl << 2); 207 return (0); 208 } 225 return 0; 226 } 227 209 228 /* 210 229 * qstr is z-string with -dot- replaced with \count to next -dot- … … 212 231 * Note: it's assumed that caller allocates buffer for cstr 213 232 */ 214 static void qstr2cstr(char *qname, char *cname) 215 { 216 char *q = qname; 217 char *c = cname; 218 while(*q != 0) 219 { 220 if (isalpha(*q) || isdigit(*q)) 233 static void QStr2CStr(const char *pcszQStr, char *pszStr, size_t cStr) 234 { 235 const char *q; 236 char *c; 237 size_t cLen = 0; 238 239 Assert(cStr > 0); 240 for (q = pcszQStr, c = pszStr; *q != '\0' && cLen < cStr-1; q++, cLen++) 241 { 242 if ( isalpha(*q) 243 || isdigit(*q) 244 || *q == '-' 245 || *q == '_') 221 246 { 222 247 *c = *q; 223 248 c++; 224 249 } 225 else if (c != & cname[0])250 else if (c != &pszStr[0]) 226 251 { 227 252 *c = '.'; 228 253 c++; 229 254 } 230 q++;231 }232 q = 0; 233 } 255 } 256 *c = '\0'; 257 } 258 234 259 /* 235 260 * 236 261 */ 237 static void cstr2qstr(char *cstr, char *qstr) 238 { 239 char *c, *pc, *q; 240 c = cstr; 241 q = qstr; 242 while(*c != 0) 243 { 244 /* a the begining or at -dot- position */ 245 if (*c == '.' || (c == cstr && q == qstr)) 246 { 247 if (c != cstr) c++; 262 static void CStr2QStr(const char *pcszStr, char *pszQStr, size_t cQStr) 263 { 264 const char *c; 265 const char *pc; 266 char *q; 267 size_t cLen = 0; 268 269 Assert(cQStr > 0); 270 for (c = pcszStr, q = pszQStr; *c != '\0' && cLen < cQStr-1; q++, cLen++) 271 { 272 /* at the begining or at -dot- position */ 273 if (*c == '.' || (c == pcszStr && q == pszQStr)) 274 { 275 if (c != pcszStr) 276 c++; 248 277 pc = strchr(c, '.'); 249 *q = pc != NULL? (pc - c) : strlen(c);250 q++;251 continue;252 }253 (*q) = (*c); /*direct copy*/254 q++;255 c++;256 } 257 q = 0;278 *q = pc ? (pc - c) : strlen(c); 279 } 280 else 281 { 282 *q = *c; 283 c++; 284 } 285 } 286 *q = '\0'; 258 287 } 259 288 … … 276 305 { 277 306 int error; 278 if (handlers == NULL) 307 308 if (!handlers) 279 309 handlers = RTMemAllocZ(2 * sizeof(struct proto_handler)); 310 280 311 handlers[0].pri = 20; 281 312 handlers[0].dir = IN; … … 285 316 handlers[1].pri = EOH; 286 317 287 switch (type) { 288 case MOD_LOAD: 289 error = 0; 290 LibAliasAttachHandlers(pData, handlers); 291 break; 292 case MOD_UNLOAD: 293 error = 0; 294 LibAliasDetachHandlers(pData, handlers); 295 RTMemFree(handlers); 296 handlers = NULL; 297 break; 298 default: 299 error = EINVAL; 300 } 301 return (error); 302 } 318 switch (type) 319 { 320 case MOD_LOAD: 321 error = 0; 322 LibAliasAttachHandlers(pData, handlers); 323 break; 324 325 case MOD_UNLOAD: 326 error = 0; 327 LibAliasDetachHandlers(pData, handlers); 328 RTMemFree(handlers); 329 handlers = NULL; 330 break; 331 332 default: 333 error = EINVAL; 334 } 335 return error; 336 }
Note:
See TracChangeset
for help on using the changeset viewer.