Print this page
5007142 Add ntohll and htonll to sys/byteorder.h
6717509 Need to use bswap/bswapq for byte swap of 64-bit integer on x32/x64
PSARC 2008/474


   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #pragma ident   "%Z%%M% %I%     %E% SMI"
  27 
  28 #include <sys/types.h>
  29 #include <string.h>
  30 #include <stdlib.h>
  31 #include <stdio.h>
  32 #include <errno.h>
  33 #include <stdarg.h>
  34 #include <limits.h>
  35 #include <ctype.h>
  36 #include <libgen.h>
  37 #include <sys/isa_defs.h>
  38 #include <sys/socket.h>
  39 #include <net/if_arp.h>
  40 #include <netinet/in.h>
  41 #include <arpa/inet.h>
  42 #include <sys/sysmacros.h>
  43 #include <libinetutil.h>
  44 #include <libdlpi.h>
  45 #include <netinet/dhcp6.h>
  46 
  47 #include "dhcp_symbol.h"
  48 #include "dhcp_inittab.h"
  49 
  50 static uint64_t         dhcp_htonll(uint64_t);
  51 static uint64_t         dhcp_ntohll(uint64_t);
  52 static void             inittab_msg(const char *, ...);
  53 static uchar_t          category_to_code(const char *);
  54 static boolean_t        encode_number(uint8_t, uint8_t, boolean_t, uint8_t,
  55                             const char *, uint8_t *, int *);
  56 static boolean_t        decode_number(uint8_t, uint8_t, boolean_t, uint8_t,
  57                             const uint8_t *, char *, int *);
  58 static dhcp_symbol_t    *inittab_lookup(uchar_t, char, const char *, int32_t,
  59                             size_t *);
  60 static dsym_category_t  itabcode_to_dsymcode(uchar_t);
  61 static boolean_t        parse_entry(char *, char **);
  62 
  63 /*
  64  * forward declaration of our internal inittab_table[].  too bulky to put
  65  * up front -- check the end of this file for its definition.
  66  *
  67  * Note: we have only an IPv4 version here.  The inittab_verify() function is
  68  * used by the DHCP server and manager.  We'll need a new function if the
  69  * server is extended to DHCPv6.
  70  */
  71 static dhcp_symbol_t    inittab_table[];


1461                         to += sprintf(to, is_signed ? "%hd" : "%hu",
1462                             ntohs(uint16));
1463                         break;
1464 
1465                 case 3:
1466                         uint32 = 0;
1467                         (void) memcpy((uchar_t *)&uint32 + 1, from, 3);
1468                         to += sprintf(to, is_signed ? "%ld" : "%lu",
1469                             ntohl(uint32));
1470                         break;
1471 
1472                 case 4:
1473                         (void) memcpy(&uint32, from, 4);
1474                         to += sprintf(to, is_signed ? "%ld" : "%lu",
1475                             ntohl(uint32));
1476                         break;
1477 
1478                 case 8:
1479                         (void) memcpy(&uint64, from, 8);
1480                         to += sprintf(to, is_signed ? "%lld" : "%llu",
1481                             dhcp_ntohll(uint64));
1482                         break;
1483 
1484                 default:
1485                         *ierrnop = ITAB_BAD_NUMBER;
1486                         inittab_msg("decode_number: unknown integer size `%d'",
1487                             size);
1488                         return (B_FALSE);
1489                 }
1490                 if (n_entries > 0)
1491                         *to++ = ' ';
1492         }
1493 
1494         *to = '\0';
1495         return (B_TRUE);
1496 }
1497 
1498 /*
1499  * encode_number(): encodes a sequence of numbers from ascii into binary;
1500  *                  number will end up on the wire so it needs to be in nbo
1501  *


1557                         (void) memcpy(to, &uint16, 2);
1558                         break;
1559 
1560                 case 3:
1561                         uint32 = htonl(strtoul(from, &endptr, 0));
1562                         if (errno != 0 || from == endptr) {
1563                                 goto error;
1564                         }
1565                         (void) memcpy(to, (uchar_t *)&uint32 + 1, 3);
1566                         break;
1567 
1568                 case 4:
1569                         uint32 = htonl(strtoul(from, &endptr, 0));
1570                         if (errno != 0 || from == endptr) {
1571                                 goto error;
1572                         }
1573                         (void) memcpy(to, &uint32, 4);
1574                         break;
1575 
1576                 case 8:
1577                         uint64 = dhcp_htonll(strtoull(from, &endptr, 0));
1578                         if (errno != 0 || from == endptr) {
1579                                 goto error;
1580                         }
1581                         (void) memcpy(to, &uint64, 8);
1582                         break;
1583 
1584                 default:
1585                         inittab_msg("encode_number: unsupported integer "
1586                             "size `%d'", size);
1587                         return (B_FALSE);
1588                 }
1589 
1590                 from = strchr(from, ' ');
1591                 if (from == NULL)
1592                         break;
1593         }
1594 
1595         return (B_TRUE);
1596 
1597 error:


1677 
1678 /*
1679  * category_to_code(): maps a category name to its numeric representation
1680  *
1681  *   input: const char *: the category name
1682  *  output: uchar_t: its internal code (numeric representation)
1683  */
1684 
1685 static uchar_t
1686 category_to_code(const char *category)
1687 {
1688         unsigned int    i;
1689 
1690         for (i = 0; i < ITAB_CAT_COUNT; i++)
1691                 if (strcasecmp(category_map[i].cme_name, category) == 0)
1692                         return (category_map[i].cme_itabcode);
1693 
1694         return (0);
1695 }
1696 
1697 /*
1698  * dhcp_htonll(): converts a 64-bit number from host to network byte order
1699  *
1700  *   input: uint64_t: the number to convert
1701  *  output: uint64_t: its value in network byte order
1702  */
1703 
1704 static uint64_t
1705 dhcp_htonll(uint64_t uint64_hbo)
1706 {
1707         return (dhcp_ntohll(uint64_hbo));
1708 }
1709 
1710 /*
1711  * dhcp_ntohll(): converts a 64-bit number from network to host byte order
1712  *
1713  *   input: uint64_t: the number to convert
1714  *  output: uint64_t: its value in host byte order
1715  */
1716 
1717 static uint64_t
1718 dhcp_ntohll(uint64_t uint64_nbo)
1719 {
1720 #ifdef  _LITTLE_ENDIAN
1721         return ((uint64_t)ntohl(uint64_nbo & 0xffffffff) << 32 |
1722             ntohl(uint64_nbo >> 32));
1723 #else
1724         return (uint64_nbo);
1725 #endif
1726 }
1727 
1728 /*
1729  * our internal table of DHCP option values, used by inittab_verify()
1730  */
1731 static dhcp_symbol_t inittab_table[] =
1732 {
1733 { DSYM_INTERNAL,        1024,   "Hostname",     DSYM_BOOL,      0,      0 },
1734 { DSYM_INTERNAL,        1025,   "LeaseNeg",     DSYM_BOOL,      0,      0 },
1735 { DSYM_INTERNAL,        1026,   "EchoVC",       DSYM_BOOL,      0,      0 },
1736 { DSYM_INTERNAL,        1027,   "BootPath",     DSYM_ASCII,     1,      128 },
1737 { DSYM_FIELD,           0,      "Opcode",       DSYM_UNUMBER8,  1,      1 },
1738 { DSYM_FIELD,           1,      "Htype",        DSYM_UNUMBER8,  1,      1 },
1739 { DSYM_FIELD,           2,      "HLen",         DSYM_UNUMBER8,  1,      1 },
1740 { DSYM_FIELD,           3,      "Hops",         DSYM_UNUMBER8,  1,      1 },
1741 { DSYM_FIELD,           4,      "Xid",          DSYM_UNUMBER32, 1,      1 },
1742 { DSYM_FIELD,           8,      "Secs",         DSYM_UNUMBER16, 1,      1 },
1743 { DSYM_FIELD,           10,     "Flags",        DSYM_OCTET,     1,      2 },
1744 { DSYM_FIELD,           12,     "Ciaddr",       DSYM_IP,        1,      1 },
1745 { DSYM_FIELD,           16,     "Yiaddr",       DSYM_IP,        1,      1 },
1746 { DSYM_FIELD,           20,     "BootSrvA",     DSYM_IP,        1,      1 },
1747 { DSYM_FIELD,           24,     "Giaddr",       DSYM_IP,        1,      1 },




   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 


  26 #include <sys/types.h>
  27 #include <string.h>
  28 #include <stdlib.h>
  29 #include <stdio.h>
  30 #include <errno.h>
  31 #include <stdarg.h>
  32 #include <limits.h>
  33 #include <ctype.h>
  34 #include <libgen.h>
  35 #include <sys/isa_defs.h>
  36 #include <sys/socket.h>
  37 #include <net/if_arp.h>
  38 #include <netinet/in.h>
  39 #include <arpa/inet.h>
  40 #include <sys/sysmacros.h>
  41 #include <libinetutil.h>
  42 #include <libdlpi.h>
  43 #include <netinet/dhcp6.h>
  44 
  45 #include "dhcp_symbol.h"
  46 #include "dhcp_inittab.h"
  47 


  48 static void             inittab_msg(const char *, ...);
  49 static uchar_t          category_to_code(const char *);
  50 static boolean_t        encode_number(uint8_t, uint8_t, boolean_t, uint8_t,
  51                             const char *, uint8_t *, int *);
  52 static boolean_t        decode_number(uint8_t, uint8_t, boolean_t, uint8_t,
  53                             const uint8_t *, char *, int *);
  54 static dhcp_symbol_t    *inittab_lookup(uchar_t, char, const char *, int32_t,
  55                             size_t *);
  56 static dsym_category_t  itabcode_to_dsymcode(uchar_t);
  57 static boolean_t        parse_entry(char *, char **);
  58 
  59 /*
  60  * forward declaration of our internal inittab_table[].  too bulky to put
  61  * up front -- check the end of this file for its definition.
  62  *
  63  * Note: we have only an IPv4 version here.  The inittab_verify() function is
  64  * used by the DHCP server and manager.  We'll need a new function if the
  65  * server is extended to DHCPv6.
  66  */
  67 static dhcp_symbol_t    inittab_table[];


1457                         to += sprintf(to, is_signed ? "%hd" : "%hu",
1458                             ntohs(uint16));
1459                         break;
1460 
1461                 case 3:
1462                         uint32 = 0;
1463                         (void) memcpy((uchar_t *)&uint32 + 1, from, 3);
1464                         to += sprintf(to, is_signed ? "%ld" : "%lu",
1465                             ntohl(uint32));
1466                         break;
1467 
1468                 case 4:
1469                         (void) memcpy(&uint32, from, 4);
1470                         to += sprintf(to, is_signed ? "%ld" : "%lu",
1471                             ntohl(uint32));
1472                         break;
1473 
1474                 case 8:
1475                         (void) memcpy(&uint64, from, 8);
1476                         to += sprintf(to, is_signed ? "%lld" : "%llu",
1477                             ntohll(uint64));
1478                         break;
1479 
1480                 default:
1481                         *ierrnop = ITAB_BAD_NUMBER;
1482                         inittab_msg("decode_number: unknown integer size `%d'",
1483                             size);
1484                         return (B_FALSE);
1485                 }
1486                 if (n_entries > 0)
1487                         *to++ = ' ';
1488         }
1489 
1490         *to = '\0';
1491         return (B_TRUE);
1492 }
1493 
1494 /*
1495  * encode_number(): encodes a sequence of numbers from ascii into binary;
1496  *                  number will end up on the wire so it needs to be in nbo
1497  *


1553                         (void) memcpy(to, &uint16, 2);
1554                         break;
1555 
1556                 case 3:
1557                         uint32 = htonl(strtoul(from, &endptr, 0));
1558                         if (errno != 0 || from == endptr) {
1559                                 goto error;
1560                         }
1561                         (void) memcpy(to, (uchar_t *)&uint32 + 1, 3);
1562                         break;
1563 
1564                 case 4:
1565                         uint32 = htonl(strtoul(from, &endptr, 0));
1566                         if (errno != 0 || from == endptr) {
1567                                 goto error;
1568                         }
1569                         (void) memcpy(to, &uint32, 4);
1570                         break;
1571 
1572                 case 8:
1573                         uint64 = htonll(strtoull(from, &endptr, 0));
1574                         if (errno != 0 || from == endptr) {
1575                                 goto error;
1576                         }
1577                         (void) memcpy(to, &uint64, 8);
1578                         break;
1579 
1580                 default:
1581                         inittab_msg("encode_number: unsupported integer "
1582                             "size `%d'", size);
1583                         return (B_FALSE);
1584                 }
1585 
1586                 from = strchr(from, ' ');
1587                 if (from == NULL)
1588                         break;
1589         }
1590 
1591         return (B_TRUE);
1592 
1593 error:


1673 
1674 /*
1675  * category_to_code(): maps a category name to its numeric representation
1676  *
1677  *   input: const char *: the category name
1678  *  output: uchar_t: its internal code (numeric representation)
1679  */
1680 
1681 static uchar_t
1682 category_to_code(const char *category)
1683 {
1684         unsigned int    i;
1685 
1686         for (i = 0; i < ITAB_CAT_COUNT; i++)
1687                 if (strcasecmp(category_map[i].cme_name, category) == 0)
1688                         return (category_map[i].cme_itabcode);
1689 
1690         return (0);
1691 }
1692 































1693 /*
1694  * our internal table of DHCP option values, used by inittab_verify()
1695  */
1696 static dhcp_symbol_t inittab_table[] =
1697 {
1698 { DSYM_INTERNAL,        1024,   "Hostname",     DSYM_BOOL,      0,      0 },
1699 { DSYM_INTERNAL,        1025,   "LeaseNeg",     DSYM_BOOL,      0,      0 },
1700 { DSYM_INTERNAL,        1026,   "EchoVC",       DSYM_BOOL,      0,      0 },
1701 { DSYM_INTERNAL,        1027,   "BootPath",     DSYM_ASCII,     1,      128 },
1702 { DSYM_FIELD,           0,      "Opcode",       DSYM_UNUMBER8,  1,      1 },
1703 { DSYM_FIELD,           1,      "Htype",        DSYM_UNUMBER8,  1,      1 },
1704 { DSYM_FIELD,           2,      "HLen",         DSYM_UNUMBER8,  1,      1 },
1705 { DSYM_FIELD,           3,      "Hops",         DSYM_UNUMBER8,  1,      1 },
1706 { DSYM_FIELD,           4,      "Xid",          DSYM_UNUMBER32, 1,      1 },
1707 { DSYM_FIELD,           8,      "Secs",         DSYM_UNUMBER16, 1,      1 },
1708 { DSYM_FIELD,           10,     "Flags",        DSYM_OCTET,     1,      2 },
1709 { DSYM_FIELD,           12,     "Ciaddr",       DSYM_IP,        1,      1 },
1710 { DSYM_FIELD,           16,     "Yiaddr",       DSYM_IP,        1,      1 },
1711 { DSYM_FIELD,           20,     "BootSrvA",     DSYM_IP,        1,      1 },
1712 { DSYM_FIELD,           24,     "Giaddr",       DSYM_IP,        1,      1 },