📄 ec_inet_solaris.c
字号:
/* ettercap -- inet utilities -- Module for SunOS (solaris) 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_solaris.c,v 1.28 2002/05/13 20:57:46 alor Exp $*/#include "../../include/ec_main.h"#include "../../include/ec_thread.h"#include "../../include/ec_buffer.h"#include "../../include/ec_inet.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/ioctl.h>#include <sys/sockio.h>#include <sys/types.h>#include <sys/time.h>#ifdef HAVE_SYS_BUFMOD_H#include <sys/bufmod.h>#endif#include <sys/dlpi.h>#ifdef HAVE_SYS_DLPI_EXT_H#include <sys/dlpi_ext.h>#endif#include <sys/stream.h>#ifdef HAVE_SYS_BUFMOD_H#include <sys/systeminfo.h>#endif#include <sys/stropts.h>#include <inet/nd.h>#include <inet/common.h>#include <ctype.h>#include <errno.h>#include <fcntl.h>#include <memory.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stropts.h>#include <unistd.h>struct ether_addr{ u_char ether_addr_octet[6];};#ifndef DLPI_DEV_PREFIX#define DLPI_DEV_PREFIX "/dev"#endif#define MAXDLBUF 8192char IpForward_status[2]; // old ipforward statusstatic u_int ctlbuf[MAXDLBUF];static struct strbuf ctl = { MAXDLBUF, 0, (char *)ctlbuf};char ebuf[100];int bufsize, offset;int SocketBuffer = -1;int dlpi_in_use;static char ETH_BROADCAST[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};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);/* protos... */static int dlattachreq(int, u_int, char *);static int dlbindack(int, char *, char *);static int dlbindreq(int, u_int, char *);static int dlinfoack(int, char *, char *);static int dlinforeq(int, char *);static int dlokack(int, const char *, char *, char *);static int send_request(int, char *, int, char *, char *);static int recv_ack(int, int, const char *, char *, char *);static int dlpromisconreq(int, u_int, char *);#if defined(SOLARIS) && defined(HAVE_SYS_BUFMOD_H)static char *get_release(u_int *, u_int *, u_int *);#endif#ifdef HAVE_SYS_BUFMOD_Hstatic int strioctl(int, int, int, char *);#endif#ifdef HAVE_DEV_DLPIstatic int get_dlpi_ppa(int, const char *, int, char *);#endifstatic char * split_dname(char *device, int *unitp);// ==============================================int Inet_FindIFace(char *iface) // 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) continue; endcp = ifrp->ifr_name + strlen(ifrp->ifr_name); for (cp = ifrp->ifr_name; cp < endcp && !isdigit((int)*cp); ++cp) continue; if (isdigit ((int)*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;}int Inet_CorrectIface(char *iface){ 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;}int Inet_GetIfaceInfo(char *iface, int *MTU, char *MyMAC, unsigned long *IP, unsigned long *NetMask){ int sock, dlpi; struct ifreq ifr; sock = socket(PF_INET, SOCK_DGRAM, 0); dlpi = Inet_OpenRawSock(iface); 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// FIXME //*MTU = ifr.ifr_mtu; *MTU = 1500; } if (MyMAC != NULL) { char buf[2048]; union DL_primitives *dlp; dlp = (union DL_primitives*) buf; dlp->physaddr_req.dl_primitive = DL_PHYS_ADDR_REQ; dlp->physaddr_req.dl_addr_type = DL_CURR_PHYS_ADDR; if (send_request(dlpi, (char *)dlp, DL_PHYS_ADDR_REQ_SIZE, "physaddr", ebuf) < 0) Error_msg("send_request(DL_PHYS_ADDR_REQ_SIZE) | %s \n", ebuf); if (recv_ack(dlpi, DL_PHYS_ADDR_ACK_SIZE, "physaddr", (char *)dlp, ebuf) < 0) Error_msg("recv_ack(DL_PHYS_ADDR_ACK_SIZE) | %s \n", ebuf); memcpy( MyMAC,(struct ether_addr *) ((char *) dlp + dlp->physaddr_ack.dl_addr_offset), ETHER_ADDR_LEN); Inet_CloseRawSock(dlpi); } 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 \t WRAPPERED TO NULL");}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) // adapted from libpcap source code{ register char *cp; int fd; int ppa; register dl_info_ack_t *infop; struct timeval to;#ifdef HAVE_SYS_BUFMOD_H u_int32 flag, ss; char *release; u_int osmajor, osminor, osmicro;#endif u_long buf[MAXDLBUF]; char dname[100];#ifndef HAVE_DEV_DLPI char dname2[100];#endif if (dlpi_in_use != 0) { DEBUG_MSG("Inet_OpenRawSock %s", iface); DEBUG_MSG("Inet_OpenRawSock \t dlpi_in_use = %d ", dlpi_in_use); return dlpi_in_use; }#ifdef HAVE_DEV_DLPI /* ** Remove any "/dev/" on the front of the device. */ cp = strrchr(iface, '/'); if (cp == NULL) cp = iface; else cp++; strlcpy(dname, cp, sizeof(dname)); DEBUG_MSG("Inet_OpenRawSock -- HAVE_DEV_DLPI [%s]", dname); /* * Split the name into a device type and a unit number. */ cp = split_dname(dname, &ppa); if (cp == NULL) Error_msg("ec_inet_solaris:%d HAVE_DEV_DLPI: %s missing or bad unit number\n", __LINE__, iface); *cp = '\0'; /* * Use "/dev/dlpi" as the device. */ cp = "/dev/dlpi"; if ((fd = open(cp, O_RDWR)) < 0) ERROR_MSG("open()"); /* * Get a table of all PPAs for that device, and search that * table for the specified device type name and unit number. */ ppa = get_dlpi_ppa(fd, dname, ppa, ebuf); if (ppa < 0) ERROR_MSG("get_dlpi_ppa()");#else /* ** Determine device and ppa */ cp = split_dname(iface, &ppa); if (cp == NULL) Error_msg("ec_inet_solaris:%d dlpi: %s missing or bad unit number\n", __LINE__, iface); if (*iface == '/') strlcpy(dname, iface, sizeof(dname)); else snprintf(dname, sizeof(dname), "%s/%s", DLPI_DEV_PREFIX, iface); strlcpy(dname2, dname, sizeof(dname2)); *(dname + strlen(dname) - strlen(cp)) = '\0'; DEBUG_MSG("Inet_OpenRawSock -- opening [%s]", dname); /* Try device without unit number */ if ((fd = open(dname, O_RDWR)) < 0) { if (errno != ENOENT) ERROR_MSG("open()"); DEBUG_MSG("Inet_OpenRawSock -- open(%s) failed... trying [%s]", dname, dname2); /* Try again with unit number */ if ((fd = open(dname2, O_RDWR)) < 0) ERROR_MSG("open()"); /* XXX Assume unit zero */ ppa = 0; }#endif /* ** Attach if "style 2" provider */ if (dlinforeq(fd, ebuf) < 0 || dlinfoack(fd, (char *)buf, ebuf) < 0) ERROR_MSG("dlinforeq() || dlinfoack()"); infop = &((union DL_primitives *)buf)->info_ack; if (infop->dl_provider_style == DL_STYLE2 && (dlattachreq(fd, ppa, ebuf) < 0 || dlokack(fd, "attach", (char *)buf, ebuf) < 0)) ERROR_MSG("dlattachreq()"); /* ** Bind */ if (dlbindreq(fd, 0, ebuf) < 0 || dlbindack(fd, (char *)buf, ebuf) < 0) ERROR_MSG("dlbindreq()"); if (dlpromisconreq(fd, DL_PROMISC_PHYS, ebuf) < 0 || dlokack(fd, "promisc_phys", (char *)buf, ebuf) < 0) ERROR_MSG("dlpromisconreq(DL_PROMISC_PHYS)"); if (dlpromisconreq(fd, DL_PROMISC_MULTI, ebuf) < 0 || dlokack(fd, "promisc_multi", (char *)buf, ebuf) < 0) DEBUG_MSG("WARNING: DL_PROMISC_MULTI failed (%s)", ebuf); if ( (dlpromisconreq(fd, DL_PROMISC_SAP, ebuf) < 0 || dlokack(fd, "promisc_sap", (char *)buf, ebuf) < 0)) ERROR_MSG("dlpromisconreq(DL_PROMISC_SAP)"); /* ** Determine link type */ if (dlinforeq(fd, ebuf) < 0 || dlinfoack(fd, (char *)buf, ebuf) < 0) ERROR_MSG("dlinforeq()"); infop = &((union DL_primitives *)buf)->info_ack; switch (infop->dl_mac_type) { case DL_CSMACD: case DL_ETHER: offset = 2; break; default: Error_msg("Interface not supported ( only DLT_EN10MB) | %d", infop->dl_mac_type); }#ifdef DLIOCRAW /* ** This is a non standard SunOS hack to get the ethernet header. */ if (strioctl(fd, DLIOCRAW, 0, NULL) < 0) ERROR_MSG("strioctl(DLIOCRAW)");#endif#ifdef HAVE_SYS_BUFMOD_H /* ** Another non standard call to get the data nicely buffered */ if (ioctl(fd, I_PUSH, "bufmod") != 0) ERROR_MSG("ioclt(I_PUSH)"); /* ** Now that the bufmod is pushed lets configure it. ** ** There is a bug in bufmod(7). When dealing with messages of ** less than snaplen size it strips data from the beginning not ** the end. ** ** This bug is supposed to be fixed in 5.3.2. Also, there is a ** patch available. Ask for bugid 1149065. */ ss = MAXDLBUF; release = get_release(&osmajor, &osminor, &osmicro); if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) && getenv("BUFMOD_FIXED") == NULL) { fprintf(stderr, "WARNING: bufmod is broken in SunOS %s; ignoring snaplen.\n", release); ss = 0; } if (ss > 0 && strioctl(fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) ERROR_MSG("strioctl(SBIOCSSNAP)"); /* ** Set up the bufmod flags */ if (strioctl(fd, SBIOCGFLAGS, sizeof(flag), (char *)&flag) < 0) ERROR_MSG("strioctl(SBIOCGFLAGS)"); flag |= SB_NO_DROPS; if (strioctl(fd, SBIOCSFLAGS, sizeof(flag), (char *)&flag) != 0) ERROR_MSG("strioctl(SBIOCSFLAGS)"); /* * Set the bufmod timeout */ to.tv_sec = 1 / 1000; to.tv_usec = (1 * 1000) % 1000000; if (strioctl(fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) ERROR_MSG("strioctl(SBIOCSTIME)");#endif /* ** As the last operation flush the read side. */ if (ioctl(fd, I_FLUSH, FLUSHR) != 0) ERROR_MSG("ioctl(I_FLUSH)"); bufsize = MAXDLBUF * sizeof(u_int32); // global var... DEBUG_MSG("Inet_OpenRawSock \t fd = %d", fd); dlpi_in_use = fd; // for later use in the Set_Promisc return (fd);}int Inet_GetRawPacket(int sock, char *buffer, int MTU, short *type){ register u_char *bp, *ep, *pk; #ifdef HAVE_SYS_BUFMOD_H register struct sb_hdr *sbp; #ifdef LBL_ALIGN struct sb_hdr sbhdr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -