+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [------ A Precis of Libnet -------------------------------------------------] [------ by udp -----------------------------------] [------ Tuesday May 2nd 2000 -- First Draft -- Released via mailing list ---] -------------[ Table of Contents ]------------------------------------------- -------------------- -0x00 [ IPR / BSD License ] -0x01 [ Executive Summary ] -0x02 [ Why this document? ] -0x03 [ What is Libpcap? ] -0x04 [ What is Libnet? ] -0x05 [ Current Issues ] -0x06 [ Future Goals ] -0x07 [ Conclusions ] -0x08 [ References ] -0x09 [ Contact Info ] -0xFF -------------------- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -0x00-------------------[ IPR / BSD License ] Redistribution and use in ASCII text format and other formats, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of this document must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in any other format must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this document must display the following acknowledgement: This work is based in part of the work of Bruce M. Simpson. 4. The name of Bruce M. Simpson may NOT be used to endorse or promote works derived from this work without specific prior written permission. No warranty or representation is made regarding the reliability, suitability, or correctness of the information within this document. Use of any code or information within this document is completely at your own risk and Bruce M. Simpson will not be held liable for any form of compensation for financial loss caused directly or indirectly by the use of information within this document. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -0x01-------------------[ Executive Summary ] Libnet is a library for working with network packets. It helps to abstract away some of the more tedious and low level aspects of network packet construction. Its major contribution to network programming is that it provides portability and a consistent API for network diagnostic and exploitative applications. It is beginning to become ubiquitous in the development of network security tools. I have reviewed the future directions for Libnet, and identified several short- term objectives for the next update. A number of long-term objectives have also been identified. Perhaps the most important of these is the separating out of link-layer code into a new sister library, leaving libnet to focus on doing things *with* packets, rather than concerning itself with the mechanics of sending and receiving them. Further discussion of protocol enhancements is anticipated in the next draft of this working document. -0x02-------------------[ Why this document? ] This document was originally written by udp to explore future directions for libnet, and also find short term issues which should be resolved before taking libnet further. We consider libpcap first, as libnet builds upon it. Our aims: - Tie relevant information about Libnet development together in one place. - Give a high-level overview of what it is and what it does. - Suggest future directions for taking Libnet forward. Our objectives: - Take over the world with Libnet. This is a current document. It will change. I will be keeping a current copy at this URL: http://www.packetfactory.net/Papers/Libnet_Precis/libnet-precis.txt Any changes to this URL will be submitted to the Libnet mailing list at securityfocus.com. It should be available from my home page if for any reason it gets 'lost'. -0x03---------------------[ What is Libpcap? Libpcap is a packet capture library. It runs on a variety of operating systems. It permits the capture of packets, in real time, using a user space application, on a variety of operating systems. It serves as a consistent and portable API for packet capture. It primarily supports the BSD family of operating systems - these OSes have a kernel-user interface known as the Berkeley Packet Filter (BPF). BPF is of note because it allows packet filters to be compiled and evaluated in kernel space. This yields performance benefits for packet capture applications, because the number of context switches between kernel and user space is greatly reduced. This also reduces CPU load, and is one reason why much of the research done in this field is conducted using BSD platforms. One big disadvantage of using libpcap: packet capture and filtering will NOT take place in-kernel on non-BSD platforms. Another disadvantage of libpcap is that it doesn't support the writing of raw packets to the link layer. Libnet does, however. This means that Libnet has taken responsibility for the interface to link-layer output functionality. Various patches have been proposed for the current pcap version, 0.4, to permit the writing of frames to the link layer. The novice reader may well be familiar with the concept of a 'raw socket', and be wondering why these aren't used as the kernel-user interface for packet capture. To quote Rich Stevens: "The semantics of BSD raw sockets are: - TCP and UDP: no one other than the kernel gets these. - ICMP: a copy of each ICMP gets passed to each matching raw socket, except for a few that the kernel generates the reply for: ICMP echo request, timestamp request, and mask request. - IGMP: all of these get passed to all matching raw sockets. - all other protocols that the kernel doesn't deal with (OSPF, etc.): these all get passed to all matching raw sockets." This is a big reason for libpcap's existence: raw sockets have their limitations, and the relevant incantations for dealing with them are horribly operating system specific. Figure X illustrates how the client application sits on top of libpcap, which provides a more usable interface to the BSD kernel's BPF services. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | client application | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | libpcap | | | +=+=+=kernel space boundary=+=+=+ | | | Berkeley Packet Filter | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure X: Libpcap as used within a typical BSD-based system [-------------- Applications which use Libpcap Libpcap has found favor amongst many software writers. At the time of writing, we know of the following client applications, which represents a small sample of the more ubiquitous applications in use by the Internet community: Ethereal Network protocol analyzer for Unix http://ethereal.zing.org/ Iplog This is an excellent precursor to snort. http://ojnk.sourceforge.net/ Ngrep Grep for network packets http://www.packetfactory.net/Projects/Ngrep/ Nmap ubiquitous remote host scanning/probing tool http://www.insecure.org/nmap/ Ntop View bandwidth utilization statistics in real time. http://www-serra.unipi.it/~ntop/ntop.html Snort Packet sniffer/logger, simple NIDS http://snort.whitehats.com/security.html Tcpdump Basic command line interface to libpcap functionality. http://www.tcpdump.org/ [-------------- Libpcap Core APIs The table below illustrates the core calls presented within libpcap. If nothing else, it should serve as an aide memoire for familiarizing oneself with how libpcap is laid out. ----8<------8<------8<------8<------8<------8<------8<------8<------8<------ +Pcap device calls------+--------------------------------------------------+ | pcap_open_live() | obtain an fd for live packet monitoring | | pcap_close() | close a file descriptor opened by pcap | | pcap_compile() | compile a pcap filter | | pcap_compile_nopcap() | compile a pcap filter for direct use with BPF | | pcap_setfilter() | specify the set of pcap filters for this session | +Pcap Event Loop--------+--------------------------------------------------+ | pcap_loop() | do simple collect & process event loop | | | (this is the API used by many simple pcap tools) | | pcap_dispatch() | collect & process packets explicitly | | pcap_next() | return a pointer to the next packet in this run | +Dump file Manangement--+--------------------------------------------------+ | pcap_open_offline() | open a dump file for offline processing | | pcap_is_swapped() | return true if savefile has different endianness | | pcap_dump_open() | open a dump file for writing | | pcap_dump_close() | close a dump file | | pcap_dump() | write a packet to a dump file | +Pcap informational-----+--------------------------------------------------+ | pcap_datalink() | return type of link layer in use with a device | | pcap_lookupdev() | find suitable device for pcap_open_live() use | | pcap_lookupnet() | determine IP & netmask associated with device | | pcap_snapshot() | return capture snapshot length in use | | pcap_stats() | return pcap statistics for this run | +-----------------------+--------------------------------------------------+ ----8<------8<------8<------8<------8<------8<------8<------8<------8<------ [-------------- Libpcap Summary Pcap is applicable to the full range of raw packet applications. This includes the vast majority of useful packet monitoring and NIDS software. Many of the applications we'd like to write around libnet operate upon real time packet input, therefore it is essential to examine libpcap in order to avoid reinventing the wheel. -0x04-------------------[ What is Libnet? Libnet is a packet construction/creation library. It does not concern itself with packet capture. It attempts to simplify the process of writing a low level network application by providing the required services in one consistent and portable package. It also provides a set of simple packet injection services for writing packets to the network. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | tracerx | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | | | libpcap | libnet | | | | +=+=+=+=+=+= Kernel<+>Userspace Boundary =+=+=+=+=+=+ | | | link layer | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Figure X: Libnet as used within the Tracerx tool -[-------------- Libnet Core APIs Consider this table a printable 'quick reference' card which will fit onto one sheet of A4 or letter paper for your deskside reference: ----8<------8<------8<------8<------8<------8<------8<------8<------8<------ +--Packet Construction ------------------------------------------------------+ | libnet_build_arp() | Build a link-layer-independent ARP datagram | | libnet_build_dns() | Build a DNS UDP datagram | | libnet_build_ethernet() | Build a link-layer Ethernet frame | | libnet_build_icmp_echo() | Build an ICMP ECHO message. | | | [Libnet also provides wrappers for building | | | mask, redirect, time exceeded, timestamp, and | | | unreachable ICMP messages] | | libnet_build_igmp() | Build an IGMP datagram | | libnet_build_ip() | Build an IP datagram | | libnet_build_rip() | Build a RIP datagram | | libnet_build_tcp() | Build a TCP segment | | libnet_build_udp() | Build a UDP datagram | | libnet_insert_ipo() | Insert IP options into a pre-built IP datagram | | libnet_insert_tcpo() | Insert TCP options into a pre-built TCP segment | +--------------------------+-------------------------------------------------+ | | | The packet building functions also create the enclosing IP or UDP datagram,| | where this is applicable - i.e. constructing ICMP, DNS, RIP datagrams. | +----------------------------------------------------------------------------+ | | +--Packet Injection ------------+- via Raw Socket ---------------------------+ | libnet_open_raw_sock() | Open a raw socket for libnet use. | | libnet_close_raw_sock() | Close a raw socket | | libnet_write_ip() | Write an IP datagram using a raw socket | | | | +--Packet Injection ------------+- via Link Layer ---------------------------+ | libnet_open_link_interface() | Open a link layer interface | | libnet_close_link_interface() | Close a link layer interface | | libnet_write_link_layer() | Write an IP datagram or ethernet frame to | | | the link layer | +-------------------------------+--------------------------------------------+ | | +--Memory Management -------------+------------------------------------------+ | libnet_init_packet() | Create a packet buffer (wraps malloc) | | libnet_init_packet_arena() | Create a memory pool | | libnet_destroy_packet() | Destroy a packet buffer (wraps free) | | libnet_destroy_packet_arena() | Destroy a memory pool | | libnet_next_packet_from_arena() | Retrieve next free buffer in pool | +---------------------------------+------------------------------------------+ | | +--Utility Functions -----+--------------------------------------------------+ | libnet_hex_dump() | Hex dump of packet to a stdio stream | | libnet_do_checksum() | Compute a checksum | | libnet_ip_check() | Compute and write the IP header checksum | | libnet_tcp_check() | Compute and write the TCP checksum for a segment | | libnet_get_prand() | Get the next pseudo-random integer | | libnet_seed_prand() | Seed the PRNG | | | | | libnet_plist_chain_xx() | Provide an efficient in-core representation of | | | port list ranges, by implementing them as linked | | | list 'tuples'. | +---------------------------------+------------------------------------------+ | | +--Informational --------+---------------------------------------------------+ | libnet_host_lookup() | Resolve an IPv4 address to a hostname | | libnet_host_lookup_r() | Resolve an IPv4 address to a hostname - reentrant | | libnet_name_resolve() | Resolve a hostname to an IPv4 address | | libnet_get_ipaddr() | Get the IP address for a link-layer interface | | libnet_get_hwaddr() | Get the MAC address for a link-layer interface | +------------------------+---------------------------------------------------+ ----8<------8<------8<------8<------8<------8<------8<------8<------8<------ -[-------------- Other Libnet services Libnet offers other packet building services, which aren't reviewed here for the sake of brevity. These include: o ASN.1 marshaling construction o DNS packet construction o OSPF packet construction -[-------------- State of the Union --[------------- OS Platform Portability Libnet manages to achieve OS-level portability, by creating a simple C API, and then sticking to it. It should be borne in mind that an API is a binding contract between a library, and its future clients. For a library to be useful, it must have an API which is simple and consistent. To become ubiquitous. it must be highly portable. Libnet manages to achieve both of these objectives. --[------------- Language Nonportability At this time, I have not seen Libnet used outside of the C language. A package for Perl 5 known as perl-libnet exists. This is an implementation of high-level stream-oriented application protocols for Perl and should not be confused with Libnet, nor is it a wrapper for Libnet. route's Libnet should not be confused with George Foot's libnet, at http://www.canvasnet.com/libnet/ either. -[-------------- Applications which use Libnet Currently, there are several other projects which make use of Libnet. These are: Firewalk Mike Schiffman's and Dave Goldsmith's network scanning tool http://www.packetfactory.net/Projects/Firewalk/ Dsniff dugsong's controversial set of network monitoring tools. http://www.monkey.org/~dugsong/dsniff/ Tracerx An attempt to coalesce differing Traceroute-like tools. http://www.packetfactory.net/Projects/Tracerx/ Zodiac A swiss army knife for DNS protocol analysis and spoofing. http://www.packetfactory.net/Projects/Zodiac/ [--------------- Applications we'd like to see ported to Libnet Pandora A box of nastiness for Netware http://www.packetfactory.net/Projects/Pandora/ -[-------------- Libnet Summary Libnet has applicability for any form of network diagnostic tool which requires low level packet construction and injection services. This includes the majority of active NIDS. It is a weapon. Weapons occasionally need to be field-stripped for cleaning, lest they jam when you need them the most. -0x05-------------------[ Current Issues -[----------------- Libpcap versus Libnet: What goes where? As documented in the Libpcap chapter, Libnet has now taken responsibility for writing to the link layer. Patches have been proposed by various people, including the late Rich Stevens, who wrote a short program to demonstrate its use - issuing a gratuitous ARP request for when a previously-downed network interface is configured to be up on BSD platforms. My thoughts: At the risk of sounding controversial to some people, I feel it makes more sense conceptually for link-layer input/output functionality to be grouped together in the same library. I believe the notion of link layer input and output belongs at the same level. I table the motion for writing a libpcap replacement. Libpcap's current disadvantages are: - it is not controlled by Libnet developers; - it is not updated as frequently as we would like; - it does not offer packet injection functionality; - the code is not re-entrant; - it does not take advantage of things such as hardware checksum offloading and many other features offered by state-of-the-art network hardware. Libnet should have link-layer read and write functionality isolated into a new sister library, which I'll hypothetically name 'Libplink'. This would enable Libnet to break new ground in real time packet creation, manipulation, and processing. Such a move would also make it easier for such things as object oriented APIs to be created, thus further promoting the use of libnet in state- of-the-art NIDS applications. The above would be distributed under a fairly liberal BSD license. The code for handling the raw socket functionality could be rolled into one file without any problems, as these functions are always used together. This includes libnet_write_ip(), libnet_open_socket(), and libnet_close_socket(). -[----------------- Documentation issues Libnet's PRNG is currently a simple wrapper for the host's C library PRNG. This has been highlighted here as a reminder that anybody writing a cryptographic application should either be writing their own PRNG, or reusing one such as Bruce Schneier's 'Yarrow'. My thoughts: We should point this out to people in the man page, just in case any idiot goes ahead and uses the prand() functionality for something real. -[----------------- Low level API issues Some issues have been found with the API which will have to be resolved for the next release. --[---------------- ILP32 Dependency As of my first reading of the code, it appeared that libnet made all the traditional assumptions about the C integer datatypes, resulting in a dependency on the ILP32 model where the int, long, and pointer types are all 32 bits wide on the host architecture. The Libnet mailing list has been mailed at this time. I am waiting on feedback from Dan Frasnelli about the changes made to the 0.99d release candidate to make Libnet operate successfully on the Alpha architecture. --[---------------- Header Organization The practice of placing declarations inside differently named header files according to their syntactic type is of questionable use. It might be better to reorganize things according to functionality, to improve modularity. --[---------------- Legacy #defines These should be stripped out as soon as possible, to avoid polluting the namespace, and to make future changes easier to implement. --[---------------- Internal declarations Libnet leaves many functions which are internal to the library in the global namespace. This includes all functions without the 'libnet_' prefix. My thoughts: We could wrap them in a way similar to _KERNEL definitions on FreeBSD, in order to hide things used to build the library from users of the library. The symbol we use to do this could probably be named _LIBNET_PRIVATE. As time permits, I will examine which symbols can be hidden away like this, and which things can be declared to have static linkage. --[---------------- Checksum function confusion This concerns an issue with the checksum functions - it might not be immediately evident upon reading the documentation what does what. libnet_do_checksum() is the generic checksummer - pass it a protocol argument and it will perform any checksumming of the packet being constructed accordingly. It is documented and is public. libnet_in_cksum() is a function which computes the IP/UDP checksum over a buffer. It is _not documented_. However, it is used by the libnet_do_checksum() function and has external linkage. It returns an int. The IP/UDP checksum is a 16 bit wide field. libnet_ip_check() is a function which computes the IP/UDP checksum over a buffer. It simply calls libnet_in_cksum() over the buffer and then uses a macro to handle stuffing the 32-bit result into a 16-bit value. Should libnet_in_cksum() be documented explicitly, or declared static and internal to the Libnet library? My thoughts: As it performs a ubiquitous function, and in keeping with the rationale behind Libnet, which is not to enforce any particular programming style (something guaranteed to annoy hackers), I propose it be _documented and made public in the library_. -[----------------- Raw Sockets: IP_HDRINCL The use of a host's raw IP socket framework to write IP datagrams to the network can greatly simplify the development of low level IP applications. However, over the years, no single consistent API has emerged for the treatment of SOCK_RAW in socket applications. Because of this, multiple versions of system tools such as ping and traceroute exist. This is one issue which libnet was originally created to address. Libnet currently trusts the host OS to do the 'right thing' with IP_HDRINCL, although there is some confusion over what the 'right thing' is. This section attempts to document the known issues with the use of IP_HDRINCL on commonly used platforms. One way of sidestepping/avoiding this issue is to go straight to the link layer, and this is often used as the solution. Byte swapping to overcome the problem with traditional BSD IP_HDRINCL behavior is done when LIBNET_BSD_BYTE_SWAP is defined. The LIBNET_BSD_BYTE_SWAP define is generic by nature. It should no longer need to be used with FreeBSD or OpenBSD. BSD/OS will need it. NetBSD's status is not known - tell me. The libnet module responsible for opening raw sockets is libnet_socket.c, and the writing code is in libnet_write_ip.c. Any changes made to the way we handle raw sockets will go there. ---[--------------- Platform-Specific Issues ----[-------------- BSD Platforms Historic BSD IP_HDRINCL implementations specify that it's a raw IP packet, including header, with everything as it will go out onto the network _EXCEPT_ the ip_len and ip_off fields in the header. This is in host order, as it is used to represent the length of the packet. The kernel will change these fields to network order using swab() when it sends the packet out on the network. However, each BSD variant appears to have its own quirks. I have attempted to document these quirks here for future reference. ----[-------------- FreeBSD FreeBSD has now been fixed with regards to the treatment of ip_off/ip_len. According to /usr/src/sys/netinet/raw_ip.c in the 4.0-STABLE release of FreeBSD, FreeBSD should have no problem with the IP_HDRINCL option, and should pass the IPv4 header to the link layer verbatim with no changes. The only exception to this is the ip_id and ip_len fields; FreeBSD will overwrite the ip_id field if it is set to zero. It will also return EINVAL if the specified IPv4 header length is greater than the length passed to the socket subsystem, or if the overall IP length is less than the length of the specified IP header, or if the IP header is not equal to the size of the IPv4 header. FreeBSD also maintains statistics for IP datagrams output with the IP_HDRINCL option. This is maintained in the ipstat.ips_rawout member, and can be viewed using 'netstat -p ip'. FreeBSD has BPF support for the link layer. ----[-------------- NetBSD From the BSD/OS 4.1 manual page for ip(4) which is current as of this writing: Unlike previous BSD releases, the program must set all the fields of the IP header, including the following: ip->ip_v = IPVERSION; ip->ip_hl = hlen >> 2; ip->ip_id = 0; /* 0 means kernel set appropriate value */ ip->ip_off = offset; The ip_len and ip_off fields must be provided in host byte order. All other fields must be provided in network byte order. See byteorder(4) for more information on network byte order. If the header source address is set to INADDR_ANY, the kernel will choose an appropriate address. According to a post dated October 1996 by Kurt J. Lidl to the tech- net@netbsd.org and freebsd-arch mailing lists: "So far, BSDi (which is the system where I first noticed this issue) has committed to fixing this interface if both the FreeBSD and NetBSD groups will commit to fixing it also." Make up your own mind about this. BSD/OS supports the BPF link-layer interface. ----[-------------- OpenBSD My reading of CHANGELOG for OpenBSD 2.1 reveals that OpenBSD's behavior with regard to ip_len and ip_off has been fixed to require these fields to be in network byte order, that is, they are sent without modification. From CHANGELOG: "This is a compatibility/portability fix and we expect other BSD systems to eventually follow suit." As of OpenBSD 2.3, IP_HDRINCL is supported from within the Linux emulation subsystem, and its semantics should be similar to the real thing. OpenBSD, in common with other BSD variants, supports the BPF interface. ----[-------------- Solaris Solaris allows the use of the IPPROTO_RAW option when requesting a PF_INET, SOCK_RAW socket. This is somewhat analogous to IP_HDRINCL. It will *expect* an IP header to be included in the data written to such a socket in this instance. It will compute the IP checksum on your behalf. Solaris (at least 2.5/2.6) and changes the ip_id field, and adds a Do Not Fragment flag to the IP header (IP_DF). It also expects the checksum to contain the length of the transport level header, and the data. Solaris uses the DLPI link layer interface. Libnet supports this link layer. This should yield the desired results. ----[-------------- IRIX From the Raw IP Networking FAQ: "Further reports which I cannot verify (can't reproduce), consist of claims that Solaris 2.x and Irix 6.x will change the sequence and acknowledgment numbers. Irix 6.x is also believed to have the problem mentioned in the previous paragraph. If you experience these problems, double check with the example source code. " SGI: Patch 2673 [IRIX 6.2] - IRIX 6.2 Networking Kernel Rollup #6 Fixes: 473385 - IP_HDRINCL does not work on IP options and ip_id is bad SGI: Patch 3577 [IRIX 6.4] - IRIX 6.4 Networking Kernel Rollup #7 473385 - IP_HDRINCL does not work on IP options and ip_id is bad I think it's becoming something of a consensus within the industry that IRIX is 'swiss cheese' when it comes to security - it's full of holes. Regard this as an inane, 'smart-ass' comment at your own peril. I would be grateful to hear from anyone who has applied the above patches to production IRIX machines which exercise this functionality. ----[-------------- Linux One bug reported in Linux in July 1998 involved Linux's sendto() over SOCK_RAW code not taking IP_HDRINCL into account, when comparing the packet length with the MTU for the underlying link layer interface. Linux uses the SOCK_PACKET link layer interface. This is currently supported by libpcap, in pcap-linux.c. ----[-------------- HPUX I don't have an HPUX host to test IP_HDRINCL functionality on, but based on what I've seen, I would wager that arbitrary IP packet injection requires that one go directly to the link layer. HPUX is known to support the DLPI interface for this. ----[-------------- Win32 IP_HDRINCL may not be supported by the underlying Winsock Service Provider under Win32. Recall that the Winsock family of libraries, under Windows platforms, define an interface for Winsock functionality; the implementation is provided by a 'Service Provider' set of DLLs. Microsoft's Winsock is known NOT to support IP_HDRINCL on any platform OTHER than Windows 2000. Details of this can be found in the Winsock Programmer's FAQ. Specifics of how IP_HDRINCL works under Windows 2000 are not known at this time. If you know of other Winsock 2 compatible SPs which grok IP_HDRINCL, let me know via email, and I will update this document. For the time being, you probably want to talk straight to NDIS, which is the link layer standard which Microsoft developed with 3Com and adopted for Windows NT. Windows 2000 makes use of the new NDIS 5.0 specification. We currently know of two Libnet port forks for Win32: the one Dan Moniz is working on, and Luca Deri's port which uses NDIS. ----[-------------- Amiga AmiTCP From http://cloanto.com/kb/4-112.html: "Some versions of Windows TCP/IP do not support certain rarely-used TCP/IP socket options which the original Amiga bsdsocket.library supports. For example, the "traceroute" command which comes with AmiTCP/IP may fail if Winsock does not support IP_HDRINCL/raw sockets." Sounds to me as though Amiga AmiTCP supports IP_HDRINCL. I'd love to hear more about this from other Amigans. It's more than likely that SANA-2 compliant network drivers for the Amiga will do link-layer capture and injection. ----[-------------- Other platforms Information about other platforms is solicited from all readers, wherever possible. I'd be particularly interested in the behavior of QNX, AmiTCP, and any embedded system which offers BSD SOCK_RAW or link layer services. I will be cataloguing and publishing this information for use in future projects. -0x06-------------------[ Future Goals Where libnet provides output, and things to be output, libpcap provides input. The primary goal of improving libnet should be to provide services which seamlessly integrate with those currently provided by libpcap, and which expand upon what is presently possible. -[----------------------- General ideas - Add IPsec packet creation, to make libnet useful for work which targets VPNs and IPsec. DoS attacks against key exchange daemons are one possible avenue. - Possibly add PPTP packet creation. - Possibly provide SPARC and ix86 optimized IP checksum routines. - Possibly allow optional offloading of checksums to the link layer device, HOWEVER, we may want to send packets with a bad checksum for a reason. At this time, having spoken to Jonathan Lemon of the FreeBSD project, I know that FreeBSD's support for checksum offloading will permit the capture and injection of packets with a bad checksum. - CSMA/CD - We'd really like to see a portable means of counting/watching collisions on link layers which have this notion. This is something libpcap doesn't have. - Add X25 support. - Add ATM support. - Add IPX/SPX support. - Add IPv6 support. Support for these protocols within Libnet is something we'd certainly like to see in future. There has been some minimal discussion of this on the mailing list, and this is one reason why this consultation document is being rolled out. Adding these would generally involve making changes to the API, particularly for IPv6. My initial thoughts on this are that we should stick to what FreeBSD and many other OS projects have done - keeping the old namespace for IPv4 'ip' et al, and naming new functions & structures with an 'ipv6' prefix Suggestions/patches for adding pcap_write(): http://ethereal.zing.org/lists/ethereal-dev/199901/msg00048.html http://www.cyberus.ca/~hadi/thepatch http://www.cyberus.ca/~hadi/pcap.html Detecting packet collisions at link layer (e.g. CSMA/CD) http://ethereal.zing.org/lists/ethereal-dev/199901/msg00028.html NetBSD camp first suggests fixing IP_HDRINCL host/net byte ordering: http://mail-index.netbsd.org/netbsd-bugs/1996/10/18/0005.html -0x07-------------------[ Conclusions For the short term: - Keep focusing on making Libnet leaner, smarter, fitter. - Do everything we can to keep the API simple and consistent. - Ensure portability. Portability encourages ubiquity. - Encourage more new network tools to be developed around libnet, and not just for the reason that it can write to the link layer. For the long term: - Begin to add other non-IP protocol support. - Look towards offering object oriented interfaces. - We may even replace libpcap. Libnet is already an excellent library. Let's remain dedicated to doing everything we can to make it rule the world. -0x08-------------------[ References | > The Packet Factory http://www.packetfactory.net/ > Libnet mailing list http://www.securityfocus.com/ > Libnet home site http://www.packetfactory.net/Projects/Libnet/ > Libnids home site http://www.packetfactory.net/Projects/Libnids/ | > Libpcap > Libpcap for Win32 http://www-serra.unipi.it/~ntop/libpcap.html > ntop: network top http://www-serra.unipi.it/~ntop/ntop.html > ngrep: network grep http://www.packetfactory.net/Projects/Ngrep/ | > Raw IP Networking FAQ http://www.whitefang.com/rin/ > Winsock Programmer's FAQ > http://www.cyberport.com/~tangent/programming/winsock/advanced.html > Fun with ARP and ICMP | http://staff.washington.edu/dittrich/papers/arp_fun.txt | > Yarrow PRNG http://www.counterpane.com/yarrow.html | > udp's home page http://www.closed-networks.com/~udp/ > dnm's home page http://www.pobox.com/~dnm/ -0x09-------------------[ Contact Info Bruce M. Simpson Dan Moniz Mike D. Schiffman Jonathan Lemon Canonical URL for this document: http://www.packetfactory.net/Papers/Libnet_Precis/libnet-precis.txt +0xFF+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[ EOF ]