Changeset 15086 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Dec 8, 2008 5:12:59 AM (16 years ago)
- Location:
- trunk/src/VBox/Devices/Network/slirp
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/ip_icmp.c
r15062 r15086 80 80 #else 81 81 pData->icmp_socket.s = IcmpCreateFile(); 82 pData->phEvents[VBOX_ICMP_EVENT_INDEX] = CreateEvent(NULL, FALSE, FALSE, NULL); 82 83 #endif 83 84 insque(pData, &pData->icmp_socket, &udb); … … 279 280 memset(&ipopt, 0, sizeof(IP_OPTION_INFORMATION)); 280 281 ipopt.Ttl = ip->ip_ttl; 281 m->m_ext = malloc(1500); 282 status = IcmpSendEcho(pData->icmp_socket.s, VBOX_SOCKET_EVENT, &addr, icp, icmplen, m->m_ext, 1500, 0); 282 status = IcmpSendEcho2(pData->icmp_socket.s, pData->phEvents[VBOX_ICMP_EVENT_INDEX], NULL, NULL, &addr, icp, icmplen, &ipopt, pData->pvIcmpBuffer, pData->szIcmpBuffer, 0); 283 283 if (status == 0) { 284 284 LogRel(("error(%d) occured while sending ICMP\n", GetLastError())); -
trunk/src/VBox/Devices/Network/slirp/libslirp.h
r14964 r15086 69 69 #define VBOX_SOCKET_EVENT_INDEX 1 70 70 71 #ifdef VBOX_WITH_SLIRP_ICMP 72 /* 73 * ICMP handle state change 74 */ 75 #define VBOX_ICMP_EVENT_INDEX 2 76 77 /* 78 * The number of events for WSAWaitForMultipleEvents(). 79 */ 80 #define VBOX_EVENT_COUNT 3 81 #else 71 82 /* 72 83 * The number of events for WSAWaitForMultipleEvents(). 73 84 */ 74 85 #define VBOX_EVENT_COUNT 2 86 87 #endif 75 88 76 89 HANDLE *slirp_get_events(PNATState pData); -
trunk/src/VBox/Devices/Network/slirp/slirp_state.h
r15054 r15086 137 137 struct socket icmp_socket; 138 138 struct icmp_storage icmp_msg_head; 139 #ifdef RT_OS_WINDOWS 140 void *pvIcmpBuffer; 141 size_t szIcmpBuffer; 142 #endif 139 143 #endif 140 144 #if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && defined(RT_OS_WINDOWS) -
trunk/src/VBox/Devices/Network/slirp/socket.c
r15061 r15086 13 13 #include <sys/filio.h> 14 14 #endif 15 #if defined(VBOX_WITH_SLIRP_ICMP) && defined (RT_OS_WINDOWS) 16 #include <icmpapi.h> 17 #endif 18 19 #ifdef VBOX_WITH_SLIRP_ICMP 20 static void send_icmp_to_guest(PNATState, char *, struct socket *); 21 static void sorecvfrom_icmp_win(PNATState, struct socket *); 22 #endif 23 static void sorecvfrom_icmp_unix(PNATState, struct socket *); 15 24 16 25 void … … 423 432 DEBUG_ARG("so = %lx", (long)so); 424 433 425 if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */ 426 char buff[1500]; 427 int len; 428 len = recvfrom(so->s, buff, 1500, 0, 429 (struct sockaddr *)&addr, &addrlen); 430 /* XXX Check if reply is "correct"? */ 431 432 if(len == -1 || len == 0) 433 { 434 u_char code = ICMP_UNREACH_PORT; 435 436 if (errno == EHOSTUNREACH) 437 code=ICMP_UNREACH_HOST; 438 else if(errno == ENETUNREACH) 439 code=ICMP_UNREACH_NET; 440 441 442 DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n", 443 errno,strerror(errno))); 444 icmp_error(pData, so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); 445 } 446 else 447 { 448 #ifdef VBOX_WITH_SLIRP_ICMP 449 struct ip *ip; 450 uint32_t dst,src; 451 char ip_copy[256]; 452 struct icmp *icp; 453 int old_ip_len; 454 struct mbuf *m; 455 struct icmp_msg *icm; 456 457 ip = (struct ip *)buff; 458 icp = (struct icmp *)((char *)ip + (ip->ip_hl << 2)); 459 460 Assert(icp->icmp_type == ICMP_ECHOREPLY || icp->icmp_type == ICMP_TIMXCEED); 461 462 if (icp->icmp_type == ICMP_TIMXCEED ) { 463 ip = &icp->icmp_ip; 464 } 465 466 icm = icmp_find_original_mbuf(pData, ip); 467 468 if (icm == NULL) { 469 LogRel(("Can't find the corresponding packet for the received ICMP\n")); 470 return; 471 } 472 473 m = icm->im_m; 474 Assert(m != NULL); 475 476 src = addr.sin_addr.s_addr; 477 478 ip = mtod(m, struct ip *); 479 /* Now ip is pointing on header we've sent from guest */ 480 if (icp->icmp_type == ICMP_TIMXCEED) { 481 old_ip_len = (ip->ip_hl << 2) + 64; 482 memcpy(ip_copy, ip, old_ip_len); 483 } 484 485 /* source address from original IP packet*/ 486 dst = ip->ip_src.s_addr; 487 488 /* overide ther tail of old packet */ 489 memcpy(m->m_data, buff, len); 490 m->m_len = len; 491 ip = mtod(m, struct ip *); /* ip is from mbuf we've overrided */ 492 493 icp = (struct icmp *)((char *)ip + (ip->ip_hl << 2)); 494 if (icp->icmp_type == ICMP_TIMXCEED) { 495 /* according RFC 793 error messages required copy of initial IP header + 64 bit */ 496 memcpy(&icp->icmp_ip, ip_copy, old_ip_len); 497 ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */ 498 } 499 500 /* the low level expects fields to be in host format so let's convert them*/ 501 NTOHS(ip->ip_len); 502 NTOHS(ip->ip_off); 503 NTOHS(ip->ip_id); 504 ip->ip_src.s_addr = src; 505 ip->ip_dst.s_addr = dst; 506 icmp_reflect(pData, m); 507 LIST_REMOVE(icm, im_list); 508 /* Don't call m_free here*/ 509 free(icm); 510 #else 511 icmp_reflect(pData, so->so_m); 512 so->so_m = 0; /* Don't m_free() it again! */ 513 #endif 514 } 515 /* No need for this socket anymore, udp_detach it */ 434 if (so->so_type == IPPROTO_ICMP) { /* This is a "ping" reply */ 435 sorecvfrom_icmp_unix(pData, so); 516 436 udp_detach(pData, so); 517 437 } else { /* A "normal" UDP packet */ 518 438 struct mbuf *m; 519 439 int len, n; … … 843 763 sofcantsendmore(so); 844 764 } 765 766 #ifdef VBOX_WITH_SLIRP_ICMP 767 static void 768 send_icmp_to_guest(PNATState pData, char *buff, struct socket *so) 769 { 770 struct ip *ip; 771 uint32_t dst,src; 772 char ip_copy[256]; 773 struct icmp *icp; 774 int old_ip_len; 775 struct mbuf *m; 776 struct icmp_msg *icm; 777 778 ip = (struct ip *)buff; 779 icp = (struct icmp *)((char *)ip + (ip->ip_hl << 2)); 780 781 Assert(icp->icmp_type == ICMP_ECHOREPLY || icp->icmp_type == ICMP_TIMXCEED); 782 783 if (icp->icmp_type == ICMP_TIMXCEED ) { 784 ip = &icp->icmp_ip; 785 } 786 787 icm = icmp_find_original_mbuf(pData, ip); 788 789 if (icm == NULL) { 790 LogRel(("Can't find the corresponding packet for the received ICMP\n")); 791 return; 792 } 793 794 m = icm->im_m; 795 Assert(m != NULL); 796 797 src = addr.sin_addr.s_addr; 798 799 ip = mtod(m, struct ip *); 800 /* Now ip is pointing on header we've sent from guest */ 801 if (icp->icmp_type == ICMP_TIMXCEED) { 802 old_ip_len = (ip->ip_hl << 2) + 64; 803 memcpy(ip_copy, ip, old_ip_len); 804 } 805 806 /* source address from original IP packet*/ 807 dst = ip->ip_src.s_addr; 808 809 /* overide ther tail of old packet */ 810 memcpy(m->m_data, buff, len); 811 m->m_len = len; 812 ip = mtod(m, struct ip *); /* ip is from mbuf we've overrided */ 813 814 icp = (struct icmp *)((char *)ip + (ip->ip_hl << 2)); 815 if (icp->icmp_type == ICMP_TIMXCEED) { 816 /* according RFC 793 error messages required copy of initial IP header + 64 bit */ 817 memcpy(&icp->icmp_ip, ip_copy, old_ip_len); 818 ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */ 819 } 820 821 /* the low level expects fields to be in host format so let's convert them*/ 822 NTOHS(ip->ip_len); 823 NTOHS(ip->ip_off); 824 NTOHS(ip->ip_id); 825 ip->ip_src.s_addr = src; 826 ip->ip_dst.s_addr = dst; 827 icmp_reflect(pData, m); 828 LIST_REMOVE(icm, im_list); 829 /* Don't call m_free here*/ 830 free(icm); 831 } 832 #endif 833 static void sorecvfrom_icmp_win(PNATState pData, struct socket *so){ 834 #if 0 835 int i; 836 len = IcmpParseReplies(pData->pvIcmpBuffer, pData->szIcmpBuffer); 837 #endif 838 } 839 static void sorecvfrom_icmp_unix(PNATState pData, struct socket *so) 840 { 841 struct sockaddr_in addr; 842 socklen_t addrlen = sizeof(struct sockaddr_in); 843 char buff[1500]; 844 int len; 845 len = recvfrom(so->s, buff, 1500, 0, 846 (struct sockaddr *)&addr, &addrlen); 847 /* XXX Check if reply is "correct"? */ 848 849 if(len == -1 || len == 0) 850 { 851 u_char code = ICMP_UNREACH_PORT; 852 853 if (errno == EHOSTUNREACH) 854 code=ICMP_UNREACH_HOST; 855 else if(errno == ENETUNREACH) 856 code=ICMP_UNREACH_NET; 857 858 859 DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n", 860 errno,strerror(errno))); 861 icmp_error(pData, so->so_m, ICMP_UNREACH,code, 0,strerror(errno)); 862 } 863 else 864 { 865 #ifdef VBOX_WITH_SLIRP_ICMP 866 send_icmp_to_guest(pData, buff, so); 867 #else 868 icmp_reflect(pData, so->so_m); 869 so->so_m = 0; /* Don't m_free() it again! */ 870 #endif 871 } 872 } 873
Note:
See TracChangeset
for help on using the changeset viewer.