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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/ksynch.h> 28 #include <sys/errno.h> 29 #include <sys/debug.h> 30 #include <sys/cmn_err.h> 31 #include <sys/kmem.h> 32 #include <sys/errno.h> 33 34 #ifdef _SunOS_2_6 35 /* 36 * on 2.6 both dki_lock.h and rpc/types.h define bool_t so we 37 * define enum_t here as it is all we need from rpc/types.h 38 * anyway and make it look like we included it. Yuck. 39 */ 40 #define _RPC_TYPES_H 41 typedef int enum_t; 42 #else 43 #ifndef DS_DDICT 44 #include <rpc/types.h> 45 #endif 46 #endif /* _SunOS_2_6 */ 47 48 #include <sys/nsc_thread.h> 49 #include <sys/nsctl/nsctl.h> 50 #include "rdc_io.h" 51 #include "rdc_ioctl.h" 52 #include "rdc_prot.h" 53 54 /* 55 * Initialize a netbuf suitable for 56 * describing an address 57 */ 58 59 void 60 init_rdc_netbuf(struct netbuf *nbuf) 61 { 62 nbuf->buf = kmem_zalloc(RDC_MAXADDR, KM_SLEEP); 63 nbuf->maxlen = RDC_MAXADDR; 64 nbuf->len = 0; 65 } 66 67 /* 68 * Free a netbuf 69 */ 70 71 void 72 free_rdc_netbuf(struct netbuf *nbuf) 73 { 74 if (!(nbuf) || !(nbuf->buf)) { 75 #ifdef DEBUG 76 cmn_err(CE_PANIC, "Null netbuf in free_rdc_netbuf"); 77 #endif 78 return; 79 } 80 kmem_free(nbuf->buf, nbuf->maxlen); 81 nbuf->buf = NULL; 82 nbuf->maxlen = 0; 83 nbuf->len = 0; 84 } 85 86 87 /* 88 * Duplicate a netbuf, must be followed by a free_rdc_netbuf(). 89 */ 90 void 91 dup_rdc_netbuf(const struct netbuf *from, struct netbuf *to) 92 { 93 init_rdc_netbuf(to); 94 to->len = from->len; 95 96 if (from->len > to->maxlen) { 97 cmn_err(CE_WARN, "!dup_rdc_netbuf: from->len %d, to->maxlen %d", 98 from->len, to->maxlen); 99 } 100 101 bcopy(from->buf, to->buf, (size_t)from->len); 102 } 103 104 105 #ifdef DEBUG 106 void 107 rdc_print_svinfo(rdc_srv_t *svp, char *str) 108 { 109 int i; 110 111 if (svp == NULL) 112 return; 113 114 cmn_err(CE_NOTE, "!rdc %s servinfo: %p\n", str, (void *) svp); 115 116 if (svp->ri_knconf != NULL) { 117 cmn_err(CE_NOTE, "!knconf: semantics %d", 118 svp->ri_knconf->knc_semantics); 119 cmn_err(CE_NOTE, "! protofmly %s", 120 svp->ri_knconf->knc_protofmly); 121 cmn_err(CE_NOTE, "! proto %s", 122 svp->ri_knconf->knc_proto); 123 cmn_err(CE_NOTE, "! rdev %lx", 124 svp->ri_knconf->knc_rdev); 125 } 126 127 for (i = 0; i < svp->ri_addr.len; i++) 128 printf("%u ", svp->ri_addr.buf[i]); 129 130 cmn_err(CE_NOTE, "!\naddr: len %d buf %p\n", 131 svp->ri_addr.len, (void *) svp->ri_addr.buf); 132 cmn_err(CE_NOTE, "!host: %s\n", svp->ri_hostname); 133 } 134 #endif /* DEBUG */ 135 136 /* 137 * Initialize an rdc servinfo 138 * Contains all the protocol we need to do a client rpc 139 * A chain of rdc_srv_t indicates a one to many 140 */ 141 142 rdc_srv_t * 143 rdc_create_svinfo(char *host, struct netbuf *svaddr, struct knetconfig *conf) 144 { 145 rdc_srv_t *nvp; 146 int hlen = strlen(host) + 1; 147 148 if (conf == NULL) { 149 return (NULL); 150 } 151 152 if (host == NULL) { 153 return (NULL); 154 } 155 156 nvp = kmem_zalloc(sizeof (*nvp), KM_SLEEP); 157 nvp->ri_knconf = kmem_alloc(sizeof (*nvp->ri_knconf), KM_SLEEP); 158 nvp->ri_hostname = kmem_zalloc(hlen, KM_SLEEP); 159 160 if (nvp == NULL || nvp->ri_hostname == NULL || nvp->ri_knconf == NULL) { 161 rdc_destroy_svinfo(nvp); 162 return (NULL); 163 } 164 165 nvp->ri_hostnamelen = hlen; 166 167 bcopy((void *)conf, (void *)nvp->ri_knconf, sizeof (*nvp->ri_knconf)); 168 nvp->ri_knconf->knc_protofmly = kmem_zalloc(KNC_STRSIZE + 1, KM_SLEEP); 169 nvp->ri_knconf->knc_proto = kmem_zalloc(KNC_STRSIZE + 1, KM_SLEEP); 170 171 if (nvp->ri_knconf->knc_protofmly == NULL || 172 nvp->ri_knconf->knc_proto == NULL) { 173 rdc_destroy_svinfo(nvp); 174 return (NULL); 175 176 } 177 178 (void) strncpy(nvp->ri_knconf->knc_protofmly, conf->knc_protofmly, 179 KNC_STRSIZE); 180 (void) strncpy(nvp->ri_knconf->knc_proto, conf->knc_proto, KNC_STRSIZE); 181 182 dup_rdc_netbuf(svaddr, &nvp->ri_addr); 183 184 nvp->ri_secdata = NULL; /* For now */ 185 (void) strncpy(nvp->ri_hostname, host, hlen); 186 #ifdef DEBUG_IP 187 rdc_print_svinfo(nvp, "!create"); 188 #endif 189 return (nvp); 190 } 191 192 void 193 rdc_destroy_svinfo(rdc_srv_t *svp) 194 { 195 if (svp == NULL) 196 return; 197 198 if (svp->ri_addr.buf && svp->ri_addr.maxlen) 199 free_rdc_netbuf(&(svp->ri_addr)); 200 201 if (svp->ri_knconf->knc_protofmly) 202 kmem_free(svp->ri_knconf->knc_protofmly, KNC_STRSIZE + 1); 203 204 if (svp->ri_knconf->knc_proto) 205 kmem_free(svp->ri_knconf->knc_proto, KNC_STRSIZE + 1); 206 207 if (svp->ri_knconf) 208 kmem_free(svp->ri_knconf, sizeof (*svp->ri_knconf)); 209 210 kmem_free(svp, sizeof (*svp)); 211 } 212 213 /* 214 * rdc_netbuf_toint 215 * Returns oldsytle ipv4 RDC ver 3 addresses for RPC protocol from netbuf 216 * Note: This would never be called in the case of IPv6 and a program 217 * mismatch ie ver 3 to ver 4 218 */ 219 int 220 rdc_netbuf_toint(struct netbuf *nb) 221 { 222 int ret; 223 if (nb->len > RDC_MAXADDR) 224 cmn_err(CE_NOTE, "!rdc_netbuf_toint: bad size %d", nb->len); 225 226 switch (nb->len) { 227 case 4: 228 bcopy(nb->buf, (char *)&ret, sizeof (int)); 229 return (ret); 230 231 case 8: 232 case 16: 233 case 32: 234 bcopy(&nb->buf[4], (char *)&ret, sizeof (int)); 235 return (ret); 236 237 default: 238 cmn_err(CE_NOTE, "!rdc_netbuf_toint: size %d", nb->len); 239 } 240 return (0); 241 } 242