在网上找到了这篇文章,http://www.examda.com/ncre2/JAVA/fudao/20060805/083135270.html,里面有介绍如何用java来实现ARP功能。
用到了一个叫Jpcap的包,可以到这里下载http://netresearch.ics.uci.edu/kfujii/Jpcap/doc/download.html。我机子的ide是netbean6.9.1 系统是winxp 32bit 我把代码稍微修改了一下,在netbean里面懒得搞输入了。代码如下,运行起来可以正确得到mac地址,我测试输入的是本机的ip地址,下面这段代码叫ARP
package ARP;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.Arrays;import jpcap.*;
import jpcap.packet.*;
public class ARP { public static byte[] arp(InetAddress ip) throws java.io.IOException{
int i;
NetworkInterface[] devices = JpcapCaptor.getDeviceList();
NetworkInterface device=null;
for(i=0;i<devices.length;i++){
System.out.println(devices[i].description);
}
device = devices[1]; //我的网卡是设备1 System.out.println("the device is"+device);
if(device==null){
throw new IllegalArgumentException(ip+"is not a local address");
}
JpcapCaptor captor=JpcapCaptor.openDevice(device, 2000, false, 3000);
captor.setFilter("arp", true);
JpcapSender sender=captor.getJpcapSenderInstance(); InetAddress srcip=null;
for(i=0;i<device.addresses.length;i++)
if(device.addresses[i].address instanceof Inet4Address){
srcip=device.addresses[i].address;
break;
}
byte[] broadcast = new byte[]{(byte)255,(byte)255,(byte)255,(byte)255,(byte)255,(byte)255};
ARPPacket arp = new ARPPacket();
arp.hardtype=ARPPacket.HARDTYPE_ETHER;
arp.prototype=ARPPacket.PROTOTYPE_IP;
arp.operation=ARPPacket.ARP_REQUEST;
arp.hlen=6;
arp.plen=4;
arp.sender_hardaddr=device.mac_address;
arp.sender_protoaddr=srcip.getAddress();
arp.target_hardaddr=broadcast;
arp.target_protoaddr=ip.getAddress(); EthernetPacket ether = new EthernetPacket();
ether.frametype=EthernetPacket.ETHERTYPE_ARP;
ether.src_mac=device.mac_address;
ether.dst_mac=broadcast;
arp.datalink=ether;
sender.sendPacket(arp);
while(true){
ARPPacket p = (ARPPacket)captor.getPacket();
if(p==null){
throw new IllegalArgumentException(ip+"is not a local address");
}
if(Arrays.equals(p.target_protoaddr,srcip.getAddress())){
return p.sender_hardaddr;
}
}
} public static void main(String args[])throws Exception{
int i;
if(args.length>1){
System.out.println("Usage:java ARP <ip address>");
}else{
byte addr[]= new byte[]{(byte)192,(byte)168,(byte)200,(byte)210}; //在这里修改IP地址
byte[] mac=ARP.arp(InetAddress.getByAddress(addr));
for(i=0;i<mac.length;i++){
System.out.print(Integer.toHexString(mac[i]&0xff)+":");
}
System.out.println();
System.exit(0);
}
} }接下一楼
用到了一个叫Jpcap的包,可以到这里下载http://netresearch.ics.uci.edu/kfujii/Jpcap/doc/download.html。我机子的ide是netbean6.9.1 系统是winxp 32bit 我把代码稍微修改了一下,在netbean里面懒得搞输入了。代码如下,运行起来可以正确得到mac地址,我测试输入的是本机的ip地址,下面这段代码叫ARP
package ARP;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.Arrays;import jpcap.*;
import jpcap.packet.*;
public class ARP { public static byte[] arp(InetAddress ip) throws java.io.IOException{
int i;
NetworkInterface[] devices = JpcapCaptor.getDeviceList();
NetworkInterface device=null;
for(i=0;i<devices.length;i++){
System.out.println(devices[i].description);
}
device = devices[1]; //我的网卡是设备1 System.out.println("the device is"+device);
if(device==null){
throw new IllegalArgumentException(ip+"is not a local address");
}
JpcapCaptor captor=JpcapCaptor.openDevice(device, 2000, false, 3000);
captor.setFilter("arp", true);
JpcapSender sender=captor.getJpcapSenderInstance(); InetAddress srcip=null;
for(i=0;i<device.addresses.length;i++)
if(device.addresses[i].address instanceof Inet4Address){
srcip=device.addresses[i].address;
break;
}
byte[] broadcast = new byte[]{(byte)255,(byte)255,(byte)255,(byte)255,(byte)255,(byte)255};
ARPPacket arp = new ARPPacket();
arp.hardtype=ARPPacket.HARDTYPE_ETHER;
arp.prototype=ARPPacket.PROTOTYPE_IP;
arp.operation=ARPPacket.ARP_REQUEST;
arp.hlen=6;
arp.plen=4;
arp.sender_hardaddr=device.mac_address;
arp.sender_protoaddr=srcip.getAddress();
arp.target_hardaddr=broadcast;
arp.target_protoaddr=ip.getAddress(); EthernetPacket ether = new EthernetPacket();
ether.frametype=EthernetPacket.ETHERTYPE_ARP;
ether.src_mac=device.mac_address;
ether.dst_mac=broadcast;
arp.datalink=ether;
sender.sendPacket(arp);
while(true){
ARPPacket p = (ARPPacket)captor.getPacket();
if(p==null){
throw new IllegalArgumentException(ip+"is not a local address");
}
if(Arrays.equals(p.target_protoaddr,srcip.getAddress())){
return p.sender_hardaddr;
}
}
} public static void main(String args[])throws Exception{
int i;
if(args.length>1){
System.out.println("Usage:java ARP <ip address>");
}else{
byte addr[]= new byte[]{(byte)192,(byte)168,(byte)200,(byte)210}; //在这里修改IP地址
byte[] mac=ARP.arp(InetAddress.getByAddress(addr));
for(i=0;i<mac.length;i++){
System.out.print(Integer.toHexString(mac[i]&0xff)+":");
}
System.out.println();
System.exit(0);
}
} }接下一楼
下面是ARPGUI的代码
package ARP;
import java.awt.*;
import java.awt.event.*;import jpcap.*;
import jpcap.packet.*;import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.Arrays;public class ARPGUI implements ActionListener{ NetworkInterface device = null;
NetworkInterface[] devicelist = null; String str_ip1,str_ip2,str_ip3,str_ip4;
int int_ip1,int_ip2,int_ip3,int_ip4;
byte b_ip1,b_ip2,b_ip3,b_ip4;
byte[] ipaddr; Frame f;
Panel p1,p2,p3,p4,p5,p6,pa,pb,pc; //p1里面的东东
Label IPLabel; //p2里面的东东
TextField T_IP1,T_IP2,T_IP3,T_IP4;
Button B_run; //p3里面的东东
TextArea T_device; //p4里面的东东
Label InLabel;
TextField T_deviceID;
Button B_apply; //p5里面的东东
Label MACLabel; //p6里面的东东
TextArea T_MACaddr; ARPcode arpcode;
public ARPGUI(){
//加入p1
p1 = new Panel();
p1.setLayout(new FlowLayout(FlowLayout.LEFT));
IPLabel = new Label("请输入IP地址");
p1.add(IPLabel); //加入p2
p2 = new Panel();
p2.setLayout(new FlowLayout(FlowLayout.LEFT));
T_IP1 = new TextField(3);
T_IP2 = new TextField(3);
T_IP3 = new TextField(3);
T_IP4 = new TextField(3);
B_run = new Button("启动");
B_run.addActionListener(this);
p2.add(T_IP1);
p2.add(T_IP2);
p2.add(T_IP3);
p2.add(T_IP4);
p2.add(B_run); //加入p3
p3 = new Panel();
T_device = new TextArea(6,45);
p3.add(T_device); //加入p4
p4 = new Panel();
InLabel = new Label("输入网卡序号");
T_deviceID = new TextField(6);
B_apply = new Button("确定");
B_apply.addActionListener(this);
p4.setLayout(new BorderLayout());
p4.add("North",InLabel);
p4.add("Center",T_deviceID);
p4.add("South",B_apply); //加入P5
p5 = new Panel();
MACLabel = new Label("MAC地址");
p5.setLayout(new BorderLayout());
p5.add("Center",MACLabel); //加入p6
p6 = new Panel();
T_MACaddr = new TextArea(6,45);
p6.add(T_MACaddr); //p1,p2加入pa
pa = new Panel();
pa.setLayout(new GridLayout(2,1));
pa.add(p1);
pa.add(p2); //p3,p4加入pb
pb = new Panel();
pb.setLayout(new FlowLayout(FlowLayout.CENTER,0,0));
pb.add(p3);
pb.add(p4); //p5,p6加入pc
pc = new Panel();
pc.setLayout(new FlowLayout(FlowLayout.CENTER,0,0));
pc.add(p5);
pc.add(p6); //全部加入frame
f = new Frame();
f.setTitle("MAC地址查询");
f.setLayout(new BorderLayout());
f.add("North",pa);
f.add("Center",pb);
f.add("South",pc);
f.pack();
f.setVisible(true); f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
}
public void actionPerformed(ActionEvent ae) {
if(ae.getSource()==B_run){
str_ip1 = T_IP1.getText();
str_ip2 = T_IP2.getText();
str_ip3 = T_IP3.getText();
str_ip4 = T_IP4.getText(); int_ip1 = Integer.parseInt(str_ip1);
int_ip2 = Integer.parseInt(str_ip2);
int_ip3 = Integer.parseInt(str_ip3);
int_ip4 = Integer.parseInt(str_ip4); b_ip1 = (byte)int_ip1;
b_ip2 = (byte)int_ip2;
b_ip3 = (byte)int_ip3;
b_ip4 = (byte)int_ip4; ipaddr = new byte[]{b_ip1,b_ip1,b_ip1,b_ip1};
arpcode = new ARPcode(ipaddr);
print();
}
if(ae.getSource()==B_apply){
int number=Integer.parseInt(T_deviceID.getText());
device = devicelist[number];
byte[] b;
try{
b =arpcode.macaddr(device);
T_MACaddr.append(str_ip1+"."+str_ip2+"."+str_ip3+"."+str_ip4+"---");
int i;
for(i=0;i<b.length;i++){
T_MACaddr.append(Integer.toHexString(b[i]&0xff)+":");
}
T_MACaddr.append("\r\n");
}catch(Exception eee){}
} } public void print(){
int i;
devicelist = arpcode.printDevice();
T_device.setText(""); for(i=0;i<devicelist.length;i++){
T_device.append(i+".");
T_device.append(devicelist[i].description+"\r\n");
} if(i==0){
device = devicelist[0]; if(device==null){
T_device.setText("no decice is founded, please check your configure");
}
} } public static void main(String args[]){ new ARPGUI();
}}下面是ARPcode的代码package ARP;import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.Arrays;import jpcap.*;
import jpcap.packet.*;public class ARPcode { byte[ ipaddress; public ARPcode(byte[] ipaddress){
this.ipaddress = ipaddress; } public NetworkInterface[] printDevice(){
NetworkInterface[] devices = JpcapCaptor.getDeviceList();
return devices;
} public byte[] arp(InetAddress ip,NetworkInterface dev) throws java.io.IOException { int i;
JpcapCaptor captor=JpcapCaptor.openDevice(dev, 2000, false, 3000);
captor.setFilter("arp", true);
JpcapSender sender=captor.getJpcapSenderInstance(); InetAddress srcip=null; for(i=0;i<dev.addresses.length;i++)
if(dev.addresses[i].address instanceof Inet4Address){
srcip=dev.addresses[i].address;
break;
}
byte[] broadcast = new byte[]{(byte)255,(byte)255,(byte)255,(byte)255,(byte)255,(byte)255};
ARPPacket arp = new ARPPacket();
arp.hardtype=ARPPacket.HARDTYPE_ETHER;
arp.prototype=ARPPacket.PROTOTYPE_IP;
arp.operation=ARPPacket.ARP_REQUEST;
arp.hlen=6;
arp.plen=4;
arp.sender_hardaddr=dev.mac_address;
arp.sender_protoaddr=srcip.getAddress();
arp.target_hardaddr=broadcast;
arp.target_protoaddr=ip.getAddress(); EthernetPacket ether = new EthernetPacket();
ether.frametype=EthernetPacket.ETHERTYPE_ARP;
ether.src_mac=dev.mac_address;
ether.dst_mac=broadcast;
arp.datalink=ether; sender.sendPacket(arp); while(true){
ARPPacket p = (ARPPacket)captor.getPacket();
if(p==null){
throw new IllegalArgumentException(ip+"is not a local address");
}
if(Arrays.equals(p.target_protoaddr,srcip.getAddress())){
return p.sender_hardaddr;
}
}}
public byte[] macaddr(NetworkInterface dev1) throws java.lang.Exception {
int i;
byte[] mac; mac=arp(InetAddress.getByAddress(ipaddress),dev1);
return mac;
}}
ps:awt在我的netbean里面不能正确显示中文字符,得把编码改成GBK.....唉......
我在ARPGUI里面输入本机的ip地址,但是得到的却是网关的mac地址,请问大家,这是什么原因啊?还有,TCPIP协议是分的5层,物理层,数据链路层,网络层,传输层,应用层。那请问,java可以工作到第几层啊?在工作的协议层方面跟C/C++又有什么区别呢?烦请大家赐教,感激不尽!