免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 11400 | 回复: 8
打印 上一主题 下一主题

linux-c,怎么取网关地址和DNS服务器地址? [复制链接]

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-05-05 12:57 |只看该作者 |倒序浏览
5可用积分
找了半天没找到

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
2 [报告]
发表于 2009-05-05 13:01 |只看该作者

回复 #1 smalloc 的帖子

你指的是自动查找?

论坛徽章:
0
3 [报告]
发表于 2009-05-05 13:04 |只看该作者

回复 #1 smalloc 的帖子

Linux C编程---网络编程| C/C++ - Unix/Linux 技术交流站Unix/Linux ...

5 个帖子 - 5 个作者 - 新贴子: 2006年8月9日
Linux C编程---网络编程. 摘要. 网络编程,一定离不开套接口;那什么是套接口呢?在Linux下,所有的I/O操作都是通过读写文件描述符而产生的,文件描述 ...
bbs.unixtech.cn/read.php?tid=120

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
4 [报告]
发表于 2009-05-05 13:06 |只看该作者
原帖由 dreamice 于 2009-5-5 13:01 发表
你指的是自动查找?

不是,是指在自动获取以后或者手动分配好的情况下,通过程序取得这个值

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
5 [报告]
发表于 2009-05-05 13:16 |只看该作者
for gateway:
# route
or if you want to see ip of the gw:
# route -n

for dns (dns for host, no such a thing of "dns for interface")
# cat /etc/resolv.conf

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
6 [报告]
发表于 2009-05-05 13:34 |只看该作者
原帖由 dreamice 于 2009-5-5 13:16 发表
for gateway:
# route
or if you want to see ip of the gw:
# route -n

for dns (dns for host, no such a thing of "dns for interface")
# cat /etc/resolv.conf

dns和奇怪,直接读这个文件和内核中的能同步吗?我并不想读这个文件.

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
7 [报告]
发表于 2009-05-05 16:24 |只看该作者
route -n能保证只有一个网关地址吗?通常路由器可能有多个网关,所以想通过已经知道的IP获得对应的网关

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
8 [报告]
发表于 2009-05-05 17:59 |只看该作者
原帖由 smalloc 于 2009-5-5 16:24 发表
route -n能保证只有一个网关地址吗?通常路由器可能有多个网关,所以想通过已经知道的IP获得对应的网关


ip route ls dev ethx
读取指定网卡ethx的路由

论坛徽章:
0
9 [报告]
发表于 2009-05-06 16:47 |只看该作者
这个代码可以获取本机默认网关 ,我在ubuntu7.10下测试了,没有问题


#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ctype.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <resolv.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define RTF_UP                        0x0001
#define RTF_GATEWAY                    0x0002
#define RTF_HOST                    0x0004
#define _PATH_PROCNET_ROUTE            "/proc/net/route"


struct addr {
    struct sockaddr_in addr;
    char *name;
    int host;
    struct addr *next;
};

static struct addr *INET_nn = NULL;    /* addr-to-name cache */


struct aftype {
    char *name;
    char *title;
    int af;
    int alen;
    char *(*print) (unsigned char *);
    char *(*sprint) (struct sockaddr *, int numeric);
    int (*input) (int type, char *bufp, struct sockaddr *);
    void (*herror) (char *text);
    int (*rprint) (int options);
    int (*rinput) (int typ, int ext, char **argv);

    /* may modify src */
    int (*getmask) (char *src, struct sockaddr * mask, char *name);

    int fd;
    char *flag_file;
};
struct aftype inet_aftype;

struct sockaddr snet_gateway;

