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。

  1. #include <arpa/inet.h>  
  2. #include <netdb.h>  
  3. #include <stdio.h>  
  4. #include <stdlib.h>  
  5. #include <string.h>  
  6. #define oops(msg) { perror(msg); exit(1);}  
  7. #include<ctype.h>  
  8.   
  9.   
  10.   
  11. void fillip(char* buffer, const char* ip);  
  12. char* name2ip(const char* name);  
  13. /** 
  14.  *  * head len: 12 
  15.  *   * query: ? + 4 
  16.  *    * total: strlen(query.buffer) + 16 
  17.  *     */  
  18. typedef struct{  
  19.         u_short txid;  
  20.         u_short flag;  
  21.         u_short question;  
  22.         u_short answer;  
  23.         u_short authority;  
  24.         u_short additional;  
  25.         char buffer[256];  
  26.         struct {  
  27.                 u_short type;  
  28.                 u_short cls;  
  29.         }query;  
  30. }dns_req;  
  31. /** length of resp: 12 */  
  32. typedef struct{  
  33.         u_short txid;  
  34.         u_short flag;  
  35.         u_short question;  
  36.         u_short answer;  
  37.         u_short authority;  
  38.         u_short addtional;  
  39.         char buffer[1024];  
  40.         struct{  
  41.                 u_short name;  
  42.                 u_short type;  
  43.                 u_short cls;  
  44.                 u_short live_l;  
  45.                 u_short live_h;  
  46.                 u_short len;  
  47.                 struct in_addr addr;  
  48.         }resp;  
  49. }dns_res;  
  50.   
  51. int hgetaddrinfo(const char *node, const char *service,  
  52.                 const struct addrinfo *hints,  
  53.                 struct addrinfo **res){  
  54.         /*    int rc = getaddrinfo(node,service,hints,res); 
  55.          *            if(rc == 0)//todo: != -> == 
  56.          *                            return rc; 
  57.          *                                            */  
  58.         char *ip = name2ip(node);               /// 如果 ping www.baidu.com  
  59.         return getaddrinfo(ip,service,hints,res);   /// 那么此时 node 指向字符串 "www.baidu.com"  
  60. }  
  61.   
  62. char *get_dns_name()  
  63. {  
  64.     int fd;  
  65.     static char buf[1024],*pstr,*pdns;  
  66.   
  67.     fd = open("/etc/resolv.conf",O_RDWR);  
  68.     read(fd,buf,1020);  
  69.     pstr = strstr(buf,"nameserver");  
  70.     pstr += strlen("nameserver");  
  71.     while(!isdigit(*pstr)){  
  72.         pstr ++;  
  73.     }  
  74.     pdns = pstr;  
  75.       
  76.     while(isdigit(*pstr) || (*pstr == '.') ){  
  77.         pstr ++;  
  78.     }  
  79.     *pstr = '\0';    
  80.     close(fd);  
  81.     return pdns;  
  82. }  
  83.   
  84.   
  85. char * name2ip(const char *node){  
  86.         struct sockaddr_in dns;  
  87.         dns_req req;  
  88.         dns_res res;  
  89.         int sockid, len, index;  
  90.         get_dns_name();  
  91.         char  dnsip[32];  
  92.   
  93.         strcpy(dnsip,get_dns_name());  
  94.   
  95.         sockid = socket(PF_INET, SOCK_DGRAM, 0);  
  96.         if(sockid == -1)  
  97.                 oops("socket");  
  98.         memset((void*)&dns, 0, sizeof(dns));  
  99.         dns.sin_family = AF_INET;  
  100.         dns.sin_port = htons(53);  
  101.         dns.sin_addr.s_addr = inet_addr(dnsip);  
  102.   
  103.         memset((void*)&req, 0, sizeof(req));  
  104.         req.txid = htons(0x4419);  
  105.         req.flag = htons(0x0100);  
  106.         req.question = htons(1);  
  107.         fillip(req.buffer,node);  
  108.         req.query.type=htons(1);  
  109.         req.query.cls=htons(1);  
  110.         memcpy(req.buffer+strlen(req.buffer)+1, (void*)(&req.query), sizeof(req.query));  
  111.   
  112.         sendto(sockid, (void*)&req, strlen(req.buffer)+17, 0,   
  113.                         (struct sockaddr*)&dns, sizeof(dns));  
  114.         recvfrom(sockid, (void*)&res, sizeof(res), 0,   
  115.                         (struct sockaddr*)&dns, &len);  
  116.         index = strlen(res.buffer)+5;  
  117.         while(1){  
  118.                 memcpy((void*)&(res.resp), res.buffer+index, 12);  
  119.                 if(ntohs(res.resp.type)==1){  
  120.                         memcpy((void*)&(res.resp.addr), res.buffer+index+12, 4);  
  121.                         break;  
  122.                 }  
  123.                 index += ntohs(res.resp.len) + 12;  
  124.         }  
  125.   
  126.         return inet_ntoa(res.resp.addr);  
  127. }  
  128.   
  129. void fillip(char* buffer, const char* ip){  
  130.         int i,j=0;  
  131.         for(i = 0; ip[i] != 0; i ++){  
  132.                 if(ip[i] != '.'){  
  133.                         buffer[i+1] = ip[i];  
  134.                 }  
  135.                 else{  
  136.                         buffer[j] = i - j;  
  137.                         j = i + 1;  
  138.                 }  
  139.         }  
  140.         buffer[j] = i - j;  
  141. }  
#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/


另外如果是出现:

ping: sendto: Network is unreachable

则需要查看一下默认网关有没有设置,可以通route命令查看

route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0     *               255.255.255.0           U          0      0        0      rausb0

发现网关(Gateway),是空着的没有设置,于是执行一下命令设置了网关:

# route add default gw 192.168.1.1
route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0     *               255.255.255.0   U     0      0        0 rausb0

default         192.168.1.1     0.0.0.0         UG    0      0        0 rausb0


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值