Chinaunix首页 | 论坛 | 博客
  • 博客访问: 52062
  • 博文数量: 14
  • 博客积分: 1545
  • 博客等级: 上尉
  • 技术积分: 170
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-13 00:33
文章分类

全部博文(14)

文章存档

2011年(4)

2010年(10)

我的朋友

分类: LINUX

2011-07-31 01:46:27

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#ifndef BUFSIZE
#define BUFSIZE 8192
#endif

struct route_info
{
    u_int dstAddr;
    u_int srcAddr;
    u_int gateWay;
    char ifName[IF_NAMESIZE];
};

/*
*
*/
int read_nlSock(int sockFd, char *bufPtr, int seqNum, int pId)
{
    struct nlmsghdr *nlHdr;
    int readLen = 0, msgLen = 0;
    
    do{
        //receive kernel response
        if((readLen = recv(sockFd, bufPtr, BUFSIZE - msgLen, 0)) < 0)
        {
              //perror("SOCK READ: ");
              return -1;
        }
 
        nlHdr = (struct nlmsghdr *)bufPtr;
        
        //check header valid
        if((NLMSG_OK(nlHdr, readLen) == 0)
            || (nlHdr->nlmsg_type == NLMSG_ERROR))
        {
              //perror("Error in received packet");
              return -1;
        }
 
        // Check if the its the last message
        if(nlHdr->nlmsg_type == NLMSG_DONE)
        {
             break;
        }
        else
        {
              //Else move the pointer to buffer appropriately
              bufPtr += readLen;
              msgLen += readLen;
        }
 
        //Check if its a multi part message
        if((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0)
        {
              //return if its not
             break;
        }
    } while((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId));

    return msgLen;
}

/*
*
*/
int parse_routes(struct nlmsghdr *nlHdr, struct route_info *rtInfo,
    const char *eth_name, char *gateway)
{
    int ret = -1;
    
    struct rtmsg *rtMsg;
    struct rtattr *rtAttr;
    int rtLen;
    
    struct in_addr dst;
    struct in_addr gate;

    rtMsg = (struct rtmsg *)NLMSG_DATA(nlHdr);
    
    // If the route is not for AF_INET or does not belong to main routing
    // table, then return.
    if ((rtMsg->rtm_family != AF_INET)
        || (rtMsg->rtm_table != RT_TABLE_MAIN))
    {
        return ret;
    }

    //get the rtattr field
    rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
    rtLen = RTM_PAYLOAD(nlHdr);    
    
    for (; RTA_OK(rtAttr,rtLen); rtAttr = RTA_NEXT(rtAttr,rtLen))
    {
           switch(rtAttr->rta_type)
        {
           case RTA_OIF:
            if_indextoname(*(int *)RTA_DATA(rtAttr), rtInfo->ifName);
            break;
            
           case RTA_GATEWAY:
            rtInfo->gateWay = *(u_int *)RTA_DATA(rtAttr);
            break;
           
           case RTA_PREFSRC:
            rtInfo->srcAddr = *(u_int *)RTA_DATA(rtAttr);
            break;
           
           case RTA_DST:
            rtInfo->dstAddr = *(u_int *)RTA_DATA(rtAttr);
            break;
           }
    }

    dst.s_addr = rtInfo->dstAddr;
    if (strstr((char *)inet_ntoa(dst), "0.0.0.0")
        && strcmp(eth_name, rtInfo->ifName) == 0)
    {
        gate.s_addr = rtInfo->gateWay;
        strcpy((char *)gateway, (char *)inet_ntoa(gate));
        ret = 0;
    }
    
    return ret;
}

/*
* get_ip_mask: get the ip and mask, specify eth name
*
* eth_name:
* ip:
* mask:
*
* return: 0 succ
*          -1 fail
*/
int get_ip_mask(const char *eth_name, char *ip, char *mask)
{
    if (eth_name == NULL || ip == NULL || mask == NULL)
    {
        return -1;
    }

    int sock;
    struct sockaddr_in sin;
    struct ifreq ifr;

    if ((sock =socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        return -1;
    }

    strncpy(ifr.ifr_name, eth_name, IFNAMSIZ);
    ifr.ifr_name[IFNAMSIZ -1] = 0;

    if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
    {
close(sock);
        return -1;
    }

    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
    char *ip_get = inet_ntoa(sin.sin_addr);
    strncpy(ip, ip_get, strlen(ip_get));

    if (ioctl(sock, SIOCGIFNETMASK, &ifr) < 0)
    {
close(sock);
        return -1;    
    }

    memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
    char *mask_get = inet_ntoa(sin.sin_addr);
    strncpy(mask, mask_get, strlen(mask_get));
    close(sock);
    return 0;
}

/********************************************************************
* get_gateway: get the gateway, specify eth name
*
* eth_name: eth name, not null
* gateway: gateway, not null
*
* return: 0 succ
*         -1 fail
********************************************************************/
int get_gateway(const char *eth_name, char *gateway)
{
    int ret = -1;
    if (eth_name == NULL || gateway == NULL)
    {
        return ret;
    }
    
    struct nlmsghdr *nlMsg;
    struct route_info *rtInfo;
    char msgBuf[BUFSIZE];

    int sock, len, msgSeq = 0;
    
    if((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
    {
           //perror("Socket Creation: ");
           return -1;
    }

    //Initialize the buffer
    memset(msgBuf, 0, BUFSIZE);

    //point the header and the msg structure pointers into the buffer
    nlMsg = (struct nlmsghdr *)msgBuf;

    nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
    nlMsg->nlmsg_type = RTM_GETROUTE;
    nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
    nlMsg->nlmsg_seq = msgSeq++;
    nlMsg->nlmsg_pid = getpid();

    //Send the request
    if (send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0){
        close(sock);
return ret;
    }

    //Read the response
    if((len = read_nlSock(sock, msgBuf, msgSeq, getpid())) < 0) {
        //printf("Read From Socket Failed.../n");
        close(sock);
return ret;
    }

    //Parse and print the response
    rtInfo = (struct route_info *)malloc(sizeof(struct route_info));
    for(; NLMSG_OK(nlMsg, len);    nlMsg = NLMSG_NEXT(nlMsg, len))
    {
        memset(rtInfo, 0, sizeof(struct route_info));
        if (parse_routes(nlMsg, rtInfo, eth_name, gateway) == 0)
        {
            ret = 0;
            break;
        }
    }
    
    free(rtInfo);
    close(sock);
    return 0;
}

int main(int argc, char **argv)
{
    if (argc != 2)
    {
        printf("usage:program \n");
        exit(0);
    }
    
    char ip[20];
    char mask[20];
    char gateway[20];
    
    memset(ip, 0, 20);
    memset(mask, 0, 20);
    memset(gateway, 0, 20);
    
    get_ip_mask(argv[1], ip, mask);
    get_gateway(argv[1], gateway);
    
    printf("ip:%s\n", ip);
    printf("mask:%s\n", mask);
    printf("gateway:%s\n", gateway);
    
    return 0;
}
阅读(4808) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~