在Linux C中检索DHCP分配的域后缀

7

我试图以ANSI C(Linux)编程方式自动检索主机的本地域后缀。例如:我的机器是ironside.0ffnet.net,我想检索“0ffnet.net”。

我看到了很多帖子都在使用getnameinfo()和getaddrinfo()解决此问题,但似乎这些函数会从/etc/hosts文件中拉取任何本地接口地址的信息。

如果我的机器通过DHCP分配地址(和相应的域后缀),则/etc/hosts文件不会得到更新,而是将此信息存储在/etc/resolv.conf中,例如:

dfex@ironside:~/hush$cat /etc/resolv.conf 
domain 0ffnet.net
search 0ffnet.net
nameserver 139.130.4.4

因此,getnameinfo()和getaddrinfo()只返回机器的主机名,不带后缀,使用/etc/hosts信息,其格式如下:

dfex@ironside:~/hush$ cat /etc/hosts
::1             ironside localhost6.localdomain6 localhost6
127.0.1.1       ironside
127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback

有没有一种函数可以在不使用system()调用的情况下提取这些信息?我一直在阅读Beej指南,但没有太大的进展。

你可能需要进行正确的DHCP广播。请参考RFC2131获取实际协议。 - Some programmer dude
3个回答

2

我需要将这个问题拆分并分别回答各部分。首先,回答标题的问题。

DHCP域

了解DHCP客户端从DHCP服务器接收到的内容的唯一方法是读取客户端在/var/lib/dhcp中留下的文件。如果其他程序控制了resolv.conf,DHCP建议的搜索域可能根本没有被使用。

"我的主机的本地域后缀"

一个主机可能属于多个域或没有域,这使得这个概念很难定义。 resolv.conf指定将用于解析主机名的域;但对于你自己的主机名,无法保证搜索将成功。

不管怎样!我真正想要的是解析器搜索列表。我该怎么做?

调用res_init,然后查看_res.dnsrch和/或_res.defdname。或者自己解析resolv.conf;它是一个非常简单且稳定的格式。

那么getdomainname()是用来做什么的?

它是用于NIS(YP)的,你可能不需要。


传说 - 感谢Alan - 我以前没有遇到过res_init。这就解决了 :) - Benjamin Dale

1

您可以尝试使用:

int getdomainname(char *name, size_t len);

尝试运行这个程序:

#include <unistd.h>
#include <stdio.h>

int main()
{
 char buf[255];
 getdomainname(buf, 255);
 printf("Domain: %s\n", buf);
 return 0; 
}

编辑:

不行,经过多次尝试,我怀疑你必须使用系统调用和一个丑陋的C解析器(在popen中使用AWK可以使这段代码变得更短)。

这段代码对我来说似乎是有效的:

#include <stdio.h>
#include <string.h>

int main()
{
 char buf[255];
 const char reqhostname[255] = "ENTER_YOUR_HOSTNAME_HERE";

 FILE *fd;
 char readbuf[255];
 char *pch;
 int token_counter = 0;

 memset(buf, 0, 255);
 strcat(buf, "host ");
 strcat(buf, reqhostname);
 fd = popen(buf, "r");
 fgets(readbuf, 255, fd);
 printf("Host returned: %s\n", readbuf);
 pclose(fd);

 pch = strtok(readbuf, " ");
 while (pch != NULL)
   {
        strcpy(buf, pch);
        break;
   }

 memset(buf2, 0, 255);
 pch = strtok(buf, ".");
 while (pch != NULL)
   {
        pch = strtok(NULL, ".");
        if (pch == NULL)
           {
                memset(buf, 0, 255);
                strncpy(buf, buf2, strlen(buf2) - 1);
                break;
           }
        token_counter++;
        strcat(buf2, pch);
        strcat(buf2, ".");
   }

 printf("Domain: %s\n", buf);

 return 0;
}

谢谢,但这似乎是尝试相同的源 - 我从上面得到的输出是:域:(无) - Benjamin Dale

1

感谢 @alan-curry,这确实指引了我正确的方向。对于其他遇到问题的人来说,res_init 绝对是正确的选择。以下是获取本地域名后缀的快速方法:

#include <stdio.h>
#include <resolv.h>

int main (int argc, char *argv[]) {

res_init();

printf ("Default domain: %s\n", _res.defdname);
return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接