Team LiB
Previous Section Next Section

10.5. libpcap Library Reference

Although the Arpsniff tool demonstrates a majority of the functionality that most tools require, the libpcap library has a lot of functionality we have not yet explored. This section provides a high-level reference, by functionality type, to all the functionality present in libpcap.

10.5.1. Lookup Functions

The following functions are used to provide information about available interfaces.

pcap_lookupdevPrototype: char *pcap_lookupdev(char *errbuf)

Purpose: pcap_lookupdev finds the first usable interface (active and supported by libpcap) for use with pcap_open_live and pcap_lookup_net returned by the operating system. The function returns a string containing the device's name if successful. If not successful, the function returns NULL and errbuf contains a human-readable error message. pcap_lookupdev is not recommended in situations where multiple network interfaces are in use. Note that if the calling user does not have appropriate privileges, this function might not return a device even though usable devices are present. You can find an example of using pcap_lookupdev in the Section 10.2.2 section earlier in this chapter.

pcap_findalldevsPrototype: int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)

Purpose: pcap_findalldevs finds all usable (active and supported by libpcap) interfaces for use with pcap_open_live. If successful, the function returns 0 and alldevsp points to a linked list of pcap_if_t structures with interface details. If not successful, the function returns -1 and errbuf is populated with a human-readable error message. You can find an example of utilizing the information returned by pcap_findalldevs in the Section 10.2.2 section earlier in this chapter.

pcap_lookupnetPrototype: int pcap_lookupnet(const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf)

Purpose: pcap_lookupnet returns the network address and network mask of the device supplied in the device parameter. The function returns 0 if successful and netp and maskp point to the network interface address and netmask, respectively. If an error occurs, pcap_lookupnet returns -1, and errbuf is populated with a human-readable error message. You can find an example of using the pcap_lookupnet function in the Section 10.2.4 section earlier in this chapter.

pcap_freealldevsPrototype: void pcap_freealldevs(pcap_if_t *alldevs)

Purpose: pcap_freealldevs frees a linked list of interface information returned by the pcap_findalldevs function.

10.5.2. Packet-Capture Functions

The following are functions for capturing packets and manipulating live capture sources.

pcap_open_livePrototype: pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *errbuf)

Purpose: pcap_open_live is used to open a live packet-capturing session from the network interface device (for example, eth0 on Linux, or le0 on a Sun Sparc). device can be NULL or any on recent Linux systems, in which case all interfaces are used for packet capture. snaplen specifies the length in bytes to be captured. If you want to capture the entire packet, set this to more than the packet size, including headers for the link type you are capturing from (65,535 should be sufficient). promisc should be 1 if the interface should be put into promiscuous mode or 0 otherwise. When a network interface is in promiscuous mode, and promiscuous mode is supported by the underlying data link layer, it captures all traffic on the network, regardless of whether it is intended for the host running the packet capture. This does not have any effect if the device is set to NULL or any. The parameter to_ms specifies a read timeout in milliseconds for when read operations should not necessarily return immediately when a packet is seen, therefore allowing us to capture multiple packets in one read operation. to_ms is not supported on all platforms (for unsupported systems, this value is ignored), and is useful mostly if you're going to use pcap_dispatch in nonblocking mode. A value of 0 causes libpcap to wait until packets arrive. pcap_open_live returns NULL is the open fails, and errbuf is set to a human-readable error message. errbuf should be of at least PCAP_ERRBUF_SIZE size. pcap_open_live can also return a warning message in errbuf on a successful call. errbuf should be checked after the successful call to determine if errbuf is still a zero length string, and any warnings should be returned to the user. You can find an example of using the pcap_open_live function in the Section 10.2.3 section earlier in this chapter.

pcap_nextPrototype: const u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)

Purpose: pcap_next reads the next packet available on the buffer. This is a wrapper to pcap_dispatch called with a cnt of 1. If successful, pcap_next returns a pointer to the captured packet. If the read was not successful for any reason, no packet was available due to a timeout, or no packets passed a filter, pcap_next returns NULL. No packet header information is returned for this function. Because no error messages are returned by pcap_next, it is more suited to simple uses and for reading from dump files. Use pcap_next_ex if you need error handling.

pcap_next_exPrototype: int pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, const u_char **pkt_data)

Purpose: pcap_next_ex returns the next packet available on the buffer. If successful, the function returns 1, and pkt_header and pkt_data point to the captured packet's libpcap capture information header and the packet, respectively. If not successful, the function returns 0 if the timeout expired, -1 if an error occurred reading the packet, or -2 if the packet is being read from a saved file and there are no more packets to read.

