Changeset 60142 in vbox
- Timestamp:
- Mar 22, 2016 9:44:59 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 106161
- Location:
- trunk/src/VBox/Devices/Network
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DrvNAT.cpp
r59312 r60142 211 211 RTCRITSECT XmitLock; 212 212 213 /** Request queue for the async host resolver. */ 214 RTREQQUEUE hHostResQueue; 215 /** Async host resolver thread. */ 216 PPDMTHREAD pHostResThread; 217 213 218 #ifdef RT_OS_DARWIN 214 219 /* Handle of the DNS watcher runloop source. */ … … 892 897 } 893 898 899 900 static DECLCALLBACK(int) drvNATHostResThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 901 { 902 PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT); 903 904 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) 905 return VINF_SUCCESS; 906 907 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 908 { 909 RTReqQueueProcess(pThis->hHostResQueue, RT_INDEFINITE_WAIT); 910 } 911 912 return VINF_SUCCESS; 913 } 914 915 916 static DECLCALLBACK(int) drvNATReqQueueInterrupt() 917 { 918 /* 919 * RTReqQueueProcess loops until request returns a warning or info 920 * status code (other than VINF_SUCCESS). 921 */ 922 return VINF_INTERRUPTED; 923 } 924 925 926 static DECLCALLBACK(int) drvNATHostResWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 927 { 928 PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT); 929 Assert(pThis != NULL); 930 931 int rc; 932 rc = RTReqQueueCallEx(pThis->hHostResQueue, NULL /*ppReq*/, 0 /*cMillies*/, 933 RTREQFLAGS_IPRT_STATUS | RTREQFLAGS_NO_WAIT, 934 (PFNRT)drvNATReqQueueInterrupt, 0); 935 return rc; 936 } 937 938 894 939 /** 895 940 * Function called by slirp to check if it's possible to feed incoming data to the network port. … … 963 1008 STAM_COUNTER_INC(&pThis->StatQueuePktSent); 964 1009 LogFlowFuncLeave(); 1010 } 1011 1012 1013 /* 1014 * Call a function on the slirp thread. 1015 */ 1016 int slirp_call(void *pvUser, PRTREQ *ppReq, RTMSINTERVAL cMillies, 1017 unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...) 1018 { 1019 PDRVNAT pThis = (PDRVNAT)pvUser; 1020 Assert(pThis); 1021 1022 int rc; 1023 1024 va_list va; 1025 va_start(va, cArgs); 1026 1027 rc = RTReqQueueCallV(pThis->hSlirpReqQueue, ppReq, cMillies, fFlags, pfnFunction, cArgs, va); 1028 1029 va_end(va); 1030 1031 if (RT_SUCCESS(rc)) 1032 drvNATNotifyNATThread(pThis, "slirp_vcall"); 1033 1034 return rc; 1035 } 1036 1037 1038 /* 1039 * Call a function on the host resolver thread. 1040 */ 1041 int slirp_call_hostres(void *pvUser, PRTREQ *ppReq, RTMSINTERVAL cMillies, 1042 unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...) 1043 { 1044 PDRVNAT pThis = (PDRVNAT)pvUser; 1045 Assert(pThis); 1046 1047 int rc; 1048 1049 AssertReturn((pThis->hHostResQueue != NIL_RTREQQUEUE), VERR_INVALID_STATE); 1050 AssertReturn((pThis->pHostResThread != NULL), VERR_INVALID_STATE); 1051 1052 va_list va; 1053 va_start(va, cArgs); 1054 1055 rc = RTReqQueueCallV(pThis->hHostResQueue, ppReq, cMillies, fFlags, 1056 pfnFunction, cArgs, va); 1057 1058 va_end(va); 1059 return rc; 965 1060 } 966 1061 … … 1345 1440 } 1346 1441 1442 RTReqQueueDestroy(pThis->hHostResQueue); 1443 pThis->hHostResQueue = NIL_RTREQQUEUE; 1444 1347 1445 RTReqQueueDestroy(pThis->hSlirpReqQueue); 1348 1446 pThis->hSlirpReqQueue = NIL_RTREQQUEUE; … … 1396 1494 pThis->hSlirpReqQueue = NIL_RTREQQUEUE; 1397 1495 pThis->hUrgRecvReqQueue = NIL_RTREQQUEUE; 1496 pThis->hHostResQueue = NIL_RTREQQUEUE; 1398 1497 pThis->EventRecv = NIL_RTSEMEVENT; 1399 1498 pThis->EventUrgRecv = NIL_RTSEMEVENT; … … 1590 1689 1591 1690 rc = RTSemEventCreate(&pThis->EventUrgRecv); 1691 AssertRCReturn(rc, rc); 1692 1693 rc = RTReqQueueCreate(&pThis->hHostResQueue); 1694 AssertRCReturn(rc, rc); 1695 1696 rc = PDMDrvHlpThreadCreate(pThis->pDrvIns, &pThis->pHostResThread, 1697 pThis, drvNATHostResThread, drvNATHostResWakeup, 1698 64 * _1K, RTTHREADTYPE_IO, "HOSTRES"); 1592 1699 AssertRCReturn(rc, rc); 1593 1700 -
trunk/src/VBox/Devices/Network/slirp/hostres.c
r59585 r60142 105 105 struct response 106 106 { 107 PNATState pData; 108 109 uint32_t src; 110 uint16_t sport; 111 107 112 struct label *labels; /* already encoded in buf */ 108 113 size_t qlen; /* original question */ … … 115 120 116 121 static int verify_header(PNATState pData, struct mbuf **pMBuf); 117 static struct mbuf *respond(PNATState pData, struct mbuf *m, struct response *res); 118 struct mbuf *resolve(PNATState pData, struct mbuf *m, struct response *res, 119 uint16_t qtype, size_t qname); 120 struct mbuf *resolve_reverse(PNATState pData, struct mbuf *m, struct response *res, 121 uint16_t qtype, size_t qname, struct in_addr addr); 122 struct mbuf *refuse(PNATState pData, struct mbuf *m, unsigned int rcode); 122 static struct mbuf *refuse_mbuf(struct mbuf *m, unsigned int rcode); 123 124 static int respond(struct response *res); 125 static int resolve(struct response *res, uint16_t qtype, size_t qname); 126 static int resolve_reverse(struct response *res, uint16_t qtype, size_t qname, 127 struct in_addr addr); 128 129 static int refuse(struct response *res, unsigned int rcode); 130 131 123 132 static ssize_t append_a(struct response *res, const char *name, struct in_addr addr); 124 133 static ssize_t append_cname(struct response *res, const char *name, const char *cname); … … 155 164 156 165 166 static void hostres_async(struct response *res); 167 static void hostres_slirp_reply(struct response *res); 168 169 170 /* 171 * Host resolver is called on slirp thread from udp.c 172 */ 157 173 struct mbuf * 158 hostresolver(PNATState pData, struct mbuf *m )159 { 160 int error;161 162 struct response res;163 164 error= verify_header(pData, &m);165 if ( error != 0)174 hostresolver(PNATState pData, struct mbuf *m, uint32_t src, uint16_t sport) 175 { 176 struct response *res; 177 size_t mlen; 178 int rc; 179 180 rc = verify_header(pData, &m); 181 if (RT_FAILURE(rc)) 166 182 return m; 167 183 168 RT_ZERO(res); 169 170 /* 171 * Do the real work 172 */ 173 m = respond(pData, m, &res); 174 175 free_labels(res.labels); 176 return m; 177 } 178 179 180 struct mbuf * 181 refuse(PNATState pData, struct mbuf *m, unsigned int rcode) 182 { 183 struct dnsmsg_header *pHdr; 184 185 pHdr = mtod(m, struct dnsmsg_header *); 186 pHdr->qr = QR_Response; 187 pHdr->rcode = rcode; 188 pHdr->ra = 1; 189 pHdr->aa = 0; 190 191 return m; 192 } 193 194 184 res = RTMemAllocZ(sizeof(*res)); 185 if (res == NULL) 186 return refuse_mbuf(m, RCode_ServFail); 187 188 res->pData = pData; 189 res->src = src; 190 res->sport = sport; 191 192 mlen = m_length(m, NULL); 193 m_copydata(m, 0, mlen, (char *)res->buf); 194 res->end = res->qlen = mlen; 195 196 rc = slirp_call_hostres(pData->pvUser, NULL, 0, 197 RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT, 198 (PFNRT)hostres_async, 1, res); 199 200 if (RT_FAILURE(rc)) 201 { 202 LogErr(("NAT: hostres: failed to post async request: %Rrc\n", rc)); 203 RTMemFree(res); 204 return refuse_mbuf(m, RCode_ServFail); 205 } 206 207 m_freem(pData, m); 208 return NULL; 209 } 210 211 212 /* 213 * Do quick sanity-checks on the request before doing async 214 * resolution. If we don't like it, immediately drop or convert to 215 * response in place and bounce back the mbuf. 216 */ 195 217 static int 196 218 verify_header(PNATState pData, struct mbuf **pMBuf) … … 201 223 202 224 m = *pMBuf; 225 mlen = m_length(m, NULL); 203 226 204 227 /* … … 215 238 pHdr = mtod(m, struct dnsmsg_header *); 216 239 240 if (RT_UNLIKELY(mlen < sizeof(*pHdr))) 241 { 242 LogErr(("NAT: hostres: packet too small: %zu bytes\n", mlen)); 243 goto drop; /* can't even refuse it */ 244 } 245 246 if (RT_UNLIKELY(mlen > DNS_MAX_UDP_LEN)) 247 { 248 LogErr(("NAT: hostres: packet too large: %zu bytes\n", mlen)); 249 goto drop; /* don't echo back huge packets */ 250 } 251 217 252 if (RT_UNLIKELY(pHdr->qr != QR_Query)) 218 253 { 219 254 LogErr(("NAT: hostres: unexpected response\n")); 220 goto drop; 221 } 222 223 mlen = m_length(m, NULL); 224 if (RT_UNLIKELY(mlen > DNS_MAX_UDP_LEN)) 225 { 226 LogErr(("NAT: hostres: packet too large\n")); 227 refuse(pData, m, RCode_FormErr); /* or drop? */ 228 return 1; 255 goto drop; /* ignore */ 229 256 } 230 257 231 258 if (RT_UNLIKELY(pHdr->opcode != OpCode_Query)) 232 259 { 233 LogErr(("NAT: hostres: unsupported opcode \n"));234 refuse (pData,m, RCode_NotImp);235 return 1;260 LogErr(("NAT: hostres: unsupported opcode %d\n", pHdr->opcode)); 261 refuse_mbuf(m, RCode_NotImp); 262 return VERR_PARSE_ERROR; 236 263 } 237 264 … … 239 266 { 240 267 LogErr(("NAT: hostres: multiple questions\n")); 241 refuse (pData,m, RCode_NotImp);242 return 1;268 refuse_mbuf(m, RCode_NotImp); 269 return VERR_PARSE_ERROR; 243 270 } 244 271 … … 246 273 { 247 274 LogErr(("NAT: hostres: answers in query\n")); 248 refuse(pData, m, RCode_NotImp); 249 return 1; 250 } 251 275 refuse_mbuf(m, RCode_NotImp); 276 return VERR_PARSE_ERROR; 277 } 278 279 /* XXX: let it fail when we parse it? */ 252 280 if (RT_UNLIKELY(mlen < sizeof(*pHdr) 253 281 + /* qname */ 1 … … 255 283 + /* qclass */ 2)) 256 284 { 257 LogErr(("NAT: hostres: packet too small \n"));258 refuse (pData,m, RCode_FormErr);259 return 1;260 } 261 262 return 0;285 LogErr(("NAT: hostres: packet too small: %zu bytes\n", mlen)); 286 refuse_mbuf(m, RCode_FormErr); 287 return VERR_PARSE_ERROR; 288 } 289 290 return VINF_SUCCESS; 263 291 264 292 drop: … … 266 294 m_freem(pData, m); 267 295 *pMBuf = NULL; 268 return 1; 269 } 270 271 296 return VERR_PARSE_ERROR; 297 } 298 299 300 /* 301 * Turn the request in mbuf into an error response. This is used on 302 * slirp thread for pre-checks before we do async resolution. 303 */ 272 304 static struct mbuf * 273 respond(PNATState pData, struct mbuf *m, struct response *res) 305 refuse_mbuf(struct mbuf *m, unsigned int rcode) 306 { 307 struct dnsmsg_header *pHdr; 308 309 pHdr = mtod(m, struct dnsmsg_header *); 310 pHdr->qr = QR_Response; 311 pHdr->rcode = rcode; 312 pHdr->ra = 1; 313 pHdr->aa = 0; 314 315 return m; 316 } 317 318 319 /* 320 * Actuall resolution runs on the dedicated host resolver thread. 321 */ 322 static void 323 hostres_async(struct response *res) 324 { 325 int rc; 326 327 /* build reply in res->buf[] */ 328 respond(res); 329 330 free_labels(res->labels); 331 332 rc = slirp_call(res->pData->pvUser, NULL, 0, 333 RTREQFLAGS_VOID | RTREQFLAGS_NO_WAIT, 334 (PFNRT)hostres_slirp_reply, 1, res); 335 336 if (RT_FAILURE(rc)) 337 { 338 LogErr(("NAT: hostres: failed to post async reply: %Rrc\n", rc)); 339 RTMemFree(res); 340 } 341 } 342 343 344 /* 345 * We are back to the slirp thread to send the reply. 346 */ 347 static void 348 hostres_slirp_reply(struct response *res) 349 { 350 PNATState pData = res->pData; 351 struct sockaddr_in src, dst; 352 struct mbuf *m = NULL; 353 size_t mlen; 354 int ok; 355 356 mlen = if_maxlinkhdr + sizeof(struct ip) + sizeof(struct udphdr); 357 mlen += res->end; 358 359 if (mlen <= MHLEN) 360 { 361 m = m_gethdr(pData, M_NOWAIT, MT_HEADER); 362 } 363 else 364 { 365 void *pvBuf; /* ignored */ 366 size_t cbBuf; 367 368 m = slirp_ext_m_get(pData, mlen, &pvBuf, &cbBuf); 369 } 370 371 if (m == NULL) 372 goto out; 373 374 /* reserve leading space for ethernet header */ 375 m->m_data += if_maxlinkhdr; 376 377 /* reserve leading space for protocol headers */ 378 m->m_pkthdr.header = mtod(m, void *); 379 m->m_data += sizeof(struct ip) + sizeof(struct udphdr); 380 381 m->m_len = 0; 382 ok = m_append(pData, m, res->end, (c_caddr_t)res->buf); 383 if (!ok) 384 { 385 m_freem(pData, m); 386 goto out; 387 } 388 389 src.sin_addr.s_addr = RT_H2N_U32(RT_N2H_U32(pData->special_addr.s_addr) | CTL_DNS); 390 src.sin_port = RT_H2N_U16_C(53); 391 dst.sin_addr.s_addr = res->src; 392 dst.sin_port = res->sport; 393 394 udp_output2(pData, NULL, m, &src, &dst, IPTOS_LOWDELAY); 395 396 out: 397 RTMemFree(res); 398 } 399 400 401 static int 402 respond(struct response *res) 274 403 { 275 404 struct dnsmsg_header *pHdr; … … 281 410 struct label *l; 282 411 283 /**284 * Copy the request into the contiguous buffer for the response285 * and parse the question.286 */287 288 mlen = m_length(m, NULL);289 m_copydata(m, 0, mlen, (char *)res->buf);290 res->end = res->qlen = mlen;291 292 412 /* convert header to response */ 293 413 pHdr = (struct dnsmsg_header *)res->buf; … … 305 425 * compression in the answer. 306 426 */ 307 while (off < mlen) {427 while (off < res->qlen) { 308 428 size_t loff, llen; 309 429 uint8_t c; … … 319 439 { 320 440 LogErr(("NAT: hostres: label pointer in the qname\n")); 321 return refuse( pData, m, RCode_FormErr);441 return refuse(res, RCode_FormErr); 322 442 } 323 443 … … 325 445 { 326 446 LogErr(("NAT: hostres: unexpected high bits\n")); 327 return refuse( pData, m, RCode_FormErr);447 return refuse(res, RCode_FormErr); 328 448 } 329 449 … … 335 455 ++off; 336 456 337 if (loff + 1 + llen > mlen)457 if (loff + 1 + llen > res->qlen) 338 458 { 339 459 LogErr(("NAT: hostres: length byte points beyound packet boundary\n")); 340 return refuse( pData, m, RCode_FormErr);460 return refuse(res, RCode_FormErr); 341 461 } 342 462 … … 355 475 { 356 476 LogErr(("NAT: hostres: dot inside label\n")); 357 return refuse( pData, m, RCode_FormErr);477 return refuse(res, RCode_FormErr); 358 478 } 359 479 … … 361 481 { 362 482 LogErr(("NAT: hostres: nul byte inside label\n")); 363 return refuse( pData, m, RCode_FormErr);483 return refuse(res, RCode_FormErr); 364 484 } 365 485 } … … 375 495 * QTYPE and QCLASS 376 496 */ 377 if (RT_UNLIKELY(off + 4 > mlen))497 if (RT_UNLIKELY(off + 4 > res->qlen)) 378 498 { 379 499 LogErr(("NAT: hostres: question too short\n")); 380 return refuse( pData, m, RCode_FormErr);500 return refuse(res, RCode_FormErr); 381 501 } 382 502 … … 393 513 { 394 514 LogErr(("NAT: hostres: unsupported qclass %d\n", qclass)); 395 return refuse( pData, m, RCode_NotImp);515 return refuse(res, RCode_NotImp); 396 516 } 397 517 … … 402 522 { 403 523 LogErr(("NAT: hostres: unsupported qtype %d\n", qtype)); 404 return refuse( pData, m, RCode_NotImp);524 return refuse(res, RCode_NotImp); 405 525 } 406 526 … … 415 535 * pointers, so truncating the buffer is safe. 416 536 */ 417 if (off < mlen)418 { 419 int trailer = mlen - off;420 421 LogDbg(("NAT: hostres: question %zu < mlen %zu\n", off, mlen));537 if (off < res->qlen) 538 { 539 int trailer = res->qlen - off; 540 541 LogDbg(("NAT: hostres: question %zu < mlen %zu\n", off, res->qlen)); 422 542 423 543 if (pHdr->nscount == 0 && pHdr->arcount == 0) 424 544 { 425 545 LogErr(("NAT: hostres: unexpected %d bytes after the question\n", trailer)); 426 return refuse( pData, m, RCode_FormErr);546 return refuse(res, RCode_FormErr); 427 547 } 428 548 … … 433 553 pHdr->arcount != 0 ? "additional" : "")); 434 554 435 m_adj(m, -trailer); 436 mlen -= trailer; 437 res->end = res->qlen = mlen; 555 res->qlen -= trailer; 556 res->end = res->qlen; 438 557 439 558 pHdr->nscount = 0; … … 448 567 */ 449 568 if (get_in_addr_arpa(&in_addr_arpa, res->labels)) 450 return resolve_reverse( pData, m,res, qtype, qname, in_addr_arpa);569 return resolve_reverse(res, qtype, qname, in_addr_arpa); 451 570 else 452 return resolve(pData, m, res, qtype, qname); 453 } 454 455 456 struct mbuf * 457 resolve(PNATState pData, struct mbuf *m, struct response *res, 458 uint16_t qtype, size_t qname) 571 return resolve(res, qtype, qname); 572 } 573 574 575 static int 576 resolve(struct response *res, uint16_t qtype, size_t qname) 459 577 { 460 578 struct dnsmsg_header *pHdr; … … 485 603 #ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER 486 604 { 487 PDNSMAPPINGENTRY pDNSMapingEntry = getDNSMapByName( pData, name);605 PDNSMAPPINGENTRY pDNSMapingEntry = getDNSMapByName(res->pData, name); 488 606 if (pDNSMapingEntry != NULL) 489 607 { … … 520 638 { 521 639 /* LogErr: h_errno */ 522 return refuse( pData, m, RCode_NXDomain);640 return refuse(res, RCode_NXDomain); 523 641 } 524 642 … … 537 655 538 656 #ifdef VBOX_WITH_DNSMAPPING_IN_HOSTRESOLVER 539 alterHostentWithDataFromDNSMap( pData, h);657 alterHostentWithDataFromDNSMap(res->pData, h); 540 658 #endif 541 659 … … 557 675 name, h->h_name)); 558 676 if (nbytes < 0) 559 return refuse( pData, m, RCode_ServFail);677 return refuse(res, RCode_ServFail); 560 678 else 561 679 { … … 598 716 cname, addr.s_addr)); 599 717 if (nbytes < 0) 600 return refuse( pData, m, RCode_ServFail);718 return refuse(res, RCode_ServFail); 601 719 else 602 720 { … … 634 752 635 753 out: 636 if (nanswers > 0) 637 { 638 int ok = m_append(pData, m, res->end - oend, (caddr_t)&res->buf[oend]); 639 if (!ok) 640 { 641 /* XXX: this may fail part way: restore old lenght, clear TC? */ 642 return refuse(pData, m, RCode_ServFail); 643 } 644 pHdr->ancount = RT_H2N_U16(nanswers); 645 } 646 memcpy(mtod(m, char *), res->buf, sizeof(struct dnsmsg_header)); 647 return m; 648 } 649 650 651 struct mbuf * 652 resolve_reverse(PNATState pData, struct mbuf *m, struct response *res, 653 uint16_t qtype, size_t qname, struct in_addr in_addr_arpa) 754 pHdr->ancount = RT_H2N_U16(nanswers); 755 return VINF_SUCCESS; 756 } 757 758 759 static int 760 resolve_reverse(struct response *res, uint16_t qtype, size_t qname, 761 struct in_addr in_addr_arpa) 654 762 { 655 763 struct dnsmsg_header *pHdr; … … 684 792 */ 685 793 { 686 PDNSMAPPINGENTRY pReverseMapping = getDNSMapByAddr( pData, &in_addr_arpa.s_addr);794 PDNSMAPPINGENTRY pReverseMapping = getDNSMapByAddr(res->pData, &in_addr_arpa.s_addr); 687 795 if (pReverseMapping != NULL) 688 796 { … … 712 820 { 713 821 /* LogErr: h_errno */ 714 return refuse( pData, m, RCode_NXDomain);822 return refuse(res, RCode_NXDomain); 715 823 } 716 824 … … 731 839 name, h->h_name)); 732 840 if (nbytes < 0) 733 return refuse( pData, m, RCode_ServFail);841 return refuse(res, RCode_ServFail); 734 842 else 735 843 { … … 741 849 742 850 out: 743 if (nanswers > 0) 744 { 745 int ok = m_append(pData, m, res->end - oend, (caddr_t)&res->buf[oend]); 746 if (!ok) 747 { 748 /* XXX: this may fail part way: restore old lenght, clear TC? */ 749 return refuse(pData, m, RCode_ServFail); 750 } 751 pHdr->ancount = RT_H2N_U16(nanswers); 752 } 753 memcpy(mtod(m, char *), res->buf, sizeof(struct dnsmsg_header)); 754 return m; 755 } 756 851 pHdr->ancount = RT_H2N_U16(nanswers); 852 return VINF_SUCCESS; 853 } 854 855 856 static int 857 refuse(struct response *res, unsigned int rcode) 858 { 859 struct dnsmsg_header *pHdr = (struct dnsmsg_header *)res->buf; 860 pHdr->rcode = rcode; 861 862 return VINF_SUCCESS; 863 } 757 864 758 865 -
trunk/src/VBox/Devices/Network/slirp/libslirp.h
r59219 r60142 38 38 39 39 #include <VBox/types.h> 40 #include <iprt/req.h> 40 41 41 42 typedef struct NATState *PNATState; … … 71 72 void slirp_urg_output(void *pvUser, struct mbuf *, const uint8_t *pu8Buf, int cb); 72 73 void slirp_post_sent(PNATState pData, void *pvArg); 74 75 int slirp_call(void *pvUser, PRTREQ *ppReq, RTMSINTERVAL cMillies, 76 unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...); 77 78 int slirp_call_hostres(void *pvUser, PRTREQ *ppReq, RTMSINTERVAL cMillies, 79 unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...); 80 73 81 74 82 void slirp_update_guest_addr_guess(PNATState pData, uint32_t guess, const char *msg); -
trunk/src/VBox/Devices/Network/slirp/slirp.h
r59142 r60142 352 352 353 353 /* hostres.c */ 354 struct mbuf *hostresolver(PNATState, struct mbuf * );354 struct mbuf *hostresolver(PNATState, struct mbuf *, uint32_t src, uint16_t sport); 355 355 356 356 /*slirp.c*/ -
trunk/src/VBox/Devices/Network/slirp/udp.c
r59143 r60142 199 199 m_adj(m, sizeof(struct udpiphdr)); 200 200 201 m = hostresolver(pData, m );201 m = hostresolver(pData, m, ip->ip_src.s_addr, uh->uh_sport); 202 202 if (m == NULL) 203 203 goto done_free_mbuf;
Note:
See TracChangeset
for help on using the changeset viewer.