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

网络截获/分析

开发平台:

C/C++

  1. /*
  2.     ettercap -- inet utilities -- Module for LINUX 2.0.x  FULL
  3.                                                    2.2.x  FULL
  4.                                                    2.4.x  FULL
  5.     Copyright (C) 2001  ALoR <alor@users.sourceforge.net>, NaGA <crwm@freemail.it>
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.     You should have received a copy of the GNU General Public License
  15.     along with this program; if not, write to the Free Software
  16.     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. // This file is included from ../ec_inet.c
  19. int Inet_FindIFace(char *iface)
  20. {
  21.    #define MAX_IFACE 20
  22.    int i;
  23.    for (i=0; i<MAX_IFACE; i++)
  24.    {
  25.       sprintf(iface,"eth%d",i);
  26.       if (Inet_CorrectIface(iface)!=-1) break;
  27.    }
  28.    if (i == MAX_IFACE)
  29.       Error_msg("ec_Inet_linux: Can't find an ethernet interface");
  30. #ifdef DEBUG
  31.    Debug_msg("Inet_FindIFace -- %s found !!", iface);
  32. #endif
  33.    return 0;
  34. }
  35. char Inet_CorrectIface(char *iface)
  36. {
  37.    int sock;
  38.    struct sockaddr sa;
  39.    struct ifreq ifr;
  40. #ifdef DEBUG
  41.    Debug_msg("Inet_CorrectIfacettIface: %s", iface);
  42. #endif
  43.    sock = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
  44.    if (sock < 0)
  45.       Error_msg("ec_Inet_linux:%d socket() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  46.    memset(&sa, 0, sizeof(sa));
  47.    sa.sa_family = AF_INET;
  48.    strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
  49.    if (bind(sock, (struct sockaddr *) &sa, sizeof(sa)))     // interface doesn't exist
  50.       return -1;
  51.    memset(&ifr, 0, sizeof(ifr));
  52.    strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
  53.    ioctl(sock, SIOCGIFFLAGS, &ifr);
  54.    if (!(ifr.ifr_flags & IFF_UP )) return -1;
  55.    close(sock);
  56.    return 0;
  57. }
  58. int Inet_GetIfaceInfo(char *iface, int *MTU, char *MyMAC, unsigned long *IP, unsigned long *NetMask)
  59. {
  60.    int sock;
  61.    struct ifreq ifr;
  62.    sock = Inet_OpenRawSock(iface);
  63.    memset(&ifr, 0, sizeof(ifr));
  64.    strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
  65.    if (MTU != NULL)
  66.    {
  67.       if ( ioctl(sock, SIOCGIFMTU, &ifr) < 0)
  68.       {
  69.          #ifdef DEBUG
  70.             Debug_msg("Inet_IPBased_Run -- MTU FAILED... assuming 1500");
  71.          #endif
  72.          *MTU = 1500;
  73.       }
  74.       else
  75.          *MTU = ifr.ifr_mtu;
  76.    }
  77.    if (MyMAC != NULL)
  78.    {
  79.       if ( ioctl(sock, SIOCGIFHWADDR, &ifr) < 0 )
  80.          Error_msg("ec_Inet_linux:%d ioctl(SIOCGIFHWADDR) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  81.       memcpy(MyMAC, ifr.ifr_hwaddr.sa_data, 6);
  82.    }
  83.    if (IP != NULL)
  84.    {
  85.       if ( ioctl(sock, SIOCGIFADDR, &ifr) < 0 )
  86.          Error_msg("ec_Inet_linux:%d ioctl(SIOCGIFADDR) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  87.       memcpy((char *)IP, ifr.ifr_addr.sa_data+2, 4);
  88.    }
  89.    if (NetMask != NULL)
  90.    {
  91.       if ( ioctl(sock, SIOCGIFNETMASK, &ifr) < 0 )
  92.          Error_msg("ec_Inet_linux:%d ioctl(SIOCGIFNETMASK) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  93.       memcpy((char *)NetMask, ifr.ifr_addr.sa_data+2, 4);
  94.       if (strcmp(Options.netmask, ""))       // specified on command line
  95.          *NetMask = inet_addr(Options.netmask);
  96.    }
  97.    close(sock);
  98.    return 0;
  99. }
  100. int Inet_OpenRawSock(char *iface)
  101. {
  102.    int sock;
  103. #ifdef HAVE_PF_PACKET
  104.    struct ifreq ifr;
  105.    struct sockaddr_ll sll;
  106. #else
  107.    struct sockaddr sa;
  108. #endif
  109. #ifdef DEBUG
  110.    Debug_msg("Inet_OpenRawSock %s", iface);
  111. #endif
  112. #ifdef HAVE_PF_PACKET
  113.    sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
  114. #else
  115.    sock = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
  116. #endif
  117.    if (sock < 0)
  118.       Error_msg("ec_Inet_linux:%d socket() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  119. #ifdef HAVE_PF_PACKET
  120.    memset(&ifr, 0, sizeof(ifr));
  121.    strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
  122.    if ( ioctl(sock, SIOCGIFINDEX, &ifr) < 0)
  123.       Error_msg("ec_Inet_linux:%d ioctl(SIOCGIFINDEX) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  124.    memset(&sll, 0, sizeof(sll));
  125.    sll.sll_family = AF_PACKET;
  126.    sll.sll_ifindex = ifr.ifr_ifindex;
  127.    sll.sll_protocol = htons(ETH_P_ALL);
  128.    if ( bind(sock, (struct sockaddr *) &sll, sizeof(sll)) == -1)
  129.       Error_msg("ec_Inet_linux:%d bind() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  130. #else
  131.    memset(&sa, 0, sizeof(sa));
  132.    strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
  133.    if ( bind(sock, &sa, sizeof(sa)) == -1)
  134.       Error_msg("ec_Inet_linux:%d bind() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
  135. #endif
  136.    return sock;
  137. }
  138. int Inet_GetRawPacket(int sock, char *buffer, int MTU, short *type)
  139. {
  140.    int len = 0;
  141.    socklen_t fromlen;
  142. #ifdef HAVE_PF_PACKET
  143.    struct sockaddr_ll from;
  144. #else
  145.    struct sockaddr from;
  146.    static char MyMAC[6]={0x65,0x74,0x74,0x65,0x72,0x63};
  147. #endif
  148.    fromlen = sizeof(from);
  149.    len = recvfrom(sock, buffer, MTU+64, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
  150.    if (len > MTU + ETH_HEADER) len = MTU + ETH_HEADER;   // workaround for bugged kernel (2.2.14)
  151. #ifdef HAVE_PF_PACKET
  152.    if (type != NULL) *type = from.sll_pkttype;
  153. #else
  154.    // the address returned for SOCK_PACKET lacks the packet type information.
  155.    if (type != NULL)
  156.    {
  157.        if (!strncmp(MyMAC,"etterc",6))    // only the first time...
  158.            Inet_GetIfaceInfo(Options.netiface, NULL, MyMAC, NULL, NULL);
  159.        if (!memcmp(MyMAC,buffer,6))
  160.            *type = 0; // PACKET_HOST
  161.        else
  162.            *type = 1; // !PACKET_HOST
  163.    }
  164. #endif
  165.    // TODO
  166.    // handle fragmented packets...
  167.    return len;
  168. }
  169. int Inet_SendRawPacket(int sock, char *buffer, int len)
  170. {
  171.    int sent;
  172. #ifdef HAVE_PF_PACKET
  173.    struct sockaddr_ll dest;
  174.    struct ifreq ifr;
  175. #else
  176.    struct sockaddr dest;
  177. #endif
  178.    memset(&dest, 0, sizeof (dest));
  179. #ifdef HAVE_PF_PACKET
  180.    memset(&ifr, 0, sizeof(ifr));
  181.    strncpy(ifr.ifr_name, Options.netiface, sizeof(ifr.ifr_name));
  182.    if ( ioctl(sock, SIOCGIFINDEX, &ifr) < 0)
  183.       Error_msg("ec_Inet_linux:%d ioctl(SIOCGIFINDEX) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  184.    dest.sll_family = AF_PACKET;
  185.    dest.sll_ifindex = ifr.ifr_ifindex;
  186.    dest.sll_protocol = htons(ETH_P_ALL);
  187. #else
  188.    strncpy(dest.sa_data, Options.netiface, sizeof (dest.sa_data));
  189. #endif
  190.    sent = sendto(sock, buffer, len, 0, (struct sockaddr *)&dest, sizeof(dest));
  191.    if (sent < len)
  192.       Error_msg("ec_Inet_linux:%d sendto() %d(%d) | ERRNO : %d | %s n", __LINE__, len, sent, errno, sys_errlist[errno]);
  193.    return (sent);
  194. }
  195. int Inet_SetPromisc(char *iface)
  196. {
  197.    int sock;
  198.    struct ifreq ifr;
  199. #ifdef DEBUG
  200.    Debug_msg("Inet_SetPromisctiface: %s", iface);
  201. #endif
  202.    sock = Inet_OpenRawSock(iface);
  203.    memset(&ifr, 0, sizeof(ifr));
  204.    strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
  205.    if ( ioctl(sock, SIOCGIFFLAGS, &ifr) < 0 )
  206.       Error_msg("ec_Inet_linux:%d ioctl(SIOCGIFFLAGS) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  207.    if (!(ifr.ifr_flags & IFF_PROMISC))
  208.    {
  209.       memset(&old_ifr, 0, sizeof(old_ifr));
  210.       old_ifr.ifr_flags = ifr.ifr_flags;              //save old flags
  211.       ifr.ifr_flags |= IFF_PROMISC;
  212.       if ( ioctl(sock, SIOCSIFFLAGS, &ifr) < 0 )      // promisc mode
  213.          Error_msg("ec_Inet_linux:%d ioctl(SIOCSIFFLAGS) | promisc on | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  214.       exit_func(Inet_Restore_ifr);
  215.    }
  216.    close(sock);
  217.    return 0;
  218. }
  219. void Inet_Restore_ifr(void)
  220. {
  221.    int sock;
  222.    struct ifreq ifr;
  223. #ifdef DEBUG
  224.    Debug_msg("Inet_Restore_ifr");
  225. #endif
  226.    sock = Inet_OpenRawSock(Options.netiface);
  227.    memset(&ifr, 0, sizeof(ifr));
  228.    strncpy(ifr.ifr_name, Options.netiface, sizeof(ifr.ifr_name));
  229.    ifr.ifr_flags = old_ifr.ifr_flags;
  230.    if ( ioctl(sock, SIOCSIFFLAGS, &ifr) < 0 )     // flag restoring
  231.       Error_msg("ec_Inet_linux:%d ioctl(SIOCSIFFLAGS) | flag restoring | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  232.    close(sock);
  233. }
  234. void Inet_DisableForwarding(void)
  235. {
  236.    FILE *fd;
  237.    fd = fopen("/proc/sys/net/ipv4/ip_forward", "r");
  238.    if (fd < 0 )
  239.    {
  240.       #ifdef DEBUG
  241.          Debug_msg("ec_Inet_linux:%d fopen(/proc/sys/net/ipv4/ip_forward) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  242.       #endif
  243.       return;
  244.    }
  245.    fscanf(fd, "%s", IpForward_status);
  246.    fclose(fd);
  247. #ifdef DEBUG
  248.    Debug_msg("Inet_DisableForwarding from %c", IpForward_status[0]);
  249. #endif
  250.    exit_func(Inet_RestoreForwarding);
  251.    fd = fopen("/proc/sys/net/ipv4/ip_forward", "w");
  252.    if (fd < 0 )
  253.    {
  254.       #ifdef DEBUG
  255.          Debug_msg("ec_Inet_linux:%d fopen(/proc/sys/net/ipv4/ip_forward) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  256.       #endif
  257.       return;
  258.    }
  259.    fprintf(fd, "0");
  260.    fclose(fd);
  261. }
  262. void Inet_RestoreForwarding(void)
  263. {
  264.    FILE *fd;
  265.    fd = fopen("/proc/sys/net/ipv4/ip_forward", "w");
  266.    if (fd < 0 )
  267.    {
  268.       #ifdef DEBUG
  269.          Debug_msg("ec_Inet_linux:%d fopen(/proc/sys/net/ipv4/ip_forward) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  270.       #endif
  271.       return;
  272.    }
  273. #ifdef DEBUG
  274.    Debug_msg("Inet_RestoreForwarding to %c", IpForward_status[0]);
  275. #endif
  276.    fprintf(fd, "%c", IpForward_status[0] );
  277.    fclose(fd);
  278. }
  279. char *Inet_MacFromIP(unsigned long ip)
  280. {
  281.    int sock;
  282.    static struct arpreq ar;
  283.    struct sockaddr_in *sin;
  284.    static char ETH_BROADCAST[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
  285. #ifdef DEBUG
  286.    Debug_msg("Inet_MacFromIP");
  287. #endif
  288.    memset((char *)&ar, 0, sizeof(ar));
  289.    strncpy(ar.arp_dev, Options.netiface, sizeof(ar.arp_dev));
  290.    sin = (struct sockaddr_in *)&ar.arp_pa;
  291.    sin->sin_family = AF_INET;
  292.    sin->sin_addr.s_addr = ip;
  293.    if ((sock = socket(AF_INET, SOCK_PACKET, 0)) == -1)
  294.       Error_msg("ec_Inet_linux:%d socket() | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
  295.    if (ioctl(sock, SIOCGARP, (caddr_t)&ar) == -1)  // not in cache... try to find it...
  296.    {
  297.       u_char *buf;
  298.       char MyMAC[6];
  299.       u_long MyIP;
  300.       int MTU, sock;
  301.       TIME_DECLARE;
  302. #ifdef DEBUG
  303.    Debug_msg("Inet_MacFromIP -- try to find it");
  304. #endif
  305.       sock = Inet_OpenRawSock(Options.netiface);
  306.       Inet_GetIfaceInfo(Options.netiface, &MTU, MyMAC, &MyIP, NULL);
  307.       if (ip == MyIP)
  308.       {
  309.          #ifdef DEBUG
  310.             Debug_msg("Inet_MacFromIP -- try to find me... ;)");
  311.          #endif
  312.          memcpy(&ar.arp_ha.sa_data, MyMAC, ETHER_ADDR_LEN);
  313.          close(sock);
  314.          return (char *) ar.arp_ha.sa_data;
  315.       }
  316.       buf = Inet_Forge_packet( ETH_HEADER + ARP_HEADER );
  317.       Inet_Forge_ethernet( buf, MyMAC, ETH_BROADCAST, ETH_P_ARP );
  318.       Inet_Forge_arp( buf+ETH_HEADER, ARPOP_REQUEST,
  319.                          MyMAC, MyIP,
  320.                          ARP_BROADCAST, ip );
  321.       Inet_SendRawPacket(sock, buf, ETH_HEADER + ARP_HEADER);
  322.       Inet_Forge_packet_destroy( buf );
  323.       buf = Inet_Forge_packet( MTU );
  324.       fcntl(sock, F_SETFL, O_NONBLOCK);
  325.       TIME_START;
  326.       do
  327.       {
  328.          int len;
  329.          short pkttype;
  330.          ETH_header *ethpkt;
  331.          ARP_header *arppkt;
  332.          len = Inet_GetRawPacket(sock, buf, MTU, &pkttype);
  333.          ethpkt = (ETH_header *)buf;
  334.          arppkt = (ARP_header *)(buf + ETH_HEADER);
  335.          TIME_FINISH;
  336.          if (len > 0 && pkttype == PACKET_HOST && ethpkt->type == htons(ETH_P_ARP) && arppkt->opcode == htons(ARPOP_REPLY))
  337.          {
  338.             if ( *(unsigned long *)arppkt->source_ip == ip )
  339.             {
  340.                memcpy(&ar.arp_ha.sa_data, &arppkt->source_add, ETHER_ADDR_LEN);
  341.                Inet_Forge_packet_destroy( buf );
  342.                close(sock);
  343.                return (char *) ar.arp_ha.sa_data;
  344.             }
  345.          }
  346.       } while ( TIME_ELAPSED < 0.5 );
  347.       return ETH_BROADCAST;  // workaround for non local ip
  348.    }
  349.    close(sock);
  350.    return (char *) ar.arp_ha.sa_data;
  351. }
  352. /* EOF */