pcap_loopPrototype: int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

Purpose: pcap_loop enters a loop for processing cnt packets from the opened capture (live or saved file). Unlike pcap_dispatch, pcap_loop does not observe read timeouts. If cnt is set to a negative number, the loop continues forever. The function specified by callback is the name of a function of the prototype void callback (u_char *user, const struct pcap_pkthdr *header, const u_char* packet). This function is called for each packet captured. The user parameter is a user-specifiable value that is passed to the callback function when it is invoked, and can be NULL. The function pcap_loop returns 0 if cnt packets were successfully read, -1 on an error, and -2 if a call to pcap_breakloop occurred before packets have been captured. If an error has occurred, you can use pcap_perror( ) or pcap_geterr( ) to obtain the error message. You can find an example of using the pcap_loop function in the Section 10.2.5 section earlier in this chapter.

pcap_dispatchPrototype: int pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

Purpose: pcap_dispatch captures and processes packets while observing read timeouts specified in pcap_open_live. The cnt parameter specifies the maximum number of packets that are to be processed. When reading from a live capture, 0 up to cnt packets can be processed depending on the status of the buffer. A cnt value of -1 processes all packets in the buffer or the entire file, if used on a saved file. The function specified by callback is the name of a function of the prototype void callback (u_char *user, const struct pcap_pkthdr *header, const u_char* packet). This function is called for each packet. The user parameter is a user-specifiable value that is passed to the callback function when it is invoked, and can be NULL. The function returns the number of packets processed if successful. 0 is returned if no packets were read (due to a read timeout, or if in nonblocking mode and no packets were available to be read), -1 if an error occurred, or -2 if a call to pcap_breakloop was made before any packets were captured. If an error has occurred, you can use pcap_perror( ) or pcap_geterr( ) to obtain the error message. Note that because of the way pcap_dispatch behaves with different platforms, it might not necessarily return immediately after a read timeout.

pcap_setnonblockPrototype: int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)

Purpose: pcap_setnonblock allows you to set the status of a live capture as blocking or nonblocking. The nonblock parameter should be 1 to set the status to nonblocking and 0 to set the status to blocking (default). pcap_setnonblock is intended for use with pcap_dispatch, and when the live capture is set to nonblocking, pcap_dispatch returns immediately if no packets are available for processing, without observing any read timeouts. If the live capture is set to block, the capture waits for packets to arrive. pcap_setnonblock returns 0 on success and -1 on an error with a human-readable error message returned in errbuf.

pcap_getnonblockPrototype: int pcap_getnonblock(pcap_t *p, char *errbuf)

Purpose: pcap_getnonblock returns the current blocking status of 1 (nonblocking) or 0 (blocking; the default). If an error occurs, the function returns -1 with the errbuf containing a human-readable error message. pcap_getnonblock always returns 0 on saved files.

pcap_set_datalinkPrototype: int pcap_set_datalink(pcap_t *p, int dlt)

Purpose: pcap_set_datalink sets the data link type on the underlying data link layer to the value in dlt (refer to Table 10-2 for example data link types) where the underlying data link layer supports multiple link types. Support for multiple link types is not available on all link types or platforms. You can obtain a list of all possible data link types supported for an interface using pcap_list_datalinks. The function returns 0 on success and -1 on failure.

pcap_compilePrototype: int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, intoptimize, bpf_u_int32 netmask)

Purpose: pcap_compile is used to compile the tcpdump format filter string str into a BPF filter fp. optimize controls whether the resulting code is optimized (value 1) or not (value 0). netmask is the IPv4 netmask of the network interface being used for capture. This value can be obtained using pcap_lookupnet, or it can be 0, in which case some tests for IPv4 broadcast addresses will not work correctly. pcap_compile returns 0 on success, -1 on error. You can find an example of using pcap_compile in the Section 10.2.4 section earlier in this chapter.

pcap_compile_nopcapPrototype: int pcap_compile_nopcap(int snaplen, int linktype, struct bpf_program *fp,char *str, int optimize, bpf_u_int32 netmask)

Purpose: pcap_compile_nopcap is a wrapper to pcap_compile that allows us to compile BPF filters without a pcap_t structure. snaplen and linktype specify the capture length and the link type (as per Table 10-2) and are used as arguments to pcap_open_dead. pcap_compile_nopcap returns 0 on success and -1 on error.

