本程序相当与命令:$netstat -r
/*
* =====================================================================================
*
* Filename: route.c
*
* Description:
*
* Version: 1.0
* Created: 2012年02月23日 21时07分13秒
* Revision: none
* Compiler: gcc
*
* Author: MaZheng (blog.csdn.net/mazheng1989), mazheng19891019@gmail.com
* Company: Dalian University Of Technology
*
* =====================================================================================
*/
#include <netinet/ip.h>
#include <netinet/in.h>
#include <sys/socketvar.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include "route.h"
#include <sys/socket.h>
#include <sys/time.h>
#include <net/route.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/param.h>
/*此函数用于将收到的套接字地址拷贝到套接字地址数据rt_info*/
void cp_rtaddrs(int ,struct sockaddr_in *,struct sockaddr_in **);
#define BUFLEN (sizeof(struct rt_msghdr)+512) /* 消息缓冲区的长度 */
#define RTA_DST 0x1 /* destination sockaddr present */
#define RTA_GATEWAY 0x2 /* gateway sockaddr present */
#define RTA_NETMASK 0x4 /* netmask sockaddr present */
#define RTA_GENMASK 0x8 /* cloning mask sockaddr present */
#define SEQ 1234 /* 消息序号 */
#define RTA_NUMBITS 10 /* */
int main(int argc,char **argv)
{
int sockfd;
char *buf;
pid_t pid;
ssize_t n;
struct rt_msghdr *rtm;
struct sockaddr_in *sa,*rt_info[RTA_NUMBITS];
struct sockaddr_in *sin;
if(argc!=2)
{
printf("usage:%s<Ip address>\n",argv[0]);
exit(0);
}
sockfd=socket(AF_ROUTE,SOCK_RAW,0);/*create a socket descriptro*/
if(sockfd==-1)
{
perror("socket error\n");
exit(1);
}
buf=(char *)calloc(1,BUFLEN);/*分配缓冲区*/
rtm=(struct rt_msghdr*)buf;
rtm->rtm_msglen=sizeof(struct rt_msghdr)+sizeof(struct sockaddr_in);/*消息长度*/
rtm->rtm_version=RTM_VERSION;/*版本号*/
rtm->rtm_type=RTM_GET;/*消息类型*/
rtm->rtm_addrs=RTM_DST;/*位屏蔽字*/
rtm->rtm_pid=pid=getpid();/*进程号*/
rtm->rtm_seq=SEQ;/*序号*/
sin=(struct sockaddr_in *)(rtm+1);/*将目的地址填入跟在消息头后的套接字地址项中*/
sin->sin_family=AF_INET;
inet_pton(AF_INET,argv[1],&sin->sin_addr);
write(sockfd,rtm,rtm->rtm_msglen);/*发送RTM_GET消息给路由套接字*/
/*通过循环读取路由套接字中的消息,直到读到类型为RTM_GET,序号为SEQ,进程ID为当前进程
* 的消息,表明该消息是所发消息的回应*/
do{
n=read(sockfd,rtm,BUFLEN);
}while(rtm->rtm_type!=RTM_GET||rtm->rtm_seq!=SEQ||rtm->rtm_pid!=pid);
sa=(struct sockaddr_in*)(rtm+1);
cp_rtaddrs(rtm->rtm_addrs,sa,rt_info);/*讲读取的套接字地址拷贝到数组rt_info*/
if((sa=rt_info[RTA_DST])!=NULL)
{
printf("dest:%s\n",inet_ntoa(sa->sin_addr));
}
if((sa=rt_info[RTA_NETMASK])!=NULL)
{
printf("netmask:%s\n",inet_ntoa(sa->sin_addr));
}
if((sa=rt_info[RTA_GATEWAY])!=NULL)
{
printf("gateway:%s\n",inet_ntoa(sa->sin_addr));
}
exit(0);
return 0;
}