ec_inet_BSD.c
上传用户:nilegod
上传日期:2007-01-08
资源大小:220k
文件大小:15k
源码类别:

网络截获/分析

开发平台:

C/C++

  1. /*
  2.     ettercap -- inet utilities -- Module for FreeBSD 4.x
  3.                                              OpenBSD 2.7
  4.     Copyright (C) 2001  ALoR <alor@users.sourceforge.net>, NaGA <crwm@freemail.it>
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.     You should have received a copy of the GNU General Public License
  14.     along with this program; if not, write to the Free Software
  15.     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  16. */
  17. // This file is included from ../ec_inet.c
  18. #include <sys/sysctl.h>
  19. #include <sys/param.h>
  20. #include <sys/timeb.h>
  21. #include <sys/file.h>
  22. #include <sys/ioctl.h>
  23. #include <ctype.h>
  24. #include <sys/types.h>
  25. #include <sys/time.h>
  26. #include <net/bpf.h>
  27. #ifdef HAVE_IFADDRS_H
  28. #include <ifaddrs.h>
  29. #endif
  30. #include <sys/socket.h>
  31. #include <net/if_dl.h>
  32. #include <net/route.h>
  33. #include <netinet/if_ether.h>
  34. #ifdef HAVE_NET_ETHERNET_H
  35.    #include <net/ethernet.h>
  36. #endif
  37. int fdprom;
  38. int size;
  39. int SocketBuffer = -1;
  40. int Inet_FindIFace(char *iface)
  41. {
  42.    struct ifaddrs *ifalist, *ifa, *ifp = NULL;
  43.    if (getifaddrs(&ifalist) != 0)
  44.       Error_msg("ec_inet_BSD:%d  getifaddrs() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  45.    for (ifa = ifalist; ifa; ifa = ifa->ifa_next)
  46.    {
  47.       if ((ifa->ifa_flags & IFF_UP) == 0 || (ifa->ifa_flags & IFF_LOOPBACK))
  48.          continue;
  49.       ifp = ifa;
  50.    }
  51.    if (ifp == NULL)  // no device found
  52.    {
  53.       free(ifalist);
  54.       return -1;
  55.    }
  56.    strcpy(iface, ifp->ifa_name);
  57. #ifdef DEBUG
  58.    Debug_msg("Inet_FindIFace -- %s found !!", iface);
  59. #endif
  60.    free(ifalist);
  61.    return 0;
  62. }
  63. char Inet_CorrectIface(char *iface)
  64. {
  65.    struct ifaddrs *ifalist, *ifa;
  66. #ifdef DEBUG
  67.    Debug_msg("Inet_CorrectIface -- %s ", iface);
  68. #endif
  69.    if (getifaddrs(&ifalist) != 0)
  70.       Error_msg("ec_inet_BSD:%d  getifaddrs() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  71.    for (ifa = ifalist; ifa; ifa = ifa->ifa_next)
  72.    {
  73.       if ( (ifa->ifa_flags & IFF_UP) == 0 || strcmp(iface, ifa->ifa_name) )
  74.          continue;
  75.    free(ifalist);
  76.    return 0;
  77.    }
  78.    // no iface found !!
  79.    free(ifalist);
  80.    return -1;
  81. }
  82. int Inet_GetIfaceInfo(char *iface, int *MTU, char *MyMAC, unsigned long *IP, unsigned long *NetMask)
  83. {
  84.    int sock;
  85.    struct ifreq ifr;
  86.    sock = socket(PF_INET, SOCK_DGRAM, 0);
  87.    memset(&ifr, 0, sizeof(ifr));
  88.    strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
  89.    if (MTU != NULL)
  90.    {
  91.       if ( ioctl(sock, SIOCGIFMTU, &ifr) < 0)
  92.       {
  93.          #ifdef DEBUG
  94.             Debug_msg("Inet_IPBased_Run -- MTU FAILED... assuming 2000");
  95.          #endif
  96.          *MTU = 2000;
  97.       }
  98.       else
  99.          *MTU = ifr.ifr_mtu + 256;
  100.    }
  101.    if (MyMAC != NULL)
  102.    {
  103.       int mib[6];
  104.       size_t len;
  105.       char *buf, *next, *end;
  106.       struct if_msghdr *ifm;
  107.       struct sockaddr_dl *sdl;
  108.       mib[0] = CTL_NET;
  109.       mib[1] = AF_ROUTE;
  110.       mib[2] = 0;
  111.       mib[3] = AF_LINK;
  112.       mib[4] = NET_RT_IFLIST;
  113.       mib[5] = 0;
  114.       if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
  115.          Error_msg("ec_Inet_BSD:%d sysctl() | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  116.       if ((buf = (char *)malloc(len)) == NULL )
  117.          Error_msg("ec_Inet_BSD:%d malloc() | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  118.       if (sysctl(mib, 6, buf, &len, NULL, 0) < 0)
  119.          Error_msg("ec_Inet_BSD:%d sysctl() | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  120.       end = buf + len;
  121.       for (next = buf ; next < end ; next += ifm->ifm_msglen)
  122.       {
  123.          ifm = (struct if_msghdr *)next;
  124.          if (ifm->ifm_type == RTM_IFINFO)
  125.          {
  126.             sdl = (struct sockaddr_dl *)(ifm + 1);
  127.             if (strncmp(&sdl->sdl_data[0], iface, sdl->sdl_nlen) == 0)
  128.             {
  129.                 memcpy(MyMAC, LLADDR(sdl), ETHER_ADDR_LEN);
  130.                 break;
  131.             }
  132.          }
  133.       }
  134.       free(buf);
  135.    }
  136.    if (IP != NULL)
  137.    {
  138.       if ( ioctl(sock, SIOCGIFADDR, &ifr) < 0 )
  139.          Error_msg("ec_Inet_BSD:%d ioctl(SIOCGIFADDR) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  140.       memcpy((char *)IP, ifr.ifr_addr.sa_data+2, 4);
  141.    }
  142.    if (NetMask != NULL)
  143.    {
  144.       if ( ioctl(sock, SIOCGIFNETMASK, &ifr) < 0 )
  145.          Error_msg("ec_Inet_BSD:%d ioctl(SIOCGIFNETMASK) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  146.       memcpy((char *)NetMask, ifr.ifr_addr.sa_data+2, 4);
  147.       if (strcmp(Options.netmask, ""))       // specified on command line
  148.          *NetMask = inet_addr(Options.netmask);
  149.    }
  150.    close(sock);
  151.    return 0;
  152. }
  153. int Inet_OpenRawSock(char *iface)
  154. {
  155.    int fd, i = 0, type;
  156.    char device[sizeof "/dev/bpf0000"];
  157.    struct bpf_version bv;
  158.    struct ifreq ifr;
  159.    char MyMAC[6];
  160.    // this BPF will ignore all outgoing packets
  161.    static struct bpf_insn insns[] = {
  162.       BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 6),           // load mac address [1][2]
  163.       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);
  164.       BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 8),           // load mac address [3][4]
  165.       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x00, 0, 2), // if equal check the third part, else jump 2
  166.       BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 10),          // load mac address [5][6]
  167.       BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x00, 1, 0), // if equal this is outgoing ! drop it !
  168.       BPF_STMT(BPF_RET|BPF_K, (u_int)-1),          // no filter, passing the wole packet
  169.       BPF_STMT(BPF_RET|BPF_K, 0),                  // ignore the packet
  170.    };
  171.    static struct bpf_program filter = {
  172.       sizeof insns / sizeof(insns[0]),
  173.       insns
  174.    };
  175.    Inet_GetIfaceInfo(iface, NULL, MyMAC, NULL, NULL);
  176.    insns[1].k = htons(*(short *)MyMAC);         // put MyMac in the filter...
  177.    insns[3].k = htons(*(short *)(MyMAC+2));
  178.    insns[5].k = htons(*(short *)(MyMAC+4));
  179. #ifdef DEBUG
  180.    Debug_msg("Inet_OpenRawSock %s", iface);
  181. #endif
  182.    do    // find an available bpf device
  183.    {
  184.       sprintf(device, "/dev/bpf%d", i++);
  185.       fd = open(device, O_RDWR);
  186.    } while (fd < 0 && errno == EBUSY);
  187.    if (fd < 0)
  188.       Error_msg("ec_inet_BSD:%d  no /dev/bpf* available | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  189. #ifdef DEBUG
  190.    Debug_msg("Inet_OpenRawSock -- /dev/bpf%d", i);
  191. #endif
  192.    if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0)      // get bpf version
  193.       Error_msg("ec_inet_BSD:%d  ioctl(BIOCVERSION) | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  194.    if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION)
  195.       Error_msg(" Kernel bpf filter out of date ");
  196.    for (size = 32768; size != 0; size >>= 1)
  197.    {
  198.       ioctl(fd, BIOCSBLEN, (caddr_t)&size);
  199.       strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));    // attach the iface to the bpf
  200.       if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0)
  201.          break;  /* that size worked; we're done */
  202.       if (errno != ENOBUFS)
  203.          Error_msg("ec_inet_BSD:%d  ioctl(BIOCSETIF) | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  204.    }
  205.    if (size == 0) Error_msg("BIOCSBLEN: No buffer size worked");
  206.    if (ioctl(fd, BIOCGBLEN, (caddr_t)&size) < 0)
  207.      Error_msg("ec_inet_BSD:%d  ioctl(BIOCGBLEN) | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  208. #ifdef DEBUG
  209.    Debug_msg("Inet_OpenRawSock -- BIOCGBLEN %d", size);
  210. #endif
  211.    if (ioctl(fd, BIOCGDLT, (caddr_t)&type) == -1)           // Get the data link layer type.
  212.       Error_msg("ec_inet_BSD:%d  ioctl(BIOCGDLT) | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  213.    if (type != DLT_EN10MB)
  214.       Error_msg("Interface not supported ( != DLT_EN10MB) | %d", type);
  215.    i = 1;
  216.    if (ioctl(fd, BIOCIMMEDIATE, &i) < 0)                    // Set immediate mode so packets are processed as they arrive.
  217.       Error_msg("ec_inet_BSD:%d  ioctl(BIOCIMMEDIATE) | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  218.    if (ioctl(fd, BIOCSETF, (caddr_t)&filter) < 0)           // Set filter program.
  219.       Error_msg("ec_inet_BSD:%d  ioctl(BIOCSETF) | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  220.    fdprom = fd;
  221.    return fd;
  222. }
  223. int Inet_GetRawPacket(int sock, char *buffer, int MTU, short *type)
  224. {
  225.    int len = 0, pktlen = 0;
  226.    u_char *buf, *bp, *ep;
  227.    static char MyMAC[6]={0x65,0x74,0x74,0x65,0x72,0x63};
  228.    if (SocketBuffer == -1)                   // only the first time
  229.       SocketBuffer = Buffer_Create(1.0e5);   // 100 K buffer
  230.    Buffer_Get(SocketBuffer, &pktlen, sizeof(u_int));
  231.    len = Buffer_Get(SocketBuffer, buffer, pktlen );
  232.    if (type != NULL)
  233.    {
  234.        if (!strncmp(MyMAC,"etterc",6))    // only the first time...
  235.            Inet_GetIfaceInfo(Options.netiface, NULL, MyMAC, NULL, NULL);
  236.        if (!memcmp(MyMAC,buffer,6))
  237.            *type = 0; // PACKET_HOST
  238.        else
  239.            *type = 1; // !PACKET_HOST
  240.    }
  241.    if (len > 0) return len;                     // there was pending fata.
  242.    buf = (char *)calloc(size, sizeof(char));    // size is global and set by BIOCGBLEN
  243.    len = read(sock, buf, size);
  244. #define bhp ((struct bpf_hdr *)bp)              // Loop through the packet(s)
  245.          bp = buf;
  246.          ep = bp + len;
  247.          while (bp < ep) {
  248.             u_int caplen, hdrlen;
  249.             caplen = bhp->bh_caplen;
  250.             hdrlen = bhp->bh_hdrlen;
  251. //          //  bp + hdrlen is my packet
  252. //          //  caplen is the length
  253.             Buffer_Put(SocketBuffer, &caplen, sizeof(u_int) );
  254.             Buffer_Put(SocketBuffer, bp + hdrlen, caplen );
  255.             bp += BPF_WORDALIGN(hdrlen + caplen);
  256.          }
  257. #undef bhp
  258.    Buffer_Get(SocketBuffer, &pktlen, sizeof(u_int));
  259.    len = Buffer_Get(SocketBuffer, buffer, pktlen );
  260.    if (type != NULL)
  261.    {
  262.        if (!memcmp(MyMAC,buffer,6))
  263.            *type = 0; // PACKET_HOST
  264.        else
  265.            *type = 1; // !PACKET_HOST
  266.    }
  267.    free(buf);
  268.    return len;
  269. }
  270. int Inet_SendRawPacket(int sock, char *buffer, int len)
  271. {
  272.    int sent;
  273.    sent = write(sock, buffer, len);
  274.    if (sent < len)
  275.       Error_msg("ec_Inet_BSD:%d write() %d(%d) | ERRNO : %d | %s n", __LINE__, len, sent, errno, sys_errlist[errno]);
  276.    return (sent);
  277. }
  278. int Inet_SetPromisc(char *iface)
  279. {
  280. #ifdef DEBUG
  281.    Debug_msg("Inet_SetPromisc %s %d", iface, fdprom);
  282. #endif
  283.    if ( ioctl(fdprom, BIOCPROMISC, NULL) < 0 )
  284.       Error_msg("ec_Inet_BSD:%d ioctl(BIOCPROMISC) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  285.    return 0;
  286. }
  287. void Inet_Restore_ifr(void)
  288. {
  289.    // this function is not needed !!
  290.    // when a bpf is closed, the interface is restored
  291. }
  292. void Inet_DisableForwarding(void)
  293. {
  294.    int mib[4];      // for sysctl()
  295.    int val = 0;     // for sysctl()   disable
  296.    size_t len;
  297.    mib[0] = CTL_NET;
  298.    mib[1] = PF_INET;
  299.    mib[2] = IPPROTO_IP;
  300.    mib[3] = IPCTL_FORWARDING;
  301.    len = sizeof(IpForward_status);
  302.    if( (sysctl(mib, 4, &IpForward_status, &len, &val, sizeof(val))) == -1)
  303.     Error_msg("ec_inet_BSD:%d sysctl() | net.inet.ip.forwarding | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  304. #ifdef DEBUG
  305.    Debug_msg("Inet_DisableForwarding | net.inet.ip.forwarding = %d  old_value = %dn", val, IpForward_status);
  306. #endif
  307.    exit_func(Inet_RestoreForwarding);
  308. }
  309. void Inet_RestoreForwarding(void)
  310. {
  311.  int mib[4];      // for sysctl()
  312.  mib[0] = CTL_NET;
  313.  mib[1] = PF_INET;
  314.  mib[2] = IPPROTO_IP;
  315.  mib[3] = IPCTL_FORWARDING;
  316.  if( (sysctl(mib, 4, NULL, NULL, &IpForward_status, sizeof(IpForward_status))) == -1)
  317.   Error_msg("ec_inet_BSD:%d sysctl() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  318. #ifdef DEBUG
  319.    Debug_msg("Inet_RestoreForwarding | net.inet.ip.forwarding = %dn", IpForward_status);
  320. #endif
  321. }
  322. char *Inet_MacFromIP(unsigned long ip)
  323. {
  324.    int mib[6];
  325.    size_t len;
  326.    char *buf, *next, *end;
  327.    struct rt_msghdr *rtm;
  328.    struct sockaddr_inarp *sin;
  329.    struct sockaddr_dl *sdl;
  330.    static char ETH_BROADCAST[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
  331. #ifdef DEBUG
  332.    Debug_msg("Inet_MacFromIP");
  333. #endif
  334.    mib[0] = CTL_NET;
  335.    mib[1] = AF_ROUTE;
  336.    mib[2] = 0;
  337.    mib[3] = AF_INET;
  338.    mib[4] = NET_RT_FLAGS;
  339.    mib[5] = RTF_LLINFO;
  340.    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
  341.       Error_msg("ec_inet_BSD:%d sysctl() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  342.    if ((buf = (char *)malloc(len)) == NULL)
  343.       Error_msg("ec_inet_BSD:%d malloc() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  344.    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0)
  345.    {
  346.       free(buf);
  347.       Error_msg("ec_inet_BSD:%d sysctl() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  348.    }
  349.    end = buf + len;
  350.    for (next = buf ; next < end ; next += rtm->rtm_msglen)
  351.    {
  352.       rtm = (struct rt_msghdr *)next;
  353.       sin = (struct sockaddr_inarp *)(rtm + 1);
  354.       sdl = (struct sockaddr_dl *)(sin + 1);
  355.       if (sin->sin_addr.s_addr == ip && sdl->sdl_alen)
  356.       {
  357.          free(buf);
  358.          return LLADDR(sdl);
  359.       }
  360.       else     // not in cache... try to find it...
  361.       {
  362.          u_char *buf;
  363.          char MyMAC[6];
  364.          u_long MyIP;
  365.          int MTU, sock;
  366.          TIME_DECLARE;
  367. #ifdef DEBUG
  368.    Debug_msg("Inet_MacFromIP -- try to find it");
  369. #endif
  370.          sock = Inet_OpenRawSock(Options.netiface);
  371.          Inet_GetIfaceInfo(Options.netiface, &MTU, MyMAC, &MyIP, NULL);
  372.          if (ip == MyIP)
  373.          {
  374.             #ifdef DEBUG
  375.                Debug_msg("Inet_MacFromIP -- try to find me... ;)");
  376.             #endif
  377.             memcpy(LLADDR(sdl), MyMAC, ETHER_ADDR_LEN);
  378.             close(sock);
  379.             return (char *) LLADDR(sdl);
  380.          }
  381.          buf = Inet_Forge_packet( ETH_HEADER + ARP_HEADER );
  382.          Inet_Forge_ethernet( buf, MyMAC, ETH_BROADCAST, ETH_P_ARP );
  383.          Inet_Forge_arp( buf+ETH_HEADER, ARPOP_REQUEST,
  384.                          MyMAC, MyIP,
  385.                          ARP_BROADCAST, ip );
  386.          Inet_SendRawPacket(sock, buf, ETH_HEADER + ARP_HEADER);
  387.          Inet_Forge_packet_destroy( buf );
  388.          buf = Inet_Forge_packet( MTU );
  389.          fcntl(sock, F_SETFL, O_NONBLOCK);
  390.          TIME_START;
  391.          do
  392.          {
  393.             int len;
  394.             short pkttype;
  395.             ETH_header *ethpkt;
  396.             ARP_header *arppkt;
  397.             len = Inet_GetRawPacket(sock, buf, MTU, &pkttype);
  398.             ethpkt = (ETH_header *)buf;
  399.             arppkt = (ARP_header *)(buf + ETH_HEADER);
  400.             TIME_FINISH;
  401.             if (len > 0 && pkttype == PACKET_HOST && ethpkt->type == htons(ETH_P_ARP) && arppkt->opcode == htons(ARPOP_REPLY))
  402.             {
  403.                if ( *(unsigned long *)arppkt->source_ip == ip )
  404.                {
  405.                   memcpy(LLADDR(sdl), &arppkt->source_add, ETHER_ADDR_LEN);
  406.                   Inet_Forge_packet_destroy( buf );
  407.                   close(sock);
  408.                   return (char *) LLADDR(sdl);
  409.                }
  410.             }
  411.          } while ( TIME_ELAPSED < 0.5 );
  412.       }
  413.    }
  414.    free(buf);
  415.    return ETH_BROADCAST;  // workaround for non local ip
  416. }
  417. /* EOF */