VirtualBox

Changeset 53399 in vbox for trunk


Ignore:
Timestamp:
Nov 25, 2014 10:49:59 PM (10 years ago)
Author:
vboxsync
Message:

NAT: new Windows ping proxy that is not limited to just one
outstanding ping of 360 bytes max. Mostly adapted from NAT Network
pxping_win.c.

Location:
trunk/src/VBox/Devices/Network
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DrvNAT.cpp

    r52976 r53399  
    833833        DWORD dwEvent = WSAWaitForMultipleEvents(nFDs, phEvents, FALSE,
    834834                                                 slirp_get_timeout_ms(pThis->pNATState),
    835                                                  FALSE);
     835                                                 /* :fAlertable */ TRUE);
    836836        if (   (dwEvent < WSA_WAIT_EVENT_0 || dwEvent > WSA_WAIT_EVENT_0 + nFDs - 1)
    837             && dwEvent != WSA_WAIT_TIMEOUT)
     837            && dwEvent != WSA_WAIT_TIMEOUT && dwEvent != WSA_WAIT_IO_COMPLETION)
    838838        {
    839839            int error = WSAGetLastError();
     
    845845        {
    846846            /* only check for slow/fast timers */
    847             slirp_select_poll(pThis->pNATState, /* fTimeout=*/true, /*fIcmp=*/false);
     847            slirp_select_poll(pThis->pNATState, /* fTimeout=*/true);
    848848            continue;
    849849        }
    850850        /* poll the sockets in any case */
    851851        Log2(("%s: poll\n", __FUNCTION__));
    852         slirp_select_poll(pThis->pNATState, /* fTimeout=*/false, /* fIcmp=*/(dwEvent == WSA_WAIT_EVENT_0));
     852        slirp_select_poll(pThis->pNATState, /* fTimeout=*/false);
    853853        /* process _all_ outstanding requests but don't wait */
    854854        RTReqQueueProcess(pThis->hSlirpReqQueue, 0);
  • trunk/src/VBox/Devices/Network/slirp/ip_icmp.c

    r53309 r53399  
    5656#include "slirp.h"
    5757#include "ip_icmp.h"
    58 #ifdef RT_OS_WINDOWS
    59 # include <Icmpapi.h>
    60 # include <Iphlpapi.h>
    61 # include <iprt/ldr.h>
    62 #endif
    6358
    6459/* The message sent when emulating PING */
     
    9792    pData->icmp_socket.so_type = IPPROTO_ICMP;
    9893    pData->icmp_socket.so_state = SS_ISFCONNECTED;
     94
     95#ifndef RT_OS_WINDOWS
    9996    if (iIcmpCacheLimit < 0)
    10097    {
     
    103100    }
    104101    pData->iIcmpCacheLimit = iIcmpCacheLimit;
    105 #ifndef RT_OS_WINDOWS
    106102# ifndef RT_OS_DARWIN
    107103    pData->icmp_socket.s = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
     
    118114    NSOCK_INC();
    119115
     116    LIST_INIT(&pData->icmp_msg_head);
     117
    120118#else /* RT_OS_WINDOWS */
    121119    if (icmpwin_init(pData) != 0)
     
    123121#endif /* RT_OS_WINDOWS */
    124122
    125     LIST_INIT(&pData->icmp_msg_head);
    126123    return 0;
    127124}
     
    133130icmp_finit(PNATState pData)
    134131{
    135     icmp_cache_clean(pData, -1);
    136132#ifdef RT_OS_WINDOWS
    137133    icmpwin_finit(pData);
    138134#else
     135    icmp_cache_clean(pData, -1);
    139136    closesocket(pData->icmp_socket.s);
    140137#endif
    141138}
    142139
     140#if !defined(RT_OS_WINDOWS)
    143141/*
    144142 * ip here is ip header + 64bytes readed from ICMP packet
     
    339337    return 0;
    340338}
     339#endif /* !RT_OS_WINDOWS */
    341340
    342341/*
     
    350349    uint8_t icmp_type;
    351350    void *icp_buf = NULL;
    352     int status;
    353351    uint32_t dst;
    354 #if !defined(RT_OS_WINDOWS)
    355     int ttl;
    356 #endif
    357352
    358353    /* int code; */
     
    409404                goto done;
    410405            }
    411             else
     406
     407#ifdef RT_OS_WINDOWS
     408            {
     409                icmpwin_ping(pData, m, hlen);
     410                break;          /* free mbuf */
     411            }
     412#else
    412413            {
    413414                struct icmp *icp;
    414415                struct sockaddr_in addr;
    415 #ifdef RT_OS_WINDOWS
    416                 IP_OPTION_INFORMATION ipopt;
    417                 int error;
    418 #endif
     416
     417                /* XXX: FIXME: this is bogus, see CTL_CHECKs above */
    419418                addr.sin_family = AF_INET;
    420419                if ((ip->ip_dst.s_addr & RT_H2N_U32(pData->netmask)) == pData->special_addr.s_addr)
     
    447446                    icp = (struct icmp *)(mtod(m, char *) + hlen);
    448447
    449 #ifndef RT_OS_WINDOWS
    450448                if (pData->icmp_socket.s != -1)
    451449                {
     450                    static bool fIcmpSocketErrorReported;
     451                    int ttl;
     452                    int status;
    452453                    ssize_t rc;
    453                     static bool fIcmpSocketErrorReported;
     454
    454455                    ttl = ip->ip_ttl;
    455456                    Log(("NAT/ICMP: try to set TTL(%d)\n", ttl));
     
    478479                    icmp_error(pData, m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno));
    479480                }
    480 #else /* RT_OS_WINDOWS */
    481                 pData->icmp_socket.so_laddr.s_addr = ip->ip_src.s_addr; /* XXX: hack*/
    482                 pData->icmp_socket.so_icmp_id = icp->icmp_id;
    483                 pData->icmp_socket.so_icmp_seq = icp->icmp_seq;
    484                 memset(&ipopt, 0, sizeof(IP_OPTION_INFORMATION));
    485                 ipopt.Ttl = ip->ip_ttl;
    486                 status = IcmpSendEcho2(pData->icmp_socket.sh /*=handle*/,
    487                                        pData->phEvents[VBOX_ICMP_EVENT_INDEX] /*=Event*/,
    488                                        NULL /*=ApcRoutine*/,
    489                                        NULL /*=ApcContext*/,
    490                                        addr.sin_addr.s_addr /*=DestinationAddress*/,
    491                                        icp->icmp_data /*=RequestData*/,
    492                                        icmplen - ICMP_MINLEN /*=RequestSize*/,
    493                                        &ipopt /*=RequestOptions*/,
    494                                        pData->pvIcmpBuffer /*=ReplyBuffer*/,
    495                                        pData->cbIcmpBuffer /*=ReplySize*/,
    496                                        1 /*=Timeout in ms*/);
    497                 error = GetLastError();
    498                 if (   status != 0
    499                     || error == ERROR_IO_PENDING)
    500                 {
    501                     /* no error! */
    502                     m->m_so = &pData->icmp_socket;
    503                     icmp_attach(pData, m);
    504                     /* don't let m_freem at the end free atached buffer */
    505                     goto done;
    506                 }
    507                 Log(("NAT: Error (%d) occurred while sending ICMP (", error));
    508                 switch (error)
    509                 {
    510                     case ERROR_INVALID_PARAMETER:
    511                         Log(("icmp_socket:%lx is invalid)\n", pData->icmp_socket.s));
    512                         break;
    513                     case ERROR_NOT_SUPPORTED:
    514                         Log(("operation is unsupported)\n"));
    515                         break;
    516                     case ERROR_NOT_ENOUGH_MEMORY:
    517                         Log(("OOM!!!)\n"));
    518                         break;
    519                     case IP_BUF_TOO_SMALL:
    520                         Log(("Buffer too small)\n"));
    521                         break;
    522                     default:
    523                         Log(("Other error!!!)\n"));
    524                         break;
    525                 }
    526 #endif /* RT_OS_WINDOWS */
    527             } /* if ip->ip_dst.s_addr == alias_addr.s_addr */
     481            }
     482#endif  /* !RT_OS_WINDOWS */
    528483            break;
    529484        case ICMP_UNREACH:
  • trunk/src/VBox/Devices/Network/slirp/ip_icmp.h

    r53350 r53399  
    208208void icmpwin_finit (PNATState);
    209209void icmpwin_ping(PNATState, struct mbuf *, int);
     210void icmpwin_process(PNATState);
    210211#endif
    211212
  • trunk/src/VBox/Devices/Network/slirp/ip_icmpwin.c

    r53381 r53399  
    4141    PNATState pData;
    4242
     43    TAILQ_ENTRY(pong) queue_entry;
     44
    4345    struct ip reqiph;
    4446    struct icmp_echo reqicmph;
     
    5355
    5456static void icmpwin_callback(struct pong *pong);
     57static void icmpwin_pong(struct pong *pong);
    5558
    5659static struct mbuf *icmpwin_get_error(struct pong *pong, int type, int code);
     
    9194    }
    9295
     96    TAILQ_INIT(&pData->pongs_expected);
     97    TAILQ_INIT(&pData->pongs_received);
     98
    9399    pData->icmp_socket.sh = IcmpCreateFile();
    94100    pData->phEvents[VBOX_ICMP_EVENT_INDEX] = CreateEvent(NULL, FALSE, FALSE, NULL);
    95     pData->cbIcmpBuffer = sizeof(ICMP_ECHO_REPLY) * 10;
    96     pData->pvIcmpBuffer = RTMemAlloc(pData->cbIcmpBuffer);
    97101
    98102    return 0;
     
    104108{
    105109    IcmpCloseHandle(pData->icmp_socket.sh);
    106     RTMemFree(pData->pvIcmpBuffer);
     110
     111    while (!TAILQ_EMPTY(&pData->pongs_received)) {
     112        struct pong *pong = TAILQ_FIRST(&pData->pongs_received);
     113        TAILQ_REMOVE(&pData->pongs_received, pong, queue_entry);
     114        RTMemFree(pong);
     115    }
     116 
     117    /* this should be empty */
     118    while (!TAILQ_EMPTY(&pData->pongs_expected)) {
     119        struct pong *pong = TAILQ_FIRST(&pData->pongs_expected);
     120        TAILQ_REMOVE(&pData->pongs_expected, pong, queue_entry);
     121        pong->pData = NULL;
     122    }
    107123}
    108124
     
    115131{
    116132    struct ip *ip = mtod(m, struct ip *);
    117     size_t reqsize;
     133    size_t reqsize, pongsize;
    118134    uint8_t ttl;
    119135    size_t bufsize;
     
    137153    bufsize += 16; /* whatever that is; empirically at least XP needs it */
    138154
    139     pong = RTMemAlloc(RT_OFFSETOF(struct pong, buf) + bufsize);
     155    pongsize = RT_OFFSETOF(struct pong, buf) + bufsize;
     156    if (pData->cbIcmpPending + pongsize > 1024 * 1024)
     157        return;
     158
     159    pong = RTMemAlloc(pongsize);
    140160    if (RT_UNLIKELY(pong == NULL))
    141161        return;
     
    209229    else /* success */
    210230    {
    211         Log2(("NAT: pong %p for ping %RTnaipv4 id 0x%04x seq %d len %d\n",
     231        Log2(("NAT: pong %p for ping %RTnaipv4 id 0x%04x seq %d len %zu (%zu)\n",
    212232              pong, dst,
    213233              RT_N2H_U16(pong->reqicmph.icmp_echo_id),
    214234              RT_N2H_U16(pong->reqicmph.icmp_echo_seq),
    215               reqsize));
     235              pongsize, reqsize));
     236
     237        pData->cbIcmpPending += pongsize;
     238        TAILQ_INSERT_TAIL(&pData->pongs_expected, pong, queue_entry);
    216239        pong = NULL;            /* callback owns it now */
    217240    }
     
    226249{
    227250    struct pong *pong = (struct pong *)ctx;
    228 
    229251    if (pong != NULL)
    230     {
    231252        icmpwin_callback(pong);
    232         RTMemFree(pong);
    233     }
    234253}
    235254
     
    239258{
    240259    struct pong *pong = (struct pong *)ctx;
    241 
    242260    if (pong != NULL)
    243     {
    244261        icmpwin_callback(pong);
    245         RTMemFree(pong);
    246     }
    247262}
    248263
     
    251266 * Actual callback code for IcmpSendEcho2().  OS version specific
    252267 * trampoline will free "pong" argument for us.
     268 *
     269 * Since async callback can be called anytime the thread is alertable,
     270 * it's not safe to do any processing here.  Instead queue it and
     271 * notify the main loop.
    253272 */
    254273static void
    255274icmpwin_callback(struct pong *pong)
     275{
     276    PNATState pData = pong->pData;
     277
     278    if (pData == NULL)
     279    {
     280        RTMemFree(pong);
     281        return;
     282    }
     283
     284#ifdef DEBUG
     285    {
     286        struct pong *expected, *already;
     287
     288        TAILQ_FOREACH(expected, &pData->pongs_expected, queue_entry)
     289        {
     290            if (expected == pong)
     291                break;
     292        }
     293        Assert(expected);
     294
     295        TAILQ_FOREACH(already, &pData->pongs_received, queue_entry)
     296        {
     297            if (already == pong)
     298                break;
     299        }
     300        Assert(!already);
     301    }
     302#endif
     303
     304    TAILQ_REMOVE(&pData->pongs_expected, pong, queue_entry);
     305    TAILQ_INSERT_TAIL(&pData->pongs_received, pong, queue_entry);
     306
     307    WSASetEvent(pData->phEvents[VBOX_ICMP_EVENT_INDEX]);
     308}
     309
     310
     311void
     312icmpwin_process(PNATState pData)
     313{
     314    struct pong_tailq pongs;
     315
     316    if (TAILQ_EMPTY(&pData->pongs_received))
     317        return;
     318
     319    TAILQ_INIT(&pongs);
     320    TAILQ_CONCAT(&pongs, &pData->pongs_received, queue_entry);
     321
     322    while (!TAILQ_EMPTY(&pongs)) {
     323        struct pong *pong = TAILQ_FIRST(&pongs);
     324        size_t sz;
     325
     326        sz = RT_OFFSETOF(struct pong, buf) + pong->bufsize;
     327        Assert(pData->cbIcmpPending >= sz);
     328        pData->cbIcmpPending -= sz;
     329
     330        icmpwin_pong(pong);
     331
     332        TAILQ_REMOVE(&pongs, pong, queue_entry);
     333        RTMemFree(pong);
     334    }
     335}
     336
     337
     338void
     339icmpwin_pong(struct pong *pong)
    256340{
    257341    PNATState pData;
  • trunk/src/VBox/Devices/Network/slirp/libslirp.h

    r50949 r53399  
    5656void slirp_select_fill(PNATState pData, int *pndfs);
    5757
    58 void slirp_select_poll(PNATState pData, int fTimeout, int fIcmp);
     58void slirp_select_poll(PNATState pData, int fTimeout);
    5959#else /* RT_OS_WINDOWS */
    6060void slirp_select_fill(PNATState pData, int *pnfds, struct pollfd *polls);
  • trunk/src/VBox/Devices/Network/slirp/slirp.c

    r53338 r53399  
    892892
    893893#if defined(RT_OS_WINDOWS)
    894 void slirp_select_poll(PNATState pData, int fTimeout, int fIcmp)
     894void slirp_select_poll(PNATState pData, int fTimeout)
    895895#else /* RT_OS_WINDOWS */
    896896void slirp_select_poll(PNATState pData, struct pollfd *polls, int ndfs)
     
    942942        goto done;
    943943#if defined(RT_OS_WINDOWS)
    944     /*XXX: before renaming please make see define
    945      * fIcmp in slirp_state.h
    946      */
    947     if (fIcmp)
    948         sorecvfrom(pData, &pData->icmp_socket);
     944    icmpwin_process(pData);
    949945#else
    950946    if (   (pData->icmp_socket.s != -1)
  • trunk/src/VBox/Devices/Network/slirp/slirp_state.h

    r53382 r53399  
    9696
    9797
     98#ifdef RT_OS_WINDOWS
     99struct pong;
     100TAILQ_HEAD(pong_tailq, pong);
     101#endif
    98102
    99103/* forward declaration */
     
    199203
    200204    struct socket icmp_socket;
     205# if !defined(RT_OS_WINDOWS)
    201206    struct icmp_storage icmp_msg_head;
    202207    int cIcmpCacheSize;
    203208    int iIcmpCacheLimit;
    204 # ifdef RT_OS_WINDOWS
    205     void *pvIcmpBuffer;
    206     uint32_t cbIcmpBuffer;
     209# else
     210    struct pong_tailq pongs_expected;
     211    struct pong_tailq pongs_received;
     212    size_t cbIcmpPending;
    207213# endif
     214
    208215#if defined(RT_OS_WINDOWS)
    209216# define VBOX_SOCKET_EVENT (pData->phEvents[VBOX_SOCKET_EVENT_INDEX])
  • trunk/src/VBox/Devices/Network/slirp/socket.c

    r53310 r53399  
    128128}
    129129#endif /* !VBOX_WITH_NAT_SEND2HOME */
     130
     131#if !defined(RT_OS_WINDOWS)
    130132static void send_icmp_to_guest(PNATState, char *, size_t, const struct sockaddr_in *);
    131 #ifdef RT_OS_WINDOWS
    132 static void sorecvfrom_icmp_win(PNATState, struct socket *);
    133 #else /* RT_OS_WINDOWS */
    134133static void sorecvfrom_icmp_unix(PNATState, struct socket *);
    135134#endif /* !RT_OS_WINDOWS */
     
    811810{
    812811    LogFlowFunc(("sorecvfrom: so = %lx\n", (long)so));
    813 
     812 
     813#ifdef RT_OS_WINDOWS
     814    /* ping is handled with ICMP API in ip_icmpwin.c */
     815    Assert(so->so_type == IPPROTO_UDP);
     816#else
    814817    if (so->so_type == IPPROTO_ICMP)
    815818    {
    816819        /* This is a "ping" reply */
    817 #ifdef RT_OS_WINDOWS
    818         sorecvfrom_icmp_win(pData, so);
    819 #else /* RT_OS_WINDOWS */
    820820        sorecvfrom_icmp_unix(pData, so);
     821        udp_detach(pData, so);
     822    }
     823    else
    821824#endif /* !RT_OS_WINDOWS */
    822         udp_detach(pData, so);
    823     }
    824     else
    825825    {
    826826        static uint8_t au8Buf[64 * 1024];
     
    12721272}
    12731273
     1274#if !defined(RT_OS_WINDOWS)
    12741275static void
    12751276send_icmp_to_guest(PNATState pData, char *buff, size_t len, const struct sockaddr_in *addr)
     
    14421443}
    14431444
    1444 #ifdef RT_OS_WINDOWS
    1445 static void
    1446 sorecvfrom_icmp_win(PNATState pData, struct socket *so)
    1447 {
    1448     int len;
    1449     int i;
    1450     struct ip *ip;
    1451     struct mbuf *m;
    1452     struct icmp *icp;
    1453     struct icmp_msg *icm;
    1454     struct ip *ip_broken; /* ICMP returns header + 64 bit of packet */
    1455     uint32_t src;
    1456     ICMP_ECHO_REPLY *icr;
    1457     int hlen = 0;
    1458     int nbytes = 0;
    1459     u_char code = ~0;
    1460     int out_len;
    1461     int size;
    1462 
    1463     len = IcmpParseReplies(pData->pvIcmpBuffer, pData->cbIcmpBuffer);
    1464     if (len < 0)
    1465     {
    1466         LogRel(("NAT: Error (%d) occurred on ICMP receiving\n", GetLastError()));
    1467         return;
    1468     }
    1469     if (len == 0)
    1470         return; /* no error */
    1471 
    1472     icr = (ICMP_ECHO_REPLY *)pData->pvIcmpBuffer;
    1473     for (i = 0; i < len; ++i)
    1474     {
    1475         LogFunc(("icr[%d] Data:%p, DataSize:%d\n",
    1476                  i, icr[i].Data, icr[i].DataSize));
    1477         switch(icr[i].Status)
    1478         {
    1479             case IP_DEST_HOST_UNREACHABLE:
    1480                 code = (code != ~0 ? code : ICMP_UNREACH_HOST);
    1481             case IP_DEST_NET_UNREACHABLE:
    1482                 code = (code != ~0 ? code : ICMP_UNREACH_NET);
    1483             case IP_DEST_PROT_UNREACHABLE:
    1484                 code = (code != ~0 ? code : ICMP_UNREACH_PROTOCOL);
    1485                 /* UNREACH error inject here */
    1486             case IP_DEST_PORT_UNREACHABLE:
    1487                 code = (code != ~0 ? code : ICMP_UNREACH_PORT);
    1488                 icmp_error(pData, so->so_m, ICMP_UNREACH, code, 0, "Error occurred!!!");
    1489                 so->so_m = NULL;
    1490                 break;
    1491             case IP_SUCCESS: /* echo replied */
    1492                 out_len = ETH_HLEN + sizeof(struct ip) +  8;
    1493                 size;
    1494                 size = MCLBYTES;
    1495                 if (out_len < MSIZE)
    1496                     size = MCLBYTES;
    1497                 else if (out_len < MCLBYTES)
    1498                     size = MCLBYTES;
    1499                 else if (out_len < MJUM9BYTES)
    1500                     size = MJUM9BYTES;
    1501                 else if (out_len < MJUM16BYTES)
    1502                     size = MJUM16BYTES;
    1503                 else
    1504                     AssertMsgFailed(("Unsupported size"));
    1505 
    1506                 m = m_getjcl(pData, M_NOWAIT, MT_HEADER, M_PKTHDR, size);
    1507                 LogFunc(("m_getjcl returns m: %p\n", m));
    1508                 if (m == NULL)
    1509                     return;
    1510                 m->m_len = 0;
    1511                 m->m_data += if_maxlinkhdr;
    1512                 m->m_pkthdr.header = mtod(m, void *);
    1513 
    1514                 ip = mtod(m, struct ip *);
    1515                 ip->ip_src.s_addr = icr[i].Address;
    1516                 ip->ip_p = IPPROTO_ICMP;
    1517                 ip->ip_dst.s_addr = so->so_laddr.s_addr; /*XXX: still the hack*/
    1518                 ip->ip_hl =  sizeof(struct ip) >> 2; /* requiered for icmp_reflect, no IP options */
    1519                 ip->ip_ttl = icr[i].Options.Ttl;
    1520 
    1521                 icp = (struct icmp *)&ip[1]; /* no options */
    1522                 icp->icmp_type = ICMP_ECHOREPLY;
    1523                 icp->icmp_code = 0;
    1524                 icp->icmp_id = so->so_icmp_id;
    1525                 icp->icmp_seq = so->so_icmp_seq;
    1526 
    1527                 icm = icmp_find_original_mbuf(pData, ip);
    1528                 if (icm)
    1529                 {
    1530                     /* on this branch we don't need stored variant */
    1531                     m_freem(pData, icm->im_m);
    1532                     LIST_REMOVE(icm, im_list);
    1533                     pData->cIcmpCacheSize--;
    1534                     RTMemFree(icm);
    1535                 }
    1536 
    1537 
    1538                 hlen = (ip->ip_hl << 2);
    1539                 Assert((hlen >= sizeof(struct ip)));
    1540 
    1541                 m->m_data += hlen + ICMP_MINLEN;
    1542                 if (!RT_VALID_PTR(icr[i].Data))
    1543                 {
    1544                     m_freem(pData, m);
    1545                     break;
    1546                 }
    1547                 m_copyback(pData, m, 0, icr[i].DataSize, icr[i].Data);
    1548                 m->m_data -= hlen + ICMP_MINLEN;
    1549                 m->m_len += hlen + ICMP_MINLEN;
    1550 
    1551 
    1552                 ip->ip_len = m_length(m, NULL);
    1553                 Assert((ip->ip_len == hlen + ICMP_MINLEN + icr[i].DataSize));
    1554 
    1555                 icmp_reflect(pData, m);
    1556                 break;
    1557             case IP_TTL_EXPIRED_TRANSIT: /* TTL expired */
    1558 
    1559                 ip_broken = icr[i].Data;
    1560                 icm = icmp_find_original_mbuf(pData, ip_broken);
    1561                 if (icm == NULL) {
    1562                     Log(("ICMP: can't find original package (first double word %x)\n", *(uint32_t *)ip_broken));
    1563                     return;
    1564                 }
    1565                 m = icm->im_m;
    1566                 ip = mtod(m, struct ip *);
    1567                 Assert(((ip_broken->ip_hl >> 2) >= sizeof(struct ip)));
    1568                 ip->ip_ttl = icr[i].Options.Ttl;
    1569                 src = ip->ip_src.s_addr;
    1570                 ip->ip_dst.s_addr = src;
    1571                 ip->ip_dst.s_addr = icr[i].Address;
    1572 
    1573                 hlen = (ip->ip_hl << 2);
    1574                 icp = (struct icmp *)((char *)ip + hlen);
    1575                 ip_broken->ip_src.s_addr = src; /*it packet sent from host not from guest*/
    1576 
    1577                 m->m_len = (ip_broken->ip_hl << 2) + 64;
    1578                 m->m_pkthdr.header = mtod(m, void *);
    1579                 m_copyback(pData, m, ip->ip_hl >> 2, icr[i].DataSize, icr[i].Data);
    1580                 icmp_reflect(pData, m);
    1581                 /* Here is different situation from Unix world, where we can receive icmp in response on TCP/UDP */
    1582                 LIST_REMOVE(icm, im_list);
    1583                 pData->cIcmpCacheSize--;
    1584                 RTMemFree(icm);
    1585                 break;
    1586             default:
    1587                 Log(("ICMP(default): message with Status: %x was received from %x\n", icr[i].Status, icr[i].Address));
    1588                 break;
    1589         }
    1590     }
    1591 }
    1592 #else /* !RT_OS_WINDOWS */
    15931445static void sorecvfrom_icmp_unix(PNATState pData, struct socket *so)
    15941446{
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