ec_inet_linux.c
上传用户:nilegod
上传日期:2007-01-08
资源大小:220k
文件大小:12k
- /*
- ettercap -- inet utilities -- Module for LINUX 2.0.x FULL
- 2.2.x FULL
- 2.4.x FULL
- 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.
- */
- // This file is included from ../ec_inet.c
- int Inet_FindIFace(char *iface)
- {
- #define MAX_IFACE 20
- int i;
- for (i=0; i<MAX_IFACE; i++)
- {
- sprintf(iface,"eth%d",i);
- if (Inet_CorrectIface(iface)!=-1) break;
- }
- if (i == MAX_IFACE)
- Error_msg("ec_Inet_linux: Can't find an ethernet interface");
- #ifdef DEBUG
- Debug_msg("Inet_FindIFace -- %s found !!", iface);
- #endif
- return 0;
- }
- char Inet_CorrectIface(char *iface)
- {
- int sock;
- struct sockaddr sa;
- struct ifreq ifr;
- #ifdef DEBUG
- Debug_msg("Inet_CorrectIfacettIface: %s", iface);
- #endif
- sock = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
- if (sock < 0)
- Error_msg("ec_Inet_linux:%d socket() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
- memset(&sa, 0, sizeof(sa));
- sa.sa_family = AF_INET;
- strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
- if (bind(sock, (struct sockaddr *) &sa, sizeof(sa))) // interface doesn't exist
- return -1;
- memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
- ioctl(sock, SIOCGIFFLAGS, &ifr);
- if (!(ifr.ifr_flags & IFF_UP )) return -1;
- close(sock);
- return 0;
- }
- int Inet_GetIfaceInfo(char *iface, int *MTU, char *MyMAC, unsigned long *IP, unsigned long *NetMask)
- {
- int sock;
- struct ifreq ifr;
- sock = 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)
- {
- #ifdef DEBUG
- Debug_msg("Inet_IPBased_Run -- MTU FAILED... assuming 1500");
- #endif
- *MTU = 1500;
- }
- else
- *MTU = ifr.ifr_mtu;
- }
- if (MyMAC != NULL)
- {
- if ( ioctl(sock, SIOCGIFHWADDR, &ifr) < 0 )
- Error_msg("ec_Inet_linux:%d ioctl(SIOCGIFHWADDR) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
- memcpy(MyMAC, ifr.ifr_hwaddr.sa_data, 6);
- }
- if (IP != NULL)
- {
- if ( ioctl(sock, SIOCGIFADDR, &ifr) < 0 )
- Error_msg("ec_Inet_linux:%d ioctl(SIOCGIFADDR) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
- memcpy((char *)IP, ifr.ifr_addr.sa_data+2, 4);
- }
- if (NetMask != NULL)
- {
- if ( ioctl(sock, SIOCGIFNETMASK, &ifr) < 0 )
- Error_msg("ec_Inet_linux:%d ioctl(SIOCGIFNETMASK) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
- 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;
- }
- int Inet_OpenRawSock(char *iface)
- {
- int sock;
- #ifdef HAVE_PF_PACKET
- struct ifreq ifr;
- struct sockaddr_ll sll;
- #else
- struct sockaddr sa;
- #endif
- #ifdef DEBUG
- Debug_msg("Inet_OpenRawSock %s", iface);
- #endif
- #ifdef HAVE_PF_PACKET
- sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
- #else
- sock = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
- #endif
- if (sock < 0)
- Error_msg("ec_Inet_linux:%d socket() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
- #ifdef HAVE_PF_PACKET
- memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
- if ( ioctl(sock, SIOCGIFINDEX, &ifr) < 0)
- Error_msg("ec_Inet_linux:%d ioctl(SIOCGIFINDEX) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
- memset(&sll, 0, sizeof(sll));
- sll.sll_family = AF_PACKET;
- sll.sll_ifindex = ifr.ifr_ifindex;
- sll.sll_protocol = htons(ETH_P_ALL);
- if ( bind(sock, (struct sockaddr *) &sll, sizeof(sll)) == -1)
- Error_msg("ec_Inet_linux:%d bind() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
- #else
- memset(&sa, 0, sizeof(sa));
- strncpy(sa.sa_data, iface, sizeof(sa.sa_data));
- if ( bind(sock, &sa, sizeof(sa)) == -1)
- Error_msg("ec_Inet_linux:%d bind() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
- #endif
- return sock;
- }
- int Inet_GetRawPacket(int sock, char *buffer, int MTU, short *type)
- {
- int len = 0;
- socklen_t fromlen;
- #ifdef HAVE_PF_PACKET
- struct sockaddr_ll from;
- #else
- struct sockaddr from;
- static char MyMAC[6]={0x65,0x74,0x74,0x65,0x72,0x63};
- #endif
- fromlen = sizeof(from);
- len = recvfrom(sock, buffer, MTU+64, MSG_TRUNC, (struct sockaddr *)&from, &fromlen);
- if (len > MTU + ETH_HEADER) len = MTU + ETH_HEADER; // workaround for bugged kernel (2.2.14)
- #ifdef HAVE_PF_PACKET
- if (type != NULL) *type = from.sll_pkttype;
- #else
- // the address returned for SOCK_PACKET lacks the packet type information.
- 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 = 0; // PACKET_HOST
- else
- *type = 1; // !PACKET_HOST
- }
- #endif
- // TODO
- // handle fragmented packets...
- return len;
- }
- int Inet_SendRawPacket(int sock, char *buffer, int len)
- {
- int sent;
- #ifdef HAVE_PF_PACKET
- struct sockaddr_ll dest;
- struct ifreq ifr;
- #else
- struct sockaddr dest;
- #endif
- memset(&dest, 0, sizeof (dest));
- #ifdef HAVE_PF_PACKET
- memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, Options.netiface, sizeof(ifr.ifr_name));
- if ( ioctl(sock, SIOCGIFINDEX, &ifr) < 0)
- Error_msg("ec_Inet_linux:%d ioctl(SIOCGIFINDEX) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
- dest.sll_family = AF_PACKET;
- dest.sll_ifindex = ifr.ifr_ifindex;
- dest.sll_protocol = htons(ETH_P_ALL);
- #else
- strncpy(dest.sa_data, Options.netiface, sizeof (dest.sa_data));
- #endif
- sent = sendto(sock, buffer, len, 0, (struct sockaddr *)&dest, sizeof(dest));
- if (sent < len)
- Error_msg("ec_Inet_linux:%d sendto() %d(%d) | ERRNO : %d | %s n", __LINE__, len, sent, errno, sys_errlist[errno]);
- return (sent);
- }
- int Inet_SetPromisc(char *iface)
- {
- int sock;
- struct ifreq ifr;
- #ifdef DEBUG
- Debug_msg("Inet_SetPromisctiface: %s", iface);
- #endif
- sock = Inet_OpenRawSock(iface);
- memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
- if ( ioctl(sock, SIOCGIFFLAGS, &ifr) < 0 )
- Error_msg("ec_Inet_linux:%d ioctl(SIOCGIFFLAGS) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
- if (!(ifr.ifr_flags & IFF_PROMISC))
- {
- memset(&old_ifr, 0, sizeof(old_ifr));
- old_ifr.ifr_flags = ifr.ifr_flags; //save old flags
- ifr.ifr_flags |= IFF_PROMISC;
- if ( ioctl(sock, SIOCSIFFLAGS, &ifr) < 0 ) // promisc mode
- Error_msg("ec_Inet_linux:%d ioctl(SIOCSIFFLAGS) | promisc on | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
- exit_func(Inet_Restore_ifr);
- }
- close(sock);
- return 0;
- }
- void Inet_Restore_ifr(void)
- {
- int sock;
- struct ifreq ifr;
- #ifdef DEBUG
- Debug_msg("Inet_Restore_ifr");
- #endif
- sock = Inet_OpenRawSock(Options.netiface);
- memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, Options.netiface, sizeof(ifr.ifr_name));
- ifr.ifr_flags = old_ifr.ifr_flags;
- if ( ioctl(sock, SIOCSIFFLAGS, &ifr) < 0 ) // flag restoring
- Error_msg("ec_Inet_linux:%d ioctl(SIOCSIFFLAGS) | flag restoring | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
- close(sock);
- }
- void Inet_DisableForwarding(void)
- {
- FILE *fd;
- fd = fopen("/proc/sys/net/ipv4/ip_forward", "r");
- if (fd < 0 )
- {
- #ifdef DEBUG
- Debug_msg("ec_Inet_linux:%d fopen(/proc/sys/net/ipv4/ip_forward) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
- #endif
- return;
- }
- fscanf(fd, "%s", IpForward_status);
- fclose(fd);
- #ifdef DEBUG
- Debug_msg("Inet_DisableForwarding from %c", IpForward_status[0]);
- #endif
- exit_func(Inet_RestoreForwarding);
- fd = fopen("/proc/sys/net/ipv4/ip_forward", "w");
- if (fd < 0 )
- {
- #ifdef DEBUG
- Debug_msg("ec_Inet_linux:%d fopen(/proc/sys/net/ipv4/ip_forward) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
- #endif
- return;
- }
- fprintf(fd, "0");
- fclose(fd);
- }
- void Inet_RestoreForwarding(void)
- {
- FILE *fd;
- fd = fopen("/proc/sys/net/ipv4/ip_forward", "w");
- if (fd < 0 )
- {
- #ifdef DEBUG
- Debug_msg("ec_Inet_linux:%d fopen(/proc/sys/net/ipv4/ip_forward) | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
- #endif
- return;
- }
- #ifdef DEBUG
- Debug_msg("Inet_RestoreForwarding to %c", IpForward_status[0]);
- #endif
- fprintf(fd, "%c", IpForward_status[0] );
- fclose(fd);
- }
- char *Inet_MacFromIP(unsigned long ip)
- {
- int sock;
- static struct arpreq ar;
- struct sockaddr_in *sin;
- static char ETH_BROADCAST[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
- #ifdef DEBUG
- Debug_msg("Inet_MacFromIP");
- #endif
- memset((char *)&ar, 0, sizeof(ar));
- strncpy(ar.arp_dev, Options.netiface, sizeof(ar.arp_dev));
- sin = (struct sockaddr_in *)&ar.arp_pa;
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = ip;
- if ((sock = socket(AF_INET, SOCK_PACKET, 0)) == -1)
- Error_msg("ec_Inet_linux:%d socket() | ERRNO : %d | %s n", __LINE__, errno, sys_errlist[errno]);
- if (ioctl(sock, SIOCGARP, (caddr_t)&ar) == -1) // not in cache... try to find it...
- {
- u_char *buf;
- char MyMAC[6];
- u_long MyIP;
- int MTU, sock;
- TIME_DECLARE;
- #ifdef DEBUG
- Debug_msg("Inet_MacFromIP -- try to find it");
- #endif
- sock = Inet_OpenRawSock(Options.netiface);
- Inet_GetIfaceInfo(Options.netiface, &MTU, MyMAC, &MyIP, NULL);
- if (ip == MyIP)
- {
- #ifdef DEBUG
- Debug_msg("Inet_MacFromIP -- try to find me... ;)");
- #endif
- memcpy(&ar.arp_ha.sa_data, MyMAC, ETHER_ADDR_LEN);
- close(sock);
- return (char *) ar.arp_ha.sa_data;
- }
- buf = Inet_Forge_packet( ETH_HEADER + ARP_HEADER );
- Inet_Forge_ethernet( buf, MyMAC, ETH_BROADCAST, ETH_P_ARP );
- Inet_Forge_arp( buf+ETH_HEADER, ARPOP_REQUEST,
- MyMAC, MyIP,
- ARP_BROADCAST, ip );
- Inet_SendRawPacket(sock, buf, ETH_HEADER + ARP_HEADER);
- Inet_Forge_packet_destroy( buf );
- buf = Inet_Forge_packet( MTU );
- fcntl(sock, F_SETFL, O_NONBLOCK);
- TIME_START;
- do
- {
- int len;
- short pkttype;
- ETH_header *ethpkt;
- ARP_header *arppkt;
- len = Inet_GetRawPacket(sock, buf, MTU, &pkttype);
- ethpkt = (ETH_header *)buf;
- arppkt = (ARP_header *)(buf + ETH_HEADER);
- TIME_FINISH;
- if (len > 0 && pkttype == PACKET_HOST && ethpkt->type == htons(ETH_P_ARP) && arppkt->opcode == htons(ARPOP_REPLY))
- {
- if ( *(unsigned long *)arppkt->source_ip == ip )
- {
- memcpy(&ar.arp_ha.sa_data, &arppkt->source_add, ETHER_ADDR_LEN);
- Inet_Forge_packet_destroy( buf );
- close(sock);
- return (char *) ar.arp_ha.sa_data;
- }
- }
- } while ( TIME_ELAPSED < 0.5 );
- return ETH_BROADCAST; // workaround for non local ip
- }
- close(sock);
- return (char *) ar.arp_ha.sa_data;
- }
- /* EOF */