VirtualBox

Changeset 49637 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 25, 2013 3:43:54 AM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
90862
Message:

Refactor a bit.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/NetworkServices/NAT/pxping.c

    r49617 r49637  
    4646#endif
    4747
     48#if defined(RT_OS_LINUX) && !defined(__USE_GNU)
     49/* XXX: https://sourceware.org/bugzilla/show_bug.cgi?id=6775 */
     50struct in6_pktinfo {
     51    struct in6_addr ipi6_addr;
     52    unsigned int ipi6_ifindex;
     53};
     54#endif
     55
    4856
    4957/* forward */
     
    190198static void pxping_pmgr_icmp6(struct pxping *pxping);
    191199static void pxping_pmgr_icmp6_echo(struct pxping *pxping,
    192                                    u16_t iplen, struct sockaddr_in6 *peer);
     200                                   ip6_addr_t *src, ip6_addr_t *dst,
     201                                   int hopl, int tclass, u16_t icmplen);
    193202static void pxping_pmgr_icmp6_error(struct pxping *pxping,
    194                                     u16_t iplen, struct sockaddr_in6 *peer);
     203                                    ip6_addr_t *src, ip6_addr_t *dst,
     204                                    int hopl, int tclass, u16_t icmplen);
    195205
    196206static void pxping_pmgr_forward_inbound(struct pxping *pxping, u16_t iplen);
     
    257267        if (status < 0) {
    258268            perror("IPV6_RECVPKTINFO");
    259             /* XXX: this is fatal */
     269            /* XXX: for now this is fatal */
    260270        }
    261271
     
    286296
    287297static u32_t
    288 update16_with_chksum(u16_t *oldp, u16_t h)
    289 {
    290     u32_t sum = (u16_t)~*oldp;
    291     sum += h;
    292 
    293     *oldp = h;
     298chksum_delta_16(u16_t oval, u16_t nval)
     299{
     300    u32_t sum = (u16_t)~oval;
     301    sum += nval;
    294302    return sum;
    295303}
     
    297305
    298306static u32_t
    299 update32_with_chksum(u32_t *oldp, u32_t u)
    300 {
    301     u32_t sum = ~*oldp;
     307chksum_update_16(u16_t *oldp, u16_t nval)
     308{
     309    u32_t sum = chksum_delta_16(*oldp, nval);
     310    *oldp = nval;
     311    return sum;
     312}
     313
     314
     315static u32_t
     316chksum_delta_32(u32_t oval, u32_t nval)
     317{
     318    u32_t sum = ~oval;
    302319    sum = FOLD_U32T(sum);
    303     sum += FOLD_U32T(u);
    304 
    305     *oldp = u;
     320    sum += FOLD_U32T(nval);
    306321    return sum;
    307322}
     
    309324
    310325static u32_t
    311 updateip6_with_chksum(ip6_addr_t *oldp, const ip6_addr_t *ip6)
     326chksum_update_32(u32_t *oldp, u32_t nval)
     327{
     328    u32_t sum = chksum_delta_32(*oldp, nval);
     329    *oldp = nval;
     330    return sum;
     331}
     332
     333
     334static u32_t
     335chksum_delta_ipv6(const ip6_addr_t *oldp, const ip6_addr_t *newp)
    312336{
    313337    u32_t sum;
    314338
    315     sum  = update32_with_chksum(&oldp->addr[0], ip6->addr[0]);
    316     sum += update32_with_chksum(&oldp->addr[1], ip6->addr[1]);
    317     sum += update32_with_chksum(&oldp->addr[2], ip6->addr[2]);
    318     sum += update32_with_chksum(&oldp->addr[3], ip6->addr[3]);
     339    sum  = chksum_delta_32(oldp->addr[0], newp->addr[0]);
     340    sum += chksum_delta_32(oldp->addr[1], newp->addr[1]);
     341    sum += chksum_delta_32(oldp->addr[2], newp->addr[2]);
     342    sum += chksum_delta_32(oldp->addr[3], newp->addr[3]);
     343
     344    return sum;
     345}
     346
     347
     348static u32_t
     349chksum_update_ipv6(ip6_addr_t *oldp, const ip6_addr_t *newp)
     350{
     351    u32_t sum;
     352
     353    sum  = chksum_update_32(&oldp->addr[0], newp->addr[0]);
     354    sum += chksum_update_32(&oldp->addr[1], newp->addr[1]);
     355    sum += chksum_update_32(&oldp->addr[2], newp->addr[2]);
     356    sum += chksum_update_32(&oldp->addr[3], newp->addr[3]);
    319357
    320358    return sum;
     
    372410    /* rewrite ICMP echo header */
    373411    sum = (u16_t)~icmph->chksum;
    374     sum += update16_with_chksum(&icmph->id, pcb->host_id);
     412    sum += chksum_update_16(&icmph->id, pcb->host_id);
    375413    sum = FOLD_U32T(sum);
    376414    icmph->chksum = ~sum;
     
    9841022    /* rewrite ICMP echo header */
    9851023    sum = (u16_t)~icmph->chksum;
    986     sum += update16_with_chksum(&icmph->id, guest_id);
     1024    sum += chksum_update_16(&icmph->id, guest_id);
    9871025    sum = FOLD_U32T(sum);
    9881026    icmph->chksum = ~sum;
     
    9901028    /* rewrite IP header */
    9911029    sum = (u16_t)~IPH_CHKSUM(iph);
    992     sum += update32_with_chksum((u32_t *)&iph->dest,
     1030    sum += chksum_update_32((u32_t *)&iph->dest,
    9931031                                ip4_addr_get_u32(&guest_ip));
    9941032    if (mapped == PXREMAP_MAPPED) {
    995         sum += update32_with_chksum((u32_t *)&iph->src,
     1033        sum += chksum_update_32((u32_t *)&iph->src,
    9961034                                    ip4_addr_get_u32(&target_ip));
    9971035    }
     
    11421180    /* rewrite inner ICMP echo header */
    11431181    sum = (u16_t)~oicmph->chksum;
    1144     sum += update16_with_chksum(&oicmph->id, guest_id);
     1182    sum += chksum_update_16(&oicmph->id, guest_id);
    11451183    sum = FOLD_U32T(sum);
    11461184    oicmph->chksum = ~sum;
     
    11481186    /* rewrite inner IP header */
    11491187    sum = (u16_t)~IPH_CHKSUM(oiph);
    1150     sum += update32_with_chksum((u32_t *)&oiph->src,
    1151                                 ip4_addr_get_u32(&guest_ip));
     1188    sum += chksum_update_32((u32_t *)&oiph->src, ip4_addr_get_u32(&guest_ip));
    11521189    if (target_mapped == PXREMAP_MAPPED) {
    1153         sum += update32_with_chksum((u32_t *)&oiph->dest,
    1154                                     ip4_addr_get_u32(&target_ip));
     1190        sum += chksum_update_32((u32_t *)&oiph->dest, ip4_addr_get_u32(&target_ip));
    11551191    }
    11561192    sum = FOLD_U32T(sum);
     
    11591195    /* rewrite outer IP header */
    11601196    sum = (u16_t)~IPH_CHKSUM(iph);
    1161     sum += update32_with_chksum((u32_t *)&iph->dest,
    1162                                 ip4_addr_get_u32(&guest_ip));
     1197    sum += chksum_update_32((u32_t *)&iph->dest, ip4_addr_get_u32(&guest_ip));
    11631198    if (error_mapped == PXREMAP_MAPPED) {
    1164         sum += update32_with_chksum((u32_t *)&iph->src,
    1165                                     ip4_addr_get_u32(&error_ip));
     1199        sum += chksum_update_32((u32_t *)&iph->src, ip4_addr_get_u32(&error_ip));
    11661200    }
    11671201    else {
     
    11871221    ssize_t nread;
    11881222    struct icmp6_echo_hdr *icmph;
    1189 #if defined(RT_OS_LINUX) && !defined(__USE_GNU)
    1190     /* XXX: https://sourceware.org/bugzilla/show_bug.cgi?id=6775 */
    1191     struct in6_pktinfo {
    1192         struct in6_addr ipi6_addr;
    1193         unsigned int ipi6_ifindex;
    1194     };
    1195 #endif
    11961223    struct in6_pktinfo *pktinfo;
    11971224    int hopl, tclass;
    1198 
    1199     int mapped;
    1200     struct ping_pcb *pcb;
    1201     ip6_addr_t guest_ip, target_ip, unmapped_target_ip;
    1202     u16_t id, guest_id;
    1203     u32_t sum;
    12041225
    12051226    char addrbuf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
     
    12311252    DPRINTF2(("%s: %s ICMPv6: ", __func__, addrstr));
    12321253
    1233     id = 0;
    12341254    if (icmph->type == ICMP6_TYPE_EREP) {
    1235         id = icmph->id;
    12361255        DPRINTF2(("echo reply %04x %u\n",
    12371256                  (unsigned int)icmph->id, (unsigned int)icmph->seqno));
     
    12591278        return;
    12601279    }
    1261 
    1262     /* XXX: refactor into pxping_pmgr_icmp6_echo(), pxping_pmgr_icmp6_error() */
    12631280
    12641281    pktinfo = NULL;
     
    12911308         * manually recompute it - for this we must know the
    12921309         * destination address of the pseudo-header that we will
    1293          * rewrite with guest's address.
     1310         * rewrite with guest's address.  (TODO: yeah, yeah, we can
     1311         * compute it from scratch...)
    12941312         */
    12951313        DPRINTF2(("%s: unable to get pktinfo\n", __func__));
     
    12971315    }
    12981316
    1299     ip6_addr_copy(target_ip, *(ip6_addr_t *)&sin6.sin6_addr);
    1300     mapped = pxremap_inbound_ip6(&unmapped_target_ip, &target_ip);
    1301     if (mapped == PXREMAP_FAILED) {
    1302         return;
    1303     }
    1304 
    1305     sys_mutex_lock(&pxping->lock);
    1306     pcb = pxping_pcb_for_reply(pxping, 1, ip6_2_ipX(&unmapped_target_ip), id);
    1307     if (pcb == NULL) {
    1308         sys_mutex_unlock(&pxping->lock);
    1309         DPRINTF2(("%s: no match\n", __func__));
    1310         return;
    1311     }
    1312 
    1313     DPRINTF2(("%s: pcb %p\n", __func__, (void *)pcb));
    1314 
    1315     /* save info before unlocking since pcb may expire */
    1316     ip6_addr_copy(guest_ip, *ipX_2_ip6(&pcb->src));
    1317     guest_id = pcb->guest_id;
    1318 
    1319     sys_mutex_unlock(&pxping->lock);
    1320 
    1321     /* rewrite ICMPv6 echo header */
    1322     sum = (u16_t)~icmph->chksum;
    1323     sum += update16_with_chksum(&icmph->id, guest_id);
    1324 
    1325     /* dst address in pseudo header (clobbers pktinfo) */
    1326     sum += updateip6_with_chksum((ip6_addr_t *)&pktinfo->ipi6_addr, &guest_ip);
    1327 
    1328     /* src address in pseudo header (clobbers target_ip) */
    1329     if (mapped) {
    1330         sum += updateip6_with_chksum(&target_ip, &unmapped_target_ip);
    1331     }
    1332 
    1333     sum = FOLD_U32T(sum);
    1334     icmph->chksum = ~sum;
    1335 
    13361317    if (hopl < 0) {
    13371318        hopl = LWIP_ICMP6_HL;
    13381319    }
    1339     else if (!mapped) {
    1340         if (hopl == 1) {
    1341             return;
    1342         }
    1343         --hopl;
    1344     }
    1345 
    1346     if (tclass < 0) {
    1347         tclass = 0;
    1348     }
    1349 
    1350     pxping_pmgr_forward_inbound6(pxping,
    1351                                  &unmapped_target_ip, /* echo reply src */
    1352                                  &guest_ip, /* echo reply dst */
    1353                                  hopl, tclass, (u16_t)nread);
     1320
     1321    if (icmph->type == ICMP6_TYPE_EREP) {
     1322        pxping_pmgr_icmp6_echo(pxping,
     1323                               (ip6_addr_t *)&sin6.sin6_addr,
     1324                               (ip6_addr_t *)&pktinfo->ipi6_addr,
     1325                               hopl, tclass, (u16_t)nread);
     1326    }
     1327    else {
     1328        pxping_pmgr_icmp6_error(pxping,
     1329                                (ip6_addr_t *)&sin6.sin6_addr,
     1330                                (ip6_addr_t *)&pktinfo->ipi6_addr,
     1331                                hopl, tclass, (u16_t)nread);
     1332    }
    13541333}
    13551334
     
    13571336static void
    13581337pxping_pmgr_icmp6_echo(struct pxping *pxping,
    1359                        u16_t iplen, struct sockaddr_in6 *peer)
    1360 {
    1361 }
     1338                       ip6_addr_t *src, ip6_addr_t *dst,
     1339                       int hopl, int tclass, u16_t icmplen)
     1340{
     1341    struct ip6_hdr *oiph;
     1342    struct icmp6_hdr *icmph, *oicmph;
     1343    struct ping_pcb *pcb;
     1344    ip6_addr_t guest_ip, target_ip, error_ip;
     1345    int target_mapped, error_mapped;
     1346    u16_t id, guest_id;
     1347    u32_t sum;
     1348
     1349    icmph = (struct icmp6_hdr *)pollmgr_udpbuf;
     1350
     1351    /*
     1352     * Inner IP datagram is not checked by the kernel and may be
     1353     * anything, possibly malicious.
     1354     */
     1355    oiph = (struct ip6_hdr *)(pollmgr_udpbuf + sizeof(*icmph));
     1356
     1357    if (IP6H_V(oiph) != 6) {
     1358        DPRINTF2(("%s: unexpected IP version %d\n", __func__, IP6H_V(oiph)));
     1359        return;
     1360    }
     1361
     1362    DPRINTF2(("%s: nexth = %d\n", __func__, IP6H_NEXTH(oiph)));
     1363}
     1364
    13621365
    13631366static void
    13641367pxping_pmgr_icmp6_error(struct pxping *pxping,
    1365                         u16_t iplen, struct sockaddr_in6 *peer)
    1366 {
     1368                        ip6_addr_t *src, ip6_addr_t *dst,
     1369                        int hopl, int tclass, u16_t icmplen)
     1370{
     1371    struct icmp6_echo_hdr *icmph;
     1372    int mapped;
     1373    struct ping_pcb *pcb;
     1374    ip6_addr_t guest_ip, target_ip;
     1375    u16_t id, guest_id;
     1376    u32_t sum;
    13671377}
    13681378
Note: See TracChangeset for help on using the changeset viewer.

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