1 遍历本机的路由信息
遍历出所有的route 信息,类似route PRINT
思路比较简单,直接用 GetIpForwardTable 获取本机的所有的路由信息,逐一遍历即可
PMIB_IPFORWARDTABLE pIpForwardTable = NULL;
PMIB_IPFORWARDROW pRow = NULL;
DWORD dwSize = 0;
BOOL bOrder = FALSE;
DWORD dwStatus = 0;
DWORD NewGateway = 0xDDBBCCAA; // this is in host order Ip Address AA.BB.CC.DD is DDCCBBAA
// Find out how big our buffer needs to be.
dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
if (dwStatus == ERROR_INSUFFICIENT_BUFFER) {
// Allocate the memory for the table
if (!(pIpForwardTable = (PMIB_IPFORWARDTABLE)malloc(dwSize))) {
printf("Malloc failed. Out of memory./n");
exit(1);
}
// Now get the table.
dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
}
if (dwStatus != ERROR_SUCCESS) {
printf("getIpForwardTable failed./n");
if (pIpForwardTable)
free(pIpForwardTable);
exit(1);
}
// Search for the row in the table we want. The default gateway has a destination
// of 0.0.0.0. Notice that we continue looking through the table, but copy only
// one row. This is so that if there happen to be multiple default gateways, we can
// be sure to delete them all.
for (unsigned long int i=0; i < pIpForwardTable->dwNumEntries; i++) {
in_addr in;
in.S_un.S_addr = pIpForwardTable->table[i].dwForwardDest;
printf("dwForwardDest %d %s /n ",pIpForwardTable->table[i].dwForwardDest,inet_ntoa(in));
}
if (pIpForwardTable)
free(pIpForwardTable);
if (pRow)
free(pRow);
2 获取到到指定IP的路由信息
这个就比较麻烦,不仅仅是本机的路由表的问题,还需要获取网络上其他主机的路由信息
类似 routert 124.42.77.38
TraceRoute程序在具体实现时,是令其向目的主机发送一个ICMP回显请求(Echo request)消息,并重复递增IP头部TTL字段的值。刚开始的时候TTL等于1,这样当该数据报抵达途中的第一个路由器时,TTL的值就被减为0,导致发生超时错误,因此该路由器生成一份ICMP超时差错报文返回给源主机。随后,主机将数据报的TTL值递增1,以便IP报文能传递到下一个路由器,下一个路由器将会生成ICMP超时超时差错报文返回给源主机。不断重复这个过程,直到数据报到达最终的目的主机,此时目的主机将返回ICMP回显应答(Echo replay)消息。这样,源主机只需对返回的每一份ICMP报文进行解析处理,就可以掌握数据报从源主机到达目的主机途中所经过的路由信息。
为了方便,直接使用Icmp函数来处理
char dstip[64] ;
strcpy(dstip,"124.42.77.38");
//if(argc!=2){
// printf("Usage: %s destIP/n",argv[0]);
// exit(-1);
//}
//WSADATA wsa;
//if(WSAStartup(MAKEWORD(2,2),&wsa)!=0){
// printf("WSAStartup failed./n");
// exit(-1);
//}
//转换IP地址到整数
unsigned long ip = inet_addr(dstip);
if(ip==INADDR_NONE){
//用户可能输入的是域名
hostent* pHost = gethostbyname(dstip);
//如果域名无法解析
if(pHost==NULL){
printf("Invalid IP or domain name: %s/n", dstip);
exit(-1);
}
//取域名的第一个IP地址
ip = *(unsigned long*)pHost->h_addr_list[0];
printf("trace route to %s(%s)/n/n",dstip,inet_ntoa(*(in_addr*)&ip));
}else{
printf("trace route to %s/n/n",dstip);
}
//打开ICMP句柄
HANDLE hIcmp;
if ((hIcmp = IcmpCreateFile()) == INVALID_HANDLE_VALUE){
printf("/tUnable to open ICMP file./n");
exit(-1);
}
//设置IP报头的TTL值
IP_OPTION_INFORMATION IpOption;
ZeroMemory(&IpOption,sizeof(IP_OPTION_INFORMATION));
IpOption.Ttl = 1;
//设置要发送的数据
char SendData[32];
memset(SendData,'0',sizeof(SendData));
//设置接收缓冲区
char ReplyBuffer[sizeof(ICMP_ECHO_REPLY)+32];
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
BOOL bLoop = TRUE;
int iMaxHop = 30;
while(bLoop && iMaxHop--){
printf("%2d: ",IpOption.Ttl);
//发送ICMP回显请求
if(IcmpSendEcho(hIcmp,(IPAddr)ip, SendData, sizeof(SendData), &IpOption,
ReplyBuffer, sizeof(ReplyBuffer), 3000)!=0){
if(pEchoReply->RoundTripTime==0){
printf("/t<1ms");
}else{
printf("/t%dms",pEchoReply->RoundTripTime);
}
printf("/t%s/n",inet_ntoa(*(in_addr*)&(pEchoReply->Address)));
//判断是否完成路由路径探测
if((unsigned long)pEchoReply->Address==ip){
printf("/nTrace complete./n");
bLoop = FALSE;
}
}else{
printf("/t*/tRequest time out./n");
}
IpOption.Ttl++;
}
IcmpCloseHandle(hIcmp);
WSACleanup();
3 jni的用法
注意c 和C++的区别
struct JNINativeInterface_;
struct JNIEnv_;
#ifdef __cplusplus
typedef JNIEnv_ JNIEnv;
#else
typedef const struct JNINativeInterface_ *JNIEnv;
#endif
/*
* We use inlined functions for C++ so that programmers can write:
*
* env->FindClass("java/lang/String")
*
* in C++ rather than:
*
* (*env)->FindClass(env, "java/lang/String")
*
* in C.
*/
即C++中使用
env->FindClass("java/lang/String")
C中使用
(*env)->FindClass(env, "java/lang/String")