ec_inet.c
上传用户:nilegod
上传日期:2007-01-08
资源大小:220k
文件大小:17k
- /*
- ettercap -- inet utilities, arp ping and more...
- 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.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/time.h>
- #include <sys/ioctl.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <errno.h>
- #include "include/ec_main.h"
- #include "include/ec_error.h"
- #include "include/ec_inet_structures.h"
- #include "include/ec_inet_forge.h"
- #include "include/ec_buffer.h"
- #ifdef DEBUG
- #include "include/ec_debug.h"
- #endif
- char ETH_BROADCAST[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
- char ARP_BROADCAST[6] = {0x0,0x0,0x0,0x0,0x0,0x0};
- typedef struct {
- u_long IP_Add;
- u_char MAC_Add[6];
- struct host_list *next;
- } host_list;
- struct ifreq old_ifr; // old iface flags
- #ifdef LINUX
- char IpForward_status[2]; // old ipforward status
- #else
- int IpForward_status; // old ipforward status
- #endif
- // protos...
- char * Inet_HostName(char *ip);
- char * Inet_NameToIp(char *name);
- char * Inet_GetMyInfo(char tipo);
- char * Inet_MyIPAddress(void);
- char * Inet_MyMACAddress(void);
- char * Inet_MySubnet(void);
- int Inet_HostInLAN(void);
- void Inet_Free_list(host_list *head);
- host_list *Inet_Host_in_LAN_list(char *interface);
- SniffingHost *Inet_NoSniff(void);
- void Inet_PutMACinString(char *mac_string, unsigned char *MAC);
- void Inet_GetMACfromString(char *mac_string, unsigned char *MAC);
- int Inet_Fake_Host(void);
- int Inet_CheckSwitch(void);
- // Following are architecture dependent !! implementations are in ./src/`uname`/ec_inet_`uname`.c
- int Inet_FindIFace(char *iface);
- char 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);
- int Inet_GetRawPacket(int sock, char *buffer, int MTU, short *type);
- int Inet_SendRawPacket(int sock, char *buffer, int len);
- void Inet_Restore_ifr(void);
- void Inet_DisableForwarding(void);
- void Inet_RestoreForwarding(void);
- char *Inet_MacFromIP(unsigned long ip);
- // ----------------------------------------
- #ifdef LINUX
- #include "linux/ec_inet_linux.c" // Architecture dependent implemetation of Inet functions...
- #endif
- #ifdef FREEBSD
- #include "BSD/ec_inet_BSD.c"
- #endif
- #ifdef OPENBSD
- #include "BSD/ec_inet_BSD.c"
- #endif
- // ----------------------------------------
- char * Inet_HostName(char *ip) // returns hostname from ip
- {
- struct hostent *host;
- static struct in_addr addr;
- addr.s_addr = inet_addr(ip);
- host = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET);
- if (host != NULL) return (char *) host->h_name;
- return "Unknown host";
- }
- char * Inet_NameToIp(char *name) // returns ip from hostname
- {
- struct hostent *host;
- static char ip[16];
- host = gethostbyname(name);
- if (host != NULL)
- strncpy(ip, inet_ntoa( *(struct in_addr *) *host->h_addr_list), 16);
- else
- strncpy(ip, "(null)", 16);
- return ip;
- }
- char * Inet_GetMyInfo(char tipo)
- {
- struct in_addr to_convert;
- u_long IP_Add, NetMask;
- unsigned char MAC_Add[6];
- static char MAC[18];
- static char MySubnet[16];
- static char IP[16];
- #ifdef DEBUG
- switch (tipo)
- {
- case 0: Debug_msg("Inet_GetMyInfo IP"); break;
- case 1: Debug_msg("Inet_GetMyInfo MAC"); break;
- case 2: Debug_msg("Inet_GetMyInfo NetMask"); break;
- }
- #endif
- Inet_GetIfaceInfo(Options.netiface, NULL, MAC_Add, &IP_Add, &NetMask);
- switch (tipo)
- {
- case 0: // requesting IP
- to_convert.s_addr = IP_Add;
- sprintf(IP, "%s", inet_ntoa(to_convert));
- return IP;
- break;
- case 1: // requesting MAC
- Inet_PutMACinString( MAC, MAC_Add );
- return MAC;
- break;
- case 2: // requesting netmask
- to_convert.s_addr = NetMask;
- sprintf(MySubnet, "%s", inet_ntoa(to_convert));
- return MySubnet;
- break;
- }
- return "(none)";
- }
- char * Inet_MyIPAddress(void)
- {
- return Inet_GetMyInfo(0);
- }
- char * Inet_MyMACAddress(void)
- {
- return Inet_GetMyInfo(1);
- }
- char * Inet_MySubnet(void)
- {
- return Inet_GetMyInfo(2);
- }
- int Inet_HostInLAN()
- {
- host_list *list;
- host_list *index;
- int host_alive = 0, k = 0;
- #ifdef DEBUG
- Debug_msg("Inet_HostInLANtIface: %s", Options.netiface);
- #endif
- list = Inet_Host_in_LAN_list(Options.netiface);
- index = list;
- for( ; index; host_alive++)
- index = (host_list *)index->next;
- if (Host_In_LAN) free(Host_In_LAN);
- Host_In_LAN = (HOST *)calloc(host_alive,sizeof(HOST));
- if (Host_In_LAN == NULL)
- Error_msg("ec_Inet:%d calloc() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
- index = list;
- for( ; index; index = (host_list *)index->next)
- {
- struct in_addr to_convert;
- to_convert.s_addr = index->IP_Add;
- sprintf(Host_In_LAN[k].ip,"%s",inet_ntoa(to_convert));
- snprintf(Host_In_LAN[k].name, 128, "%s", Inet_HostName(Host_In_LAN[k].ip));
- Inet_PutMACinString(Host_In_LAN[k].mac, index->MAC_Add);
- k++;
- }
- Inet_Free_list(list);
- return host_alive;
- }
- void Inet_Free_list(host_list *head)
- {
- if (!head) return;
- Inet_Free_list((host_list *) head->next);
- free(head);
- }
- host_list *Inet_Host_in_LAN_list(char *interface)
- {
- int sock, N_hosts, index, MTU;
- u_long NetMask, BroadAdd;
- host_list *head;
- u_char *buf;
- TIME_DECLARE;
- #ifdef DEBUG
- Debug_msg("Inet_HostInLAN_list");
- #endif
- head = (host_list *)malloc(sizeof(host_list));
- if (head == NULL)
- Error_msg("ec_Inet:%d malloc() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
- head->next = NULL;
- sock = Inet_OpenRawSock(interface);
- Inet_GetIfaceInfo(interface, &MTU, head->MAC_Add, &head->IP_Add, &NetMask);
- if (Options.silent) return head;
- N_hosts = ntohl(~NetMask);
- #ifdef DEBUG
- Debug_msg("Inet_HostInLAN_list -- netmask 0x%0x hosts %d", NetMask, N_hosts);
- #endif
- if (Options.broadping)
- {
- BroadAdd = head->IP_Add | (~NetMask);
- buf = Inet_Forge_packet( ETH_HEADER + IP_HEADER + ICMP_HEADER );
- Inet_Forge_ethernet( buf, head->MAC_Add, ETH_BROADCAST, ETH_P_IP );
- Inet_Forge_ip( buf + ETH_HEADER,
- head->IP_Add,
- BroadAdd,
- sizeof(ICMP_header),
- 0xe77e,
- 0,
- IPPROTO_ICMP );
- Inet_Forge_icmp( buf + ETH_HEADER + IP_HEADER, ICMP_ECHO, 0, NULL, 0 );
- Inet_SendRawPacket(sock, buf, ETH_HEADER + IP_HEADER + ICMP_HEADER);
- Inet_Forge_packet_destroy( buf );
- }
- else // !broadping
- {
- buf = Inet_Forge_packet( ETH_HEADER + ARP_HEADER );
- // frame ethernet header
- Inet_Forge_ethernet( buf, head->MAC_Add, ETH_BROADCAST, ETH_P_ARP );
- for (index=1; index<=N_hosts; index++)
- {
- int dest_ip;
- dest_ip = (head->IP_Add&NetMask)|htonl(index);
- // if dest is equal to me
- if (dest_ip != head->IP_Add)
- {
- // arp request
- Inet_Forge_arp( buf+ETH_HEADER, ARPOP_REQUEST,
- head->MAC_Add, head->IP_Add,
- ARP_BROADCAST, dest_ip );
- Inet_SendRawPacket(sock, buf, ETH_HEADER + ARP_HEADER);
- }
- usleep(500);
- }
- Inet_Forge_packet_destroy( buf );
- }
- #ifdef DEBUG
- Debug_msg("Inet_HostInLAN_list -- listening for replies...");
- #endif
- fcntl(sock, F_SETFL, O_NONBLOCK);
- TIME_START;
- buf = Inet_Forge_packet( MTU );
- if (Options.broadping)
- {
- do
- {
- short pkttype;
- int len;
- host_list **index;
- ETH_header *HEther;
- IP_header *HIP;
- TIME_FINISH;
- len = Inet_GetRawPacket(sock, buf, MTU, &pkttype);
- if (len > 0 && pkttype == PACKET_HOST)
- {
- HEther = (ETH_header *) buf;
- if ( ntohs(HEther->type) == ETH_P_IP )
- {
- HIP = (IP_header *)(HEther + 1);
- if (HIP->proto != IPPROTO_ICMP) continue;
- index = &head;
- #ifdef DEBUG
- Debug_msg("Inet_HostInLAN_list -- got a reply after %.5f seconds", TIME_ELAPSED );
- #endif
- while(*index != NULL && memcmp(&((*index)->IP_Add),&HIP->source_ip,4))
- index = (host_list **)&((*index)->next);
- if (*index == NULL)
- {
- if ( (*index = (host_list *)malloc(sizeof(host_list))) == NULL)
- Error_msg("ec_inet:%d malloc() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
- (*index)->next = NULL;
- memcpy((*index)->MAC_Add, HEther->source_mac, 6);
- memcpy((char *)&((*index)->IP_Add), &HIP->source_ip, 4);
- }
- }
- }
- } while ( TIME_ELAPSED < 1 );
- }
- else // !broadping
- {
- do
- {
- int leng = 0;
- short pkttype;
- host_list **index;
- ETH_header *ethpkt;
- ARP_header *arppkt;
- leng = Inet_GetRawPacket(sock, buf, MTU, &pkttype);
- ethpkt = (ETH_header *)buf;
- arppkt = (ARP_header *)(buf + ETH_HEADER);
- TIME_FINISH;
- if (leng > 0 && pkttype == PACKET_HOST && ethpkt->type == htons(ETH_P_ARP) && arppkt->opcode == htons(ARPOP_REPLY))
- {
- index = &head;
- #ifdef DEBUG
- Debug_msg("Inet_HostInLAN_list -- got a reply after %.5f seconds", TIME_ELAPSED );
- #endif
- while(*index != NULL && memcmp(&((*index)->IP_Add),arppkt->source_ip,4))
- index = (host_list **)&((*index)->next);
- if (*index == NULL)
- {
- if ( (*index = (host_list *)malloc(sizeof(host_list))) == NULL)
- Error_msg("ec_inet:%d malloc() | ERRNO : %d | %s", __LINE__, errno, sys_errlist[errno]);
- (*index)->next = NULL;
- memcpy((*index)->MAC_Add, arppkt->source_add, 6);
- memcpy((char *)&((*index)->IP_Add), arppkt->source_ip, 4);
- }
- }
- } while ( TIME_ELAPSED < 1.5 );
- }
- Inet_Forge_packet_destroy( buf );
- close(sock);
- return head;
- }
- SniffingHost *Inet_NoSniff(void)
- {
- static SniffingHost *SniffTable=NULL;
- int i, j, len, sock, MTU, SniffTableIndex=0;
- ETH_header *HEther;
- IP_header *HIP;
- u_char *buf;
- TIME_DECLARE;
- #ifdef DEBUG
- Debug_msg("Inet_NoSniff");
- #endif
- if (SniffTable) free (SniffTable);
- SniffTable = calloc(number_of_hosts_in_lan, sizeof(SniffingHost));
- memset(SniffTable,0,sizeof(SniffingHost)*number_of_hosts_in_lan);
- sock = Inet_OpenRawSock(Options.netiface);
- Inet_GetIfaceInfo(Options.netiface, &MTU, NULL, NULL, NULL);
- buf = Inet_Forge_packet( ETH_HEADER + IP_HEADER + ICMP_HEADER );
- for (i=0; i<number_of_hosts_in_lan; i++)
- {
- if (inet_addr(Inet_MyIPAddress()) != inet_addr(Host_In_LAN[i].ip))
- {
- char MyMAC[6];
- char DestMAC[6];
- Inet_GetMACfromString(Host_In_LAN[0].mac, MyMAC);
- Inet_GetMACfromString(Host_In_LAN[i].mac, DestMAC);
- Inet_Forge_ethernet( buf, MyMAC, DestMAC, ETH_P_IP );
- Inet_Forge_ip( buf + ETH_HEADER,
- inet_addr(Host_In_LAN[0].ip),
- inet_addr(Host_In_LAN[i].ip),
- sizeof(ICMP_header),
- 0xe77e,
- 0,
- IPPROTO_ICMP );
- Inet_Forge_icmp( buf + ETH_HEADER + IP_HEADER, ICMP_ECHO, 0, NULL, 0 );
- Inet_SendRawPacket(sock, buf, ETH_HEADER + IP_HEADER + ICMP_HEADER);
- usleep(1000);
- }
- }
- Inet_Forge_packet_destroy( buf );
- #ifdef DEBUG
- Debug_msg("Inet_NoSniff -- after ICMP storm");
- #endif
- buf = Inet_Forge_packet( MTU );
- fcntl(sock, F_SETFL, O_NONBLOCK);
- TIME_START;
- // Search for strange replies
- do
- {
- short pkttype;
- TIME_FINISH;
- len = Inet_GetRawPacket(sock, buf, MTU, &pkttype);
- if (len > 0 && pkttype == PACKET_HOST)
- {
- HEther = (ETH_header *) buf;
- if ( ntohs(HEther->type) == ETH_P_IP )
- {
- unsigned char MACS[20];
- HIP = (IP_header *)(HEther + 1);
- Inet_PutMACinString(MACS, HEther->source_mac);
- if (HIP->proto != IPPROTO_ICMP) continue;
- #ifdef DEBUG
- Debug_msg("Inet_NoSniff -- got a ICMP reply after %.5f seconds", TIME_ELAPSED );
- #endif
- for(i=0; i<number_of_hosts_in_lan; i++)
- {
- if ( inet_addr(Host_In_LAN[i].ip ) == HIP->source_ip )
- {
- if (memcmp(MACS,Host_In_LAN[i].mac,17))
- {
- for (j=0; j<number_of_hosts_in_lan; j++)
- if (!memcmp(MACS, Host_In_LAN[j].mac, 17)) break;
- SniffTable[SniffTableIndex].Host_Index1=j;
- SniffTable[SniffTableIndex].Host_Index2=i;
- SniffTable[SniffTableIndex].mode=1;
- SniffTableIndex++;
- break;
- }
- }
- }
- }
- }
- } while ( TIME_ELAPSED < 3 );
- // Search for strange ARP entries
- for (i=0; i<number_of_hosts_in_lan-1; i++)
- for(j=i+1; j<number_of_hosts_in_lan; j++)
- if (!memcmp(Host_In_LAN[i].mac, Host_In_LAN[j].mac, 17))
- {
- SniffTable[SniffTableIndex].Host_Index1=i;
- SniffTable[SniffTableIndex].Host_Index2=j;
- SniffTable[SniffTableIndex].mode=2;
- SniffTableIndex++;
- }
- Inet_Forge_packet_destroy( buf );
- close(sock);
- return (SniffTable);
- }
- int Inet_Fake_Host()
- {
- unsigned int N_hosts, index, index1=0, index2, base_ip, fake_ip=0;
- unsigned long NetMask;
- Inet_GetIfaceInfo(Options.netiface, NULL, NULL, NULL, &NetMask);
- N_hosts = ntohl(~NetMask);
- base_ip = inet_addr(Host_In_LAN[0].ip)&NetMask;
- for (index=1; index<N_hosts; index++)
- {
- fake_ip = base_ip|htonl(index);
- for (index2=0; index2 < number_of_hosts_in_lan; index2++)
- if (fake_ip == inet_addr(Host_In_LAN[index2].ip))
- break;
- if (index2 == number_of_hosts_in_lan) break;
- }
- if (index1 == N_hosts) return 0;
- return (fake_ip);
- }
- // 0 - Unknown
- // 1 - Hub
- // 2 - Switch
- int Inet_CheckSwitch()
- {
- int link_type=2;
- if (number_of_hosts_in_lan>1)
- {
- int fakeip,destip,sock,MTU,i;
- char MyMAC[6],DestMAC[6];
- char *buf;
- TIME_DECLARE;
- fakeip=Inet_Fake_Host();
- destip=inet_addr(Host_In_LAN[1].ip);
- Inet_GetMACfromString(Host_In_LAN[1].mac, DestMAC);
- sock = Inet_OpenRawSock(Options.netiface);
- fcntl(sock, F_SETFL, O_NONBLOCK);
- Inet_GetIfaceInfo(Options.netiface, &MTU, MyMAC, NULL, NULL);
- Inet_SetPromisc(Options.netiface);
- buf = Inet_Forge_packet(MTU);
- Inet_Forge_ethernet( buf, MyMAC, DestMAC, ETH_P_IP );
- Inet_Forge_ip( buf + ETH_HEADER,
- fakeip, destip,
- sizeof(ICMP_header),
- 0xe77e, 0,
- IPPROTO_ICMP );
- Inet_Forge_icmp( buf + ETH_HEADER + IP_HEADER, ICMP_ECHO, 0, NULL, 0 );
- Inet_SendRawPacket(sock, buf, ETH_HEADER + IP_HEADER + ICMP_HEADER);
- Inet_Forge_ethernet( buf, MyMAC, DestMAC, ETH_P_ARP );
- Inet_Forge_arp( buf+ETH_HEADER, ARPOP_REPLY,
- DestMAC, fakeip,
- DestMAC, destip );
- for(i=0; i<5; i++)
- {
- usleep(1000);
- Inet_SendRawPacket(sock, buf, ETH_HEADER + ARP_HEADER);
- }
- TIME_START;
- do
- {
- short type; int len;
- len=Inet_GetRawPacket(sock,buf,MTU,&type);
- TIME_FINISH;
- if (len>0)
- {
- ETH_header *eth;
- eth=(ETH_header *)buf;
- if (!memcmp(DestMAC,eth->dest_mac,6))
- {
- link_type=1;
- break;
- }
- }
- }while(TIME_ELAPSED<1);
- free(buf);
- close(sock);
- }
- else return 0;
- Inet_Restore_ifr();
- return link_type;
- }
- void Inet_GetMACfromString(char *mac_string, unsigned char *MAC)
- {
- unsigned int MAC_Add[6];
- int i;
- memset(&MAC_Add, 0, 6);
- i = sscanf(mac_string,"%02X:%02X:%02X:%02X:%02X:%02X",
- (unsigned int *)&MAC_Add[0],(unsigned int *)&MAC_Add[1],(unsigned int *)&MAC_Add[2],
- (unsigned int *)&MAC_Add[3],(unsigned int *)&MAC_Add[4],(unsigned int *)&MAC_Add[5]);
- if (i == 0)
- Error_msg("Incorrect parsing of MAC [%s] !!nIt must be in the form 01:02:03:04:05:06 !!", mac_string);
- for (i=0; i<6; i++)
- MAC[i]=(unsigned char)MAC_Add[i];
- }
- void Inet_PutMACinString(char *mac_string, unsigned char *MAC)
- {
- unsigned int MAC_Add[6];
- int i;
- for (i=0; i<6; i++)
- MAC_Add[i]=(unsigned int)MAC[i];
- sprintf(mac_string,"%02X:%02X:%02X:%02X:%02X:%02X",
- (unsigned int)MAC_Add[0],(unsigned int)MAC_Add[1],(unsigned int)MAC_Add[2],
- (unsigned int)MAC_Add[3],(unsigned int)MAC_Add[4],(unsigned int)MAC_Add[5]);
- }
- /* EOF */