📄 ec_inet_bsd.c
字号:
/* ettercap -- inet utilities -- Module for FreeBSD 4.x OpenBSD 2.[789] NetBSD 1.5 Copyright (C) 2001 ALoR <alor@users.sourceforge.net>, NaGA <crwm@freemail.it> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. $Id: ec_inet_BSD.c,v 1.19 2002/06/12 16:19:35 alor Exp $*/#include "../../include/ec_main.h"#include "../../include/ec_inet.h"#include "../../include/ec_thread.h"#include "../../include/ec_buffer.h"#include "../../include/ec_inet_forge.h"#include "../../include/ec_inet_structures.h"#include <ctype.h>#include <sys/ioctl.h>#include <fcntl.h>#include <sys/sysctl.h>#include <sys/param.h>#include <sys/timeb.h>#include <sys/file.h>#include <sys/ioctl.h>#include <ctype.h>#include <sys/types.h>#include <sys/time.h>#include <net/bpf.h>#ifdef HAVE_IFADDRS_H #include <ifaddrs.h>#endif#include <sys/socket.h>#include <net/if_dl.h>#include <net/route.h>#include <net/if_types.h>#include <arpa/inet.h>#include <netinet/if_ether.h>#ifdef HAVE_NET_ETHERNET_H #include <net/ethernet.h>#endifint IpForward_status; // old ipforward statusint bpf_in_use;int size;int SocketBuffer = -1;static char ARP_BROADCAST[6] = {0x0,0x0,0x0,0x0,0x0,0x0};// protos...int Inet_FindIFace(char *iface);int Inet_CorrectIface(char *iface);int Inet_GetIfaceInfo(char *iface, int *MTU, char *MyMAC, u_long *IP, u_long *NetMask);int Inet_SetPromisc(char *iface);int Inet_OpenRawSock(char *iface);void Inet_CloseRawSock(int sock);int Inet_GetRawPacket(int sock, char *buffer, int MTU, short *type);int Inet_SendRawPacket(int sock, char *buffer, int len);void Inet_SetNonBlock(int sock);void Inet_Restore_ifr(void);void Inet_DisableForwarding(void);void Inet_RestoreForwarding(void);char *Inet_MacFromIP(unsigned long ip);#ifdef PERMIT_HTTPS void Inet_UnSetARPEntry(void); int Inet_SetARPEntry(unsigned long IP, char MAC[6]); void Inet_UnsetRoute(void); void Inet_SetRoute(void);#endif// ----------------------------------------------int Inet_FindIFace(char *iface){#ifdef HAVE_GETIFADDRS struct ifaddrs *ifalist, *ifa, *ifp = NULL; int minunit, n; char *cp; if (getifaddrs(&ifalist) != 0) ERROR_MSG("getifaddrs()"); minunit = 666; for (ifa = ifalist; ifa; ifa = ifa->ifa_next) { if ((ifa->ifa_flags & IFF_UP) == 0 || (ifa->ifa_flags & IFF_LOOPBACK) || (ifa->ifa_flags & IFF_POINTOPOINT)) continue; if ( !strncmp(ifa->ifa_name, "pflog", 5) ) continue; for (cp = ifa->ifa_name; !isdigit(*cp); ++cp) continue; n = atoi(cp); if (n < minunit) { minunit = n; ifp = ifa; } } if (ifp == NULL) // no device found { free(ifalist); return -1; } strlcpy(iface, ifp->ifa_name, sizeof(Options.netiface)); DEBUG_MSG("Inet_FindIFace -- %s found !!", iface); free(ifalist); return 0;#else // don't have getifaddrs// adapded from pcap_lookupdev int fd, minunit, n; char *cp; struct ifreq *ifrp, *ifend, *ifnext, *mp; struct ifconf ifc; char *buf; struct ifreq ifr; unsigned int buf_size; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) ERROR_MSG("socket()"); buf_size = 8192; for (;;) { buf = malloc (buf_size); if (buf == NULL) ERROR_MSG("malloc()"); ifc.ifc_len = buf_size; ifc.ifc_buf = buf; memset (buf, 0, buf_size); if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 && errno != EINVAL) ERROR_MSG("ioctl(SIOCGIFCONF)"); if (ifc.ifc_len < buf_size) break; free (buf); buf_size *= 2; } ifrp = (struct ifreq *)buf; ifend = (struct ifreq *)(buf + ifc.ifc_len); mp = NULL; minunit = 666; for (; ifrp < ifend; ifrp = ifnext) { const char *endcp;#ifdef HAVE_SOCKADDR_SA_LEN n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name); if (n < sizeof(*ifrp)) ifnext = ifrp + 1; else ifnext = (struct ifreq *)((char *)ifrp + n); if (ifrp->ifr_addr.sa_family != AF_INET) continue;#else ifnext = ifrp + 1;#endif strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { if (errno == ENXIO) continue; ERROR_MSG("ioctl(SIOCGIFFLAGS)"); } DEBUG_MSG("Inet_FindIFace -- check for [%s]", ifr.ifr_name); /* Must be up and not the loopback */ if ((ifr.ifr_flags & IFF_UP) == 0 || (ifr.ifr_flags & IFF_LOOPBACK) != 0 || !strncmp(ifr.ifr_name, "pflog", 5)) continue; endcp = ifrp->ifr_name + strlen(ifrp->ifr_name); for (cp = ifrp->ifr_name; cp < endcp && !isdigit(*cp); ++cp) continue; if (isdigit (*cp)) { n = atoi(cp); } else { n = 0; } if (n < minunit) { minunit = n; mp = ifrp; } } close(fd); if (mp == NULL) // no device found { free(buf); return -1; } strlcpy(iface, mp->ifr_name, sizeof(Options.netiface)); free(buf); DEBUG_MSG("Inet_FindIFace -- %s found !!", iface); return 0;#endif}int Inet_CorrectIface(char *iface){#ifdef HAVE_GETIFADDRS struct ifaddrs *ifalist, *ifa; DEBUG_MSG("Inet_CorrectIface -- %s ", iface); if (getifaddrs(&ifalist) != 0) ERROR_MSG(" getifaddrs()"); for (ifa = ifalist; ifa; ifa = ifa->ifa_next) { if ( (ifa->ifa_flags & IFF_UP) == 0 || (ifa->ifa_flags & IFF_LOOPBACK) != 0 || strcmp(iface, ifa->ifa_name) ) continue; free(ifalist); return 0; } // no iface found !! free(ifalist); return -1;#else // don't have getifaddrs int sock; struct ifreq ifr; DEBUG_MSG("Inet_CorrectIface\t\tIface: %s", iface); sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) ERROR_MSG("socket()"); memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); if ( ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) // check for iface { close(sock); return -1; } if (!(ifr.ifr_flags & IFF_UP )) // check for flag UP { close(sock); return -1; } if (ifr.ifr_flags & IFF_LOOPBACK ) // check for loopback { Options.normal = 1; Error_msg("Ettercap can't be run on loopback device"); } if ( ioctl(sock, SIOCGIFADDR, &ifr) < 0 ) // check for alias { close(sock); return -1; } close(sock); return 0;#endif}int Inet_GetIfaceInfo(char *iface, int *MTU, char *MyMAC, unsigned long *IP, unsigned long *NetMask){ int sock; struct ifreq ifr; sock = socket(PF_INET, SOCK_DGRAM, 0); memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); if (MTU != NULL) { if ( ioctl(sock, SIOCGIFMTU, &ifr) < 0) { DEBUG_MSG("Inet_GetIfaceInfo -- MTU FAILED... assuming 1500"); *MTU = 1500; } else //*MTU = ifr.ifr_ifru.ifru_mtu; *MTU = ifr.ifr_mtu; } if (MyMAC != NULL) { int mib[6]; size_t len; char *buf, *next, *end; struct if_msghdr *ifm; struct sockaddr_dl *sdl; mib[0] = CTL_NET; mib[1] = AF_ROUTE; mib[2] = 0; mib[3] = AF_LINK; mib[4] = NET_RT_IFLIST; mib[5] = 0; if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) ERROR_MSG("sysctl()"); if ((buf = (char *)malloc(len)) == NULL ) ERROR_MSG("malloc()"); if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) ERROR_MSG("sysctl()"); end = buf + len; for (next = buf ; next < end ; next += ifm->ifm_msglen) { ifm = (struct if_msghdr *)next; if (ifm->ifm_type == RTM_IFINFO) { sdl = (struct sockaddr_dl *)(ifm + 1); if (strncmp(&sdl->sdl_data[0], iface, sdl->sdl_nlen) == 0) { memcpy(MyMAC, LLADDR(sdl), ETHER_ADDR_LEN); break; } } } free(buf); } if (IP != NULL) { if ( ioctl(sock, SIOCGIFADDR, &ifr) < 0 ) ERROR_MSG("ioctl(SIOCGIFADDR)"); memcpy((char *)IP, ifr.ifr_addr.sa_data+2, 4); } if (NetMask != NULL) { if ( ioctl(sock, SIOCGIFNETMASK, &ifr) < 0 ) ERROR_MSG("ioctl(SIOCGIFNETMASK)"); memcpy((char *)NetMask, ifr.ifr_addr.sa_data+2, 4); if (strcmp(Options.netmask, "")) // specified on command line *NetMask = inet_addr(Options.netmask); } close(sock); return 0;}void Inet_SetNonBlock(int sock){ DEBUG_MSG("Inet_SetNonBlock fd = %d", sock); fcntl(sock, F_SETFL, O_NONBLOCK);}void Inet_CloseRawSock(int sock){ DEBUG_MSG("Inet_CloseRawSock \t wrappered to NULL"); //close(sock); // the bpf is close when ettercap exits}int Inet_OpenRawSock(char *iface){ int fd, i = 0, type; char device[sizeof "/dev/bpf0000"]; struct bpf_version bv; struct ifreq ifr; char MyMAC[6]; // this BPF will ignore all outgoing packets static struct bpf_insn insns[] = { BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 6), // load mac address [1][2] BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x00, 0, 4), // k is left 0x00 and will be set later... insns[1].k = htons(*(short *)MyMAC); BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 8), // load mac address [3][4] BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x00, 0, 2), // if equal check the third part, else jump 2 BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 10), // load mac address [5][6] BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x00, 1, 0), // if equal this is outgoing ! drop it ! BPF_STMT(BPF_RET|BPF_K, (u_int)-1), // no filter, passing the wole packet BPF_STMT(BPF_RET|BPF_K, 0), // ignore the packet }; static struct bpf_program filter = { sizeof insns / sizeof(insns[0]), insns };#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) u_int spoof_eth_src = 1;#endif if (bpf_in_use != 0) { DEBUG_MSG("Inet_OpenRawSock %s", iface); DEBUG_MSG("Inet_OpenRawSock \t bpf_in_use = %d ", bpf_in_use); return bpf_in_use; } Inet_GetIfaceInfo(iface, NULL, MyMAC, NULL, NULL); insns[1].k = htons(*(short *)MyMAC); // put MyMac in the filter... insns[3].k = htons(*(short *)(MyMAC+2)); insns[5].k = htons(*(short *)(MyMAC+4)); DEBUG_MSG("Inet_OpenRawSock %s", iface); do // find an available bpf device { sprintf(device, "/dev/bpf%d", i++); fd = open(device, O_RDWR); } while (fd < 0 && errno == EBUSY); if (fd < 0) Error_msg("ec_inet_bsd:%d no /dev/bpf* available (tried to open %d) | ERRNO : %d | %s", __LINE__, i, errno, strerror(errno)); DEBUG_MSG("Inet_OpenRawSock \t fd = %d -- /dev/bpf%d ", fd, i-1); if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) // get bpf version ERROR_MSG(" ioctl(BIOCVERSION)"); if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION) Error_msg(" Kernel bpf filter out of date "); for (size = 32768; size != 0; size >>= 1) { ioctl(fd, BIOCSBLEN, (caddr_t)&size); strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); // attach the iface to the bpf if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0) break; /* that size worked; we're done */ if (errno != ENOBUFS) ERROR_MSG(" ioctl(BIOCSETIF)"); } if (size == 0) Error_msg("BIOCSBLEN: No buffer size worked"); if (ioctl(fd, BIOCGBLEN, (caddr_t)&size) < 0) ERROR_MSG(" ioctl(BIOCGBLEN)"); if (ioctl(fd, BIOCGDLT, (caddr_t)&type) == -1) // Get the data link layer type. ERROR_MSG(" ioctl(BIOCGDLT)"); if (type != DLT_EN10MB) Error_msg("%s : Interface not supported ( only DLT_EN10MB) | %d", iface, type);#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT) // auto fill the source mac address now set to OFF if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) ERROR_MSG(" ioctl(BIOCSHDRCMPLT)");#endif i = 1; if (ioctl(fd, BIOCIMMEDIATE, &i) < 0) // Set immediate mode so packets are processed as they arrive. ERROR_MSG(" ioctl(BIOCIMMEDIATE)"); if (ioctl(fd, BIOCSETF, (caddr_t)&filter) < 0) // Set filter program. ERROR_MSG(" ioctl(BIOCSETF)"); bpf_in_use = fd; return fd;}int Inet_GetRawPacket(int sock, char *buffer, int MTU, short *type){ int len = 0, pktlen = 0; u_char *buf, *bp, *ep; static char MyMAC[6]={0x65,0x74,0x74,0x65,0x72,0x63}; if (SocketBuffer == -1) // only the first time { SocketBuffer = Buffer_Create(1.0e5); // 100 K buffer DEBUG_MSG("Inet_GetRawPacket creates the buffer for the first time -- buf id = %d", SocketBuffer); } Buffer_Get(SocketBuffer, &pktlen, sizeof(u_int)); len = Buffer_Get(SocketBuffer, buffer, pktlen ); if (type != NULL) { if (!strncmp(MyMAC,"etterc",6)) // only the first time... Inet_GetIfaceInfo(Options.netiface, NULL, MyMAC, NULL, NULL); if (!memcmp(MyMAC,buffer,6)) *type = PACKET_HOST; else *type = !PACKET_HOST; } if (len > 0) return len; // there was pending fata. buf = (char *)calloc(size, sizeof(char)); // size is global and set by BIOCGBLEN len = read(sock, buf, size);#define bhp ((struct bpf_hdr *)bp) // Loop through the packet(s) bp = buf; ep = bp + len; while (bp < ep) { u_int caplen, hdrlen; caplen = bhp->bh_caplen; hdrlen = bhp->bh_hdrlen;// // bp + hdrlen is my packet// // caplen is the length Buffer_Put(SocketBuffer, &caplen, sizeof(u_int) ); Buffer_Put(SocketBuffer, bp + hdrlen, caplen ); bp += BPF_WORDALIGN(hdrlen + caplen); }#undef bhp Buffer_Get(SocketBuffer, &pktlen, sizeof(u_int)); len = Buffer_Get(SocketBuffer, buffer, pktlen ); if (type != NULL) { if (!memcmp(MyMAC,buffer,6)) *type = PACKET_HOST; else *type = !PACKET_HOST; } free(buf); return len;}int Inet_SendRawPacket(int sock, char *buffer, int len){ int sent; sent = write(sock, buffer, len); if (sent < len) { while (errno == ENOBUFS) { usleep(5000); sent = write(sock, buffer, len); if (sent == len) return (sent); } Error_msg("ec_inet_bsd:%d write() %d(%d) | ERRNO : %d | %s \n", __LINE__, len, sent, errno, strerror(errno)); } return (sent);}int Inet_SetPromisc(char *iface){ DEBUG_MSG("Inet_SetPromisc %s %d", iface, bpf_in_use); if ( ioctl(bpf_in_use, BIOCPROMISC, NULL) < 0 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -