1# This file is part of Scapy 2# See http://www.secdev.org/projects/scapy for more information 3# Copyright (C) Lucas Preston <lucas.preston@infinite.io> 4# This program is published under a GPLv2 license 5 6# scapy.contrib.description = Network File System (NFS) v3 7# scapy.contrib.status = loads 8 9from scapy.contrib.oncrpc import RPC, RPC_Call, Object_Name 10from binascii import unhexlify 11from scapy.packet import Packet, bind_layers 12from scapy.fields import IntField, IntEnumField, FieldListField, LongField, \ 13 XIntField, XLongField, ConditionalField, PacketListField, StrLenField, \ 14 PacketField 15from scapy.modules.six import integer_types 16 17nfsstat3 = { 18 0: 'NFS3_OK', 19 1: 'NFS3ERR_PERM', 20 2: 'NFS3ERR_NOENT', 21 5: 'NFS3ERR_IO', 22 6: 'NFS3ERR_NXIO', 23 13: 'NFS3ERR_ACCES', 24 17: 'NFS3ERR_EXIST', 25 18: 'NFS3ERR_XDEV', 26 19: 'NFS3ERR_NODEV', 27 20: 'NFS3ERR_NOTDIR', 28 21: 'NFS3ERR_ISDIR', 29 22: 'NFS3ERR_INVAL', 30 27: 'NFS3ERR_FBIG', 31 28: 'NFS3ERR_NOSPC', 32 30: 'NFS3ERR_ROFS', 33 31: 'NFS3ERR_MLINK', 34 63: 'NFS3ERR_NAMETOOLONG', 35 66: 'NFS3ERR_NOTEMPTY', 36 69: 'NFS3ERR_DQUOT', 37 70: 'NFS3ERR_STALE', 38 71: 'NFS3ERR_REMOTE', 39 10001: 'NFS3ERR_BADHANDLE', 40 10002: 'NFS3ERR_NOT_SYNC', 41 10003: 'NFS3ERR_BAD_COOKIE', 42 10004: 'NFS3ERR_NOTSUPP', 43 10005: 'NFS3ERR_TOOSMALL', 44 10006: 'NFS3ERR_SERVERFAULT', 45 10007: 'NFS3ERR_BADTYPE', 46 10008: 'NFS3ERR_JUKEBOX' 47} 48 49ftype3 = { 50 1: 'NF3REG', 51 2: 'NF3DIR', 52 3: 'NF3BLK', 53 4: 'NF3CHR', 54 5: 'NF3LNK', 55 6: 'NF3SOCK', 56 7: 'NF3FIFO' 57} 58 59 60def loct(x): 61 if isinstance(x, integer_types): 62 return oct(x) 63 if isinstance(x, tuple): 64 return "(%s)" % ", ".join(map(loct, x)) 65 if isinstance(x, list): 66 return "[%s]" % ", ".join(map(loct, x)) 67 return x 68 69 70class OIntField(IntField): 71 """IntField child with octal representation""" 72 def i2repr(self, pkt, x): 73 return loct(self.i2h(pkt, x)) 74 75 76class Fattr3(Packet): 77 name = 'File Attributes' 78 fields_desc = [ 79 IntEnumField('type', 0, ftype3), 80 OIntField('mode', 0), 81 IntField('nlink', 0), 82 IntField('uid', 0), 83 IntField('gid', 0), 84 LongField('size', 0), 85 LongField('used', 0), 86 FieldListField( 87 'rdev', [0, 0], IntField('', None), count_from=lambda x: 2 88 ), 89 XLongField('fsid', 0), 90 XLongField('fileid', 0), 91 IntField('atime_s', 0), 92 IntField('atime_ns', 0), 93 IntField('mtime_s', 0), 94 IntField('mtime_ns', 0), 95 IntField('ctime_s', 0), 96 IntField('ctime_ns', 0) 97 ] 98 99 def extract_padding(self, s): 100 return '', s 101 102 103class File_Object(Packet): 104 name = 'File Object' 105 fields_desc = [ 106 IntField('length', 0), 107 StrLenField('fh', b'', length_from=lambda pkt: pkt.length), 108 StrLenField('fill', b'', length_from=lambda pkt: (4 - pkt.length) % 4) 109 ] 110 111 def set(self, new_filehandle, length=None, fill=None): 112 # convert filehandle to bytes if it was passed as a string 113 if new_filehandle.isalnum(): 114 new_filehandle = unhexlify(new_filehandle) 115 116 if length is None: 117 length = len(new_filehandle) 118 if fill is None: 119 fill = b'\x00' * ((4 - length) % 4) 120 121 self.length = length 122 self.fh = new_filehandle 123 self.fill = fill 124 125 def extract_padding(self, s): 126 return '', s 127 128 129class WCC_Attr(Packet): 130 name = 'File Attributes' 131 fields_desc = [ 132 LongField('size', 0), 133 IntField('mtime_s', 0), 134 IntField('mtime_ns', 0), 135 IntField('ctime_s', 0), 136 IntField('ctime_ns', 0) 137 ] 138 139 def extract_padding(self, s): 140 return '', s 141 142 143class File_From_Dir_Plus(Packet): 144 name = 'File' 145 fields_desc = [ 146 LongField('fileid', 0), 147 PacketField('filename', Object_Name(), Object_Name), 148 LongField('cookie', 0), 149 IntField('attributes_follow', 0), 150 ConditionalField( 151 PacketField('attributes', Fattr3(), Fattr3), 152 lambda pkt: pkt.attributes_follow == 1 153 ), 154 IntField('handle_follows', 0), 155 ConditionalField( 156 PacketField('filehandle', File_Object(), File_Object), 157 lambda pkt: pkt.handle_follows == 1 158 ), 159 IntField('value_follows', 0) 160 ] 161 162 def extract_padding(self, s): 163 return '', s 164 165 166class File_From_Dir(Packet): 167 name = 'File' 168 fields_desc = [ 169 LongField('fileid', 0), 170 PacketField('filename', Object_Name(), Object_Name), 171 LongField('cookie', 0), 172 IntField('value_follows', 0) 173 ] 174 175 def extract_padding(self, s): 176 return '', s 177 178 179attrs_enum = {0: 'DONT SET', 1: 'SET'} 180times_enum = {0: 'DONT CHANGE', 1: 'SERVER TIME', 2: 'CLIENT TIME'} 181 182 183class Sattr3(Packet): 184 name = 'Setattr3' 185 fields_desc = [ 186 IntEnumField('set_mode', 0, attrs_enum), 187 ConditionalField(OIntField('mode', 0), lambda pkt: pkt.set_mode == 1), 188 IntEnumField('set_uid', 0, attrs_enum), 189 ConditionalField(IntField('uid', 0), lambda pkt: pkt.set_uid == 1), 190 IntEnumField('set_gid', 0, attrs_enum), 191 ConditionalField(IntField('gid', 0), lambda pkt: pkt.set_gid == 1), 192 IntEnumField('set_size', 0, attrs_enum), 193 ConditionalField(LongField('size', 0), lambda pkt: pkt.set_size == 1), 194 IntEnumField('set_atime', 0, times_enum), 195 ConditionalField( 196 IntField('atime_s', 0), lambda pkt: pkt.set_atime == 2 197 ), 198 ConditionalField( 199 IntField('atime_ns', 0), lambda pkt: pkt.set_atime == 2 200 ), 201 IntEnumField('set_mtime', 0, times_enum), 202 ConditionalField( 203 IntField('mtime_s', 0), lambda pkt: pkt.set_mtime == 2 204 ), 205 ConditionalField( 206 IntField('mtime_ns', 0), lambda pkt: pkt.set_mtime == 2 207 ) 208 ] 209 210 def extract_padding(self, s): 211 return '', s 212 213 214class GETATTR_Call(Packet): 215 name = 'GETATTR Call' 216 fields_desc = [ 217 PacketField('filehandle', File_Object(), File_Object) 218 ] 219 220 221class GETATTR_Reply(Packet): 222 name = 'GETATTR Reply' 223 fields_desc = [ 224 IntEnumField('status', 0, nfsstat3), 225 ConditionalField( 226 PacketField('attributes', Fattr3(), Fattr3), 227 lambda pkt: pkt.status == 0 228 ) 229 ] 230 231 def extract_padding(self, s): 232 return '', None 233 234 235bind_layers(RPC, GETATTR_Call, mtype=0) 236bind_layers( 237 RPC_Call, GETATTR_Call, program=100003, pversion=3, procedure=1 238) 239bind_layers(RPC, GETATTR_Reply, mtype=1) 240 241 242class LOOKUP_Call(Packet): 243 name = 'LOOKUP Call' 244 fields_desc = [ 245 PacketField('dir', File_Object(), File_Object), 246 PacketField('filename', Object_Name(), Object_Name) 247 ] 248 249 250class LOOKUP_Reply(Packet): 251 name = 'LOOKUP Reply' 252 fields_desc = [ 253 IntEnumField('status', 0, nfsstat3), 254 ConditionalField( 255 PacketField('filehandle', File_Object(), File_Object), 256 lambda pkt: pkt.status == 0 257 ), 258 ConditionalField(IntField('af_file', 0), lambda pkt: pkt.status == 0), 259 ConditionalField( 260 PacketField('file_attributes', Fattr3(), Fattr3), 261 lambda pkt: pkt.status == 0 and pkt.af_file == 1 262 ), 263 IntField('af_dir', 0), 264 ConditionalField( 265 PacketField('dir_attributes', Fattr3(), Fattr3), 266 lambda pkt: pkt.af_dir == 1 267 ) 268 ] 269 270 271bind_layers(RPC, LOOKUP_Call, mtype=0) 272bind_layers(RPC, LOOKUP_Reply, mtype=1) 273bind_layers(RPC_Call, LOOKUP_Call, program=100003, pversion=3, procedure=3) 274 275 276class NULL_Call(Packet): 277 name = 'NFS NULL Call' 278 fields_desc = [] 279 280 281class NULL_Reply(Packet): 282 name = 'NFS NULL Reply' 283 fields_desc = [] 284 285 286bind_layers(RPC, NULL_Call, mtype=0) 287bind_layers(RPC, NULL_Reply, mtype=1) 288bind_layers(RPC_Call, NULL_Call, program=100003, pversion=3, procedure=0) 289 290 291class FSINFO_Call(Packet): 292 name = 'FSINFO Call' 293 fields_desc = [ 294 PacketField('filehandle', File_Object(), File_Object) 295 ] 296 297 298class FSINFO_Reply(Packet): 299 name = 'FSINFO Reply' 300 fields_desc = [ 301 IntEnumField('status', 0, nfsstat3), 302 IntField('attributes_follow', 0), 303 ConditionalField( 304 PacketField('attributes', Fattr3(), Fattr3), 305 lambda pkt: pkt.attributes_follow == 1 306 ), 307 ConditionalField(IntField('rtmax', 0), lambda pkt: pkt.status == 0), 308 ConditionalField(IntField('rtpref', 0), lambda pkt: pkt.status == 0), 309 ConditionalField(IntField('rtmult', 0), lambda pkt: pkt.status == 0), 310 ConditionalField(IntField('wtmax', 0), lambda pkt: pkt.status == 0), 311 ConditionalField(IntField('wtpref', 0), lambda pkt: pkt.status == 0), 312 ConditionalField(IntField('wtmult', 0), lambda pkt: pkt.status == 0), 313 ConditionalField(IntField('dtpref', 0), lambda pkt: pkt.status == 0), 314 ConditionalField( 315 LongField('maxfilesize', 0), lambda pkt: pkt.status == 0 316 ), 317 ConditionalField( 318 IntField('timedelta_s', 0), lambda pkt: pkt.status == 0 319 ), 320 ConditionalField( 321 IntField('timedelta_ns', 0), lambda pkt: pkt.status == 0 322 ), 323 ConditionalField( 324 XIntField('properties', 0), lambda pkt: pkt.status == 0 325 ), 326 ] 327 328 329bind_layers(RPC, FSINFO_Call, mtype=0) 330bind_layers(RPC, FSINFO_Reply, mtype=1) 331bind_layers( 332 RPC_Call, FSINFO_Call, program=100003, pversion=3, procedure=19 333) 334 335 336class PATHCONF_Call(Packet): 337 name = 'PATHCONF Call' 338 fields_desc = [ 339 PacketField('filehandle', File_Object(), File_Object) 340 ] 341 342 343class PATHCONF_Reply(Packet): 344 name = 'PATHCONF Reply' 345 fields_desc = [ 346 IntEnumField('status', 0, nfsstat3), 347 IntField('attributes_follow', 0), 348 ConditionalField( 349 PacketField('attributes', Fattr3(), Fattr3), 350 lambda pkt: pkt.attributes_follow == 1 351 ), 352 ConditionalField(IntField('linkmax', 0), lambda pkt: pkt.status == 0), 353 ConditionalField(IntField('name_max', 0), lambda pkt: pkt.status == 0), 354 ConditionalField( 355 IntEnumField('no_trunc', 0, {0: 'NO', 1: 'YES'}), 356 lambda pkt: pkt.status == 0 357 ), 358 ConditionalField( 359 IntEnumField('chown_restricted', 0, {0: 'NO', 1: 'YES'}), 360 lambda pkt: pkt.status == 0 361 ), 362 ConditionalField( 363 IntEnumField('case_insensitive', 0, {0: 'NO', 1: 'YES'}), 364 lambda pkt: pkt.status == 0 365 ), 366 ConditionalField( 367 IntEnumField('case_preserving', 0, {0: 'NO', 1: 'YES'}), 368 lambda pkt: pkt.status == 0 369 ) 370 ] 371 372 373bind_layers(RPC, PATHCONF_Call, mtype=0) 374bind_layers(RPC, PATHCONF_Reply, mtype=1) 375bind_layers( 376 RPC_Call, PATHCONF_Call, program=100003, pversion=3, procedure=20 377) 378 379access_specs = { 380 0x0001: 'READ', 381 0x0002: 'LOOKUP', 382 0x0004: 'MODIFY', 383 0x0008: 'EXTEND', 384 0x0010: 'DELETE', 385 0x0020: 'EXECUTE' 386} 387 388 389class ACCESS_Call(Packet): 390 name = 'ACCESS Call' 391 fields_desc = [ 392 PacketField('filehandle', File_Object(), File_Object), 393 IntEnumField('check_access', 1, access_specs) 394 ] 395 396 397class ACCESS_Reply(Packet): 398 name = 'ACCESS Reply' 399 fields_desc = [ 400 IntEnumField('status', 0, nfsstat3), 401 IntField('attributes_follow', 0), 402 ConditionalField( 403 PacketField('attributes', Fattr3(), Fattr3), 404 lambda pkt: pkt.attributes_follow == 1 405 ), 406 ConditionalField( 407 XIntField('access_rights', 0), lambda pkt: pkt.status == 0 408 ) 409 ] 410 411 412bind_layers(RPC, ACCESS_Call, mtype=0) 413bind_layers(RPC, ACCESS_Reply, mtype=1) 414bind_layers(RPC_Call, ACCESS_Call, program=100003, pversion=3, procedure=4) 415 416 417class READDIRPLUS_Call(Packet): 418 name = 'READDIRPLUS Call' 419 fields_desc = [ 420 PacketField('filehandle', File_Object(), File_Object), 421 LongField('cookie', 0), 422 LongField('verifier', 0), 423 IntField('dircount', 512), 424 IntField('maxcount', 4096) 425 ] 426 427 428class READDIRPLUS_Reply(Packet): 429 name = 'READDIRPLUS Reply' 430 fields_desc = [ 431 IntEnumField('status', 0, nfsstat3), 432 IntField('attributes_follow', 0), 433 ConditionalField( 434 PacketField('attributes', Fattr3(), Fattr3), 435 lambda pkt: pkt.attributes_follow == 1 436 ), 437 ConditionalField( 438 LongField('verifier', 0), lambda pkt: pkt.status == 0 439 ), 440 ConditionalField( 441 IntField('value_follows', 0), lambda pkt: pkt.status == 0 442 ), 443 ConditionalField( 444 PacketListField( 445 'files', None, File_From_Dir_Plus, 446 next_cls_cb=lambda pkt, lst, cur, remain: 447 File_From_Dir_Plus if pkt.value_follows == 1 and 448 (len(lst) == 0 or cur.value_follows == 1) and 449 len(remain) > 4 else None 450 ), 451 lambda pkt: pkt.status == 0 452 ), 453 ConditionalField(IntField('eof', 0), lambda pkt: pkt.status == 0) 454 ] 455 456 def extract_padding(self, s): 457 return '', s 458 459 460bind_layers(RPC, READDIRPLUS_Call, mtype=0) 461bind_layers(RPC, READDIRPLUS_Reply, mtype=1) 462bind_layers( 463 RPC_Call, READDIRPLUS_Call, program=100003, pversion=3, procedure=17 464) 465 466 467class WRITE_Call(Packet): 468 name = 'WRITE Call' 469 fields_desc = [ 470 PacketField('filehandle', File_Object(), File_Object), 471 LongField('offset', 0), 472 IntField('count', 0), 473 IntEnumField('stable', 0, {0: 'UNSTABLE', 1: 'STABLE'}), 474 IntField('length', 0), 475 StrLenField('contents', b'', length_from=lambda pkt: pkt.length), 476 StrLenField('fill', b'', length_from=lambda pkt: (4 - pkt.length) % 4) 477 ] 478 479 480class WRITE_Reply(Packet): 481 name = 'WRITE Reply' 482 fields_desc = [ 483 IntEnumField('status', 0, nfsstat3), 484 IntField('af_before', 0), 485 ConditionalField( 486 PacketField('attributes_before', WCC_Attr(), WCC_Attr), 487 lambda pkt: pkt.af_before == 1 488 ), 489 IntField('af_after', 0), 490 ConditionalField( 491 PacketField('attributes_after', Fattr3(), Fattr3), 492 lambda pkt: pkt.af_after == 1 493 ), 494 ConditionalField(IntField('count', 0), lambda pkt: pkt.status == 0), 495 ConditionalField( 496 IntEnumField('committed', 0, {0: 'UNSTABLE', 1: 'STABLE'}), 497 lambda pkt: pkt.status == 0 498 ), 499 ConditionalField( 500 XLongField('verifier', 0), lambda pkt: pkt.status == 0 501 ) 502 ] 503 504 505bind_layers(RPC, WRITE_Call, mtype=0) 506bind_layers(RPC, WRITE_Reply, mtype=1) 507bind_layers(RPC_Call, WRITE_Call, program=100003, pversion=3, procedure=7) 508 509 510class COMMIT_Call(Packet): 511 name = 'COMMIT Call' 512 fields_desc = [ 513 PacketField('filehandle', File_Object(), File_Object), 514 LongField('offset', 0), 515 IntField('count', 0) 516 ] 517 518 519class COMMIT_Reply(Packet): 520 name = 'COMMIT Reply' 521 fields_desc = [ 522 IntEnumField('status', 0, nfsstat3), 523 IntField('af_before', 0), 524 ConditionalField( 525 PacketField('attributes_before', WCC_Attr(), WCC_Attr), 526 lambda pkt: pkt.af_before == 1 527 ), 528 IntField('af_after', 0), 529 ConditionalField( 530 PacketField('attributes_after', Fattr3(), Fattr3), 531 lambda pkt: pkt.af_after == 1 532 ), 533 ConditionalField( 534 XLongField('verifier', 0), lambda pkt: pkt.status == 0 535 ) 536 ] 537 538 539bind_layers(RPC, COMMIT_Call, mtype=0) 540bind_layers(RPC, COMMIT_Reply, mtype=1) 541bind_layers( 542 RPC_Call, COMMIT_Call, program=100003, pversion=3, procedure=21 543) 544 545 546class SETATTR_Call(Packet): 547 name = 'SETATTR Call' 548 fields_desc = [ 549 PacketField('filehandle', File_Object(), File_Object), 550 PacketField('attributes', Sattr3(), Sattr3), 551 IntField('check', 0) 552 ] 553 554 555class SETATTR_Reply(Packet): 556 name = 'SETATTR Reply' 557 fields_desc = [ 558 IntEnumField('status', 0, nfsstat3), 559 IntField('af_before', 0), 560 ConditionalField( 561 PacketField('attributes_before', WCC_Attr(), WCC_Attr), 562 lambda pkt: pkt.af_before == 1 563 ), 564 IntField('af_after', 0), 565 ConditionalField( 566 PacketField('attributes_after', Fattr3(), Fattr3), 567 lambda pkt: pkt.af_after == 1 568 ) 569 ] 570 571 572bind_layers(RPC, SETATTR_Call, mtype=0) 573bind_layers(RPC, SETATTR_Reply, mtype=1) 574bind_layers( 575 RPC_Call, SETATTR_Call, program=100003, pversion=3, procedure=2 576) 577 578 579class FSSTAT_Call(Packet): 580 name = 'FSSTAT Call' 581 fields_desc = [ 582 PacketField('filehandle', File_Object(), File_Object) 583 ] 584 585 586class FSSTAT_Reply(Packet): 587 name = 'FSSTAT Reply' 588 fields_desc = [ 589 IntEnumField('status', 0, nfsstat3), 590 IntField('attributes_follow', 0), 591 ConditionalField( 592 PacketField('attributes', Fattr3(), Fattr3), 593 lambda pkt: pkt.attributes_follow == 1 594 ), 595 ConditionalField(LongField('tbytes', 0), lambda pkt: pkt.status == 0), 596 ConditionalField(LongField('fbytes', 0), lambda pkt: pkt.status == 0), 597 ConditionalField(LongField('abytes', 0), lambda pkt: pkt.status == 0), 598 ConditionalField(LongField('tfiles', 0), lambda pkt: pkt.status == 0), 599 ConditionalField(LongField('ffiles', 0), lambda pkt: pkt.status == 0), 600 ConditionalField(LongField('afiles', 0), lambda pkt: pkt.status == 0), 601 ConditionalField(IntField('invarsec', 0), lambda pkt: pkt.status == 0) 602 ] 603 604 605bind_layers(RPC, FSSTAT_Call, mtype=0) 606bind_layers(RPC, FSSTAT_Reply, mtype=1) 607bind_layers( 608 RPC_Call, FSSTAT_Call, program=100003, pversion=3, procedure=18 609) 610 611 612class CREATE_Call(Packet): 613 name = 'CREATE Call' 614 fields_desc = [ 615 PacketField('dir', File_Object(), File_Object), 616 PacketField('filename', Object_Name(), Object_Name), 617 IntEnumField('create_mode', None, {0: 'UNCHECKED', 618 1: 'GUARDED', 619 2: 'EXCLUSIVE'}), 620 ConditionalField( 621 PacketField('attributes', Sattr3(), Sattr3), 622 lambda pkt: pkt.create_mode != 2 623 ), 624 ConditionalField( 625 XLongField('verifier', 0), lambda pkt: pkt.create_mode == 2 626 ) 627 ] 628 629 630class CREATE_Reply(Packet): 631 name = 'CREATE Reply' 632 fields_desc = [ 633 IntEnumField('status', 0, nfsstat3), 634 ConditionalField( 635 IntField('handle_follows', 0), lambda pkt: pkt.status == 0 636 ), 637 ConditionalField( 638 PacketField('filehandle', File_Object(), File_Object), 639 lambda pkt: pkt.status == 0 and pkt.handle_follows == 1 640 ), 641 ConditionalField( 642 IntField('attributes_follow', 0), lambda pkt: pkt.status == 0 643 ), 644 ConditionalField( 645 PacketField('attributes', Fattr3(), Fattr3), 646 lambda pkt: pkt.status == 0 and pkt.attributes_follow == 1 647 ), 648 IntField('af_before', 0), 649 ConditionalField( 650 PacketField('dir_attributes_before', WCC_Attr(), WCC_Attr), 651 lambda pkt: pkt.af_before == 1 652 ), 653 IntField('af_after', 0), 654 ConditionalField( 655 PacketField('dir_attributes_after', Fattr3(), Fattr3), 656 lambda pkt: pkt.af_after == 1 657 ) 658 ] 659 660 661bind_layers(RPC, CREATE_Call, mtype=0) 662bind_layers(RPC, CREATE_Reply, mtype=1) 663bind_layers(RPC_Call, CREATE_Call, program=100003, pversion=3, procedure=8) 664 665 666class REMOVE_Call(Packet): 667 name = 'REMOVE Call' 668 fields_desc = [ 669 PacketField('dir', File_Object(), File_Object), 670 PacketField('filename', Object_Name(), Object_Name) 671 ] 672 673 674class REMOVE_Reply(Packet): 675 name = 'REMOVE Reply' 676 fields_desc = [ 677 IntEnumField('status', 0, nfsstat3), 678 IntField('af_before', 0), 679 ConditionalField( 680 PacketField('attributes_before', WCC_Attr(), WCC_Attr), 681 lambda pkt: pkt.af_before == 1 682 ), 683 IntField('af_after', 0), 684 ConditionalField( 685 PacketField('attributes_after', Fattr3(), Fattr3), 686 lambda pkt: pkt.af_after == 1 687 ) 688 ] 689 690 691bind_layers(RPC, REMOVE_Call, mtype=0) 692bind_layers(RPC, REMOVE_Reply, mtype=1) 693bind_layers( 694 RPC_Call, REMOVE_Call, program=100003, pversion=3, procedure=12 695) 696 697 698class READDIR_Call(Packet): 699 name = 'READDIR Call' 700 fields_desc = [ 701 PacketField('filehandle', File_Object(), File_Object), 702 LongField('cookie', 0), 703 XLongField('verifier', 0), 704 IntField('count', 0) 705 ] 706 707 708class READDIR_Reply(Packet): 709 name = 'READDIR Reply' 710 fields_desc = [ 711 IntEnumField('status', 0, nfsstat3), 712 IntField('attributes_follow', 0), 713 ConditionalField( 714 PacketField('attributes', Fattr3(), Fattr3), 715 lambda pkt: pkt.attributes_follow == 1 716 ), 717 ConditionalField( 718 XLongField('verifier', 0), lambda pkt: pkt.status == 0 719 ), 720 ConditionalField( 721 IntField('value_follows', 0), lambda pkt: pkt.status == 0 722 ), 723 ConditionalField( 724 PacketListField( 725 'files', None, File_From_Dir, 726 next_cls_cb=lambda pkt, lst, cur, remain: 727 File_From_Dir if pkt.value_follows == 1 and 728 (len(lst) == 0 or cur.value_follows == 1) and 729 len(remain) > 4 else None 730 ), 731 lambda pkt: pkt.status == 0), 732 ConditionalField(IntField('eof', 0), lambda pkt: pkt.status == 0) 733 ] 734 735 736bind_layers(RPC, READDIR_Call, mtype=0) 737bind_layers(RPC, READDIR_Reply, mtype=1) 738bind_layers( 739 RPC_Call, READDIR_Call, program=100003, pversion=3, procedure=16 740) 741 742 743class RENAME_Call(Packet): 744 name = 'RENAME Call' 745 fields_desc = [ 746 PacketField('dir_from', File_Object(), File_Object), 747 PacketField('name_from', Object_Name(), Object_Name), 748 PacketField('dir_to', File_Object(), File_Object), 749 PacketField('name_to', Object_Name(), Object_Name), 750 ] 751 752 753class RENAME_Reply(Packet): 754 name = 'RENAME Reply' 755 fields_desc = [ 756 IntEnumField('status', 0, nfsstat3), 757 IntField('af_before_f', 0), 758 ConditionalField( 759 PacketField('attributes_before_f', WCC_Attr(), WCC_Attr), 760 lambda pkt: pkt.af_before_f == 1 761 ), 762 IntField('af_after_f', 0), 763 ConditionalField( 764 PacketField('attributes_after_f', Fattr3(), Fattr3), 765 lambda pkt: pkt.af_after_f == 1 766 ), 767 IntField('af_before_t', 0), 768 ConditionalField( 769 PacketField('attributes_before_t', WCC_Attr(), WCC_Attr), 770 lambda pkt: pkt.af_before_t == 1 771 ), 772 IntField('af_after_t', 0), 773 ConditionalField( 774 PacketField('attributes_after_t', Fattr3(), Fattr3), 775 lambda pkt: pkt.af_after_t == 1 776 ) 777 ] 778 779 780bind_layers(RPC, RENAME_Call, mtype=0) 781bind_layers(RPC, RENAME_Reply, mtype=1) 782bind_layers( 783 RPC_Call, RENAME_Call, program=100003, pversion=3, procedure=14 784) 785 786 787class LINK_Call(Packet): 788 name = 'LINK Call' 789 fields_desc = [ 790 PacketField('filehandle', File_Object(), File_Object), 791 PacketField('link_dir', File_Object(), File_Object), 792 PacketField('link_name', Object_Name(), Object_Name) 793 ] 794 795 796class LINK_Reply(Packet): 797 name = 'LINK Reply' 798 fields_desc = [ 799 IntEnumField('status', 0, nfsstat3), 800 IntField('af_file', 0), 801 ConditionalField( 802 PacketField('file_attributes', Fattr3(), Fattr3), 803 lambda pkt: pkt.af_file == 1 804 ), 805 IntField('af_link_before', 0), 806 ConditionalField( 807 PacketField('link_attributes_before', WCC_Attr(), WCC_Attr), 808 lambda pkt: pkt.af_link_before == 1 809 ), 810 IntField('af_link_after', 0), 811 ConditionalField( 812 PacketField('link_attributes_after', Fattr3(), Fattr3), 813 lambda pkt: pkt.af_link_after == 1 814 ) 815 ] 816 817 818bind_layers(RPC, LINK_Call, mtype=0) 819bind_layers(RPC, LINK_Reply, mtype=1) 820bind_layers(RPC_Call, LINK_Call, program=100003, pversion=3, procedure=15) 821 822 823class RMDIR_Call(Packet): 824 name = 'RMDIR Call' 825 fields_desc = [ 826 PacketField('dir', File_Object(), File_Object), 827 PacketField('filename', Object_Name(), Object_Name), 828 ] 829 830 831class RMDIR_Reply(Packet): 832 name = 'RMDIR Reply' 833 fields_desc = [ 834 IntEnumField('status', 0, nfsstat3), 835 IntField('af_before', 0), 836 ConditionalField( 837 PacketField('attributes_before', WCC_Attr(), WCC_Attr), 838 lambda pkt: pkt.af_before == 1 839 ), 840 IntField('af_after', 0), 841 ConditionalField( 842 PacketField('attributes_after', Fattr3(), Fattr3), 843 lambda pkt: pkt.af_after == 1 844 ) 845 ] 846 847 848bind_layers(RPC, RMDIR_Call, mtype=0) 849bind_layers(RPC, RMDIR_Reply, mtype=1) 850bind_layers(RPC_Call, RMDIR_Call, program=100003, pversion=3, procedure=13) 851 852 853class READLINK_Call(Packet): 854 name = 'READLINK Call' 855 fields_desc = [ 856 PacketField('filehandle', File_Object(), File_Object) 857 ] 858 859 860class READLINK_Reply(Packet): 861 name = 'READLINK Reply' 862 fields_desc = [ 863 IntEnumField('status', 0, nfsstat3), 864 IntField('attributes_follow', 0), 865 ConditionalField( 866 PacketField('attributes', Fattr3(), Fattr3), 867 lambda pkt: pkt.attributes_follow == 1 868 ), 869 ConditionalField( 870 PacketField('filename', Object_Name(), Object_Name), 871 lambda pkt: pkt.status == 0 872 ) 873 ] 874 875 876bind_layers(RPC, READLINK_Call, mtype=0) 877bind_layers(RPC, READLINK_Reply, mtype=1) 878bind_layers( 879 RPC_Call, READLINK_Call, program=100003, pversion=3, procedure=5 880) 881 882 883class READ_Call(Packet): 884 name = 'READ Call' 885 fields_desc = [ 886 PacketField('filehandle', File_Object(), File_Object), 887 LongField('offset', 0), 888 IntField('count', 0) 889 ] 890 891 892class READ_Reply(Packet): 893 name = 'READ Reply' 894 fields_desc = [ 895 IntEnumField('status', 0, nfsstat3), 896 IntField('attributes_follow', 0), 897 ConditionalField( 898 PacketField('attributes', Fattr3(), Fattr3), 899 lambda pkt: pkt.attributes_follow == 1 900 ), 901 ConditionalField(IntField('count', 0), lambda pkt: pkt.status == 0), 902 ConditionalField(IntField('eof', 0), lambda pkt: pkt.status == 0), 903 ConditionalField( 904 IntField('data_length', 0), lambda pkt: pkt.status == 0 905 ), 906 ConditionalField( 907 StrLenField('data', b'', length_from=lambda pkt: pkt.data_length), 908 lambda pkt: pkt.status == 0 909 ), 910 ConditionalField( 911 StrLenField( 912 'fill', b'', length_from=lambda pkt: (4 - pkt.data_length) % 4 913 ), 914 lambda pkt: pkt.status == 0 915 ) 916 ] 917 918 919bind_layers(RPC, READ_Call, mtype=0) 920bind_layers(RPC, READ_Reply, mtype=1) 921bind_layers(RPC_Call, READ_Call, program=100003, pversion=3, procedure=6) 922 923 924class MKDIR_Call(Packet): 925 name = 'MKDIR Call' 926 fields_desc = [ 927 PacketField('dir', File_Object(), File_Object), 928 PacketField('dir_name', Object_Name(), Object_Name), 929 PacketField('attributes', Sattr3(), Sattr3) 930 ] 931 932 933class MKDIR_Reply(Packet): 934 name = 'MKDIR Reply' 935 fields_desc = [ 936 IntEnumField('status', 0, nfsstat3), 937 ConditionalField( 938 IntField('handle_follows', 0), lambda pkt: pkt.status == 0 939 ), 940 ConditionalField( 941 PacketField('filehandle', File_Object(), File_Object), 942 lambda pkt: pkt.status == 0 and pkt.handle_follows == 1 943 ), 944 ConditionalField( 945 IntField('attributes_follow', 0), lambda pkt: pkt.status == 0 946 ), 947 ConditionalField( 948 PacketField('attributes', Fattr3(), Fattr3), 949 lambda pkt: pkt.status == 0 and pkt.attributes_follow == 1 950 ), 951 IntField('af_before', 0), 952 ConditionalField( 953 PacketField('dir_attributes_before', WCC_Attr(), WCC_Attr), 954 lambda pkt: pkt.af_before == 1 955 ), 956 IntField('af_after', 0), 957 ConditionalField( 958 PacketField('dir_attributes_after', Fattr3(), Fattr3), 959 lambda pkt: pkt.af_after == 1 960 ) 961 ] 962 963 964bind_layers(RPC, MKDIR_Call, mtype=0) 965bind_layers(RPC, MKDIR_Reply, mtype=1) 966bind_layers(RPC_Call, MKDIR_Call, program=100003, pversion=3, procedure=9) 967 968 969class SYMLINK_Call(Packet): 970 name = 'SYMLINK Call' 971 fields_desc = [ 972 PacketField('dir', File_Object(), File_Object), 973 PacketField('dir_name', Object_Name(), Object_Name), 974 PacketField('attributes', Sattr3(), Sattr3), 975 PacketField('link_name', Object_Name(), Object_Name) 976 ] 977 978 979class SYMLINK_Reply(Packet): 980 name = 'SYMLINK Reply' 981 fields_desc = [ 982 IntEnumField('status', 0, nfsstat3), 983 ConditionalField( 984 IntField('handle_follows', 0), lambda pkt: pkt.status == 0 985 ), 986 ConditionalField( 987 PacketField('filehandle', File_Object(), File_Object), 988 lambda pkt: pkt.status == 0 and pkt.handle_follows == 1 989 ), 990 ConditionalField( 991 IntField('attributes_follow', 0), lambda pkt: pkt.status == 0 992 ), 993 ConditionalField( 994 PacketField('attributes', Fattr3(), Fattr3), 995 lambda pkt: pkt.status == 0 and pkt.attributes_follow == 1 996 ), 997 IntField('af_before', 0), 998 ConditionalField( 999 PacketField('dir_attributes_before', WCC_Attr(), WCC_Attr), 1000 lambda pkt: pkt.af_before == 1 1001 ), 1002 IntField('af_after', 0), 1003 ConditionalField( 1004 PacketField('dir_attributes_after', Fattr3(), Fattr3), 1005 lambda pkt: pkt.af_after == 1 1006 ) 1007 ] 1008 1009 1010bind_layers(RPC, SYMLINK_Call, mtype=0) 1011bind_layers(RPC, SYMLINK_Reply, mtype=1) 1012bind_layers( 1013 RPC_Call, SYMLINK_Call, program=100003, pversion=3, procedure=10 1014) 1015