14a5d661aSToomas Soome /* $NetBSD: bootparam.c,v 1.11 1997/06/26 19:11:32 drochner Exp $ */ 24a5d661aSToomas Soome 34a5d661aSToomas Soome /* 44a5d661aSToomas Soome * Copyright (c) 1995 Gordon W. Ross 54a5d661aSToomas Soome * All rights reserved. 64a5d661aSToomas Soome * 74a5d661aSToomas Soome * Redistribution and use in source and binary forms, with or without 84a5d661aSToomas Soome * modification, are permitted provided that the following conditions 94a5d661aSToomas Soome * are met: 104a5d661aSToomas Soome * 1. Redistributions of source code must retain the above copyright 114a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer. 124a5d661aSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright 134a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer in the 144a5d661aSToomas Soome * documentation and/or other materials provided with the distribution. 154a5d661aSToomas Soome * 3. The name of the author may not be used to endorse or promote products 164a5d661aSToomas Soome * derived from this software without specific prior written permission. 174a5d661aSToomas Soome * 4. All advertising materials mentioning features or use of this software 184a5d661aSToomas Soome * must display the following acknowledgement: 194a5d661aSToomas Soome * This product includes software developed by Gordon W. Ross 204a5d661aSToomas Soome * 214a5d661aSToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 224a5d661aSToomas Soome * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 234a5d661aSToomas Soome * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 244a5d661aSToomas Soome * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 254a5d661aSToomas Soome * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 264a5d661aSToomas Soome * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 274a5d661aSToomas Soome * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 284a5d661aSToomas Soome * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 294a5d661aSToomas Soome * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 304a5d661aSToomas Soome * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 314a5d661aSToomas Soome */ 324a5d661aSToomas Soome 334a5d661aSToomas Soome #include <sys/cdefs.h> 344a5d661aSToomas Soome 354a5d661aSToomas Soome /* 364a5d661aSToomas Soome * RPC/bootparams 374a5d661aSToomas Soome */ 384a5d661aSToomas Soome 394a5d661aSToomas Soome #include <sys/param.h> 404a5d661aSToomas Soome #include <sys/socket.h> 414a5d661aSToomas Soome 424a5d661aSToomas Soome #include <net/if.h> 434a5d661aSToomas Soome 444a5d661aSToomas Soome #include <netinet/in.h> 454a5d661aSToomas Soome #include <netinet/in_systm.h> 464a5d661aSToomas Soome 474a5d661aSToomas Soome #include <string.h> 484a5d661aSToomas Soome 494a5d661aSToomas Soome #include "rpcv2.h" 504a5d661aSToomas Soome 514a5d661aSToomas Soome #include "stand.h" 524a5d661aSToomas Soome #include "net.h" 534a5d661aSToomas Soome #include "netif.h" 544a5d661aSToomas Soome #include "rpc.h" 554a5d661aSToomas Soome #include "bootparam.h" 564a5d661aSToomas Soome 574a5d661aSToomas Soome #ifdef DEBUG_RPC 584a5d661aSToomas Soome #define RPC_PRINTF(a) printf a 594a5d661aSToomas Soome #else 604a5d661aSToomas Soome #define RPC_PRINTF(a) 614a5d661aSToomas Soome #endif 624a5d661aSToomas Soome 634a5d661aSToomas Soome struct in_addr bp_server_addr; /* net order */ 644a5d661aSToomas Soome n_short bp_server_port; /* net order */ 654a5d661aSToomas Soome 664a5d661aSToomas Soome /* 674a5d661aSToomas Soome * RPC definitions for bootparamd 684a5d661aSToomas Soome */ 694a5d661aSToomas Soome #define BOOTPARAM_PROG 100026 704a5d661aSToomas Soome #define BOOTPARAM_VERS 1 714a5d661aSToomas Soome #define BOOTPARAM_WHOAMI 1 724a5d661aSToomas Soome #define BOOTPARAM_GETFILE 2 734a5d661aSToomas Soome 744a5d661aSToomas Soome /* 754a5d661aSToomas Soome * Inet address in RPC messages 764a5d661aSToomas Soome * (Note, really four ints, NOT chars. Blech.) 774a5d661aSToomas Soome */ 784a5d661aSToomas Soome struct xdr_inaddr { 794a5d661aSToomas Soome u_int32_t atype; 804a5d661aSToomas Soome int32_t addr[4]; 814a5d661aSToomas Soome }; 824a5d661aSToomas Soome 834a5d661aSToomas Soome int xdr_inaddr_encode(char **p, struct in_addr ia); 844a5d661aSToomas Soome int xdr_inaddr_decode(char **p, struct in_addr *ia); 854a5d661aSToomas Soome 864a5d661aSToomas Soome int xdr_string_encode(char **p, char *str, int len); 874a5d661aSToomas Soome int xdr_string_decode(char **p, char *str, int *len_p); 884a5d661aSToomas Soome 894a5d661aSToomas Soome 904a5d661aSToomas Soome /* 914a5d661aSToomas Soome * RPC: bootparam/whoami 924a5d661aSToomas Soome * Given client IP address, get: 934a5d661aSToomas Soome * client name (hostname) 944a5d661aSToomas Soome * domain name (domainname) 954a5d661aSToomas Soome * gateway address 964a5d661aSToomas Soome * 974a5d661aSToomas Soome * The hostname and domainname are set here for convenience. 984a5d661aSToomas Soome * 994a5d661aSToomas Soome * Note - bpsin is initialized to the broadcast address, 1004a5d661aSToomas Soome * and will be replaced with the bootparam server address 1014a5d661aSToomas Soome * after this call is complete. Have to use PMAP_PROC_CALL 1024a5d661aSToomas Soome * to make sure we get responses only from a servers that 1034a5d661aSToomas Soome * know about us (don't want to broadcast a getport call). 1044a5d661aSToomas Soome */ 1054a5d661aSToomas Soome int 106*7b2a1233SToomas Soome bp_whoami(int sockfd) 1074a5d661aSToomas Soome { 1084a5d661aSToomas Soome /* RPC structures for PMAPPROC_CALLIT */ 1094a5d661aSToomas Soome struct args { 1104a5d661aSToomas Soome u_int32_t prog; 1114a5d661aSToomas Soome u_int32_t vers; 1124a5d661aSToomas Soome u_int32_t proc; 1134a5d661aSToomas Soome u_int32_t arglen; 1144a5d661aSToomas Soome struct xdr_inaddr xina; 1154a5d661aSToomas Soome } *args; 1164a5d661aSToomas Soome struct repl { 1174a5d661aSToomas Soome u_int16_t _pad; 1184a5d661aSToomas Soome u_int16_t port; 1194a5d661aSToomas Soome u_int32_t encap_len; 1204a5d661aSToomas Soome /* encapsulated data here */ 1214a5d661aSToomas Soome n_long capsule[64]; 1224a5d661aSToomas Soome } *repl; 1234a5d661aSToomas Soome struct { 1244a5d661aSToomas Soome n_long h[RPC_HEADER_WORDS]; 1254a5d661aSToomas Soome struct args d; 1264a5d661aSToomas Soome } sdata; 1274a5d661aSToomas Soome char *send_tail, *recv_head; 1284a5d661aSToomas Soome struct iodesc *d; 129*7b2a1233SToomas Soome void *pkt; 130*7b2a1233SToomas Soome int len, x, rc; 1314a5d661aSToomas Soome 1324a5d661aSToomas Soome RPC_PRINTF(("bp_whoami: myip=%s\n", inet_ntoa(myip))); 1334a5d661aSToomas Soome 134*7b2a1233SToomas Soome rc = -1; 1354a5d661aSToomas Soome if (!(d = socktodesc(sockfd))) { 1364a5d661aSToomas Soome RPC_PRINTF(("bp_whoami: bad socket. %d\n", sockfd)); 137*7b2a1233SToomas Soome return (rc); 1384a5d661aSToomas Soome } 1394a5d661aSToomas Soome args = &sdata.d; 1404a5d661aSToomas Soome 1414a5d661aSToomas Soome /* 1424a5d661aSToomas Soome * Build request args for PMAPPROC_CALLIT. 1434a5d661aSToomas Soome */ 1444a5d661aSToomas Soome args->prog = htonl(BOOTPARAM_PROG); 1454a5d661aSToomas Soome args->vers = htonl(BOOTPARAM_VERS); 1464a5d661aSToomas Soome args->proc = htonl(BOOTPARAM_WHOAMI); 1474a5d661aSToomas Soome args->arglen = htonl(sizeof(struct xdr_inaddr)); 1484a5d661aSToomas Soome send_tail = (char*) &args->xina; 1494a5d661aSToomas Soome 1504a5d661aSToomas Soome /* 1514a5d661aSToomas Soome * append encapsulated data (client IP address) 1524a5d661aSToomas Soome */ 1534a5d661aSToomas Soome if (xdr_inaddr_encode(&send_tail, myip)) 154*7b2a1233SToomas Soome return (rc); 1554a5d661aSToomas Soome 1564a5d661aSToomas Soome /* RPC: portmap/callit */ 1574a5d661aSToomas Soome d->myport = htons(--rpc_port); 1584a5d661aSToomas Soome d->destip.s_addr = INADDR_BROADCAST; /* XXX: subnet bcast? */ 1594a5d661aSToomas Soome /* rpc_call will set d->destport */ 1604a5d661aSToomas Soome 161*7b2a1233SToomas Soome pkt = NULL; 1624a5d661aSToomas Soome len = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_CALLIT, 163*7b2a1233SToomas Soome args, send_tail - (char*)args, (void **)&repl, &pkt); 1644a5d661aSToomas Soome if (len < 8) { 1654a5d661aSToomas Soome printf("bootparamd: 'whoami' call failed\n"); 166*7b2a1233SToomas Soome goto done; 1674a5d661aSToomas Soome } 1684a5d661aSToomas Soome 1694a5d661aSToomas Soome /* Save bootparam server address (from IP header). */ 1704a5d661aSToomas Soome rpc_fromaddr(repl, &bp_server_addr, &bp_server_port); 1714a5d661aSToomas Soome 1724a5d661aSToomas Soome /* 1734a5d661aSToomas Soome * Note that bp_server_port is now 111 due to the 1744a5d661aSToomas Soome * indirect call (using PMAPPROC_CALLIT), so get the 1754a5d661aSToomas Soome * actual port number from the reply data. 1764a5d661aSToomas Soome */ 1774a5d661aSToomas Soome bp_server_port = repl->port; 1784a5d661aSToomas Soome 1794a5d661aSToomas Soome RPC_PRINTF(("bp_whoami: server at %s:%d\n", 1804a5d661aSToomas Soome inet_ntoa(bp_server_addr), ntohs(bp_server_port))); 1814a5d661aSToomas Soome 1824a5d661aSToomas Soome /* We have just done a portmap call, so cache the portnum. */ 1834a5d661aSToomas Soome rpc_pmap_putcache(bp_server_addr, 1844a5d661aSToomas Soome BOOTPARAM_PROG, 1854a5d661aSToomas Soome BOOTPARAM_VERS, 1864a5d661aSToomas Soome (int)ntohs(bp_server_port)); 1874a5d661aSToomas Soome 1884a5d661aSToomas Soome /* 1894a5d661aSToomas Soome * Parse the encapsulated results from bootparam/whoami 1904a5d661aSToomas Soome */ 1914a5d661aSToomas Soome x = ntohl(repl->encap_len); 1924a5d661aSToomas Soome if (len < x) { 1934a5d661aSToomas Soome printf("bp_whoami: short reply, %d < %d\n", len, x); 194*7b2a1233SToomas Soome goto done; 1954a5d661aSToomas Soome } 1964a5d661aSToomas Soome recv_head = (char*) repl->capsule; 1974a5d661aSToomas Soome 1984a5d661aSToomas Soome /* client name */ 1994a5d661aSToomas Soome hostnamelen = MAXHOSTNAMELEN-1; 2004a5d661aSToomas Soome if (xdr_string_decode(&recv_head, hostname, &hostnamelen)) { 2014a5d661aSToomas Soome RPC_PRINTF(("bp_whoami: bad hostname\n")); 202*7b2a1233SToomas Soome goto done; 2034a5d661aSToomas Soome } 2044a5d661aSToomas Soome 2054a5d661aSToomas Soome /* domain name */ 2064a5d661aSToomas Soome domainnamelen = MAXHOSTNAMELEN-1; 2074a5d661aSToomas Soome if (xdr_string_decode(&recv_head, domainname, &domainnamelen)) { 2084a5d661aSToomas Soome RPC_PRINTF(("bp_whoami: bad domainname\n")); 209*7b2a1233SToomas Soome goto done; 2104a5d661aSToomas Soome } 2114a5d661aSToomas Soome 2124a5d661aSToomas Soome /* gateway address */ 2134a5d661aSToomas Soome if (xdr_inaddr_decode(&recv_head, &gateip)) { 2144a5d661aSToomas Soome RPC_PRINTF(("bp_whoami: bad gateway\n")); 215*7b2a1233SToomas Soome goto done; 2164a5d661aSToomas Soome } 2174a5d661aSToomas Soome 2184a5d661aSToomas Soome /* success */ 219*7b2a1233SToomas Soome rc = 0; 220*7b2a1233SToomas Soome done: 221*7b2a1233SToomas Soome free(pkt); 222*7b2a1233SToomas Soome return(rc); 2234a5d661aSToomas Soome } 2244a5d661aSToomas Soome 2254a5d661aSToomas Soome 2264a5d661aSToomas Soome /* 2274a5d661aSToomas Soome * RPC: bootparam/getfile 2284a5d661aSToomas Soome * Given client name and file "key", get: 2294a5d661aSToomas Soome * server name 2304a5d661aSToomas Soome * server IP address 2314a5d661aSToomas Soome * server pathname 2324a5d661aSToomas Soome */ 2334a5d661aSToomas Soome int 234*7b2a1233SToomas Soome bp_getfile(int sockfd, char *key, struct in_addr *serv_addr, char *pathname) 2354a5d661aSToomas Soome { 2364a5d661aSToomas Soome struct { 2374a5d661aSToomas Soome n_long h[RPC_HEADER_WORDS]; 2384a5d661aSToomas Soome n_long d[64]; 2394a5d661aSToomas Soome } sdata; 240*7b2a1233SToomas Soome void *pkt; 2414a5d661aSToomas Soome char serv_name[FNAME_SIZE]; 242*7b2a1233SToomas Soome char *rdata, *send_tail; 2434a5d661aSToomas Soome /* misc... */ 2444a5d661aSToomas Soome struct iodesc *d; 245*7b2a1233SToomas Soome int rc = -1, sn_len, path_len, rlen; 2464a5d661aSToomas Soome 2474a5d661aSToomas Soome if (!(d = socktodesc(sockfd))) { 2484a5d661aSToomas Soome RPC_PRINTF(("bp_getfile: bad socket. %d\n", sockfd)); 2494a5d661aSToomas Soome return (-1); 2504a5d661aSToomas Soome } 2514a5d661aSToomas Soome 2524a5d661aSToomas Soome send_tail = (char*) sdata.d; 2534a5d661aSToomas Soome 2544a5d661aSToomas Soome /* 2554a5d661aSToomas Soome * Build request message. 2564a5d661aSToomas Soome */ 2574a5d661aSToomas Soome 2584a5d661aSToomas Soome /* client name (hostname) */ 2594a5d661aSToomas Soome if (xdr_string_encode(&send_tail, hostname, hostnamelen)) { 2604a5d661aSToomas Soome RPC_PRINTF(("bp_getfile: bad client\n")); 2614a5d661aSToomas Soome return (-1); 2624a5d661aSToomas Soome } 2634a5d661aSToomas Soome 2644a5d661aSToomas Soome /* key name (root or swap) */ 2654a5d661aSToomas Soome if (xdr_string_encode(&send_tail, key, strlen(key))) { 2664a5d661aSToomas Soome RPC_PRINTF(("bp_getfile: bad key\n")); 2674a5d661aSToomas Soome return (-1); 2684a5d661aSToomas Soome } 2694a5d661aSToomas Soome 2704a5d661aSToomas Soome /* RPC: bootparam/getfile */ 2714a5d661aSToomas Soome d->myport = htons(--rpc_port); 2724a5d661aSToomas Soome d->destip = bp_server_addr; 2734a5d661aSToomas Soome /* rpc_call will set d->destport */ 274*7b2a1233SToomas Soome pkt = NULL; 2754a5d661aSToomas Soome rlen = rpc_call(d, 2764a5d661aSToomas Soome BOOTPARAM_PROG, BOOTPARAM_VERS, BOOTPARAM_GETFILE, 2774a5d661aSToomas Soome sdata.d, send_tail - (char*)sdata.d, 278*7b2a1233SToomas Soome (void **)&rdata, &pkt); 2794a5d661aSToomas Soome if (rlen < 4) { 2804a5d661aSToomas Soome RPC_PRINTF(("bp_getfile: short reply\n")); 2814a5d661aSToomas Soome errno = EBADRPC; 282*7b2a1233SToomas Soome goto done; 2834a5d661aSToomas Soome } 2844a5d661aSToomas Soome 2854a5d661aSToomas Soome /* 2864a5d661aSToomas Soome * Parse result message. 2874a5d661aSToomas Soome */ 2884a5d661aSToomas Soome 2894a5d661aSToomas Soome /* server name */ 2904a5d661aSToomas Soome sn_len = FNAME_SIZE-1; 291*7b2a1233SToomas Soome if (xdr_string_decode(&rdata, serv_name, &sn_len)) { 2924a5d661aSToomas Soome RPC_PRINTF(("bp_getfile: bad server name\n")); 293*7b2a1233SToomas Soome goto done; 2944a5d661aSToomas Soome } 2954a5d661aSToomas Soome 2964a5d661aSToomas Soome /* server IP address (mountd/NFS) */ 297*7b2a1233SToomas Soome if (xdr_inaddr_decode(&rdata, serv_addr)) { 2984a5d661aSToomas Soome RPC_PRINTF(("bp_getfile: bad server addr\n")); 299*7b2a1233SToomas Soome goto done; 3004a5d661aSToomas Soome } 3014a5d661aSToomas Soome 3024a5d661aSToomas Soome /* server pathname */ 3034a5d661aSToomas Soome path_len = MAXPATHLEN-1; 304*7b2a1233SToomas Soome if (xdr_string_decode(&rdata, pathname, &path_len)) { 3054a5d661aSToomas Soome RPC_PRINTF(("bp_getfile: bad server path\n")); 306*7b2a1233SToomas Soome goto done; 3074a5d661aSToomas Soome } 3084a5d661aSToomas Soome 3094a5d661aSToomas Soome /* success */ 310*7b2a1233SToomas Soome rc = 0; 311*7b2a1233SToomas Soome done: 312*7b2a1233SToomas Soome free(pkt); 313*7b2a1233SToomas Soome return(rc); 3144a5d661aSToomas Soome } 3154a5d661aSToomas Soome 3164a5d661aSToomas Soome 3174a5d661aSToomas Soome /* 3184a5d661aSToomas Soome * eXternal Data Representation routines. 3194a5d661aSToomas Soome * (but with non-standard args...) 3204a5d661aSToomas Soome */ 3214a5d661aSToomas Soome 3224a5d661aSToomas Soome 3234a5d661aSToomas Soome int 324*7b2a1233SToomas Soome xdr_string_encode(char **pkt, char *str, int len) 3254a5d661aSToomas Soome { 326*7b2a1233SToomas Soome uint32_t *lenp; 3274a5d661aSToomas Soome char *datap; 3284a5d661aSToomas Soome int padlen = (len + 3) & ~3; /* padded length */ 3294a5d661aSToomas Soome 3304a5d661aSToomas Soome /* The data will be int aligned. */ 331*7b2a1233SToomas Soome lenp = (uint32_t *) *pkt; 3324a5d661aSToomas Soome *pkt += sizeof(*lenp); 3334a5d661aSToomas Soome *lenp = htonl(len); 3344a5d661aSToomas Soome 3354a5d661aSToomas Soome datap = *pkt; 3364a5d661aSToomas Soome *pkt += padlen; 3374a5d661aSToomas Soome bcopy(str, datap, len); 3384a5d661aSToomas Soome 3394a5d661aSToomas Soome return (0); 3404a5d661aSToomas Soome } 3414a5d661aSToomas Soome 3424a5d661aSToomas Soome int 343*7b2a1233SToomas Soome xdr_string_decode(char **pkt, char *str, int *len_p) 3444a5d661aSToomas Soome { 345*7b2a1233SToomas Soome uint32_t *lenp; 3464a5d661aSToomas Soome char *datap; 3474a5d661aSToomas Soome int slen; /* string length */ 3484a5d661aSToomas Soome int plen; /* padded length */ 3494a5d661aSToomas Soome 3504a5d661aSToomas Soome /* The data will be int aligned. */ 351*7b2a1233SToomas Soome lenp = (uint32_t *) *pkt; 3524a5d661aSToomas Soome *pkt += sizeof(*lenp); 3534a5d661aSToomas Soome slen = ntohl(*lenp); 3544a5d661aSToomas Soome plen = (slen + 3) & ~3; 3554a5d661aSToomas Soome 3564a5d661aSToomas Soome if (slen > *len_p) 3574a5d661aSToomas Soome slen = *len_p; 3584a5d661aSToomas Soome datap = *pkt; 3594a5d661aSToomas Soome *pkt += plen; 3604a5d661aSToomas Soome bcopy(datap, str, slen); 3614a5d661aSToomas Soome 3624a5d661aSToomas Soome str[slen] = '\0'; 3634a5d661aSToomas Soome *len_p = slen; 3644a5d661aSToomas Soome 3654a5d661aSToomas Soome return (0); 3664a5d661aSToomas Soome } 3674a5d661aSToomas Soome 3684a5d661aSToomas Soome 3694a5d661aSToomas Soome int 370*7b2a1233SToomas Soome xdr_inaddr_encode(char **pkt, struct in_addr ia) 3714a5d661aSToomas Soome { 3724a5d661aSToomas Soome struct xdr_inaddr *xi; 3734a5d661aSToomas Soome u_char *cp; 3744a5d661aSToomas Soome int32_t *ip; 3754a5d661aSToomas Soome union { 3764a5d661aSToomas Soome n_long l; /* network order */ 3774a5d661aSToomas Soome u_char c[4]; 3784a5d661aSToomas Soome } uia; 3794a5d661aSToomas Soome 3804a5d661aSToomas Soome /* The data will be int aligned. */ 3814a5d661aSToomas Soome xi = (struct xdr_inaddr *) *pkt; 3824a5d661aSToomas Soome *pkt += sizeof(*xi); 3834a5d661aSToomas Soome xi->atype = htonl(1); 3844a5d661aSToomas Soome uia.l = ia.s_addr; 3854a5d661aSToomas Soome cp = uia.c; 3864a5d661aSToomas Soome ip = xi->addr; 3874a5d661aSToomas Soome /* 3884a5d661aSToomas Soome * Note: the htonl() calls below DO NOT 3894a5d661aSToomas Soome * imply that uia.l is in host order. 3904a5d661aSToomas Soome * In fact this needs it in net order. 3914a5d661aSToomas Soome */ 3924a5d661aSToomas Soome *ip++ = htonl((unsigned int)*cp++); 3934a5d661aSToomas Soome *ip++ = htonl((unsigned int)*cp++); 3944a5d661aSToomas Soome *ip++ = htonl((unsigned int)*cp++); 3954a5d661aSToomas Soome *ip++ = htonl((unsigned int)*cp++); 3964a5d661aSToomas Soome 3974a5d661aSToomas Soome return (0); 3984a5d661aSToomas Soome } 3994a5d661aSToomas Soome 4004a5d661aSToomas Soome int 401*7b2a1233SToomas Soome xdr_inaddr_decode(char **pkt, struct in_addr *ia) 4024a5d661aSToomas Soome { 4034a5d661aSToomas Soome struct xdr_inaddr *xi; 4044a5d661aSToomas Soome u_char *cp; 4054a5d661aSToomas Soome int32_t *ip; 4064a5d661aSToomas Soome union { 4074a5d661aSToomas Soome n_long l; /* network order */ 4084a5d661aSToomas Soome u_char c[4]; 4094a5d661aSToomas Soome } uia; 4104a5d661aSToomas Soome 4114a5d661aSToomas Soome /* The data will be int aligned. */ 4124a5d661aSToomas Soome xi = (struct xdr_inaddr *) *pkt; 4134a5d661aSToomas Soome *pkt += sizeof(*xi); 4144a5d661aSToomas Soome if (xi->atype != htonl(1)) { 4154a5d661aSToomas Soome RPC_PRINTF(("xdr_inaddr_decode: bad addrtype=%d\n", 4164a5d661aSToomas Soome ntohl(xi->atype))); 4174a5d661aSToomas Soome return(-1); 4184a5d661aSToomas Soome } 4194a5d661aSToomas Soome 4204a5d661aSToomas Soome cp = uia.c; 4214a5d661aSToomas Soome ip = xi->addr; 4224a5d661aSToomas Soome /* 4234a5d661aSToomas Soome * Note: the ntohl() calls below DO NOT 4244a5d661aSToomas Soome * imply that uia.l is in host order. 4254a5d661aSToomas Soome * In fact this needs it in net order. 4264a5d661aSToomas Soome */ 4274a5d661aSToomas Soome *cp++ = ntohl(*ip++); 4284a5d661aSToomas Soome *cp++ = ntohl(*ip++); 4294a5d661aSToomas Soome *cp++ = ntohl(*ip++); 4304a5d661aSToomas Soome *cp++ = ntohl(*ip++); 4314a5d661aSToomas Soome ia->s_addr = uia.l; 4324a5d661aSToomas Soome 4334a5d661aSToomas Soome return (0); 4344a5d661aSToomas Soome } 435