VirtualBox

Changeset 15086 in vbox for trunk/src/VBox/Devices/Network


Ignore:
Timestamp:
Dec 8, 2008 5:12:59 AM (16 years ago)
Author:
vboxsync
Message:

slirp:ICMP: windows support (mostly reorganization, shouldn't compile on windows)

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  
    8080#else
    8181        pData->icmp_socket.s = IcmpCreateFile();
     82        pData->phEvents[VBOX_ICMP_EVENT_INDEX] = CreateEvent(NULL, FALSE, FALSE, NULL);
    8283#endif
    8384        insque(pData, &pData->icmp_socket, &udb);
     
    279280      memset(&ipopt, 0, sizeof(IP_OPTION_INFORMATION));
    280281      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);
    283283      if (status == 0) {
    284284            LogRel(("error(%d) occured while sending ICMP\n", GetLastError()));
  • trunk/src/VBox/Devices/Network/slirp/libslirp.h

    r14964 r15086  
    6969#define VBOX_SOCKET_EVENT_INDEX         1
    7070
     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
    7182/*
    7283 * The number of events for WSAWaitForMultipleEvents().
    7384 */
    7485#define VBOX_EVENT_COUNT                2
     86
     87#endif
    7588
    7689HANDLE *slirp_get_events(PNATState pData);
  • trunk/src/VBox/Devices/Network/slirp/slirp_state.h

    r15054 r15086  
    137137    struct socket icmp_socket;
    138138    struct icmp_storage icmp_msg_head;
     139#ifdef RT_OS_WINDOWS
     140    void *pvIcmpBuffer;
     141    size_t szIcmpBuffer;
     142#endif
    139143#endif
    140144#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && defined(RT_OS_WINDOWS)
  • trunk/src/VBox/Devices/Network/slirp/socket.c

    r15061 r15086  
    1313#include <sys/filio.h>
    1414#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
     20static void send_icmp_to_guest(PNATState, char *, struct socket *);
     21static void sorecvfrom_icmp_win(PNATState, struct socket *);
     22#endif
     23static void sorecvfrom_icmp_unix(PNATState, struct socket *);
    1524
    1625void
     
    423432    DEBUG_ARG("so = %lx", (long)so);
    424433
    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);
    516436          udp_detach(pData, so);
    517         } else {                                /* A "normal" UDP packet */
     437    } else {                                /* A "normal" UDP packet */
    518438          struct mbuf *m;
    519439          int len, n;
     
    843763        sofcantsendmore(so);
    844764}
     765
     766#ifdef VBOX_WITH_SLIRP_ICMP
     767static void
     768send_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
     833static 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}
     839static 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.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette