busybox无法ping域名的解决办法

busybox无法ping域名的解决办法

$ ping www.google.com
ping : bad address 'www.google.com

现在各个版本的busybox都一样, 网上有人讲需要libnss_dns* …文件, 拷贝过去还是不能用,

手编2.6.21内核+手编1.5.1busybox+一堆deb包解压缩出gcc, 一个自定义的linux基本完成了,就差这么一个东西, hack源代码…
最终发现getaddrinfo这个函数调用失败,解决思路就是模拟dns协议把域名发给dns服务器,把域名转化为ip,然后再调用getaddrinfo,试验成功。

1. 把下面这段代码加入libbb/xconnect.c 的开头。
2. 把xconnect.c的str2sockaddr函数中getaddrinfo改为hgetaddrinfo。
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define oops(msg) { perror(msg); exit(1);}
#include<ctype.h>
 
 
 
void fillip(char* buffer, const char* ip);
char* name2ip(const char* name);
/**
 *  * head len: 12
 *   * query: ? + 4
 *    * total: strlen(query.buffer) + 16
 *     */
typedef struct{
        u_short txid;
        u_short flag;
        u_short question;
        u_short answer;
        u_short authority;
        u_short additional;
        char buffer[256];
        struct {
                u_short type;
                u_short cls;
        }query;
}dns_req;
/** length of resp: 12 */
typedef struct{
        u_short txid;
        u_short flag;
        u_short question;
        u_short answer;
        u_short authority;
        u_short addtional;
        char buffer[1024];
        struct{
                u_short name;
                u_short type;
                u_short cls;
                u_short live_l;
                u_short live_h;
                u_short len;
                struct in_addr addr;
        }resp;
}dns_res;
 
int hgetaddrinfo(const char *node, const char *service,
                const struct addrinfo *hints,
                struct addrinfo **res){
        /*    int rc = getaddrinfo(node,service,hints,res);
         *            if(rc == 0)//todo: != -> ==
         *                            return rc;
         *                                            */
        char *ip = name2ip(node);				/// 如果 ping www.baidu.com
        return getaddrinfo(ip,service,hints,res);   /// 那么此时 node 指向字符串 "www.baidu.com"
}
 
char *get_dns_name()
{
	int fd;
	static char	buf[1024],*pstr,*pdns;
 
	fd = open("/etc/resolv.conf",O_RDWR);
	read(fd,buf,1020);
	pstr = strstr(buf,"nameserver");
	pstr += strlen("nameserver");
	while(!isdigit(*pstr)){
		pstr ++;
	}
	pdns = pstr;
	
	while(isdigit(*pstr) || (*pstr == '.') ){
		pstr ++;
	}
	*pstr = '\0';  
	close(fd);
	return pdns;
}
 
 
char * name2ip(const char *node){
        struct sockaddr_in dns;
        dns_req req;
        dns_res res;
        int sockid, len, index;
		get_dns_name();
		char  dnsip[32];
 
		strcpy(dnsip,get_dns_name());
 
        sockid = socket(PF_INET, SOCK_DGRAM, 0);
        if(sockid == -1)
                oops("socket");
        memset((void*)&dns, 0, sizeof(dns));
        dns.sin_family = AF_INET;
        dns.sin_port = htons(53);
        dns.sin_addr.s_addr = inet_addr(dnsip);
 
        memset((void*)&req, 0, sizeof(req));
        req.txid = htons(0x4419);
        req.flag = htons(0x0100);
        req.question = htons(1);
        fillip(req.buffer,node);
        req.query.type=htons(1);
        req.query.cls=htons(1);
        memcpy(req.buffer+strlen(req.buffer)+1, (void*)(&req.query), sizeof(req.query));
 
        sendto(sockid, (void*)&req, strlen(req.buffer)+17, 0, 
                        (struct sockaddr*)&dns, sizeof(dns));
        recvfrom(sockid, (void*)&res, sizeof(res), 0, 
                        (struct sockaddr*)&dns, &len);
        index = strlen(res.buffer)+5;
        while(1){
                memcpy((void*)&(res.resp), res.buffer+index, 12);
                if(ntohs(res.resp.type)==1){
                        memcpy((void*)&(res.resp.addr), res.buffer+index+12, 4);
                        break;
                }
                index += ntohs(res.resp.len) + 12;
        }
 
        return inet_ntoa(res.resp.addr);
}
 
void fillip(char* buffer, const char* ip){
        int i,j=0;
        for(i = 0; ip[i] != 0; i ++){
                if(ip[i] != '.'){
                        buffer[i+1] = ip[i];
                }
                else{
                        buffer[j] = i - j;
                        j = i + 1;
                }
        }
        buffer[j] = i - j;
}

原文链接:http://hankjin.blog.163.com/blog/static/337319372009327101324432/

但是这位大神的博客已经注销了。我们还是收藏先。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值