char *proc_gen_fmt(char *name, int more, FILE * fh,...)
{
    char buf[512], format[512] = "";
    char *title, *head, *hdr;
    va_list ap;

    if (!fgets(buf, (sizeof buf) - 1, fh))
    return NULL;
    strcat(buf, " ";

    va_start(ap, fh);
    title = va_arg(ap, char *);
    for (hdr = buf; hdr {
    while (isspace(*hdr) || *hdr == '|')
     hdr++;
    head = hdr;
    hdr = strpbrk(hdr, "| \t\n";
    if (hdr)
     *hdr++ = 0;

    if (!strcmp(title, head)) {
     strcat(format, va_arg(ap, char *));
     title = va_arg(ap, char *);
     if (!title || !head)
        break;
    } else {
     strcat(format, "%*s";    /* XXX */
    }
    strcat(format, " ";
    }
    va_end(ap);

    if (!more && title) {
    fprintf(stderr, "warning: %s does not contain required field %s\n",
        name, title);
    return NULL;
    }
    return strdup(format);
}


static int INET_getsock(char *bufp, struct sockaddr *sap)
{
    char *sp = bufp, *bp;
    unsigned int i;
    unsigned val;
    struct sockaddr_in *sin;

    sin = (struct sockaddr_in *) sap;
    sin->sin_family = AF_INET;
    sin->sin_port = 0;

    val = 0;
    bp = (char *) &val;
    for (i = 0; i < sizeof(sin->sin_addr.s_addr); i++) {
    *sp = toupper(*sp);

    if ((*sp >= 'A') && (*sp <= 'F'))
     bp |= (int) (*sp - 'A') + 10;
    else if ((*sp >= '0') && (*sp <= '9'))
     bp |= (int) (*sp - '0');
    else
     return (-1);

    bp <<= 4;
    sp++;
    *sp = toupper(*sp);

    if ((*sp >= 'A') && (*sp <= 'F'))
     bp |= (int) (*sp - 'A') + 10;
    else if ((*sp >= '0') && (*sp <= '9'))
     bp |= (int) (*sp - '0');
    else
     return (-1);

    sp++;
    }
    sin->sin_addr.s_addr = htonl(val);

    return (sp - bufp);
}

static int INET_resolve(char *name, struct sockaddr_in *sin, int hostfirst)
{
    struct hostent *hp;
    struct netent *np;

    /* Grmpf. -FvK */
    sin->sin_family = AF_INET;
    sin->sin_port = 0;

    /* Default is special, meaning 0.0.0.0. */
    if (!strcmp(name, "default") {
    sin->sin_addr.s_addr = INADDR_ANY;
    return (1);
    }
    /* Look to see if it's a dotted quad. */
    if (inet_aton(name, &sin->sin_addr)) {
    return 0;
    }
#ifdef EMBED
    return(-1);
#else
    /* If we expect this to be a hostname, try hostname database first */
#ifdef DEBUG
    if (hostfirst) fprintf (stderr, "gethostbyname (%s)\n", name);
#endif
    if (hostfirst &&
    (hp = gethostbyname(name)) != (struct hostent *) NULL) {
    memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0],
        sizeof(struct in_addr));
    return 0;
    }
    /* Try the NETWORKS database to see if this is a known network. */
#ifdef DEBUG
    fprintf (stderr, "getnetbyname (%s)\n", name);
#endif
    if ((np = getnetbyname(name)) != (struct netent *) NULL) {
    sin->sin_addr.s_addr = htonl(np->n_net);
    return 1;
    }
    if (hostfirst) {
    /* Don't try again */
    errno = h_errno;
    return -1;
    }
#ifdef DEBUG
    res_init();
    _res.options |= RES_DEBUG;
#endif

#ifdef DEBUG
    fprintf (stderr, "gethostbyname (%s)\n", name);
#endif
    if ((hp = gethostbyname(name)) == (struct hostent *) NULL) {
    errno = h_errno;
    return -1;
    }
    memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0],
     sizeof(struct in_addr));

    return 0;
#endif
}

static int INET_input(int type, char *bufp, struct sockaddr *sap)
{
    switch (type) {
    case 1:
    return (INET_getsock(bufp, sap));
    case 256:
    return (INET_resolve(bufp, (struct sockaddr_in *) sap, 1));
    default:
    return (INET_resolve(bufp, (struct sockaddr_in *) sap, 0));
    }
}
char *safe_strncpy(char *dst, const char *src, size_t size)
{
    dst[size-1] = '\0';
    return strncpy(dst,src,size-1);
}
static int INET_rresolve(char *name, size_t len, struct sockaddr_in *sin,
             int numeric, unsigned int netmask)
{
    struct hostent *ent;
    struct netent *np;
    struct addr *pn;
    unsigned long ad, host_ad;
    int host = 0;

    /* Grmpf. -FvK */
    if (sin->sin_family != AF_INET) {
        errno = EAFNOSUPPORT;
    return (-1);
    }
    ad = (unsigned long) sin->sin_addr.s_addr;
    if (ad == INADDR_ANY) {
    if ((numeric & 0x0FFF) == 0) {
     if (numeric & 0x8000)
        safe_strncpy(name, "default", len);
     else
     safe_strncpy(name, "*", len);
     return (0);
    }
    }
    if (numeric & 0x0FFF) {
        safe_strncpy(name, inet_ntoa(sin->sin_addr), len);
    return (0);
    }

    if ((ad & (~netmask)) != 0 || (numeric & 0x4000))
    host = 1;
    pn = INET_nn;
    while (pn != NULL) {
    if (pn->addr.sin_addr.s_addr == ad && pn->host == host) {
     safe_strncpy(name, pn->name, len);
     return (0);
    }
    pn = pn->next;
    }

    host_ad = ntohl(ad);
    np = NULL;
    ent = NULL;
#ifndef EMBED
    if (host) {
        ent = gethostbyaddr((char *) &ad, 4, AF_INET);
    if (ent != NULL)
     safe_strncpy(name, ent->h_name, len);
    }
#ifndef __UC_LIBC__
    else {
    np = getnetbyaddr(host_ad, AF_INET);
    if (np != NULL)
     safe_strncpy(name, np->n_name, len);
    }
#endif
#endif
    if ((ent == NULL) && (np == NULL))
    safe_strncpy(name, inet_ntoa(sin->sin_addr), len);
    pn = (struct addr *) malloc(sizeof(struct addr));
    pn->addr = *sin;
    pn->next = INET_nn;
    pn->host = host;
    pn->name = (char *) malloc(strlen(name) + 1);
    strcpy(pn->name, name);
    INET_nn = pn;

    return (0);
}
static char *INET_sprint(struct sockaddr *sap, int numeric)
{
    static char buff[128];

    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
    return safe_strncpy(buff, "[NONE SET]", sizeof(buff));

    if (INET_rresolve(buff, sizeof(buff), (struct sockaddr_in *) sap,
         numeric, 0xffffff00) != 0)
    return (NULL);

    return (buff);
}

int main()
{
    int ext=1,numeric=0;
    char buff[1024], iface[16], flags[64];
    char gate_addr[128], net_addr[128];
    char mask_addr[128];
    int num, iflags, metric, refcnt, use, mss, window, irtt;
    FILE *fp = fopen(_PATH_PROCNET_ROUTE, "r";
    char *fmt;
    if (!fp) {
        perror(_PATH_PROCNET_ROUTE);
        printf("INET (IPv4) not configured in this system.\n";
    return 1;
    }

    irtt = 0;
    window = 0;
    mss = 0;

    fmt = proc_gen_fmt(_PATH_PROCNET_ROUTE, 0, fp,
         "Iface", "%16s",
         "Destination", "%128s",
         "Gateway", "%128s",
         "Flags", "%X",
         "RefCnt", "%d",
         "Use", "%d",
         "Metric", "%d",
         "Mask", "%128s",
         "MTU", "%d",
         "Window", "%d",
         "IRTT", "%d",
         NULL);
    /* "%16s %128s %128s %X %d %d %d %128s %d %d %d\n" */

    if (!fmt)
    return 1;

    while (fgets(buff, 1023, fp)) {

    num = sscanf(buff, fmt,
         iface, net_addr, gate_addr,
         &iflags, &refcnt, &use, &metric, mask_addr,
         &mss, &window, &irtt);
    if (num < 10 || !(iflags & RTF_UP))
     continue;

    INET_input(1, gate_addr, &snet_gateway);

     strcpy(gate_addr, INET_sprint(&snet_gateway, numeric | 0x4000));
     gate_addr[15] = '\0';
    if (iflags & RTF_GATEWAY)   
        printf("==gateway=======%s===%s=====\n",gate_addr,iface);
   
    }

    free(fmt);
    (void) fclose(fp);
    return (0);
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP