Content-type: text/html Manpage of LIBPNET6


Section: LIBPNET6 API Reference (3)
Updated: March 30, 2003
Index Return to Main Contents



 - libpnet6's functionality to access IP datagrams.

This document describes the functions in libpnet6 that you can use to access raw IP datagrams.

In particular, this section will explain the pnet_ip
and pnet_ip6 structures used to describe IPv4 and IPv6 datagrams and the functions available to get and set different fields in those datagrams.

NOTE: in order to be able to follow this, some familiarity with IP datagrams and the IP protocol is required (and assumed in this document).

To use this functionality, you'll need to to include the file <pnet6tlp.h> next to the <pnet6.h> file.



libpnet6 provides a generic API to handle both IPv4 and IPv6 datagrams. In general, the same function can be used to read (similar) properties from IP datagrams. Where this is not possible, the API makes the proper distinction.



The IP datagram data types

IPv4 datagrams are represented by the following struct:

typedef struct pnet_ip {
    pnet_byte   ip_vhl; /* Version and Header Length */
    pnet_byte   ip_tos; /* Type of Service byte */
    pnet_ushort ip_len; /* Total length of datagram */
    pnet_ushort ip_id;  /* Identification of datagram */
    pnet_ushort ip_off; /* Fragmentation offset */
    pnet_byte   ip_ttl; /* Time to live byte */
    pnet_byte   ip_p;   /* Protocol of user level datagram */
    pnet_ushort ip_sum; /* Header checksum */
    pnet_uint   ip_src; /* Source address of datagram */
    pnet_uint   ip_dst; /* Destination address of datagram */
} pnet_ip;

# define PNET_IP_RF     0x8000     /* Reserved fragment flag */
# define PNET_IP_DF     0x4000     /* Don't fragment flag */
# define PNET_IP_MF     0x2000     /* More fragments */
# define PNET_IP_FRAGOFFMASK 0x1FFF /* Actual value of frag offset */

# define PNET_IPHDRLEN( ip )    ( ((ip)->ip_vhl & 0X0F) )
# define PNET_IPVERSION(  ip )  ( ((ip)->ip_vhl & 0xF0) >> 4 )

IPv6 datagrams are represented by the following struct:

typedef struct pnet_ip6 {
    union {
        pnet_byte       _un_ip6_vfc;    /* Version and priority */
        pnet_uint       _un_ip6_head;   /* Holds traffic class and flow info */
    } _ip6_hdr_un;

    pnet_ushort ip6_plen;    /* Payload length       */
    pnet_byte   ip6_nxt;     /* Next header ( == proto) */
    pnet_byte   ip6_hlim;    /* Hop limit            */
    pnet_byte   ip6_src[16]; /* Let's hope this size won't   */
    pnet_byte   ip6_dst[16]; /* change any time soon         */
} pnet_ip6;

# define ip6_vfc        _ip6_hdr_un._un_ip6_vfc
# define ip6_flow       _ip6_hdr_un._un_ip6_head

All the fields are in network byte order. Since some of the fields in these structs depend on the machine's byte order, currently it's not advised to read these values directly, unless you now what you're doing. To access the different fields and get them in the proper machine byte order, the following functions are defined.


Functions whose name begins with pnetIP_ are applicable to both IPv4 and IPv6 datagrams. Whenever a funtion is only applicable for a specific type of datagram, this is reflected in its name: pnetIP4_ is used for strictly IPv4 properties, attributes or functionality, while pnetIP6_ is used for pure IPv6. Unless otherwise stated, a void* must be a pointer to a pnet_ip or a pnet_ip6. As usual, functions return -1 on failure and 0 on success, unless otherwise indicated.

int pnetIP_Version( void* pip );

Returns the version of the IP datagram. Values can be 4 or 6. Returns -1 on error.

int pnetIP_Source( void * pip, PNETADDR pa );

Returns the source address of the IP datagram as a PNETADDR address. The address has the proper family format (IPv4 or IPv6) as determined from the datagram's version.

int pnetIP_Destination( void * pip );

Returns the destination address of the IP datagram as a PNETADDR address. The address has the proper family format (IPv4 or IPv6) as determined from the datagram's version.

pnet_byte* pnetIP_Payload( void * pip );

Returns a pointer to the actual payload of the IP datagram, i.e. the contents of the IP datagram immediately following its header. NULL is returned upon error.

int pnetIP_Protocol( void * pip );

Returns the protocol of the IP datagram (or the next header field of an IPv6) datagram, -1 on error. For example, 6 is returned for a TCP datagram.

int pnetIP_HeaderLength( void * pip );

Returns the header length of the IP datagram. For IPv6 this only includes the first header, i.e. the value is always 40. For IPv4 this includes any IP options contained in the header, and should be at least 20. On error, -1 is returned.

int pnetIP_PayloadLength( void * pip );

Returns the length of the datagram payload. On error -1 is returned.

int pnetIP_TTL( void * ip ); int pnetIP_Hoplimit( void * ip);

