tcpdump mailing list archives
Re: Initializing a device
From: Guy Harris <guy () alum mit edu>
Date: Fri, 6 Jan 2012 03:15:39 -0800
On Jan 5, 2012, at 1:40 AM, Akos Vandra wrote:
I browsed through the code of pcap_open_live, and pcap_set_promisc, and related stuff, and I think that now I understand how this works. However in my opinion, the way parameter passing is implemented breaks the principle of modularity. iface here = pcap_canusb, pcap_usbmon, etc. What is the correct term for these?
There isn't one. I've used "device-type module" later in this message. "iface" is close to "interface", and that could be confused with "interface" in the sense of a network interface, on which you might do capture.
I keep using iface and module interleavedly in my mails... If - let's say - my interface (canusb) needs a parameter for the baud rate, and another interface, let's say a more low-level radio iface needs parameters like frequency, channel, modulation (ASK or FSK), then to fully support these capture ifaces, we would need to add a lot of parameters to pcap_open_live,
No, we wouldn't need to (and we wouldn't ever do so, as that'd break source and binary compatibility). You browsed through pcap_open_live(), so presumably you've seen that it's just pcap_t * pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf) { pcap_t *p; int status; p = pcap_create(source, errbuf); if (p == NULL) return (NULL); status = pcap_set_snaplen(p, snaplen); if (status < 0) goto fail; status = pcap_set_promisc(p, promisc); if (status < 0) goto fail; status = pcap_set_timeout(p, to_ms); if (status < 0) goto fail; [some code to make the backwards-compatibility stuff work a little better elided] status = pcap_activate(p); if (status < 0) goto fail; return (p); fail: [error-message-generation-code elided] pcap_close(p); return (NULL); } I.e., that it's a wrapper around pcap_create() and pcap_activate(). It exists so that programs written using the old pcap_open_live() API will continue to compile and run. Programs that need to use *any* capabilities not provided by pcap_open_live(), such as setting the kernel capture buffer size, setting monitor mode on 802.11 interfaces, or setting the time stamp type, must use the newer APIs - pcap_create(), the appropriate setter routines, and pcap_activate().
and a lot of API functions (like pcap_set_modulation, pcap_set_channel) which are used by a single iface. That is - in my opinion - bad.
The current API was chosen during a discussion on the tcpdump-workers mailing list back in 2008. The thread can be found in http://thread.gmane.org/gmane.network.tcpdump.devel/2800/ We ended up going with something along the lines of Michael Richardson's suggestion: http://thread.gmane.org/gmane.network.tcpdump.devel/2800/focus=2830 "I.e. we should instead have a new pcap_open() call, and then we should have a serious of calls that set various options or ask for various things based upon that handle."
My suggestion for a solutoin - which is a *lot* of work -, but will add a nice functionality to libpcap: Please view this from a higher level, if you guys like it we might think about data structures, etc later, I have ideas about that too, but they are quite immature yet. Add a new _op command list_parameters, which returns a list of the parameters that it needs with data about: parameter name, type, default value. If the _op is unset, or returns null, it means the iface doesn't need any (backw compatibility). Add a few new API calls to create a list of parameters, and set values in it. These functions check if the correct type of argument is given. params_create - returns a handle params_set_uint8 - sets an uint value, etc. Then pass this parameters structure to the activate_op, and it can do the activation based on these parameters. Now if we add a new parameter, there is no need for new API calls, just add a new entry to the param_list.
Something along those lines was proposed in that thread: http://thread.gmane.org/gmane.network.tcpdump.devel/2800/focus=2818 and that proposal evolved: http://thread.gmane.org/gmane.network.tcpdump.devel/2800/focus=2819 http://thread.gmane.org/gmane.network.tcpdump.devel/2800/focus=2820 http://thread.gmane.org/gmane.network.tcpdump.devel/2800/focus=2822 http://thread.gmane.org/gmane.network.tcpdump.devel/2800/focus=2823 http://thread.gmane.org/gmane.network.tcpdump.devel/2800/focus=2824 http://thread.gmane.org/gmane.network.tcpdump.devel/2800/focus=2826 and then Michael Richardson said http://thread.gmane.org/gmane.network.tcpdump.devel/2800/focus=2828 which, shortly afterwards, got us moving in the direction of his suggestion. An API pattern based on a list of parameters is more complicated than the current API pattern, as you have to create and manipulate the list. One disadvantage of the current API pattern is that it can't handle new parameters added by new device-type modules without changing the core API. Another small one is that if a program *could* work if a given parameter can't be set, by, say, not offering the option to set it, but *should* offer that option if it's available - a classic autoconf example, i.e. check whether pcap_set_XXX() is available and set a #define HAVE_PCAP_SET_XXX, and use #ifdefs to call it only if it's available - you could potentially avoid autoconf if the options are identified by #define names, by just #ifdeffing on the #define name. One disadvantage of changing the API pattern is that programs that would use the new API's capabilities will have to add more autoconf stuff to check for the new new API and use it rather than using the new (pcap_create()/pcap_set_XXX()/pcap_activate()) API if available or the old (pcap_open_live()) API if not. If we're going to change the API pattern again, let's make sure it's the last time we do that....
This would be very handy for UIs too, as they could implement a generic capture interface options dialog, and use the list returned by the param_list_op to populate it with widgets or controls.
Yes, although a UI might still handle some options specially, e.g. if, as, and when we add an 802.11 channel option, it might only be made available if monitor mode was selected, so a GUI should either hide or gray out the channel option if monitor mode wasn't selected.
I think the whole decision has one very sensitive part: As this architecture mainly eases implementation of different kinds of ifaces which are *not* based on ethernet, like my can device, or an i2c device, or a generic radio device, or whatever comes to mind, the main question is if it's libpcap's goal to support these.
libpcap's goal from Day One has been to support arbitrary network interface types - one interface type that has had special-parameter support for a while is 802.11, for which we have the "monitor mode" flag.- This is the tcpdump-workers list. Visit https://cod.sandelman.ca/ to unsubscribe.
Current thread:
- Initializing a device Akos Vandra (Jan 04)
- Re: Initializing a device Sam Roberts (Jan 04)
- Re: Initializing a device Guy Harris (Jan 04)
- Re: Initializing a device Akos Vandra (Jan 05)
- Re: Initializing a device Guy Harris (Jan 06)
- Re: Initializing a device Akos Vandra (Jan 06)
- Re: Initializing a device Jakub Zawadzki (Jan 06)
- Re: Initializing a device Akos Vandra (Jan 06)
- Re: Initializing a device Guy Harris (Jan 11)
- Re: Initializing a device Akos Vandra (Jan 12)
- Re: Initializing a device Guy Harris (Jan 12)
- Re: Initializing a device Akos Vandra (Jan 12)
- Re: Initializing a device Akos Vandra (Jan 17)
- Re: Initializing a device Akos Vandra (Jan 05)
- Re: Initializing a device Guy Harris (Jan 06)