Package rekall :: Package plugins :: Package linux :: Module arp
[frames] | no frames]

Source Code for Module rekall.plugins.linux.arp

  1  # Rekall Memory Forensics 
  2  # 
  3  # Copyright 2013 Google Inc. All Rights Reserved. 
  4  # 
  5  # This program is free software; you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation; either version 2 of the License, or (at 
  8  # your option) any later version. 
  9  # 
 10  # This program is distributed in the hope that it will be useful, but 
 11  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 13  # General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License 
 16  # along with this program; if not, write to the Free Software 
 17  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 18   
 19  """ 
 20  @author:       Andrew Case 
 21  @license:      GNU General Public License 2.0 or later 
 22  @contact:      atcuno@gmail.com 
 23  @organization: Digital Forensics Solutions 
 24  """ 
 25  from rekall import obj 
 26  from rekall.plugins.linux import common 
 27   
 28   
 29  arp_overlay = { 
 30      'neigh_table': [None, { 
 31          # From /include/linux/socket.h 
 32          'family': [None, ['Enumeration', dict( 
 33              choices={ 
 34                  0: "AF_UNSPEC", 
 35                  1: "AF_UNIX", 
 36                  2: "AF_INET", 
 37                  10: "AF_INET6", 
 38                  }, 
 39              target="unsigned int", 
 40              )]] 
 41          }], 
 42      'neighbour': [None, { 
 43          "ha": [None, ["Array", dict( 
 44              target="byte", 
 45              count=lambda x: x.dev.addr_len)]], 
 46          }], 
 47      } 
48 49 50 -class ArpModification(obj.ProfileModification):
51 @classmethod
52 - def modify(cls, profile):
54
55 56 -class Arp(common.LinuxPlugin):
57 """print the ARP table.""" 58 59 # This plugin seems broken now. 60 __name = "arp" 61 62 table_header = [ 63 dict(name="ip", width=45, align="r"), 64 dict(name="mac", width=20, align="r"), 65 dict(name="dev", width=15, align="r") 66 ] 67
68 - def __init__(self, **kwargs):
69 super(Arp, self).__init__(**kwargs) 70 self.profile = ArpModification(self.profile)
71
72 - def get_handle_tables(self):
73 # In earlier Linux neigh_table is a linked list. 74 if self.session.profile.neigh_table().m("next") != None: 75 tables = self.profile.get_constant_object( 76 "neigh_tables", 77 target="Pointer", 78 target_args=dict( 79 target="neigh_table" 80 ) 81 ) 82 83 for table in tables.walk_list("next"): 84 for x in self.handle_table(table): 85 yield x 86 87 # But since 3.19 it is an array of pointers to neigh_tables. 88 # http://lxr.free-electrons.com/source/net/core/neighbour.c?v=3.19#L1517 89 # static struct neigh_table *neigh_tables[NEIGH_NR_TABLES] 90 # NEIGH_NR_TABLES is in an enum and it is 3. 91 else: 92 tables = self.profile.get_constant_object( 93 "neigh_tables", 94 target="Array", 95 target_args=dict( 96 target="Pointer", 97 count=3, 98 target_args=dict( 99 target="neigh_table" 100 ) 101 ) 102 ) 103 104 for table in tables: 105 for x in self.handle_table(table): 106 yield x
107
108 - def handle_table(self, ntable):
109 # Support a few ways of finding these parameters depending on kernel 110 # versions. 111 hash_size = (ntable.m("hash_mask") or 112 ntable.nht.m("hash_mask") or 113 1 << ntable.nht.hash_shift) 114 115 hash_table = ntable.m("hash_buckets") or ntable.nht.hash_buckets 116 117 buckets = self.profile.Array(offset=hash_table, 118 vm=self.kernel_address_space, 119 target='Pointer', count=hash_size, 120 target_args=dict(target="neighbour")) 121 122 for neighbour in buckets: 123 if neighbour: 124 for x in self.walk_neighbour(neighbour.deref()): 125 yield x
126
127 - def walk_neighbour(self, neighbour):
128 while 1: 129 # get the family from each neighbour in order to work with IPv4 and 130 # IPv6. 131 family = neighbour.tbl.family 132 133 if family == "AF_INET": 134 ip = neighbour.primary_key.cast("Ipv4Address") 135 136 elif family == "AF_INET6": 137 ip = neighbour.primary_key.cast("Ipv6Address") 138 else: 139 ip = '?' 140 141 mac = ":".join(["%.02x" % x for x in neighbour.ha]) 142 devname = neighbour.dev.name 143 144 yield dict(ip=ip, mac=mac, dev=devname) 145 146 neighbour = neighbour.next.deref() 147 148 if not neighbour: 149 break
150
151 - def collect(self):
152 for x in self.get_handle_tables(): 153 yield x
154