/* * Assign a key to cliptr, or output cliptr's value as a key. * On assignment the value is specified in valstr in hexascii; * on output its value is printed in hexascii, provided the key * was entered at the interpreter (not obtained from OBP and * thus hidden). */ static int clkey(cli_ent_t *cliptr, char *valstr, boolean_t out) { uint_t len, vmax; if (out) { char buffer[2 * WANBOOT_MAXKEYLEN + 1]; if (!CLF_ISHIDDEN(cliptr)) { len = cliptr->varlen * 2 + 1; (void) octet_to_hexascii(cliptr->varptr, cliptr->varlen, buffer, &len); printf("%s", buffer); } else { printf("*HIDDEN*"); } return (CLI_CONT); } else { len = strlen(valstr); vmax = cliptr->varmax; if (len != vmax * 2 || hexascii_to_octet(valstr, len, cliptr->varptr, &vmax) != 0) { return (CLI_FAIL); } cliptr->varlen = vmax; CLF_CLRHIDDEN(cliptr); return (CLI_SET); } }
/* * Assign a client-id to cliptr, or output cliptr's value as a client-id. * On assignment the value is specified in valstr, either in hexascii or * as a quoted string; on output its value is printed in hexascii. */ static int clcid(cli_ent_t *cliptr, char *valstr, boolean_t out) { uint_t len, vmax; boolean_t hexascii = B_TRUE; char buffer[2 * WB_MAX_CID_LEN + 1]; if (out) { len = cliptr->varlen * 2 + 1; (void) octet_to_hexascii(cliptr->varptr, cliptr->varlen, buffer, &len); printf("%s", buffer); return (CLI_CONT); } else { len = strlen(valstr); vmax = cliptr->varmax - 1; /* space for the prefix */ /* * Check whether the value is a quoted string; if so, strip * the quotes and note that it's not in hexascii. */ if ((valstr[0] == '"' || valstr[0] == '\'') && valstr[len-1] == valstr[0]) { hexascii = B_FALSE; ++valstr; len -= 2; valstr[len] = '\0'; } else { /* * If the value contains any non-hex digits assume * that it's not in hexascii. */ char *p; for (p = valstr; *p != '\0'; ++p) { if (!isxdigit(*p)) { hexascii = B_FALSE; break; } } } if (hexascii) { if (len > vmax * 2 || hexascii_to_octet(valstr, len, (char *)(cliptr->varptr), &vmax) != 0) { return (CLI_FAIL); } cliptr->varlen = vmax; } else { if (len > vmax) { return (CLI_FAIL); } bcopy(valstr, cliptr->varptr, len); cliptr->varlen = len; } return (CLI_SET); } }
/* * Compares the fields in fields[] agains the fields in target `targetp', * using `query' to decide what fields to compare. Returns B_TRUE if `dnp' * matches `targetp', B_FALSE if not. On success, `dnp' is completely * filled in. */ static boolean_t record_match(char *fields[], dn_rec_t *dnp, const dn_rec_t *targetp, uint_t query) { unsigned int qflags[] = { DN_QFDYNAMIC, DN_QFAUTOMATIC, DN_QFMANUAL, DN_QFUNUSABLE, DN_QFBOOTP_ONLY }; unsigned int flags[] = { DN_FDYNAMIC, DN_FAUTOMATIC, DN_FMANUAL, DN_FUNUSABLE, DN_FBOOTP_ONLY }; unsigned int i; uint_t dn_cid_len; dnp->dn_cip.s_addr = ntohl(inet_addr(fields[DNF_CIP])); if (DSVC_QISEQ(query, DN_QCIP) && dnp->dn_cip.s_addr != targetp->dn_cip.s_addr) return (B_FALSE); if (DSVC_QISNEQ(query, DN_QCIP) && dnp->dn_cip.s_addr == targetp->dn_cip.s_addr) return (B_FALSE); dnp->dn_lease = atoi(fields[DNF_LEASE]); if (DSVC_QISEQ(query, DN_QLEASE) && targetp->dn_lease != dnp->dn_lease) return (B_FALSE); if (DSVC_QISNEQ(query, DN_QLEASE) && targetp->dn_lease == dnp->dn_lease) return (B_FALSE); /* * We use dn_cid_len since dnp->dn_cid_len is of type uchar_t but * hexascii_to_octet() expects an uint_t * */ dn_cid_len = DN_MAX_CID_LEN; if (hexascii_to_octet(fields[DNF_CID], strlen(fields[DNF_CID]), dnp->dn_cid, &dn_cid_len) != 0) return (B_FALSE); dnp->dn_cid_len = dn_cid_len; if (DSVC_QISEQ(query, DN_QCID) && (dnp->dn_cid_len != targetp->dn_cid_len || (memcmp(dnp->dn_cid, targetp->dn_cid, dnp->dn_cid_len) != 0))) return (B_FALSE); if (DSVC_QISNEQ(query, DN_QCID) && (dnp->dn_cid_len == targetp->dn_cid_len && (memcmp(dnp->dn_cid, targetp->dn_cid, dnp->dn_cid_len) == 0))) return (B_FALSE); dnp->dn_sip.s_addr = ntohl(inet_addr(fields[DNF_SIP])); if (DSVC_QISEQ(query, DN_QSIP) && dnp->dn_sip.s_addr != targetp->dn_sip.s_addr) return (B_FALSE); if (DSVC_QISNEQ(query, DN_QSIP) && dnp->dn_sip.s_addr == targetp->dn_sip.s_addr) return (B_FALSE); unescape('|', fields[DNF_MACRO], dnp->dn_macro, sizeof (dnp->dn_macro)); if (DSVC_QISEQ(query, DN_QMACRO) && strcmp(targetp->dn_macro, dnp->dn_macro) != 0) return (B_FALSE); if (DSVC_QISNEQ(query, DN_QMACRO) && strcmp(targetp->dn_macro, dnp->dn_macro) == 0) return (B_FALSE); dnp->dn_flags = atoi(fields[DNF_FLAGS]); for (i = 0; i < sizeof (qflags) / sizeof (unsigned int); i++) { if (DSVC_QISEQ(query, qflags[i]) && (dnp->dn_flags & flags[i]) != (targetp->dn_flags & flags[i])) return (B_FALSE); if (DSVC_QISNEQ(query, qflags[i]) && (dnp->dn_flags & flags[i]) == (targetp->dn_flags & flags[i])) return (B_FALSE); } dnp->dn_sig = atoll(fields[DNF_SIG]); unescape('|', fields[DNF_COMMENT], dnp->dn_comment, sizeof (dnp->dn_comment)); return (B_TRUE); }
/* * Determine whether the kernel has a cached DHCP ACK, and if so * initialize dhcp_pl and dhcp_ifn. */ static boolean_t dhcp_info_init(void) { boolean_t ret = B_FALSE; char dummy; char *dhcack = NULL; long dhcacksz; char *ackp; /* * See whether the kernel has a cached DHCP ACK, and if so get it. * If there is no DHCP ACK, then the returned length is equal to * the size of an empty string. */ if ((dhcacksz = sysinfo(SI_DHCP_CACHE, &dummy, sizeof (dummy))) == sizeof ("")) { return (B_TRUE); } if ((dhcack = malloc(dhcacksz)) == NULL) { goto cleanup; } if ((dhcp_pl = calloc(1, sizeof (PKT_LIST))) == NULL) { goto cleanup; } (void) sysinfo(SI_DHCP_CACHE, (caddr_t)dhcack, dhcacksz); /* * The first IFNAMSIZ bytes are reserved for the interface name; * the ACK follows. */ ackp = &dhcack[IFNAMSIZ]; /* * Convert and scan the options. */ dhcp_pl->len = strlen(ackp) / 2; if ((dhcp_pl->pkt = malloc(dhcp_pl->len)) == NULL) { goto cleanup; } if (hexascii_to_octet(ackp, dhcp_pl->len * 2, dhcp_pl->pkt, &dhcp_pl->len) != 0) { goto cleanup; } if (dhcp_options_scan(dhcp_pl, B_TRUE) != 0) { goto cleanup; } /* * Set the interface-name. */ (void) strlcpy(dhcp_ifn, dhcack, sizeof (dhcp_ifn)); ret = B_TRUE; cleanup: if (!ret) { dhcp_info_end(); } if (dhcack != NULL) { free(dhcack); } return (ret); }