Content-type: text/html Manpage of LIBPNET6


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



This document describes libpnet6's address functions. See pnet6(3) for an introduction to libpnet6 itself.

In particular, this section will explain how to:

- Work with PNETADDR objects.



Internet addresses are represented in libpnet6 as PNETADDR objects. This can be an IPv4, IPv6 or a Local address (the last one is used with UNIX sockets, of the PNET_LOCAL address family).

Note that conceptually, a PNETADDR object is the same as a struct sockaddr_in object: that is, it's not just an Internet address, but contains additional information, such as a port number to be used with TCP/UDP communication.

It can happen that a single host resolves to more than one address, for example, a host running a dual IPv4/IPv6 stack will have an IPv6 address next to its IPv4 address. Also multihomed hosts can resolve to more than one address. To accommodate this, a PNETADDR is actually a linked list of addresses for the given host. See below for more information on that.

Normally, direct access to address objects is not required. In the cases when it is, the following functions can be used.



PNETADDR pnetAddrMake( void );

Makes a PNETADDR object. The contents are undefined.

void pnetAddrFree( PNETADDR addr);

Frees this object and the entire linked list of addresses it might contain.

PNETADDR pnetAddrNext( PNETADDR addr);

Returns the next address in the list, NULL if there are no more entries.

void pnetAddrCopy(PNETADDR to, PNETADDR from);

Copies the second address into the first. Memory for the target object must have been allocated using pnetAddrMake() or pnetAddrResolve() (see below). Only the first address in a possible chain of addresses is copied.

int pnetAddrGetFamily(PNETADDR addr);

Returns the address family of this PNETADDR. Can be PNET_IPv4, PNET_IPv6, PNET_LOCAL, or -1 if an error has occurred.

int pnetAddrGetPort(PNETADDR addr);

Returns an integer, representing the port number used by this address, if set, else -1. For PNET_LOCAL addresses, no ports are defined, and the return value is always -1.

int pnetAddrSetPort(PNETADDR addr, int port);

Set the port number for this address to the value indicated.

int pnetAddrLookupPort(PNETADDR addr, const char * type, const char service);

This function looks up the port number that belongs to the given service, and is of the requested type (currently, "tcp" and "udp" are supported as types), and sets the port number for this address to the value it finds. Return value is -1 if the given service was not found (for the given type); 0 is returned on success.

const pnet_byte* pnetAddrGetBinary(PNETADDR addr, int * len);

This funtion returns a pointer to the actual binary data representing the Internet address. The length of this array of bytes is returned through len. Usually, the length will be 4 for IPv4 address, and 16 for IPv6 addresses.

In the following, ''true'' is defined as any value other than 0 (although it's normally 1, this should not be relied upon).

int pnetAddrIsLoopback(PNETADDR addr);

Returns true if this address is a Loopback address.

int pnetAddrIsLinkLocal(PNETADDR addr);

For PNET_IPv6 addresses, returns true if the address is link local. Link local addresses start with fe8x, fe9x, feax, febx, where x is any hexadecimal number. Officially, the link local addresses have the following prefix fe80::/64.

int pnetAddrIsMCLinkLocal(PNETADDR addr);

For PNET_IPv6 addresses, returns true if the address is multicast link local. Multicast link local addresses start with ffx2, where x is any hexadecimal number.

int pnetAddrIsSiteLocal(PNETADDR addr);

Returns true if this address is a site-local address. Site-local addresses have a prefix of fec0::/10.

int pnetAddrIsUnspecified(PNETADDR addr);

Returns true if this address is the unspecified address (i.e. the null address, or wildcard address).

int pnetAddrIsV4Mapped(PNETADDR addr);

For IPv6 addresses, return true if this is in fact a IPv4 mapped address.

int pnetAddrIsV4Compatible(PNETADDR addr);

For IPv6 addresses, return true if this is in fact a IPv4 compatible address.

PNETADDR pnetAddrResolve( int fam, const char * name);

Resolve the address pointed to by name. If fam is not PNET_UNSPEC, try to resolve the address in the given family only. Allowed values are PNET_IPv4 or PNET_IPv6; no resolution is perfomed on PNET_LOCAL addresses. If family is PNET_UNSPEC then libpnet6 will try to resolve addresses in both the IPv4 and IPv6 domains.

The name parameter can be a string containing a host name, such as "", or an IPv4/IPv6 address. In the latter case, no resolving is performed; a PNETADDR object is simply created and properly initialized; the fam parameter is ignored in this case, since that can be derived from the address format itself.

If successful, a new linked list of PNETADDR objects is created and returned. On failure, NULL is returned. In most cases, the linked list will contain only a single object.

char * pnet_ntop(PNETADDR addr, char * buf, int len); char * pnetAddrToString( PNETADDR addr, char * buf, int len);

Returns a human readable string representation of this addr. The second function is the preferred one to use of the two. The constant PNET_ADDR_STRLEN can be used to allocate sufficient space to hold any possible address representation.

int pnet_pton( int fam, const char * addr, PNETADDR pa);

Convert a string containing an IPv4/IPv6 address (not a host name) to a binary address and store if in the provided PNETADDR parameter. The first parameter indicates the address family to use, either PNET_IPv4, PNET_IPv6, or PNET_LOCAL.



Although making the address object opaque is useful from a programming point of view, it's not always practical: if a function needs to deal with a PNETADDR, it must allocate memory, access the object, then free the memory. There are times, when constantly allocating and freeing memory to deal with many different PNETADDR objects can proove too costly. Instead, allocating a local variable on the stack can save the time it takes to place calls to malloc() and free(). However, since the PNETADDR objects are opaque, you can't do this. For that purpose, libpnet6 defines an object of type PNETADDRSTORAGE. You can declare such an object, say, pas, and use the PNET_SADDR(pas) macro, to access it as if it were a PNETADDR object, without having to explicitly allocate memory on the heap.

The following code fragment illustrates this. Instead of doing

void foo( void )
    PNETADDR pa;

    pa = pnetAddrMake();        /* Allocate address object */

    /* call function that needs a pre-allocated PNETADDR object */
    func( other args, pa );

    pnetAddrFree( pa );         /* Get rid of object */
you can do
void foo( void )

    /* call function that needs a pre-allocated PNETADDR object */
    func( other args, PNET_SADDR( pas ) );

This obviates the need to allocate and free memory on the fly. Be careful with the second form though: if for some reason the variable's next pointer is set by another function, this memory will be lost when foo() exists, because that pointer won't be followed up and freed by libpnet6, as is the case when pnetAddrFree() is used.



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






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