/* * _hpaddr: construct hostent structure with one address */ static struct hostent * _hpaddr(int af, const char *name, void *addr, int *errp) { struct hostent *hp, hpbuf; char *addrs[2]; hp = &hpbuf; hp->h_name = (char *)name; hp->h_aliases = NULL; hp->h_addrtype = af; hp->h_length = ADDRLEN(af); hp->h_addr_list = addrs; addrs[0] = (char *)addr; addrs[1] = NULL; return _hpcopy(hp, errp); }
gint format_addr (struct sockaddr *sa, gchar *h, gsize hL, gchar *p, gsize pL, GError **err) { if (!sa) { GSETERROR(err,"Invalid parameter"); return 0; } memset (h, 0x00, hL); memset (p, 0x00, pL); *h = '?'; *p = '?'; /*no reverse resolution, only numeric addresses*/ if (0 != getnameinfo (sa, ADDRLEN(sa), h, hL, p, pL, NI_NUMERICHOST|NI_NUMERICSERV)) { GSETERROR(err, "Cannot format the address (%s)", strerror(errno)); return 0; } return 1; }
static int _files_ghbyname(void *rval, void *cb_data, va_list ap) { const char *name; int af; int *errp; int match, nalias; char *p, *line, *addrstr, *cname; FILE *fp; struct hostent *rethp, *hp, hpbuf; char *aliases[MAXALIASES + 1], *addrs[2]; union inx_addr addrbuf; char buf[BUFSIZ]; int af0; name = va_arg(ap, const char *); af = va_arg(ap, int); errp = va_arg(ap, int *); *(struct hostent **)rval = NULL; if ((fp = _files_open(errp)) == NULL) return NS_UNAVAIL; rethp = hp = NULL; af0 = af; while (fgets(buf, sizeof(buf), fp)) { line = buf; if ((addrstr = _hgetword(&line)) == NULL || (cname = _hgetword(&line)) == NULL) continue; match = (strcasecmp(cname, name) == 0); nalias = 0; while ((p = _hgetword(&line)) != NULL) { if (!match) match = (strcasecmp(p, name) == 0); if (nalias < MAXALIASES) aliases[nalias++] = p; } if (!match) continue; switch (af0) { case AF_INET: if (inet_aton(addrstr, (struct in_addr *)&addrbuf) != 1) { *errp = NO_DATA; /* name found */ continue; } af = af0; break; #ifdef INET6 case AF_INET6: if (inet_pton(af, addrstr, &addrbuf) != 1) { *errp = NO_DATA; /* name found */ continue; } af = af0; break; #endif case AF_UNSPEC: if (inet_aton(addrstr, (struct in_addr *)&addrbuf) == 1) { af = AF_INET; break; } #ifdef INET6 if (inet_pton(AF_INET6, addrstr, &addrbuf) == 1) { af = AF_INET6; break; } #endif *errp = NO_DATA; /* name found */ continue; /* NOTREACHED */ } hp = &hpbuf; hp->h_name = cname; hp->h_aliases = aliases; aliases[nalias] = NULL; hp->h_addrtype = af; hp->h_length = ADDRLEN(af); hp->h_addr_list = addrs; addrs[0] = (char *)&addrbuf; addrs[1] = NULL; hp = _hpcopy(hp, errp); rethp = _hpmerge(rethp, hp, errp); } fclose(fp); *(struct hostent **)rval = rethp; return (rethp != NULL) ? NS_SUCCESS : NS_NOTFOUND; }
/* Retrieve address information for the given ifp */ static int if_get_addr (struct interface *ifp, struct sockaddr *addr, const char *label) { int ret; struct lifreq lifreq; struct sockaddr_storage mask, dest; char *dest_pnt = NULL; u_char prefixlen = 0; afi_t af; int flags = 0; /* Interface's name and address family. * We need to use the logical interface name / label, if we've been * given one, in order to get the right address */ strncpy (lifreq.lifr_name, (label ? label : ifp->name), IFNAMSIZ); /* Interface's address. */ memcpy (&lifreq.lifr_addr, addr, ADDRLEN (addr)); af = addr->sa_family; /* Point to point or broad cast address pointer init. */ dest_pnt = NULL; if (AF_IOCTL (af, SIOCGLIFDSTADDR, (caddr_t) & lifreq) >= 0) { memcpy (&dest, &lifreq.lifr_dstaddr, ADDRLEN (addr)); if (af == AF_INET) dest_pnt = (char *) &(SIN (&dest)->sin_addr); else dest_pnt = (char *) &(SIN6 (&dest)->sin6_addr); flags = ZEBRA_IFA_PEER; } if (af == AF_INET) { ret = if_ioctl (SIOCGLIFNETMASK, (caddr_t) & lifreq); if (ret < 0) { if (errno != EADDRNOTAVAIL) { zlog_warn ("SIOCGLIFNETMASK (%s) fail: %s", ifp->name, safe_strerror (errno)); return ret; } return 0; } memcpy (&mask, &lifreq.lifr_addr, ADDRLEN (addr)); prefixlen = ip_masklen (SIN (&mask)->sin_addr); if (!dest_pnt && (if_ioctl (SIOCGLIFBRDADDR, (caddr_t) & lifreq) >= 0)) { memcpy (&dest, &lifreq.lifr_broadaddr, sizeof (struct sockaddr_in)); dest_pnt = (char *) &SIN (&dest)->sin_addr; } } #ifdef HAVE_IPV6 else if (af == AF_INET6) { if (if_ioctl_ipv6 (SIOCGLIFSUBNET, (caddr_t) & lifreq) < 0) { if (ifp->flags & IFF_POINTOPOINT) prefixlen = IPV6_MAX_BITLEN; else zlog_warn ("SIOCGLIFSUBNET (%s) fail: %s", ifp->name, safe_strerror (errno)); } else { prefixlen = lifreq.lifr_addrlen; } } #endif /* HAVE_IPV6 */ /* Set address to the interface. */ if (af == AF_INET) connected_add_ipv4 (ifp, flags, &SIN (addr)->sin_addr, prefixlen, (struct in_addr *) dest_pnt, label); #ifdef HAVE_IPV6 else if (af == AF_INET6) connected_add_ipv6 (ifp, flags, &SIN6 (addr)->sin6_addr, prefixlen, (struct in6_addr *) dest_pnt, label); #endif /* HAVE_IPV6 */ return 0; }