unsigned long in_netof(struct in_addr in) { unsigned long i, net; struct in_ifaddr *ia; /* Setup locals */ i = ntohl(in.s_addr); /* Get network number */ if ( IN_CLASSA(i) ) net = i & IN_CLASSA_NET; else if ( IN_CLASSB(i) ) net = i & IN_CLASSB_NET; else if ( IN_CLASSC(i) ) net = i & IN_CLASSC_NET; else if ( IN_CLASSD(i) ) net = i & IN_CLASSD_NET; else return 0; /* Check if subnet */ for (ia = in_ifaddr; ia != NULL; ia = ia->ia_next) if (net == ia->ia_net) return (i & ia->ia_subnetmask); return net; }
/* This calculates the netmask that we should use for static routes. * This IS different from the calculation used to calculate the netmask * for an interface address. */ static uint32_t route_netmask(uint32_t ip_in) { /* used to be unsigned long - check if error */ uint32_t p = ntohl(ip_in); uint32_t t; if (IN_CLASSA(p)) t = ~IN_CLASSA_NET; else { if (IN_CLASSB(p)) t = ~IN_CLASSB_NET; else { if (IN_CLASSC(p)) t = ~IN_CLASSC_NET; else t = 0; } } while (t & p) t >>= 1; return (htonl(~t)); }
/* Utility function to convert ipv4 prefixes to Classful prefixes */ void apply_classful_mask_ipv4 (struct prefix_ipv4 *p) { u_int32_t destination; destination = ntohl (p->prefix.s_addr); if (p->prefixlen == IPV4_MAX_PREFIXLEN); /* do nothing for host routes */ else if (IN_CLASSC (destination)) { p->prefixlen=24; apply_mask_ipv4(p); } else if (IN_CLASSB(destination)) { p->prefixlen=16; apply_mask_ipv4(p); } else { p->prefixlen=8; apply_mask_ipv4(p); } }
/* * Given a host-order address, calculate client's default net mask. * Consult netmasks database to see if net is further subnetted. * We'll only snag the first netmask that matches our criteria. * We return the resultant netmask in host order. */ void get_netmask4(const struct in_addr *n_addrp, struct in_addr *s_addrp) { struct in_addr hp, tp; /* * First check if VLSM is in use. */ hp.s_addr = htonl(n_addrp->s_addr); if (getnetmaskbyaddr(hp, &tp) == 0) { s_addrp->s_addr = ntohl(tp.s_addr); return; } /* * Fall back on standard classed networks. */ if (IN_CLASSA(n_addrp->s_addr)) s_addrp->s_addr = IN_CLASSA_NET; else if (IN_CLASSB(n_addrp->s_addr)) s_addrp->s_addr = IN_CLASSB_NET; else if (IN_CLASSC(n_addrp->s_addr)) s_addrp->s_addr = IN_CLASSC_NET; else s_addrp->s_addr = IN_CLASSE_NET; }
/// This function uses Windows Sockets macros to get standard class information. It /// does not know about subnetting or any classes beyond class C. TINetSocketAddress::TINetClass TINetSocketAddress::GetClass() const { if (IN_CLASSA(GetNetworkAddress())) return ClassA; if (IN_CLASSB(GetNetworkAddress())) return ClassB; if (IN_CLASSC(GetNetworkAddress())) return ClassC; return ClassUnknown; }
static int config_ip_prefix(struct in_addr *addr) { if (IN_CLASSA(addr->s_addr)) return 32 - IN_CLASSA_NSHIFT; if (IN_CLASSB(addr->s_addr)) return 32 - IN_CLASSB_NSHIFT; if (IN_CLASSC(addr->s_addr)) return 32 - IN_CLASSC_NSHIFT; return 0; }
static uint32_t inet_class_netmask(uint32_t ip) { ip = ntohl(ip); if (IN_CLASSA(ip)) return htonl(IN_CLASSA_NET); if (IN_CLASSB(ip)) return htonl(IN_CLASSB_NET); if (IN_CLASSC(ip)) return htonl(IN_CLASSC_NET); return INADDR_ANY; }
//--------------------------------------------------------------------------- // Search the entity with the IPv4 address 'addr' struct cx_entity *nasmt_CLASS_cx4(struct sk_buff *skb, unsigned char dscp, int *paddr_type, unsigned char *cx_index) { //--------------------------------------------------------------------------- unsigned char cxi; uint32_t daddr; struct cx_entity *cx=NULL; struct classifier_entity *pclassifier=NULL; struct in_addr masked_addr; #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_cx4: begin\n"); #endif if (skb!=NULL) { daddr = ((struct iphdr*)(skb_network_header(skb)))->daddr; if (daddr != INADDR_ANY) { #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_cx4: SOURCE ADDR %d.%d.%d.%d",NIPADDR(ip_hdr(skb)->saddr)); printk(" DEST ADDR %d.%d.%d.%d\n",NIPADDR(ip_hdr(skb)->daddr)); #endif if (ipv4_is_multicast(ip_hdr(skb)->daddr)) { // TO BE CHECKED *paddr_type = NAS_IPV4_ADDR_MC_SIGNALLING; } else { if (ipv4_is_lbcast(ip_hdr(skb)->daddr)) { // TO BE CHECKED *paddr_type = NAS_IPV4_ADDR_BROADCAST; } else { if (IN_CLASSA(ip_hdr(skb)->daddr) || IN_CLASSB(ip_hdr(skb)->daddr) || IN_CLASSC(ip_hdr(skb)->daddr)) { *paddr_type = NAS_IPV4_ADDR_UNICAST; cxi = 0; (*cx_index)++; pclassifier = gpriv->cx[cxi].sclassifier[dscp]; while (pclassifier!=NULL) { // verify that this is an IPv4 classifier if ((pclassifier->version == NAS_VERSION_4) || (pclassifier->version == NAS_VERSION_DEFAULT)) { nasmt_create_mask_ipv4_addr(&masked_addr, pclassifier->dplen); if (IN_ARE_ADDR_MASKED_EQUAL(&ip_hdr(skb)->daddr, &(pclassifier->daddr.ipv4), &masked_addr)) { #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_cx4: IP MASK MATCHED: found cx %d: %d.%d.%d.%d/%d\n",cxi, NIPADDR(pclassifier->daddr.ipv4), pclassifier->dplen); #endif return &gpriv->cx[cxi]; } } // goto to next classification rule for the connection pclassifier = pclassifier->next; } } else { *paddr_type = NAS_IPV4_ADDR_UNKNOWN; } } } } } return cx; }
/* * Get the netmask of an IP address. This routine is used if * SIOCGIFNETMASK doesn't work. */ u_int32_t ipaddrtonetmask(u_int32_t addr) { if (IN_CLASSA(addr)) return IN_CLASSA_NET; if (IN_CLASSB(addr)) return IN_CLASSB_NET; if (IN_CLASSC(addr)) return IN_CLASSC_NET; error(FATAL, "unknown IP address class: %08X", addr); /* NOTREACHED */ }
int nl_set_ifaddr(struct in_addr ifaddr, struct in_addr bcaddr, int ifindex) { struct { struct ifaddrmsg ifa; struct { struct rtattr rta; struct in_addr addr; } data[3]; } m; memset(&m, 0, sizeof(m)); m.ifa.ifa_family = AF_INET; if (IN_CLASSA(ifaddr.s_addr)) m.ifa.ifa_prefixlen = IN_CLASSA_NSHIFT; else if (IN_CLASSB(ifaddr.s_addr)) m.ifa.ifa_prefixlen = IN_CLASSB_NSHIFT; else if (IN_CLASSC(ifaddr.s_addr)) m.ifa.ifa_prefixlen = IN_CLASSC_NSHIFT; else if (IN_CLASSD(ifaddr.s_addr)) m.ifa.ifa_prefixlen = 0; m.ifa.ifa_prefixlen = 24; m.ifa.ifa_flags = 0; //IFA_F_PERMANENT; m.ifa.ifa_scope = RT_SCOPE_UNIVERSE; m.ifa.ifa_index = ifindex; m.data[0].rta.rta_len = RTA_LENGTH(sizeof(ifaddr)); m.data[0].rta.rta_type = IFA_LOCAL; m.data[0].addr.s_addr = ifaddr.s_addr; m.data[1].rta.rta_len = RTA_LENGTH(sizeof(ifaddr)); m.data[1].rta.rta_type = IFA_ADDRESS; m.data[1].addr.s_addr = ifaddr.s_addr; m.data[2].rta.rta_len = RTA_LENGTH(sizeof(ifaddr)); m.data[2].rta.rta_type = IFA_BROADCAST; m.data[2].addr.s_addr = bcaddr.s_addr; DEBUG(LOG_DEBUG, 0, "Sending new ifaddr %s %s netlink message index=%d", ip_to_str(ifaddr), ip_to_str(bcaddr), ifindex); return nl_create_and_send_msg(rtnlsock, RTM_NEWADDR, &m, sizeof(m)); }
unsigned long get_netmask (unsigned long addr) { unsigned long dst; if (addr == 0) return (0); dst = htonl (addr); if (IN_CLASSA (dst)) return (ntohl (IN_CLASSA_NET)); if (IN_CLASSB (dst)) return (ntohl (IN_CLASSB_NET)); if (IN_CLASSC (dst)) return (ntohl (IN_CLASSC_NET)); return (0); }
void start_networking(void) { struct ip_addr ipaddr = { htonl(IF_IPADDR) }; struct ip_addr netmask = { htonl(IF_NETMASK) }; struct ip_addr gw = { 0 }; char *ip = NULL; #ifdef CONFIG_PRINT tprintk("Waiting for network.\n"); #endif dev = init_netfront(NULL, NULL, rawmac, &ip); if (ip) { ipaddr.addr = inet_addr(ip); if (IN_CLASSA(ntohl(ipaddr.addr))) netmask.addr = htonl(IN_CLASSA_NET); else if (IN_CLASSB(ntohl(ipaddr.addr))) netmask.addr = htonl(IN_CLASSB_NET); else if (IN_CLASSC(ntohl(ipaddr.addr))) netmask.addr = htonl(IN_CLASSC_NET); else tprintk("Strange IP %s, leaving netmask to 0.\n", ip); } tprintk("IP %x netmask %x gateway %x.\n", ntohl(ipaddr.addr), ntohl(netmask.addr), ntohl(gw.addr)); #ifdef CONFIG_PRINT tprintk("TCP/IP bringup begins.\n"); #endif netif = xmalloc(struct netif); tcpip_init(tcpip_bringup_finished, netif); netif_add(netif, &ipaddr, &netmask, &gw, rawmac, netif_netfront_init, ip_input); netif_set_default(netif); netif_set_up(netif); down(&tcpip_is_up); #ifdef CONFIG_FRONT tprintk("Network is ready.\n"); #endif }
uint32_t get_netmask(uint32_t addr) { uint32_t dst; if (addr == 0) return 0; dst = htonl(addr); if (IN_CLASSA(dst)) return ntohl(IN_CLASSA_NET); if (IN_CLASSB(dst)) return ntohl(IN_CLASSB_NET); if (IN_CLASSC(dst)) return ntohl(IN_CLASSC_NET); return 0; }
static struct in_addr networkFromInaddr(struct in_addr a) { struct in_addr b; b.s_addr = ntohl(a.s_addr); #if USE_CLASSFUL if (IN_CLASSC(b.s_addr)) b.s_addr &= IN_CLASSC_NET; else if (IN_CLASSB(b.s_addr)) b.s_addr &= IN_CLASSB_NET; else if (IN_CLASSA(b.s_addr)) b.s_addr &= IN_CLASSA_NET; #else /* use /24 for everything */ b.s_addr &= IN_CLASSC_NET; #endif b.s_addr = htonl(b.s_addr); return b; }
static inline int inet_abc_len(__be32 addr) { int rc = -1; /* Something else, probably a multicast. */ if (ipv4_is_zeronet(addr)) rc = 0; else { __u32 haddr = ntohl(addr); if (IN_CLASSA(haddr)) rc = 8; else if (IN_CLASSB(haddr)) rc = 16; else if (IN_CLASSC(haddr)) rc = 24; } return rc; }
static __inline__ int inet_abc_len(u32 addr) { if (ZERONET(addr)) return 0; addr = ntohl(addr); if (IN_CLASSA(addr)) return 8; if (IN_CLASSB(addr)) return 16; if (IN_CLASSC(addr)) return 24; /* * Something else, probably a multicast. */ return -1; }
static __inline__ int inet_abc_len(u32 addr) { int rc = -1; /* Something else, probably a multicast. */ if (ZERONET(addr)) rc = 0; else { addr = ntohl(addr); if (IN_CLASSA(addr)) rc = 8; else if (IN_CLASSB(addr)) rc = 16; else if (IN_CLASSC(addr)) rc = 24; } return rc; }
static unsigned long getnetmask (unsigned long ip_in) { unsigned long t, p = ntohl (ip_in); if (IN_CLASSA (p)) t = ~IN_CLASSA_NET; else { if (IN_CLASSB (p)) t = ~IN_CLASSB_NET; else { if (IN_CLASSC (p)) t = ~IN_CLASSC_NET; else t = 0; } } while (t & p) t >>= 1; return htonl (~t); }
void resume_networking(int cancelled) { //struct netif *netif; struct ip_addr ipaddr = { htonl(IF_IPADDR) }; struct ip_addr netmask = { htonl(IF_NETMASK) }; struct ip_addr gw = { htonl(0xc0a87a01) }; char *ip = NULL; #ifdef CONFIG_PRINT tprintk("Waiting for network.\n"); #endif dev = init_netfront(NULL, NULL, rawmac, &ip); if(!cancelled){ if (ip) { ipaddr.addr = inet_addr(ip); if (IN_CLASSA(ntohl(ipaddr.addr))) netmask.addr = htonl(IN_CLASSA_NET); else if (IN_CLASSB(ntohl(ipaddr.addr))) netmask.addr = htonl(IN_CLASSB_NET); else if (IN_CLASSC(ntohl(ipaddr.addr))) netmask.addr = htonl(IN_CLASSC_NET); else tprintk("Strange IP %s, leaving netmask to 0.\n", ip); } tprintk("IP %x netmask %x gateway %x.\n", ntohl(ipaddr.addr), ntohl(netmask.addr), ntohl(gw.addr)); netif = xmalloc(struct netif); netif_add(netif, &ipaddr, &netmask, &gw, rawmac, netif_netfront_init, ip_input); netif_set_default(netif); netif_set_up(netif); down(&tcpip_is_up); } #ifdef CONFIG_SUSPEND tprintk("TCP/IP bringup begins.\n"); #endif }
sockaddr_u * netof( sockaddr_u *hostaddr ) { static sockaddr_u netofbuf[8]; static int next_netofbuf; u_int32 netnum; sockaddr_u * netaddr; netaddr = &netofbuf[next_netofbuf]; next_netofbuf = (next_netofbuf + 1) % COUNTOF(netofbuf); memcpy(netaddr, hostaddr, sizeof(*netaddr)); if (IS_IPV4(netaddr)) { netnum = SRCADR(netaddr); /* * We live in a modern CIDR world where the basement nets, which * used to be class A, are now probably associated with each * host address. So, for class-A nets, all bits are significant. */ if (IN_CLASSC(netnum)) netnum &= IN_CLASSC_NET; else if (IN_CLASSB(netnum)) netnum &= IN_CLASSB_NET; SET_ADDR4(netaddr, netnum); } else if (IS_IPV6(netaddr)) /* assume the typical /64 subnet size */ zero_mem(&NSRCADR6(netaddr)[8], 8); #ifdef DEBUG else { msyslog(LOG_ERR, "netof unknown AF %d", AF(netaddr)); exit(1); } #endif return netaddr; }
/* Utility function to convert ipv4 netmask to prefixes ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16" ex.) "1.0.0.0" NULL => "1.0.0.0/8" */ int netmask_isis_str2prefix_str (const char *net_str, const char *mask_str, char *prefix_str) { struct in_addr network; struct in_addr mask; u_char prefixlen; u_int32_t destination; int ret; ret = inet_aton (net_str, &network); if (! ret) return 0; if (mask_str) { ret = inet_aton (mask_str, &mask); if (! ret) return 0; prefixlen = isis_ip_masklen (mask); } else { destination = ntohl (network.s_addr); if (network.s_addr == 0) prefixlen = 0; else if (IN_CLASSC (destination)) prefixlen = 24; else if (IN_CLASSB (destination)) prefixlen = 16; else if (IN_CLASSA (destination)) prefixlen = 8; else return 0; } sprintf (prefix_str, "%s/%d", net_str, prefixlen); return 1; }
static unsigned int guess_prefix_len(struct in_addr addr) { uint32_t prefix = ntohl(addr.s_addr); unsigned int len; /* At a minimum, use the prefix len for this IPv4 address class. */ if (IN_CLASSA(prefix)) len = 8; else if (IN_CLASSB(prefix)) len = 16; else if (IN_CLASSC(prefix)) len = 24; else len = 0; /* If the address has bits beyond the default class, * extend the prefix until we've covered all of them. */ return len + __count_net_bits(prefix << len); }
static void set_broadcast_address( uint32_t net_address) { #if defined(USE_INADDR) && USE_INADDR /* Note: sometimes INADDR_BROADCAST does not let me get any unicast messages. Not sure why... */ net_address = net_address; bip_set_broadcast_addr(INADDR_BROADCAST); #elif defined(USE_CLASSADDR) && USE_CLASSADDR long broadcast_address = 0; if (IN_CLASSA(ntohl(net_address))) broadcast_address = (ntohl(net_address) & ~IN_CLASSA_HOST) | IN_CLASSA_HOST; else if (IN_CLASSB(ntohl(net_address))) broadcast_address = (ntohl(net_address) & ~IN_CLASSB_HOST) | IN_CLASSB_HOST; else if (IN_CLASSC(ntohl(net_address))) broadcast_address = (ntohl(net_address) & ~IN_CLASSC_HOST) | IN_CLASSC_HOST; else if (IN_CLASSD(ntohl(net_address))) broadcast_address = (ntohl(net_address) & ~IN_CLASSD_HOST) | IN_CLASSD_HOST; else broadcast_address = INADDR_BROADCAST; bip_set_broadcast_addr(htonl(broadcast_address)); #else /* these are network byte order variables */ long broadcast_address = 0; long net_mask = 0; net_mask = getIpMaskForIpAddress(net_address); if (BIP_Debug) { struct in_addr address; address.s_addr = net_mask; printf("IP Mask: %s\n", inet_ntoa(address)); } broadcast_address = (net_address & net_mask) | (~net_mask); bip_set_broadcast_addr(broadcast_address); #endif }
/* * Provide a classful subnet mask based on the client's IP address. */ static in_addr_t generate_classful_subnet(in_addr_t client_ipaddr) { struct in_addr subnetmask; char *netstr; if (IN_CLASSA(client_ipaddr)) { subnetmask.s_addr = IN_CLASSA_NET; } else if (IN_CLASSB(client_ipaddr)) { subnetmask.s_addr = IN_CLASSB_NET; } else if (IN_CLASSC(client_ipaddr)) { subnetmask.s_addr = IN_CLASSC_NET; } else { subnetmask.s_addr = IN_CLASSE_NET; } netstr = inet_ntoa(subnetmask); (void) bootinfo_put(BI_SUBNET_MASK, netstr, strlen(netstr) + 1, 0); return (subnetmask.s_addr); }
unsigned long ip_get_mask(unsigned long addr) { unsigned long dst; if (addr == 0L) return(0L); /* special case */ dst = ntohl(addr); if (IN_CLASSA(dst)) return(htonl(IN_CLASSA_NET)); if (IN_CLASSB(dst)) return(htonl(IN_CLASSB_NET)); if (IN_CLASSC(dst)) return(htonl(IN_CLASSC_NET)); /* * Something else, probably a multicast. */ return(0); }
/* * Lookup a netmask * Return non-zero on failure. * * XXX - This is OK as a default, but to really make this automatic, * we would need to get the subnet mask from the ether interface. * If this is wrong, specify the correct value in the bootptab. * * Both inputs are in network order. */ int lookup_netmask(u_int32 addr, u_int32 *result) { int32 m, a; a = ntohl(addr); m = 0; if (IN_CLASSA(a)) m = IN_CLASSA_NET; if (IN_CLASSB(a)) m = IN_CLASSB_NET; if (IN_CLASSC(a)) m = IN_CLASSC_NET; if (!m) return -1; *result = htonl(m); return 0; }
/* This calculates the netmask that we should use for static routes. * This IS different from the calculation used to calculate the netmask * for an interface address. */ static unsigned long route_netmask (unsigned long ip_in) { unsigned long p = ntohl (ip_in); unsigned long t; if (IN_CLASSA (p)) t = ~IN_CLASSA_NET; else { if (IN_CLASSB (p)) t = ~IN_CLASSB_NET; else { if (IN_CLASSC (p)) t = ~IN_CLASSC_NET; else t = 0; } } while (t & p) t >>= 1; return (htonl (~t)); }
static bool valid_reflector_address( const char *address ) { debug( "Validating an IPv4 address ( %s ).", address != NULL ? address : "" ); assert( address != NULL ); struct in_addr dst; int ret = inet_pton( AF_INET, address, &dst ); if ( ret != 1 ) { error( "Invalid IP address ( %s ).", address ); return false; } const uint32_t dst_addr = ntohl( dst.s_addr ); if ( ( IN_CLASSA( dst_addr ) && ( dst_addr != INADDR_ANY ) && ( dst_addr != INADDR_LOOPBACK ) ) || IN_CLASSB( dst_addr ) || IN_CLASSC( dst_addr ) || IN_CLASSD( dst_addr ) ) { debug( "Valid IPv4 address ( %s ).", address ); return true; } error( "Invalid IP address ( %s ).", address ); return false; }
static void egpnrprint(netdissect_options *ndo, const struct egp_packet *egp, u_int length) { const uint8_t *cp; uint32_t addr; uint32_t net; u_int netlen; u_int gateways, distances, networks; u_int intgw, extgw, t_gateways; const char *comma; addr = EXTRACT_IPV4_TO_NETWORK_ORDER(egp->egp_sourcenet); if (IN_CLASSA(addr)) { net = addr & IN_CLASSA_NET; netlen = 1; } else if (IN_CLASSB(addr)) { net = addr & IN_CLASSB_NET; netlen = 2; } else if (IN_CLASSC(addr)) { net = addr & IN_CLASSC_NET; netlen = 3; } else { net = 0; netlen = 0; } cp = (const uint8_t *)(egp + 1); length -= sizeof(*egp); intgw = EXTRACT_U_1(egp->egp_intgw); extgw = EXTRACT_U_1(egp->egp_extgw); t_gateways = intgw + extgw; for (gateways = 0; gateways < t_gateways; ++gateways) { /* Pickup host part of gateway address */ addr = 0; if (length < 4 - netlen) goto trunc; ND_TCHECK_LEN(cp, 4 - netlen); switch (netlen) { case 1: addr = EXTRACT_U_1(cp); cp++; /* fall through */ case 2: addr = (addr << 8) | EXTRACT_U_1(cp); cp++; /* fall through */ case 3: addr = (addr << 8) | EXTRACT_U_1(cp); cp++; break; } addr |= net; length -= 4 - netlen; if (length < 1) goto trunc; ND_TCHECK_1(cp); distances = EXTRACT_U_1(cp); cp++; length--; ND_PRINT(" %s %s ", gateways < intgw ? "int" : "ext", ipaddr_string(ndo, (const u_char *)&addr)); comma = ""; ND_PRINT("("); while (distances != 0) { if (length < 2) goto trunc; ND_TCHECK_2(cp); ND_PRINT("%sd%u:", comma, EXTRACT_U_1(cp)); cp++; comma = ", "; networks = EXTRACT_U_1(cp); cp++; length -= 2; while (networks != 0) { /* Pickup network number */ if (length < 1) goto trunc; ND_TCHECK_1(cp); addr = ((uint32_t) EXTRACT_U_1(cp)) << 24; cp++; length--; if (IN_CLASSB(addr)) { if (length < 1) goto trunc; ND_TCHECK_1(cp); addr |= ((uint32_t) EXTRACT_U_1(cp)) << 16; cp++; length--; } else if (!IN_CLASSA(addr)) { if (length < 2) goto trunc; ND_TCHECK_2(cp); addr |= ((uint32_t) EXTRACT_U_1(cp)) << 16; cp++; addr |= ((uint32_t) EXTRACT_U_1(cp)) << 8; cp++; length -= 2; } ND_PRINT(" %s", ipaddr_string(ndo, (const u_char *)&addr)); networks--; } distances--; } ND_PRINT(")"); } return; trunc: ND_PRINT("[|]"); }
/* * _dnsinfo_parse_sortaddr * * Parse arguments to the sortlist token. */ static dns_sortaddr_t * _dnsinfo_parse_sortaddr(char *token) { struct in_addr addr; struct in_addr mask; struct sockaddr *sa; char *slash; dns_sortaddr_t *sortaddr = NULL; slash = strchr(token, '/'); if (slash != NULL) { *slash = '\0'; } sa = _dnsinfo_parse_address(token); if (sa == NULL) { // if we could not parse the address goto done; } else if (sa->sa_family != AF_INET) { // if not AF_INET goto done; } else { /* ALIGN: cast ok, sockaddr was malloc'd */ addr = ((struct sockaddr_in *)(void *)sa)->sin_addr; free(sa); sa = NULL; } if (slash != NULL) { sa = _dnsinfo_parse_address(slash + 1); if (sa == NULL) { // if we could not parse the provided mask goto done; } else if (sa->sa_family != AF_INET) { // if mask not AF_INET goto done; } else { /* ALIGN: cast ok, sockaddr was malloc'd */ mask = ((struct sockaddr_in *)(void *)sa)->sin_addr; free(sa); sa = NULL; } } else { in_addr_t a; in_addr_t m; a = ntohl(addr.s_addr); if (IN_CLASSA(a)) { m = IN_CLASSA_NET; } else if (IN_CLASSB(a)) { m = IN_CLASSB_NET; } else if (IN_CLASSC(a)) { m = IN_CLASSC_NET; } else { goto done; } mask.s_addr = htonl(m); } sortaddr = malloc(sizeof(*sortaddr)); sortaddr->address = addr; sortaddr->mask = mask; done : if (sa != NULL) free(sa); return sortaddr; }