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