├── README.rpm ├── README ├── NEWS ├── rpm ├── redhat.spec └── mandriva.spec ├── autogen.sh ├── TODO ├── doc ├── UPDATE-CHECK ├── create-man.sh ├── netdiscover.txt └── netdiscover.8 ├── src ├── Makefile.am ├── fhandle.h ├── misc.h ├── screen.h ├── fhandle.c ├── ifaces.h ├── data_al.h ├── data_reply.c ├── misc.c ├── data_request.c ├── data_unique.c ├── ifaces.c ├── screen.c └── main.c ├── configure.ac ├── Makefile.am ├── AUTHORS ├── .github └── workflows │ ├── check-update-oui.yml │ └── full-check.yml ├── README.md ├── update-oui-database.sh ├── ChangeLog └── COPYING /README.rpm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | README.md -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | Look at https://github.com/netdiscover-scanner/netdiscover for news. 2 | -------------------------------------------------------------------------------- /rpm/redhat.spec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netdiscover-scanner/netdiscover/HEAD/rpm/redhat.spec -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Run this to generate all the initial makefiles, etc. 3 | 4 | autoreconf --install 5 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | - Mac ignore filter 2 | - Add support to sort entries 3 | - Make parsable output compatible with the three view modes 4 | - Implement network guessing mode 5 | - Add identified hosts list 6 | -------------------------------------------------------------------------------- /doc/UPDATE-CHECK: -------------------------------------------------------------------------------- 1 | When updating, change the following files (if needed): 2 | 3 | - Add rights for contributors (copyright) 4 | - ChangeLog 5 | - Check for spelling errors in ChangeLog and manpage. 6 | - doc/create-man.sh (DATE, version) 7 | - Generate a new manpage. 8 | - README 9 | - src/oui.h (refresh via update-oui-database.sh) 10 | - configure.ac (VERSION) 11 | - Test on Debian Sid. 12 | - Generate extra tarballs via 'make dist' and upload to GitHub 13 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | sbin_PROGRAMS = netdiscover 2 | 3 | netdiscover_SOURCES = \ 4 | main.c\ 5 | ifaces.c\ 6 | screen.c\ 7 | ifaces.h\ 8 | screen.h\ 9 | fhandle.c\ 10 | fhandle.h\ 11 | misc.c\ 12 | misc.h\ 13 | oui.h\ 14 | data_al.h\ 15 | data_reply.c \ 16 | data_request.c \ 17 | data_unique.c 18 | 19 | netdiscover_LDADD = \ 20 | -lpthread -lpcap 21 | 22 | netdiscover_CFLAGS = \ 23 | -fcommon 24 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_INIT([netdiscover], [0.21], [https://github.com/netdiscover-scanner/netdiscover/issues]) 2 | AC_CONFIG_AUX_DIR([build-aux]) 3 | AM_INIT_AUTOMAKE([-Wall -Werror]) 4 | AC_PROG_CC 5 | 6 | dnl Checks for header files. 7 | dnl check for pcap.h 8 | AC_CHECK_HEADER(pcap.h,, 9 | AC_MSG_ERROR(Cannot find pcap.h - You need libpcap installed.)) 10 | 11 | AC_CONFIG_HEADERS([config.h]) 12 | AC_CONFIG_FILES([Makefile src/Makefile]) 13 | AC_OUTPUT 14 | 15 | printf "\nRun ./update-oui-database.sh if you want a updated MAC vendors database.\n\n" 16 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # against of error: Makefile.am:3: `doc_DATA' is used but `docdir' is undefined 2 | docdir = @docdir@ 3 | 4 | SUBDIRS = src 5 | 6 | man_MANS= doc/netdiscover.8 7 | 8 | EXTRA_DIST = \ 9 | autogen.sh \ 10 | doc/create-man.sh \ 11 | doc/netdiscover.8 \ 12 | doc/netdiscover.txt \ 13 | README.md \ 14 | README.rpm \ 15 | rpm/mandriva.spec \ 16 | rpm/redhat.spec \ 17 | update-oui-database.sh 18 | 19 | distclean-local: 20 | -rm -rf autom4te.cache/ \ 21 | build-aux/ 22 | 23 | rm -f \ 24 | aclocal.m4 \ 25 | config.h.in \ 26 | configure \ 27 | doc/Makefile.in \ 28 | INSTALL \ 29 | Makefile.in \ 30 | src/Makefile.in 31 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | ******************************************************************************* 2 | AUTHORS 3 | ******************************************************************************* 4 | 5 | If you have any suggestion or bugs, file a bug here[1]. 6 | Also if you want to contribute, feel free to send any patches or pull requests. 7 | 8 | [1] https://github.com/netdiscover-scanner/netdiscover/issues 9 | 10 | 11 | Netdiscover 12 | =========== 13 | 14 | Netdiscover has been written by Jaime Penalba Estebanez 15 | The project page can be found here[2]. 16 | 17 | [2] https://github.com/netdiscover-scanner/netdiscover 18 | 19 | For historical reasons, the old homepages for this project are listed below: 20 | 21 | - http://www.nixgeneration.com/~jaime/netdiscover/ 22 | - https://sourceforge.net/projects/netdiscover/ 23 | 24 | -------------------------------------------------------------------------------- /doc/create-man.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2015-2020 Joao Eriberto Mota Filho 4 | # Create a manpage using txt2man command. Version 2.0, 2020-06-19. 5 | # This file is part of txt2man package for Debian. 6 | # This script can be used under BSD-3-Clause license. 7 | 8 | #-------------------------------------------------------- 9 | # Don't change the following lines 10 | TEST=$(txt2man -h 2> /dev/null) 11 | [ "$TEST" ] || { echo -e "\nYou need to install txt2man, from https://github.com/mvertes/txt2man.\n"; exit 1; } 12 | 13 | function create-man { 14 | txt2man -d "$T2M_DATE" -t $T2M_NAME -r $T2M_NAME-$T2M_VERSION -s $T2M_LEVEL -v "$T2M_DESC" $T2M_NAME.txt > $T2M_NAME.$T2M_LEVEL 15 | } 16 | #-------------------------------------------------------- 17 | 18 | T2M_DATE="14 Aug 2025" 19 | T2M_NAME=netdiscover 20 | T2M_VERSION=0.21 21 | T2M_LEVEL=8 22 | T2M_DESC="active/passive ARP reconnaissance tool" 23 | create-man 24 | -------------------------------------------------------------------------------- /.github/workflows/check-update-oui.yml: -------------------------------------------------------------------------------- 1 | name: check-update-oui.yml 2 | 3 | on: 4 | push: 5 | paths: 6 | - "configure.ac" 7 | - "update-oui-database.sh" 8 | pull_request: 9 | paths: 10 | - "configure.ac" 11 | - "update-oui-database.sh" 12 | 13 | jobs: 14 | build: 15 | 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: install_dependencies 21 | run: sudo apt install axel dos2unix 22 | - name: test_oui_secure 23 | run: | 24 | [ -e oui.txt-20* ] && rm -f oui.txt-20* src/oui.h 25 | ./update-oui-database.sh 26 | COUNT=$(cat src/oui.h | wc -l) 27 | if [ "$COUNT" -lt 30000 ]; then { echo "Invalid src/oui.h"; exit 1; }; fi 28 | - name: test_oui_insecure 29 | run: | 30 | [ -e oui.txt-20* ] && rm -f oui.txt-20* src/oui.h 31 | ./update-oui-database.sh --insecure 32 | COUNT=$(cat src/oui.h | wc -l) 33 | if [ "$COUNT" -lt 30000 ]; then { echo "Invalid src/oui.h"; exit 1; }; fi 34 | -------------------------------------------------------------------------------- /src/fhandle.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * fhandle.h 3 | * 4 | * Thu Dec 29 07:05:08 2005 5 | * Copyright 2005-2006 Jaime Peñalba Estebanez 6 | ****************************************************************************/ 7 | 8 | /* 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | */ 23 | 24 | #ifndef _FHANDLE_H 25 | #define _FHANDLE_H 26 | 27 | #ifdef __cplusplus 28 | extern "C" 29 | { 30 | #endif 31 | 32 | 33 | // File handling functions 34 | char **fread_list(char *); 35 | 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | 41 | #endif /* _FHANDLE_H */ 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Netdiscover 2 | by Jaime Penalba 3 | 4 | Welcome to official Netdiscover repository (since Feb. 05, 2019). 5 | 6 | Netdiscover is a network address discovering tool, developed mainly for those 7 | wireless networks without dhcp server, it also works on hub/switched networks. 8 | Its based on arp packets, it will send arp requests and sniff for replies. 9 | 10 | Its my first public C tool, so don't be too hard with me, if some parts on the 11 | code looks like obfuscated or are unreadable, and feel free to send suggestions 12 | to https://github.com/netdiscover-scanner/netdiscover/issues or patches (PR) to 13 | https://github.com/netdiscover-scanner/netdiscover/pulls. 14 | 15 | Also notify me for any bug or compilation error, it must compile with gcc 2.95 16 | or newer. 17 | 18 | An excessive CPU consumption happens on OpenBSD, due to threads design and the 19 | use of pcap_open_live() with pcap_loop(), any suggestions for fix are welcome. 20 | 21 | 22 | ## Requirements 23 | 24 | - libpcap 25 | - libnet > 1.1.2 26 | 27 | 28 | ## Build 29 | 30 | ``` 31 | $ ./update-oui-database.sh (optional, to update the MAC addresses list) 32 | $ ./autogen.sh 33 | $ ./configure 34 | $ make 35 | # make install 36 | ``` 37 | 38 | To return to original source code, you can use '$ make distclean' command. 39 | 40 | 41 | ## Bugs & Contact 42 | 43 | Feel free to notify me about any problem, bug, suggestions or fixes at: 44 | https://github.com/netdiscover-scanner/netdiscover/issues or 45 | https://github.com/netdiscover-scanner/netdiscover/pulls 46 | -------------------------------------------------------------------------------- /src/misc.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * misc.h 3 | * 4 | * Thu Jul 21 03:19:30 2005 5 | * Copyright 2005-2009 Jaime Penalba Estebanez 6 | * Copyright 2009 Janusz Uzycki 7 | ****************************************************************************/ 8 | 9 | /* 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | 25 | 26 | #ifndef _MISC_H 27 | #define _MISC_H 28 | 29 | #include "data_al.h" 30 | 31 | #ifdef __cplusplus 32 | extern "C" 33 | { 34 | #endif 35 | 36 | /* Functions */ 37 | char *search_vendor(unsigned char[6]); 38 | void string_cutter(char *, int); 39 | int load_known_mac_table(char *); 40 | void search_mac(struct data_registry *); 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | 46 | #endif /* _MISC_H */ 47 | -------------------------------------------------------------------------------- /rpm/mandriva.spec: -------------------------------------------------------------------------------- 1 | %define name netdiscover 2 | %define version 0.3beta7 3 | %define release 20060404cvs 4 | 5 | Summary: A network address discovering/monitoring tool 6 | Name: %{name} 7 | Version: %{version} 8 | Release: %{release} 9 | Source0: %{name}-%{version}.tar.bz2 10 | License: GPL 11 | Group: Networking/Other 12 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot 13 | BuildArch: i586 14 | BuildRequires: libpcap0-devel libnet2-devel 15 | Requires: libpcap0 libnet2 16 | URL: http://nixgeneration.com/~jaime/netdiscover/ 17 | 18 | %description 19 | Netdiscover is an active/passive address reconnaissance tool, mainly developed 20 | for those wireless networks without dhcp server, when you are wardriving. It 21 | can be also used on hub/switched networks. 22 | 23 | Built on top of libnet and libpcap, it can passively detect online hosts, or 24 | search for them, by actively sending arp requests, it can also be used to 25 | inspect your network arp traffic, and find network addresses using auto scan 26 | mode, which will scan for common local networks. 27 | 28 | %prep 29 | %setup 30 | 31 | %build 32 | if [ ! -f configure ] 33 | then 34 | ./autogen.sh 35 | fi 36 | %configure2_5x 37 | %make 38 | 39 | %install 40 | %makeinstall 41 | rm -rf $RPM_BUILD_ROOT/usr/doc 42 | 43 | %clean 44 | rm -rf $RPM_BUILD_ROOT 45 | 46 | %files 47 | %defattr(-,root,root) 48 | %doc ChangeLog README AUTHORS INSTALL NEWS TODO 49 | %dir %{_sbindir}/netdiscover 50 | %dir %{_mandir} 51 | %{_mandir}/* 52 | 53 | 54 | %changelog 55 | * Thu Apr 26 2006 Francis Giraldeau - 0.3beta7-20060404cvs 56 | - Correction of installation directories 57 | 58 | * Mon Mar 27 2006 Francis Giraldeau - 0.3beta6-20060223cvs 59 | - Initial writing 60 | -------------------------------------------------------------------------------- /.github/workflows/full-check.yml: -------------------------------------------------------------------------------- 1 | name: full-check 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: install_dependencies 13 | run: sudo apt install libnet1-dev libpcap-dev 14 | - name: first_build 15 | run: | 16 | ./autogen.sh 17 | ./configure 18 | make 19 | sudo make install 20 | sudo make uninstall 21 | make distclean 22 | - name: second_build 23 | run: | 24 | ./autogen.sh 25 | ./configure 26 | make 27 | sudo make install 28 | - name: run_program_version 29 | run: | 30 | sudo netdiscover -h 2>&1 | egrep -i Netdiscover -A 30 31 | - name: run_program_scan 32 | run: | 33 | sudo netdiscover -P -r 127.0.0.0/16 34 | - name: check_version 35 | run: | 36 | VERC=$(cat configure.ac | grep AC_INIT | cut -d"," -f2 | egrep -o '[0-9.]+') 37 | VERP=$(netdiscover -h | grep Net | cut -d" " -f2) 38 | if [ "$VERC" = "$VERP" ] 39 | then 40 | echo "Version $VERP confirmed" 41 | exit 0 42 | else 43 | echo "Wrong version. configure.ac says $VERC, but netdiscover says $VERP" 44 | exit 1 45 | fi 46 | - name: test_make_dist 47 | run: | 48 | make distclean 49 | ./autogen.sh 50 | ./configure 51 | make dist 52 | mkdir test_dist 53 | mv netdiscover-*.tar.gz test_dist 54 | cd test_dist 55 | tar -xvf netdiscover-*.tar.gz 56 | rm -f netdiscover-*.tar.gz 57 | cd netdiscover-* 58 | ./autogen.sh 59 | ./configure 60 | make 61 | sudo make install 62 | sudo make uninstall 63 | make distclean 64 | -------------------------------------------------------------------------------- /src/screen.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * screen.h 3 | * 4 | * Tue Jul 12 03:22:19 2005 5 | * Copyright 2005-2009 Jaime Penalba Estebanez 6 | * Copyright 2006 Guillaume Pratte 7 | * Copyright 2009 Janusz Uzycki 8 | * 9 | ****************************************************************************/ 10 | 11 | /* 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 3 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License 23 | * along with this program; if not, write to the Free Software 24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 | */ 26 | 27 | 28 | #ifndef _SCREEN_H 29 | #define _SCREEN_H 30 | 31 | #ifdef __cplusplus 32 | extern "C" 33 | { 34 | #endif 35 | 36 | #include 37 | 38 | /* ARP types definitions */ 39 | #define NARP_REQUEST 1 40 | #define NARP_REPLY 2 41 | 42 | /* Screen modes definitions */ 43 | #define SMODE_REPLY 0 44 | #define SMODE_REQUEST 1 45 | #define SMODE_HELP 2 46 | #define SMODE_HOST 3 47 | 48 | /* Known Hosts highlight color */ 49 | //#define KNOWN_COLOR "\33[42;30m%s\33[0m\n" 50 | #define KNOWN_COLOR "\33[1m%s\33[0m\n" 51 | 52 | /* Ohh no, more globals */ 53 | struct winsize win_sz; 54 | char *current_network; 55 | int parsable_output, continue_listening; 56 | 57 | 58 | /* Screen functions */ 59 | void print_screen(); 60 | void fill_screen(); 61 | void read_key(); 62 | void init_screen(); 63 | void sighandler(int); 64 | 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | #endif /* _SCREEN_H */ 71 | -------------------------------------------------------------------------------- /src/fhandle.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * fhandle.c 3 | * 4 | * Thu Dec 29 07:04:39 2005 5 | * Copyright 2005 Jaime Penalba Estebanez 6 | * Copyright 2008 Gustavo Chain 7 | ****************************************************************************/ 8 | 9 | /* 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include "fhandle.h" 29 | 30 | /* Read range list from file */ 31 | char **fread_list(char *file) 32 | { 33 | FILE *rl; 34 | char **rlist; 35 | char line[100]; 36 | int lcount = 0; 37 | int trim; 38 | 39 | if ((rl = fopen(file, "r")) == NULL) 40 | return NULL; 41 | 42 | /* Count lines and rewind, kinda lamme... */ 43 | while (fgets(line, sizeof(line), rl) != NULL) 44 | lcount++; 45 | rewind(rl); 46 | 47 | rlist = (char **) malloc (sizeof(char *) * (lcount + 1)); 48 | lcount = 0; 49 | 50 | /* Read lines again and fill double-linked list */ 51 | while (fgets(line, sizeof(line), rl) != NULL) { 52 | 53 | trim = strlen(line) - 1; 54 | while ( trim >= 0 && ( line[trim] == '\r' || line[trim] == '\n' )) { 55 | line[trim] = '\0'; 56 | trim--; 57 | } 58 | 59 | rlist[lcount] = (char *) malloc (sizeof(char) * (strlen(line) + 1)); 60 | snprintf(rlist[lcount], strlen(line) + 1, "%s", line); 61 | lcount++; 62 | } 63 | 64 | rlist[lcount] = NULL; 65 | fclose(rl); 66 | return rlist; 67 | } 68 | -------------------------------------------------------------------------------- /src/ifaces.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * ifaces.h 3 | * 4 | * Mon Jun 27 04:56:18 2005 5 | * Copyright 2005-2009 Jaime Penalba Estebanez 6 | * Copyright 2006 Guillaume Pratte 7 | * Copyright 2007-2008 Gustavo Chain 8 | * Copyright 2021 Enrico Schmitz 9 | * 10 | ****************************************************************************/ 11 | 12 | /* 13 | * This program is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 3 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 26 | */ 27 | 28 | 29 | #ifndef _IFACES_H 30 | #define _IFACES_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" 34 | { 35 | #endif 36 | 37 | #include 38 | #include 39 | #include "data_al.h" 40 | 41 | /* If system is Solaris */ 42 | #if defined(sun) && (defined(__svr4__) || defined(__SVR4)) 43 | #define PCAP_TOUT 20 44 | typedef uint64_t u_int64_t; 45 | typedef uint32_t u_int32_t; 46 | typedef uint16_t u_int16_t; 47 | typedef uint8_t u_int8_t; 48 | #else 49 | #define PCAP_TOUT 512 50 | #endif 51 | 52 | 53 | /* Shitty globals */ 54 | char errbuf[PCAP_ERRBUF_SIZE]; 55 | 56 | /* Threads data structure */ 57 | struct t_data { 58 | char *interface; 59 | char *source_ip; 60 | char *pcap_filter; 61 | struct ether_addr **ignore_macs; 62 | }; 63 | 64 | /* Sniffer/Packet processing Functions */ 65 | void *start_sniffer(void *); 66 | void process_arp_header(struct data_registry *, const u_char *); 67 | void process_packet(u_char *, struct pcap_pkthdr *, const u_char *); 68 | 69 | /* ARP Generation & Injection */ 70 | void inject_init(char *); 71 | void forge_arp(char *, char *, char *); 72 | void inject_destroy(); 73 | 74 | #ifdef __cplusplus 75 | } 76 | #endif 77 | 78 | #endif /* _IFACES_H */ 79 | -------------------------------------------------------------------------------- /src/data_al.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * data_al.h 3 | * 4 | * Sat Apr 5 09:36:32 CEST 2008 5 | * Copyright 2008-2009 Jaime Penalba Estebanez 6 | * Copyright 2009 Janusz Uzycki 7 | * Copyright 2022 Brendan Coles 8 | * 9 | * Data abstraction layer 10 | ****************************************************************************/ 11 | 12 | /* 13 | * This program is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 3 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 26 | */ 27 | 28 | #ifndef _DATA_AL_H 29 | #define _DATA_AL_H 30 | 31 | #include 32 | #include "screen.h" 33 | 34 | #ifdef __cplusplus 35 | extern "C" 36 | { 37 | #endif 38 | 39 | pthread_mutex_t *data_access; 40 | 41 | 42 | /* Holds each data type total counters */ 43 | struct data_counter { 44 | unsigned int pakets; // Total pakets 45 | unsigned int hosts; // Total hosts 46 | unsigned int length; // Total length 47 | }; 48 | 49 | 50 | /* Holds ethernet headers packet data */ 51 | struct p_header { 52 | unsigned char smac[6]; // Source MAC 53 | unsigned char dmac[6]; // Destination MAC 54 | unsigned int length; // Paket length 55 | }; 56 | 57 | 58 | /* Holds registry data */ 59 | struct data_registry { 60 | struct p_header *header; // Ethernet data header 61 | char *sip; // Source IP 62 | char *dip; // Destination IP 63 | char *vendor; // MAC vendor 64 | short type; // Paket type 65 | unsigned int count; // Total pakets count 66 | unsigned int tlength; // Total pakets length 67 | char focused; // Focused (colour / bold) 68 | struct data_registry *next; // Next registry 69 | }; 70 | 71 | 72 | /* Holds data abstraction layer for data types */ 73 | struct data_al { 74 | void (*init)(void); // Init data 75 | void (*beginning_registry)(void); // Go to 1st reg 76 | void (*next_registry)(void); // Go to next reg 77 | struct data_registry *(*current_registry)(void); // Get current reg 78 | void (*print_line)(void); // Print reg line 79 | void (*print_header)(int width); // Print scr header 80 | void (*add_registry)(struct data_registry *registry); // Add new registry 81 | unsigned int (*hosts_count)(void); // Get hosts count 82 | void (*print_simple_header)(); // Print smp header 83 | }; 84 | 85 | 86 | extern const struct data_al _data_reply; 87 | extern const struct data_al _data_request; 88 | extern const struct data_al _data_unique; 89 | 90 | #ifdef __cplusplus 91 | } 92 | #endif 93 | 94 | #endif /* _DATA_AL_H */ 95 | -------------------------------------------------------------------------------- /src/data_reply.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * data_reply.c 3 | * 4 | * Sat Apr 5 09:36:32 CEST 2008 5 | * Copyright 2008-2016 Jaime Penalba Estebanez 6 | * Copyright 2009 Janusz Uzycki 7 | * Copyright 2022 Brendan Coles 8 | * 9 | * Data abstraction layer part for arp replies 10 | ****************************************************************************/ 11 | 12 | /* 13 | * This program is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 3 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "misc.h" 34 | #include "data_al.h" 35 | 36 | 37 | /* Pointers to hold list data */ 38 | struct data_registry *first_reply, *last_reply; 39 | 40 | /* Pointer to handle list */ 41 | struct data_registry *current_reply; 42 | 43 | /* Registry data counter */ 44 | struct data_counter reply_count; 45 | 46 | /* Screen printing buffers */ 47 | char line[300], tline[300]; 48 | extern char blank[]; 49 | 50 | 51 | /* Initialize required data */ 52 | void reply_init() 53 | { 54 | first_reply = NULL; 55 | last_reply = NULL; 56 | } 57 | 58 | /* Used to beging the iteration between registries */ 59 | void reply_beginning_registry() { current_reply = first_reply; } 60 | 61 | /* Go to next registry */ 62 | void reply_next_registry(void) { current_reply = current_reply->next; } 63 | 64 | /* Return current registry mainly to check if its null */ 65 | struct data_registry *reply_current_reply(void) { return current_reply; } 66 | 67 | /* Return hosts count */ 68 | unsigned int reply_hosts_count(void) { return reply_count.hosts; } 69 | 70 | 71 | 72 | /* Print current registry line (for interactive mode) */ 73 | void reply_print_line() 74 | { 75 | int j; 76 | 77 | sprintf(line, " "); 78 | sprintf(tline, " "); 79 | 80 | /* Set IP */ 81 | sprintf(tline, "%s ", current_reply->sip); 82 | strcat(line, tline); 83 | 84 | /* Fill with spaces */ 85 | for (j=strlen(line); j<17; j++) 86 | strcat(line, blank); 87 | 88 | /* IP & MAC */ 89 | sprintf(tline, "%02x:%02x:%02x:%02x:%02x:%02x ", 90 | current_reply->header->smac[0], current_reply->header->smac[1], 91 | current_reply->header->smac[2], current_reply->header->smac[3], 92 | current_reply->header->smac[4], current_reply->header->smac[5]); 93 | strcat(line, tline); 94 | 95 | /* Count, Length & Vendor */ 96 | sprintf(tline, "%5d %7d %s", current_reply->count, 97 | current_reply->header->length, current_reply->vendor ); 98 | strcat(line, tline); 99 | 100 | 101 | /* Fill again with spaces and cut the string to fit width */ 102 | for (j=strlen(line); (jfocused == 0) 108 | printf("%s\n", line); 109 | else 110 | printf(KNOWN_COLOR, line); 111 | } 112 | 113 | 114 | /* Add new data to the registry list */ 115 | void reply_add_registry(struct data_registry *registry) 116 | { 117 | int i = 0; 118 | 119 | _data_unique.add_registry(registry); 120 | 121 | if ( first_reply == NULL ) 122 | { 123 | reply_count.hosts++; 124 | search_mac(registry); 125 | 126 | first_reply = registry; 127 | last_reply = registry; 128 | 129 | } else { 130 | 131 | struct data_registry *tmp_registry; 132 | tmp_registry = first_reply; 133 | 134 | /* Check for dupe packets */ 135 | while ( tmp_registry != NULL && i != 1 ) { 136 | 137 | if ( ( strcmp(tmp_registry->sip, registry->sip) == 0 ) && 138 | ( memcmp(tmp_registry->header->smac, registry->header->smac, 6) == 0 ) ) { 139 | 140 | tmp_registry->count++; 141 | tmp_registry->header->length += registry->header->length; 142 | 143 | i = 1; 144 | } 145 | 146 | tmp_registry = tmp_registry->next; 147 | } 148 | 149 | /* Add it if isnt dupe */ 150 | if ( i != 1 ) { 151 | 152 | reply_count.hosts++; 153 | search_mac(registry); 154 | 155 | last_reply->next = registry; 156 | last_reply = registry; 157 | } 158 | } 159 | 160 | reply_count.pakets++; 161 | reply_count.length += registry->header->length; 162 | 163 | } 164 | 165 | 166 | void reply_print_header_sumary(int width) 167 | { 168 | int j; 169 | 170 | sprintf(line, " %i Captured ARP Reply packets, from %i hosts. Total size: %i", 171 | reply_count.pakets, reply_count.hosts, reply_count.length); 172 | printf("%s", line); 173 | 174 | /* Fill with spaces */ 175 | for (j=strlen(line); j. 140 | 141 | This manual page was originally written by Nicolas Weyland, for the Debian 142 | project. This man page has been merged into netdiscover project and 143 | modified from the original by Jaime Penalba and Joao Eriberto Mota Filho. 144 | -------------------------------------------------------------------------------- /src/misc.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * misc.c 3 | * 4 | * Thu Jul 21 03:20:02 2005 5 | * Copyright 2005-2009 Jaime Penalba Estebanez 6 | * Copyright 2009 Janusz Uzycki 7 | ****************************************************************************/ 8 | 9 | /* 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License 21 | * along with this program; if not, write to the Free Software 22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "ifaces.h" 33 | #include "fhandle.h" 34 | #include "misc.h" 35 | #include "oui.h" 36 | 37 | 38 | /* optional table/list of MAC addresses of known hosts */ 39 | char **known_mac_table; 40 | 41 | 42 | /* 43 | struct ether_addr **split_mac_list(char *string) 44 | { 45 | int x; 46 | int count = 0; 47 | char *aux; 48 | struct ether_addr **macs; 49 | const char delimiters[] = ","; 50 | 51 | // Count number of items in the string 52 | for (x=0; x 0) { 128 | known_mac_table[i][0] = '?'; 129 | /* WARNING */ 130 | i++; continue; 131 | } else { 132 | /* finish parsing, skip all others lines - ERROR */ 133 | break; 134 | } 135 | } 136 | 137 | /* Convert mac to upper */ 138 | for (j=0; j<12; j++) 139 | known_mac_table[i][j] = toupper(known_mac_table[i][j]); 140 | 141 | 142 | /* convert all spaces and tabulator after MAC address into '\0' */ 143 | for (j = 12; j < len; j++) 144 | { 145 | if ((known_mac_table[i][j] == ' ') || (known_mac_table[i][j] == '\t')) 146 | known_mac_table[i][j] = '\0'; 147 | else 148 | break; // first char of hostname 149 | } 150 | 151 | if (j >= len) { 152 | printf("WARNING: no host name given in the file! (%s)\n", 153 | known_mac_table[i]); 154 | sleep(5); 155 | /* protection */ 156 | known_mac_table[i][13] = '!'; 157 | } 158 | 159 | /* next line */ 160 | i++; 161 | } // while 162 | 163 | printf("Parsing known MACs table completed.\n"); 164 | return 0; 165 | } 166 | 167 | char *get_known_mac_hostname(char *mac_hostname) 168 | { 169 | if (strlen(mac_hostname) != 12) { 170 | /* error in MACs table content */ 171 | return NULL; 172 | } 173 | 174 | /* skip MAC and all '\0' */ 175 | mac_hostname += 12; 176 | while (*mac_hostname == '\0') mac_hostname++; 177 | 178 | return mac_hostname; 179 | } 180 | 181 | 182 | /* find out known host name */ 183 | char *search_known_mac(unsigned char mac[6]) 184 | { 185 | char tmac[13]; 186 | int i; 187 | 188 | /* protection */ 189 | if (known_mac_table == NULL) 190 | return NULL; 191 | 192 | sprintf(tmac, "%02x%02x%02x%02x%02x%02x", 193 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 194 | 195 | /* Convert mac to upper */ 196 | for (i=0; i<12; i++) 197 | tmac[i] = toupper(tmac[i]); 198 | 199 | i = 0; 200 | 201 | while (known_mac_table[i] != NULL) { 202 | 203 | if (strcmp(known_mac_table[i]/*separated MAC*/, tmac) == 0) 204 | return get_known_mac_hostname(known_mac_table[i]); 205 | i++; 206 | } 207 | 208 | return NULL; 209 | } 210 | 211 | 212 | /* First try find out known host name, otherwise use standard vendor */ 213 | void search_mac(struct data_registry *registry) 214 | { 215 | registry->vendor = search_known_mac(registry->header->smac); 216 | 217 | if (registry->vendor == NULL) { 218 | registry->vendor = search_vendor(registry->header->smac); 219 | registry->focused = 0; /* unidentified host, vendor used */ 220 | } else { 221 | registry->focused = 1; /* identified host, hostname used */ 222 | } 223 | } 224 | 225 | -------------------------------------------------------------------------------- /src/data_request.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * data_request.c 3 | * 4 | * Sat Apr 5 09:36:32 CEST 2008 5 | * Copyright 2008-2016 Jaime Penalba Estebanez 6 | * Copyright 2009 Janusz Uzycki 7 | * Copyright 2022 Brendan Coles 8 | * 9 | * Data abstraction layer part for arp request 10 | ****************************************************************************/ 11 | 12 | /* 13 | * This program is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 3 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "misc.h" 34 | #include "data_al.h" 35 | 36 | 37 | /* Pointers to hold list data */ 38 | struct data_registry *request_first, *request_last; 39 | 40 | /* Pointer to handle list */ 41 | struct data_registry *request_current; 42 | 43 | /* Registry data counter */ 44 | struct data_counter request_count; 45 | 46 | /* Screen printing buffers */ 47 | char line[300], tline[300]; 48 | extern char blank[]; 49 | 50 | 51 | /* Initialize required data */ 52 | void request_init() 53 | { 54 | request_first = NULL; 55 | request_last = NULL; 56 | } 57 | 58 | /* Used to beging the iteration between registries */ 59 | void request_beginning_registry() { request_current = request_first; } 60 | 61 | /* Go to next registry */ 62 | void request_next_registry(void) { request_current = request_current->next; } 63 | 64 | /* Return current registry mainly to check if its null */ 65 | struct data_registry *request_current_registry(void) {return request_current;} 66 | 67 | /* Return hosts count */ 68 | unsigned int request_hosts_count(void) { return request_count.hosts; } 69 | 70 | 71 | /* Print current registry line (for interactive mode) */ 72 | void request_print_line() 73 | { 74 | int j; 75 | 76 | sprintf(line, " "); 77 | sprintf(tline, " "); 78 | 79 | /* Get source IP */ 80 | sprintf(tline, "%s ", request_current->sip); 81 | strcat(line, tline); 82 | 83 | /* Fill with spaces */ 84 | for (j=strlen(line); j<17; j++) 85 | strcat(line, blank); 86 | 87 | /* Get source MAC */ 88 | sprintf(tline, "%02x:%02x:%02x:%02x:%02x:%02x ", 89 | request_current->header->smac[0], request_current->header->smac[1], 90 | request_current->header->smac[2], request_current->header->smac[3], 91 | request_current->header->smac[4], request_current->header->smac[5]); 92 | strcat(line, tline); 93 | 94 | /* Get destination IP */ 95 | sprintf(tline, "%s", request_current->dip); 96 | strcat(line, tline); 97 | 98 | /* Fill with spaces */ 99 | for (j=strlen(line); j<54; j++) 100 | strcat(line, blank); 101 | 102 | /* Count, Length & Vendor */ 103 | sprintf(tline, "%5d", request_current->count); 104 | strcat(line, tline); 105 | 106 | /* Fill again with spaces and cut the string to fit width */ 107 | for (j=strlen(line); (jfocused == 0) 113 | printf("%s\n", line); 114 | else 115 | printf(KNOWN_COLOR, line); 116 | } 117 | 118 | 119 | /* Add new data to the registry list */ 120 | void request_add_registry(struct data_registry *registry) 121 | { 122 | int i = 0; 123 | 124 | _data_unique.add_registry(registry); 125 | 126 | if ( request_first == NULL ) 127 | { 128 | request_count.hosts++; 129 | search_mac(registry); 130 | 131 | request_first = registry; 132 | request_last = registry; 133 | 134 | } else { 135 | 136 | struct data_registry *tmp_request; 137 | tmp_request = request_first; 138 | 139 | /* Check for dupe packets */ 140 | while ( tmp_request != NULL && i != 1 ) { 141 | 142 | if ( ( strcmp(tmp_request->sip, registry->sip) == 0 ) && 143 | ( strcmp(tmp_request->dip, registry->dip) == 0 ) && 144 | ( memcmp(tmp_request->header->smac, registry->header->smac, 6) == 0 ) ) { 145 | 146 | tmp_request->count++; 147 | tmp_request->header->length += registry->header->length; 148 | 149 | i = 1; 150 | } 151 | 152 | tmp_request = tmp_request->next; 153 | } 154 | 155 | /* Add it if isnt dupe */ 156 | if ( i != 1 ) { 157 | 158 | request_count.hosts++; 159 | search_mac(registry); 160 | 161 | request_last->next = registry; 162 | request_last = registry; 163 | } 164 | } 165 | 166 | request_count.pakets++; 167 | request_count.length += registry->header->length; 168 | 169 | } 170 | 171 | 172 | void request_print_header_sumary(int width) 173 | { 174 | int j; 175 | 176 | sprintf(line, " %i Captured ARP Request packets, from %i hosts. Total size: %i", 177 | request_count.pakets, request_count.hosts, request_count.length); 178 | printf("%s", line); 179 | 180 | /* Fill with spaces */ 181 | for (j=strlen(line); j. 236 | .PP 237 | This manual page was originally written by Nicolas Weyland, for the Debian 238 | project. This man page has been merged into \fBnetdiscover\fP project and 239 | modified from the original by Jaime Penalba and Joao Eriberto Mota Filho. 240 | -------------------------------------------------------------------------------- /src/data_unique.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * data_unique.c 3 | * 4 | * Sat Apr 5 09:36:32 CEST 2008 5 | * Copyright 2008-2016 Jaime Penalba Estebanez 6 | * Copyright 2009 Janusz Uzycki 7 | * Copyright 2022 Brendan Coles 8 | * 9 | * Data abstraction layer part for unique hosts 10 | ****************************************************************************/ 11 | 12 | /* 13 | * This program is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 3 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 26 | */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "misc.h" 35 | #include "data_al.h" 36 | 37 | 38 | /* Pointers to hold list data */ 39 | struct data_registry *first_unique, *last_unique; 40 | 41 | /* Pointer to handle list */ 42 | struct data_registry *current_unique; 43 | 44 | /* Registry data counter */ 45 | struct data_counter unique_count; 46 | 47 | /* Screen printing buffers */ 48 | char line[300], tline[300]; 49 | extern char blank[]; 50 | 51 | 52 | /* Initialize required data */ 53 | void unique_init() 54 | { 55 | first_unique = NULL; 56 | last_unique = NULL; 57 | } 58 | 59 | /* Used to beging the iteration between registries */ 60 | void unique_beginning_registry() { current_unique = first_unique; } 61 | 62 | /* Go to next registry */ 63 | void unique_next_registry(void) { current_unique = current_unique->next; } 64 | 65 | /* Return current registry mainly to check if its null */ 66 | struct data_registry *unique_current_unique(void) { return current_unique; } 67 | 68 | /* Return hosts count */ 69 | unsigned int unique_hosts_count(void) { return unique_count.hosts; } 70 | 71 | 72 | /* Print current registry line (for interactive mode) */ 73 | void unique_print_line() 74 | { 75 | int j; 76 | 77 | sprintf(line, " "); 78 | sprintf(tline, " "); 79 | 80 | /* Set IP */ 81 | sprintf(tline, "%s ", current_unique->sip); 82 | strcat(line, tline); 83 | 84 | /* Fill with spaces */ 85 | for (j=strlen(line); j<17; j++) 86 | strcat(line, blank); 87 | 88 | /* IP & MAC */ 89 | sprintf(tline, "%02x:%02x:%02x:%02x:%02x:%02x ", 90 | current_unique->header->smac[0], current_unique->header->smac[1], 91 | current_unique->header->smac[2], current_unique->header->smac[3], 92 | current_unique->header->smac[4], current_unique->header->smac[5]); 93 | strcat(line, tline); 94 | 95 | /* Count, Length & Vendor */ 96 | sprintf(tline, "%5d %7d %s", current_unique->count, 97 | current_unique->tlength, current_unique->vendor ); 98 | strcat(line, tline); 99 | 100 | /* Fill again with spaces and cut the string to fit width */ 101 | for (j=strlen(line); (jfocused == 0) 108 | printf("%s\n", line); 109 | else 110 | printf(KNOWN_COLOR, line); 111 | } 112 | 113 | 114 | /* Add new data to the registry list */ 115 | void unique_add_registry(struct data_registry *registry) 116 | { 117 | int i = 0; 118 | struct data_registry *new_data; 119 | 120 | 121 | if ( first_unique == NULL ) 122 | { 123 | /* Duplicate this registry, as the pointer is being used by rep/req al */ 124 | new_data = (struct data_registry *) malloc (sizeof(struct data_registry)); 125 | *new_data = *registry; 126 | 127 | unique_count.hosts++; 128 | search_mac(new_data); 129 | 130 | first_unique = new_data; 131 | last_unique = new_data; 132 | 133 | /* Set for printing if parsable_output is enabled */ 134 | if (parsable_output) 135 | current_unique = new_data; 136 | 137 | } else { 138 | 139 | struct data_registry *tmp_registry; 140 | tmp_registry = first_unique; 141 | 142 | /* Check for dupe packets */ 143 | while ( tmp_registry != NULL && i != 1 ) { 144 | 145 | if ( ( strcmp(tmp_registry->sip, registry->sip) == 0 ) && 146 | ( memcmp(tmp_registry->header->smac, registry->header->smac, 6) == 0 ) ) { 147 | 148 | tmp_registry->count++; 149 | tmp_registry->tlength += registry->header->length; 150 | 151 | /* Not required to print if parsable_output is enabled */ 152 | if (parsable_output) 153 | current_unique = NULL; 154 | 155 | i = 1; 156 | } 157 | 158 | tmp_registry = tmp_registry->next; 159 | } 160 | 161 | /* Add it if isnt dupe */ 162 | if ( i != 1 ) { 163 | 164 | /* Duplicate this registry, as the pointer is being used by rep/req al */ 165 | new_data = (struct data_registry *) malloc (sizeof(struct data_registry)); 166 | *new_data = *registry; 167 | 168 | unique_count.hosts++; 169 | search_mac(new_data); 170 | 171 | last_unique->next = new_data; 172 | last_unique = new_data; 173 | 174 | /* Set for printing if parsable_output is enabled */ 175 | if (parsable_output) 176 | current_unique = new_data; 177 | } 178 | } 179 | 180 | unique_count.pakets++; 181 | unique_count.length += registry->header->length; 182 | 183 | 184 | if (parsable_output && current_unique != NULL) { 185 | unique_print_line(); 186 | fflush(stdout); 187 | } 188 | } 189 | 190 | void unique_print_header_sumary(int width) 191 | { 192 | int j; 193 | 194 | sprintf(line, " %i Captured ARP Req/Rep packets, from %i hosts. Total size: %i", 195 | unique_count.pakets, unique_count.hosts, unique_count.length); 196 | printf("%s", line); 197 | 198 | /* Fill with spaces */ 199 | for (j=strlen(line); j 6 | * Copyright 2007-2008 Gustavo Chain 7 | * Copyright 2021 bcoles 8 | ****************************************************************************/ 9 | 10 | /* 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with this program; if not, write to the Free Software 23 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 24 | */ 25 | 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | #include "screen.h" 37 | #include "ifaces.h" 38 | #include "data_al.h" 39 | 40 | 41 | #include 42 | #include 43 | #include 44 | 45 | 46 | #define ARP_REPLY "\x00\x02" 47 | #define ARP_REQUEST "\x00\x01" 48 | 49 | #ifndef ETHER_HDRLEN 50 | #define ETHER_HDRLEN 14 51 | #endif 52 | 53 | #ifndef ETH_HLEN 54 | #define ETH_HLEN 14 55 | #endif 56 | 57 | #ifndef ETH_ALEN 58 | #define ETH_ALEN 6 59 | #endif 60 | 61 | #ifndef IP_ALEN 62 | #define IP_ALEN 4 63 | #endif 64 | 65 | #ifndef ARPOP_REQUEST 66 | #define ARPOP_REQUEST 1 67 | #define ARPOP_REPLY 2 68 | #endif 69 | 70 | 71 | 72 | 73 | /* Shitty globals */ 74 | pcap_t *inject; 75 | unsigned char smac[] = { 0xCA, 0xFE, 0xCA, 0xFE, 0xCA, 0xFE }; 76 | struct p_header *temp_header; 77 | 78 | 79 | /* Start Sniffing on given iface */ 80 | void *start_sniffer(void *args) 81 | { 82 | pcap_t *descr; 83 | struct bpf_program fp; 84 | struct t_data *datos; 85 | char *filter; 86 | 87 | datos = (struct t_data *)args; 88 | 89 | /* Open interface */ 90 | descr = pcap_open_live(datos->interface, BUFSIZ, 1, PCAP_TOUT, errbuf); 91 | if(descr == NULL) { 92 | printf("pcap_open_live(): %s\n", errbuf); 93 | sighandler(0); // QUIT 94 | } 95 | 96 | /* Set pcap filter */ 97 | filter = (datos->pcap_filter == NULL) ? "arp" : datos->pcap_filter; 98 | if(pcap_compile(descr, &fp, filter, 0, 0) == -1) { 99 | printf("pcap_compile(): %s\n", pcap_geterr(descr)); 100 | sighandler(0); // QUIT 101 | } 102 | pcap_setfilter(descr, &fp); 103 | 104 | /* Start loop for packet capture */ 105 | pcap_loop(descr, -1, (pcap_handler)process_packet, NULL); 106 | 107 | return NULL; 108 | } 109 | 110 | 111 | /* Handle packets recived from pcap_loop */ 112 | void process_packet(u_char *args, struct pcap_pkthdr* pkthdr, 113 | const u_char* packet) 114 | { 115 | struct p_header *new_header; 116 | new_header = (struct p_header *) malloc (sizeof(struct p_header)); 117 | 118 | /* Get packet ethernet header data and fill struct */ 119 | memcpy(new_header->dmac, packet, 6); /* dest mac */ 120 | memcpy(new_header->smac, packet + 6, 6); /* src mac */ 121 | new_header->length = pkthdr->len; /* Packet size */ 122 | 123 | /* Discard packets with our mac as source */ 124 | if (memcmp(new_header->smac, smac, 6) == 0) 125 | { 126 | free(new_header); 127 | return; 128 | } 129 | 130 | unsigned char type[2]; 131 | memcpy(type, packet + 20, 2); 132 | 133 | struct data_registry *new_reg; 134 | new_reg = (struct data_registry *) malloc (sizeof(struct data_registry)); 135 | new_reg->header = new_header; 136 | new_reg->tlength = new_header->length; 137 | process_arp_header(new_reg, packet); 138 | 139 | /* Check if its ARP request or reply, and add it to list */ 140 | if (memcmp(type, ARP_REPLY, 2) == 0) { 141 | new_reg->type = 2; /* Arp Type */ 142 | pthread_mutex_lock(data_access); 143 | _data_reply.add_registry(new_reg); 144 | pthread_mutex_unlock(data_access); 145 | 146 | } else if (memcmp(type, ARP_REQUEST, 2) == 0) { 147 | new_reg->type = 1; /* Arp Type */ 148 | pthread_mutex_lock(data_access); 149 | _data_request.add_registry(new_reg); 150 | pthread_mutex_unlock(data_access); 151 | 152 | } else { 153 | free(new_header); 154 | free(new_reg->sip); 155 | free(new_reg->dip); 156 | free(new_reg); 157 | } 158 | } 159 | 160 | /* Handle arp packet header */ 161 | void process_arp_header(struct data_registry *new_reg, const u_char* packet) 162 | { 163 | 164 | /* Populate basic common registry info */ 165 | new_reg->count = 1; 166 | new_reg->next = NULL; 167 | 168 | /* Allocate memory for ip addrs */ 169 | new_reg->sip = (char *) malloc (sizeof(char) * 16); 170 | new_reg->dip = (char *) malloc (sizeof(char) * 16); 171 | 172 | /* Source IP */ 173 | sprintf(new_reg->sip, "%d.%d.%d.%d", 174 | packet[28], packet[29], packet[30], packet[31]); 175 | 176 | /* Destination IP */ 177 | sprintf(new_reg->dip, "%d.%d.%d.%d", 178 | packet[38], packet[39], packet[40], packet[41]); 179 | } 180 | 181 | /* Get our mac address */ 182 | void get_mac(char *disp) 183 | { 184 | 185 | #ifdef __linux__ 186 | struct ifreq ifr; 187 | size_t if_name_len = strlen(disp); 188 | 189 | if (if_name_len < sizeof(ifr.ifr_name)) { 190 | memcpy(ifr.ifr_name, disp, if_name_len); 191 | ifr.ifr_name[if_name_len] = 0; 192 | } else { 193 | printf("interface name is too long"); 194 | exit(1); 195 | } 196 | 197 | int fd = socket(AF_UNIX,SOCK_DGRAM,0); 198 | if (fd == -1) { 199 | printf("%s", strerror(errno)); 200 | exit(1); 201 | } 202 | 203 | if (ioctl(fd,SIOCGIFHWADDR,&ifr) == -1) { 204 | int temp_errno = errno; 205 | close(fd); 206 | printf("%s", strerror(temp_errno)); 207 | exit(1); 208 | } 209 | close(fd); 210 | 211 | if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { 212 | printf("not an Ethernet interface"); 213 | exit(1); 214 | } 215 | 216 | //unsigned char* mac = (unsigned char*) ; 217 | memcpy(smac, ifr.ifr_hwaddr.sa_data, ETH_ALEN); 218 | #else 219 | //printf("Unsuported OS\n"); 220 | //exit(1); 221 | #endif 222 | } 223 | 224 | 225 | /* Init device for libpcap and get mac addr */ 226 | void inject_init(char *disp) 227 | { 228 | char loc_errbuf[PCAP_ERRBUF_SIZE]; 229 | 230 | /* Open interface for injection */ 231 | inject = pcap_open_live(disp, BUFSIZ, 1, PCAP_TOUT, loc_errbuf); 232 | if(inject == NULL) { 233 | printf("pcap_open_live(): %s\n", loc_errbuf); 234 | exit(1); 235 | } 236 | 237 | get_mac(disp); 238 | } 239 | 240 | 241 | /* Forge Arp Packet, using libpcap */ 242 | void forge_arp(char *source_ip, char *dest_ip, char *disp) 243 | { 244 | in_addr_t sip, dip; 245 | 246 | char raw_arp[] = 247 | "\xff\xff\xff\xff\xff\xff" // mac destination 248 | "\x00\x00\x00\x00\x00\x00" // mac source 249 | "\x08\x06" // type 250 | "\x00\x01" // hw type 251 | "\x08\x00" // protocol type 252 | "\x06" // hw size 253 | "\x04" // protocol size 254 | "\x00\x01" // opcode 255 | "\x00\x00\x00\x00\x00\x00" // sender mac 256 | "\x00\x00\x00\x00" // sender ip 257 | "\xff\xff\xff\xff\xff\xff" // target mac 258 | "\x00\x00\x00\x00"; // target ip 259 | 260 | /* get src & dst ip address */ 261 | dip = inet_addr(dest_ip); 262 | sip = inet_addr(source_ip); 263 | 264 | memcpy(raw_arp + 28, (char*) &sip, IP_ALEN); 265 | memcpy(raw_arp + 38, (char*) &dip, IP_ALEN); 266 | 267 | /* set mac addr */ 268 | memcpy(raw_arp + 6, smac, ETH_ALEN); 269 | memcpy(raw_arp + 22, smac, ETH_ALEN); 270 | 271 | /* Inject the packet */ 272 | pcap_sendpacket(inject, (unsigned char *)raw_arp, sizeof(raw_arp) - 1); 273 | 274 | } 275 | 276 | 277 | void inject_destroy() 278 | { 279 | pcap_close(inject); 280 | } 281 | -------------------------------------------------------------------------------- /update-oui-database.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # update-oui-database.sh 4 | # This script creates the src/oui.h file needed by netdiscover. 5 | # 6 | # Copyright 2016-2025 Joao Eriberto Mota Filho 7 | # Copyright 2025 Bernhard M. Wiedemann 8 | # This file is under GPL-2+ license. 9 | # 10 | # netdiscover was written by Jaime Penalba Estebanez 11 | # and is available at https://github.com/netdiscover-scanner/netdiscover 12 | # 13 | # License for this script: 14 | # 15 | # This program is free software; you can redistribute it and/or 16 | # modify it under the terms of the GNU General Public License 17 | # as published by the Free Software Foundation; either version 2 18 | # of the License, or (at your option) any later version. 19 | # 20 | # This program is distributed in the hope that it will be useful, 21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | # GNU General Public License for more details. 24 | # 25 | # You should have received a copy of the GNU General Public License 26 | # along with this program; if not, write to the Free Software 27 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 28 | 29 | VERSION=0.6 30 | 31 | # CHANGELOG 32 | # 33 | # v0.6, 2025-08-14, Eriberto 34 | # 35 | # * Using mtime to define DATA2 to make update-oui-database.sh reproducible. 36 | # Thanks to Bernhard M. Wiedemann . (PR #38) 37 | # * Added an autofix for x01 binary byte. 38 | # * Added a check for dos2unix results. 39 | # 40 | # v0.5, 2022-10-29, Eriberto 41 | # 42 | # * Change main download site from https://linuxnet.ca/ieee/oui.txt (link down) 43 | # to https://standards-oui.ieee.org. (Fix #23) 44 | # 45 | # v0.4, 2022-02-17, Eriberto 46 | # 47 | # * Add --insecure option to download from 48 | # http://standards-oui.ieee.org/oui/oui.txt. (Fix #15, again) 49 | # 50 | # v0.3, 2021-11-11, Eriberto 51 | # 52 | # * Change download site from http://standards-oui.ieee.org/oui/oui.txt to 53 | # https://linuxnet.ca/ieee/oui.txt. (Fix #15) 54 | # 55 | # v0.2, 2020-06-29, Eriberto 56 | # 57 | # * Drop 'sed -z' to execute in macOS. 58 | # * Drop not needed PATH variable, also for macOS. 59 | # 60 | # v0.1, 2016-04-13, Eriberto 61 | # 62 | # * Initial release. 63 | 64 | 65 | ##################### 66 | # Initial variables # 67 | ##################### 68 | 69 | DATE=$(date +%F | tr -d "-") 70 | NAME=oui.txt-$DATE 71 | OUIFILE=src/oui.h 72 | [ -e $NAME ] && DATE2=$(date -r $NAME +%F) || DATE2=$(date +%F) 73 | 74 | # Minimum amount of MAC addresses for check. Is not needed to update this every 75 | # time. The main goal is check if a generated file was corrupted. 76 | # To calculate, use "cat `oui_file` | grep "base 16" | wc -l" 77 | # Last definition on 2021-11-11. 78 | MINIMUM_MAC=30500 79 | 80 | # URL to download 81 | URL=https://standards-oui.ieee.org 82 | 83 | # Insecure URL 84 | IURL=http://standards-oui.ieee.org/oui/oui.txt 85 | 86 | #################### 87 | # Help and version # 88 | #################### 89 | 90 | if [ "$1" = "--help" ] || [ "$1" = "-h" ] 91 | then 92 | printf "\nupdate-oui-database.sh $VERSION\n\n" 93 | printf "Usage: ./update-oui-database.sh [OPTIONS]\n\n" 94 | printf " --no-download Do not download the oui.txt. Use an already downloaded version.\n" 95 | printf " --insecure Use an insecure address, started with http, instead of https.\n" 96 | printf " --help, -h Show this help.\n" 97 | printf " --version, -v Show version.\n\n" 98 | printf "If running without options, the program will download the oui.txt file from\ndefault place.\n\n" 99 | printf "Default place: $URL\n" 100 | printf "Insecure place: $IURL\n" 101 | exit 0 102 | fi 103 | 104 | if [ "$1" = "--version" ] || [ "$1" = "-v" ] 105 | then 106 | printf "\nupdate-oui-database.sh\n\n" 107 | printf "Version $VERSION\n\n" 108 | exit 0 109 | fi 110 | 111 | 112 | ###################### 113 | # Check for dos2unix # 114 | ###################### 115 | 116 | dos2unix -V > /dev/null 2> /dev/null || { printf "\nYou need dos2unix command to use this script.\n\n"; exit 1; } 117 | 118 | ###################### 119 | # Check for insecure # 120 | ###################### 121 | 122 | # Not needed for https://standards-oui.ieee.org/ 123 | if [ "$1" = "--insecure" ] 124 | then 125 | # Redefining $URL to use insecure 126 | URL="$IURL" 127 | fi 128 | 129 | ################## 130 | # Check for gzip # 131 | ################## 132 | 133 | gzip -V > /dev/null 2> /dev/null || { printf "\nYou need gzip command to use this script.\n\n"; exit 1; } 134 | 135 | ################# 136 | # Check for sed # 137 | ################# 138 | 139 | sed --version > /dev/null 2> /dev/null || { printf "\nYou need sed command to use this script.\n\n"; exit 1; } 140 | 141 | #################### 142 | # OUI.txt download # 143 | #################### 144 | 145 | # Check if .gz is present 146 | 147 | URLEND=${URL: -3} 148 | GZ="" 149 | 150 | if [ "$URLEND" = ".gz" ]; then GZ=".gz"; fi 151 | 152 | # Search for downloaders 153 | 154 | DOWN=0 155 | 156 | if [ "$1" = "--no-download" ]; then DOWN=no; fi 157 | 158 | if [ "$DOWN" = "0" ]; then axel -V > /dev/null 2> /dev/null && DOWN="axel -ao ${NAME}${GZ}"; fi 159 | if [ "$DOWN" = "0" ]; then curl -V > /dev/null 2> /dev/null && DOWN="curl -Lo ${NAME}${GZ}"; fi 160 | if [ "$DOWN" = "0" ]; then wget -V > /dev/null 2> /dev/null && DOWN="wget -O ${NAME}${GZ}"; fi 161 | if [ "$DOWN" = "0" ]; then printf "\nYou need axel (faster!), wget or curl to use this script.\n\n" && exit 1; fi 162 | 163 | # Download the oui.txt 164 | 165 | if ( [ -f "${NAME}.gz" ] || [ -f "$NAME" ] ) && [ "$DOWN" != "no" ] 166 | then 167 | printf "\nThe file $NAME (with or without .gz) already exists. To run this script, remove it or use --no-download option.\n\n" 168 | exit 1 169 | elif [ ! -f "${NAME}.gz" ] && [ ! -f "$NAME" ] && [ "$DOWN" = "no" ] 170 | then 171 | printf "\nThe file $NAME (with or without .gz) is missing. To download it don't use --no-download option.\n\n" 172 | exit 1 173 | elif [ "$DOWN" != "no" ] 174 | then 175 | printf "\n\nDownloading oui.txt from $URL\n" 176 | printf "Downloader to be used: $(echo $DOWN | cut -d" " -f1)\n\n" 177 | $DOWN $URL 178 | fi 179 | 180 | ################### 181 | # Unzip if needed # 182 | ################### 183 | 184 | if [ -f "${NAME}.gz" ] 185 | then 186 | echo "Found ${NAME}.gz. Unpacking..." 187 | gunzip "${NAME}.gz" 188 | fi 189 | 190 | ####################### 191 | # Fixing known issues # 192 | ####################### 193 | 194 | # Removing binary x01 195 | grep -qaP '\x01' $NAME && sed 's/\x01/ /g' $NAME > oui.x01 && mv oui.x01 $NAME 196 | 197 | ###################### 198 | # Processing OUI.txt # 199 | ###################### 200 | 201 | # Final check and conversion to Unix 202 | 203 | TOTAL_MAC=$(cat $NAME | grep "base 16" | wc -l) 204 | 205 | if [ "$TOTAL_MAC" -lt "$MINIMUM_MAC" ] 206 | then 207 | printf "\nThe file $NAME seems to be corrupted. There are $TOTAL_MAC MAC addresses. However, over the $MINIMUM_MAC addresses were expected.\n\n" 208 | exit 1 209 | fi 210 | 211 | dos2unix -q $NAME 212 | 213 | # Check the conversion to Unix 214 | 215 | egrep $'\r' $NAME > /dev/null && { printf "\n\nERROR: dos2unix failed to convert the file $NAME"; \ 216 | printf "\n\nRunning dos2unix without -q option to identify the problem:\n\n"; \ 217 | dos2unix $NAME; \ 218 | exit 1; } 219 | 220 | ###################### 221 | # Building src/oui.h # 222 | ###################### 223 | 224 | printf "\n\nBuilding the $OUIFILE.\n" 225 | 226 | # The header 227 | 228 | cat << EOT > $OUIFILE 229 | /* 230 | * Organizationally Unique Identifier list downloaded on $DATE2 231 | * Automatically generated from $URL 232 | * For Netdiscover by Jaime Penalba 233 | * 234 | */ 235 | 236 | struct oui { 237 | char *prefix; /* 24 bit global prefix */ 238 | char *vendor; /* Vendor id string */ 239 | }; 240 | 241 | struct oui oui_table[] = { 242 | EOT 243 | 244 | # The MACs 245 | 246 | cat $NAME | grep "base 16" | tr '\t' ' ' | tr -s " " | sed 's/(base 16) //' | \ 247 | grep '[0-9A-F]' | sort | sed 's/ /", "/' | sed 's/^/ { "/' | \ 248 | tr '\n' '#' | sed 's/#/" },#/g' | tr '#' '\n' >> $OUIFILE 249 | 250 | # Total of MACs 251 | 252 | TOTALMAC=$(cat $OUIFILE | egrep "{ .[0-9A-F]" | wc -l) 253 | 254 | # The tail 255 | 256 | cat << EOT >> $OUIFILE 257 | { NULL, NULL } 258 | }; 259 | 260 | // Total $TOTALMAC items. 261 | EOT 262 | 263 | printf "Done. $OUIFILE has $TOTALMAC MAC addresses.\n" 264 | # END 265 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | Netdiscover 0.21 - 14 Aug 2025 2 | * update-oui-database.sh: 3 | - Using mtime to define DATA2 to update-oui-database.sh reproducible. 4 | Thanks to Bernhard M. Wiedemann . (PR #38) 5 | - Added an autofix for x01 binary byte. 6 | - Added a check for dos2unix results. 7 | - Released version 0.6. 8 | * Updated OUI table. 9 | 10 | Netdiscover 0.20 - 13 May 2025 11 | * Added full support to CIDR subnets. Thanks to Jefferson J. Raimon 12 | . 13 | * Fixed a fail to build from source with GCC 15. Thanks to Josh Ellithorpe 14 | . 15 | * Updated OUI table. 16 | 17 | Netdiscover 0.11 - 26 Mar. 2025 18 | * Added -R option to assume user is root or that he has the required 19 | capabilities without running any checks. Thanks to VBrawl 20 | . 21 | * No longer install extra documents. Extra docs like AUTHORS and TODO must 22 | remain in source code only. Commonly, other projects don't install them. 23 | * Updated OUI table. 24 | 25 | Netdiscover 0.10 - 29 Oct. 2022 26 | * Changed secure download site from https://linuxnet.ca/ieee/oui.txt 27 | (link down) to https://standards-oui.ieee.org in update-oui-database.sh 28 | script. 29 | * Fixed segfault when HOME env is not set. Thanks to Till Zimmermann 30 | . 31 | * Use unsigned int for data_counter.hosts. Thanks to Brendan Coles 32 | 33 | * Updated OUI table. 34 | 35 | Netdiscover 0.9 - 19 Feb. 2022 36 | * ifaces: process_packet: Return if source MAC address matches host MAC. 37 | Thanks to bcoles . 38 | * Using a secure URL for OUI download and added the option --insecure to 39 | download from IEEE (insecure). 40 | * Fixed 'make dist' process. 41 | * Moved manpage install from doc/Makefile.am to Makefile.am. 42 | * GitHub CI: 43 | - Added a final command test. 44 | - Added a test for 'make dist'. 45 | - Test if the program version is right. 46 | - Created a new CI to test download via secure and insecure modes. 47 | * Updated OUI table. 48 | 49 | Netdiscover 0.8.1 - 01 Nov. 2021 50 | * Migrated README to README.md. 51 | * Replaced deprecated function pcap_lookupdev() with pcap_findalldevs(). 52 | Thanks to bcoles . 53 | * Updated manpage version and date. 54 | * Updated OUI table. 55 | * Using version set in configure.ac for src/main.c. Consequently... 56 | * ...Added a new GitHub CI stanza to check version. 57 | 58 | Netdiscover 0.8 - 11 Jul. 2021 59 | * Changed PCAP_TOUT from 0 to 512 in src/ifaces.h, to avoid no results when 60 | scanning with CIDR /24 if netdiscover is being built with libpcap >= 1.10. 61 | Thanks to Enrico Schmitz. 62 | * Updated manpage date and version. 63 | * Updated OUI table. 64 | 65 | Netdiscover 0.7 - 29 Jun. 2020 66 | * Updated create-man.sh to 2.0 version. 67 | * Updated manpage date. 68 | * Updated update-oui-database.sh to be useful in macOS. 69 | * Updated OUI table. 70 | 71 | Netdiscover 0.6 - 17 Apr. 2020 72 | * Added a CI test to be run by GitHub. (Eriberto) 73 | * Fix build with GCC 10. (Jaime Peñalba) 74 | * Updated OUI table. (Eriberto) 75 | 76 | Netdiscover 0.5.1 - 07 Feb. 2019 77 | * Added an official repository notice in README. 78 | * Added dates of releases in ChangeLog. 79 | * Added some copyright notices. 80 | * Several important fixes and improvements in manpage and help page. 81 | * Updated OUI table (1 change since yesterday). 82 | 83 | Netdiscover 0.5 - 06 Feb. 2019 84 | * Added some missing entries in last changelog (0.4). 85 | * Fixed the following warning from GCC: "warning: ignoring return value 86 | of system, declared with attribute warn_unused_result". 87 | * Full updated the manpage and help page. Added missing options, examples, 88 | etc. 89 | * Removed INSTALL file. This file must be created by autotools when in 90 | build process to always provide updated instructions. 91 | * Removed Usage and Examples sections from README file. It will make easier 92 | the maintenance. All information are in help and manpage. 93 | * Updated checklist to release a new version. 94 | * Updated OUI table (5 new changes since yesterday). 95 | * Using txt2man to generate the manpage. 96 | 97 | Netdiscover 0.4 - 06 Feb. 2019 98 | * Added a checklist for release a new version (file doc/UPDATE-CHECK). 99 | * Added a distclean-local target to Makefile.am to remove files after a 100 | 'make distclean'. 101 | * Added a new script to update OUI table (src/oui.h). 102 | * Fixed a segmentation fault after start in a terminal with more than 103 | 300 columns (Debian bug #818791). 104 | * Fixed -l option in manpage. 105 | * Fixed spelling errors in final binary and in manpage. 106 | * Moved the old script update-oui-database-legacy.sh to new directory 107 | 'legacy'. 108 | * Updated OUI table. 109 | * Updated project homepage in several files to point to GitHub. 110 | * Updated README to get all options from manpage. 111 | * Updated the address for bugs list in configure.ac. 112 | 113 | Netdiscover 0.3-beta7 (Currently working on it) - 24 Mar. 2015 114 | * update-oui-database.sh script modified to work with latest oui.txt 115 | * Larry Reznick : oui script fixes for redhat and code 116 | reformatting to make it more readable including manpage 117 | * Emanuele Acri : Libnet injection replaced by pcap 118 | * Frantisek Hanzlik : oui script speed drastically 119 | improved 120 | * Janusz Uzycki : Scroll page up/down feature added 121 | * Janusz Uzycki : Known hosts list feature 122 | * Janusz Uzycki : Fix for undefined docdir 123 | * Several variable naming changes 124 | * Autotools scripts updated 125 | * Fixed scroll limits & some screen improvements 126 | * Fixed crash when freeing common ranges list at end of scan 127 | * New data abstraction layer added to handle different view modes 128 | * Included script to update oui database. 129 | * Added custom pcap filter option. Patch by Gustavo Chain. 130 | * Some code layout clean. 131 | * Several fixes to avoid potential buffer overflows. Patch by Alex. 132 | * fhandle.c fixed to be able to handle ms-dos line format. Patch by Alex. 133 | * Some ranges not working through -r option fixed. Patch by Alex. 134 | * Improved network addresses sanity checks, thanks to Alex. 135 | * Netmask will be setup to /24 by default if its omitted, thanks to Alex. 136 | * Added .2 .200 hosts to be scanned on fast mode, thanks again to Alex. 137 | * Some unnecessary mallocs where removed to prevent memory leaks, 138 | thanks to Alex (SuD) for the patch. 139 | * Hang when "h" is pressed twice fixed 140 | * Mandriva and RedHat rpm .spec files added, thanks to Francis Giraldeau 141 | and Guillaume Pratte for the contribution 142 | * Buffer overflow on search_vendor fixed, thanks to Guillaume Pratte 143 | * Solaris bus error when freeing a pointer returned by getenv fixed 144 | * Added parsable output thanks to Guillaume Pratte for the patch 145 | * Added support to read ranges from a given file using -l switch 146 | * Manpage updated with new features and some examples 147 | * Added support to read user config files for ranges and fast mode lists 148 | * MAC vendors list updated 149 | * Hang on Ctrl+C fixed, thanks to Alex (SuD) for the patch 150 | * Improved argument handling, thanks to Alex (SuD) for reporting 151 | 152 | Netdiscover 0.3-beta6 - 22 Oct. 2005 153 | * Changed installation path to sbin 154 | * Added man page, Thanks to Nicolas Weyland 155 | * Added help screen (pressing "h" while running) 156 | * Added new screen to display arp request 157 | * Fixed screen refresh/display problems 158 | * Improved screen interface to display large hosts lists, j/k or up/down 159 | arrow keys can now be used to scroll 160 | * Fixed packet length count display 161 | 162 | Netdiscover 0.3-beta5 - 01 Sep. 2005 163 | * Now arp request sender data is added to the stations list 164 | * Improved sniffer packet processing code 165 | * Major code cleaning / commenting done 166 | * If no interface is specified will autoselect firstone available 167 | * Better error handling, including interface and uid checking 168 | 169 | Netdiscover 0.3-beta4 - 24 Aug. 2005 170 | * Fixed header checks on configure.in, thanks to Charlie Brady for reporting 171 | * Suppress sleep time between each arp request, instead sleep between each 172 | network scanned, also called the hardcore mode :) (like in older betas) 173 | * Added request count option (-c switch) 174 | * Some screen display changes 175 | * Supports decimal sleep times 176 | * Some changes to support gcc 2.95 177 | * Added customizable array for ips scanned on fast mode 178 | * Some changes made around scanning loops, and sleep time, the scan will be 179 | slower by default, but safer (longer sleeps to avoid packet loss) 180 | * Changed usage parameters, to easier way (thanks to SuD for the idea) 181 | 182 | Netdiscover 0.3-beta3 - 08 Aug. 2005 183 | * Completing documentation for 0.3 final release 184 | * Added support to change last octet of scanning host (option "n") 185 | * Solaris and OpenBSD support added, also must work on other unixes 186 | * Improved configure.in, now checks the system, libnet.h and pcap.h 187 | 188 | Netdiscover 0.3-beta2 - 23 Jul. 2005 189 | * Added mac vendor database, and identifying 190 | 191 | Netdiscover 0.3-beta1 20 Jul. 2005 192 | * Added other thread for screen refresh, also refresh time as parameter 193 | * Fast scan mode, will only scan for .1, .100 and .254 of each network 194 | * Improved arp packet forgery, now doesn't lose packets 195 | * No more lamme ip changing at given interface, now you can browse 196 | while scanning, and ioctls where removed 197 | * A lot more of fixes for portability 198 | 199 | Netdiscover 0.2 beta (July 17, 2005) 200 | * Added getopt for parameter handling 201 | * Sleep time parameter added 202 | * New passive mode detection 203 | * New /8, /16, /24 scan mode 204 | * New auto scan mode 205 | * Added packet counters 206 | * Scan progress added 207 | * Nicer interface (no more scrolling!) 208 | * Ignore packets with our mac address as source 209 | 210 | Netdiscover 0.1 beta (July 11, 2005) 211 | * First beta version released 212 | -------------------------------------------------------------------------------- /src/screen.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * screen.c 3 | * 4 | * Tue Jul 12 03:23:41 2005 5 | * Copyright 2005-2009 Jaime Penalba Estebanez 6 | * Copyright 2006 Guillaume Pratte 7 | * Copyright 2009 Janusz Uzycki 8 | * 9 | ****************************************************************************/ 10 | 11 | /* 12 | * This program is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License as published by 14 | * the Free Software Foundation; either version 3 of the License, or 15 | * (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License 23 | * along with this program; if not, write to the Free Software 24 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 | */ 26 | 27 | /* 28 | * Thanks to Christophe Devine, aircrack creator, who gave me the 29 | * inspiration to make this screen interface. You can see his site 30 | * here http://www.cr0.net:8040/code/network/ 31 | */ 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "screen.h" 43 | #include "misc.h" 44 | #include "ifaces.h" 45 | #include "data_al.h" 46 | 47 | 48 | /* Shity globals */ 49 | struct termios stored_settings, working_settings; 50 | extern pthread_t screen, keys, sniffer, injection; 51 | 52 | 53 | int scroll; 54 | int smode, oldmode; 55 | char line[300], tline[300]; 56 | char blank[] = " "; 57 | 58 | 59 | /* Inits lists with null pointers, sighandlers, etc */ 60 | void init_screen() 61 | { 62 | /* Interface properties */ 63 | scroll = 0; 64 | smode = SMODE_HOST; 65 | 66 | /* Set interative mode options if no parsable mode */ 67 | if(!parsable_output) { 68 | /* Set signal handlers */ 69 | signal( SIGCONT, sighandler ); 70 | signal( SIGINT, sighandler ); 71 | signal( SIGKILL, sighandler ); 72 | signal( SIGTERM, sighandler ); 73 | signal( SIGHUP, sighandler ); 74 | signal( SIGABRT, sighandler ); 75 | 76 | /* Set console properties to read keys */ 77 | tcgetattr(0,&stored_settings); 78 | working_settings = stored_settings; 79 | 80 | working_settings.c_lflag &= ~(ICANON|ECHO); 81 | working_settings.c_cc[VTIME] = 0; 82 | working_settings.c_cc[VMIN] = 1; 83 | tcsetattr(0,TCSANOW,&working_settings); 84 | } 85 | } 86 | 87 | 88 | /* Handle signals and set terminal */ 89 | void sighandler(int signum) 90 | { 91 | if (parsable_output) { 92 | exit(0); 93 | } else { 94 | if (signum == SIGCONT) { 95 | tcsetattr(0,TCSANOW,&working_settings); 96 | } else { 97 | tcsetattr(0,TCSANOW,&stored_settings); 98 | 99 | signal(SIGINT, SIG_DFL); 100 | signal(SIGTERM, SIG_DFL); 101 | pthread_kill(keys, signum); 102 | 103 | exit(0); 104 | } 105 | } 106 | } 107 | 108 | 109 | /* Check scrolling limit */ 110 | int scroll_limit() 111 | { 112 | const struct data_al *current_data_mode; 113 | 114 | /* Use corresponding data layer depending on current screen mode */ 115 | current_data_mode = NULL; 116 | 117 | switch (smode) { 118 | case SMODE_REPLY: 119 | current_data_mode = &_data_reply; 120 | break; 121 | case SMODE_REQUEST: 122 | current_data_mode = &_data_request; 123 | break; 124 | case SMODE_HOST: 125 | current_data_mode = &_data_unique; 126 | break; 127 | case SMODE_HELP: 128 | current_data_mode = &_data_unique; 129 | break; 130 | } 131 | 132 | return current_data_mode->hosts_count() - scroll; 133 | } 134 | 135 | 136 | /* Read input keys */ 137 | void read_key() 138 | { 139 | int ch, i; 140 | ch = getchar(); 141 | 142 | /* Check for arrow keys */ 143 | if ( ch == 27 && (ch = getchar()) == 91) { 144 | switch (getchar()) { 145 | case 66: 146 | ch = 106; 147 | break; 148 | case 65: 149 | ch = 107; 150 | break; 151 | } 152 | } 153 | 154 | switch (ch) { 155 | case 107: // Scroll up 156 | if (scroll > 0) 157 | scroll--; 158 | break; 159 | case 106: // Scroll down 160 | if (scroll_limit() > 1) 161 | scroll++; 162 | break; 163 | case ',': // Scroll page up 164 | for (i = 0; i < win_sz.ws_row - 7; i++) 165 | if (scroll > 0) 166 | scroll--; 167 | break; 168 | case '.': // Scroll page down 169 | for (i = 0; i < win_sz.ws_row - 7; i++) 170 | if (scroll_limit() > 1) 171 | scroll++; 172 | break; 173 | case 114: // Show requests view 174 | smode = SMODE_REQUEST; 175 | scroll = 0; 176 | break; 177 | case 97: // Show replies view 178 | smode = SMODE_REPLY; 179 | scroll = 0; 180 | break; 181 | case 117: // Show unique hosts view 182 | smode = SMODE_HOST; 183 | scroll = 0; 184 | break; 185 | case 113: // Quit 186 | if (smode == SMODE_HELP) 187 | smode = oldmode; 188 | else 189 | sighandler(0); 190 | break; 191 | case 104: // Show help screen 192 | if (smode != SMODE_HELP) { 193 | oldmode = smode; 194 | smode = SMODE_HELP; 195 | scroll = 0; 196 | } 197 | break; 198 | } 199 | 200 | /* Debug code 201 | else 202 | { 203 | printf("\n\nYou pressed %i\n\n", ch); 204 | sleep(2); 205 | } */ 206 | 207 | print_screen(); 208 | } 209 | 210 | 211 | /* Clear and fill the screen */ 212 | void print_screen() 213 | { 214 | /* Get Console Size */ 215 | if (ioctl(0, TIOCGWINSZ, &win_sz) < 0) { 216 | win_sz.ws_row = 24; 217 | win_sz.ws_col = 80; 218 | } 219 | 220 | /* Flush and print screen */ 221 | fprintf( stderr, "\33[1;1H" ); 222 | pthread_mutex_lock(data_access); 223 | fill_screen(); 224 | pthread_mutex_unlock(data_access); 225 | fprintf( stderr, "\33[J" ); 226 | fflush(stdout); 227 | } 228 | 229 | 230 | /* Print header line containing scanning and current screen mode */ 231 | void print_status_header() 232 | { 233 | int j; 234 | char *current_smode = NULL; 235 | 236 | switch (smode) { 237 | case SMODE_REPLY: 238 | current_smode = "ARP Reply"; 239 | break; 240 | case SMODE_REQUEST: 241 | current_smode = "ARP Request"; 242 | break; 243 | case SMODE_HOST: 244 | current_smode = "Unique Hosts"; 245 | break; 246 | case SMODE_HELP: 247 | current_smode = "Help"; 248 | break; 249 | } 250 | 251 | sprintf(line, " Currently scanning: %s | Screen View: %s", 252 | current_network, current_smode); 253 | printf("%s", line); 254 | 255 | /* Fill with spaces */ 256 | for (j=strlen(line); jprint_header(win_sz.ws_col); 294 | 295 | /* Print screen main data */ 296 | if (smode != SMODE_HELP) { 297 | 298 | int x = 0; 299 | 300 | current_data_mode->beginning_registry(); 301 | while (current_data_mode->current_registry() != NULL) { 302 | 303 | if (x >= scroll) 304 | current_data_mode->print_line(); 305 | 306 | current_data_mode->next_registry(); 307 | x++; 308 | 309 | /* Check if end of screen was reached */ 310 | if (x >= ( (win_sz.ws_row + scroll) - 7)) 311 | break; 312 | } 313 | 314 | } else if(smode == SMODE_HELP) { 315 | int i; 316 | 317 | printf("\t ______________________________________________ \n" 318 | "\t | | \n" 319 | "\t | \33[1mUsage Keys\33[0m | \n" 320 | "\t | h: show this help screen | \n" 321 | "\t | j: scroll down (or down arrow) | \n" 322 | "\t | k: scroll up (or up arrow) | \n" 323 | "\t | .: scroll page up | \n" 324 | "\t | ,: scroll page down | \n" 325 | "\t | q: exit this screen or end | \n" 326 | "\t | | \n" 327 | "\t | \33[1mScreen views\33[0m | \n" 328 | "\t | a: show arp replies list | \n" 329 | "\t | r: show arp requests list | \n" 330 | "\t | u: show unique hosts detected | \n" 331 | "\t | | \n" 332 | "\t ---------------------------------------------- \n"); 333 | 334 | 335 | 336 | for (i=25; i 6 | * Copyright 2006 Guillaume Pratte 7 | * Copyright 2007-2008 Gustavo Chain 8 | * Copyright 2009 Janusz Uzycki 9 | * Copyright 2019-2021 Joao Eriberto Mota Filho 10 | * Copyright 2021 Brendan Coles 11 | * Copyright 2022 Till Zimmermann 12 | * Copyright 2024 VBrawl 13 | * Copyright 2025 Jefferson J. Raimon 14 | * Copyright 2025 Josh Ellithorpe 15 | * 16 | ****************************************************************************/ 17 | 18 | /* 19 | * This program is free software; you can redistribute it and/or modify 20 | * it under the terms of the GNU General Public License as published by 21 | * the Free Software Foundation; either version 3 of the License, or 22 | * (at your option) any later version. 23 | * 24 | * This program is distributed in the hope that it will be useful, 25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 | * GNU General Public License for more details. 28 | * 29 | * You should have received a copy of the GNU General Public License 30 | * along with this program; if not, write to the Free Software 31 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 32 | */ 33 | 34 | #define _GNU_SOURCE 35 | 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | #include 45 | #include 46 | 47 | #include "ifaces.h" 48 | #include "screen.h" 49 | #include "fhandle.h" 50 | #include "misc.h" 51 | #include "../config.h" 52 | 53 | #define RPATH "%s/.netdiscover/ranges" 54 | #define FPATH "%s/.netdiscover/fastips" 55 | 56 | 57 | extern void parseable_scan_end(); 58 | void *inject_arp(void *arg); 59 | void *screen_refresh(void *arg); 60 | void *parsable_screen_refresh(void *arg); 61 | void scan_range(char *disp, char *sip); 62 | void usage(char *commando); 63 | 64 | 65 | /* Last octect of ips scaned in fast mode */ 66 | /* Add new addr if needed here */ 67 | char **fast_ips; 68 | char *dfast_ips[] = { "1", "2", "100", "200", "254", NULL}; 69 | 70 | /* Common local networks to scan */ 71 | /* Add new networks if needed here */ 72 | char **common_net; 73 | char *dcommon_net[] = { 74 | "192.168.0.0/16", 75 | "172.16.0.0/16", 76 | "172.26.0.0/16", 77 | "172.27.0.0/16", 78 | "172.17.0.0/16", 79 | "172.18.0.0/16", 80 | "172.19.0.0/16", 81 | "172.20.0.0/16", 82 | "172.21.0.0/16", 83 | "172.22.0.0/16", 84 | "172.23.0.0/16", 85 | "172.24.0.0/16", 86 | "172.25.0.0/16", 87 | "172.28.0.0/16", 88 | "172.29.0.0/16", 89 | "172.30.0.0/16", 90 | "172.31.0.0/16", 91 | "10.0.0.0/8", 92 | NULL 93 | }; 94 | 95 | 96 | pthread_t injection, sniffer, screen, keys; 97 | 98 | /* Command line flags */ 99 | int flag_fast_mode; 100 | int flag_repeat_scan; 101 | int flag_network_octect; 102 | int flag_supress_sleep; 103 | int flag_ignore_files; 104 | int flag_auto_scan; 105 | long flag_sleep_time; 106 | 107 | 108 | /* Read control keys */ 109 | void *keys_thread(void *arg) 110 | { 111 | while ( 1 == 1 ) 112 | read_key(); 113 | } 114 | 115 | // Convert IP string to uint32_t 116 | uint32_t ip_to_int(const char *ip) { 117 | struct in_addr addr; 118 | inet_aton(ip, &addr); 119 | return ntohl(addr.s_addr); 120 | } 121 | 122 | // Convert uint32_t to IP string 123 | void int_to_ip(uint32_t ip, char *buf) { 124 | struct in_addr addr; 125 | addr.s_addr = htonl(ip); 126 | strcpy(buf, inet_ntoa(addr)); 127 | } 128 | 129 | 130 | /* main, fetch params and start */ 131 | int main(int argc, char **argv) 132 | { 133 | int c; 134 | int flag_passive_mode = 0; 135 | int flag_scan_range = 0; 136 | int flag_scan_list = 0; 137 | int flag_assume_root = 0; 138 | int no_parsable_header = 0; 139 | char *plist = NULL; 140 | char *mlist = NULL; 141 | 142 | /* Config file handling vars */ 143 | char *home, *path; 144 | 145 | struct t_data datos; 146 | 147 | /* Some default values for the program options. */ 148 | datos.source_ip = NULL; 149 | datos.interface = NULL; 150 | datos.pcap_filter = NULL; 151 | flag_sleep_time = 99; 152 | flag_network_octect = 67; 153 | flag_repeat_scan = 1; 154 | flag_auto_scan = 0; 155 | 156 | /* Globals defined in screen.h */ 157 | parsable_output = 0; 158 | continue_listening = 0; 159 | 160 | current_network = (char *) malloc ((sizeof(char)) * 19); 161 | sprintf(current_network, "Starting."); 162 | 163 | /* Fetch parameters */ 164 | while ((c = getopt(argc, argv, "i:s:r:l:m:n:c:F:pRSfdPNLh")) != EOF) 165 | { 166 | switch (c) 167 | { 168 | case 'i': /* Set the interface */ 169 | datos.interface = (char *) malloc (sizeof(char) * (strlen(optarg) + 1)); 170 | sprintf(datos.interface, "%s", optarg); 171 | break; 172 | 173 | case 'p': /* Enable passive mode */ 174 | flag_passive_mode = 1; 175 | break; 176 | 177 | case 's': /* Set sleep time */ 178 | flag_sleep_time = atol(optarg); 179 | break; 180 | 181 | case 'S': /* Enable sleep supression */ 182 | flag_supress_sleep = 1; 183 | break; 184 | 185 | case 'c': /* Set no. of times to repeat the scan */ 186 | flag_repeat_scan = atoi(optarg); 187 | break; 188 | 189 | case 'n': /* Set las used octect */ 190 | flag_network_octect = atoi(optarg); 191 | break; 192 | 193 | case 'r': /* Set the range to scan */ 194 | datos.source_ip = (char *) malloc (sizeof(char) * strlen(optarg) + 1); 195 | sprintf(datos.source_ip, "%s", optarg); 196 | flag_scan_range = 1; 197 | break; 198 | 199 | case 'R': /* Assume user has the required capabilities (Don't run any checks) */ 200 | flag_assume_root = 1; 201 | break; 202 | 203 | case 'l': /* Scan ranges on the given file */ 204 | plist = (char *) malloc (sizeof(char) * (strlen(optarg) + 1)); 205 | sprintf(plist, "%s", optarg); 206 | flag_scan_list = 1; 207 | break; 208 | 209 | case 'm': /* Scan MACs on the given file */ 210 | mlist = (char *) malloc (sizeof(char) * (strlen(optarg) + 1)); 211 | sprintf(mlist, "%s", optarg); 212 | break; 213 | 214 | case 'f': /* Enable fast mode */ 215 | flag_fast_mode = 1; 216 | break; 217 | 218 | case 'F': /* Edit pcap filter */ 219 | datos.pcap_filter = (char *) malloc (sizeof(char) * (strlen(optarg) + 1)); 220 | sprintf(datos.pcap_filter, "%s", optarg); 221 | break; 222 | 223 | case 'd': /* Ignore home config files */ 224 | flag_ignore_files = 1; 225 | break; 226 | 227 | case 'P': /* Produces parsable output (vs interactive screen) */ 228 | parsable_output = 1; 229 | break; 230 | 231 | case 'N': /* Do not print header under parsable mode */ 232 | no_parsable_header = 1; 233 | break; 234 | 235 | case 'L': /* Continue to listen in parsable output mode after active scan is completed */ 236 | parsable_output = 1; 237 | continue_listening = 1; 238 | break; 239 | 240 | default: 241 | printf("\n"); /* continues... */ 242 | 243 | case 'h': /* Show help */ 244 | usage(argv[0]); 245 | exit(1); 246 | break; 247 | } 248 | } 249 | 250 | if (optind < argc) { 251 | printf("Invalid extra argument: %s\n\n", argv[optind]); 252 | usage(argv[0]); 253 | exit(1); 254 | } 255 | 256 | 257 | /* Check for uid 0 */ 258 | if(!flag_assume_root) { 259 | if ( getuid() && geteuid() ) 260 | { 261 | printf("You must be root to run this.\n"); 262 | exit(1); 263 | } 264 | } 265 | 266 | /* If no iface was specified, autoselect one. exit, if no one available */ 267 | if (datos.interface == NULL) 268 | { 269 | pcap_if_t *devices = NULL; 270 | 271 | if (pcap_findalldevs(&devices, errbuf) != 0) { 272 | printf("Couldn't find capture devices: %s\n", errbuf); 273 | exit(1); 274 | } 275 | 276 | if (devices == NULL || devices->name == NULL) { 277 | printf("Couldn't find suitable capture device: %s\n", errbuf); 278 | exit(1); 279 | } 280 | 281 | datos.interface = strdup(devices->name); 282 | pcap_freealldevs(devices); 283 | } 284 | 285 | /* Check whether user config files are either disabled or can be found */ 286 | if ((flag_ignore_files != 1) && (home = getenv("HOME")) == NULL) 287 | { 288 | printf("Couldn't figure out users home path (~). Please set the $HOME " 289 | "environment variable or specify -d to disable user configuration files.\n"); 290 | exit(1); 291 | } 292 | 293 | /* Load user config files or set defaults */ 294 | if (flag_ignore_files != 1) 295 | { 296 | 297 | /* Read user configured ranges */ 298 | path = (char *) malloc (sizeof(char) * (strlen(home) + strlen(RPATH) + 1)); 299 | sprintf(path, RPATH, home); 300 | 301 | if ((common_net = fread_list(path)) == NULL) 302 | common_net = dcommon_net; 303 | free(path); 304 | 305 | /* Read user configured ips */ 306 | path = (char *) malloc (sizeof(char) * (strlen(home) + strlen(FPATH) + 1)); 307 | sprintf(path, FPATH, home); 308 | 309 | if((fast_ips = fread_list(path)) == NULL) 310 | fast_ips = dfast_ips; 311 | free(path); 312 | 313 | } else { 314 | 315 | /* Set defaults */ 316 | common_net = dcommon_net; 317 | fast_ips = dfast_ips; 318 | 319 | } 320 | 321 | /* Read range list given by user if specified */ 322 | if (flag_scan_list == 1) { 323 | if ((common_net = fread_list(plist)) == NULL) { 324 | printf("File \"%s\" containing ranges, cannot be read.\n", plist); 325 | exit(1); 326 | } 327 | } 328 | 329 | /* Read Mac list of known hosts */ 330 | if (mlist != NULL) { 331 | if (load_known_mac_table(mlist) < 0) { 332 | printf("File \"%s\" containing MACs and host names, cannot be read.\n", mlist); 333 | exit(1); 334 | } 335 | } 336 | 337 | /* Init libnet, data layers and screen */ 338 | inject_init(datos.interface); 339 | _data_reply.init(); 340 | _data_request.init(); 341 | _data_unique.init(); 342 | init_screen(); 343 | 344 | /* Init mutex */ 345 | data_access = (pthread_mutex_t *)malloc(sizeof (pthread_mutex_t)); 346 | pthread_mutex_init(data_access, NULL); 347 | 348 | /* If no mode was selected, enable auto scan */ 349 | if ((flag_scan_range != 1) && (flag_passive_mode != 1)) 350 | flag_auto_scan = 1; 351 | 352 | /* Start the execution */ 353 | if (parsable_output) { 354 | 355 | if (!no_parsable_header) 356 | _data_unique.print_simple_header(); 357 | 358 | } else { 359 | int retsys = system("clear"); 360 | if (retsys == -1){ printf("clear system call failed"); } 361 | pthread_create(&screen, NULL, screen_refresh, (void *)NULL); 362 | pthread_create(&keys, NULL, keys_thread, (void *)NULL); 363 | } 364 | 365 | pthread_create(&sniffer, NULL, start_sniffer, (void *)&datos); 366 | 367 | if (flag_passive_mode == 1) { 368 | current_network = "(passive)"; 369 | pthread_join(sniffer,NULL); 370 | 371 | } else { 372 | if (pthread_create(&injection, NULL, inject_arp, (void *)&datos)) 373 | perror("Could not create injection thread"); 374 | 375 | pthread_join(sniffer,NULL); 376 | } 377 | 378 | if(datos.pcap_filter != NULL) 379 | free(datos.pcap_filter); 380 | 381 | return 0; 382 | } 383 | 384 | 385 | /* Refresh screen function called by screen thread */ 386 | void *screen_refresh(void *arg) 387 | { 388 | while (1==1) { 389 | print_screen(); 390 | sleep(1); 391 | } 392 | } 393 | 394 | 395 | /* Start the arp injection on the given network device */ 396 | void *inject_arp(void *arg) 397 | { 398 | struct t_data *datos; 399 | 400 | datos = (struct t_data *)arg; 401 | sleep(2); 402 | 403 | /* Scan the given range, or start the auto scan mode */ 404 | if ( flag_auto_scan != 1 ) { 405 | scan_range(datos->interface, datos->source_ip); 406 | 407 | } else { 408 | int x = 0; 409 | 410 | while (common_net[x] != NULL) { 411 | scan_range(datos->interface, common_net[x]); 412 | x++; 413 | } 414 | } 415 | 416 | /* Wait for last arp replys and mark as scan finished */ 417 | sleep(2); 418 | sprintf(current_network, "Finished!"); 419 | inject_destroy(); 420 | 421 | /* If parseable output is enabled, print end and exit */ 422 | if(parsable_output) 423 | parseable_scan_end(); 424 | 425 | return NULL; 426 | } 427 | 428 | 429 | /* Scan 255 hosts network */ 430 | void scan_net(char *disp, char *sip) 431 | { 432 | int x, j; 433 | char test[16], fromip[16]; 434 | 435 | sprintf(fromip,"%s.%i", sip, flag_network_octect); 436 | 437 | /* Repeat given times */ 438 | for (x=0; x 30) { 515 | printf("\nERROR: Invalid CIDR prefix '%d' (must be between 1 and 30)\n\n", prefix); 516 | exit(1); 517 | } 518 | } 519 | 520 | ip = ip_to_int(ip_str); 521 | netmask = (prefix == 32) ? 0xFFFFFFFF : (~0U << (32 - prefix)); 522 | network = ip & netmask; 523 | broadcast = network | ~netmask; 524 | 525 | start_ip = network + 1; 526 | end_ip = broadcast - 1; 527 | 528 | // Att current_network to show actual prefix 529 | sprintf(current_network, "%s/%d", ip_str, prefix); 530 | 531 | for (x = 0; x < flag_repeat_scan; x++) 532 | { 533 | for (uint32_t i = start_ip; i <= end_ip; i++) 534 | { 535 | int_to_ip(i, target_ip); 536 | int_to_ip(start_ip, fromip); 537 | 538 | forge_arp(fromip, target_ip, disp); 539 | 540 | if (flag_supress_sleep != 1) 541 | { 542 | if (flag_sleep_time != 99) 543 | usleep(flag_sleep_time * 1000); 544 | else 545 | usleep(1 * 1000); 546 | } 547 | } 548 | 549 | if (flag_supress_sleep == 1) 550 | { 551 | if (flag_sleep_time != 99) 552 | usleep(flag_sleep_time * 1000); 553 | else 554 | usleep(1 * 1000); 555 | } 556 | } 557 | } 558 | 559 | /* Print usage instructions */ 560 | void usage(char *comando) 561 | { 562 | printf("Netdiscover %s [Active/passive ARP reconnaissance tool]\n" 563 | "Written by: Jaime Penalba \n\n" 564 | "Usage: %s [-i device] [-r range | -l file | -p] [-m file] [-F filter] " 565 | "[-s time] [-c count] [-n node] [-dfPLNS]\n" 566 | " -i device: your network device\n" 567 | " -r range: scan a given range instead of auto scan. 192.168.6.0/24,/16,/8\n" 568 | " -l file: scan the list of ranges contained into the given file\n" 569 | " -p passive mode: do not send anything, only sniff\n" 570 | " -m file: scan a list of known MACs and host names\n" 571 | " -F filter: customize pcap filter expression (default: \"arp\")\n" 572 | " -s time: time to sleep between each ARP request (milliseconds)\n" 573 | " -c count: number of times to send each ARP request (for nets with packet loss)\n" 574 | " -n node: last source IP octet used for scanning (from 2 to 253)\n" 575 | " -d ignore home config files for autoscan and fast mode\n" 576 | " -R assume user is root or has the required capabilities without running any checks\n" 577 | " -f enable fastmode scan, saves a lot of time, recommended for auto\n" 578 | " -P print results in a format suitable for parsing by another program and stop after active scan\n" 579 | " -L similar to -P but continue listening after the active scan is completed\n" 580 | " -N Do not print header. Only valid when -P or -L is enabled.\n" 581 | " -S enable sleep time suppression between each request (hardcore mode)\n\n" 582 | "If -r, -l or -p are not enabled, netdiscover will scan for common LAN addresses.\n", 583 | VERSION, comando); 584 | } 585 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | 2 | GNU GENERAL PUBLIC LICENSE 3 | Version 3, 29 June 2007 4 | 5 | Copyright (C) 2007 Free Software Foundation, Inc. 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The GNU General Public License is a free, copyleft license for 12 | software and other kinds of works. 13 | 14 | The licenses for most software and other practical works are designed 15 | to take away your freedom to share and change the works. By contrast, 16 | the GNU General Public License is intended to guarantee your freedom to 17 | share and change all versions of a program--to make sure it remains free 18 | software for all its users. We, the Free Software Foundation, use the 19 | GNU General Public License for most of our software; it applies also to 20 | any other work released this way by its authors. You can apply it to 21 | your programs, too. 22 | 23 | When we speak of free software, we are referring to freedom, not 24 | price. Our General Public Licenses are designed to make sure that you 25 | have the freedom to distribute copies of free software (and charge for 26 | them if you wish), that you receive source code or can get it if you 27 | want it, that you can change the software or use pieces of it in new 28 | free programs, and that you know you can do these things. 29 | 30 | To protect your rights, we need to prevent others from denying you 31 | these rights or asking you to surrender the rights. Therefore, you have 32 | certain responsibilities if you distribute copies of the software, or if 33 | you modify it: responsibilities to respect the freedom of others. 34 | 35 | For example, if you distribute copies of such a program, whether 36 | gratis or for a fee, you must pass on to the recipients the same 37 | freedoms that you received. You must make sure that they, too, receive 38 | or can get the source code. And you must show them these terms so they 39 | know their rights. 40 | 41 | Developers that use the GNU GPL protect your rights with two steps: 42 | (1) assert copyright on the software, and (2) offer you this License 43 | giving you legal permission to copy, distribute and/or modify it. 44 | 45 | For the developers' and authors' protection, the GPL clearly explains 46 | that there is no warranty for this free software. For both users' and 47 | authors' sake, the GPL requires that modified versions be marked as 48 | changed, so that their problems will not be attributed erroneously to 49 | authors of previous versions. 50 | 51 | Some devices are designed to deny users access to install or run 52 | modified versions of the software inside them, although the manufacturer 53 | can do so. This is fundamentally incompatible with the aim of 54 | protecting users' freedom to change the software. The systematic 55 | pattern of such abuse occurs in the area of products for individuals to 56 | use, which is precisely where it is most unacceptable. Therefore, we 57 | have designed this version of the GPL to prohibit the practice for those 58 | products. If such problems arise substantially in other domains, we 59 | stand ready to extend this provision to those domains in future versions 60 | of the GPL, as needed to protect the freedom of users. 61 | 62 | Finally, every program is threatened constantly by software patents. 63 | States should not allow patents to restrict development and use of 64 | software on general-purpose computers, but in those that do, we wish to 65 | avoid the special danger that patents applied to a free program could 66 | make it effectively proprietary. To prevent this, the GPL assures that 67 | patents cannot be used to render the program non-free. 68 | 69 | The precise terms and conditions for copying, distribution and 70 | modification follow. 71 | 72 | TERMS AND CONDITIONS 73 | 74 | 0. Definitions. 75 | 76 | "This License" refers to version 3 of the GNU General Public License. 77 | 78 | "Copyright" also means copyright-like laws that apply to other kinds of 79 | works, such as semiconductor masks. 80 | 81 | "The Program" refers to any copyrightable work licensed under this 82 | License. Each licensee is addressed as "you". "Licensees" and 83 | "recipients" may be individuals or organizations. 84 | 85 | To "modify" a work means to copy from or adapt all or part of the work 86 | in a fashion requiring copyright permission, other than the making of an 87 | exact copy. The resulting work is called a "modified version" of the 88 | earlier work or a work "based on" the earlier work. 89 | 90 | A "covered work" means either the unmodified Program or a work based 91 | on the Program. 92 | 93 | To "propagate" a work means to do anything with it that, without 94 | permission, would make you directly or secondarily liable for 95 | infringement under applicable copyright law, except executing it on a 96 | computer or modifying a private copy. Propagation includes copying, 97 | distribution (with or without modification), making available to the 98 | public, and in some countries other activities as well. 99 | 100 | To "convey" a work means any kind of propagation that enables other 101 | parties to make or receive copies. Mere interaction with a user through 102 | a computer network, with no transfer of a copy, is not conveying. 103 | 104 | An interactive user interface displays "Appropriate Legal Notices" 105 | to the extent that it includes a convenient and prominently visible 106 | feature that (1) displays an appropriate copyright notice, and (2) 107 | tells the user that there is no warranty for the work (except to the 108 | extent that warranties are provided), that licensees may convey the 109 | work under this License, and how to view a copy of this License. If 110 | the interface presents a list of user commands or options, such as a 111 | menu, a prominent item in the list meets this criterion. 112 | 113 | 1. Source Code. 114 | 115 | The "source code" for a work means the preferred form of the work 116 | for making modifications to it. "Object code" means any non-source 117 | form of a work. 118 | 119 | A "Standard Interface" means an interface that either is an official 120 | standard defined by a recognized standards body, or, in the case of 121 | interfaces specified for a particular programming language, one that 122 | is widely used among developers working in that language. 123 | 124 | The "System Libraries" of an executable work include anything, other 125 | than the work as a whole, that (a) is included in the normal form of 126 | packaging a Major Component, but which is not part of that Major 127 | Component, and (b) serves only to enable use of the work with that 128 | Major Component, or to implement a Standard Interface for which an 129 | implementation is available to the public in source code form. A 130 | "Major Component", in this context, means a major essential component 131 | (kernel, window system, and so on) of the specific operating system 132 | (if any) on which the executable work runs, or a compiler used to 133 | produce the work, or an object code interpreter used to run it. 134 | 135 | The "Corresponding Source" for a work in object code form means all 136 | the source code needed to generate, install, and (for an executable 137 | work) run the object code and to modify the work, including scripts to 138 | control those activities. However, it does not include the work's 139 | System Libraries, or general-purpose tools or generally available free 140 | programs which are used unmodified in performing those activities but 141 | which are not part of the work. For example, Corresponding Source 142 | includes interface definition files associated with source files for 143 | the work, and the source code for shared libraries and dynamically 144 | linked subprograms that the work is specifically designed to require, 145 | such as by intimate data communication or control flow between those 146 | subprograms and other parts of the work. 147 | 148 | The Corresponding Source need not include anything that users 149 | can regenerate automatically from other parts of the Corresponding 150 | Source. 151 | 152 | The Corresponding Source for a work in source code form is that 153 | same work. 154 | 155 | 2. Basic Permissions. 156 | 157 | All rights granted under this License are granted for the term of 158 | copyright on the Program, and are irrevocable provided the stated 159 | conditions are met. This License explicitly affirms your unlimited 160 | permission to run the unmodified Program. The output from running a 161 | covered work is covered by this License only if the output, given its 162 | content, constitutes a covered work. This License acknowledges your 163 | rights of fair use or other equivalent, as provided by copyright law. 164 | 165 | You may make, run and propagate covered works that you do not 166 | convey, without conditions so long as your license otherwise remains 167 | in force. You may convey covered works to others for the sole purpose 168 | of having them make modifications exclusively for you, or provide you 169 | with facilities for running those works, provided that you comply with 170 | the terms of this License in conveying all material for which you do 171 | not control copyright. Those thus making or running the covered works 172 | for you must do so exclusively on your behalf, under your direction 173 | and control, on terms that prohibit them from making any copies of 174 | your copyrighted material outside their relationship with you. 175 | 176 | Conveying under any other circumstances is permitted solely under 177 | the conditions stated below. Sublicensing is not allowed; section 10 178 | makes it unnecessary. 179 | 180 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 181 | 182 | No covered work shall be deemed part of an effective technological 183 | measure under any applicable law fulfilling obligations under article 184 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 185 | similar laws prohibiting or restricting circumvention of such 186 | measures. 187 | 188 | When you convey a covered work, you waive any legal power to forbid 189 | circumvention of technological measures to the extent such circumvention 190 | is effected by exercising rights under this License with respect to 191 | the covered work, and you disclaim any intention to limit operation or 192 | modification of the work as a means of enforcing, against the work's 193 | users, your or third parties' legal rights to forbid circumvention of 194 | technological measures. 195 | 196 | 4. Conveying Verbatim Copies. 197 | 198 | You may convey verbatim copies of the Program's source code as you 199 | receive it, in any medium, provided that you conspicuously and 200 | appropriately publish on each copy an appropriate copyright notice; 201 | keep intact all notices stating that this License and any 202 | non-permissive terms added in accord with section 7 apply to the code; 203 | keep intact all notices of the absence of any warranty; and give all 204 | recipients a copy of this License along with the Program. 205 | 206 | You may charge any price or no price for each copy that you convey, 207 | and you may offer support or warranty protection for a fee. 208 | 209 | 5. Conveying Modified Source Versions. 210 | 211 | You may convey a work based on the Program, or the modifications to 212 | produce it from the Program, in the form of source code under the 213 | terms of section 4, provided that you also meet all of these conditions: 214 | 215 | a) The work must carry prominent notices stating that you modified 216 | it, and giving a relevant date. 217 | 218 | b) The work must carry prominent notices stating that it is 219 | released under this License and any conditions added under section 220 | 7. This requirement modifies the requirement in section 4 to 221 | "keep intact all notices". 222 | 223 | c) You must license the entire work, as a whole, under this 224 | License to anyone who comes into possession of a copy. This 225 | License will therefore apply, along with any applicable section 7 226 | additional terms, to the whole of the work, and all its parts, 227 | regardless of how they are packaged. This License gives no 228 | permission to license the work in any other way, but it does not 229 | invalidate such permission if you have separately received it. 230 | 231 | d) If the work has interactive user interfaces, each must display 232 | Appropriate Legal Notices; however, if the Program has interactive 233 | interfaces that do not display Appropriate Legal Notices, your 234 | work need not make them do so. 235 | 236 | A compilation of a covered work with other separate and independent 237 | works, which are not by their nature extensions of the covered work, 238 | and which are not combined with it such as to form a larger program, 239 | in or on a volume of a storage or distribution medium, is called an 240 | "aggregate" if the compilation and its resulting copyright are not 241 | used to limit the access or legal rights of the compilation's users 242 | beyond what the individual works permit. Inclusion of a covered work 243 | in an aggregate does not cause this License to apply to the other 244 | parts of the aggregate. 245 | 246 | 6. Conveying Non-Source Forms. 247 | 248 | You may convey a covered work in object code form under the terms 249 | of sections 4 and 5, provided that you also convey the 250 | machine-readable Corresponding Source under the terms of this License, 251 | in one of these ways: 252 | 253 | a) Convey the object code in, or embodied in, a physical product 254 | (including a physical distribution medium), accompanied by the 255 | Corresponding Source fixed on a durable physical medium 256 | customarily used for software interchange. 257 | 258 | b) Convey the object code in, or embodied in, a physical product 259 | (including a physical distribution medium), accompanied by a 260 | written offer, valid for at least three years and valid for as 261 | long as you offer spare parts or customer support for that product 262 | model, to give anyone who possesses the object code either (1) a 263 | copy of the Corresponding Source for all the software in the 264 | product that is covered by this License, on a durable physical 265 | medium customarily used for software interchange, for a price no 266 | more than your reasonable cost of physically performing this 267 | conveying of source, or (2) access to copy the 268 | Corresponding Source from a network server at no charge. 269 | 270 | c) Convey individual copies of the object code with a copy of the 271 | written offer to provide the Corresponding Source. This 272 | alternative is allowed only occasionally and noncommercially, and 273 | only if you received the object code with such an offer, in accord 274 | with subsection 6b. 275 | 276 | d) Convey the object code by offering access from a designated 277 | place (gratis or for a charge), and offer equivalent access to the 278 | Corresponding Source in the same way through the same place at no 279 | further charge. You need not require recipients to copy the 280 | Corresponding Source along with the object code. If the place to 281 | copy the object code is a network server, the Corresponding Source 282 | may be on a different server (operated by you or a third party) 283 | that supports equivalent copying facilities, provided you maintain 284 | clear directions next to the object code saying where to find the 285 | Corresponding Source. Regardless of what server hosts the 286 | Corresponding Source, you remain obligated to ensure that it is 287 | available for as long as needed to satisfy these requirements. 288 | 289 | e) Convey the object code using peer-to-peer transmission, provided 290 | you inform other peers where the object code and Corresponding 291 | Source of the work are being offered to the general public at no 292 | charge under subsection 6d. 293 | 294 | A separable portion of the object code, whose source code is excluded 295 | from the Corresponding Source as a System Library, need not be 296 | included in conveying the object code work. 297 | 298 | A "User Product" is either (1) a "consumer product", which means any 299 | tangible personal property which is normally used for personal, family, 300 | or household purposes, or (2) anything designed or sold for incorporation 301 | into a dwelling. In determining whether a product is a consumer product, 302 | doubtful cases shall be resolved in favor of coverage. For a particular 303 | product received by a particular user, "normally used" refers to a 304 | typical or common use of that class of product, regardless of the status 305 | of the particular user or of the way in which the particular user 306 | actually uses, or expects or is expected to use, the product. A product 307 | is a consumer product regardless of whether the product has substantial 308 | commercial, industrial or non-consumer uses, unless such uses represent 309 | the only significant mode of use of the product. 310 | 311 | "Installation Information" for a User Product means any methods, 312 | procedures, authorization keys, or other information required to install 313 | and execute modified versions of a covered work in that User Product from 314 | a modified version of its Corresponding Source. The information must 315 | suffice to ensure that the continued functioning of the modified object 316 | code is in no case prevented or interfered with solely because 317 | modification has been made. 318 | 319 | If you convey an object code work under this section in, or with, or 320 | specifically for use in, a User Product, and the conveying occurs as 321 | part of a transaction in which the right of possession and use of the 322 | User Product is transferred to the recipient in perpetuity or for a 323 | fixed term (regardless of how the transaction is characterized), the 324 | Corresponding Source conveyed under this section must be accompanied 325 | by the Installation Information. But this requirement does not apply 326 | if neither you nor any third party retains the ability to install 327 | modified object code on the User Product (for example, the work has 328 | been installed in ROM). 329 | 330 | The requirement to provide Installation Information does not include a 331 | requirement to continue to provide support service, warranty, or updates 332 | for a work that has been modified or installed by the recipient, or for 333 | the User Product in which it has been modified or installed. Access to a 334 | network may be denied when the modification itself materially and 335 | adversely affects the operation of the network or violates the rules and 336 | protocols for communication across the network. 337 | 338 | Corresponding Source conveyed, and Installation Information provided, 339 | in accord with this section must be in a format that is publicly 340 | documented (and with an implementation available to the public in 341 | source code form), and must require no special password or key for 342 | unpacking, reading or copying. 343 | 344 | 7. Additional Terms. 345 | 346 | "Additional permissions" are terms that supplement the terms of this 347 | License by making exceptions from one or more of its conditions. 348 | Additional permissions that are applicable to the entire Program shall 349 | be treated as though they were included in this License, to the extent 350 | that they are valid under applicable law. If additional permissions 351 | apply only to part of the Program, that part may be used separately 352 | under those permissions, but the entire Program remains governed by 353 | this License without regard to the additional permissions. 354 | 355 | When you convey a copy of a covered work, you may at your option 356 | remove any additional permissions from that copy, or from any part of 357 | it. (Additional permissions may be written to require their own 358 | removal in certain cases when you modify the work.) You may place 359 | additional permissions on material, added by you to a covered work, 360 | for which you have or can give appropriate copyright permission. 361 | 362 | Notwithstanding any other provision of this License, for material you 363 | add to a covered work, you may (if authorized by the copyright holders of 364 | that material) supplement the terms of this License with terms: 365 | 366 | a) Disclaiming warranty or limiting liability differently from the 367 | terms of sections 15 and 16 of this License; or 368 | 369 | b) Requiring preservation of specified reasonable legal notices or 370 | author attributions in that material or in the Appropriate Legal 371 | Notices displayed by works containing it; or 372 | 373 | c) Prohibiting misrepresentation of the origin of that material, or 374 | requiring that modified versions of such material be marked in 375 | reasonable ways as different from the original version; or 376 | 377 | d) Limiting the use for publicity purposes of names of licensors or 378 | authors of the material; or 379 | 380 | e) Declining to grant rights under trademark law for use of some 381 | trade names, trademarks, or service marks; or 382 | 383 | f) Requiring indemnification of licensors and authors of that 384 | material by anyone who conveys the material (or modified versions of 385 | it) with contractual assumptions of liability to the recipient, for 386 | any liability that these contractual assumptions directly impose on 387 | those licensors and authors. 388 | 389 | All other non-permissive additional terms are considered "further 390 | restrictions" within the meaning of section 10. If the Program as you 391 | received it, or any part of it, contains a notice stating that it is 392 | governed by this License along with a term that is a further 393 | restriction, you may remove that term. If a license document contains 394 | a further restriction but permits relicensing or conveying under this 395 | License, you may add to a covered work material governed by the terms 396 | of that license document, provided that the further restriction does 397 | not survive such relicensing or conveying. 398 | 399 | If you add terms to a covered work in accord with this section, you 400 | must place, in the relevant source files, a statement of the 401 | additional terms that apply to those files, or a notice indicating 402 | where to find the applicable terms. 403 | 404 | Additional terms, permissive or non-permissive, may be stated in the 405 | form of a separately written license, or stated as exceptions; 406 | the above requirements apply either way. 407 | 408 | 8. Termination. 409 | 410 | You may not propagate or modify a covered work except as expressly 411 | provided under this License. Any attempt otherwise to propagate or 412 | modify it is void, and will automatically terminate your rights under 413 | this License (including any patent licenses granted under the third 414 | paragraph of section 11). 415 | 416 | However, if you cease all violation of this License, then your 417 | license from a particular copyright holder is reinstated (a) 418 | provisionally, unless and until the copyright holder explicitly and 419 | finally terminates your license, and (b) permanently, if the copyright 420 | holder fails to notify you of the violation by some reasonable means 421 | prior to 60 days after the cessation. 422 | 423 | Moreover, your license from a particular copyright holder is 424 | reinstated permanently if the copyright holder notifies you of the 425 | violation by some reasonable means, this is the first time you have 426 | received notice of violation of this License (for any work) from that 427 | copyright holder, and you cure the violation prior to 30 days after 428 | your receipt of the notice. 429 | 430 | Termination of your rights under this section does not terminate the 431 | licenses of parties who have received copies or rights from you under 432 | this License. If your rights have been terminated and not permanently 433 | reinstated, you do not qualify to receive new licenses for the same 434 | material under section 10. 435 | 436 | 9. Acceptance Not Required for Having Copies. 437 | 438 | You are not required to accept this License in order to receive or 439 | run a copy of the Program. Ancillary propagation of a covered work 440 | occurring solely as a consequence of using peer-to-peer transmission 441 | to receive a copy likewise does not require acceptance. However, 442 | nothing other than this License grants you permission to propagate or 443 | modify any covered work. These actions infringe copyright if you do 444 | not accept this License. Therefore, by modifying or propagating a 445 | covered work, you indicate your acceptance of this License to do so. 446 | 447 | 10. Automatic Licensing of Downstream Recipients. 448 | 449 | Each time you convey a covered work, the recipient automatically 450 | receives a license from the original licensors, to run, modify and 451 | propagate that work, subject to this License. You are not responsible 452 | for enforcing compliance by third parties with this License. 453 | 454 | An "entity transaction" is a transaction transferring control of an 455 | organization, or substantially all assets of one, or subdividing an 456 | organization, or merging organizations. If propagation of a covered 457 | work results from an entity transaction, each party to that 458 | transaction who receives a copy of the work also receives whatever 459 | licenses to the work the party's predecessor in interest had or could 460 | give under the previous paragraph, plus a right to possession of the 461 | Corresponding Source of the work from the predecessor in interest, if 462 | the predecessor has it or can get it with reasonable efforts. 463 | 464 | You may not impose any further restrictions on the exercise of the 465 | rights granted or affirmed under this License. For example, you may 466 | not impose a license fee, royalty, or other charge for exercise of 467 | rights granted under this License, and you may not initiate litigation 468 | (including a cross-claim or counterclaim in a lawsuit) alleging that 469 | any patent claim is infringed by making, using, selling, offering for 470 | sale, or importing the Program or any portion of it. 471 | 472 | 11. Patents. 473 | 474 | A "contributor" is a copyright holder who authorizes use under this 475 | License of the Program or a work on which the Program is based. The 476 | work thus licensed is called the contributor's "contributor version". 477 | 478 | A contributor's "essential patent claims" are all patent claims 479 | owned or controlled by the contributor, whether already acquired or 480 | hereafter acquired, that would be infringed by some manner, permitted 481 | by this License, of making, using, or selling its contributor version, 482 | but do not include claims that would be infringed only as a 483 | consequence of further modification of the contributor version. For 484 | purposes of this definition, "control" includes the right to grant 485 | patent sublicenses in a manner consistent with the requirements of 486 | this License. 487 | 488 | Each contributor grants you a non-exclusive, worldwide, royalty-free 489 | patent license under the contributor's essential patent claims, to 490 | make, use, sell, offer for sale, import and otherwise run, modify and 491 | propagate the contents of its contributor version. 492 | 493 | In the following three paragraphs, a "patent license" is any express 494 | agreement or commitment, however denominated, not to enforce a patent 495 | (such as an express permission to practice a patent or covenant not to 496 | sue for patent infringement). To "grant" such a patent license to a 497 | party means to make such an agreement or commitment not to enforce a 498 | patent against the party. 499 | 500 | If you convey a covered work, knowingly relying on a patent license, 501 | and the Corresponding Source of the work is not available for anyone 502 | to copy, free of charge and under the terms of this License, through a 503 | publicly available network server or other readily accessible means, 504 | then you must either (1) cause the Corresponding Source to be so 505 | available, or (2) arrange to deprive yourself of the benefit of the 506 | patent license for this particular work, or (3) arrange, in a manner 507 | consistent with the requirements of this License, to extend the patent 508 | license to downstream recipients. "Knowingly relying" means you have 509 | actual knowledge that, but for the patent license, your conveying the 510 | covered work in a country, or your recipient's use of the covered work 511 | in a country, would infringe one or more identifiable patents in that 512 | country that you have reason to believe are valid. 513 | 514 | If, pursuant to or in connection with a single transaction or 515 | arrangement, you convey, or propagate by procuring conveyance of, a 516 | covered work, and grant a patent license to some of the parties 517 | receiving the covered work authorizing them to use, propagate, modify 518 | or convey a specific copy of the covered work, then the patent license 519 | you grant is automatically extended to all recipients of the covered 520 | work and works based on it. 521 | 522 | A patent license is "discriminatory" if it does not include within 523 | the scope of its coverage, prohibits the exercise of, or is 524 | conditioned on the non-exercise of one or more of the rights that are 525 | specifically granted under this License. You may not convey a covered 526 | work if you are a party to an arrangement with a third party that is 527 | in the business of distributing software, under which you make payment 528 | to the third party based on the extent of your activity of conveying 529 | the work, and under which the third party grants, to any of the 530 | parties who would receive the covered work from you, a discriminatory 531 | patent license (a) in connection with copies of the covered work 532 | conveyed by you (or copies made from those copies), or (b) primarily 533 | for and in connection with specific products or compilations that 534 | contain the covered work, unless you entered into that arrangement, 535 | or that patent license was granted, prior to 28 March 2007. 536 | 537 | Nothing in this License shall be construed as excluding or limiting 538 | any implied license or other defenses to infringement that may 539 | otherwise be available to you under applicable patent law. 540 | 541 | 12. No Surrender of Others' Freedom. 542 | 543 | If conditions are imposed on you (whether by court order, agreement or 544 | otherwise) that contradict the conditions of this License, they do not 545 | excuse you from the conditions of this License. If you cannot convey a 546 | covered work so as to satisfy simultaneously your obligations under this 547 | License and any other pertinent obligations, then as a consequence you may 548 | not convey it at all. For example, if you agree to terms that obligate you 549 | to collect a royalty for further conveying from those to whom you convey 550 | the Program, the only way you could satisfy both those terms and this 551 | License would be to refrain entirely from conveying the Program. 552 | 553 | 13. Use with the GNU Affero General Public License. 554 | 555 | Notwithstanding any other provision of this License, you have 556 | permission to link or combine any covered work with a work licensed 557 | under version 3 of the GNU Affero General Public License into a single 558 | combined work, and to convey the resulting work. The terms of this 559 | License will continue to apply to the part which is the covered work, 560 | but the special requirements of the GNU Affero General Public License, 561 | section 13, concerning interaction through a network will apply to the 562 | combination as such. 563 | 564 | 14. Revised Versions of this License. 565 | 566 | The Free Software Foundation may publish revised and/or new versions of 567 | the GNU General Public License from time to time. Such new versions will 568 | be similar in spirit to the present version, but may differ in detail to 569 | address new problems or concerns. 570 | 571 | Each version is given a distinguishing version number. If the 572 | Program specifies that a certain numbered version of the GNU General 573 | Public License "or any later version" applies to it, you have the 574 | option of following the terms and conditions either of that numbered 575 | version or of any later version published by the Free Software 576 | Foundation. If the Program does not specify a version number of the 577 | GNU General Public License, you may choose any version ever published 578 | by the Free Software Foundation. 579 | 580 | If the Program specifies that a proxy can decide which future 581 | versions of the GNU General Public License can be used, that proxy's 582 | public statement of acceptance of a version permanently authorizes you 583 | to choose that version for the Program. 584 | 585 | Later license versions may give you additional or different 586 | permissions. However, no additional obligations are imposed on any 587 | author or copyright holder as a result of your choosing to follow a 588 | later version. 589 | 590 | 15. Disclaimer of Warranty. 591 | 592 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 593 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 594 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 595 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 596 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 597 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 598 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 599 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 600 | 601 | 16. Limitation of Liability. 602 | 603 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 604 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 605 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 606 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 607 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 608 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 609 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 610 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 611 | SUCH DAMAGES. 612 | 613 | 17. Interpretation of Sections 15 and 16. 614 | 615 | If the disclaimer of warranty and limitation of liability provided 616 | above cannot be given local legal effect according to their terms, 617 | reviewing courts shall apply local law that most closely approximates 618 | an absolute waiver of all civil liability in connection with the 619 | Program, unless a warranty or assumption of liability accompanies a 620 | copy of the Program in return for a fee. 621 | 622 | END OF TERMS AND CONDITIONS 623 | 624 | How to Apply These Terms to Your New Programs 625 | 626 | If you develop a new program, and you want it to be of the greatest 627 | possible use to the public, the best way to achieve this is to make it 628 | free software which everyone can redistribute and change under these terms. 629 | 630 | To do so, attach the following notices to the program. It is safest 631 | to attach them to the start of each source file to most effectively 632 | state the exclusion of warranty; and each file should have at least 633 | the "copyright" line and a pointer to where the full notice is found. 634 | 635 | 636 | Copyright (C) 637 | 638 | This program is free software: you can redistribute it and/or modify 639 | it under the terms of the GNU General Public License as published by 640 | the Free Software Foundation, either version 3 of the License, or 641 | (at your option) any later version. 642 | 643 | This program is distributed in the hope that it will be useful, 644 | but WITHOUT ANY WARRANTY; without even the implied warranty of 645 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 646 | GNU General Public License for more details. 647 | 648 | You should have received a copy of the GNU General Public License 649 | along with this program. If not, see . 650 | 651 | Also add information on how to contact you by electronic and paper mail. 652 | 653 | If the program does terminal interaction, make it output a short 654 | notice like this when it starts in an interactive mode: 655 | 656 | Copyright (C) 657 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 658 | This is free software, and you are welcome to redistribute it 659 | under certain conditions; type `show c' for details. 660 | 661 | The hypothetical commands `show w' and `show c' should show the appropriate 662 | parts of the General Public License. Of course, your program's commands 663 | might be different; for a GUI interface, you would use an "about box". 664 | 665 | You should also get your employer (if you work as a programmer) or school, 666 | if any, to sign a "copyright disclaimer" for the program, if necessary. 667 | For more information on this, and how to apply and follow the GNU GPL, see 668 | . 669 | 670 | The GNU General Public License does not permit incorporating your program 671 | into proprietary programs. If your program is a subroutine library, you 672 | may consider it more useful to permit linking proprietary applications with 673 | the library. If this is what you want to do, use the GNU Lesser General 674 | Public License instead of this License. But first, please read 675 | . 676 | 677 | --------------------------------------------------------------------------------