// all.h
// 2005/06/20,a.m. wenxy
#ifndef _ALL_H
#define _ALL_H
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <string.h>
#include <errno.h>
// ---------------------
// ´´½¨ARP°üµÄÍ·Îļþ
#include<netinet/in.h>
#include<arpa/inet.h>
/* #include<linux/if_ether.h> */
#include<ctype.h>
#include <fcntl.h>
// ---------------------
#include <unistd.h>
#include <string>
#include <iostream>
using namespace std;
#define MAX_MAC_LEN 24 // MAC×Ö´®»º³åÇøµÄ×î´ó³¤¶È(byte)
#define COMPART_MAC ":" // MAC×Ö´®µÄ·Ö¸ñ·û, Warnning:Ð޸Ĵ˺꣬±ØÐëÔÙÐÞ¸ÄÔ´³ÌÐò!!!
#endif /* end _ALL_h */
// end file
// main.cpp
// 2005/06/20,a.m. wenxy
#include "all.h"
// function declare
static string GetLocalMac(string & strEth); // get loacl NIC's MAC
void set_ip_addr(char *,char *); // Ìî³äIP
void set_hw_addr(char buf[], char *str); // Ìî³äMAC
static string GetMacByIP(string strSrcIP, string strSrcMAC, string strDesIP ,string strNIC); // »ñÈ¡Ö¸¶¨IPµÄMAC
/*
#define SRC_IP "10.0.1.77" // Ô´IP
#define DES_IP "10.0.1.35" // Ä¿µÄIP
#define LOCAL_HW "00:C0:4C:39:0D:6F" // 10.0.1.77µÄeth0µÄMAC
#define DEVICE "eth0" // ½Ó¿Ú
*/
#define PADD_MAC "00:00:00:00:00:00" // Ìî³äµÄMAC
#define DES_MAC "FF:FF:FF:FF:FF:FF" // ¹ã²¥MAC
#define ARP_SEND_COUNT 3 // ·¢ËÍARPÇëÇóµÄARP°üµÄ¸öÊý
struct ether_header
{
unsigned char ether_dhost[6]; /* destination eth addr */
unsigned char ether_shost[6]; /* source ether addr */
unsigned short ether_type; /* packet type ID field */
};
struct arp_header
{
unsigned short int ar_hrd; /* Format of hardware address. */
unsigned short int ar_pro; /* Format of protocol address. */
unsigned char ar_hln; /* Length of hardware address. */
unsigned char ar_pln; /* Length of protocol address. */
// -------------------------
unsigned short int ar_op; /* ARP opcode (command). */
unsigned char __ar_sha[6]; /* Sender hardware address. */
unsigned char __ar_sip[4]; /* Sender IP address. */
unsigned char __ar_tha[6]; /* Target hardware address. */
unsigned char __ar_tip[4]; /* Target IP address. */
// -------------------------
};
struct arp_packet
{
struct ether_header ethhdr;
struct arp_header arphdr;
unsigned char padding[18]; /* filled with 0 */
};
/* arp reply:
* op = 2
* ethhdr.ether_dhost = arphdr.__ar_tha = switch hard addr
* ethhdr.ether_shost = arphdr.__ar_sha = local hard addr
* arphdr.__ar_tip = switch ip
* arphdr.__ar_sip = victim ip
*/
#define FRAME_TYPE 0x0806 /* arp=0x0806,rarp=0x8035 */
#define HARD_TYPE 1 /* ethernet is 1 */
#define PROTO_TYPE 0x0800 /* IP is 0x0800 */
#define OP_CODE 1 /* arp=1/2,1ΪÇëÇó£¬2ΪӦ´ð,rarp=3/4 */
// linuxÏ»ñÈ¡LANÀïÖ¸¶¨IPµÄÍø¿¨MAC
// In: argv[1]:±¾»úIP£¬argv[2]:Ä¿µÄIP
// Out:
int main( int argc, char *argv[] )
{
string strETH; // ±¾»úNICÃû³Æ
string strLocalMAC; // ±¾»úMAC
string strSrcIP; // ±¾»úIP
string strDesMAC; // Ä¿µÄMAC
string strDesIP; // Ä¿µÄIP
// ¼ì²é²ÎÊý
if ( argc != 4 )
{
printf("Useage: get_mac [interface name of the IP] [IP] [ARP IP]\n\n");
return 0;
}
strETH = argv[1]; //"eth0";
strSrcIP = argv[2]; //"10.0.1.77";
strDesIP = argv[3]; //"10.0.1.69";
printf("Run ......\n");
printf("»ñÈ¡ %s ½Ó¿ÚµÄMAC ......\n", strETH.c_str());
// »ñÈ¡Ö¸¶¨NICÃû³ÆµÄMAC
strLocalMAC = GetLocalMac(strETH);
#if 0
printf("Note: %s[%s]\n", strETH.c_str(), strLocalMAC.c_str());
#endif
// »ñÈ¡Ö¸¶¨½Ó¿ÚMAC
if ( 0 == strcmp( (const char*)strLocalMAC.c_str(), (const char*)"") )
{
printf("Error: call strcmp() failed\n");
printf("--------------------------------\n\n");
return -1;
}
else
{
printf("»ñÈ¡½Ó¿ÚMAC³É¹¦: %s [%s]\n", strETH.c_str(), strLocalMAC.c_str());
}
// »ñÈ¡Ö¸¶¨IPÍø¿¨µÄMAC
strDesMAC = GetMacByIP(strSrcIP, strLocalMAC, strDesIP, strETH);
printf("strDesMAC = %s\n", strDesMAC.c_str());
//
return 0;
}
// »ñÈ¡±¾µØijÍø¿¨µÄMAC
// In: strEth
// Out: Èô³É¹¦£¬·µ»ØMAC×Ö·û´®£¬Ê§°Ü£¬·µ»Ø""(¿Õ´®)
static string GetLocalMac(string & strEth)
{
string strLocalMAC;
int s;
struct ifreq buffer;
char chBuff[MAX_MAC_LEN];
memset(chBuff, 0x0, sizeof(chBuff));
//arp_process(NULL);
s = socket(PF_INET, SOCK_DGRAM, 0);
if (-1 == s)
{
printf("Error: create socket failture\n");
printf("--------------------------------\n\n");
return "";
}
memset(&buffer, 0x00, sizeof(buffer));
strcpy(buffer.ifr_name, strEth.c_str()); // "eth0"
if ( -1 == ioctl(s, SIOCGIFHWADDR, &buffer))
{
printf("Error: »ñÈ¡½Ó¿Ú %S MAC ʧ°Ü\n", strEth.c_str());
printf("--------------------------------\n\n");
return "";
}
close(s);
for( s = 0; s < 6; s++ )
{
memset(chBuff, 0x0, sizeof(chBuff));
sprintf( chBuff, "%.2X", (unsigned char)buffer.ifr_hwaddr.sa_data[s]);
strLocalMAC += chBuff;
//printf("%.2X", (unsigned char)buffer.ifr_hwaddr.sa_data[s]);
if (s < 5)
{
memset(chBuff, 0x0, sizeof(chBuff));
sprintf( chBuff, "%s", COMPART_MAC);
strLocalMAC += chBuff;
//printf(":");
}
}
//printf("\n");
return strLocalMAC;
}
//-------------------------------------------------------
// ·¢ËÍARP°ü£¬²¢½ÓÊÕARPÓ¦´ð°ü£¬È¡³öMAC
// In: strSrcIP:±¾»úIP£¬strSrcMAC:±¾»úIPµÄMAC£¬strDesIP:±»ÇëÇóÓ¦´ðMACµÄIP , strNIC:±¾µØ½Ó¿ÚÃû
// Out: Èô³É¹¦£¬·µ»ØMAC£¬Ê§°Ü·µ»Ø""(¿Õ´®)
static string GetMacByIP(string strSrcIP, string strSrcMAC, string strDesIP ,string strNIC)
{
int sockfd; // socket handle
struct arp_packet arp; // arp ÇëÇó°ü
struct arp_packet arpRes; // arp Ó¦Óôð°ü
struct sockaddr sa; // eth
char chSrcIP[24];
char chDesIP[24];
char chSrcMAC[24];
char chNIC[8];
memset(chSrcIP, 0x00, sizeof(chSrcIP));
memset(chDesIP, 0x00, sizeof(chDesIP));
memset(chSrcMAC, 0x00, sizeof(chSrcMAC));
memset(chNIC, 0x00, sizeof(chNIC));
sprintf(chSrcIP, "%s", strSrcIP.c_str());
sprintf(chDesIP, "%s", strDesIP.c_str());
sprintf(chSrcMAC, "%s", strSrcMAC.c_str());
sprintf(chNIC, "%s", strNIC.c_str());
#define SRC_IP chSrcIP // Ô´IP
#define DES_IP chDesIP // Ä¿µÄIP
#define LOCAL_HW chSrcMAC // eth0µÄMAC
#define DEVICE chNIC // ±¾»ú½Ó¿ÚÃû
memset(&arp, 0x00, sizeof(arp));
memset(&arpRes, 0x00, sizeof(arpRes));
#if 1
printf("Ô´IP[%s] Ô´MAC[%s] Ä¿µÄIP[%s]\n", strSrcIP.c_str(), strSrcMAC.c_str(), strDesIP.c_str());
#endif
sockfd = socket(AF_INET, SOCK_PACKET, htons(0x0806));
if(sockfd < 0)
{
printf("Error: create socket failed\n");
printf("--------------------------------\n\n");
return "";
}
/*
// ÉèÖÃsocketΪ·Ç×èÈûģʽ
if ( -1 != fcntl(sockfd, F_SETFL, O_NONBLOCK) )
{
printf("ÉèÖÃsocketΪ·Ç×èÈûģʽ³É¹¦\n");
}
else
{
printf("Warning: ÉèÖÃsocketΪ·Ç×èÈûģʽʧ°Ü[errno = %d]\n", errno);
}
*/
// ÉèÖÃsocket½ÓÊÕ³¬Ê±
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec= 100;
if ( 0 == setsockopt( sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) )
{
printf("ÉèÖÃsocket½ÓÊÕ³¬Ê±³É¹¦\n");
}
else
{
printf("Warning: ÉèÖÃsocket½ÓÊÕ³¬Ê±Ê§°Ü[errno = %d]\n", errno);
}
#if 1
printf("´´½¨socket SOCK_PACKET ³É¹¦\n");
printf("Note: ´´½¨ARPÇëÇó°ü ......\n");
printf("--------------------------------\n\n");
#endif
// ´´½¨ARPÇëÇó°ü
/* init arp packet header */
arp.ethhdr.ether_type = htons(FRAME_TYPE);
set_hw_addr( (char *)arp.ethhdr.ether_dhost, DES_MAC );
set_hw_addr( (char *)arp.ethhdr.ether_shost, LOCAL_HW );
#if 1
printf("%x|", arp.ethhdr.ether_type);
for (int i = 0; i < 6; i++)
{
printf("%d_", arp.ethhdr.ether_dhost[i]);
}
printf("|");
for (int i = 0; i < 6; i++)
{
printf("%d_", arp.ethhdr.ether_shost[i]);
}
printf("\n--------------------------------\n");
printf("³õʼ»¯ARP°üÖ¡Í·(ÒÔÌ«ÍøÊײ¿)³É¹¦\n\n");
#endif
/* init arp packet data */
printf("³õʼ»¯ARP°üÖ¡Êý¾Ý(ARPÇëÇó·Ö×é) ......\n");
printf("--------------------------------\n");
arp.arphdr.ar_hrd = htons(HARD_TYPE); // 1
arp.arphdr.ar_pro = htons(PROTO_TYPE); // 0x0800
arp.arphdr.ar_op = htons(OP_CODE); // 1
arp.arphdr.ar_hln = (unsigned char)(6);
arp.arphdr.ar_pln = (unsigned char)(4);
#if 1
printf("%d|%d|%d|%d|%d|\n", arp.arphdr.ar_hrd, arp.arphdr.ar_pro, arp.arphdr.ar_op, arp.arphdr.ar_hln, arp.arphdr.ar_pln);
printf("--------------------------------\n");
#endif
set_hw_addr((char *)arp.arphdr.__ar_tha, DES_MAC); // ÇëÇóIPµÄMAC
set_hw_addr((char *)arp.arphdr.__ar_sha, LOCAL_HW); // ·¢ËÍÕßµÄMAC
set_ip_addr((char *)arp.arphdr.__ar_tip, DES_IP); // ÇëÇóMACµÄIP
set_ip_addr((char *)arp.arphdr.__ar_sip, SRC_IP); // Ô´IP
bzero(arp.padding, 18); // Ìî³ä18¸ö×Ö½Ú
#if 1
for (int i = 0; i < 6; i++)
{
printf("%d_", arp.arphdr.__ar_sha[i]);
}
printf("|");
for (int i = 0; i < 6; i++)
{
printf("%d_", arp.arphdr.__ar_sip[i]);
}
printf("|");
for (int i = 0; i < 6; i++)
{
printf("%d_", arp.arphdr.__ar_tha[i]);
}
printf("|");
for (int i = 0; i < 6; i++)
{
printf("%d_", arp.arphdr.__ar_tip[i]);
}
printf("|");
printf("\n--------------------------------\n");
#endif
/* send arp reply packet */
memset(&sa, 0x00, sizeof(sa));
strcpy(sa.sa_data, DEVICE);
// ·¢ËÍARP°ü
int nSendCount = ARP_SEND_COUNT;
while( (nSendCount --) > 0)
{
printf("·¢ËÍARPÇëÇó°ü[%d Bytes]...... [µÚ%d¸ö]\n", sizeof(arp), nSendCount);
if( sendto(sockfd, &arp, sizeof(arp), 0, (struct sockaddr*) &sa, sizeof(sa)) < 0 )
{
printf("Error: ·¢ËÍARP°üʧ°Ü [errno = %d]\n", errno);
return "";
}
}
// ½ÓÊÕARPÓ¦´ð°ü
printf("NOte: ½ÓÊÕARPÓ¦´ð ......\n");
int nTryCount = 5;
int nRecvByte = 0;
int nAddrLen = sizeof(sa);
do
{
nRecvByte = recvfrom(sockfd, &arpRes, sizeof(arpRes),0, (struct sockaddr*)&sa, (socklen_t*)&nAddrLen);
// ÈôÊÇËùÇëÇóIPµÄARPÓ¦´ð°ü£¬Í˳öwhile
string strTarIP; /* Target IP address */
if ( nRecvByte >= 60 && 2 == ntohs(arpRes.arphdr.ar_op) )
{
char chBuff[MAX_MAC_LEN];
string strTarIP; /* Target IP address */
// ¸ñʽ»¯IP
for (int s = 0; s < 4; s++)
{
memset(chBuff, 0x00, sizeof(chBuff));
sprintf( (char *)chBuff, "%d", (unsigned char)arpRes.arphdr.__ar_sip[s]);
strTarIP += chBuff;
if (s < 3)
{
memset(chBuff, 0x00, sizeof(chBuff));
sprintf( (char *)chBuff, "%s", ".");
strTarIP += chBuff;
}
}
if ( !strcmp(strTarIP.c_str(), strDesIP.c_str()) )
{
printf("\nÇëÇóIP[%s] = Ó¦´ðIP[%s]\n", strDesIP.c_str(), strTarIP.c_str());
break;
}
}
}while( nTryCount -- ); // ½ÓÊÕARPÓ¦´ð°üµÄ´ÎÊý
printf("ÒѽÓÊÕµ½ARPÓ¦´ð°ü [%d Bytes]\n", nRecvByte);
// ½ÓÊÕ³¬Ê±£¬»ò´íÎó
if ( nRecvByte == -1 )
{
printf("Warning: ½ÓÊÕ³¬Ê±£¬»ò¼ÆËã»ú[%s]ûÓÐÏìÓ¦\n", strDesIP.c_str());
close(sockfd);
return "";
}
printf("·ÖÎöARPÓ¦´ð°ü ......\n");
char chBuff[MAX_MAC_LEN];
string strTarIP; /* Target IP address */
string strTarMAC; /* Target hardware address */
memset(chBuff, 0x00, sizeof(chBuff));
// ¸ñʽ»¯IP
for (int s = 0; s < 4; s++)
{
memset(chBuff, 0x00, sizeof(chBuff));
sprintf( (char *)chBuff, "%d", (unsigned char)arpRes.arphdr.__ar_sip[s]);
strTarIP += chBuff;
if (s < 3)
{
memset(chBuff, 0x00, sizeof(chBuff));
sprintf( (char *)chBuff, "%s", ".");
strTarIP += chBuff;
}
}
// ¸ñʽ»¯MAC
memset(chBuff, 0x00, sizeof(chBuff));
for (int s = 0; s < 6; s++)
{
memset(chBuff, 0x00, sizeof(chBuff));
sprintf( (char *)chBuff, "%02X", (unsigned char)arpRes.arphdr.__ar_sha[s]);
strTarMAC += chBuff;
if (s < 5)
{
memset(chBuff, 0x00, sizeof(chBuff));
sprintf( (char *)chBuff, "%s", COMPART_MAC);
strTarMAC += chBuff;
}
}
// Êä³öÄ¿µÄIP£¬Ä¿µÄMAC
printf("Ó¦´ðIP[%s] ¶ÔÓ¦µÄMAC[%s]\n", strTarIP.c_str(), strTarMAC.c_str());
printf("\n--------------------------------\n\n");
close(sockfd);
// ·µ»Ø±»ÇëÇóµÄMAC
return strTarMAC;
/* return */
}
// Ìî³äMAC
void set_hw_addr (char buf[], char *str)
{
int i;
char c, val;
for(i = 0; i < 6; i++)
{
if (!(c = tolower(*str++)))
perror("Invalid hardware address"),exit(1);
if (isdigit(c))
val = c - '0';
else if (c >= 'a' && c <= 'f')
val = c-'a'+10;
else
perror("Invalid hardware address"),exit(1);
buf[i] = val << 4;
if (!(c = tolower(*str++)))
perror("Invalid hardware address"),exit(1);
if (isdigit(c))
val = c - '0';
else if (c >= 'a' && c <= 'f')
val = c-'a'+10;
else
perror("Invalid hardware address"),exit(1);
buf[i] |= val;
if (*str == ':')
str++;
}
}
// Ìî³äIP
void set_ip_addr(char *buf, char *str)
{
struct in_addr addr;
memset(&addr, 0x00, sizeof(addr));
addr.s_addr = inet_addr(str);
memcpy(buf, &addr, 4);
}
//-------------------------------------------------------
// end file
# makefile
bin = get_mac
objets = main.o
rubbish = $(objets) $(bin)
$(bin) : main.o
g++ -o $(bin) main.o
main.o : main.cpp all.h
g++ -c main.cpp
.PHONY : clean
clean :
-rm $(rubbish)
# end makefile