1 How to write a libpcap module 2 3WARNING: this document describes an unstable interface; future releases 4of libpcap may, and some probably will, change the interface in an 5incompatible fashion. If you submit your module to the libpcap 6developers for inclusion in libpcap, not only does that make it more 7likely that it will be available in the libpcap provided by operating 8system vendors (such as Linux distributions), but it also means that we 9will attempt to update it to handle future changes to this interface. 10If we add new capabilities, we may have to ask you how to provide those 11additional capabilities if you're using an underlying mechanism for 12which we have neither the source code nor the documentation. 13 14NOTE: this document assumes familiarity with the entire libpcap API. 15 16TODO: more routines, more stuff that the activate routine has to do 17(such as setting the list of DLT_s), convert to Markdown? 18 19On Linux, *BSD, macOS, Solaris, AIX, HP-UX, IRIX, and Tru64 UNIX, 20Libpcap supports capturing on network interfaces as supported by the 21operating system networking stack, using the native packet capture 22mechanism provided by the OS. On Windows, it supports it with the help 23of the driver and library supplied by WinPcap and Npcap. 24 25In addition, it also supports capturing on other types of devices, such 26as: 27 28 specialized capture cards, such as Endace DAG cards; 29 30 network adapters that provide special high-performance code 31 paths, such as CSPI Myricom adapters; 32 33 buses such as USB; 34 35 software communication channels such as D-Bus and Linux netlink; 36 37 etc.. 38 39Support for those devices is provided by modules compiled into libpcap. 40 41If you want to add such a module, you would first have to check the list 42of link-layer header types supported by libpcap, to see if one of those 43would be sufficient for your device. The current version of the list 44can be found at 45 46 https://www.tcpdump.org/linktypes.html 47 48If none of those would work for your device, please read 49doc/DLT_ALLOCATE_HOWTO.md and the introductory paragraphs on the Web 50page mentioned above, and then send a request for the new link-layer 51header type to tcpdump-workers@lists.tcpdump.org. 52 53Once you have a link-layer header type value or values that you can use, 54you can add new module. 55 56The module should be a C source file, with a name of the form 57pcap-{MOD}.c, where {MOD} is a name appropriate for your device; for 58example, the support for DAG cards is in pcap-dag.c, and the support for 59capturing USB traffic on Linux is pcap-usb-linux.c. 60 61Your module is assumed to support one or more named devices. The names 62should be relatively short names, containing only lower-case 63alphanumeric characters, consisting of a prefix that ends with an 64alphabetic character and, if there can be more than one device instance, 65possibly followed by a numerical device ID, such as "mydevice" or 66"mydevice0"/"mydevice1"/.... If you have more than one type of device 67that you can support, you can have more than one prefix, each of which 68can be followed by a numerical device ID. 69 70The two exported functions that your module must provide are routines to 71provide a list of device instances and a program to initialize a 72created-but-not-activated pcap_t for an instance of one of your devices. 73 74The "list of device instances" routine takes, as arguments: 75 76 a pointer to a pcap_if_list_t; 77 78 a pointer to an error message buffer. 79 80The error message buffer may be assumed to be PCAP_ERRBUF_SIZE bytes 81large, but must not be assumed to be larger. By convention, the routine 82typically has a name containing "findalldevs". 83 84The routine should attempt to determine what device instances are 85available and add them to the list pointed to by the first argument; 86this may be impossible for some modules, but, for those modules, it may 87be difficult to capture on the devices using Wirehshark (although it 88should be possible to capture on them using tcpdump, TShark, or other 89programs that take a device name on the command line), so we recommend 90that your routine provide the list of devices if possible. If it 91cannot, it should just immediately return 0. 92 93The routine should add devices to the list by calling the add_dev() 94routine in libpcap, declared in the pcap-int.h header. It takes, as 95arguments: 96 97 the pointer to the pcap_if_list_t passed as an argument to the 98 routine; 99 100 the device name, as described above; 101 102 a 32-bit word of flags, as provided by pcap_findalldevs(); 103 104 a text description of the device, or NULL if there is no 105 description; 106 107 the error message buffer pointer provided to the routine. 108 109add_dev() will, if it succeeds, return a pointer to a pcap_if_t that was 110added to the list of devices. If it fails, it will return NULL; in this 111case, the error message buffer has been filled in with an error string, 112and your routine must return -1 to indicate the error. 113 114If your routine succeeds, it must return 0. If it fails, it must fill 115in the error message buffer with an error string and return -1. 116 117The "initialize the pcap_t" routine takes, as arguments: 118 119 a pointer to a device name; 120 121 a pointer to an error message buffer; 122 123 a pointer to an int. 124 125It returns a pointer to a pcap_t. 126 127Your module will probably need, for each pcap_t for an opened device, a 128private data structure to maintain its own information about the opened 129device. These should be allocated per opened instance, not per device; 130if, for example, mydevice0 can be captured on by more than one program 131at the same time, there will be more than one pcap_t opened for 132mydevice0, and so there will be separate private data structures for 133each pcap_t. If you need to maintain per-device, rather than per-opened 134instance information, you will have to maintain that yourself. 135 136The routine should first check the device to see whether it looks like a 137device that this module would handle; for example, it should begin with 138one of the device name prefixes for your module and, if your devices 139have instance numbers, be followed by a number. If it is not one of 140those devices, you must set the integer pointed to by the third 141argument to 0, to indicate that this is *not* one of the devices for 142your module, and return NULL. 143 144If it *is* one of those devices, it should call pcap_create_common, 145passing to it the error message buffer as the first argument and the 146size of the per-opened instance data structure as the second argument. 147If it fails, it will return NULL; you must return NULL in this case. 148 149If it succeeds, the pcap_t pointed to by the return value has been 150partially initialized, but you will need to complete the process. It 151has a "priv" member, which is a void * that points to the private data 152structure attached to it; that structure has been initialized to zeroes. 153 154What you need to set are some function pointers to your routines to 155handle certain operations: 156 157 activate_op 158 the routine called when pcap_activate() is done on the 159 pcap_t 160 161 can_set_rfmon_op 162 the routine called when pcap_can_set_rfmon() is done on 163 the pcap_t - if your device doesn't support 802.11 164 monitor mode, you can leave this as initialized by 165 pcap_create_common(), as that routine will return "no, 166 monitor mode isn't supported". 167 168Once you've set the activate_op and, if necessary, the can_set_rfmon_op, 169you must return the pcap_t * that was returned to you. 170 171Your activate routine takes, as an argument, a pointer to the pcap_t 172being activated, and returns an int. 173 174The perameters set for the device in the pcap_create() call, and after 175that call(), are mostly in the opt member of the pcap_t: 176 177 device 178 the name of the device 179 180 timeout 181 the buffering timeout, in milliseconds 182 183 buffer_size 184 the buffer size to use 185 186 promisc 187 1 if promiscuous mode is to be used, 0 otherwise 188 189 rfmon 190 1 if monitor mode is to be used, 0 otherwise 191 192 immediate 193 1 if the device should be in immediate mode, 0 otherwise 194 195 nonblock 196 1 if the device should be in non-blocking mode, 0 197 otherwise 198 199 tstamp_type 200 the type of time stamp to supply 201 202 tstamp_precision 203 the time stamp precision to supply 204 205The snapshot member of the pcap_t structure will contain the snapshot 206length to be used. 207 208Your routine should attempt to set up the device for capturing. If it 209fails, it must return an error indication which is one of the PCAP_ERROR 210values. For PCAP_ERROR, it must also set the errbuf member of the 211pcap_t to an error string. For PCAP_ERROR_NO_SUCH_DEVICE and 212PCAP_ERROR_PERM_DENIED, it may set it to an error string providing 213additional information that may be useful for debugging, or may just 214leave it as a null string. 215 216If it succeeds, it must set certain function pointers in the pcap_t 217structure: 218 219 read_op 220 called whenever packets are to be read 221 222 inject_op 223 called whenever packets are to be injected 224 225 setfilter_op 226 called whenever pcap_setfilter() is called 227 228 setdirection_op 229 called whenever pcap_setdirection() is called 230 231 set_datalink_op 232 called whnever pcap_set_datalink() is called 233 234 getnonblock_op 235 called whenever pcap_getnonblock() is called 236 237 setnonblock_op 238 called whenever pcap_setnonblock() is called 239 240 stats_op 241 called whenever pcap_stats() is called 242 243 cleanup_op 244 called if the activate routine fails or pcap_close() is 245 called 246 247and must also set the linktype member to the DLT_ value for the device. 248 249On UN*Xes, if the device supports waiting for packets to arrive with 250select()/poll()/epoll()/kqueues etc., it should set the selectable_fd 251member of the structure to the descriptor you would use with those 252calls. If it does not, then, if that's because the device polls for 253packets rather than receiving interrupts or other signals when packets 254arrive, it should have a struct timeval in the private data structure, 255set the value of that struct timeval to the poll timeout, and set the 256required_select_timeout member of the pcap_t to point to the struct 257timeval. 258 259The read_op routine is called when pcap_dispatch(), pcap_loop(), 260pcap_next(), or pcap_next_ex() is called. It is passed the same 261arguments as pcap_dispatch() is called. 262 263The routine should first check if the break_loop member of the pcap_t is 264non-zero and, if so, set that member to zero and return 265PCAP_ERROR_BREAK. 266 267Then, if the pcap_t is in blocking mode (as opposed to non-blocking 268mode), and there are no packets immediately available to be passed to 269the callback, it should block waiting for packets to arrive, using the 270buffering timeout, first, and read packets from the device if necessary. 271 272Then it should loop through the available packets, calling the callback 273routine for each packet: 274 275 If the PACKET_COUNT_IS_UNLIMITED() macro evaluates to true when 276 passed the packet count argument, the loop should continue until 277 there are no more packets immediately available or the 278 break_loop member of the pcap_t is non-zero. If the break_loop 279 member is fount to be non-zero, it should set that member to 280 zero and return PCAP_ERROR_BREAK. 281 282 If it doesn't evaluat to true, then the loop should also 283 terminate if the specified number of packets have been delivered 284 to the callback. 285 286Note that there is *NO* requirement that the packet header or data 287provided to the callback remain available, or valid, after the callback 288routine returns; if the callback needs to save the data for other code 289to use, it must make a copy of that data. This means that the module is 290free to, for example, overwrite the buffer into which it read the 291packet, or release back to the kernel a packet in a memory-mapped 292buffer shared between the kernel and userland, after the callback 293returns. 294 295If an error occurs when reading packets from the device, it must set the 296errbuf member of the pcap_t to an error string and return PCAP_ERROR. 297 298If no error occurs, it must return the number of packets that were 299supplied to the callback routine. 300 301The inject routine is passed a pointer to the pcap_t, a buffer 302containing the contents of the packet to inject, and the number of bytes 303in the packet. If the device doesn't support packet injection, the 304routine must set the errbuf member of the pcap_t to a message indicating 305that packet injection isn't supported and return PCAP_ERROR. Otherwise, 306it should attempt to inject the packet; if the attempt fails, it must 307set the errbuf member of the pcap_t to an error message and return 308PCAP_ERROR. Otherwise, it should return the number of bytes injected. 309 310The setfilter routine is passed a pointer to the pcap_t and a pointer 311to a struct bpf_program containing a BPF program to be used as a filter. 312If the mechanism used by your module can perform filtering with a BPF 313program, it would attempt to set that filter to the specified program. 314 315If that failed because the program was too large, or used BPF features 316not supported by that mechanism, the module should fall back on 317filtering in userland by saving a copy of the filter with a call to 318install_bpf_program(), setting a flag in the private data instructure 319indicating that filtering is being done by the module and, in the read 320routine's main loop, checking the flag and, if it's set, calling 321pcap_filter(), passing it the fcode.bf_insns member of the pcap_t, the 322raw packet data, the on-the-wire length of the packet, and the captured 323length of the packet, and only passing the packet to the callback 324routine, and counting it, if pcap_filter() returns a non-zero value. 325(If the flag is not set, all packets should be passed to the callback 326routine and counted, as the filtering is being done by the mechanism 327used by the module.) If install_bpf_program() returns a negative value, 328the routine should return PCAP_ERROR. 329 330If the attempt to set the filter failed for any other reason, the 331routine must set the errbuf member of the pcap_t to an error message and 332return PCAP_ERROR. 333 334If the attempt to set the filter succeeded, or it failed because the 335mechanism used by the module rejected it and the call to 336install_bpf_program() succeeded, the routine should return 0. 337 338If the mechanism the module uses doesn't support filtering, the pointer 339to the setfilter routine can just be set to point to 340install_bpf_program; the module does not need a routine of its own to 341handle that. 342 343The setdirection routine is passed a pointer to the pcap_t and a 344pcap_direction_t indicating which packet directions should be accepted. 345If the module can't arrange to handle only incoming packets or only 346outgoing packets, it can set the pointer to the setdirection routine to 347NULL, and calls to pcap_setdirection() will fail with an error message 348indicating that setting the direction isn't supported. 349 350XXX describe set_datalink, including what the activate routine has to do 351XXX 352 353XXX describe the rest of the routines XXX 354