1 /**************************************************************************** 2 * fs/nfs/rpc.h 3 * 4 * Copyright (C) 2012 Gregory Nutt. All rights reserved. 5 * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved. 6 * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com> 7 * Gregory Nutt <gnutt@nuttx.org> 8 * 9 * Leveraged from OpenBSD: 10 * 11 * copyright (c) 2003 12 * the regents of the university of michigan 13 * all rights reserved 14 * 15 * permission is granted to use, copy, create derivative works and 16 * redistribute this software and such derivative works for any purpose, so 17 * long as the name of the university of michigan is not used in any 18 * advertising or publicity pertaining to the use or distribution of this 19 * software without specific, written prior authorization. if the above 20 * copyright notice or any other identification of the university of michigan 21 * is included in any copy of any portion of this software, then the 22 * disclaimer below must also be included. 23 * 24 * this software is provided as is, without representation from the 25 * university of michigan as to its fitness for any purpose, and without 26 * warranty by the university of michigan of any kind, either express or 27 * implied, including without limitation the implied warranties of 28 * merchantability and fitness for a particular purpose. the regents of the 29 * university of michigan shall not be liable for any damages, including 30 * special, indirect, incidental, or consequential damages, with respect to 31 * any claim arising out of or in connection with the use of the software, 32 * even if it has been or is hereafter advised of the possibility of such 33 * damages. 34 * 35 * Copyright (c) 1989, 1993 36 * The Regents of the University of California. All rights reserved. 37 * 38 * This code is derived from software contributed to Berkeley by 39 * Rick Macklem at The University of Guelph. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by the University of 53 * California, Berkeley and its contributors. 54 * 4. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 * 70 ****************************************************************************/ 71 72 #ifndef __FS_NFS_RPC_H 73 #define __FS_NFS_RPC_H 74 75 /**************************************************************************** 76 * Included Files 77 ****************************************************************************/ 78 79 #include <sys/types.h> 80 #include <securec.h> 81 #include <netinet/in.h> 82 #include "nfs_proto.h" 83 84 #ifdef __cplusplus 85 #if __cplusplus 86 extern "C" { 87 #endif /* __cplusplus */ 88 #endif /* __cplusplus */ 89 90 /**************************************************************************** 91 * Pre-processor Definitions 92 ****************************************************************************/ 93 94 /* Version # */ 95 96 #define RPC_VER2 2 97 98 /* Authentication */ 99 100 #define RPCAUTH_NULL 0 101 #define RPCAUTH_UNIX 1 102 #define RPCAUTH_SHORT 2 103 #define RPCAUTH_KERB4 4 104 #define RPCAUTH_MAXSIZ 400 105 #define RPCVERF_MAXSIZ 12 106 /* For Kerb, can actually be 400 */ 107 #define RPCAUTH_UNIXGIDS 16 108 109 #define NFS_IPPROTO_TCP 6 110 #define NFS_IPPROTO_UDP 17 111 #define NFS_PROTO_TYPE NFS_IPPROTO_TCP 112 113 #if (NFS_PROTO_TYPE == NFS_IPPROTO_TCP) 114 #define NFS_PROTOTYPE IPPROTO_TCP /* Default protocol to provide */ 115 #elif (NFS_PROTO_TYPE == NFS_IPPROTO_UDP) 116 #define NFS_PROTOTYPE IPPROTO_UDP 117 #endif 118 119 /* There is an argument we can set in nfs server influences the port number we can use. 120 * When it is "secure", nfs use port number under 1024. 121 * When it is "insecure", nfs use port number over 1024. 122 * And "secure" is default. 123 */ 124 125 #define RPCCONN_MAXPORT 1023 126 #define RPCCONN_MINPORT 256 127 128 129 /* Constants associated with authentication flavours. */ 130 131 #define RPCAKN_FULLNAME 0 132 #define RPCAKN_NICKNAME 1 133 134 /* RPC Constants */ 135 136 #define RPC_CALL 0 137 #define RPC_REPLY 1 138 #define RPC_MSGACCEPTED 0 139 #define RPC_MSGDENIED 1 140 #define RPC_PROGUNAVAIL 1 141 #define RPC_PROGMISMATCH 2 142 #define RPC_PROCUNAVAIL 3 143 #define RPC_GARBAGE 4 144 145 #define RPC_MISMATCH 0 146 #define RPC_AUTHERR 1 147 148 /* Authentication failures */ 149 150 #define AUTH_BADCRED 1 151 #define AUTH_REJECTCRED 2 152 #define AUTH_BADVERF 3 153 #define AUTH_REJECTVERF 4 154 #define AUTH_TOOWEAK 5 155 156 /* Sizes of RPC header parts */ 157 158 #define RPC_SIZ 24 159 #define RPC_REPLYSIZ 28 160 #define RPC_RPATH_MAXSIZE NFS_MOUNT_PATH_MAX_SIZE 161 162 #if (NFS_PROTO_TYPE == NFS_IPPROTO_TCP) 163 #define RPC_RMSIZE 4 164 #define RPC_RM_FLAGMENT_LAST_FLAG 0x80000000 165 #define RPC_RM_FLAGMENT_LEN_MASK 0x7FFFFFFF 166 #elif (NFS_PROTO_TYPE == NFS_IPPROTO_UDP) 167 #define RPC_RMSIZE 0 168 #endif 169 170 /* RPC Prog definitions */ 171 172 #define RPCPROG_MNT 100005 173 #define RPCMNT_VER1 1 174 #define RPCMNT_VER3 3 175 #define RPCMNT_MOUNT 1 176 #define RPCMNT_DUMP 2 177 #define RPCMNT_UMOUNT 3 178 #define RPCMNT_UMNTALL 4 179 #define RPCMNT_EXPORT 5 180 #define RPCMNT_NAMELEN 255 181 #define RPCMNT_PATHLEN 1024 182 #define RPCPROG_NFS 100003 183 184 /* RPC definitions for the portmapper. */ 185 186 #define PMAPPORT 111 187 #define PMAPPROG 100000 188 #define PMAPVERS 2 189 190 #define PMAPPROC_NULL 0 191 #define PMAPPROC_SET 1 192 #define PMAPPROC_UNSET 2 193 #define PMAPPROC_GETPORT 3 194 #define PMAPPROC_DUMP 4 195 #define PMAPPROC_CALLIT 5 196 197 #define RPC_SUCCESS 0 198 199 /**************************************************************************** 200 * Public Types 201 ****************************************************************************/ 202 203 /* Global RPC statistics */ 204 205 #ifdef CONFIG_NFS_STATISTICS 206 struct rpcstats 207 { 208 int rpcretries; 209 int rpcrequests; 210 int rpctimeouts; 211 int rpcinvalid; 212 }; 213 #endif 214 215 /* PMAP headers */ 216 217 struct call_args_pmap 218 { 219 uint32_t prog; 220 uint32_t vers; 221 uint32_t proc; 222 uint32_t port; 223 }; 224 225 struct call_result_pmap 226 { 227 uint32_t port; 228 }; 229 230 /* MOUNTD headers */ 231 232 struct call_args_mount 233 { 234 uint32_t len; 235 char rpath[RPC_RPATH_MAXSIZE]; 236 }; 237 238 struct call_args_umount 239 { 240 uint32_t len; 241 char rpath[RPC_RPATH_MAXSIZE]; 242 }; 243 244 245 246 /* Generic RPC call headers */ 247 248 enum auth_flavor 249 { 250 AUTH_NONE = 0, 251 AUTH_SYS = 1, 252 AUTH_SHORT = 2, 253 AUTH_DES = 3, 254 AUTH_MAX 255 256 /* and more to be defined */ 257 }; 258 259 struct call_result_mount 260 { 261 uint32_t status; 262 struct file_handle fhandle; 263 uint32_t authlen; 264 uint32_t autolist[AUTH_MAX]; 265 }; 266 267 /* Generic RPC call headers */ 268 269 struct rpc_auth_info 270 { 271 uint32_t authtype; /* auth type */ 272 uint32_t authlen; /* auth length */ 273 }; 274 275 struct auth_unix 276 { 277 uint32_t stamp; 278 uint32_t hostname_len; 279 280 /* use n uint32_t(s) to store CONFIG_NFS_MACHINE_NAME_SIZE bytes */ 281 282 uint32_t hostname[(CONFIG_NFS_MACHINE_NAME_SIZE + sizeof(uint32_t) - 1) / sizeof(uint32_t)]; 283 uint32_t uid; 284 uint32_t gid; 285 uint32_t gidlist; 286 uint32_t gidlist_value; 287 }; 288 289 struct rpc_call_header 290 { 291 #if (NFS_PROTO_TYPE == NFS_IPPROTO_TCP) 292 uint32_t rp_recmark; /* fragment header */ 293 #endif 294 uint32_t rp_xid; /* request transaction id */ 295 int32_t rp_direction; /* call direction (0) */ 296 uint32_t rp_rpcvers; /* RPC version (2) */ 297 uint32_t rp_prog; /* program */ 298 uint32_t rp_vers; /* version */ 299 uint32_t rp_proc; /* procedure */ 300 struct rpc_auth_info rpc_auth; 301 struct auth_unix rpc_auth_unix; 302 struct rpc_auth_info rpc_verf; 303 }; 304 305 struct rpc_call_pmap 306 { 307 struct rpc_call_header ch; 308 struct call_args_pmap pmap; 309 }; 310 311 struct rpc_call_mount 312 { 313 struct rpc_call_header ch; 314 struct call_args_mount mount; 315 }; 316 317 struct rpc_call_umount 318 { 319 struct rpc_call_header ch; 320 struct call_args_umount umount; 321 }; 322 323 struct rpc_call_create 324 { 325 struct rpc_call_header ch; 326 struct CREATE3args create; 327 }; 328 329 struct rpc_call_lookup 330 { 331 struct rpc_call_header ch; 332 struct LOOKUP3args lookup; 333 }; 334 #define SIZEOF_rpc_call_lookup(n) (sizeof(struct rpc_call_header) + SIZEOF_LOOKUP3args(n)) 335 336 struct rpc_call_read 337 { 338 struct rpc_call_header ch; 339 struct READ3args read; 340 }; 341 342 struct rpc_call_write 343 { 344 struct rpc_call_header ch; 345 struct WRITE3args write; /* Variable length */ 346 }; 347 #define SIZEOF_rpc_call_write(n) (sizeof(struct rpc_call_header) + SIZEOF_WRITE3args(n)) 348 349 struct rpc_call_remove 350 { 351 struct rpc_call_header ch; 352 struct REMOVE3args remove; 353 }; 354 355 struct rpc_call_rename 356 { 357 struct rpc_call_header ch; 358 struct RENAME3args rename; 359 }; 360 361 struct rpc_call_mkdir 362 { 363 struct rpc_call_header ch; 364 struct MKDIR3args mkdir; 365 }; 366 367 struct rpc_call_rmdir 368 { 369 struct rpc_call_header ch; 370 struct RMDIR3args rmdir; 371 }; 372 373 struct rpc_call_readdir 374 { 375 struct rpc_call_header ch; 376 struct READDIR3args readdir; 377 }; 378 379 struct rpc_call_setattr 380 { 381 struct rpc_call_header ch; 382 struct SETATTR3args setattr; 383 }; 384 385 struct rpc_call_fs 386 { 387 struct rpc_call_header ch; 388 struct FS3args fs; 389 }; 390 391 /* Generic RPC reply headers */ 392 393 struct rpc_reply_header 394 { 395 #if (NFS_PROTO_TYPE == NFS_IPPROTO_TCP) 396 uint32_t rp_recmark; /* fragment header */ 397 #endif 398 uint32_t rp_xid; /* Request transaction id */ 399 uint32_t rp_direction; /* Call direction (1) */ 400 uint32_t type; 401 struct rpc_auth_info rpc_verfi; 402 uint32_t status; 403 }; 404 405 struct nfs_reply_header 406 { 407 #if (NFS_PROTO_TYPE == NFS_IPPROTO_TCP) 408 uint32_t rp_recmark; /* fragment header */ 409 #endif 410 uint32_t rp_xid; /* Request transaction id */ 411 uint32_t rp_direction; /* Call direction (1) */ 412 uint32_t type; 413 struct rpc_auth_info rpc_verfi; 414 uint32_t status; 415 uint32_t nfs_status; 416 }; 417 418 struct rpc_reply_pmap 419 { 420 struct rpc_reply_header rh; 421 struct call_result_pmap pmap; 422 }; 423 424 struct rpc_reply_mount 425 { 426 struct rpc_reply_header rh; 427 struct call_result_mount mount; 428 }; 429 430 struct rpc_reply_umount 431 { 432 struct rpc_reply_header rh; 433 }; 434 435 struct rpc_reply_create 436 { 437 struct rpc_reply_header rh; 438 uint32_t status; 439 struct CREATE3resok create; 440 }; 441 442 struct rpc_reply_lookup 443 { 444 struct rpc_reply_header rh; 445 uint32_t status; 446 struct LOOKUP3resok lookup; 447 }; 448 449 struct rpc_reply_write 450 { 451 struct rpc_reply_header rh; 452 uint32_t status; 453 struct WRITE3resok write; /* Variable length */ 454 }; 455 456 struct rpc_reply_read 457 { 458 struct rpc_reply_header rh; 459 uint32_t status; 460 struct READ3resok read; /* Variable length */ 461 }; 462 463 #define SIZEOF_rpc_reply_read(n) \ 464 (sizeof(struct rpc_reply_header) + sizeof(uint32_t) + \ 465 SIZEOF_READ3resok(n)) 466 467 struct rpc_reply_remove 468 { 469 struct rpc_reply_header rh; 470 uint32_t status; 471 struct REMOVE3resok remove; 472 }; 473 474 struct rpc_reply_rename 475 { 476 struct rpc_reply_header rh; 477 uint32_t status; 478 struct RENAME3resok rename; 479 }; 480 481 struct rpc_reply_mkdir 482 { 483 struct rpc_reply_header rh; 484 uint32_t status; 485 struct MKDIR3resok mkdir; 486 }; 487 488 struct rpc_reply_rmdir 489 { 490 struct rpc_reply_header rh; 491 uint32_t status; 492 struct RMDIR3resok rmdir; 493 }; 494 495 struct rpc_reply_readdir 496 { 497 struct rpc_reply_header rh; 498 uint32_t status; 499 struct READDIR3resok readdir; 500 }; 501 502 #define SIZEOF_rpc_reply_readdir(n) \ 503 (sizeof(struct rpc_reply_header) + sizeof(uint32_t) + \ 504 SIZEOF_READDIR3resok(n)) 505 506 struct rpc_reply_fsinfo 507 { 508 struct rpc_reply_header rh; 509 uint32_t status; 510 struct nfsv3_fsinfo fsinfo; 511 }; 512 513 struct rpc_reply_fsstat 514 { 515 struct rpc_reply_header rh; 516 uint32_t status; 517 struct nfs_statfs fsstat; 518 }; 519 520 struct rpc_reply_getattr 521 { 522 struct rpc_reply_header rh; 523 uint32_t status; 524 struct nfs_fattr attr; 525 }; 526 527 struct rpc_reply_setattr 528 { 529 struct rpc_reply_header rh; 530 uint32_t status; 531 struct SETATTR3resok setattr; 532 }; 533 534 struct rpcclnt 535 { 536 nfsfh_t rc_fh; /* File handle of the root directory */ 537 unsigned int rc_fhsize; /* File size of the root directory */ 538 char *rc_path; /* Server's path of the mounted directory */ 539 uint32_t xid; 540 struct sockaddr *rc_name; 541 int rc_so; /* RPC socket */ 542 543 bool rc_timeout; /* Receipt of reply timed out */ 544 uint8_t rc_sotype; /* Type of socket */ 545 uint8_t rc_retry; /* Max retries */ 546 }; 547 548 /**************************************************************************** 549 * Public Function Prototypes 550 ****************************************************************************/ 551 552 void rpcclnt_init(void); 553 int rpcclnt_connect(struct rpcclnt *rpc); 554 void rpcclnt_disconnect(struct rpcclnt *rpc); 555 int rpcclnt_umount(struct rpcclnt *rpc); 556 void rpcclnt_safedisconnect(struct rpcclnt *rpc); 557 int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version, 558 void *request, size_t reqlen, 559 void *response, size_t resplen); 560 void rpcclnt_setuidgid(uint32_t uid, uint32_t gid); 561 562 #ifdef __cplusplus 563 #if __cplusplus 564 } 565 #endif /* __cplusplus */ 566 #endif /* __cplusplus */ 567 568 #endif /* __FS_NFS_RPC_H */ 569