Returns the value of the time to live field for an IPv4 datagram, or the hoplimit for an IPv6 datagram. The two are interchangeable.

pnet_ushort pnetIP_TLHComputeChecksum( void * pip, byte * tlh, int tlh_len, pnet_byte * payload, int payload_len, int chk_off, int pseudo_header );

Computes the checksum for a Transport Level Datagram that is making use of the given IP datagram. If pseudo_header is set, then it is assumed that an IP pseudo-header needs to be prepended to the datagram, and taken into consideration during checksum computation. It is assumed that the offset into the transport layer header is located at chk_off. payload is the payload of the transport level datagram, whose length is given by payload_len. Both tlh and payload can be NULL, and won't be taken into consideration during checksum computation. Alternatively, setting chk_off to a value less than zero will disable checksum computation as well.

int pnetIP_Send( PNETSOCK ps, PNETADDR pa, void * pip, pnet_byte * tlh, int tlh_len, int chk_off, int pseudo_header, pnet_byte * data, int datalen );

Send an IP datagram, pointed to by pip to the given address pa on the given socket ps. The socket must be a raw socket in the address family matching the type of IP datagram (i.e IPv4 or IPv6), and with a protocol matching the IP datagram's protocol, or else 0 (possbly 255 on Linux). See pnet6-raw (3) for a discussion on raw sockets.

The payload of the ip datagram is a transport Level header, identified by thl, whose length is tlh_len (say a TCP header), followed by some transport level payload, identified by data of length datalen. Both tlh and data are optional, and can be set to NULL if not used.

If chk_off is a value greater or equal to 0, then it indicates the offset into the transport level header tlh where the checksum is stored (the zero offset being interpreted as the start of the tranport level header). This tells libpnet6 to compute and store the checksum for this tlh at the location specified by chk_off. In addition, if the particular transport level header requires a TCP-style pseudo-header for checksum computation, then pseudo_header should be set to a value other than 0. For example, since ICMP does not use a pseudo-header in its checksum computations, the pseudo-header should be set to 0, but the chk_off should be set to 2, since the ICMP checksum is stored starting at byte offset 2 in the ICMP header. Setting chk_off to a value less than 0 tells libpnet6 to bypass the checksum computation (either because the caller has calculated it, or wants the kernel to calculate and fill in the checksum).

The following are IPv4 specific functions. All IP header values are returned in host-byte order.

pnet_ip* pnetIP4_Build( pnet_ip * ip, int tos, int tlen, int id, int frag_off, int ff, int ttl, int proto, PNETADDR src, PNETADDR );

This function fills in an IPv4 header from the given parameters. No IP options are supported yet. The pointer returned is the same pointer that is passed to the function as its first argument.

int pnetIP4_Tos( pnet_ip * ip );

Returns the type of service byte for this IPv4 datagram. Never fails.

int pnetIP4_Id( pnet_ip * ip );

Returns the id of this IPv4 datagram. Never fails.

int pnetIP4_FragOffset( pnet_ip * ip );

Returns the fragmentation offset for this IPv4 datagram. Never fails.

int pnetIP4_MoreFrags( pnet_ip * ip );

Returns 1 if the more-frags flag is set for this IPv4 datagram, 0 otherwise.

int pnetIP4_DontFrag( pnet_ip * ip );

Returns 1 if the don't-frag flag is set for this IPv4 datagram, 0 otherwise.

int pnetIP4_Checksum( pnet_ip * ip );

Returns the value of the IPv4 header checksum field. Never fails.

pnet_ushort pnetIP4_ComputeChecksum( pnet_ip * ip );

Computes the checksum for this diagram, and returns it. The value of the datagram's original checksum is not changed.

The following are IPv6 specific functions.

pnet_ip6* pnetIP6_Build( pnet_ip6 * ip6, int tc, pnet_uint flow, pnet_ushort len, int next_header, int hoplimit, PNETADDR src, PNETADDR dst );

This function fills in an IPv6 header. The header to be filled in is passed as the first argument. The filled in header is also returned by the function.

int pnetIP6_Priority( pnet_ip6 * ip6 );

Returns the value of the priority field for this IPv6 datagram.

int pnetIP6_TrafficClass( pnet_ip6 * ip6 );

Returns the value of the traffic class field for this IPv6 datagram.

int pnetIP6_Flow( pnet_ip6 * ip6 );

Returns the value of the flow info (last 20 bits of the first IPv6 header word) for this IPv6 datagram.




pnet6(3), pnet6-addr(3), pnet6-api(3), pnet6-aux(3), pnet6-if(3), pnet6-ip(3), pnet6-log(3), pnet6-pkt(3), pnet6-raw(3), pnet6-socket(3), pnet6-tcp(3), pnet6-threads(3), pnet6-udp(3).



The current version of libpnet6 is highly experimental.

You can always get the most recent version from



You bet.



Peter Bozarov. Send mail to kingofgib (at)




This document was created by man2html, using the manual pages.
Time: 06:22:19 GMT, May 26, 2003