获得本地路由表的程序

本程序相当与命令:$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;
}



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值