Changeset 7baa948


Ignore:
Timestamp:
06/27/14 13:42:59 (6 years ago)
Author:
Shane Alcock <salcock@…>
Branches:
4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, getfragoff, libtrace4, master, ndag_format, pfring, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
Children:
fb20640
Parents:
fa7faf3
Message:

Added trace_get_fragment_offset to API

New function performs all the bit-shifting, masking,
multiplying and (in the case of IPv6) header skipping necessary to
work out the fragment offset for a packet, in bytes.

Fixed trace_get_source_port and trace_get_destination_port so
that they do not try to lookup port numbers if the packet is
not the first fragment.

IPv6 fragment offsets probably need more testing.

Location:
lib
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • lib/libtrace.h.in

    rc7021d9 r7baa948  
    17791779                uint16_t *csum);
    17801780
     1781/** Calculates the fragment offset in bytes for an IP packet
     1782 * @param packet        The libtrace packet to calculate the offset for
     1783 * @param[out] more     A boolean flag to indicate whether there are more
     1784 *                      fragments after the current packet.
     1785 * @return The fragment offset for the packet in bytes. If the packet is not
     1786 * an IP packet or the fragment offset is not present in packet, the return
     1787 * value will be 0.
     1788 *
     1789 * @note The value returned is in bytes, not 8-octet units as it is stored
     1790 * in the fragment offset field in the headers. In other words, libtrace
     1791 * automatically does the multiplication for you.
     1792 *
     1793 * The value passed in for 'more' does not matter; it will be overwritten
     1794 * with the value of the More Fragments flag from the IP header.
     1795 *
     1796 * New in libtrace 3.0.20
     1797 */
     1798DLLEXPORT uint16_t trace_get_fragment_offset(const libtrace_packet_t *packet,
     1799                uint8_t *more);
     1800
    17811801/** Gets a pointer to the transport layer header (if any)
    17821802 * @param packet   The libtrace packet to find the transport header for
  • 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}
  • lib/protocols_transport.c

    r10f924c r7baa948  
    382382        uint32_t remaining;
    383383        uint8_t proto;
    384         const struct ports_t *port =
    385                 (const struct ports_t*)trace_get_transport((libtrace_packet_t*)packet,
     384        struct ports_t *port;
     385        uint16_t fragoff;
     386        uint8_t more;
     387
     388        fragoff = trace_get_fragment_offset(packet, &more);
     389
     390        /* If we're not the first fragment, we're unlikely to be able
     391         * to get any useful port numbers from this packet.
     392         */
     393        if (fragoff != 0)
     394                return 0;
     395       
     396       
     397        port = (struct ports_t*)trace_get_transport(
     398                        (libtrace_packet_t*)packet,
    386399                        &proto, &remaining);
    387400
     
    405418        uint32_t remaining;
    406419        uint8_t proto;
    407         struct ports_t *port =
    408                 (struct ports_t*)trace_get_transport((libtrace_packet_t*)packet,
     420        struct ports_t *port;
     421        uint16_t fragoff;
     422        uint8_t more;
     423
     424        fragoff = trace_get_fragment_offset(packet, &more);
     425
     426        /* If we're not the first fragment, we're unlikely to be able
     427         * to get any useful port numbers from this packet.
     428         */
     429        if (fragoff != 0)
     430                return 0;
     431       
     432       
     433        port = (struct ports_t*)trace_get_transport(
     434                        (libtrace_packet_t*)packet,
    409435                        &proto, &remaining);
    410436        /* Snapped too early */
Note: See TracChangeset for help on using the changeset viewer.