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 Lock Manager (NLM) v4 7# scapy.contrib.status = loads 8 9from scapy.contrib.oncrpc import RPC, RPC_Call, Object_Name 10from scapy.packet import Packet, bind_layers 11from scapy.fields import IntField, StrLenField, LongField, PacketField, \ 12 IntEnumField 13from scapy.contrib.nfs import File_Object 14 15nlm4_stats = { 16 0: 'NLM4_GRANTED', 17 1: 'NLM4_DENIED', 18 2: 'NLM4_DENIED_NOLOCKS', 19 3: 'NLM4_BLOCKED', 20 4: 'NLM4_DENIED_GRACE_PERIOD', 21 5: 'NLM4_DEADLCK', 22 6: 'NLM4_ROFS', 23 7: 'NLM4_STALE_FH', 24 8: 'NLM4_FBIG', 25 9: 'NLM4_FAILED' 26} 27 28 29class NLM4_Cookie(Packet): 30 name = 'Cookie' 31 fields_desc = [ 32 IntField('length', 0), 33 StrLenField('contents', '', length_from=lambda pkt: pkt.length), 34 StrLenField('fill', b'', length_from=lambda pkt: (4 - pkt.length) % 4) 35 ] 36 37 def set(self, c, length=None, fill=None): 38 if length is None: 39 length = len(c) 40 if fill is None: 41 fill = b'\x00' * ((4 - len(c)) % 4) 42 self.length = length 43 self.contents = c 44 self.fill = fill 45 46 def extract_padding(self, s): 47 return '', s 48 49 50class SHARE_Call(Packet): 51 name = 'SHARE Call' 52 fields_desc = [ 53 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 54 PacketField('caller', Object_Name(), Object_Name), 55 PacketField('filehandle', File_Object(), File_Object), 56 PacketField('owner', Object_Name(), Object_Name), 57 IntField('mode', 0), 58 IntField('access', 0), 59 IntEnumField('reclaim', 0, {0: 'NO', 1: 'YES'}) 60 ] 61 62 63class SHARE_Reply(Packet): 64 name = 'SHARE Reply' 65 fields_desc = [ 66 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 67 IntEnumField('status', 0, nlm4_stats), 68 IntField('sequence', 0) 69 ] 70 71 72bind_layers(RPC_Call, SHARE_Call, program=100021, pversion=4, procedure=20) 73bind_layers(RPC, SHARE_Call, mtype=0) 74bind_layers(RPC, SHARE_Reply, mtype=1) 75 76 77class UNSHARE_Call(Packet): 78 name = 'UNSHARE Reply' 79 fields_desc = [ 80 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 81 PacketField('caller', Object_Name(), Object_Name), 82 PacketField('filehandle', File_Object(), File_Object), 83 PacketField('owner', Object_Name(), Object_Name), 84 IntField('mode', 0), 85 IntField('access', 0), 86 IntEnumField('reclaim', 0, {0: 'NO', 1: 'YES'}) 87 ] 88 89 90class UNSHARE_Reply(Packet): 91 name = 'UNSHARE Reply' 92 fields_desc = [ 93 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 94 IntEnumField('status', 0, nlm4_stats), 95 IntField('sequence', 0) 96 ] 97 98 99bind_layers( 100 RPC_Call, UNSHARE_Call, program=100021, pversion=4, procedure=21 101) 102bind_layers(RPC, UNSHARE_Call, mtype=0) 103bind_layers(RPC, UNSHARE_Reply, mtype=1) 104 105 106class LOCK_Call(Packet): 107 name = 'LOCK Call' 108 fields_desc = [ 109 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 110 IntEnumField('block', 0, {0: 'NO', 1: 'YES'}), 111 IntEnumField('exclusive', 0, {0: 'NO', 1: 'YES'}), 112 PacketField('caller', Object_Name(), Object_Name), 113 PacketField('filehandle', File_Object(), File_Object), 114 PacketField('owner', Object_Name(), Object_Name), 115 IntField('svid', 0), 116 LongField('l_offset', 0), 117 LongField('l_len', 0), 118 IntField('reclaim', 0), 119 IntField('state', 0) 120 ] 121 122 123class LOCK_Reply(Packet): 124 name = 'LOCK Reply' 125 fields_desc = [ 126 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 127 IntEnumField('status', 0, nlm4_stats) 128 ] 129 130 131bind_layers(RPC_Call, LOCK_Call, program=100021, pversion=4, procedure=2) 132bind_layers(RPC, LOCK_Call, mtype=0) 133bind_layers(RPC, LOCK_Reply, mtype=1) 134 135 136class UNLOCK_Call(Packet): 137 name = 'UNLOCK Call' 138 fields_desc = [ 139 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 140 PacketField('caller', Object_Name(), Object_Name), 141 PacketField('filehandle', File_Object(), File_Object), 142 PacketField('owner', Object_Name(), Object_Name), 143 IntField('svid', 0), 144 LongField('l_offset', 0), 145 LongField('l_len', 0) 146 ] 147 148 149class UNLOCK_Reply(Packet): 150 name = 'UNLOCK Reply' 151 fields_desc = [ 152 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 153 IntEnumField('status', 0, nlm4_stats) 154 ] 155 156 157bind_layers(RPC_Call, UNLOCK_Call, program=100021, pversion=4, procedure=4) 158bind_layers(RPC, UNLOCK_Call, mtype=0) 159bind_layers(RPC, UNLOCK_Reply, mtype=1) 160 161 162class GRANTED_MSG_Call(Packet): 163 name = 'GRANTED_MSG Call' 164 fields_desc = [ 165 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 166 IntEnumField('exclusive', 0, {0: 'NO', 1: 'YES'}), 167 PacketField('caller', Object_Name(), Object_Name), 168 PacketField('filehandle', File_Object(), File_Object), 169 PacketField('owner', Object_Name(), Object_Name), 170 IntField('svid', 0), 171 LongField('l_offset', 0), 172 LongField('l_len', 0) 173 ] 174 175 176class GRANTED_MSG_Reply(Packet): 177 name = 'GRANTED_MSG Reply' 178 fields_desc = [] 179 180 181bind_layers( 182 RPC_Call, GRANTED_MSG_Call, program=100021, pversion=4, procedure=10 183) 184bind_layers(RPC, GRANTED_MSG_Call, mtype=0) 185bind_layers(RPC, GRANTED_MSG_Reply, mtype=1) 186 187 188class GRANTED_RES_Call(Packet): 189 name = 'GRANTED_RES Call' 190 fields_desc = [ 191 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 192 IntEnumField('status', 0, nlm4_stats) 193 ] 194 195 196class GRANTED_RES_Reply(Packet): 197 name = 'GRANTED_RES Reply' 198 fields_desc = [] 199 200 201bind_layers( 202 RPC_Call, GRANTED_RES_Call, program=100021, pversion=4, procedure=15 203) 204bind_layers(RPC, GRANTED_RES_Call, mtype=0) 205bind_layers(RPC, GRANTED_RES_Reply, mtype=1) 206 207 208class CANCEL_Call(Packet): 209 name = 'CANCEL Call' 210 fields_desc = [ 211 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 212 IntEnumField('block', 0, {0: 'NO', 1: 'YES'}), 213 IntEnumField('exclusive', 0, {0: 'NO', 1: 'YES'}), 214 PacketField('caller', Object_Name(), Object_Name), 215 PacketField('filehandle', File_Object(), File_Object), 216 PacketField('owner', Object_Name(), Object_Name), 217 IntField('svid', 0), 218 LongField('l_offset', 0), 219 LongField('l_len', 0) 220 ] 221 222 223class CANCEL_Reply(Packet): 224 name = 'CANCEL Reply' 225 fields_desc = [ 226 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 227 IntEnumField('status', 0, nlm4_stats) 228 ] 229 230 231bind_layers(RPC_Call, CANCEL_Call, program=100021, pversion=4, procedure=3) 232bind_layers(RPC, CANCEL_Call, mtype=0) 233bind_layers(RPC, CANCEL_Reply, mtype=1) 234 235 236class TEST_Call(Packet): 237 name = 'TEST Call' 238 fields_desc = [ 239 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 240 IntEnumField('exclusive', 0, {0: 'NO', 1: 'YES'}), 241 PacketField('caller', Object_Name(), Object_Name), 242 PacketField('filehandle', File_Object(), File_Object), 243 PacketField('owner', Object_Name(), Object_Name), 244 IntField('svid', 0), 245 LongField('l_offset', 0), 246 LongField('l_len', 0) 247 ] 248 249 250class TEST_Reply(Packet): 251 name = 'TEST Reply' 252 fields_desc = [ 253 PacketField('cookie', NLM4_Cookie(), NLM4_Cookie), 254 IntEnumField('status', 0, nlm4_stats) 255 ] 256 257 258bind_layers(RPC_Call, TEST_Call, program=100021, pversion=4, procedure=1) 259bind_layers(RPC, TEST_Call, mtype=0) 260bind_layers(RPC, TEST_Reply, mtype=1) 261