1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-06 22:49:02 +00:00

Nmap 3.98BETA1

This commit is contained in:
fyodor
2006-01-21 23:57:49 +00:00
parent 3ed6bb8785
commit 76acd0a496
20 changed files with 192 additions and 1825 deletions

View File

@@ -1,10 +1,5 @@
# Nmap Changelog ($Id$); -*-text-*-
o The 26 Nmap commands that previously included an underscore
(--max_rtt_timeout, --senc_eth, --host_timeout, etc.) have been
renamed to use a hyphen in the preferred format
(i.e. --max-rtt-timeout). Underscores are still supported for
backwared compatability.
3.98BETA1
o Added run time interaction as documented at
http://www.insecure.org/nmap/man/man-runtime-interaction.html .
@@ -39,9 +34,35 @@ o Added the --badsum option, which causes Nmap to use invalid TCP or
author of that paper, Ed3f (ed3f(a)antifork.org), is also the author
of this patch.
o The 26 Nmap commands that previously included an underscore
(--max_rtt_timeout, --send_eth, --host_timeout, etc.) have been
renamed to use a hyphen in the preferred format
(i.e. --max-rtt-timeout). Underscores are still supported for
backwared compatability.
o More excellent NmapFE patches from Priit Laes (amd(a)store20.com)
were applied to remove deprecated GTK API calls which could cause
compilation failures and also "Gtk-CRITICAL" warning messages.
were applied to remove all deprecated GTK API calls. This also
eliminates the annoying Gtk-Critical and Gtk-WARNING runtime messages.
o Changed the way the __attribute__ compiler extension is detected so
that it works with the latest Fedora Core 4 updates (and perhaps other
systems). Thanks to Duilio Protti (dprotti(a)fceia.unr.edu.ar) for
writing the patch. The compilation error message this fixes was
usually something like: "nmap.o(.rodata+0x17c): undefined reference
to `__gthrw_pthread_cancel(unsigned long)"
o Added some exception handling code to mswin32/winfix.cc to prevent
Nmap from crashing mysteriously when you have WinPcap 3.0 or earlier
(instead of the required 3.1). It now prints an error message instead
asking you to upgrade, then reduces functionality to connect()-only
mode.
o Stripped the firewall API out of the libdnet included with Nmap
because Nmap doesn't use it anyway. This saves space and reduces the
likelyhood of compilation errors and warnings.
o Modified the previously useless --noninteractive option so that it
deactivates runtime interaction.
3.96BETA1

View File

@@ -1,4 +1,4 @@
export NMAP_VERSION = 3.97Shmoo
export NMAP_VERSION = 3.98BETA1
NMAP_NAME= Nmap
NMAP_URL= http://www.insecure.org/nmap/
NMAP_PLATFORM=@host@

View File

@@ -250,6 +250,7 @@ void NmapOps::Initialize() {
mass_dns = true;
resolve_all = 0;
dns_servers = NULL;
noninteractive = false;
}
bool NmapOps::TCPScan() {

View File

@@ -292,6 +292,7 @@ class NmapOps {
int numhosts_up;
int numhosts_scanning;
stype scantype;
bool noninteractive;
private:
int max_rtt_timeout;

View File

@@ -2,7 +2,7 @@
.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1).
.\" Instead of manually editing it, you probably should edit the DocBook XML
.\" source for it and then use the DocBook XSL Stylesheets to regenerate it.
.TH "NMAP" "1" "01/12/2006" "" "Nmap Reference Guide"
.TH "NMAP" "1" "01/21/2006" "" "Nmap Reference Guide"
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
@@ -122,31 +122,31 @@ PORT SPECIFICATION AND SCAN ORDER:
\-r: Scan ports consecutively \- don't randomize
SERVICE/VERSION DETECTION:
\-sV: Probe open ports to determine service/version info
\-\-version_light: Limit to most likely probes for faster identification
\-\-version_all: Try every single probe for version detection
\-\-version_trace: Show detailed version scan activity (for debugging)
\-\-version\-light: Limit to most likely probes for faster identification
\-\-version\-all: Try every single probe for version detection
\-\-version\-trace: Show detailed version scan activity (for debugging)
OS DETECTION:
\-O: Enable OS detection
\-\-osscan_limit: Limit OS detection to promising targets
\-\-osscan_guess: Guess OS more aggressively
\-\-osscan\-limit: Limit OS detection to promising targets
\-\-osscan\-guess: Guess OS more aggressively
TIMING AND PERFORMANCE:
\-T[0\-5]: Set timing template (higher is faster)
\-\-min_hostgroup/max_hostgroup <size>: Parallel host scan group sizes
\-\-min_parallelism/max_parallelism <msec>: Probe parallelization
\-\-min_rtt_timeout/max_rtt_timeout/initial_rtt_timeout <msec>: Specifies
\-\-min\-hostgroup/max\-hostgroup <size>: Parallel host scan group sizes
\-\-min\-parallelism/max\-parallelism <msec>: Probe parallelization
\-\-min_rtt_timeout/max\-rtt\-timeout/initial\-rtt\-timeout <msec>: Specifies
probe round trip time.
\-\-max_retries <tries>: Caps number of port scan probe retransmissions.
\-\-host_timeout <msec>: Give up on target after this long
\-\-scan_delay/\-\-max_scan_delay <msec>: Adjust delay between probes
\-\-max\-retries <tries>: Caps number of port scan probe retransmissions.
\-\-host\-timeout <msec>: Give up on target after this long
\-\-scan\-delay/\-\-max_scan\-delay <msec>: Adjust delay between probes
FIREWALL/IDS EVASION AND SPOOFING:
\-f; \-\-mtu <val>: fragment packets (optionally w/given MTU)
\-D <decoy1,decoy2[,ME],...>: Cloak a scan with decoys
\-S <IP_Address>: Spoof source address
\-e <iface>: Use specified interface
\-g/\-\-source_port <portnum>: Use given port number
\-\-data_length <num>: Append random data to sent packets
\-g/\-\-source\-port <portnum>: Use given port number
\-\-data\-length <num>: Append random data to sent packets
\-\-ttl <val>: Set IP time\-to\-live field
\-\-spoof_mac <mac address/prefix/vendor name>: Spoof your MAC address
\-\-spoof\-mac <mac address/prefix/vendor name>: Spoof your MAC address
\-\-badsum: Send packets with a bogus TCP/UDP checksum
OUTPUT:
\-oN/\-oX/\-oS/\-oG <file>: Output scan in normal, XML, s|<rIpt kIddi3,
@@ -154,9 +154,9 @@ OUTPUT:
\-oA <basename>: Output in the three major formats at once
\-v: Increase verbosity level (use twice for more effect)
\-d[level]: Set or increase debugging level (Up to 9 is meaningful)
\-\-packet_trace: Show all packets sent and received
\-\-packet\-trace: Show all packets sent and received
\-\-iflist: Print host interfaces and routes (for debugging)
\-\-append_output: Append to rather than clobber specified output files
\-\-append\-output: Append to rather than clobber specified output files
\-\-resume <filename>: Resume an aborted scan
\-\-stylesheet <path/URL>: XSL stylesheet to transform XML output to HTML
\-\-webxml: Reference stylesheet from Insecure.Org for more portable XML
@@ -165,7 +165,7 @@ MISC:
\-6: Enable IPv6 scanning
\-A: Enables OS detection and Version detection
\-\-datadir <dirname>: Specify custom Nmap data file location
\-\-send_eth/\-\-send_ip: Send using raw ethernet frames or IP packets
\-\-send\-eth/\-\-send\-ip: Send using raw ethernet frames or IP packets
\-\-privileged: Assume that the user is fully privileged
\-V: Print version number
\-h: Print this help summary page.
@@ -265,7 +265,7 @@ The
option sends an ICMP echo request and a TCP packet to port 80 by default. When executed by an unprivileged user, a SYN packet is sent (using a
\fBconnect()\fR
call) to port 80 on the target. When a privileged user tries to scan targets on a local ethernet network, ARP requests (\fB\-PR\fR) are used unless
\fB\-\-send_ip\fR
\fB\-\-send\-ip\fR
was specified. The
\fB\-sP\fR
option can be combined with any of the discovery probe types (the
@@ -315,7 +315,7 @@ and
.TP
\fB\-PU [portlist]\fR (UDP Ping)
Another host discovery option is the UDP ping, which sends an empty (unless
\fB\-\-data_length\fR
\fB\-\-data\-length\fR
is specified) UDP packet to the given ports. The portlist takes the same format as with the previously discussed
\fB\-PS\fR
and
@@ -349,7 +349,7 @@ ARP scan puts Nmap and its optimized algorithms in charge of ARP requests. And i
\fB\-PE\fR
or
\fB\-PS\fR) are specified, Nmap uses ARP instead for any of the targets which are on the same LAN. If you absolutely don't want to do an ARP scan, specify
\fB\-\-send_ip\fR.
\fB\-\-send\-ip\fR.
.TP
\fB\-n\fR (No DNS resolution)
Tells Nmap to
@@ -453,7 +453,7 @@ A big challenge with UDP scanning is doing it quickly. Open and filtered ports r
\fInet/ipv4/icmp.c\fR).
.sp
Nmap detects rate limiting and slows down accordingly to avoid flooding the network with useless packets that the target machine will drop. Unfortunately, a Linux\-style limit of one packet per second makes a 65,536\-port scan take more than 18 hours. Ideas for speeding your UDP scans up include scanning more hosts in parallel, doing a quick scan of just the popular ports first, scanning from behind the firewall, and using
\fB\-\-host_timeout\fR
\fB\-\-host\-timeout\fR
to skip slow hosts.
.TP
\fB\-sN\fR; \fB\-sF\fR; \fB\-sX\fR (TCP Null, FIN, and Xmas scans)
@@ -679,22 +679,22 @@ to scan all ports regardless of any
Exclude
directive.
.TP
\fB\-\-version_intensity <intensity>\fR (Set version scan intensity)
\fB\-\-version\-intensity <intensity>\fR (Set version scan intensity)
When performing a version scan (\fB\-sV\fR), nmap sends a series of probes, each of which is assigned a rarity value between 1 and 9. The lower\-numbered probes are effective against a wide variety of common services, while the higher numbered ones are rarely useful. The intensity level specifies which probes should be applied. The higher the number, the more likely it is the service will be correctly identified. However, high intensity scans take longer. The intensity must be between 0 and 9. The default is 7. When a probe is registered to the target port via the
\fInmap\-service\-probes\fRports
directive, that probe is tried regardless of intensity level. This ensures that the DNS probes will always be attempted against any open port 53, the SSL probe will be done against 443, etc.
.TP
\fB\-\-version_light\fR (Enablie light mode)
\fB\-\-version\-light\fR (Enablie light mode)
This is a convenience alias for
\fB\-\-version_intensity 2\fR. This light mode makes version scanning much faster, but it is slightly less likely to identify services.
\fB\-\-version\-intensity 2\fR. This light mode makes version scanning much faster, but it is slightly less likely to identify services.
.TP
\fB\-\-version_all\fR (Try every single probe)
\fB\-\-version\-all\fR (Try every single probe)
An alias for
\fB\-\-version_intensity 9\fR, ensuring that every single probe is attempted against each port.
\fB\-\-version\-intensity 9\fR, ensuring that every single probe is attempted against each port.
.TP
\fB\-\-version_trace\fR (Trace version scan activity)
\fB\-\-version\-trace\fR (Trace version scan activity)
This causes Nmap to print out extensive debugging info about what version scanning is doing. It is a subset of what you get with
\fB\-\-packet_trace\fR.
\fB\-\-packet\-trace\fR.
.TP
\fB\-sR\fR (RPC scan)
This method works in conjunction with the various port scan methods of Nmap. It takes all the TCP/UDP ports found open and floods them with SunRPC program NULL commands in an attempt to determine whether they are RPC ports, and if so, what program and version number they serve up. Thus you can effectively obtain the same info as
@@ -728,7 +728,7 @@ Enables OS detection, as discussed above. Alternatively, you can use
\fB\-A\fR
to enable both OS detection and version detection.
.TP
\fB\-\-osscan_limit\fR (Limit OS detection to promising targets)
\fB\-\-osscan\-limit\fR (Limit OS detection to promising targets)
OS detection is far more effective if at least one open and one closed TCP port are found. Set this option and Nmap will not even try OS detection against hosts that do not meet this criteria. This can save substantial time, particularly on
\fB\-P0\fR
scans against many hosts. It only matters when OS detection is requested with
@@ -736,7 +736,7 @@ scans against many hosts. It only matters when OS detection is requested with
or
\fB\-A\fR.
.TP
\fB\-\-osscan_guess\fR; \fB\-\-fuzzy\fR (Guess OS detection results)
\fB\-\-osscan\-guess\fR; \fB\-\-fuzzy\fR (Guess OS detection results)
When Nmap is unable to detect a perfect OS match, it sometimes offers up near\-matches as possibilities. The match has to be very close for Nmap to do this by default. Either of these (equivalent) options make Nmap guess more aggressively.
.SH "TIMING AND PERFORMANCE"
.PP
@@ -744,32 +744,32 @@ One of my highest Nmap development priorities has always been performance. A def
.PP
Techniques for improving scan times include omitting non\-critical tests, and upgrading to the latest version of Nmap (performance enhancements are made frequently). Optimizing timing parameters can also make a substantial difference. Those options are listed below.
.TP
\fB\-\-min_hostgroup <numhosts>\fR; \fB\-\-max_hostgroup <numhosts>\fR (Adjust parallel scan group sizes)
\fB\-\-min\-hostgroup <numhosts>\fR; \fB\-\-max\-hostgroup <numhosts>\fR (Adjust parallel scan group sizes)
Nmap has the ability to port scan or version scan multiple hosts in parallel. Nmap does this by dividing the target IP space into groups and then scanning one group at a time. In general, larger groups are more efficient. The downside is that host results can't be provided until the whole group is finished. So if Nmap started out with a group size of 50, the user would not receive any reports (except for the updates offered in verbose mode) until the first 50 hosts are completed.
.sp
By default, Nmap takes a compromise approach to this conflict. It starts out with a group size as low as five so the first results come quickly and then increases the groupsize to as high as 1024. The exact default numbers depend on the options given. For efficiency reasons, Nmap uses larger group sizes for UDP or few\-port TCP scans.
.sp
When a maximum group size is specified with
\fB\-\-max_hostgroup\fR, Nmap will never exceed that size. Specify a minimum size with
\fB\-\-min_hostgroup\fR
\fB\-\-max\-hostgroup\fR, Nmap will never exceed that size. Specify a minimum size with
\fB\-\-min\-hostgroup\fR
and Nmap will try to keep group sizes above that level. Nmap may have to use smaller groups than you specify if there are not enough target hosts left on a given interface to fulfill the specified minimum. Both may be set to keep the group size within a specific range, though this is rarely desired.
.sp
The primary use of these options is to specify a large minimum group size so that the full scan runs more quickly. A common choice is 256 to scan a network in Class C sized chunks. For a scan with many ports, exceeding that number is unlikely to help much. For scans of just a few port numbers, host group sizes of 2048 or more may be helpful.
.TP
\fB\-\-min_parallelism <numprobes>\fR; \fB\-\-max_parallelism <numprobes>\fR (Adjust probe parallelization)
\fB\-\-min\-parallelism <numprobes>\fR; \fB\-\-max\-parallelism <numprobes>\fR (Adjust probe parallelization)
These options control the total number of probes that may be outstanding for a host group. They are used for port scanning and host discovery. By default, Nmap calculates an ever\-changing ideal parallelism based on network performance. If packets are being dropped, Nmap slows down and allows fewer outstanding probes. The ideal probe number slowly rises as the network proves itself worthy. These options place minimum or maximum bounds on that variable. By default, the ideal parallelism can drop to 1 if the network proves unreliable and rise to several hundred in perfect conditions.
.sp
The most common usage is to set
\fB\-\-min_parallelism\fR
\fB\-\-min\-parallelism\fR
to a number higher than one to speed up scans of poorly performing hosts or networks. This is a risky option to play with, as setting it too high may affect accuracy. Setting this also reduces Nmap's ability to control parallelism dynamically based on network conditions. A value of ten might be reasonable, though I only adjust this value as a last resort.
.sp
The
\fB\-\-max_parallelism\fR
\fB\-\-max\-parallelism\fR
option is sometimes set to one to prevent Nmap from sending more than one probe at a time to hosts. This can be useful in combination with
\fB\-\-scan_delay\fR
\fB\-\-scan\-delay\fR
(discussed later), although the latter usually serves the purpose well enough by itself.
.TP
\fB\-\-min_rtt_timeout <time>\fR, \fB\-\-max_rtt_timeout <time>\fR, \fB\-\-initial_rtt_timeout <time>\fR (Adjust probe timeouts)
\fB\-\-min_rtt_timeout <time>\fR, \fB\-\-max\-rtt\-timeout <time>\fR, \fB\-\-initial\-rtt\-timeout <time>\fR (Adjust probe timeouts)
Nmap maintains a running timeout value for determining how long it will wait for a probe response before giving up or retransmitting the probe. This is calculated based on the response times of previous probes. If the network latency shows itself to be significant and variable, this timeout can grow to several seconds. It also starts at a conservative (high) level and may stay that way for a while when Nmap scans unresponsive hosts.
.sp
These options take a value in milliseconds, or you can append
@@ -777,39 +777,39 @@ s,
m, or
h
to the argument to specify a time in seconds, minutes, or hours. Specifying a lower
\fB\-\-max_rtt_timeout\fR
\fB\-\-max\-rtt\-timeout\fR
and
\fB\-\-initial_rtt_timeout\fR
\fB\-\-initial\-rtt\-timeout\fR
than the defaults can cut scan times significantly. This is particularly true for pingless (\fB\-P0\fR) scans, and those against heavily filtered networks. Don't get too aggressive though. The scan can end up taking longer if you specify such a low value that many probes are timing out and retransmitting while the response is in transit.
.sp
If all the hosts are on a local network, 100 milliseconds is a reasonable aggressive
\fB\-\-max_rtt_timeout\fR
\fB\-\-max\-rtt\-timeout\fR
value. If routing is involved, ping a host on the network first with the ICMP ping utility, or with a custom packet crafter such as hping2 that is more likely to get through a firewall. Look at the maximum round trip time out of ten packets or so. You might want to double that for the
\fB\-\-initial_rtt_timeout\fR
\fB\-\-initial\-rtt\-timeout\fR
and triple or quadruple it for the
\fB\-\-max_rtt_timeout\fR. I generally do not set the maximum rtt below 100ms, no matter what the ping times are. Nor do I exceed 1000ms.
\fB\-\-max\-rtt\-timeout\fR. I generally do not set the maximum rtt below 100ms, no matter what the ping times are. Nor do I exceed 1000ms.
.sp
\fB\-\-min_rtt_timeout\fR
is a rarely used option that could be useful when a network is so unreliable that even Nmap's default is too aggressive. Since Nmap only reduces the timeout down to the minimum when the network seems to be reliable, this need is unusual and should be reported as a bug to the nmap\-dev mailing list.
.TP
\fB\-\-max_retries <numtries>\fR (Specify the maximum number of port scan probe retransmissions)
\fB\-\-max\-retries <numtries>\fR (Specify the maximum number of port scan probe retransmissions)
When Nmap receives no response to a port scan probe, it could mean the port is filtered. Or maybe the probe or response was simply lost on the network. It is also possible that the target host has rate limiting enabled that temporarily blocked the response. So Nmap tries again by retransmitting the initial probe. If Nmap detects poor network reliability, it may try many more times before giving up on a port. While this benefits accuracy, it also lengthen scan times. When performance is critical, scans may be sped up by limiting the number of retransmissions allowed. You can even specify
\fB\-\-max_retries 0\fR
\fB\-\-max\-retries 0\fR
to prevent any retransmissions, though that is rarely recommended.
.sp
The default (with no
\fB\-T\fR
template) is to allow ten retransmissions. If a network seems reliable and the target hosts aren't rate limiting, Nmap usually only does one retransmission. So most target scans aren't even affected by dropping
\fB\-\-max_retries\fR
\fB\-\-max\-retries\fR
to a low value such as three. Such values can substantially speed scans of slow (rate limited) hosts. You usually lose some information when Nmap gives up on ports early, though that may be preferable to letting the
\fB\-\-host_timeout\fR
\fB\-\-host\-timeout\fR
expire and losing all information about the target.
.TP
\fB\-\-host_timeout <time>\fR (Give up on slow target hosts)
\fB\-\-host\-timeout <time>\fR (Give up on slow target hosts)
Some hosts simply take a
\fIlong\fR
time to scan. This may be due to poorly performing or unreliable networking hardware or software, packet rate limiting, or a restrictive firewall. The slowest few percent of the scanned hosts can eat up a majority of the scan time. Sometimes it is best to cut your losses and skip those hosts initially. This can be done by specifying
\fB\-\-host_timeout\fR
\fB\-\-host\-timeout\fR
with the number of milliseconds you are willing to wait. Alternatively, you can append
s,
m, or
@@ -818,23 +818,23 @@ to the argument to specify a timeout in seconds, minutes, or hours. I often spec
30m
to ensure that Nmap doesn't waste more than half an hour on a single host. Note that Nmap may be scanning other hosts at the same time during that half an hour as well, so it isn't a complete loss. A host that times out is skipped. No port table, OS detection, or version detection results are printed for that host.
.TP
\fB\-\-scan_delay <time>\fR; \fB\-\-max_scan_delay <time>\fR (Adjust delay between probes)
\fB\-\-scan\-delay <time>\fR; \fB\-\-max_scan\-delay <time>\fR (Adjust delay between probes)
This option causes Nmap to wait at least the given number of milliseconds between each probe it sends to a given host. As with many other timing options, you can append
s,
m, or
h
to the argument to specify a delay in seconds, minutes, or hours instead. This is particularly useful in the case of rate limiting. Solaris machines (among many others) will usually respond to UDP scan probe packets with only one ICMP message per second. Any more than that sent by Nmap will be wasteful. A
\fB\-\-scan_delay\fR
\fB\-\-scan\-delay\fR
of
1s
will keep Nmap at that slow rate. Nmap tries to detect rate limiting and adjust the scan delay accordingly, but it doesn't hurt to specify it explicitly if you already know what rate works best.
.sp
When Nmap adjusts the scan delay upward to cope with rate limiting, the scan slows down dramatically. The
\fB\-\-max_scan_delay\fR
\fB\-\-max_scan\-delay\fR
option specifies the largest delay that Nmap will allow. Setting this value too low can lead to wasteful packet retransmissions and possible missed ports when the target implements strict rate limiting.
.sp
Another use of
\fB\-\-scan_delay\fR
\fB\-\-scan\-delay\fR
is to evade threshold based intrusion detection and prevention systems (IDS/IPS).
.TP
\fB\-T <Paranoid|Sneaky|Polite|Normal|Aggressive|Insane>\fR (Set a timing template)
@@ -882,11 +882,11 @@ are similar but they only wait 15 seconds and 0.4 seconds, respectively, between
is Nmap's default behavior, which includes parallelization.
\fBT4\fR
does the equivalent of
\fB\-\-max_rtt_timeout 1250 \-\-initial_rtt_timeout 500 \-\-max_retries 6\fR
\fB\-\-max\-rtt\-timeout 1250 \-\-initial\-rtt\-timeout 500 \-\-max\-retries 6\fR
and sets the maximum TCP scan delay to 10 milliseconds.
\fBT5\fR
does the equivalent of
\fB\-\-max_rtt_timeout 300 \-\-min_rtt_timeout 50 \-\-initial_rtt_timeout 250 \-\-max_retries 2 \-\-host_timeout 900000\fR
\fB\-\-max\-rtt\-timeout 300 \-\-min_rtt_timeout 50 \-\-initial\-rtt\-timeout 250 \-\-max\-retries 2 \-\-host\-timeout 900000\fR
as well as setting the maximum TCP scan delay to 5ms.
.SH "FIREWALL/IDS EVASION AND SPOOFING"
.PP
@@ -913,7 +913,7 @@ option. Don't also specify
\fB\-f\fR
if you use
\fB\-\-mtu\fR. The offset must be a multiple of 8. While fragmented packets won't get by packet filters and firewalls that queue all IP fragments, such as the CONFIG_IP_ALWAYS_DEFRAG option in the Linux kernel, some networks can't afford the performance hit this causes and thus leave it disabled. Others can't enable this because fragments may take different routes into their networks. Some source systems defragment outgoing packets in the kernel. Linux with the iptables connection tracking module is one such example. Do a scan while a sniffer such as Ethereal is running to ensure that sent packets are fragmented. If your host OS is causing problems, try the
\fB\-\-send_eth\fR
\fB\-\-send\-eth\fR
option to bypass the IP layer and send raw ethernet frames.
.TP
\fB\-D <decoy1 [,decoy2][,ME],...>\fR (Cloak a scan with decoys)
@@ -948,7 +948,7 @@ would normally be advisable as well.
\fB\-e <interface>\fR (Use specified interface)
Tells Nmap what interface to send and receive packets on. Nmap should be able to detect this automatically, but it will tell you if it cannot.
.TP
\fB\-\-source_port <portnumber>;\fR \fB\-g <portnumber>\fR (Spoof source port number)
\fB\-\-source\-port <portnumber>;\fR \fB\-g <portnumber>\fR (Spoof source port number)
One surprisingly common misconfiguration is to trust traffic based only on the source port number. It is easy to understand how this comes about. An administrator will set up a shiny new firewall, only to be flooded with complains from ungrateful users whose applications stopped working. In particular, DNS may be broken because the UDP DNS replies from external servers can no longer enter the network. FTP is another common example. In active FTP transfers, the remote server tries to establish a connection back to the client to transfer the requested file.
.sp
Secure solutions to these problems exist, often in the form of application\-level proxies or protocol\-parsing firewall modules. Unfortunately there are also easier, insecure solutions. Noting that DNS replies come from port 53 and active ftp from port 20, many admins have fallen into the trap of simply allowing incoming traffic from those ports. They often assume that no attacker would notice and exploit such firewall holes. In other cases, admins consider this a short\-term stop\-gap measure until they can implement a more secure solution. Then they forget the security upgrade.
@@ -958,31 +958,31 @@ Overworked network administrators are not the only ones to fall into this trap.
Nmap offers the
\fB\-g\fR
and
\fB\-\-source_port\fR
\fB\-\-source\-port\fR
options (they are equivalent) to exploit these weaknesses. Simply provide a port number and Nmap will send packets from that port where possible. Nmap must use different port numbers for certain OS detection tests to work properly, and DNS requests ignore the
\fB\-\-source_port\fR
\fB\-\-source\-port\fR
flag because Nmap relies on system libraries to handle those. Most TCP scans, including SYN scan, support the option completely, as does UDP scan.
.TP
\fB\-\-data_length <number>\fR (Append random data to sent packets)
\fB\-\-data\-length <number>\fR (Append random data to sent packets)
Normally Nmap sends minimalist packets containing only a header. So its TCP packets are generally 40 bytes and ICMP echo requests are just 28. This option tells Nmap to append the given number of random bytes to most of the packets it sends. OS detection (\fB\-O\fR) packets are not affected, but most pinging and portscan packets are. This slows things down, but can make a scan slightly less conspicuous.
.TP
\fB\-\-ttl <value>\fR (Set IP time\-to\-live field)
Sets the IPv4 time\-to\-live field in sent packets to the given value.
.TP
\fB\-\-randomize_hosts\fR (Randomize target host order)
\fB\-\-randomize\-hosts\fR (Randomize target host order)
Tells Nmap to shuffle each group of up to 8096 hosts before it scans them. This can make the scans less obvious to various network monitoring systems, especially when you combine it with slow timing options. If you want to randomize over larger group sizes, increase PING_GROUP_SZ in
\fInmap.h\fR
and recompile. An alternative solution is to generate the target IP list with a list scan (\fB\-sL \-n \-oN \fR\fB\fIfilename\fR\fR), randomize it with a Perl script, then provide the whole list to Nmap with
\fB\-iL\fR.
.TP
\fB\-\-spoof_mac <mac address, prefix, or vendor name>\fR (Spoof MAC address)
\fB\-\-spoof\-mac <mac address, prefix, or vendor name>\fR (Spoof MAC address)
Asks Nmap to use the given MAC address for all of the raw ethernet frames it sends. This option implies
\fB\-\-send_eth\fR
\fB\-\-send\-eth\fR
to ensure that Nmap actually sends ethernet\-level packets. The MAC given can take several formats. If it is simply the string
\(lq0\(rq, Nmap chooses a completely random MAC for the session. If the given string is an even number of hex digits (with the pairs optionally separated by a colon), Nmap will use those as the MAC. If less than 12 hex digits are provided, Nmap fills in the remainder of the 6 bytes with random values. If the argument isn't a 0 or hex string, Nmap looks through
\fInmap\-mac\-prefixes\fR
to find a vendor name containing the given string (it is case insensitive). If a match is found, Nmap uses the vendor's OUI (3\-byte prefix) and fills out the remaining 3 bytes randomly. Valid
\fB\-\-spoof_mac\fR
\fB\-\-spoof\-mac\fR
argument examples are
Apple,
0,
@@ -1131,10 +1131,10 @@ sets level nine. That is the highest effective level and will produce thousands
Debugging output is useful when a bug is suspected in Nmap, or if you are simply confused as to what Nmap is doing and why. As this feature is mostly intended for developers, debug lines aren't always self\-explanatory. You may get something like:
Timeout vals: srtt: \-1 rttvar: \-1 to: 1000000 delta 14987 ==> srtt: 14987 rttvar: 14987 to: 100000. If you don't understand a line, your only recourses are to ignore it, look it up in the source code, or request help from the development list (nmap\-dev). Some lines are self explanatory, but the messages become more obscure as the debug level is increased.
.TP
\fB\-\-packet_trace\fR (Trace packets and data sent and received)
\fB\-\-packet\-trace\fR (Trace packets and data sent and received)
Causes Nmap to print a summary of every packet sent or received. This is often used for debugging, but is also a valuable way for new users to understand exactly what Nmap is doing under the covers. To avoid printing thousands of lines, you may want to specify a limited number of ports to scan, such as
\fB\-p20\-30\fR. If you only care about the goings on of the version detection subsystem, use
\fB\-\-version_trace\fR
\fB\-\-version\-trace\fR
instead.
.TP
\fB\-\-iflist\fR (List interfaces and routes)
@@ -1142,12 +1142,12 @@ Prints the interface list and system routes as detected by Nmap. This is useful
.PP
\fBMiscellaneous output options\fR
.TP
\fB\-\-append_output\fR (Append to rather than clobber output files)
\fB\-\-append\-output\fR (Append to rather than clobber output files)
When you specify a filename to an output format flag such as
\fB\-oX\fR
or
\fB\-oN\fR, that file is overwritten by default. If you prefer to keep the existing content of the file and append the new results, specify the
\fB\-\-append_output\fR
\fB\-\-append\-output\fR
option. All output filenames specified in that Nmap execution will then be appended to rather than clobbered. This doesn't work well for XML (\fB\-oX\fR) scan data as the resultant file generally won't parse properly until you fix it up by hand.
.TP
\fB\-\-resume <filename>\fR (Resume aborted scan)
@@ -1218,10 +1218,10 @@ or
\fI/usr/share/nmap\fR
. As a last resort, Nmap will look in the current directory.
.TP
\fB\-\-send_eth\fR (Use raw ethernet sending)
\fB\-\-send\-eth\fR (Use raw ethernet sending)
Asks Nmap to send packets at the raw ethernet (data link) layer rather than the higher IP (network) layer. By default, Nmap chooses the one which is generally best for the platform it is running on. Raw sockets (IP layer) are generally most efficient for UNIX machines, while ethernet frames are required for Windows operation since Microsoft disabled raw socket support. Nmap still uses raw IP packets on UNIX despite this option when there is no other choice (such as non\-ethernet connections).
.TP
\fB\-\-send_ip\fR (Send at raw IP level)
\fB\-\-send\-ip\fR (Send at raw IP level)
Asks Nmap to send packets via raw IP sockets rather than sending lower level ethernet frames. It is the complement to the
\fB\-\-send\-eth\fR
option discussed previously.
@@ -1239,6 +1239,13 @@ to activate this mode and then type
h
for help. This option is rarely used because proper shells are usually more familiar and feature\-complete. This option includes a bang (!) operator for executing shell commands, which is one of many reasons not to install Nmap setuid root.
.TP
\fB\-\-noninteractive\fR (For running Nmap from a program)
This option may be specified when Nmap is run by a program rather than an actual user watching the screen directly. The only difference at this time is that Runtime Interaction (described in
the section called \(lqRUNTIME INTERACTION\(rq) is disabled. Despite the confusingly similar name, this option is
\fInot\fR
simply the opposite of
\fB\-\-interactive\fR.
.TP
\fB\-V\fR; \fB\-\-version\fR (Print version number)
Prints the Nmap version number and exits.
.TP
@@ -1258,7 +1265,9 @@ During the execution of nmap, all key presses are captured. This allows you to i
\fIlowercase letters increase\fR
the amount of printing, and
\fIuppercase letters decrease\fR
the printing.
the printing. This functionality can be disabled by specifying the
\fB\-\-noninteractive\fR
option.
.TP
\fBv\fR / \fBV\fR
Increase / Decrease the Verbosity
@@ -1313,10 +1322,6 @@ since first sending a couple probes to determine whether a host is up is wastefu
\fBnmap \-P0 \-p80 \-oX logs/pb\-port80scan.xml \-oG logs/pb\-port80scan.gnmap 216.163.128.20/20\fR
.PP
This scans 4096 IPs for any webservers (without pinging them) and saves the output in grepable and XML formats.
.PP
\fBhost \-l company.com | cut \-d \-f 4 | nmap \-v \-iL \-\fR
.PP
Do a DNS zone transfer to find the hosts in company.com and then feed the IP addresses to nmap. The above commands are for my GNU/Linux box \-\- other systems have different commands for performing a zone transfer.
.SH "BUGS"
.PP
Like its author, Nmap isn't perfect. But you can help make it better by sending bug reports or even writing patches. If Nmap doesn't behave the way you expect, first upgrade to the latest version available from

View File

@@ -1,4 +1,4 @@
Nmap 3.97Shmoo ( http://www.insecure.org/nmap/ )
Nmap 3.98BETA1 ( http://www.insecure.org/nmap/ )
Usage: nmap [Scan Type(s)] [Options] {target specification}
TARGET SPECIFICATION:
Can pass hostnames, IP addresses, networks, etc.
@@ -14,8 +14,8 @@ HOST DISCOVERY:
-PS/PA/PU [portlist]: TCP SYN/ACK or UDP discovery to given ports
-PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes
-n/-R: Never do DNS resolution/Always resolve [default: sometimes]
--dns_servers <serv1[,serv2],...>: Specify custom DNS servers
--system_dns: Use OS's DNS resolver
--dns-servers <serv1[,serv2],...>: Specify custom DNS servers
--system-dns: Use OS's DNS resolver
SCAN TECHNIQUES:
-sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans
-sN/sF/sX: TCP Null, FIN, and Xmas scans
@@ -30,32 +30,32 @@ PORT SPECIFICATION AND SCAN ORDER:
-r: Scan ports consecutively - don't randomize
SERVICE/VERSION DETECTION:
-sV: Probe open ports to determine service/version info
--version_intensity <level>: Set from 0 (light) to 9 (try all probes)
--version_light: Limit to most likely probes (intensity 2)
--version_all: Try every single probe (intensity 9)
--version_trace: Show detailed version scan activity (for debugging)
--version-intensity <level>: Set from 0 (light) to 9 (try all probes)
--version-light: Limit to most likely probes (intensity 2)
--version-all: Try every single probe (intensity 9)
--version-trace: Show detailed version scan activity (for debugging)
OS DETECTION:
-O: Enable OS detection
--osscan_limit: Limit OS detection to promising targets
--osscan_guess: Guess OS more aggressively
--osscan-limit: Limit OS detection to promising targets
--osscan-guess: Guess OS more aggressively
TIMING AND PERFORMANCE:
-T[0-5]: Set timing template (higher is faster)
--min_hostgroup/max_hostgroup <size>: Parallel host scan group sizes
--min_parallelism/max_parallelism <msec>: Probe parallelization
--min_rtt_timeout/max_rtt_timeout/initial_rtt_timeout <msec>: Specifies
--min-hostgroup/max-hostgroup <size>: Parallel host scan group sizes
--min-parallelism/max-parallelism <msec>: Probe parallelization
--min-rtt-timeout/max-rtt-timeout/initial-rtt-timeout <msec>: Specifies
probe round trip time.
--max_retries <tries>: Caps number of port scan probe retransmissions.
--host_timeout <msec>: Give up on target after this long
--scan_delay/--max_scan_delay <msec>: Adjust delay between probes
--max-retries <tries>: Caps number of port scan probe retransmissions.
--host-timeout <msec>: Give up on target after this long
--scan-delay/--max-scan-delay <msec>: Adjust delay between probes
FIREWALL/IDS EVASION AND SPOOFING:
-f; --mtu <val>: fragment packets (optionally w/given MTU)
-D <decoy1,decoy2[,ME],...>: Cloak a scan with decoys
-S <IP_Address>: Spoof source address
-e <iface>: Use specified interface
-g/--source_port <portnum>: Use given port number
--data_length <num>: Append random data to sent packets
-g/--source-port <portnum>: Use given port number
--data-length <num>: Append random data to sent packets
--ttl <val>: Set IP time-to-live field
--spoof_mac <mac address/prefix/vendor name>: Spoof your MAC address
--spoof-mac <mac address/prefix/vendor name>: Spoof your MAC address
--badsum: Send packets with a bogus TCP/UDP checksum
OUTPUT:
-oN/-oX/-oS/-oG <file>: Output scan in normal, XML, s|<rIpt kIddi3,
@@ -63,18 +63,18 @@ OUTPUT:
-oA <basename>: Output in the three major formats at once
-v: Increase verbosity level (use twice for more effect)
-d[level]: Set or increase debugging level (Up to 9 is meaningful)
--packet_trace: Show all packets sent and received
--packet-trace: Show all packets sent and received
--iflist: Print host interfaces and routes (for debugging)
--append_output: Append to rather than clobber specified output files
--append-output: Append to rather than clobber specified output files
--resume <filename>: Resume an aborted scan
--stylesheet <path/URL>: XSL stylesheet to transform XML output to HTML
--webxml: Reference stylesheet from Insecure.Org for more portable XML
--no_stylesheet: Prevent associating of XSL stylesheet w/XML output
--no-stylesheet: Prevent associating of XSL stylesheet w/XML output
MISC:
-6: Enable IPv6 scanning
-A: Enables OS detection and Version detection
--datadir <dirname>: Specify custom Nmap data file location
--send_eth/--send_ip: Send using raw ethernet frames or IP packets
--send-eth/--send-ip: Send using raw ethernet frames or IP packets
--privileged: Assume that the user is fully privileged
-V: Print version number
-h: Print this help summary page.

View File

@@ -9,6 +9,9 @@ o Removed the following directories:
o Removed all filenames from EXTRA_libdnet_la_SOURCES sources, as
they aren't needed with GNU automake 1.9.2
o Removed the fw-* files except for fw-none because Nmap doesn't use
the firewall API. Changed configure.in to always use fw-non.
o Removed files in now-removed dires that were reference from
configure.in:318

View File

@@ -22590,83 +22590,7 @@ esac
fi
if test "$ac_cv_header_Iphlpapi_h" = yes ; then
case $LIBOBJS in
"fw-pktfilter.$ac_objext" | \
*" fw-pktfilter.$ac_objext" | \
"fw-pktfilter.$ac_objext "* | \
*" fw-pktfilter.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS fw-pktfilter.$ac_objext" ;;
esac
elif test "$ac_cv_header_net_pfvar_h" = yes ; then
case $LIBOBJS in
"fw-pf.$ac_objext" | \
*" fw-pf.$ac_objext" | \
"fw-pf.$ac_objext "* | \
*" fw-pf.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS fw-pf.$ac_objext" ;;
esac
elif test "$ac_cv_header_netinet_ip_fw_h" = yes ; then
case "$host_os" in
*freebsd5* | *kfreebsd*)
case $LIBOBJS in
"fw-none.$ac_objext" | \
*" fw-none.$ac_objext" | \
"fw-none.$ac_objext "* | \
*" fw-none.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS fw-none.$ac_objext" ;;
esac
;;
*)
case $LIBOBJS in
"fw-ipfw.$ac_objext" | \
*" fw-ipfw.$ac_objext" | \
"fw-ipfw.$ac_objext "* | \
*" fw-ipfw.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS fw-ipfw.$ac_objext" ;;
esac
;;
esac
elif test "$ac_cv_header_netinet_ip_fil_h" = yes ; then
case $LIBOBJS in
"fw-ipf.$ac_objext" | \
*" fw-ipf.$ac_objext" | \
"fw-ipf.$ac_objext "* | \
*" fw-ipf.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS fw-ipf.$ac_objext" ;;
esac
elif test "$ac_cv_header_linux_ip_fw_h" = yes ; then
case $LIBOBJS in
"fw-ipchains.$ac_objext" | \
*" fw-ipchains.$ac_objext" | \
"fw-ipchains.$ac_objext "* | \
*" fw-ipchains.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS fw-ipchains.$ac_objext" ;;
esac
elif test "$ac_cv_header_linux_ip_fwchains_h" = yes ; then
case $LIBOBJS in
"fw-ipchains.$ac_objext" | \
*" fw-ipchains.$ac_objext" | \
"fw-ipchains.$ac_objext "* | \
*" fw-ipchains.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS fw-ipchains.$ac_objext" ;;
esac
elif test "$ac_cv_header_linux_netfilter_ipv4_ipchains_core_h" = yes ; then
case $LIBOBJS in
"fw-ipchains.$ac_objext" | \
*" fw-ipchains.$ac_objext" | \
"fw-ipchains.$ac_objext "* | \
*" fw-ipchains.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS fw-ipchains.$ac_objext" ;;
esac
else
case $LIBOBJS in
case $LIBOBJS in
"fw-none.$ac_objext" | \
*" fw-none.$ac_objext" | \
"fw-none.$ac_objext "* | \
@@ -22674,7 +22598,6 @@ else
*) LIBOBJS="$LIBOBJS fw-none.$ac_objext" ;;
esac
fi
if test "$ac_cv_header_Iphlpapi_h" = yes ; then
case $LIBOBJS in

View File

@@ -240,30 +240,9 @@ else
AC_LIBOBJ([eth-none])
fi
dnl Check for firewall interface.
if test "$ac_cv_header_Iphlpapi_h" = yes ; then
AC_LIBOBJ([fw-pktfilter])
elif test "$ac_cv_header_net_pfvar_h" = yes ; then
AC_LIBOBJ([fw-pf])
elif test "$ac_cv_header_netinet_ip_fw_h" = yes ; then
dnl XXX - ipfw2 support later...
case "$host_os" in
*freebsd5* | *kfreebsd*)
AC_LIBOBJ([fw-none]) ;;
*)
AC_LIBOBJ([fw-ipfw]) ;;
esac
elif test "$ac_cv_header_netinet_ip_fil_h" = yes ; then
AC_LIBOBJ([fw-ipf])
elif test "$ac_cv_header_linux_ip_fw_h" = yes ; then
AC_LIBOBJ([fw-ipchains])
elif test "$ac_cv_header_linux_ip_fwchains_h" = yes ; then
AC_LIBOBJ([fw-ipchains])
elif test "$ac_cv_header_linux_netfilter_ipv4_ipchains_core_h" = yes ; then
AC_LIBOBJ([fw-ipchains])
else
AC_LIBOBJ([fw-none])
fi
dnl Using fw-none since Nmap doesn't need any of the firewall-related rules
dnl --Fyodor
AC_LIBOBJ([fw-none])
dnl Check for network interface interface.
if test "$ac_cv_header_Iphlpapi_h" = yes ; then

View File

@@ -1,227 +0,0 @@
/*
* fw-ipchains.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: fw-ipchains.c,v 1.8 2004/05/05 21:25:20 dugsong Exp $
*/
#include "config.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#undef __USE_BSD
#include <netinet/ip_icmp.h>
#include <linux/if.h>
#ifdef HAVE_LINUX_IP_FW_H
#include <linux/ip_fw.h>
#elif defined(HAVE_LINUX_IP_FWCHAINS_H)
#include <linux/ip_fwchains.h>
#elif defined(HAVE_LINUX_NETFILTER_IPV4_IPCHAINS_CORE_H)
#include <linux/netfilter_ipv4/ipchains_core.h>
#endif
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "dnet.h"
#define PROC_IPCHAINS_FILE "/proc/net/ip_fwchains"
struct fw_handle {
int fd;
};
static void
fr_to_fwc(const struct fw_rule *fr, struct ip_fwchange *fwc)
{
memset(fwc, 0, sizeof(*fwc));
strlcpy(fwc->fwc_rule.ipfw.fw_vianame, fr->fw_device, IFNAMSIZ);
if (fr->fw_op == FW_OP_ALLOW)
strlcpy(fwc->fwc_rule.label, IP_FW_LABEL_ACCEPT,
sizeof(fwc->fwc_rule.label));
else
strlcpy(fwc->fwc_rule.label, IP_FW_LABEL_BLOCK,
sizeof(fwc->fwc_rule.label));
if (fr->fw_dir == FW_DIR_IN)
strlcpy(fwc->fwc_label, IP_FW_LABEL_INPUT,
sizeof(fwc->fwc_label));
else
strlcpy(fwc->fwc_label, IP_FW_LABEL_OUTPUT,
sizeof(fwc->fwc_label));
fwc->fwc_rule.ipfw.fw_proto = fr->fw_proto;
fwc->fwc_rule.ipfw.fw_src.s_addr = fr->fw_src.addr_ip;
fwc->fwc_rule.ipfw.fw_dst.s_addr = fr->fw_dst.addr_ip;
addr_btom(fr->fw_src.addr_bits, &fwc->fwc_rule.ipfw.fw_smsk.s_addr,
IP_ADDR_LEN);
addr_btom(fr->fw_dst.addr_bits, &fwc->fwc_rule.ipfw.fw_dmsk.s_addr,
IP_ADDR_LEN);
/* XXX - ICMP? */
fwc->fwc_rule.ipfw.fw_spts[0] = fr->fw_sport[0];
fwc->fwc_rule.ipfw.fw_spts[1] = fr->fw_sport[1];
fwc->fwc_rule.ipfw.fw_dpts[0] = fr->fw_dport[0];
fwc->fwc_rule.ipfw.fw_dpts[1] = fr->fw_dport[1];
}
static void
fwc_to_fr(const struct ip_fwchange *fwc, struct fw_rule *fr)
{
memset(fr, 0, sizeof(*fr));
strlcpy(fr->fw_device, fwc->fwc_rule.ipfw.fw_vianame,
sizeof(fr->fw_device));
if (strcmp(fwc->fwc_rule.label, IP_FW_LABEL_ACCEPT) == 0)
fr->fw_op = FW_OP_ALLOW;
else
fr->fw_op = FW_OP_BLOCK;
if (strcmp(fwc->fwc_label, IP_FW_LABEL_INPUT) == 0)
fr->fw_dir = FW_DIR_IN;
else
fr->fw_dir = FW_DIR_OUT;
fr->fw_proto = fwc->fwc_rule.ipfw.fw_proto;
fr->fw_src.addr_type = fr->fw_dst.addr_type = ADDR_TYPE_IP;
fr->fw_src.addr_ip = fwc->fwc_rule.ipfw.fw_src.s_addr;
fr->fw_dst.addr_ip = fwc->fwc_rule.ipfw.fw_dst.s_addr;
addr_mtob(&fwc->fwc_rule.ipfw.fw_smsk.s_addr, IP_ADDR_LEN,
&fr->fw_src.addr_bits);
addr_mtob(&fwc->fwc_rule.ipfw.fw_dmsk.s_addr, IP_ADDR_LEN,
&fr->fw_dst.addr_bits);
/* XXX - ICMP? */
fr->fw_sport[0] = fwc->fwc_rule.ipfw.fw_spts[0];
fr->fw_sport[1] = fwc->fwc_rule.ipfw.fw_spts[1];
fr->fw_dport[0] = fwc->fwc_rule.ipfw.fw_dpts[0];
fr->fw_dport[1] = fwc->fwc_rule.ipfw.fw_dpts[1];
}
fw_t *
fw_open(void)
{
fw_t *fw;
if ((fw = calloc(1, sizeof(*fw))) != NULL) {
if ((fw->fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
return (fw_close(fw));
}
return (fw);
}
int
fw_add(fw_t *fw, const struct fw_rule *rule)
{
struct ip_fwchange fwc;
fr_to_fwc(rule, &fwc);
return (setsockopt(fw->fd, IPPROTO_IP, IP_FW_APPEND,
&fwc, sizeof(fwc)));
}
int
fw_delete(fw_t *fw, const struct fw_rule *rule)
{
struct ip_fwchange fwc;
fr_to_fwc(rule, &fwc);
return (setsockopt(fw->fd, IPPROTO_IP, IP_FW_DELETE,
&fwc, sizeof(fwc)));
}
int
fw_loop(fw_t *fw, fw_handler callback, void *arg)
{
FILE *fp;
struct ip_fwchange fwc;
struct fw_rule fr;
char buf[BUFSIZ];
u_int phi, plo, bhi, blo, tand, txor;
int ret;
if ((fp = fopen(PROC_IPCHAINS_FILE, "r")) == NULL)
return (-1);
while (fgets(buf, sizeof(buf), fp) != NULL) {
if (sscanf(buf,
"%8s %X/%X->%X/%X %s %hX %hX %hu %u %u %u %u "
"%hu-%hu %hu-%hu A%X X%X %hX %u %hu %s\n",
fwc.fwc_label,
&fwc.fwc_rule.ipfw.fw_src.s_addr,
&fwc.fwc_rule.ipfw.fw_smsk.s_addr,
&fwc.fwc_rule.ipfw.fw_dst.s_addr,
&fwc.fwc_rule.ipfw.fw_dmsk.s_addr,
fwc.fwc_rule.ipfw.fw_vianame,
&fwc.fwc_rule.ipfw.fw_flg,
&fwc.fwc_rule.ipfw.fw_invflg,
&fwc.fwc_rule.ipfw.fw_proto,
&phi, &plo, &bhi, &blo,
&fwc.fwc_rule.ipfw.fw_spts[0],
&fwc.fwc_rule.ipfw.fw_spts[1],
&fwc.fwc_rule.ipfw.fw_dpts[0],
&fwc.fwc_rule.ipfw.fw_dpts[1],
&tand, &txor,
&fwc.fwc_rule.ipfw.fw_redirpt,
&fwc.fwc_rule.ipfw.fw_mark,
&fwc.fwc_rule.ipfw.fw_outputsize,
fwc.fwc_rule.label) != 23)
break;
if (strcmp(fwc.fwc_rule.label, IP_FW_LABEL_ACCEPT) != 0 &&
strcmp(fwc.fwc_rule.label, IP_FW_LABEL_BLOCK) != 0 &&
strcmp(fwc.fwc_rule.label, IP_FW_LABEL_REJECT) != 0)
continue;
if (strcmp(fwc.fwc_label, IP_FW_LABEL_INPUT) != 0 &&
strcmp(fwc.fwc_label, IP_FW_LABEL_OUTPUT) != 0)
continue;
if (strcmp(fwc.fwc_rule.label, "-") == 0)
(fwc.fwc_rule.label)[0] = '\0';
if (strcmp(fwc.fwc_rule.ipfw.fw_vianame, "-") == 0)
(fwc.fwc_rule.ipfw.fw_vianame)[0] = '\0';
fwc.fwc_rule.ipfw.fw_src.s_addr =
htonl(fwc.fwc_rule.ipfw.fw_src.s_addr);
fwc.fwc_rule.ipfw.fw_dst.s_addr =
htonl(fwc.fwc_rule.ipfw.fw_dst.s_addr);
fwc.fwc_rule.ipfw.fw_smsk.s_addr =
htonl(fwc.fwc_rule.ipfw.fw_smsk.s_addr);
fwc.fwc_rule.ipfw.fw_dmsk.s_addr =
htonl(fwc.fwc_rule.ipfw.fw_dmsk.s_addr);
fwc_to_fr(&fwc, &fr);
if ((ret = callback(&fr, arg)) != 0) {
fclose(fp);
return (ret);
}
}
fclose(fp);
return (0);
}
fw_t *
fw_close(fw_t *fw)
{
if (fw != NULL) {
if (fw->fd >= 0)
close(fw->fd);
free(fw);
}
return (NULL);
}

View File

@@ -1,281 +0,0 @@
/*
* fw-ipf.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: fw-ipf.c,v 1.18 2005/02/16 21:42:53 dugsong Exp $
*/
#include "config.h"
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#define _NETINET_IP6_H_ /* XXX */
#include <netinet/in.h>
#define ip_t ipf_ip_t
#ifdef HAVE_NETINET_IP_FIL_COMPAT_H
# include <netinet/ip_fil_compat.h>
#else
# include <netinet/ip_compat.h>
#endif
#include <netinet/ip_fil.h>
#undef ip_t
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define KMEM_NAME "/dev/kmem"
#include "dnet.h"
#if !defined(fi_saddr) && !defined(fi_daddr)
# define fi_saddr fi_src.s_addr
# define fi_daddr fi_dst.s_addr
#endif
struct fw_handle {
int fd;
int kfd;
};
static void
rule_to_ipf(const struct fw_rule *rule, struct frentry *fr)
{
memset(fr, 0, sizeof(*fr));
if (*rule->fw_device != '\0') {
strlcpy(fr->fr_ifname, rule->fw_device, IFNAMSIZ);
strlcpy(fr->fr_oifname, rule->fw_device, IFNAMSIZ);
}
if (rule->fw_op == FW_OP_ALLOW)
fr->fr_flags |= FR_PASS;
else
fr->fr_flags |= FR_BLOCK;
if (rule->fw_dir == FW_DIR_IN)
fr->fr_flags |= FR_INQUE;
else
fr->fr_flags |= FR_OUTQUE;
fr->fr_ip.fi_p = rule->fw_proto;
fr->fr_ip.fi_saddr = rule->fw_src.addr_ip;
fr->fr_ip.fi_daddr = rule->fw_dst.addr_ip;
addr_btom(rule->fw_src.addr_bits, &fr->fr_mip.fi_saddr, IP_ADDR_LEN);
addr_btom(rule->fw_dst.addr_bits, &fr->fr_mip.fi_daddr, IP_ADDR_LEN);
switch (rule->fw_proto) {
case IPPROTO_ICMP:
fr->fr_icmpm = rule->fw_sport[1] << 8 |
(rule->fw_dport[1] & 0xff);
fr->fr_icmp = rule->fw_sport[0] << 8 |
(rule->fw_dport[0] & 0xff);
break;
case IPPROTO_TCP:
case IPPROTO_UDP:
fr->fr_sport = rule->fw_sport[0];
if (rule->fw_sport[0] != rule->fw_sport[1]) {
fr->fr_scmp = FR_INRANGE;
fr->fr_stop = rule->fw_sport[1];
} else
fr->fr_scmp = FR_EQUAL;
fr->fr_dport = rule->fw_dport[0];
if (rule->fw_dport[0] != rule->fw_dport[1]) {
fr->fr_dcmp = FR_INRANGE;
fr->fr_dtop = rule->fw_dport[1];
} else
fr->fr_dcmp = FR_EQUAL;
break;
}
}
static void
ipf_ports_to_rule(uint8_t cmp, uint16_t port, uint16_t top, uint16_t *range)
{
switch (cmp) {
case FR_EQUAL:
range[0] = range[1] = port;
break;
case FR_NEQUAL:
range[0] = port - 1;
range[1] = port + 1;
break;
case FR_LESST:
range[0] = 0;
range[1] = port - 1;
break;
case FR_GREATERT:
range[0] = port + 1;
range[1] = TCP_PORT_MAX;
break;
case FR_LESSTE:
range[0] = 0;
range[1] = port;
break;
case FR_GREATERTE:
range[0] = port;
range[1] = TCP_PORT_MAX;
break;
case FR_OUTRANGE:
range[0] = port;
range[1] = top;
break;
case FR_INRANGE:
range[0] = port;
range[1] = top;
break;
default:
range[0] = 0;
range[1] = TCP_PORT_MAX;
}
}
static void
ipf_to_rule(const struct frentry *fr, struct fw_rule *rule)
{
memset(rule, 0, sizeof(*rule));
strlcpy(rule->fw_device, fr->fr_ifname, sizeof(rule->fw_device));
rule->fw_op = (fr->fr_flags & FR_PASS) ? FW_OP_ALLOW : FW_OP_BLOCK;
rule->fw_dir = (fr->fr_flags & FR_INQUE) ? FW_DIR_IN : FW_DIR_OUT;
rule->fw_proto = fr->fr_ip.fi_p;
rule->fw_src.addr_type = rule->fw_dst.addr_type = ADDR_TYPE_IP;
rule->fw_src.addr_ip = fr->fr_ip.fi_saddr;
rule->fw_dst.addr_ip = fr->fr_ip.fi_daddr;
addr_mtob(&fr->fr_mip.fi_saddr, IP_ADDR_LEN,
&rule->fw_src.addr_bits);
addr_mtob(&fr->fr_mip.fi_daddr, IP_ADDR_LEN,
&rule->fw_dst.addr_bits);
switch (rule->fw_proto) {
case IPPROTO_ICMP:
rule->fw_sport[0] = ntohs(fr->fr_icmp & fr->fr_icmpm) >> 8;
rule->fw_sport[1] = ntohs(fr->fr_icmpm) >> 8;
rule->fw_dport[0] = ntohs(fr->fr_icmp & fr->fr_icmpm) & 0xff;
rule->fw_dport[1] = ntohs(fr->fr_icmpm) & 0xff;
break;
case IPPROTO_TCP:
case IPPROTO_UDP:
ipf_ports_to_rule(fr->fr_scmp, fr->fr_sport,
fr->fr_stop, rule->fw_sport);
ipf_ports_to_rule(fr->fr_dcmp, fr->fr_dport,
fr->fr_dtop, rule->fw_dport);
break;
}
}
fw_t *
fw_open(void)
{
fw_t *fw;
if ((fw = calloc(1, sizeof(*fw))) != NULL) {
fw->fd = fw->kfd = -1;
if ((fw->fd = open(IPL_NAME, O_RDWR, 0)) < 0)
return (fw_close(fw));
if ((fw->kfd = open(KMEM_NAME, O_RDONLY)) < 0)
return (fw_close(fw));
}
return (fw);
}
int
fw_add(fw_t *fw, const struct fw_rule *rule)
{
struct frentry fr;
assert(fw != NULL && rule != NULL);
rule_to_ipf(rule, &fr);
return (ioctl(fw->fd, SIOCADDFR, &fr));
}
int
fw_delete(fw_t *fw, const struct fw_rule *rule)
{
struct frentry fr;
assert(fw != NULL && rule != NULL);
rule_to_ipf(rule, &fr);
return (ioctl(fw->fd, SIOCDELFR, &fr));
}
static int
fw_kcopy(fw_t *fw, u_char *buf, off_t pos, size_t n)
{
int i;
if (lseek(fw->kfd, pos, 0) < 0)
return (-1);
while ((i = read(fw->kfd, buf, n)) < n) {
if (i <= 0)
return (-1);
buf += i;
n -= i;
}
return (0);
}
int
fw_loop(fw_t *fw, fw_handler callback, void *arg)
{
struct friostat fio;
struct friostat *fiop = &fio;
struct frentry *frp, fr;
struct fw_rule rule;
int ret;
memset(&fio, 0, sizeof(fio));
#ifdef __OpenBSD__
if (ioctl(fw->fd, SIOCGETFS, fiop) < 0)
#else
if (ioctl(fw->fd, SIOCGETFS, &fiop) < 0) /* XXX - darren! */
#endif
return (-1);
for (frp = fio.f_fout[(int)fio.f_active]; frp != NULL;
frp = fr.fr_next) {
if (fw_kcopy(fw, (u_char *)&fr, (u_long)frp, sizeof(fr)) < 0)
return (-1);
ipf_to_rule(&fr, &rule);
if ((ret = callback(&rule, arg)) != 0)
return (ret);
}
for (frp = fio.f_fin[(int)fio.f_active]; frp != NULL;
frp = fr.fr_next) {
if (fw_kcopy(fw, (u_char *)&fr, (u_long)frp, sizeof(fr)) < 0)
return (-1);
ipf_to_rule(&fr, &rule);
if ((ret = callback(&rule, arg)) != 0)
return (ret);
}
return (0);
}
fw_t *
fw_close(fw_t *fw)
{
if (fw != NULL) {
if (fw->fd >= 0)
close(fw->fd);
if (fw->kfd >= 0)
close(fw->kfd);
free(fw);
}
return (NULL);
}

View File

@@ -1,324 +0,0 @@
/*
* fw-ipfw.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: fw-ipfw.c,v 1.16 2004/01/14 04:52:10 dugsong Exp $
*/
#include "config.h"
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip_fw.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "dnet.h"
struct fw_handle {
int fd;
};
static void
fr_to_ipfw_device(const char *device, char *name, short *unit)
{
char *p;
p = strpbrk(device, "0123456789");
*unit = atoi(p);
strlcpy(name, device, p - device + 1);
}
static void
fr_to_ipfw(const struct fw_rule *fr, struct ip_fw *ipfw)
{
int i;
memset(ipfw, 0, sizeof(*ipfw));
if (fr->fw_dir == FW_DIR_IN) {
if (*fr->fw_device != '\0') {
fr_to_ipfw_device(fr->fw_device,
ipfw->fw_in_if.fu_via_if.name,
&ipfw->fw_in_if.fu_via_if.unit);
ipfw->fw_flg |= IP_FW_F_IIFNAME;
}
ipfw->fw_flg |= IP_FW_F_IN;
} else {
if (*fr->fw_device != '\0') {
fr_to_ipfw_device(fr->fw_device,
ipfw->fw_out_if.fu_via_if.name,
&ipfw->fw_out_if.fu_via_if.unit);
ipfw->fw_flg |= IP_FW_F_OIFNAME;
}
ipfw->fw_flg |= IP_FW_F_OUT;
}
if (fr->fw_op == FW_OP_ALLOW)
ipfw->fw_flg |= IP_FW_F_ACCEPT;
else
ipfw->fw_flg |= IP_FW_F_DENY;
ipfw->fw_prot = fr->fw_proto;
ipfw->fw_src.s_addr = fr->fw_src.addr_ip;
ipfw->fw_dst.s_addr = fr->fw_dst.addr_ip;
addr_btom(fr->fw_src.addr_bits, &ipfw->fw_smsk.s_addr, IP_ADDR_LEN);
addr_btom(fr->fw_dst.addr_bits, &ipfw->fw_dmsk.s_addr, IP_ADDR_LEN);
switch (fr->fw_proto) {
case IP_PROTO_TCP:
case IP_PROTO_UDP:
i = 0;
if (fr->fw_sport[0] != fr->fw_sport[1]) {
ipfw->fw_flg |= IP_FW_F_SRNG;
ipfw->fw_uar.fw_pts[i++] = fr->fw_sport[0];
ipfw->fw_uar.fw_pts[i++] = fr->fw_sport[1];
IP_FW_SETNSRCP(ipfw, 2);
} else if (fr->fw_sport[0] > 0) {
ipfw->fw_uar.fw_pts[i++] = fr->fw_sport[0];
IP_FW_SETNSRCP(ipfw, 1);
}
if (fr->fw_dport[0] != fr->fw_dport[1]) {
ipfw->fw_flg |= IP_FW_F_DRNG;
ipfw->fw_uar.fw_pts[i++] = fr->fw_dport[0];
ipfw->fw_uar.fw_pts[i++] = fr->fw_dport[1];
IP_FW_SETNDSTP(ipfw, 2);
} else if (fr->fw_dport[0] > 0) {
ipfw->fw_uar.fw_pts[i++] = fr->fw_dport[0];
IP_FW_SETNDSTP(ipfw, 1);
}
break;
case IP_PROTO_ICMP:
if (fr->fw_sport[1]) {
ipfw->fw_uar.fw_icmptypes[fr->fw_sport[0] / 32] |=
1 << (fr->fw_sport[0] % 32);
ipfw->fw_flg |= IP_FW_F_ICMPBIT;
}
/* XXX - no support for ICMP code. */
break;
}
}
static void
ipfw_to_fr(const struct ip_fw *ipfw, struct fw_rule *fr)
{
int i;
memset(fr, 0, sizeof(*fr));
if ((ipfw->fw_flg & IP_FW_F_IN) && *ipfw->fw_in_if.fu_via_if.name)
snprintf(fr->fw_device, sizeof(fr->fw_device), "%s%d",
ipfw->fw_in_if.fu_via_if.name,
ipfw->fw_in_if.fu_via_if.unit);
else if ((ipfw->fw_flg & IP_FW_F_OUT) &&
*ipfw->fw_out_if.fu_via_if.name)
snprintf(fr->fw_device, sizeof(fr->fw_device), "%s%d",
ipfw->fw_out_if.fu_via_if.name,
ipfw->fw_out_if.fu_via_if.unit);
fr->fw_op = (ipfw->fw_flg & IP_FW_F_ACCEPT) ?
FW_OP_ALLOW : FW_OP_BLOCK;
fr->fw_dir = (ipfw->fw_flg & IP_FW_F_IN) ? FW_DIR_IN : FW_DIR_OUT;
fr->fw_proto = ipfw->fw_prot;
fr->fw_src.addr_type = fr->fw_dst.addr_type = ADDR_TYPE_IP;
fr->fw_src.addr_ip = ipfw->fw_src.s_addr;
fr->fw_dst.addr_ip = ipfw->fw_dst.s_addr;
addr_mtob(&ipfw->fw_smsk.s_addr, IP_ADDR_LEN, &fr->fw_src.addr_bits);
addr_mtob(&ipfw->fw_dmsk.s_addr, IP_ADDR_LEN, &fr->fw_dst.addr_bits);
switch (fr->fw_proto) {
case IP_PROTO_TCP:
case IP_PROTO_UDP:
if ((ipfw->fw_flg & IP_FW_F_SRNG) &&
IP_FW_GETNSRCP(ipfw) == 2) {
fr->fw_sport[0] = ipfw->fw_uar.fw_pts[0];
fr->fw_sport[1] = ipfw->fw_uar.fw_pts[1];
} else if (IP_FW_GETNSRCP(ipfw) == 1) {
fr->fw_sport[0] = fr->fw_sport[1] =
ipfw->fw_uar.fw_pts[0];
} else if (IP_FW_GETNSRCP(ipfw) == 0) {
fr->fw_sport[0] = 0;
fr->fw_sport[1] = TCP_PORT_MAX;
}
if ((ipfw->fw_flg & IP_FW_F_DRNG) &&
IP_FW_GETNDSTP(ipfw) == 2) {
i = IP_FW_GETNSRCP(ipfw);
fr->fw_dport[0] = ipfw->fw_uar.fw_pts[i];
fr->fw_dport[1] = ipfw->fw_uar.fw_pts[i + 1];
} else if (IP_FW_GETNDSTP(ipfw) == 1) {
i = IP_FW_GETNSRCP(ipfw);
fr->fw_dport[0] = fr->fw_dport[1] =
ipfw->fw_uar.fw_pts[i];
} else if (IP_FW_GETNDSTP(ipfw) == 0) {
fr->fw_dport[0] = 0;
fr->fw_dport[1] = TCP_PORT_MAX;
}
break;
case IP_PROTO_ICMP:
if (ipfw->fw_flg & IP_FW_F_ICMPBIT) {
for (i = 0; i < IP_FW_ICMPTYPES_DIM * 32; i++) {
if (ipfw->fw_uar.fw_icmptypes[i / 32] &
(1U << (i % 32))) {
fr->fw_sport[0] = i;
fr->fw_sport[1] = 0xff;
break;
}
}
}
/* XXX - no support for ICMP code. */
break;
}
}
fw_t *
fw_open(void)
{
fw_t *fw;
if ((fw = calloc(1, sizeof(*fw))) != NULL) {
if ((fw->fd = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) < 0)
return (fw_close(fw));
}
return (fw);
}
int
fw_add(fw_t *fw, const struct fw_rule *rule)
{
struct ip_fw ipfw;
assert(fw != NULL && rule != NULL);
fr_to_ipfw(rule, &ipfw);
return (setsockopt(fw->fd, IPPROTO_IP, IP_FW_ADD,
&ipfw, sizeof(ipfw)));
}
static int
fw_cmp(const struct fw_rule *a, const struct fw_rule *b)
{
if (strcmp(a->fw_device, b->fw_device) != 0 || a->fw_op != b->fw_op ||
a->fw_dir != b->fw_dir || a->fw_proto != b->fw_proto ||
addr_cmp(&a->fw_src, &b->fw_src) != 0 ||
addr_cmp(&a->fw_dst, &b->fw_dst) != 0 ||
memcmp(a->fw_sport, b->fw_sport, sizeof(a->fw_sport)) != 0 ||
memcmp(a->fw_dport, b->fw_dport, sizeof(a->fw_dport)) != 0)
return (-1);
return (0);
}
int
fw_delete(fw_t *fw, const struct fw_rule *rule)
{
struct ip_fw *ipfw;
struct fw_rule fr;
int nbytes, nalloc, ret;
u_char *buf, *new;
assert(rule != NULL);
nbytes = nalloc = sizeof(*ipfw);
if ((buf = malloc(nbytes)) == NULL)
return (-1);
while (nbytes >= nalloc) {
nalloc = nalloc * 2 + 200;
nbytes = nalloc;
if ((new = realloc(buf, nbytes)) == NULL) {
if (buf)
free(buf);
return (-1);
}
buf = new;
if (getsockopt(fw->fd, IPPROTO_IP, IP_FW_GET,
buf, &nbytes) < 0) {
free(buf);
return (-1);
}
}
ret = -1;
/* XXX - 65535 is the fixed ipfw default rule. */
for (ipfw = (struct ip_fw *)buf; ipfw->fw_number < 65535; ipfw++) {
ipfw_to_fr(ipfw, &fr);
if (fw_cmp(&fr, rule) == 0) {
if (setsockopt(fw->fd, IPPROTO_IP, IP_FW_DEL,
ipfw, sizeof(*ipfw)) < 0)
ret = -2;
else
ret = 0;
break;
}
}
free(buf);
if (ret < 0) {
if (ret == -1)
errno = ESRCH;
return (-1);
}
return (0);
}
int
fw_loop(fw_t *fw, fw_handler callback, void *arg)
{
struct ip_fw *ipfw;
struct fw_rule fr;
int i, cnt, nbytes, nalloc, ret;
u_char *buf, *new;
nbytes = nalloc = sizeof(*ipfw);
if ((buf = malloc(nbytes)) == NULL)
return (-1);
while (nbytes >= nalloc) {
nalloc = nalloc * 2 + 200;
nbytes = nalloc;
if ((new = realloc(buf, nbytes)) == NULL) {
if (buf)
free(buf);
return (-1);
}
buf = new;
if (getsockopt(fw->fd, IPPROTO_IP, IP_FW_GET,
buf, &nbytes) < 0) {
free(buf);
return (-1);
}
}
cnt = nbytes / sizeof(*ipfw);
ipfw = (struct ip_fw *)buf;
ret = 0;
for (i = 0; i < cnt; i++) {
ipfw_to_fr(&ipfw[i], &fr);
if ((ret = callback(&fr, arg)) != 0)
break;
}
free(buf);
return (ret);
}
fw_t *
fw_close(fw_t *fw)
{
if (fw != NULL) {
if (fw->fd >= 0)
close(fw->fd);
free(fw);
}
return (NULL);
}

View File

@@ -1,315 +0,0 @@
/*
* fw-pf.c
*
* Copyright (c) 2001 Dug Song <dugsong@monkey.org>
*
* $Id: fw-pf.c,v 1.20 2005/02/14 20:43:32 dugsong Exp $
*/
#include "config.h"
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/pfvar.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "dnet.h"
/*
* XXX - cope with moving pf API
*/
#if defined(DIOCRCLRTABLES)
/* XXX - can't isolate the following change:
* $OpenBSD: pfvar.h,v 1.112 2002/12/17 12:30:13 mcbride Exp $
* so i'll take 1.119's DIOCRCLRTABLES - 12 days of pf unsupported.
*/
# define HAVE_PF_CHANGE_GET_TICKET 1
/* OpenBSD 3.3+ - 3.6 */
/* $OpenBSD: pfvar.h,v 1.197 2004/06/14 20:53:27 cedric Exp $ */
/* $OpenBSD: pfvar.h,v 1.130 2003/01/09 10:40:45 cedric Exp $ */
/* $OpenBSD: pfvar.h,v 1.127 2003/01/05 22:14:23 dhartmei Exp $ */
# define PFRA_ADDR(ra) (ra)->addr.v.a.addr.v4.s_addr
# define PFRA_MASK(ra) (ra)->addr.v.a.mask.v4.s_addr
# define pfioc_changerule pfioc_rule
# define oldrule rule
# define newrule rule
#elif defined(DIOCBEGINADDRS)
/* $OpenBSD: pfvar.h,v 1.102 2002/11/23 05:16:58 mcbride Exp $ */
# define PFRA_ADDR(ra) (ra)->addr.addr.v4.s_addr
# define PFRA_MASK(ra) (ra)->addr.mask.v4.s_addr
#elif defined(PFRULE_FRAGMENT)
/* OpenBSD 3.2 */
/* $OpenBSD: pfvar.h,v 1.68 2002/04/24 18:10:25 dhartmei Exp $ */
# define PFRA_ADDR(ra) (ra)->addr.addr.v4.s_addr
# define PFRA_MASK(ra) (ra)->mask.v4.s_addr
#elif defined (PF_AEQ)
/* OpenBSD 3.1 */
/* $OpenBSD: pfvar.h,v 1.51 2001/09/15 03:54:40 frantzen Exp $ */
# define PFRA_ADDR(ra) (ra)->addr.v4.s_addr
# define PFRA_MASK(ra) (ra)->mask.v4.s_addr
#else
/* OpenBSD 3.0 */
# define PFRA_ADDR(ra) (ra)->addr
# define PFRA_ADDR(ra) (ra)->mask
#endif
struct fw_handle {
int fd;
};
static void
fr_to_pr(const struct fw_rule *fr, struct pf_rule *pr)
{
memset(pr, 0, sizeof(*pr));
strlcpy(pr->ifname, fr->fw_device, sizeof(pr->ifname));
pr->action = (fr->fw_op == FW_OP_ALLOW) ? PF_PASS : PF_DROP;
pr->direction = (fr->fw_dir == FW_DIR_IN) ? PF_IN : PF_OUT;
pr->proto = fr->fw_proto;
pr->af = AF_INET;
PFRA_ADDR(&pr->src) = fr->fw_src.addr_ip;
addr_btom(fr->fw_src.addr_bits, &(PFRA_MASK(&pr->src)), IP_ADDR_LEN);
PFRA_ADDR(&pr->dst) = fr->fw_dst.addr_ip;
addr_btom(fr->fw_dst.addr_bits, &(PFRA_MASK(&pr->dst)), IP_ADDR_LEN);
switch (fr->fw_proto) {
case IP_PROTO_ICMP:
if (fr->fw_sport[1])
pr->type = (u_char)(fr->fw_sport[0] &
fr->fw_sport[1]) + 1;
if (fr->fw_dport[1])
pr->code = (u_char)(fr->fw_dport[0] &
fr->fw_dport[1]) + 1;
break;
case IP_PROTO_TCP:
case IP_PROTO_UDP:
pr->src.port[0] = htons(fr->fw_sport[0]);
pr->src.port[1] = htons(fr->fw_sport[1]);
if (pr->src.port[0] == pr->src.port[1]) {
pr->src.port_op = PF_OP_EQ;
} else
pr->src.port_op = PF_OP_IRG;
pr->dst.port[0] = htons(fr->fw_dport[0]);
pr->dst.port[1] = htons(fr->fw_dport[1]);
if (pr->dst.port[0] == pr->dst.port[1]) {
pr->dst.port_op = PF_OP_EQ;
} else
pr->dst.port_op = PF_OP_IRG;
break;
}
}
static int
pr_to_fr(const struct pf_rule *pr, struct fw_rule *fr)
{
memset(fr, 0, sizeof(*fr));
strlcpy(fr->fw_device, pr->ifname, sizeof(fr->fw_device));
if (pr->action == PF_DROP)
fr->fw_op = FW_OP_BLOCK;
else if (pr->action == PF_PASS)
fr->fw_op = FW_OP_ALLOW;
else
return (-1);
fr->fw_dir = pr->direction == PF_IN ? FW_DIR_IN : FW_DIR_OUT;
fr->fw_proto = pr->proto;
if (pr->af != AF_INET)
return (-1);
fr->fw_src.addr_type = ADDR_TYPE_IP;
addr_mtob(&(PFRA_MASK(&pr->src)), IP_ADDR_LEN, &fr->fw_src.addr_bits);
fr->fw_src.addr_ip = PFRA_ADDR(&pr->src);
fr->fw_dst.addr_type = ADDR_TYPE_IP;
addr_mtob(&(PFRA_MASK(&pr->dst)), IP_ADDR_LEN, &fr->fw_dst.addr_bits);
fr->fw_dst.addr_ip = PFRA_ADDR(&pr->dst);
switch (fr->fw_proto) {
case IP_PROTO_ICMP:
if (pr->type) {
fr->fw_sport[0] = pr->type - 1;
fr->fw_sport[1] = 0xff;
}
if (pr->code) {
fr->fw_dport[0] = pr->code - 1;
fr->fw_dport[1] = 0xff;
}
break;
case IP_PROTO_TCP:
case IP_PROTO_UDP:
fr->fw_sport[0] = ntohs(pr->src.port[0]);
fr->fw_sport[1] = ntohs(pr->src.port[1]);
if (pr->src.port_op == PF_OP_EQ)
fr->fw_sport[1] = fr->fw_sport[0];
fr->fw_dport[0] = ntohs(pr->dst.port[0]);
fr->fw_dport[1] = ntohs(pr->dst.port[1]);
if (pr->dst.port_op == PF_OP_EQ)
fr->fw_dport[1] = fr->fw_dport[0];
}
return (0);
}
#ifdef HAVE_PF_CHANGE_GET_TICKET
static int
_fw_cmp(const struct fw_rule *a, const struct fw_rule *b)
{
if (strcmp(a->fw_device, b->fw_device) != 0 || a->fw_op != b->fw_op ||
a->fw_dir != b->fw_dir || a->fw_proto != b->fw_proto ||
addr_cmp(&a->fw_src, &b->fw_src) != 0 ||
addr_cmp(&a->fw_dst, &b->fw_dst) != 0 ||
memcmp(a->fw_sport, b->fw_sport, sizeof(a->fw_sport)) != 0 ||
memcmp(a->fw_dport, b->fw_dport, sizeof(a->fw_dport)) != 0)
return (-1);
return (0);
}
#endif
fw_t *
fw_open(void)
{
fw_t *fw;
if ((fw = calloc(1, sizeof(*fw))) != NULL) {
if ((fw->fd = open("/dev/pf", O_RDWR)) < 0)
return (fw_close(fw));
}
return (fw);
}
int
fw_add(fw_t *fw, const struct fw_rule *rule)
{
struct pfioc_changerule pcr;
assert(fw != NULL && rule != NULL);
memset(&pcr, 0, sizeof(pcr));
#ifdef HAVE_PF_CHANGE_GET_TICKET
{
struct fw_rule fr;
if (ioctl(fw->fd, DIOCGETRULES, &pcr) < 0)
return (-1);
while ((int)--pcr.nr >= 0) {
if (ioctl(fw->fd, DIOCGETRULE, &pcr) == 0 &&
pr_to_fr(&pcr.rule, &fr) == 0) {
if (_fw_cmp(rule, &fr) == 0) {
errno = EEXIST;
return (-1);
}
}
}
}
#endif
#ifdef DIOCBEGINADDRS
{
struct pfioc_pooladdr ppa;
if (ioctl(fw->fd, DIOCBEGINADDRS, &ppa) < 0)
return (-1);
pcr.pool_ticket = ppa.ticket;
}
#endif
pcr.action = PF_CHANGE_ADD_TAIL;
fr_to_pr(rule, &pcr.newrule);
return (ioctl(fw->fd, DIOCCHANGERULE, &pcr));
}
int
fw_delete(fw_t *fw, const struct fw_rule *rule)
{
struct pfioc_changerule pcr;
assert(fw != NULL && rule != NULL);
memset(&pcr, 0, sizeof(pcr));
#ifdef HAVE_PF_CHANGE_GET_TICKET
{
struct fw_rule fr;
int found = 0;
if (ioctl(fw->fd, DIOCGETRULES, &pcr) < 0)
return (-1);
while ((int)--pcr.nr >= 0) {
if (ioctl(fw->fd, DIOCGETRULE, &pcr) == 0 &&
pr_to_fr(&pcr.rule, &fr) == 0) {
if (_fw_cmp(rule, &fr) == 0) {
found = 1;
break;
}
}
}
if (!found) {
errno = ENOENT;
return (-1);
}
}
#endif
#ifdef DIOCBEGINADDRS
{
struct pfioc_pooladdr ppa;
if (ioctl(fw->fd, DIOCBEGINADDRS, &ppa) < 0)
return (-1);
pcr.pool_ticket = ppa.ticket;
}
#endif
pcr.action = PF_CHANGE_REMOVE;
fr_to_pr(rule, &pcr.oldrule);
return (ioctl(fw->fd, DIOCCHANGERULE, &pcr));
}
int
fw_loop(fw_t *fw, fw_handler callback, void *arg)
{
struct pfioc_rule pr;
struct fw_rule fr;
uint32_t n, max;
int ret = 0;
memset(&pr, 0, sizeof(pr));
if (ioctl(fw->fd, DIOCGETRULES, &pr) < 0)
return (-1);
for (n = 0, max = pr.nr; n < max; n++) {
pr.nr = n;
if ((ret = ioctl(fw->fd, DIOCGETRULE, &pr)) < 0)
break;
if (pr_to_fr(&pr.rule, &fr) < 0)
continue;
if ((ret = callback(&fr, arg)) != 0)
break;
}
return (ret);
}
fw_t *
fw_close(fw_t *fw)
{
if (fw != NULL) {
if (fw->fd >= 0)
close(fw->fd);
free(fw);
}
return (NULL);
}

View File

@@ -1,444 +0,0 @@
/*
* fw-pktfilter.c
*
* Copyright (c) 2002 Dug Song <dugsong@monkey.org>
* Copyright (c) 2001 Jean-Baptiste Marchand, Herv<72> Schauer Consultants.
*
* $Id: fw-pktfilter.c,v 1.4 2005/02/15 06:37:06 dugsong Exp $
*/
#include "config.h"
#include <iphlpapi.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dnet.h"
#define PKTFILTER_PIPE "\\\\.\\pipe\\PktFltPipe"
#define MAX_RULE_LENGTH 256
#define FILTER_FAILURE 0 /* filter had a syntax error */
#define FILTER_SUCCESS 1 /* filter was correctly added */
#define FILTER_MESSAGE 2 /* informative message returned to the client */
char *icmp_types[] = {
"echorep", /* 0: echo reply */
"", /* 1: unused */
"", /* 2: unused */
"unreach", /* 3: destination unreachable */
"squench", /* 4: source quench */
"redir", /* 5: redirect */
"", /* 6: unused */
"", /* 7: unused */
"echo", /* 8: echo request */
"router_adv", /* 9: router advertisement */
"router_sol", /* 10: router solicitation */
"timex", /* 11: time exceeded */
"paramprob", /* 12: parameter problem */
"timest", /* 13: timestamp request */
"timestrep", /* 14: timestamp reply */
"inforeq", /* 15: information request */
"inforep", /* 16: information reply */
"maskreq", /* 17: address mask request */
"maskrep", /* 18: address mask reply */
NULL
};
struct fw_handle {
IP_ADAPTER_INFO *ifinfo;
/* XXX - rules cache for delete lookup? */
};
static int
parse_addr(char *p, struct addr *a)
{
if (strcmp(p, "any") == 0)
return (addr_aton("0.0.0.0/0", a));
return (addr_aton(p, a));
}
static int
parse_portspec(char *str, uint16_t *ports)
{
char *p = strsep(&str, " ");
if (p[0] == '=') {
ports[0] = ports[1] = atoi(strsep(&str, " "));
} else if (p[0] == '<') {
ports[1] = atoi(strsep(&str, " "));
if (p[1] != '=') ports[1]--;
} else if (p[0] == '>') {
ports[1] = TCP_PORT_MAX;
ports[0] = atoi(strsep(&str, " "));
if (p[1] != '=') ports[0]++;
} else if (p[0] != '\0') {
if (strcmp(strsep(&str, " "), "><") != 0)
return (-1);
ports[0] = atoi(p) + 1;
ports[1] = atoi(strsep(&str, " ")) - 1;
}
return (0);
}
static int
parse_icmpspec(char *str, uint16_t *type, uint16_t *code)
{
char *p, *e;
int i;
p = strsep(&str, " ");
for (i = 0; icmp_types[i] && strcmp(p, icmp_types[i]); i++)
;
if (icmp_types[i] == NULL) {
i = strtol(p, &e, 10);
if (*e != '\0')
return (-1);
}
type[0] = i;
type[1] = 0xff;
p = strsep(&str, " ");
if (p != NULL && strcmp(p, "code")) {
p = strsep(&str, " ");
i = strtol(p, &e, 10);
if (*e != '\0')
return (-1);
code[0] = i;
code[1] = 0xff;
}
return (0);
}
/*
<op> <dir> on <device> all
<op> <dir> on <device> proto <proto> all
<op> <dir> on <device> proto <proto> from <src> [ports] to <dst> [ports]
<op> <dir> on <device> proto icmp all [icmp-type <type> [code <code>]]
<op> <dir> on <device> proto icmp from <src> to <dst> [icmp-type <type> [code <code>]]
*/
static int
parse_rule(char *str, struct fw_rule *rule)
{
char *p, *q;
memset(rule, 0, sizeof(*rule));
/* action */
p = strsep(&str, " ");
if (strcmp(p, "block") == 0)
rule->fw_op = FW_OP_BLOCK;
else if (strcmp(p, "pass") == 0)
rule->fw_op = FW_OP_ALLOW;
else return (-1);
/* direction */
p = strsep(&str, " ");
if (strcmp(p, "in") == 0)
rule->fw_dir = FW_DIR_IN;
else if (strcmp(p, "out") == 0)
rule->fw_dir = FW_DIR_OUT;
else return (-1);
/* device */
if (strcmp(strsep(&str, " "), "on") != 0)
return (-1);
p = strsep(&str, " ");
/* XXX - handle bug in pktfltsrv.c */
if ((q = strstr(p, "proto")) != NULL)
*q = '\0';
if (strcmp(p, "all") != 0)
strlcpy(rule->fw_device, p, sizeof(rule->fw_device));
/* proto */
p = strsep(&str, " ");
/* XXX - handle bug in pktfltsrv.c */
if (strcmp(p, "proto") == 0)
p = strsep(&str, " ");
/* XXX - handle default rules */
if (strcmp(p, "all") == 0)
return (0);
if (strcmp(p, "icmp") == 0)
rule->fw_proto = IP_PROTO_ICMP;
else if (strcmp(p, "tcp") == 0)
rule->fw_proto = IP_PROTO_TCP;
else if (strcmp(p, "udp") == 0)
rule->fw_proto = IP_PROTO_UDP;
else rule->fw_proto = atoi(p);
/* source */
p = strsep(&str, " ");
if (strcmp(p, "all") == 0)
return (0);
if (strcmp(p, "from") != 0)
goto icmp_type_code;
p = strsep(&str, " ");
if (parse_addr(p, &rule->fw_src) < 0)
return (-1);
/* source port */
p = strsep(&str, " ");
if (strcmp(p, "port") == 0) {
if ((p = strstr(str, " to ")) == NULL)
return (-1);
*p++ = '\0';
if (parse_portspec(str, rule->fw_sport) < 0)
return (-1);
str = p + 3;
} else if (strcmp(p, "to") != 0)
return (-1);
/* destination */
p = strsep(&str, " ");
if (parse_addr(p, &rule->fw_dst) < 0)
return (-1);
/* destination port */
p = strsep(&str, " ");
if (strcmp(p, "port") == 0)
return (parse_portspec(str, rule->fw_dport));
icmp_type_code:
/* icmp-type, code */
if (strcmp(p, "icmp-type") == 0) {
if (parse_icmpspec(str, rule->fw_sport, rule->fw_dport) < 0)
return (-1);
}
return (0);
}
static int
format_rule(const struct fw_rule *rule, char *buf, int len)
{
char tmp[128];
strlcpy(buf, (rule->fw_op == FW_OP_ALLOW) ? "pass " : "block ", len);
strlcat(buf, (rule->fw_dir == FW_DIR_IN) ? "in " : "out ", len);
snprintf(tmp, sizeof(tmp), "on %s ", rule->fw_device);
strlcat(buf, tmp, len);
if (rule->fw_proto != 0) {
snprintf(tmp, sizeof(tmp), "proto %d ", rule->fw_proto);
strlcat(buf, tmp, len);
}
/* source */
if (rule->fw_src.addr_type != ADDR_TYPE_NONE) {
snprintf(tmp, sizeof(tmp), "from %s ",
addr_ntoa(&rule->fw_src));
strlcat(buf, tmp, len);
} else
strlcat(buf, "from any ", len);
/* sport */
if (rule->fw_proto == IP_PROTO_TCP || rule->fw_proto == IP_PROTO_UDP) {
if (rule->fw_sport[0] == rule->fw_sport[1])
snprintf(tmp, sizeof(tmp), "port = %d ",
rule->fw_sport[0]);
else
snprintf(tmp, sizeof(tmp), "port %d >< %d ",
rule->fw_sport[0] - 1, rule->fw_sport[1] + 1);
strlcat(buf, tmp, len);
}
/* destination */
if (rule->fw_dst.addr_type != ADDR_TYPE_NONE) {
snprintf(tmp, sizeof(tmp), "to %s ",
addr_ntoa(&rule->fw_dst));
strlcat(buf, tmp, len);
} else
strlcat(buf, "to any ", len);
/* dport */
if (rule->fw_proto == IP_PROTO_TCP || rule->fw_proto == IP_PROTO_UDP) {
if (rule->fw_dport[0] == rule->fw_dport[1])
snprintf(tmp, sizeof(tmp), "port = %d",
rule->fw_dport[0]);
else
snprintf(tmp, sizeof(tmp), "port %d >< %d",
rule->fw_dport[0] - 1, rule->fw_dport[1] + 1);
strlcat(buf, tmp, len);
} else if (rule->fw_proto == IP_PROTO_ICMP) {
if (rule->fw_sport[1]) {
snprintf(tmp, sizeof(tmp), "icmp-type %d",
rule->fw_sport[0]);
strlcat(buf, tmp, len);
if (rule->fw_dport[1]) {
snprintf(tmp, sizeof(tmp), " code %d",
rule->fw_dport[0]);
strlcat(buf, tmp, len);
}
}
}
return (strlen(buf));
}
static char *
call_pipe(const char *msg, int len)
{
HANDLE *pipe;
DWORD i;
char *p, *reply, status;
if (!WaitNamedPipe(PKTFILTER_PIPE, NMPWAIT_USE_DEFAULT_WAIT) ||
(pipe = CreateFile(PKTFILTER_PIPE, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) {
return (NULL);
}
reply = NULL;
if (WriteFile(pipe, msg, len, &i, NULL)) {
if (ReadFile(pipe, &status, sizeof(status), &i, NULL)) {
if (status == FILTER_FAILURE) {
ReadFile(pipe, &status, sizeof(status),
&i, NULL);
} else if (status == FILTER_MESSAGE) {
/* get msg length */
if (ReadFile(pipe, &len, 4, &i, NULL)) {
/* get msg */
p = reply = calloc(1, len + 1);
if (!ReadFile(pipe, reply, len,
&i, NULL)) {
free(reply);
reply = NULL;
}
}
} else if (status == FILTER_SUCCESS)
reply = strdup(""); /* XXX */
}
}
CloseHandle(pipe);
return (reply);
}
fw_t *
fw_open(void)
{
fw_t *f;
IP_ADAPTER_INFO *ifinfo;
ULONG size;
if ((f = calloc(1, sizeof(*f))) == NULL)
return (NULL);
size = sizeof(*f->ifinfo);
f->ifinfo = malloc(size);
if (GetAdaptersInfo(f->ifinfo, &size) != ERROR_SUCCESS) {
free(f->ifinfo);
f->ifinfo = malloc(size);
GetAdaptersInfo(f->ifinfo, &size);
}
/* XXX - normalize interface names. */
for (ifinfo = f->ifinfo; ifinfo != NULL; ifinfo = ifinfo->Next) {
char *fmt;
if (ifinfo->Type == MIB_IF_TYPE_ETHERNET)
fmt = "eth";
else if (ifinfo->Type == MIB_IF_TYPE_PPP)
fmt = "ppp";
else if (ifinfo->Type == MIB_IF_TYPE_SLIP)
fmt = "sl";
else if (ifinfo->Type == MIB_IF_TYPE_LOOPBACK)
fmt = "lo";
else if (ifinfo->Type == MIB_IF_TYPE_TOKENRING)
fmt = "tr";
else if (ifinfo->Type == MIB_IF_TYPE_FDDI)
fmt = "fd";
else
fmt = "if";
sprintf(ifinfo->AdapterName, "%s%lu", fmt, ifinfo->ComboIndex);
}
return (f);
}
int
fw_add(fw_t *f, const struct fw_rule *rule)
{
char *p, buf[MAX_RULE_LENGTH];
int len;
len = format_rule(rule, buf, sizeof(buf));
if ((p = call_pipe(buf, len)) == NULL)
return (-1);
free(p);
return (0);
}
int
fw_delete(fw_t *f, const struct fw_rule *rule)
{
struct fw_rule tmp;
char *p, *line, *msg, cmd[128], buf[MAX_RULE_LENGTH];
int n, ruleno, len;
format_rule(rule, buf, sizeof(buf));
len = snprintf(cmd, sizeof(cmd), "List on %s", rule->fw_device);
if ((msg = call_pipe(cmd, len)) == NULL)
return (-1);
for (ruleno = 0, p = msg; (line = strsep(&p, "\r\n")) != NULL; ) {
if (strncmp(line, "rule ", 5) == 0) {
line += 5;
n = atoi(strsep(&line, ":"));
if (parse_rule(line + 1, &tmp) == 0 &&
memcmp(&tmp, rule, sizeof(tmp)) == 0) {
ruleno = n;
break;
}
}
}
free(msg);
if (ruleno == 0) {
errno = ENXIO;
SetLastError(ERROR_NO_DATA);
return (-1);
}
len = snprintf(cmd, sizeof(cmd), "delete %d on %s",
ruleno, rule->fw_device);
if ((p = call_pipe(cmd, len)) == NULL)
return (-1);
free(p);
return (0);
}
int
fw_loop(fw_t *f, fw_handler callback, void *arg)
{
struct fw_rule rule;
IP_ADAPTER_INFO *ifinfo;
char *p, *line, *msg, buf[MAX_RULE_LENGTH];
int len, ret;
for (ret = 0, ifinfo = f->ifinfo; ret == 0 && ifinfo != NULL;
ifinfo = ifinfo->Next) {
len = snprintf(buf, sizeof(buf), "list on %s",
ifinfo->AdapterName);
if ((msg = call_pipe(buf, len)) == NULL)
return (-1);
/* parse msg */
for (p = msg; (line = strsep(&p, "\r\n")) != NULL; ) {
if (*line == '\0' || *line == '#' || isspace(*line))
continue;
if (parse_rule(line, &rule) == 0) {
if ((ret = callback(&rule, arg)) != 0)
break;
}
}
free(msg);
}
return (ret);
}
fw_t *
fw_close(fw_t *f)
{
if (f != NULL) {
free(f->ifinfo);
free(f);
}
return (NULL);
}

View File

@@ -174,22 +174,22 @@ void win_init()
// Try to initialize winpcap
#ifdef _MSC_VER
__try
try
#endif
{
ULONG len = sizeof(pcaplist);
pcap_avail = 1;
if(o.debugging > 2) printf("***WinIP*** trying to initialize winpcap 2.1\n");
if(o.debugging > 2) printf("***WinIP*** trying to initialize winpcap 3.1\n");
PacketGetAdapterNames(pcaplist, &len);
if(o.debugging)
printf("Winpcap present, dynamic linked to: %s\n", pcap_lib_version());
}
#ifdef _MSC_VER
__except(GetExceptionCode() == DLI_ERROR)
catch(...)
{
pcap_avail = 0;
printf("WARNING: Failed to locate Winpcap. Nmap may not function properly until this is installed! WinPcap is freely available from http://winpcap.polito.it.\n");
printf("WARNING: Failed to locate/load Winpcap. Nmap may not function properly until version 3.1 or later is installed! WinPcap is freely available from http://winpcap.polito.it.\n");
}
#endif
@@ -199,11 +199,15 @@ void win_init()
#if defined(_MSC_VER) && _MSC_VER >= 1300
if(pcap_avail)
{
try {
if(FAILED(__HrLoadAllImportsForDll("wpcap.dll")))
{
error("WARNING: your winpcap is too old to use. Nmap may not function.\n");
pcap_avail = 0;
}
} catch (...) {
error("WARNING: Could not import all necessary WinPcap functions. You may need to upgrade to version 3.1 or higher from http://www.winpcap.org. Resorting to connect() mode -- Nmap may not function completely");
}
}
#endif
@@ -260,7 +264,7 @@ static FARPROC WINAPI winip_dli_fail_hook(unsigned code, PDelayLoadInfo info)
printf(" failed to load dll: %s\n", info->szDll);
if(!stricmp(info->szDll, "wpcap.dll"))
printf(" this is most likely because you have"
" winpcap 2.0 (2.1 or later is required)\n"
" winpcap 2.0 (3.1 or later is required)\n"
"Get it from http://netgroup-serv.polito.it/winpcap\n");
break;

29
nmap.cc
View File

@@ -227,6 +227,7 @@ int nmap_main(int argc, char *argv[]) {
char **fakeargv;
Target *currenths;
vector<Target *> Targets;
char *portlist = NULL; /* Ports list specified by user */
char *proberr;
char emptystring[1];
int sourceaddrwarning = 0; /* Have we warned them yet about unguessable
@@ -414,7 +415,7 @@ int nmap_main(int argc, char *argv[]) {
} else if (optcmp(long_options[option_index].name, "append-output") == 0) {
o.append_output = 1;
} else if (strcmp(long_options[option_index].name, "noninteractive") == 0) {
/* Do nothing */
o.noninteractive = true;
} else if (optcmp(long_options[option_index].name, "spoof-mac") == 0) {
/* I need to deal with this later, once I'm sure that I have output
files set up, --datadir, etc. */
@@ -709,11 +710,9 @@ int nmap_main(int argc, char *argv[]) {
}
break;
case 'p':
if (ports)
if (ports || portlist)
fatal("Only 1 -p option allowed, separate multiple ranges with commas.");
ports = getpts(optarg);
if (!ports)
fatal("Your port specification string is not parseable");
portlist = strdup(optarg);
break;
case 'q': quashargv++; break;
case 'R': o.resolve_all++; break;
@@ -853,6 +852,14 @@ int nmap_main(int argc, char *argv[]) {
fatal("The fast scan (-F) is incompatible with ping scan");
}
if (portlist) {
ports = getpts(portlist);
if (!ports)
fatal("Your port specification string is not parseable");
free(portlist);
portlist = NULL;
}
if (fastscan && ports) {
fatal("You can specify fast scan (-F) or explicitly select individual ports (-p), but not both");
} else if (fastscan && o.ipprotscan) {
@@ -1488,7 +1495,14 @@ struct scan_lists *getpts(char *origexpr) {
int i;
int tcpportcount = 0, udpportcount = 0, protcount = 0;
struct scan_lists *ports;
int range_type = SCAN_TCP_PORT|SCAN_UDP_PORT|SCAN_PROTOCOLS;
int range_type = 0;
if (o.TCPScan())
range_type |= SCAN_TCP_PORT;
else if (o.UDPScan())
range_type |= SCAN_UDP_PORT;
else if (o.ipprotscan)
range_type |= SCAN_PROTOCOLS;
porttbl = (u8 *) safe_zalloc(65536);
@@ -1725,9 +1739,6 @@ f --spoof \"/usr/local/bin/pico -z hello.c\" -sS -oN e.log example.com/24\n\n");
char *seqreport(struct seq_info *seq) {
static char report[512];
char tmp[256];
char *p;
int i;
snprintf(report, sizeof(report), "TCP Sequence Prediction: Class=%s\n Difficulty=%d (%s)\n", seqclass2ascii(seq->seqclass), seq->index, seqidx2difficultystr(seq->index));
return report;

View File

@@ -104,7 +104,7 @@
#ifndef NMAP_WINCONFIG_H
#define NMAP_WINCONFIG_H
#define NMAP_VERSION "3.97Shmoo"
#define NMAP_VERSION "3.98BETA1"
#define NMAP_NAME "Nmap"
#define NMAP_URL "http://www.insecure.org/nmap"
#define NMAP_PLATFORM "i686-pc-windows-windows"

View File

@@ -172,15 +172,15 @@ distro:
include/queue.h include/stamp-h.in include/config.h.in \
include/err.h INSTALL libdnet-stripped.vcproj LICENSE \
Makefile.am Makefile.am.common Makefile.in NMAP_MODIFICATIONS \
README src/fw-ipf.c src/route-none.c src/ip-cooked.c \
README src/route-none.c src/ip-cooked.c \
src/arp-win32.c src/ip-util.c src/route-win32.c src/fw-none.c \
src/eth-linux.c src/route-bsd.c src/route-linux.c src/fw-pf.c \
src/eth-linux.c src/route-bsd.c src/route-linux.c \
src/tun-bsd.c src/strlcat.c src/tun-none.c src/memcmp.c \
src/route-hpux.c src/addr-util.c src/eth-ndd.c src/ip6.c \
src/intf.c src/Makefile.in src/addr.c src/eth-dlpi.c \
src/fw-ipchains.c src/rand.c src/tun-solaris.c src/intf-win32.c \
src/eth-none.c src/ip.c src/fw-pktfilter.c src/ip-win32.c \
src/fw-ipfw.c src/arp-ioctl.c src/arp-none.c src/Makefile.am \
src/rand.c src/tun-solaris.c src/intf-win32.c \
src/eth-none.c src/ip.c src/ip-win32.c \
src/arp-ioctl.c src/arp-none.c src/Makefile.am \
src/eth-bsd.c src/strsep.c src/err.c src/strlcpy.c src/blob.c \
src/eth-win32.c src/eth-snoop.c src/eth-pfilt.c src/tun-linux.c \
src/arp-bsd.c THANKS TODO \

12
tty.cc
View File

@@ -199,11 +199,19 @@ static int tty_getchar()
return -1;
}
/* This is the best method here. It will catch all of the predefined keypresses and interpret them, and it will also tell you if you should print anything. A value of true being returned means a nonstandard key has been pressed and the calling method should print a status message */
/* This is the best method here. It will catch all of the predefined
keypresses and interpret them, and it will also tell you if you
should print anything. A value of true being returned means a
nonstandard key has been pressed and the calling method should
print a status message */
bool keyWasPressed()
{
int c;
if (o.noninteractive)
return false;
if ((c = tty_getchar()) >= 0) {
// Eat any extra keys (so they can't queue up and print forever)
while (tty_getchar() >= 0);

View File

@@ -215,9 +215,11 @@ char *chomp(char *string) {
considered to be the same), nonzero otherwise. */
int optcmp(const char *a, const char *b) {
while(*a && *b) {
if ((*a == '_' || *a == '-') && (*b != '_' && *b != '-'))
return 1;
if (*a != *b)
if (*a == '_' || *a == '-') {
if (*b != '_' && *b != '-')
return 1;
}
else if (*a != *b)
return 1;
a++; b++;
}