Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/protocols_l3.c

    r9ca1fce r7baa948  
    724724}
    725725
     726DLLEXPORT uint16_t trace_get_fragment_offset(const libtrace_packet_t *packet,
     727                uint8_t *more) {
     728
     729        void *l3;
     730        uint16_t ethertype;
     731        uint32_t remaining;
     732
     733        *more = 0;
     734
     735        l3 = trace_get_layer3(packet, &ethertype, &remaining);
     736        if (l3 == NULL)
     737                return 0;
     738
     739        if (ethertype == TRACE_ETHERTYPE_IP) {
     740                libtrace_ip_t *ip = (libtrace_ip_t *)l3;
     741                uint16_t offset = 0;
     742
     743                /* Fragment offset appears in 7th and 8th bytes */
     744                if (remaining < 8)
     745                        return 0;
     746                 
     747                offset = ntohs(ip->ip_off);
     748
     749                if ((offset & 0x2000) != 0)
     750                        *more = 1;
     751                return (offset & 0x1FFF) * 8;
     752        }
     753
     754        if (ethertype == TRACE_ETHERTYPE_IPV6) {
     755                libtrace_ip6_t *ip6 = (libtrace_ip6_t *)l3;
     756                void *payload = ip6++;
     757                uint8_t nxt = ip6->nxt;
     758                uint16_t len;
     759               
     760                /* First task, find a Fragment header if present */
     761                if (remaining < sizeof(libtrace_ip6_t))
     762                        return 0;
     763                remaining -= sizeof(libtrace_ip6_t);
     764
     765                /* Adapted from trace_get_payload_from_ip6 */
     766                while (1) {
     767                        switch (nxt) {
     768                        case 0:
     769                        case TRACE_IPPROTO_ROUTING:
     770                        case TRACE_IPPROTO_AH:
     771                        case TRACE_IPPROTO_DSTOPTS:
     772                        {
     773
     774                                /* Length does not include the first 8 bytes */
     775                                len=((libtrace_ip6_ext_t*)payload)->len * 8;
     776                                len += 8;
     777
     778                                if (remaining < len) {
     779                                        /* Snap too short */
     780                                        return 0;
     781                                }
     782                                remaining-=len;
     783
     784                                nxt=((libtrace_ip6_ext_t*)payload)->nxt;
     785                                continue;
     786                        }
     787                        case TRACE_IPPROTO_FRAGMENT:
     788                        {
     789                                libtrace_ip6_frag_t *frag = (libtrace_ip6_frag_t *)payload;
     790                                uint16_t offset;
     791                                len = sizeof(libtrace_ip6_frag_t);
     792                                if (remaining < len) {
     793                                        /* Snap too short */
     794                                        return 0;
     795                                }
     796                                remaining-=len;
     797
     798                                offset = ntohs(frag->frag_off);
     799                                if ((offset & 0x0001) != 0)
     800                                        *more = 1;
     801
     802                                return ((offset & 0xFFF8) >> 3) * 8;
     803                         }
     804                         default:
     805                                return 0;
     806                         }
     807                }
     808
     809        }
     810        return 0;
     811}
Note: See TracChangeset for help on using the changeset viewer.