/* * This is used for user output only, so it does not matter when an error occurs. */ const char *pdnsd_a2str(pdnsd_a *a, char *buf, int maxlen) { const char *res= SEL_IPVER( inet_ntop(AF_INET,&a->ipv4,buf,maxlen), inet_ntop(AF_INET6,&a->ipv6,buf,maxlen) ); if (!res) { log_error("inet_ntop: %s", strerror(errno)); return "?.?.?.?"; } return res; }
int is_local_addr(pdnsd_a *a) { int retval=0, sock, cnt; struct ifconf ifc; char buf[2048]; if ((sock=socket(PF_INET,SOCK_DGRAM, IPPROTO_UDP))==-1) { if(++socketopen_errs<=MAX_SOCKETOPEN_ERRS) { log_warn("Could not open socket in is_local_addr(): %s",strerror(errno)); } return 0; } ifc.ifc_len=sizeof(buf); ifc.ifc_buf=buf; if (ioctl(sock,SIOCGIFCONF,&ifc)==-1) { if(++siocgifconf_errs<=MAX_SIOCGIFCONF_ERRS) { log_warn("ioctl() call with request SIOCGIFCONF failed in is_local_addr(): %s",strerror(errno)); } goto close_sock_return; } cnt=0; while(cnt+sizeof(struct ifreq)<=ifc.ifc_len) { struct ifreq *ir= (struct ifreq *)(buf+cnt); cnt += SIZEOF_ADDR_IFREQ(*ir); if (cnt>ifc.ifc_len) break; if (SEL_IPVER(ir->ifr_addr.sa_family==AF_INET && ((struct sockaddr_in *)&ir->ifr_addr)->sin_addr.s_addr==a->ipv4.s_addr, ir->ifr_addr.sa_family==AF_INET6 && IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)&ir->ifr_addr)->sin6_addr, &a->ipv6))) { retval=1; break; } } close_sock_return: close(sock); return retval; }
/* Report the current configuration to the file descriptor f (for the status fifo, see status.c) */ int report_conf_stat(int f) { int i,n,retval=0; fsprintf_or_return(f,"\nConfiguration:\n==============\nGlobal:\n-------\n"); fsprintf_or_return(f,"\tCache size: %li kB\n",global.perm_cache); fsprintf_or_return(f,"\tServer directory: %s\n",global.cache_dir); fsprintf_or_return(f,"\tScheme file (for Linux pcmcia support): %s\n",global.scheme_file); fsprintf_or_return(f,"\tServer port: %i\n",global.port); { char buf[ADDRSTR_MAXLEN]; fsprintf_or_return(f,"\tServer IP (%s=any available one): %s\n", SEL_IPVER("0.0.0.0","::"), pdnsd_a2str(&global.a,buf,ADDRSTR_MAXLEN)); if(!is_inaddr_any(&global.out_a)) { fsprintf_or_return(f,"\tIP bound to interface used for querying remote servers: %s\n", pdnsd_a2str(&global.out_a,buf,ADDRSTR_MAXLEN)); } } #ifdef ENABLE_IPV6 if(!run_ipv4) { char buf[ADDRSTR_MAXLEN]; fsprintf_or_return(f,"\tIPv4 to IPv6 prefix: %s\n",inet_ntop(AF_INET6,&global.ipv4_6_prefix,buf,ADDRSTR_MAXLEN)?:"?.?.?.?"); }
int is_inaddr_any(pdnsd_a *a) { return SEL_IPVER( a->ipv4.s_addr==INADDR_ANY, IN6_IS_ADDR_UNSPECIFIED(&a->ipv6) ); }
int is_local_addr(pdnsd_a *a) { int retval=0, sock, cnt; # ifdef WIN32 INTERFACE_INFO ifo[26]; DWORD ifo_len; # else struct ifconf ifc; char buf[2048]; # endif if ((sock=socket(PF_INET,SOCK_DGRAM, IPPROTO_UDP))==-1) { if(++socketopen_errs<=MAX_SOCKETOPEN_ERRS) { # ifdef WIN32 log_warn("Could not open socket in is_local_addr(): %d",WSAGetLastError()); # else log_warn("Could not open socket in is_local_addr(): %s",strerror(errno)); # endif } return 0; } # ifdef WIN32 if ((WSAIoctl(sock,SIO_GET_INTERFACE_LIST, NULL,0, ifo,sizeof(ifo), &ifo_len, NULL, NULL))!=0) { if(++siocgifconf_errs<=MAX_SIOCGIFCONF_ERRS) { log_warn("(WSAIoctl() call with request SIOCGIFCONF failed in is_local_addr(): %s",strerror(errno)); } goto close_sock_return; } for (cnt = 0; cnt<(int)(ifo_len/sizeof(INTERFACE_INFO)); cnt++) { if (SEL_IPVER(ifo[cnt].iiAddress.Address.sa_family==AF_INET && ifo[cnt].iiAddress.AddressIn.sin_addr.s_addr==a->ipv4.s_addr, ifo[cnt].iiAddress.Address.sa_family==AF_INET6 && IN6_ARE_ADDR_EQUAL(&ifo[cnt].iiAddress.AddressIn6.sin6_addr, &a->ipv6))) { retval=1; break; } } # else ifc.ifc_len=sizeof(buf); ifc.ifc_buf=buf; if (ioctl(sock,SIOCGIFCONF,&ifc)==-1) { if(++siocgifconf_errs<=MAX_SIOCGIFCONF_ERRS) { log_warn("ioctl() call with request SIOCGIFCONF failed in is_local_addr(): %s",strerror(errno)); } goto close_sock_return; } cnt=0; while(cnt+sizeof(struct ifreq)<=ifc.ifc_len) { struct ifreq *ir= (struct ifreq *)(buf+cnt); cnt += SIZEOF_ADDR_IFREQ(*ir); if (cnt>ifc.ifc_len) break; if (SEL_IPVER(ir->ifr_addr.sa_family==AF_INET && ((struct sockaddr_in *)&ir->ifr_addr)->sin_addr.s_addr==a->ipv4.s_addr, ir->ifr_addr.sa_family==AF_INET6 && IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)&ir->ifr_addr)->sin6_addr, &a->ipv6))) { retval=1; break; } } # endif close_sock_return: # ifdef WIN32 closesocket(sock); # else close(sock); # endif return retval; }