pcap_setfilterPrototype: int pcap_setfilter(pcap_t *p, struct bpf_program *fp)

Purpose: pcap_setfilter is used to set a compiled BPF filter on a capture session. fp contains the compiled BPF program as generated by pcap_compile. pcap_setfilter returns 0 on success and -1 on error. You can find an example of using pcap_setfilter in the Section 10.2.4 section earlier in this chapter.

pcap_freecodePrototype: void pcap_freecode(struct bpf_program *fp)

Purpose: pcap_freecode is used to free the memory used by a compiled BPF filter. You can find an example of using pcap_freecode in the Section 10.2.4 section earlier in this chapter.

pcap_breakloopPrototype: void pcap_breakloop(pcap_t *)

Purpose: pcap_breakloop is used to signal pcap_dispatch or pcap_loop (and pcap_next on some platforms) to exit. A flag is set that is checked within many of the functions, and therefore pcap_dispatch and pcap_loop might not exit immediately but can capture up to one more packet.

pcap_filenoPrototype: int pcap_fileno(pcap_t *p)

Purpose: pcap_fileno returns the file descriptor for the capture session. This returns the handle for when a live capture is in progress and -1 if the session is using a saved file.

pcap_closePrototype: void pcap_close(pcap_t *p)

Purpose: pcap_close closes the open session and any associated file handles.

pcap_open_deadPrototype: pcap_t *pcap_open_dead(int linktype, int snaplen)

Purpose: pcap_open_dead is used to create a pcap_t handle, without opening a live capture or saved file. This is commonly used for compiling BPF code. linktype and snaplen specify the link type as per Table 10-2 and the capture length.

10.5.3. Save and Dump File Functions

The following functions are for saving and reading packets from files on disk.

pcap_open_offlinePrototype: pcap_t *pcap_open_offline(const char *fname, char *errbuf)

Purpose: pcap_open_offline is used to open a libpcap-format saved file as a packet source. The fname string holds a filename appropriate for the underlying platform, and can be "-" to denote STDIN. On success a pcap_t handle is returned that can be used to return packets using any of the libpcap functions for capturing packets (such as pcap_next_ex). On error, the function returns NULL, and errbuf is populated with an appropriate human-readable error message.

pcap_dump_openPrototype: pcap_dumper_t *pcap_dump_open(pcap_t *p, const char *fname)

Purpose: pcap_dump_open is used to open a file for saving packets to a disk file. The fname string holds an appropriate filename for the underlying platform, or can be "-" to denote STDOUT. pcap_dump_open returns a pcap_dumper_t handle on success that can used for calling pcap_dump, or NULL on error.

pcap_dumpPrototype: void pcap_dump(u_char *user, struct pcap_pkthdr *h, u_char *sp)

Purpose: pcap_dump writes a packet with the libpcap packet header h, and the packet body sp, to the saved file opened with pcap_dump_open. If called directly, the user value should be the pcap_dumper_t handle opened by pcap_dump_open. pcap_dump can also be called from pcap_loop or pcap_dispatch to dump captured packets directly to a file.

pcap_dump_closePrototype: void pcap_dump_close(pcap_dumper_t *p)

Purpose: pcap_dump_close closes the saved file associated with the p handle.

pcap_dump_flushPrototype: int pcap_dump_flush(pcap_dumper_t *p)

Purpose: pcap_dump_flush is used to flush the file output buffer to disk therefore writing any packets output on dump session p using pcap_dump, but not yet written to disk. pcap_dump_flush returns 0 on success, or -1 on error.

pcap_major_versionPrototype: int pcap_major_version(pcap_t *p)

Purpose: pcap_major_version returns the major version of the libpcap library used to write a saved file opened with pcap_open_offline.

pcap_minor_versionPrototype: int pcap_minor_version(pcap_t *p)

Purpose: pcap_minor_version returns the minor version of the libpcap library used to write a saved file opened with pcap_open_offline.

pcap_filePrototype: FILE *pcap_file(pcap_t *p)

Purpose: pcap_file returns the file handle to a saved file opened with pcap_open_offline. pcap_file returns the handle on success, or NULL if the pcap_t handle p relates to a live capture opened with pcap_open_live.

pcap_is_swappedPrototype: int pcap_is_swapped(pcap_t *p)

Purpose: pcap_is_swapped returns 1 if the saved file referred to by p is in a different byte order than the byte order used in the underlying platform, or 0 if it is the same. If the saved file is in a different byte order, most platforms provide the ntohs( ) and ntohl() functions for converting network order to host order (i.e., big endian to little endian) and/or htons() and htonl( ) for converting host order to network order (i.e., little endian to big endian).

