File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mpd / src / ip.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:39:23 2021 UTC (4 years ago) by misho
Branches: mpd, MAIN
CVS tags: v5_9p16, v5_9, HEAD
mpd 5.9

    1: 
    2: /*
    3:  * ip.c
    4:  *
    5:  * Written by Alexander Motin <mav@FreeBSD.org>
    6:  */
    7: 
    8: #include "ppp.h"
    9: #include "ip.h"
   10: #include "util.h"
   11: 
   12: /*
   13:  * IpShowRoutes()
   14:  *
   15:  * Show routing tables
   16:  */
   17: 
   18: int
   19: IpShowRoutes(Context ctx, int ac, const char *const av[], const void *arg)
   20: {
   21:   FILE	*fp;
   22:   char	buf[256];
   23:   char	*c;
   24: 
   25:   (void)ac;
   26:   (void)av;
   27:   (void)arg;
   28: 
   29:   if ((fp = popen(PATH_NETSTAT " -nr -f inet", "r")) == NULL)
   30:   {
   31:     Perror("popen");
   32:     return(CMD_ERR_OTHER);
   33:   }
   34:   while (fgets(buf,sizeof(buf)-1,fp)) {
   35:     if ((c=strrchr(buf,'\n')))
   36: 	*c='\r';
   37:     Printf("%s\n",buf);
   38:   }
   39:   pclose(fp);
   40:   return(0);
   41: }
   42: 
   43: /*
   44:  * IpAddrInRange()
   45:  *
   46:  * Is the IP address within the range?
   47:  */
   48: 
   49: int
   50: IpAddrInRange(struct u_range *range, struct u_addr *addr)
   51: {
   52:   u_int32_t mask;
   53:   u_int8_t bmask;
   54:   int	i;
   55: 
   56:   if (u_rangeempty(range))
   57:     return(1);	// For compatibility we think that empty range includes any ip.
   58: 
   59:   if (range->addr.family!=addr->family)
   60:     return(0);
   61: 
   62:   switch (range->addr.family) {
   63:     case AF_INET:
   64: 	    mask = range->width ? htonl(~0 << (32 - range->width)) : 0;
   65: 	    return((addr->u.ip4.s_addr & mask) == (range->addr.u.ip4.s_addr & mask));
   66: 	break;
   67:     case AF_INET6:
   68: 	    for (i=0; i<((range->width+7)/8); i++) {
   69: 		if ((i*8+7)<range->width) {
   70: 		    if (addr->u.ip6.s6_addr[i]!=range->addr.u.ip6.s6_addr[i])
   71: 			return 0;
   72: 		} else {
   73: 		    bmask=(range->width==i*8)? 0 : (~0 << (8 - range->width));
   74: 		    if ((addr->u.ip6.s6_addr[i] & bmask) != (range->addr.u.ip6.s6_addr[i] & bmask))
   75: 			return 0;
   76: 		}
   77: 	    }
   78: 	    return 1;
   79: 	break;
   80:   }
   81:   return 0;
   82: }
   83: 
   84: /*
   85:  * ParseAddr()
   86:  *
   87:  * Parse an IP address & mask of the form X.Y.Z.W/M.
   88:  * If no slash, then M is assumed to be 32.
   89:  * Returns TRUE if successful
   90:  */
   91: 
   92: int
   93: ParseAddr(const char *s, struct u_addr *addr, u_char allow)
   94: {
   95:   if (strchr(s, '/'))
   96:     return (FALSE);
   97: 
   98: /* Get IP address part; if that fails, try looking up hostname */
   99: 
  100:   if ((allow&ALLOW_IPV4) && inet_pton(AF_INET, s, &addr->u.ip4))
  101:   {
  102:     addr->family=AF_INET;
  103:   } 
  104:   else if ((allow&ALLOW_IPV6) && inet_pton(AF_INET6, s, &addr->u.ip6))
  105:   {
  106:     addr->family=AF_INET6;
  107:   } 
  108:   else if ((allow&ALLOW_IPV4) && !GetAnyIpAddress(addr, s)) 
  109:   {
  110:     addr->family=AF_INET;
  111:   }
  112:   else if (allow&ALLOW_IPV4)
  113:   {
  114:   	struct hostent	*hptr;
  115: 	int		k;
  116: 
  117: 	if ((hptr = gethostbyname(s)) == NULL) {
  118:     	    return (FALSE);
  119: 	}
  120: 	for (k = 0; hptr->h_addr_list[k]; k++);
  121: 	if (k == 0)
  122: 	    k = 1;
  123: 	memcpy(&addr->u.ip4, hptr->h_addr_list[random() % k], sizeof(addr->u.ip4));
  124: 	addr->family=AF_INET;
  125:   } 
  126:   else 
  127:   {
  128:     return (FALSE);
  129:   }
  130: 
  131:   return(TRUE);
  132: }
  133: 
  134: /*
  135:  * ParseRange()
  136:  *
  137:  * Parse an IP address & mask of the form X.Y.Z.W/M.
  138:  * If no slash, then M is assumed to be 32.
  139:  * Returns TRUE if successful
  140:  */
  141: 
  142: int
  143: ParseRange(const char *s, struct u_range *range, u_char allow)
  144: {
  145:   int			n_bits;
  146:   char			*widp, buf[64];
  147: 
  148:   strlcpy(buf, s, sizeof(buf));
  149:   if ((widp = strchr(buf, '/')) != NULL)
  150:     *widp++ = '\0';
  151:   else
  152:     widp = buf + strlen(buf);
  153: 
  154: /* Get IP address part; if that fails, try looking up hostname */
  155: 
  156:   if (!ParseAddr(buf, &range->addr, allow)) 
  157:     return(FALSE);
  158: 
  159: /* Get mask width */
  160: 
  161:   if (*widp)
  162:   {
  163:     if ((n_bits = atoi(widp)) < 0 || (range->addr.family==AF_INET && n_bits > 32) || (range->addr.family==AF_INET6 && n_bits > 128))
  164:     {
  165:       return(FALSE);
  166:     }
  167:   }
  168:   else if (range->addr.family==AF_INET) {
  169:     n_bits = 32;
  170:   } else {
  171:     n_bits = 128;
  172:   }
  173:   range->width = n_bits;
  174: 
  175:   return(TRUE);
  176: }
  177: 
  178: /*
  179:  * ParseAddrPort()
  180:  *
  181:  * Parse an IP address & port of the form X.Y.Z.W P.
  182:  * Returns pointer to sockaddr_in. Not thread safe!
  183:  */
  184: 
  185: struct sockaddr_storage *
  186: ParseAddrPort(int ac, const char *const av[], u_char allow)
  187: {
  188:   static struct sockaddr_storage ss;
  189:   struct u_addr addr;
  190:   int		port = 0;
  191: 
  192:   if (ac < 1 || ac > 2)
  193:     return (NULL);
  194: 
  195:   if (!ParseAddr(av[0], &addr, allow))
  196:     return(NULL);
  197: 
  198:   if (ac > 1) {
  199:     if ((port = atoi(av[1])) < 1 || port > 65535) {
  200:       Log(LG_ERR, ("Bad port \"%s\"", av[1]));
  201:       return (NULL);
  202:     }
  203:   }
  204: 
  205:   memset(&ss, 0, sizeof(ss));
  206:   ss.ss_family = addr.family;
  207:   switch (addr.family) {
  208:     case AF_INET:
  209: 	ss.ss_len = sizeof(struct sockaddr_in);
  210: 	((struct sockaddr_in*)&ss)->sin_addr = addr.u.ip4;
  211: 	((struct sockaddr_in*)&ss)->sin_port = htons(port);
  212: 	break;
  213:     case AF_INET6:
  214: 	ss.ss_len = sizeof(struct sockaddr_in6);
  215: 	((struct sockaddr_in6*)&ss)->sin6_addr = addr.u.ip6;
  216: 	((struct sockaddr_in6*)&ss)->sin6_port = htons(port);
  217: 	break;
  218:     default:
  219: 	ss.ss_len = sizeof(struct sockaddr_storage);
  220:   }
  221: 
  222:   return (&ss);
  223: }
  224: 
  225: sa_family_t	u_addrfamily(struct u_addr *addr)
  226: {
  227:     return addr->family;
  228: }
  229: 
  230: sa_family_t	u_rangefamily(struct u_range *range)
  231: {
  232:     return range->addr.family;
  233: }
  234: 
  235: char   *u_addrtoa(struct u_addr *addr, char *dst, size_t size)
  236: {
  237:     dst[0]=0;
  238:     
  239:     if (addr->family==AF_INET) {
  240: 	inet_ntop(addr->family, &addr->u.ip4, dst, size);
  241:     } 
  242:     else if (addr->family==AF_INET6) 
  243:     {
  244:         inet_ntop(addr->family, &addr->u.ip6, dst, size);
  245:     }
  246:     else if (addr->family==AF_UNSPEC) 
  247:     {
  248:         snprintf(dst,size,"UNSPEC");
  249:     }
  250: 
  251:     return dst;
  252: }
  253: 
  254: char   *u_rangetoa(struct u_range *range, char *dst, size_t size)
  255: {
  256:     if (!u_addrtoa(&range->addr, dst, size))
  257: 	return NULL;
  258: 
  259:     if (range->addr.family!=AF_UNSPEC)
  260: 	snprintf(dst+strlen(dst), size-strlen(dst), "/%d", range->width);
  261: 
  262:     return dst;
  263: }
  264: 
  265: void u_addrcopy(const struct u_addr *src, struct u_addr *dst)
  266: {
  267:     memcpy(dst,src,sizeof(struct u_addr));
  268: }
  269: 
  270: void  u_rangecopy(const struct u_range *src, struct u_range *dst)
  271: {
  272:     memcpy(dst,src,sizeof(struct u_range));
  273: }
  274: 
  275: void u_addrclear(struct u_addr *addr)
  276: {
  277:     memset(addr,0,sizeof(struct u_addr));
  278: }
  279: 
  280: void u_rangeclear(struct u_range *range)
  281: {
  282:     memset(range,0,sizeof(struct u_range));
  283: }
  284: 
  285: void in_addrtou_addr(const struct in_addr *src, struct u_addr *dst)
  286: {
  287:     u_addrclear(dst);
  288:     dst->family=AF_INET;
  289:     dst->u.ip4=*src;
  290: }
  291: 
  292: void in6_addrtou_addr(const struct in6_addr *src, struct u_addr *dst)
  293: {
  294:     u_addrclear(dst);
  295:     dst->family=AF_INET6;
  296:     dst->u.ip6=*src;
  297: }
  298: 
  299: void u_addrtoin_addr(const struct u_addr *src, struct in_addr *dst)
  300: {
  301:     *dst=src->u.ip4;
  302: }
  303: 
  304: void u_addrtoin6_addr(const struct u_addr *src, struct in6_addr *dst)
  305: {
  306:     *dst=src->u.ip6;
  307: }
  308: 
  309: void in_addrtou_range(const struct in_addr *src, u_char width, struct u_range *dst)
  310: {
  311:     u_rangeclear(dst);
  312:     in_addrtou_addr(src, &dst->addr);
  313:     dst->width = width;
  314: }
  315: 
  316: void in6_addrtou_range(const struct in6_addr *src, u_char width, struct u_range *dst)
  317: {
  318:     u_rangeclear(dst);
  319:     in6_addrtou_addr(src, &dst->addr);
  320:     dst->width = width;
  321: }
  322: 
  323: int u_addrempty(struct u_addr *addr)
  324: {
  325:     int i;
  326:     switch (addr->family) {
  327: 	case AF_INET:
  328: 		return (addr->u.ip4.s_addr==0); 
  329: 	    break;
  330: 	case AF_INET6:
  331: 		for (i=0;i<16;i++) {
  332: 		    if (addr->u.ip6.s6_addr[i]!=0)
  333: 			return 0;
  334: 		}
  335: 		return 1;
  336: 	    break;
  337:     }
  338:     return 1;
  339: }
  340: 
  341: int u_rangeempty(struct u_range *range)
  342: {
  343:     return u_addrempty(&range->addr);
  344: }
  345: 
  346: int u_rangehost(struct u_range *range)
  347: {
  348:     switch (range->addr.family) {
  349: 	case AF_INET:
  350: 		return (range->width==32); 
  351: 	    break;
  352: 	case AF_INET6:
  353: 		return (range->width==128); 
  354: 	    break;
  355:     }
  356:     return 0;
  357: }
  358: 
  359: static struct in6_addr
  360: bits2mask6(int bits)
  361: {
  362:   struct in6_addr result;
  363:   u_int32_t bit = 0x80;
  364:   u_char *c = result.s6_addr;
  365: 
  366:   memset(&result, '\0', sizeof(result));
  367: 
  368:   while (bits) {
  369:     if (bit == 0) {
  370:       bit = 0x80;
  371:       c++;
  372:     }
  373:     *c |= bit;
  374:     bit >>= 1;
  375:     bits--;
  376:   }
  377: 
  378:   return result;
  379: }
  380: 
  381: void u_rangetosockaddrs(struct u_range *range, struct sockaddr_storage *dst, struct sockaddr_storage *msk)
  382: {
  383:     memset(dst,0,sizeof(struct sockaddr_storage));
  384:     memset(msk,0,sizeof(struct sockaddr_storage));
  385:     dst->ss_family = msk->ss_family = range->addr.family;
  386:     switch (range->addr.family) {
  387: 	case AF_INET:
  388: 		((struct sockaddr_in*)dst)->sin_len=sizeof(struct sockaddr_in);
  389: 		((struct sockaddr_in*)dst)->sin_addr=range->addr.u.ip4;
  390: 		((struct sockaddr_in*)msk)->sin_len=sizeof(struct sockaddr_in);
  391: 		((struct sockaddr_in*)msk)->sin_addr.s_addr=htonl(0xFFFFFFFFLL<<(32 - range->width));
  392: 	    break;
  393: 	case AF_INET6:
  394: 		((struct sockaddr_in6*)dst)->sin6_len=sizeof(struct sockaddr_in6);
  395: 		((struct sockaddr_in6*)dst)->sin6_addr=range->addr.u.ip6;
  396: 		((struct sockaddr_in6*)msk)->sin6_len=sizeof(struct sockaddr_in6);
  397: 		((struct sockaddr_in6*)msk)->sin6_addr=bits2mask6(range->width);
  398: 	    break;
  399: 	default:
  400: 		dst->ss_len=sizeof(struct sockaddr_storage);
  401: 	    break;
  402:     }
  403: }
  404: 
  405: void u_addrtosockaddr(struct u_addr *addr, in_port_t port, struct sockaddr_storage *dst)
  406: {
  407:     memset(dst,0,sizeof(struct sockaddr_storage));
  408:     dst->ss_family=addr->family;
  409:     switch (addr->family) {
  410: 	case AF_INET:
  411: 		((struct sockaddr_in*)dst)->sin_len=sizeof(struct sockaddr_in);
  412: 		((struct sockaddr_in*)dst)->sin_addr=addr->u.ip4;
  413: 		((struct sockaddr_in*)dst)->sin_port=htons(port);
  414: 	    break;
  415: 	case AF_INET6:
  416: 		((struct sockaddr_in6*)dst)->sin6_len=sizeof(struct sockaddr_in6);
  417: 		((struct sockaddr_in6*)dst)->sin6_addr=addr->u.ip6;
  418: 		((struct sockaddr_in6*)dst)->sin6_port=htons(port);
  419: 	    break;
  420: 	default:
  421: 		dst->ss_len=sizeof(struct sockaddr_storage);
  422: 	    break;
  423:     }
  424: }
  425: 
  426: void sockaddrtou_addr(struct sockaddr_storage *src, struct u_addr *addr, in_port_t *port)
  427: {
  428:     addr->family=src->ss_family;
  429:     switch (addr->family) {
  430: 	case AF_INET:
  431: 		addr->u.ip4=((struct sockaddr_in*)src)->sin_addr;
  432: 		*port=ntohs(((struct sockaddr_in*)src)->sin_port);
  433: 	    break;
  434: 	case AF_INET6:
  435: 		addr->u.ip6=((struct sockaddr_in6*)src)->sin6_addr;
  436: 		*port=ntohs(((struct sockaddr_in6*)src)->sin6_port);
  437: 	    break;
  438: 	default:
  439: 	    memset(addr,0,sizeof(struct u_addr));
  440: 	    *port=0;
  441: 	    break;
  442:     }
  443: }
  444: 
  445: int u_addrcompare(const struct u_addr *addr1, const struct u_addr *addr2)
  446: {
  447:   int	i;
  448: 
  449:   if (addr1->family<addr2->family)
  450:     return(-1);
  451:   else if (addr1->family>addr2->family)
  452:     return(1);
  453:   
  454:   switch (addr1->family) {
  455:     case AF_INET:
  456: 	    if (addr1->u.ip4.s_addr < addr2->u.ip4.s_addr)
  457: 		return (-1);
  458: 	    else if (addr1->u.ip4.s_addr == addr2->u.ip4.s_addr)
  459: 		return (0);
  460: 	    else 
  461: 		return (1);
  462: 	break;
  463:     case AF_INET6:
  464: 	    for (i=0; i<16; i++) {
  465: 		if (addr1->u.ip6.s6_addr[i] < addr2->u.ip6.s6_addr[i])
  466: 		    return (-1);
  467: 		else if (addr1->u.ip6.s6_addr[i] > addr2->u.ip6.s6_addr[i])
  468: 		    return (1);
  469: 	    }
  470: 	    return 0;
  471: 	break;
  472:   }
  473:   return 0;
  474: }
  475: 
  476: int u_rangecompare(const struct u_range *range1, const struct u_range *range2)
  477: {
  478:   if (range1->width<range2->width)
  479:     return(-1);
  480:   else if (range1->width>range2->width)
  481:     return(1);
  482: 
  483:   return u_addrcompare(&range1->addr,&range2->addr);
  484: }
  485: 
  486: uint32_t
  487: u_addrtoid(const struct u_addr *addr)
  488: {
  489:     uint32_t id;
  490: 
  491:     if (addr->family==AF_INET) {
  492: 	id = ntohl(addr->u.ip4.s_addr);
  493:     } else if (addr->family==AF_INET6) {
  494: 	const uint32_t *a32 = (const uint32_t *)(const void *)(&addr->u.ip6.s6_addr[0]);
  495:         id = a32[0] + a32[1] + a32[2] + a32[3];
  496:     } else {
  497: 	id = 0;
  498:     }
  499: 
  500:     return (id);
  501: }
  502: 
  503: u_char
  504: in_addrtowidth(struct in_addr *mask)
  505: {
  506: 	u_char width = 0;
  507: 	uint32_t m = ntohl(mask->s_addr);
  508: 
  509: 	while ((m & 0x80000000) != 0) {
  510: 		m <<= 1;
  511: 		width++;
  512: 	}
  513: 	return (width);
  514: }
  515: 
  516: struct in_addr *
  517: widthtoin_addr(u_char width, struct in_addr *mask)
  518: {
  519: 	mask->s_addr = htonl(0xFFFFFFFF << (32 - width));
  520: 	return (mask);
  521: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>