Annotation of embedaddon/mpd/src/ip.c, revision 1.1.1.1

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

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