1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-05 14:09:02 +00:00

Merge r18534:r18591 from nmap-exp/djalal/nse-nfs/

This commit is contained in:
djalal
2010-07-06 00:29:54 +00:00
parent 0347e05487
commit 53b2b629dc
2 changed files with 296 additions and 48 deletions

View File

@@ -1,21 +1,22 @@
description = [[
Retrieves disk space statistics from the remote NFS share
Retrieves disk space statistics and information from the remote NFS
share. This script will try to emulate the behaviour of the "df" tool.
The script will provide pathconf information of the remote NFS if
the version used is NFSv3.
]]
---
-- @output
-- PORT STATE SERVICE
-- | nfs-statfs:
-- | /home/storage/backup
-- | Block size: 512
-- | Total blocks: 1901338728
-- | Free blocks: 729769328
-- | Available blocks: 633186880
-- | /home
-- | Block size: 512
-- | Total blocks: 1901338728
-- | Free blocks: 729769328
-- |_ Available blocks: 633186880
-- | nfs-statfs:
-- |
-- | Filesystem 1K-blocks Used Available Use% Blocksize
-- | /mnt/nfs/files 5542276 2732012 2528728 52% 4096
-- |_ /mnt/nfs/opensource 5534416 620640 4632644 12% 4096
--
-- @args nfs-statfs.human If set to '1' or 'true' shows the filesystem
-- size in the human readable format.
--
-- Version 0.3
@@ -23,43 +24,185 @@ Retrieves disk space statistics from the remote NFS share
-- Created 01/25/2010 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
-- Revised 02/22/2010 - v0.2 - adapted to support new RPC library
-- Revised 03/13/2010 - v0.3 - converted host to port rule
-- Revised 06/28/2010 - v0.4 - added NFSv3 support and doc
author = "Patrik Karlsson"
author = "Patrik Karlsson, Djalal Harouni"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"discovery", "safe"}
require("shortport")
require("rpc")
require("tab")
portrule = shortport.port_or_service(111, "rpcbind", {"tcp", "udp"} )
action = function(host, port)
local result, entry = {}, {}
local status, mounts = rpc.Helper.ShowMounts( host, port )
if ( not(status) ) then
return stdnse.format_output(false, mounts)
end
for _, v in ipairs( mounts ) do
local entry = {}
local status, stats = rpc.Helper.ExportStats(host, port, v.name)
entry.name = v.name
if (not(status)) then
table.insert(entry, string.format("ERROR: %s", stats))
else
table.insert( entry, string.format("Block size: %d", stats.block_size) )
table.insert( entry, string.format("Total blocks: %d", stats.total_blocks) )
table.insert( entry, string.format("Free blocks: %d", stats.free_blocks) )
table.insert( entry, string.format("Available blocks: %d", stats.available_blocks) )
end
table.insert( result, entry )
end
return stdnse.format_output( true, result )
local function table_fsstat(nfs, mount, stats)
local fs, err = rpc.Util.calc_fsstat_table(stats, nfs.version, nfs.human)
if fs == nil then
return false, err
end
fs.filesystem = string.format("%s", mount)
return true, fs
end
local function table_fsinfo(nfs, fsinfo)
local ret = {}
local fs, err = rpc.Util.calc_fsinfo_table(fsinfo, nfs.version, nfs.human)
if fs == nil then
return false, err
end
ret.maxfilesize = fs.maxfilesize
return true, ret
end
local function table_pathconf(nfs, pconf)
local ret = {}
local fs, err = rpc.Util.calc_pathconf_table(pconf, nfs.version)
if fs == nil then
return false, err
end
ret.linkmax = fs.linkmax
return true, ret
end
local function report(nfs, tables)
local outtab, tab_size, tab_avail
local tab_filesys, tab_used, tab_use,
tab_bs, tab_maxfs, tab_linkmax = " Filesystem",
"Used", "Use%", "Blocksize", "Maxfilesize", "Maxlink"
if nfs.human then
tab_size = "Size"
tab_avail = "Avail"
else
tab_size = "1K-blocks"
tab_avail = "Available"
end
if nfs.version == 2 then
outtab = tab.new(6)
tab.nextrow(outtab)
tab.addrow(outtab, tab_filesys, tab_size, tab_used,
tab_avail, tab_use, tab_bs)
for _, t in ipairs(tables) do
tab.nextrow(outtab)
tab.addrow(outtab, (" %s"):format(t.filesystem), t.size,
t.used, t.available, t.use, t.bsize)
end
elseif nfs.version == 3 then
outtab = tab.new(7)
tab.nextrow(outtab)
tab.addrow(outtab, tab_filesys, tab_size, tab_used,
tab_avail, tab_use, tab_maxfs, tab_linkmax)
for _, t in ipairs(tables) do
tab.nextrow(outtab)
tab.addrow(outtab, (" %s"):format(t.filesystem), t.size,
t.used, t.available, t.use, t.maxfilesize,
t.linkmax)
end
end
return tab.dump(outtab)
end
local function nfs_filesystem_info(nfs, mount, filesystem)
local results, res, status = {}, {}
local nfsobj = rpc.NFS:new()
local mnt_comm, nfs_comm, fhandle
mnt_comm, fhandle = rpc.Helper.MountPath(nfs.host, nfs.port, mount)
if mnt_comm == nil then
return false, fhandle
end
local nfs_comm, status = rpc.Helper.NfsOpen(nfs.host, nfs.port)
if nfs_comm == nil then
rpc.Helper.UnmountPath(mnt_comm, mount)
return false, status
end
nfs.version = nfs_comm.version
-- use simple check since NFSv1 is not used anymore.
if (mnt_comm.version ~= nfs_comm.version) then
rpc.Helper.UnmountPath(mnt_comm, mount)
return false, string.format("versions mismatch, nfs v%d - mount v%d",
nfs_comm.version, mnt_comm.version)
end
if nfs_comm.version < 3 then
status, res = nfsobj:StatFs(nfs_comm, fhandle)
elseif nfs_comm.version == 3 then
status, res = nfsobj:FsStat(nfs_comm, fhandle)
end
if status then
status, res = table_fsstat(nfs, mount, res)
if status then
for k, v in pairs(res) do
results[k] = v
end
end
if nfs_comm.version == 3 then
status, res = nfsobj:FsInfo(nfs_comm, fhandle)
if status then
status, res = table_fsinfo(nfs, res)
if status then
for k, v in pairs(res) do
results[k] = v
end
end
end
status, res = nfsobj:PathConf(nfs_comm, fhandle)
if status then
status, res = table_pathconf(nfs, res)
if status then
for k, v in pairs(res) do
results[k] = v
end
end
end
end
end
rpc.Helper.NfsClose(nfs_comm)
rpc.Helper.UnmountPath(mnt_comm, mount)
if (not(status)) then
return status, res
end
table.insert(filesystem, results)
return true, nil
end
action = function(host, port)
local o, fs_info, mounts, status = {}, {}, {}, {}
local nfs_info =
{
host = host,
port = port,
human = nmap.registry.args['nfs-statfs.human'] or nil,
}
status, mounts = rpc.Helper.ShowMounts( host, port )
if (not(status)) then
return stdnse.format_output(false, mounts)
end
for _, v in ipairs(mounts) do
local err
status, err = nfs_filesystem_info(nfs_info, v.name, fs_info)
if (not(status)) then
return stdnse.format_output(false, err)
end
end
table.insert(o, report(nfs_info, fs_info))
return stdnse.format_output(true, o)
end