int slirp_get_system_dns_servers(void) { char buff[512]; char buff2[257]; FILE *f; if (dns_addr_count > 0) return dns_addr_count; #ifdef CONFIG_DARWIN /* on Darwin /etc/resolv.conf is a symlink to /private/var/run/resolv.conf * in some siutations, the symlink can be destroyed and the system will not * re-create it. Darwin-aware applications will continue to run, but "legacy" * Unix ones will not. */ f = fopen("/private/var/run/resolv.conf", "r"); if (!f) f = fopen("/etc/resolv.conf", "r"); /* desperate attempt to sanity */ #else f = fopen("/etc/resolv.conf", "r"); #endif if (!f) return -1; DN("emulator: IP address of your DNS(s): "); while (fgets(buff, 512, f) != NULL) { if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) { uint32_t tmp_ip; if (inet_strtoip(buff2, &tmp_ip) < 0) continue; if (tmp_ip == loopback_addr_ip) tmp_ip = our_addr_ip; if (dns_addr_count < DNS_ADDR_MAX) { dns_addr[dns_addr_count++] = tmp_ip; if (dns_addr_count > 1) DN(", "); DN("%s", inet_iptostr(tmp_ip)); } else { DN("(more)"); break; } } } DN("\n"); fclose(f); if (!dns_addr_count) return -1; return dns_addr_count; }
int slirp_get_system_dns_servers(void) { char buff[512]; char buff2[257]; FILE *f; if (dns_addr_count > 0) return dns_addr_count; #ifdef CONFIG_DARWIN f = fopen("/private/var/run/resolv.conf", "r"); if (!f) f = fopen("/etc/resolv.conf", "r"); #else f = fopen("/etc/resolv.conf", "r"); #endif if (!f) return -1; DN("emulator: IP address of your DNS(s): "); while (fgets(buff, 512, f) != NULL) { if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) { uint32_t tmp_ip; if (inet_strtoip(buff2, &tmp_ip) < 0) continue; if (tmp_ip == loopback_addr_ip) tmp_ip = our_addr_ip; if (dns_addr_count < DNS_ADDR_MAX) { dns_addr[dns_addr_count++] = tmp_ip; if (dns_addr_count > 1) DN(", "); DN("%s", inet_iptostr(tmp_ip)); } else { DN("(more)"); break; } } } DN("\n"); fclose(f); if (!dns_addr_count) return -1; return dns_addr_count; }
void icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize, const char *message) { unsigned hlen, shlen, s_ip_len; register struct ip *ip; register struct icmp *icp; register struct mbuf *m; DEBUG_CALL("icmp_error"); DEBUG_ARG("msrc = %lx", (long )msrc); DEBUG_ARG("msrc_len = %d", msrc->m_len); if(type!=ICMP_UNREACH && type!=ICMP_TIMXCEED) goto end_error; /* check msrc */ if(!msrc) goto end_error; ip = mtod(msrc, struct ip *); #ifdef DEBUG { char bufa[20], bufb[20]; strcpy(bufa, inet_iptostr(ip_geth(ip->ip_src))); strcpy(bufb, inet_iptostr(ip_geth(ip->ip_dst))); DEBUG_MISC((dfd, " %.16s to %.16s\n", bufa, bufb)); } #endif if(ip->ip_off & IP_OFFMASK) goto end_error; /* Only reply to fragment 0 */ shlen=ip->ip_hl << 2; s_ip_len=ip->ip_len; if(ip->ip_p == IPPROTO_ICMP) { icp = (struct icmp *)((char *)ip + shlen); /* * Assume any unknown ICMP type is an error. This isn't * specified by the RFC, but think about it.. */ if(icp->icmp_type>18 || icmp_flush[icp->icmp_type]) goto end_error; } /* make a copy */ if(!(m=m_get())) goto end_error; /* get mbuf */ { int new_m_size; new_m_size=sizeof(struct ip )+ICMP_MINLEN+msrc->m_len+ICMP_MAXDATALEN; if(new_m_size>m->m_size) m_inc(m, new_m_size); } memcpy(m->m_data, msrc->m_data, msrc->m_len); m->m_len = msrc->m_len; /* copy msrc to m */ /* make the header of the reply packet */ ip = mtod(m, struct ip *); hlen= sizeof(struct ip ); /* no options in reply */ /* fill in icmp */ m->m_data += hlen; m->m_len -= hlen; icp = mtod(m, struct icmp *); if(minsize) s_ip_len=shlen+ICMP_MINLEN; /* return header+8b only */ else if(s_ip_len>ICMP_MAXDATALEN) /* maximum size */ s_ip_len=ICMP_MAXDATALEN; m->m_len=ICMP_MINLEN+s_ip_len; /* 8 bytes ICMP header */ /* min. size = 8+sizeof(struct ip)+8 */ icp->icmp_type = type; icp->icmp_code = code; icp->icmp_id = 0; icp->icmp_seq = 0; memcpy(&icp->icmp_ip, msrc->m_data, s_ip_len); /* report the ip packet */ HTONS(icp->icmp_ip.ip_len); HTONS(icp->icmp_ip.ip_id); HTONS(icp->icmp_ip.ip_off); #ifdef DEBUG if(message) { /* DEBUG : append message to ICMP packet */ int message_len; char *cpnt; message_len=strlen(message); if(message_len>ICMP_MAXDATALEN) message_len=ICMP_MAXDATALEN; cpnt=(char *)m->m_data+m->m_len; memcpy(cpnt, message, message_len); m->m_len+=message_len; } #endif icp->icmp_cksum = 0; icp->icmp_cksum = cksum(m, m->m_len); m->m_data -= hlen; m->m_len += hlen; /* fill in ip */ ip->ip_hl = hlen >> 2; ip->ip_len = m->m_len; ip->ip_tos=((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */ ip->ip_ttl = MAXTTL; ip->ip_p = IPPROTO_ICMP; ip->ip_dst = ip->ip_src; /* ip adresses */ ip->ip_src = ip_setn(alias_addr_ip); (void ) ip_output((struct socket *)NULL, m); STAT(icmpstat.icps_reflect++); end_error: return; }