📄 ppldnsv6.c
字号:
if (setsockopt(sock_rt, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) == -1) { perror("DEBUG: [get_output_if] setsockopt(SOL_SOCKET, SO_BROADCAST"); close(sock_rt); return -1; } if (connect(sock_rt, (struct sockaddr*)&remote, sizeof(struct sockaddr_in6)) == -1 ) { perror("DEBUG: [get_output_if] connect"); close(sock_rt); return -1; } len = sizeof(iface_out); if (getsockname(sock_rt, (struct sockaddr *)&iface_out, &len) == -1 ) { perror("DEBUG: [get_output_if] getsockname"); close(sock_rt); return -1; } close(sock_rt); if (iface_out.sin6_addr.s6_addr == 0) { /* what is this case?? */ return -1; } inet_ntop(AF_INET6, (const void*) &iface_out.sin6_addr, address, size-1); return 0;}static int ppl_dns_get_local_fqdn_ipv6 (char **servername, char **serverip, char **netmask, char *interface, unsigned int pos_interface);static int ppl_dns_get_local_fqdn_ipv4 (char **servername, char **serverip, char **netmask, char *interface, unsigned int pos_interface);PPL_DECLARE (int)ppl_dns_get_local_fqdn (char **servername, char **serverip, char **netmask, char *interface, unsigned int pos_interface, int family){ if (family==AF_INET6) { return ppl_dns_get_local_fqdn_ipv6(servername, serverip, netmask, interface, pos_interface); } else { return ppl_dns_get_local_fqdn_ipv4(servername, serverip, netmask, interface, pos_interface); }}#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE_CC__) || defined (__linux)#include <ifaddrs.h>static intppl_dns_get_local_fqdn_ipv4 (char **servername, char **serverip, char **netmask, char *interface, unsigned int pos_interface){ int i = 0; struct ifaddrs *ifap, *ifa; *servername = NULL; *serverip = NULL; *netmask = NULL; if (getifaddrs(&ifap)) return -1; /* cannot fetch interfaces */ if (pos_interface>0) /* The method must return the interface at pos_interface */ { i = 0; for (ifa = ifap; ifa; ifa=ifa->ifa_next) { if (ifa->ifa_addr==NULL || ifa->ifa_addr->sa_family!=AF_INET) { /* skip non AF_INET interface */ pos_interface++; } else { if (i+1==pos_interface) { char *atmp; atmp = inet_ntoa (((struct sockaddr_in *) ifa->ifa_addr)->sin_addr); *servername = osip_strdup (atmp); *serverip = osip_strdup (atmp); atmp = inet_ntoa (((struct sockaddr_in *) ifa->ifa_netmask)->sin_addr); *netmask = osip_strdup (atmp); freeifaddrs(ifap); return 0; } } i++; } freeifaddrs(ifap); return -1; } if (interface!=NULL) /* The method must return the interface named interface */ { for (ifa = ifap; ifa; ifa=ifa->ifa_next) { if (ifa->ifa_addr!=NULL && ifa->ifa_addr->sa_family==AF_INET && 0==strcmp(ifa->ifa_name, interface)) { char *atmp; atmp = inet_ntoa (((struct sockaddr_in *) ifa->ifa_addr)->sin_addr); *servername = osip_strdup (atmp); *serverip = osip_strdup (atmp); atmp = inet_ntoa (((struct sockaddr_in *) ifa->ifa_netmask)->sin_addr); *netmask = osip_strdup (atmp); freeifaddrs(ifap); return 0; } } freeifaddrs(ifap); return -1; } *serverip = (char*)malloc(50); ppl_dns_default_gateway_ipv4 (*serverip, 49); if (*serverip==NULL) { freeifaddrs(ifap); return -1; } *servername = osip_strdup(*serverip); /* look for the mask */ for (ifa = ifap; ifa; ifa=ifa->ifa_next) { if (ifa->ifa_addr!=NULL && ifa->ifa_addr->sa_family==AF_INET) { char *atmp; atmp = inet_ntoa (((struct sockaddr_in *) ifa->ifa_addr)->sin_addr); if (0==strcmp(*serverip, atmp)) { atmp = inet_ntoa (((struct sockaddr_in *) ifa->ifa_netmask)->sin_addr); *netmask = osip_strdup (atmp); freeifaddrs(ifap); return 0; } } } /* We might not need the mask? */ freeifaddrs(ifap); return 0;}static intppl_dns_get_local_fqdn_ipv6 (char **servername, char **serverip, char **netmask, char *interface, unsigned int pos_interface){ int i = 0; struct ifaddrs *ifap, *ifa; *servername = NULL; *serverip = NULL; *netmask = NULL; if (getifaddrs(&ifap)) return -1; /* cannot fetch interfaces */ if (pos_interface>0) /* The method must return the interface at pos_interface */ { i = 0; for (ifa = ifap; ifa; ifa=ifa->ifa_next) { if (ifa->ifa_addr==NULL || ifa->ifa_addr->sa_family!=AF_INET6) { /* skip non AF_INET interface */ pos_interface++; } else { if (i+1==pos_interface) { *servername = (char*) osip_malloc(50); inet_ntop(AF_INET6, (const void*) &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, (*servername), 49); *serverip = osip_strdup (*servername); *netmask = (char*) osip_malloc(50); inet_ntop(AF_INET6, (const void*) &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr, (*netmask), 49); freeifaddrs(ifap); return 0; } } i++; } freeifaddrs(ifap); return -1; } if (interface!=NULL) /* The method must return the interface named interface */ { for (ifa = ifap; ifa; ifa=ifa->ifa_next) { if (ifa->ifa_addr!=NULL && ifa->ifa_addr->sa_family==AF_INET6 && 0==strcmp(ifa->ifa_name, interface)) { *servername = (char*) osip_malloc(50); inet_ntop(AF_INET6, (const void*) &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, (*servername), 49); *serverip = osip_strdup (*servername); *netmask = (char*) osip_malloc(50); inet_ntop(AF_INET6, (const void*) &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr, (*netmask), 49); freeifaddrs(ifap); return 0; } } freeifaddrs(ifap); return -1; } *serverip = (char*)malloc(50); ppl_dns_default_gateway_ipv6 (*serverip, 49); if (*serverip==NULL) { freeifaddrs(ifap); return -1; } *servername = osip_strdup(*serverip); /* look for the mask */ for (ifa = ifap; ifa; ifa=ifa->ifa_next) { if (ifa->ifa_addr!=NULL && ifa->ifa_addr->sa_family==AF_INET6) { char atmp[50]; inet_ntop(AF_INET6, (const void*) &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, atmp, 49); if (0==strcmp(*serverip, atmp)) { *netmask = (char*) osip_malloc(50); inet_ntop(AF_INET6, (const void*) &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr, *netmask, 49); freeifaddrs(ifap); return 0; } } } /* We might not need the mask? */ freeifaddrs(ifap); return 0;}#else#if defined(__sun__)#include <sys/sockio.h>#endifstatic int ppl_dns_get_local_fqdn_ipv4 (char **servername, char **serverip, char **netmask, char *interface, unsigned int pos_interface){ struct ifconf netconf; int sock, err, if_count, i, j = 0; char tmp[160]; char fqdn_proposal[10][21]; char ip_proposal[10][21]; char def_gateway[50]; *servername = NULL; *serverip = NULL; *netmask = NULL; netconf.ifc_len = 160; netconf.ifc_buf = tmp; sock = ppl_socket (PF_INET, SOCK_DGRAM, 0); err = ioctl (sock, SIOCGIFCONF, &netconf); if (err < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "ioctl failed! cannot detect the ip address!\n")); ppl_socket_close (sock); return -1; } ppl_socket_close (sock); if_count = netconf.ifc_len / 32; if (pos_interface>0) /* The method must return the interface at pos_interface */ { for (i = 0; i < if_count; i++) { struct ifreq *ifr; ifr = &(netconf.ifc_req[i]); if (i+1==pos_interface) { char *atmp; atmp = inet_ntoa (((struct sockaddr_in *) (&ifr->ifr_addr))->sin_addr); *servername = osip_strdup (atmp); *serverip = osip_strdup (atmp);#ifdef __linux { sock = ppl_socket (PF_INET, SOCK_DGRAM, 0); if (sock <= 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "ioctl failed! cannot detect the netmask for %s!\n", *serverip)); return 0; /* we probably don't need the mask? */ } else if (ioctl (sock, SIOCGIFNETMASK, /*&if_data */ &(netconf.ifc_req[i])) < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "ioctl failed! cannot detect the netmask for %s!\n", *serverip)); } else { struct in_addr in; in.s_addr = *((unsigned long *) &netconf.ifc_req[i].ifr_netmask.sa_data[2]); /* *((unsigned long *) &if_data.ifr_netmask.sa_data[2]); */ *netmask = osip_strdup (inet_ntoa (in)); } ppl_socket_close (sock); }#endif return 0; /* even if the mask detection has failed? */ } } return -1; /* even if the mask detection has failed? */ } for (i = 0; i < if_count; i++) { if (interface != NULL && strcmp (netconf.ifc_req[i].ifr_name, interface) == 0) { char *atmp; atmp = inet_ntoa (((struct sockaddr_in *) (&netconf.ifc_req[i]. ifr_addr))->sin_addr); strncpy (fqdn_proposal[0], netconf.ifc_req[i].ifr_name, 30); strncpy (ip_proposal[0], atmp, 30); *servername = osip_strdup (ip_proposal[0]); *serverip = osip_strdup (ip_proposal[0]);#ifdef __linux { struct ifreq if_data; strcpy (if_data.ifr_name, interface); sock = ppl_socket (PF_INET, SOCK_DGRAM, 0); if (sock <= 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "ioctl failed! cannot detect the netmask for %s!\n", atmp)); } else if (ioctl (sock, SIOCGIFNETMASK, &if_data) < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "ioctl failed! cannot detect the netmask for %s!\n", atmp)); } else { struct in_addr in; in.s_addr = *((unsigned long *) &if_data.ifr_netmask.sa_data[2]); *netmask = osip_strdup (inet_ntoa (in)); } ppl_socket_close (sock); }#endif return 0; } if (interface == NULL && strcmp (netconf.ifc_req[i].ifr_name, "lo") != 0) { char *atmp; atmp = inet_ntoa (((struct sockaddr_in *) (&netconf.ifc_req[i]. ifr_addr))->sin_addr); strncpy (fqdn_proposal[j], netconf.ifc_req[i].ifr_name, 20); strncpy (ip_proposal[j], atmp, 20); j++; } } if (interface != NULL) return -1; if (j == 1) { *servername = osip_strdup (ip_proposal[0]); *serverip = osip_strdup (ip_proposal[0]);#ifdef __linux { struct ifreq if_data; strcpy (if_data.ifr_name, fqdn_proposal[0]); sock = ppl_socket (PF_INET, SOCK_DGRAM, 0); if (sock <= 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "ioctl failed! cannot detect the netmask for %s!\n", fqdn_proposal[0])); } else if (ioctl (sock, SIOCGIFNETMASK, &if_data) < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "ioctl failed! cannot detect the netmask for %s!\n", fqdn_proposal[0])); } else { struct in_addr in; in.s_addr = *((unsigned long *) &if_data.ifr_netmask.sa_data[2]); *netmask = osip_strdup (inet_ntoa (in)); } ppl_socket_close (sock); }#endif return PPL_SUCCESS; } else { ppl_dns_default_gateway_ipv4 (def_gateway, 49); if (def_gateway != NULL) { for (i = 0; i < j; i++) { if (strcmp (ip_proposal[i], def_gateway) == 0) { *servername = osip_strdup (ip_proposal[i]); *serverip = osip_strdup (ip_proposal[i]);#ifdef __linux { struct ifreq if_data; strcpy (if_data.ifr_name, fqdn_proposal[i]); sock = ppl_socket (PF_INET, SOCK_DGRAM, 0); if (sock <= 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "ioctl failed! cannot detect the netmask for %s!\n", fqdn_proposal[i])); } else if (ioctl (sock, SIOCGIFNETMASK, &if_data) < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "ioctl failed! cannot detect the netmask for %s!\n", fqdn_proposal[i])); perror ("socket failed"); } else { struct in_addr in; in.s_addr = *((unsigned long *) &if_data.ifr_netmask.sa_data[2]); *netmask = osip_strdup (inet_ntoa (in)); } ppl_socket_close (sock); }#endif return PPL_SUCCESS; } } } } return -1;}static int ppl_dns_get_local_fqdn_ipv6 (char **servername, char **serverip, char **netmask, char *interface, unsigned int pos_interface){ *servername = NULL; *serverip = NULL; *netmask = NULL; /* TODO */ return -1;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -