sns_utils 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +60 -0
- data/Rakefile +34 -0
- data/bin/ipex +14 -0
- data/lib/sns_utils/ip_extractor.rb +88 -0
- data/lib/sns_utils/ipv4.rb +12 -0
- data/lib/sns_utils/ipv6.rb +44 -0
- data/lib/sns_utils/mac.rb +5 -0
- data/lib/sns_utils/version.rb +3 -0
- data/lib/sns_utils.rb +46 -0
- data/man/ipex.1 +56 -0
- data/man/ipex.1.ronn +43 -0
- data/man/ipex.1.txt +53 -0
- data/sns_utils.gemspec +26 -0
- data/spec/fixtures/ipv4_ipv6_mac.log +4 -0
- data/spec/fixtures/ipv4_simple.log +12 -0
- data/spec/fixtures/ipv6_simple.log +172 -0
- data/spec/fixtures/mac_simple.log +6 -0
- data/spec/fixtures/thresholds.log +35 -0
- data/spec/sns_utils/ip_extractor_spec.rb +103 -0
- data/spec/spec_helper.rb +8 -0
- metadata +132 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6a569b79f304d0060cd3d6c21898000777995042
|
4
|
+
data.tar.gz: b15db537d09f79751fdca09d94474a90e185fb76
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a6f4bb613fd181471772a0a60886d5d09332724a3a1b29c014a0fea132b6273f68456a3233945fb26bffbe836737682e34592ed7784ce01fbae8ed35e4ab9da9
|
7
|
+
data.tar.gz: ca7c31915d5669691554b0d46cd6ae448ffef1dc528274a078dc03a8dd09c89d40b805d962fad3e52e1c3d327faf70da91ac968498255ffb40ff966b9ad82219
|
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
spec/fixtures/xlarge.log
|
19
|
+
mac_addrs.txt
|
20
|
+
ip_addrs.txt
|
21
|
+
SOLUTION.txt
|
22
|
+
.idea
|
23
|
+
*.iml
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 sahglie
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# SnsUtils
|
2
|
+
|
3
|
+
Find and extract IP and MAC addresses in FILE based on repeated occurrences.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'sns_utils'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install sns_utils
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
$ gem install gem-man (if you haven't already)
|
21
|
+
$ gem man sns_utils
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
30
|
+
|
31
|
+
|
32
|
+
## Performance Notes
|
33
|
+
|
34
|
+
### Grep Baseline Perf
|
35
|
+
|
36
|
+
xlarge.log is 5GB with 50 million lines
|
37
|
+
|
38
|
+
time grep -c -E '(?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}' spec/fixtures/xlarge.log
|
39
|
+
=> real 12m0.658s
|
40
|
+
user 11m59.672s
|
41
|
+
sys 0m0.991s
|
42
|
+
|
43
|
+
|
44
|
+
xlarge.log is 514MB with 5 million lines
|
45
|
+
|
46
|
+
time grep -c -E '(?:[0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}' spec/fixtures/xlarge.log
|
47
|
+
=> real 1m12.063s
|
48
|
+
user 1m11.956s
|
49
|
+
sys 0m0.108s
|
50
|
+
|
51
|
+
## ip_extract
|
52
|
+
|
53
|
+
xlarge.log is 514MB with 5 million lines
|
54
|
+
|
55
|
+
ip_extract spec/fixtures/xlarge.log
|
56
|
+
=> real 2m18.938s
|
57
|
+
user 2m18.356s
|
58
|
+
sys 0m0.578s
|
59
|
+
|
60
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'ronn'
|
3
|
+
|
4
|
+
|
5
|
+
namespace :man do
|
6
|
+
directory "man"
|
7
|
+
|
8
|
+
Dir["man/*.ronn"].each do |ronn|
|
9
|
+
basename = File.basename(ronn, ".ronn")
|
10
|
+
roff = "man/#{basename}"
|
11
|
+
|
12
|
+
file roff => ["man", ronn] do
|
13
|
+
sh "#{Gem.ruby} -S ronn --roff --pipe #{ronn} > #{roff}"
|
14
|
+
end
|
15
|
+
|
16
|
+
file "#{roff}.txt" => roff do
|
17
|
+
sh "groff -Wall -mtty-char -mandoc -Tascii #{roff} | col -b > #{roff}.txt"
|
18
|
+
end
|
19
|
+
|
20
|
+
task :build_all_pages => "#{roff}.txt"
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Build the man pages"
|
24
|
+
task :build => "man:build_all_pages"
|
25
|
+
|
26
|
+
desc "Clean up from the built man pages"
|
27
|
+
task :clean do
|
28
|
+
rm "man/ipex.1"
|
29
|
+
rm "man/ipex.1.txt"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
task :build => ["man:clean", "man:build"]
|
34
|
+
task :release => ["man:clean", "man:build"]
|
data/bin/ipex
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Exit cleanly from an early interrupt
|
4
|
+
Signal.trap("INT") { exit 1 }
|
5
|
+
|
6
|
+
require_relative "../lib/sns_utils"
|
7
|
+
|
8
|
+
begin
|
9
|
+
SnsUtils::IpExtractor.new(ARGV).run
|
10
|
+
rescue Errno::ENOENT => err
|
11
|
+
abort "ipex: #{err.message}"
|
12
|
+
rescue OptionParser::InvalidOption, OptionParser::InvalidArgument => err
|
13
|
+
abort "usage: ipex FILE [-m MAC_THRESHOLD] [-i IP_THRESHOLD] [-d OUTPUT_DIR]"
|
14
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module SnsUtils
|
2
|
+
class IpExtractor
|
3
|
+
attr_accessor :file, :options
|
4
|
+
attr_accessor :ip_addrs, :ip_addrs_log, :mac_addrs, :mac_addrs_log
|
5
|
+
|
6
|
+
IPV4_REGEX = ::SnsUtils::IPv4::REGEX
|
7
|
+
IPV6_REGEX = ::SnsUtils::IPv6::REGEX
|
8
|
+
MAC_REGEX = ::SnsUtils::MAC::REGEX
|
9
|
+
IP_REGEX = / ((?: ^|\s) (?: #{IPV6_REGEX} | #{IPV4_REGEX} | #{MAC_REGEX}) (?: \s|$)) /xi
|
10
|
+
|
11
|
+
def initialize(argv)
|
12
|
+
@file, @options = parse_options(argv)
|
13
|
+
self.ip_addrs = {}
|
14
|
+
self.mac_addrs = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
extract_addresses
|
19
|
+
log_ip_addrs
|
20
|
+
log_mac_addrs
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def extract_addresses
|
27
|
+
File.open(file, 'r').each do |line|
|
28
|
+
line.scan(IP_REGEX).each { |md| log_addr(md[0].to_s.strip!) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def log_ip_addrs
|
33
|
+
self.ip_addrs_log = ip_addrs.select { |_, count| count >= options.ip_threshold }.keys
|
34
|
+
write_file(::SnsUtils.ip_out_file, ip_addrs_log)
|
35
|
+
end
|
36
|
+
|
37
|
+
def log_mac_addrs
|
38
|
+
self.mac_addrs_log = mac_addrs.select { |_, count| count >= options.mac_threshold }.keys
|
39
|
+
write_file(::SnsUtils.mac_out_file, mac_addrs_log)
|
40
|
+
end
|
41
|
+
|
42
|
+
def write_file(file, entries)
|
43
|
+
file_path = output_dir(options.output_dir, file)
|
44
|
+
File.open(file_path, "w+") do |f|
|
45
|
+
entries.each { |e| f.puts(e) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def output_dir(dir, file)
|
50
|
+
dir ? File.expand_path(File.join(dir, file)) : file
|
51
|
+
end
|
52
|
+
|
53
|
+
def log_addr(ip)
|
54
|
+
key = IPAddr.new(ip).to_string
|
55
|
+
ip_addrs[key] ||= 0
|
56
|
+
ip_addrs[key] += 1
|
57
|
+
rescue IPAddr::InvalidAddressError => e
|
58
|
+
mac_addrs[ip] ||= 0
|
59
|
+
mac_addrs[ip] += 1
|
60
|
+
end
|
61
|
+
|
62
|
+
def parse_options(argv)
|
63
|
+
options = OpenStruct.new
|
64
|
+
options.mac_threshold = 8
|
65
|
+
options.ip_threshold = 10
|
66
|
+
options.output_dir = nil
|
67
|
+
|
68
|
+
parser = OptionParser.new do |opts|
|
69
|
+
opts.on("-m N", Integer, "MAC address threshold, logs entries with N <= occurrences") do |n|
|
70
|
+
options.mac_threshold = Integer(n).abs
|
71
|
+
end
|
72
|
+
|
73
|
+
opts.on("-i N", Integer, "IP address threshold, logs entries with N =< occurrences") do |n|
|
74
|
+
options.ip_threshold = Integer(n).abs
|
75
|
+
end
|
76
|
+
|
77
|
+
opts.on("-d OUTPUT_DIR", String, "Dir used to write output files") do |dir|
|
78
|
+
options.output_dir = dir
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
parser.parse(argv)
|
83
|
+
|
84
|
+
file = argv[0] || raise(OptionParser::InvalidOption.new)
|
85
|
+
[file, options]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module SnsUtils
|
2
|
+
# NOTE: the regexes are from Resolv::IPv4 in ruby's stdlib. They were copied here because we
|
3
|
+
# need to match IPs in the context of a large string and the Resolv regex has string start
|
4
|
+
# and string end anchors which don't allow this.
|
5
|
+
module IPv4
|
6
|
+
REGEX_256 = /0
|
7
|
+
|1(?:[0-9][0-9]?)?
|
8
|
+
|2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
|
9
|
+
|[3-9][0-9]?/x
|
10
|
+
REGEX = /#{REGEX_256}\.#{REGEX_256}\.#{REGEX_256}\.#{REGEX_256}/x
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module SnsUtils
|
2
|
+
# NOTE: the regexes are from Resolv::IPv4 in ruby's stdlib. They were copied here because we
|
3
|
+
# need to match IPs in the context of a large string and the Resolv regex has string start
|
4
|
+
# and string end anchors which don't allow this.
|
5
|
+
module IPv6
|
6
|
+
##
|
7
|
+
# IPv6 address format a:b:c:d:e:f:g:h
|
8
|
+
REGEX_8HEX = /
|
9
|
+
(?:[0-9A-Fa-f]{1,4}:){7}
|
10
|
+
[0-9A-Fa-f]{1,4}
|
11
|
+
/x
|
12
|
+
|
13
|
+
##
|
14
|
+
# Compressed IPv6 address format a::b
|
15
|
+
REGEX_COMPRESSEDHEX = /
|
16
|
+
(?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)? ::
|
17
|
+
(?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?
|
18
|
+
/x
|
19
|
+
|
20
|
+
##
|
21
|
+
# IPv4 mapped IPv6 address format a:b:c:d:e:f:w.x.y.z
|
22
|
+
REGEX_6HEX4DEC = /
|
23
|
+
(?:[0-9A-Fa-f]{1,4}:){6,6}
|
24
|
+
\d+\.\d+\.\d+\.\d+
|
25
|
+
/x
|
26
|
+
|
27
|
+
##
|
28
|
+
# Compressed IPv4 mapped IPv6 address format a::b:w.x.y.z
|
29
|
+
REGEX_COMPRESSEDHEX4DEC = /
|
30
|
+
(?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)? ::
|
31
|
+
(?:[0-9A-Fa-f]{1,4}:)*
|
32
|
+
\d+\.\d+\.\d+\.\d+
|
33
|
+
/x
|
34
|
+
|
35
|
+
##
|
36
|
+
# A composite IPv6 address Regexp.
|
37
|
+
REGEX = /
|
38
|
+
(?:#{REGEX_8HEX}) |
|
39
|
+
(?:#{REGEX_COMPRESSEDHEX}) |
|
40
|
+
(?:#{REGEX_6HEX4DEC}) |
|
41
|
+
(?:#{REGEX_COMPRESSEDHEX4DEC})
|
42
|
+
/x
|
43
|
+
end
|
44
|
+
end
|
data/lib/sns_utils.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require "strscan"
|
3
|
+
require 'ipaddr'
|
4
|
+
require "optparse"
|
5
|
+
require 'ostruct'
|
6
|
+
|
7
|
+
require_relative 'sns_utils/ipv4'
|
8
|
+
require_relative 'sns_utils/ipv6'
|
9
|
+
require_relative 'sns_utils/mac'
|
10
|
+
require_relative "sns_utils/ip_extractor"
|
11
|
+
require_relative "sns_utils/version"
|
12
|
+
|
13
|
+
|
14
|
+
module SnsUtils
|
15
|
+
def self.root
|
16
|
+
@root ||= File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.ip_out_file
|
20
|
+
"ip_addrs.txt"
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.mac_out_file
|
24
|
+
"mac_addrs.txt"
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.create_test_log(line, rep=1_000)
|
28
|
+
File.open("#{::SnsUtils.root}/spec/fixtures/xlarge.log", "w+") do |f|
|
29
|
+
rep.times do
|
30
|
+
f.puts("2013-08-20 16:05:06,975 [http-8082-3] INFO - Rendered text template (0.0ms)")
|
31
|
+
f.puts("2013-08-20 16:05:06,975 [http-8082-3] INFO - Completed 200 OK in 5295ms (Views: 1.0ms | ActiveRecord: 0.0ms)")
|
32
|
+
f.puts(line)
|
33
|
+
f.puts("2013-08-20 16:08:39,281 [http-8082-3] INFO - Redirected to https://apsearch-qa.berkeley.edu/login")
|
34
|
+
f.puts("169.229.216.83 - - [25/Aug/2013:07:02:29 -0700] \"GET / HTTP/1.0\" 302 303 \"-\" \"check_http/v2053 (nagios-plugins 1.4.13)")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
if $PROGRAM_NAME == __FILE__
|
43
|
+
line = "9.9.9 blah blah blah VALID 0.0.0.0 xxxx<<> 2001:0000:1234:0000:0000:C1C0:ABCD:0876 VALID >>> blah blah blah VALID 00:A0:C9:14:C8:29"
|
44
|
+
::SnsUtils.create_test_log(line, 1_000_000)
|
45
|
+
end
|
46
|
+
|
data/man/ipex.1
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
.\" generated with Ronn/v0.7.3
|
2
|
+
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
3
|
+
.
|
4
|
+
.TH "IPEX" "1" "August 2013" "" ""
|
5
|
+
.
|
6
|
+
.SH "NAME"
|
7
|
+
\fBipex\fR \- IP/Mac Address Extractor
|
8
|
+
.
|
9
|
+
.SH "SYNOPSIS"
|
10
|
+
\fBipex FILE [\-m THRESHOLD] [\-i THRESHOLD] [\-d OUTPUT_DIR]\fR
|
11
|
+
.
|
12
|
+
.SH "DESCRIPTION"
|
13
|
+
Find and extract IP and MAC addresses in FILE\. Addresses with repeat occurrences greater than or equal to a given threshold are logged to ip_addrs\.txt and mac_addrs\.txt respectively\. By default, MAC addresses that occur at least 8 times are logged and IP addresses that occur at least 10 times are logged\. All matches are performed as case insensitive\.
|
14
|
+
.
|
15
|
+
.SH "OPTIONS"
|
16
|
+
.
|
17
|
+
.TP
|
18
|
+
\fB\-m\fR
|
19
|
+
Set the MAC address threshold, defaults to 8
|
20
|
+
.
|
21
|
+
.TP
|
22
|
+
\fB\-i\fR
|
23
|
+
Set the IP address threshold, defaults to 10
|
24
|
+
.
|
25
|
+
.TP
|
26
|
+
\fB\-d\fR
|
27
|
+
Specify directory where MAC and IP output files are written to, defaults to current directory
|
28
|
+
.
|
29
|
+
.SH "FORMATS"
|
30
|
+
Matches the following address formats:
|
31
|
+
.
|
32
|
+
.IP "\(bu" 4
|
33
|
+
IPv4: standard format a\.b\.c\.d
|
34
|
+
.
|
35
|
+
.IP "\(bu" 4
|
36
|
+
IPv6: canonical format a:b:c:d:e:f:g:h
|
37
|
+
.
|
38
|
+
.IP "\(bu" 4
|
39
|
+
IPv6: compressed format a::b
|
40
|
+
.
|
41
|
+
.IP "\(bu" 4
|
42
|
+
IPv6: IPv4 mapped IPv6 format a:b:c:d:e:f:w\.x\.y\.z
|
43
|
+
.
|
44
|
+
.IP "\(bu" 4
|
45
|
+
IPv6: compressed IPv4 mapped IPv6 format a::b:w\.x\.y\.z
|
46
|
+
.
|
47
|
+
.IP "\(bu" 4
|
48
|
+
MAC: Separated by \'\-\' aa\-bb\-cc\-dd\-ee\-ff
|
49
|
+
.
|
50
|
+
.IP "\(bu" 4
|
51
|
+
MAC: Separated by \':\' aa:bb:cc:dd:ee:ff
|
52
|
+
.
|
53
|
+
.IP "" 0
|
54
|
+
.
|
55
|
+
.SH "NOTE ON LARGE FILES"
|
56
|
+
Depending on how large the file is, this utility can take a long time to complete: for a 512MB file with (5 million) entries it took just over 2 min \-\- YMMV depending on your hardware
|
data/man/ipex.1.ronn
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
ipex(1) -- IP/Mac Address Extractor
|
2
|
+
=======================================
|
3
|
+
|
4
|
+
## SYNOPSIS
|
5
|
+
|
6
|
+
`ipex FILE [-m THRESHOLD] [-i THRESHOLD] [-d OUTPUT_DIR]`
|
7
|
+
|
8
|
+
## DESCRIPTION
|
9
|
+
|
10
|
+
Find and extract IP and MAC addresses in FILE. Addresses with repeat occurrences
|
11
|
+
greater than or equal to a given threshold are logged to ip_addrs.txt and mac_addrs.txt
|
12
|
+
respectively. By default, MAC addresses that occur at least 8 times are logged
|
13
|
+
and IP addresses that occur at least 10 times are logged. All matches are performed
|
14
|
+
as case insensitive.
|
15
|
+
|
16
|
+
## OPTIONS
|
17
|
+
|
18
|
+
* `-m`:
|
19
|
+
Set the MAC address threshold, defaults to 8
|
20
|
+
|
21
|
+
* `-i`:
|
22
|
+
Set the IP address threshold, defaults to 10
|
23
|
+
|
24
|
+
* `-d`:
|
25
|
+
Specify directory where MAC and IP output files are written to, defaults to
|
26
|
+
current directory
|
27
|
+
|
28
|
+
## FORMATS
|
29
|
+
Matches the following address formats:
|
30
|
+
|
31
|
+
* IPv4: standard format a.b.c.d
|
32
|
+
* IPv6: canonical format a:b:c:d:e:f:g:h
|
33
|
+
* IPv6: compressed format a::b
|
34
|
+
* IPv6: IPv4 mapped IPv6 format a:b:c:d:e:f:w.x.y.z
|
35
|
+
* IPv6: compressed IPv4 mapped IPv6 format a::b:w.x.y.z
|
36
|
+
* MAC: Separated by '-' aa-bb-cc-dd-ee-ff
|
37
|
+
* MAC: Separated by ':' aa:bb:cc:dd:ee:ff
|
38
|
+
|
39
|
+
## NOTE ON LARGE FILES
|
40
|
+
Depending on how large the file is, this utility can take a long time to
|
41
|
+
complete: for a 512MB file with (5 million) entries it took just over 2 min
|
42
|
+
-- YMMV depending on your hardware
|
43
|
+
|
data/man/ipex.1.txt
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
IPEX(1) IPEX(1)
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
NAME
|
6
|
+
ipex - IP/Mac Address Extractor
|
7
|
+
|
8
|
+
SYNOPSIS
|
9
|
+
ipex FILE [-m THRESHOLD] [-i THRESHOLD] [-d OUTPUT_DIR]
|
10
|
+
|
11
|
+
DESCRIPTION
|
12
|
+
Find and extract IP and MAC addresses in FILE. Addresses with repeat
|
13
|
+
occurrences greater than or equal to a given threshold are logged to
|
14
|
+
ip_addrs.txt and mac_addrs.txt respectively. By default, MAC addresses
|
15
|
+
that occur at least 8 times are logged and IP addresses that occur at
|
16
|
+
least 10 times are logged. All matches are performed as case insensi-
|
17
|
+
tive.
|
18
|
+
|
19
|
+
OPTIONS
|
20
|
+
-m Set the MAC address threshold, defaults to 8
|
21
|
+
|
22
|
+
-i Set the IP address threshold, defaults to 10
|
23
|
+
|
24
|
+
-d Specify directory where MAC and IP output files are written to,
|
25
|
+
defaults to current directory
|
26
|
+
|
27
|
+
FORMATS
|
28
|
+
Matches the following address formats:
|
29
|
+
|
30
|
+
o IPv4: standard format a.b.c.d
|
31
|
+
|
32
|
+
o IPv6: canonical format a:b:c:d:e:f:g:h
|
33
|
+
|
34
|
+
o IPv6: compressed format a::b
|
35
|
+
|
36
|
+
o IPv6: IPv4 mapped IPv6 format a:b:c:d:e:f:w.x.y.z
|
37
|
+
|
38
|
+
o IPv6: compressed IPv4 mapped IPv6 format a::b:w.x.y.z
|
39
|
+
|
40
|
+
o MAC: Separated by '-' aa-bb-cc-dd-ee-ff
|
41
|
+
|
42
|
+
o MAC: Separated by ':' aa:bb:cc:dd:ee:ff
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
NOTE ON LARGE FILES
|
47
|
+
Depending on how large the file is, this utility can take a long time
|
48
|
+
to complete: for a 512MB file with (5 million) entries it took just
|
49
|
+
over 2 min -- YMMV depending on your hardware
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
August 2013 IPEX(1)
|
data/sns_utils.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sns_utils/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sns_utils"
|
8
|
+
spec.version = SnsUtils::VERSION
|
9
|
+
spec.authors = ["sahglie"]
|
10
|
+
spec.email = ["sahglie@gmail.com"]
|
11
|
+
spec.description = %q{Find and extract IP and MAC addresses in FILE}
|
12
|
+
spec.summary = %q{Find and extract IP and MAC addresses in FILE}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.files += Dir.glob('man/*')
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_runtime_dependency "ronn"
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rspec", "~> 2.7"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
end
|
@@ -0,0 +1,4 @@
|
|
1
|
+
# blah blah blah VALID 0.0.0.0 xxxx<<> 2001:0000:1234:0000:0000:C1C0:ABCD:0876 VALID >>>
|
2
|
+
# 3ffe:0b00:0000:0000:0001:0000:0000:000a VALID <<<<<<<<<< INVALID 1.1.1.
|
3
|
+
# blah blah blah VALID 99.1.1.1 xxxx<<> VALID FF02:0000:0000:0000:0000:0000:0000:0001 >>>
|
4
|
+
# blah blah blah INVALID a5::91::7 xxxx<<> VALID 00:A0:C9:14:C8:29 >>>
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# NOTE, some of the following IPs are duplicates, just in
|
2
|
+
# a different format so the 81 valid ips map to 61 valid
|
3
|
+
# ips.
|
4
|
+
|
5
|
+
# valid 2001:0000:1234:0000:0000:C1C0:ABCD:0876
|
6
|
+
# valid 3ffe:0b00:0000:0000:0001:0000:0000:000a
|
7
|
+
# valid FF02:0000:0000:0000:0000:0000:0000:0001
|
8
|
+
# valid 0000:0000:0000:0000:0000:0000:0000:0001
|
9
|
+
# valid 0000:0000:0000:0000:0000:0000:0000:0000
|
10
|
+
# valid ::ffff:192.168.1.26
|
11
|
+
# valid 2::10
|
12
|
+
# valid ff02::1
|
13
|
+
# valid fe80::
|
14
|
+
# valid 2002::
|
15
|
+
# valid 2001:db8::
|
16
|
+
# valid 2001:0db8:1234::
|
17
|
+
# valid ::ffff:0:0
|
18
|
+
# valid ::1
|
19
|
+
# valid ::ffff:192.168.1.1
|
20
|
+
# valid 1:2:3:4:5:6:7:8
|
21
|
+
# valid 1:2:3:4:5:6::8
|
22
|
+
# valid 1:2:3:4:5::8
|
23
|
+
# valid 1:2:3:4::8
|
24
|
+
# valid 1:2:3::8
|
25
|
+
# valid 1:2::8
|
26
|
+
# valid 1::8
|
27
|
+
# valid 1::2:3:4:5:6:7
|
28
|
+
# valid 1::2:3:4:5:6
|
29
|
+
# valid 1::2:3:4:5
|
30
|
+
# valid 1::2:3:4
|
31
|
+
# valid 1::2:3
|
32
|
+
# valid 1::8
|
33
|
+
# valid ::2:3:4:5:6:7:8
|
34
|
+
# valid ::2:3:4:5:6:7
|
35
|
+
# valid ::2:3:4:5:6
|
36
|
+
# valid ::2:3:4:5
|
37
|
+
# valid ::2:3:4
|
38
|
+
# valid ::2:3
|
39
|
+
# valid ::8
|
40
|
+
# valid 1:2:3:4:5:6::
|
41
|
+
# valid 1:2:3:4:5::
|
42
|
+
# valid 1:2:3:4::
|
43
|
+
# valid 1:2:3::
|
44
|
+
# valid 1:2::
|
45
|
+
# valid 1::
|
46
|
+
# valid 1:2:3:4:5::7:8
|
47
|
+
# valid 1:2:3:4::7:8
|
48
|
+
# valid 1:2:3::7:8
|
49
|
+
# valid 1:2::7:8
|
50
|
+
# valid 1::7:8
|
51
|
+
# valid 1:2:3:4:5:6:1.2.3.4
|
52
|
+
# valid 1:2:3:4:5::1.2.3.4
|
53
|
+
# valid 1:2:3:4::1.2.3.4
|
54
|
+
# valid 1:2:3::1.2.3.4
|
55
|
+
# valid 1:2::1.2.3.4
|
56
|
+
# valid 1::1.2.3.4
|
57
|
+
# valid 1:2:3:4::5:1.2.3.4
|
58
|
+
# valid 1:2:3::5:1.2.3.4
|
59
|
+
# valid 1:2::5:1.2.3.4
|
60
|
+
# valid 1::5:1.2.3.4
|
61
|
+
# valid 1::5:11.22.33.44
|
62
|
+
# valid 2001:0000:1234:0000:0000:C1C0:ABCD:0876
|
63
|
+
# valid 2001:0000:1234:0000:0000:C1C0:ABCD:0876
|
64
|
+
# valid fe80::217:f2ff:254.7.237.98
|
65
|
+
# valid fe80::217:f2ff:fe07:ed62
|
66
|
+
# valid 2001:DB8:0:0:8:800:200C:417A # unicast, full
|
67
|
+
# valid FF01:0:0:0:0:0:0:101 # multicast, full
|
68
|
+
# valid 0:0:0:0:0:0:0:1 # loopback, full
|
69
|
+
# valid 0:0:0:0:0:0:0:0 # unspecified, full
|
70
|
+
# valid 2001:DB8::8:800:200C:417A # unicast, compressed
|
71
|
+
# valid FF01::101 # multicast, compressed
|
72
|
+
# valid ::1 # loopback, compressed, non-routable
|
73
|
+
# valid :: # unspecified, compressed, non-routable
|
74
|
+
# valid 0:0:0:0:0:0:13.1.68.3 # IPv4-compatible IPv6 address, full, deprecated
|
75
|
+
# valid 0:0:0:0:0:FFFF:129.144.52.38 # IPv4-mapped IPv6 address, full
|
76
|
+
# valid ::13.1.68.3 # IPv4-compatible IPv6 address, compressed, deprecated
|
77
|
+
# valid ::FFFF:129.144.52.38 # IPv4-mapped IPv6 address, compressed
|
78
|
+
# valid fe80:0000:0000:0000:0204:61ff:fe9d:f156
|
79
|
+
# valid fe80:0:0:0:204:61ff:fe9d:f156
|
80
|
+
# valid fe80::204:61ff:fe9d:f156
|
81
|
+
# valid fe80:0:0:0:204:61ff:254.157.241.86
|
82
|
+
# valid fe80::204:61ff:254.157.241.86
|
83
|
+
# valid ::1
|
84
|
+
# valid fe80::
|
85
|
+
# valid fe80::1
|
86
|
+
|
87
|
+
# not valid 02001:0000:1234:0000:0000:C1C0:ABCD:0876 # extra 0 not allowed!
|
88
|
+
# not valid 2001:0000:1234:0000:00001:C1C0:ABCD:0876 # extra 0 not allowed!
|
89
|
+
# not valid 2001:0000:1234:0000:0000:C1C0:ABCD:0876 0
|
90
|
+
# not valid 2001:0000:1234: 0000:0000:C1C0:ABCD:0876
|
91
|
+
# not valid 3ffe:0b00:0000:0001:0000:0000:000a
|
92
|
+
# not valid FF02:0000:0000:0000:0000:0000:0000:0000:0001
|
93
|
+
# not valid 3ffe:b00::1::a
|
94
|
+
# not valid ::1111:2222:3333:4444:5555:6666::
|
95
|
+
# not valid 1:2:3::4:5::7:8
|
96
|
+
# not valid 12345::6:7:8
|
97
|
+
# not valid 1::5:400.2.3.4
|
98
|
+
# not valid 1::5:260.2.3.4
|
99
|
+
# not valid 1::5:256.2.3.4
|
100
|
+
# not valid 1::5:1.256.3.4
|
101
|
+
# not valid 1::5:1.2.256.4
|
102
|
+
# not valid 1::5:1.2.3.256
|
103
|
+
# not valid 1::5:300.2.3.4
|
104
|
+
# not valid 1::5:1.300.3.4
|
105
|
+
# not valid 1::5:1.2.300.4
|
106
|
+
# not valid 1::5:1.2.3.300
|
107
|
+
# not valid 1::5:900.2.3.4
|
108
|
+
# not valid 1::5:1.900.3.4
|
109
|
+
# not valid 1::5:1.2.900.4
|
110
|
+
# not valid 1::5:1.2.3.900
|
111
|
+
# not valid 1::5:300.300.300.300
|
112
|
+
# not valid 1::5:3000.30.30.30
|
113
|
+
# not valid 1::400.2.3.4
|
114
|
+
# not valid 1::260.2.3.4
|
115
|
+
# not valid 1::256.2.3.4
|
116
|
+
# not valid 1::1.256.3.4
|
117
|
+
# not valid 1::1.2.256.4
|
118
|
+
# not valid 1::1.2.3.256
|
119
|
+
# not valid 1::300.2.3.4
|
120
|
+
# not valid 1::1.300.3.4
|
121
|
+
# not valid 1::1.2.300.4
|
122
|
+
# not valid 1::1.2.3.300
|
123
|
+
# not valid 1::900.2.3.4
|
124
|
+
# not valid 1::1.900.3.4
|
125
|
+
# not valid 1::1.2.900.4
|
126
|
+
# not valid 1::1.2.3.900
|
127
|
+
# not valid 1::300.300.300.300
|
128
|
+
# not valid 1::3000.30.30.30
|
129
|
+
# not valid ::400.2.3.4
|
130
|
+
# not valid ::260.2.3.4
|
131
|
+
# not valid ::256.2.3.4
|
132
|
+
# not valid ::1.256.3.4
|
133
|
+
# not valid ::1.2.256.4
|
134
|
+
# not valid ::1.2.3.256
|
135
|
+
# not valid ::300.2.3.4
|
136
|
+
# not valid ::1.300.3.4
|
137
|
+
# not valid ::1.2.300.4
|
138
|
+
# not valid ::1.2.3.300
|
139
|
+
# not valid ::900.2.3.4
|
140
|
+
# not valid ::1.900.3.4
|
141
|
+
# not valid ::1.2.900.4
|
142
|
+
# not valid ::1.2.3.900
|
143
|
+
# not valid ::300.300.300.300
|
144
|
+
# not valid ::3000.30.30.30
|
145
|
+
# not valid 2001:DB8:0:0:8:800:200C:417A:221 # unicast, full
|
146
|
+
# not valid FF01::101::2 # multicast, compressed
|
147
|
+
# not valid # nothing
|
148
|
+
# Not sure about this one; apparently some systems treat the leading "0" in ".086" as the start of an octal number
|
149
|
+
# not valid fe80:0000:0000:0000:0204:61ff:254.157.241.086
|
150
|
+
# not valid :
|
151
|
+
# not valid 1111:2222:3333:4444::5555:
|
152
|
+
# not valid 1111:2222:3333::5555:
|
153
|
+
# not valid 1111:2222::5555:
|
154
|
+
# not valid 1111::5555:
|
155
|
+
# not valid ::5555:
|
156
|
+
# not valid :::
|
157
|
+
# not valid 1111:
|
158
|
+
# not valid :
|
159
|
+
# not valid :1111:2222:3333:4444::5555
|
160
|
+
# not valid :1111:2222:3333::5555
|
161
|
+
# not valid :1111:2222::5555
|
162
|
+
# not valid :1111::5555
|
163
|
+
# not valid :::5555
|
164
|
+
# not valid :::
|
165
|
+
# not valid 1.2.3.4:1111:2222:3333:4444::5555
|
166
|
+
# not valid 1.2.3.4:1111:2222:3333::5555
|
167
|
+
# not valid 1.2.3.4:1111:2222::5555
|
168
|
+
# not valid 1.2.3.4:1111::5555
|
169
|
+
# not valid 1.2.3.4::5555
|
170
|
+
# not valid 1.2.3.4::
|
171
|
+
# not valid 2001:1:1:1:1:1:255Z255X255Y255
|
172
|
+
# not valid ::ffff:192x168.1.26
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# IPv4 occurs 10 times
|
2
|
+
# valid 1.1.1.1
|
3
|
+
# valid 1.1.1.1
|
4
|
+
# valid 1.1.1.1
|
5
|
+
# valid 1.1.1.1
|
6
|
+
# valid 1.1.1.1
|
7
|
+
# valid 1.1.1.1
|
8
|
+
# valid 1.1.1.1
|
9
|
+
# valid 1.1.1.1
|
10
|
+
# valid 1.1.1.1
|
11
|
+
# valid 1.1.1.1
|
12
|
+
|
13
|
+
# MAC occurs 8 times
|
14
|
+
# valid 00:A0:C9:14:C8:29
|
15
|
+
# valid 00:A0:C9:14:C8:29
|
16
|
+
# valid 00:A0:C9:14:C8:29
|
17
|
+
# valid 00:A0:C9:14:C8:29
|
18
|
+
# valid 00:A0:C9:14:C8:29
|
19
|
+
# valid 00:A0:C9:14:C8:29
|
20
|
+
# valid 00:A0:C9:14:C8:29
|
21
|
+
# valid 00:A0:C9:14:C8:29
|
22
|
+
|
23
|
+
# IPv4 occurs 5 times
|
24
|
+
# 0.0.0.0
|
25
|
+
# 0.0.0.0
|
26
|
+
# 0.0.0.0
|
27
|
+
# 0.0.0.0
|
28
|
+
# 0.0.0.0
|
29
|
+
|
30
|
+
# IPv6 occurs 5 times
|
31
|
+
# valid 00:00:00:00:00:00
|
32
|
+
# valid 00:00:00:00:00:00
|
33
|
+
# valid 00:00:00:00:00:00
|
34
|
+
# valid 00:00:00:00:00:00
|
35
|
+
# valid 00:00:00:00:00:00
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require_relative "../spec_helper"
|
2
|
+
|
3
|
+
describe SnsUtils::IpExtractor do
|
4
|
+
context "extracting IPv4 ips" do
|
5
|
+
let(:file) { fixture_path("ipv4_simple.log") }
|
6
|
+
|
7
|
+
it "finds valid entries" do
|
8
|
+
extractor = SnsUtils::IpExtractor.new([file]).run
|
9
|
+
extractor.ip_addrs.should have(5).entries
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "extracting IPv6 ips" do
|
14
|
+
let(:file) { fixture_path("ipv6_simple.log") }
|
15
|
+
|
16
|
+
it "finds valid entries" do
|
17
|
+
extractor = SnsUtils::IpExtractor.new([file]).run
|
18
|
+
extractor.ip_addrs.should have(61).entries
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "extracting MAC addresses" do
|
23
|
+
let(:file) { fixture_path("mac_simple.log") }
|
24
|
+
|
25
|
+
it "finds valid entries" do
|
26
|
+
extractor = SnsUtils::IpExtractor.new([file]).run
|
27
|
+
extractor.mac_addrs.should have(2).entries
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "extracting IPv4, IPv6, and MACs" do
|
32
|
+
let(:file) { fixture_path("ipv4_ipv6_mac.log") }
|
33
|
+
|
34
|
+
it "finds valid entries" do
|
35
|
+
extractor = SnsUtils::IpExtractor.new([file]).run
|
36
|
+
extractor.ip_addrs.should have(5).entries
|
37
|
+
extractor.mac_addrs.should have(1).entry
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "Occurrence threshold options" do
|
42
|
+
let(:file) { fixture_path("thresholds.log") }
|
43
|
+
|
44
|
+
it "raises error for invalid thresholds" do
|
45
|
+
expect { SnsUtils::IpExtractor.new([file, "-i", "x"]) }.to \
|
46
|
+
raise_error(OptionParser::InvalidArgument)
|
47
|
+
|
48
|
+
expect { SnsUtils::IpExtractor.new([file, "-m", "x"]) }.to \
|
49
|
+
raise_error(OptionParser::InvalidArgument)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "has default IP and MAC threshold" do
|
53
|
+
extractor = SnsUtils::IpExtractor.new([file])
|
54
|
+
extractor.options.mac_threshold.should eql(8)
|
55
|
+
extractor.options.ip_threshold.should eql(10)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "uses default IP and MAC threshold" do
|
59
|
+
extractor = SnsUtils::IpExtractor.new([file])
|
60
|
+
extractor.run
|
61
|
+
|
62
|
+
extractor.ip_addrs_log.should have(1).entry
|
63
|
+
extractor.mac_addrs_log.should have(1).entry
|
64
|
+
end
|
65
|
+
|
66
|
+
it "adjusts default IP and MAC threshold" do
|
67
|
+
extractor = SnsUtils::IpExtractor.new([file, "-i", "5", "-m", "4"])
|
68
|
+
extractor.options.mac_threshold.should eql(4)
|
69
|
+
extractor.options.ip_threshold.should eql(5)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "uses adjusted IP and MAC threshold" do
|
73
|
+
extractor = SnsUtils::IpExtractor.new([file, "-i", "5", "-m", "5"]).run
|
74
|
+
extractor.ip_addrs_log.should have(2).entries
|
75
|
+
extractor.mac_addrs_log.should have(2).entries
|
76
|
+
|
77
|
+
extractor = SnsUtils::IpExtractor.new([file, "-i", "11", "-m", "11"]).run
|
78
|
+
extractor.ip_addrs_log.should be_empty
|
79
|
+
extractor.mac_addrs_log.should be_empty
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "Output dir option" do
|
84
|
+
let(:file) { fixture_path("ipv4_simple.log") }
|
85
|
+
let(:tmp_dir) { "#{::SnsUtils.root}/tmp" }
|
86
|
+
|
87
|
+
after(:all) do
|
88
|
+
File.delete("#{tmp_dir}/#{::SnsUtils.ip_out_file}")
|
89
|
+
File.delete("#{tmp_dir}/#{::SnsUtils.mac_out_file}")
|
90
|
+
end
|
91
|
+
|
92
|
+
it "configures custom output directory" do
|
93
|
+
options = SnsUtils::IpExtractor.new([file, "-d", tmp_dir]).options
|
94
|
+
options.output_dir.should eql(tmp_dir)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "writes to custom output directory" do
|
98
|
+
SnsUtils::IpExtractor.new([file, "-d", tmp_dir]).run
|
99
|
+
File.exists?("#{tmp_dir}/#{::SnsUtils.ip_out_file}").should be_true
|
100
|
+
File.exists?("#{tmp_dir}/#{::SnsUtils.mac_out_file}").should be_true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sns_utils
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- sahglie
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ronn
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.7'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.7'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Find and extract IP and MAC addresses in FILE
|
70
|
+
email:
|
71
|
+
- sahglie@gmail.com
|
72
|
+
executables:
|
73
|
+
- ipex
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- .gitignore
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- bin/ipex
|
83
|
+
- lib/sns_utils.rb
|
84
|
+
- lib/sns_utils/ip_extractor.rb
|
85
|
+
- lib/sns_utils/ipv4.rb
|
86
|
+
- lib/sns_utils/ipv6.rb
|
87
|
+
- lib/sns_utils/mac.rb
|
88
|
+
- lib/sns_utils/version.rb
|
89
|
+
- man/ipex.1
|
90
|
+
- man/ipex.1.ronn
|
91
|
+
- man/ipex.1.txt
|
92
|
+
- sns_utils.gemspec
|
93
|
+
- spec/fixtures/ipv4_ipv6_mac.log
|
94
|
+
- spec/fixtures/ipv4_simple.log
|
95
|
+
- spec/fixtures/ipv6_simple.log
|
96
|
+
- spec/fixtures/mac_simple.log
|
97
|
+
- spec/fixtures/thresholds.log
|
98
|
+
- spec/sns_utils/ip_extractor_spec.rb
|
99
|
+
- spec/spec_helper.rb
|
100
|
+
homepage: ''
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
metadata: {}
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 2.0.3
|
121
|
+
signing_key:
|
122
|
+
specification_version: 4
|
123
|
+
summary: Find and extract IP and MAC addresses in FILE
|
124
|
+
test_files:
|
125
|
+
- spec/fixtures/ipv4_ipv6_mac.log
|
126
|
+
- spec/fixtures/ipv4_simple.log
|
127
|
+
- spec/fixtures/ipv6_simple.log
|
128
|
+
- spec/fixtures/mac_simple.log
|
129
|
+
- spec/fixtures/thresholds.log
|
130
|
+
- spec/sns_utils/ip_extractor_spec.rb
|
131
|
+
- spec/spec_helper.rb
|
132
|
+
has_rdoc:
|