10.5.4. Status Functions

These functions are used to interrogate interfaces for information.

pcap_datalinkPrototype: int pcap_datalink(pcap_t *p)

Purpose: pcap_datalink returns the type of the underlying data link layer of a session. This can be compared to the predefined list of values included in Table 10-2, or converted to a human-readable string using pcap_datalink_val_to_name or pcap_datalink_val_to_description. You can find an example of using pcap_datalink in the Section 10.2.4 section earlier in this chapter.

pcap_list_datalinksPrototype: int pcap_list_datalinks(pcap_t *p, int **dlt_buf);

Purpose: pcap_list_datalinks lists all data link types supported by a capture device. Where multiple types are supported, a particular data link type can be selected with pcap_set_datalink. pcap_list_datalinks returns the number of supported data links on success, with dlt_buf pointing to an array of data link type values. The function returns -1 on error. The data link type values can be converted to human-readable link types (such as the values in Table 10-2) using the pcap_datalink_val_to_name or pcap_datalink_val_to_description functions. You can find an example of using pcap_list_datalinks in the Section 10.2.4 section earlier in this chapter.

pcap_snapshotPrototype: int pcap_snapshot(pcap_t *p)

Purpose: pcap_snapshot returns the number of bytes captured per packet (snapshot length) of the opened session. This is the value specified at the pcap_open_live call to open the interface.

pcap_statsPrototype: int pcap_stats(pcap_t *p, struct pcap_stat *ps)

Purpose: pcap_stats is used to return capture statistics for all packets captured since the start of the capture. pcap_stats is relevant only for live captures because statistics are not stored in saved files. The pcap_stat structure returned contains the members ps_recv (number of packets received), ps_drop (number of packets dropped), ps_ifdrop (number of packets dropped by the interface; this is not supported on all platforms), and, on Windows platforms, bs_capt (number of packets reaching the application). Exactly what is measured for packets received and dropped depends on the platform. For example, when using BPF filters, some platforms count all packets received, while others count only the packets passing the filter. pcap_stats returns -1 on error or when statistics are not supported and it returns 0 on success.

pcap_lib_versionPrototype: const char *pcap_lib_version(void)

Purpose: pcap_lib_version returns a string containing the description of the libpcap version in use. For libpcap version 0.8.3 this is something such as libpcap version 0.8.3.

pcap_datalink_name_to_valPrototype: int pcap_datalink_name_to_val(const char *name);

Purpose: pcap_datalink_name_to_val returns the numeric value of a data link type when supplied as a string. The string name is a data link type, minus the DLT_, as described in Table 10-2. The numeric value is returned on success, or -1 on error.

pcap_datalink_val_to_namePrototype: const char *pcap_datalink_val_to_name(int dlt);

Purpose: pcap_datalink_val_to_name returns the data link name as per Table 10-2 when supplied with the numeric value in dlt. This returns the name on success, or NULL on error. You can find an example of using pcap_datalink_val_to_name in the Section 10.2.4 section earlier in this chapter.

pcap_datalink_val_to_descriptionPrototype: const char *pcap_datalink_val_to_description(int dlt)

Purpose: pcap_datalink_val_to_description returns a short text description when supplied with the numeric value in dlt. This description is contained in the array dlt_choices in pcap.c of the libpcap source code. This returns the name on success, or NULL on error. You can find an example of using pcap_datalink_val_to_description in the Section 10.2.4 section earlier in this chapter.

10.5.5. Error-Handling Functions

libpcap supplies three functions for determining and reporting errors, as shown in the following.

pcap_geterrPrototype: char *pcap_geterr(pcap_t *p)

Purpose: pcap_geterr returns the error text for the last libpcap error that has occurred. This requires that the pcap_t handle p has not been closed using pcap_close. pcap_geterr is used to obtain human-readable error messages for all libpcap functions that do not supply this ability through the use of an errbuf parameter.

pcap_strerrorPrototype: char *pcap_strerror(int error)

Purpose: pcap_strerror is an implementation of strerror(1) for platforms that do not have their own implementation. pcap_strerror returns an operating system error message for a given error code.

pcap_perrorPrototype: void pcap_perror(pcap_t *p, char *prefix)

Purpose: pcap_perror prints the last libpcap error message to STDERR in human-readable format, prefixed by the string prefix .

    Team LiB
    Previous Section Next Section