ffi-pcap 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +10 -0
- data/ChangeLog.rdoc +27 -0
- data/LICENSE.txt +23 -0
- data/README.rdoc +30 -0
- data/Rakefile +26 -0
- data/VERSION +1 -0
- data/examples/ipfw_divert.rb +49 -0
- data/examples/print_bytes.rb +17 -0
- data/lib/ffi-pcap.rb +1 -0
- data/lib/ffi/pcap.rb +42 -0
- data/lib/ffi/pcap/addr.rb +21 -0
- data/lib/ffi/pcap/bpf.rb +106 -0
- data/lib/ffi/pcap/bsd.rb +98 -0
- data/lib/ffi/pcap/capture_wrapper.rb +289 -0
- data/lib/ffi/pcap/common_wrapper.rb +175 -0
- data/lib/ffi/pcap/copy_handler.rb +38 -0
- data/lib/ffi/pcap/crt.rb +15 -0
- data/lib/ffi/pcap/data_link.rb +173 -0
- data/lib/ffi/pcap/dead.rb +37 -0
- data/lib/ffi/pcap/dumper.rb +55 -0
- data/lib/ffi/pcap/error_buffer.rb +44 -0
- data/lib/ffi/pcap/exceptions.rb +21 -0
- data/lib/ffi/pcap/file_header.rb +26 -0
- data/lib/ffi/pcap/in_addr.rb +9 -0
- data/lib/ffi/pcap/interface.rb +29 -0
- data/lib/ffi/pcap/live.rb +303 -0
- data/lib/ffi/pcap/offline.rb +53 -0
- data/lib/ffi/pcap/packet.rb +164 -0
- data/lib/ffi/pcap/packet_header.rb +24 -0
- data/lib/ffi/pcap/pcap.rb +252 -0
- data/lib/ffi/pcap/stat.rb +57 -0
- data/lib/ffi/pcap/time_val.rb +48 -0
- data/lib/ffi/pcap/typedefs.rb +27 -0
- data/lib/ffi/pcap/version.rb +6 -0
- data/spec/data_link_spec.rb +65 -0
- data/spec/dead_spec.rb +34 -0
- data/spec/dumps/http.pcap +0 -0
- data/spec/dumps/simple_tcp.pcap +0 -0
- data/spec/error_buffer_spec.rb +17 -0
- data/spec/file_header_spec.rb +28 -0
- data/spec/live_spec.rb +87 -0
- data/spec/offline_spec.rb +61 -0
- data/spec/packet_behaviors.rb +68 -0
- data/spec/packet_injection_spec.rb +38 -0
- data/spec/packet_spec.rb +111 -0
- data/spec/pcap_spec.rb +149 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/wrapper_behaviors.rb +124 -0
- data/tasks/rcov.rb +6 -0
- data/tasks/rdoc.rb +17 -0
- data/tasks/spec.rb +9 -0
- data/tasks/yard.rb +21 -0
- metadata +157 -0
data/.gitignore
ADDED
data/ChangeLog.rdoc
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
=== 0.2.0 / 2010-04-22
|
2
|
+
* emonti fork merged back into sophsec/ffi-pcap
|
3
|
+
* ... ignore that whole "caper" thing. It will return as another lib entirely.
|
4
|
+
|
5
|
+
=== 0.1.4 / 2010-04-20 (emonti/ffi-pcap)
|
6
|
+
* Fixes and example for pcap dumper
|
7
|
+
|
8
|
+
=== 0.1.3 / 2010-03-05 (emonti/ffi-pcap)
|
9
|
+
* Minor fixes for ruby 1.9 compatability
|
10
|
+
|
11
|
+
=== 0.1.2 / 2010-01-03 (emonti/ffi-pcap)
|
12
|
+
* Branched from sophsec/ffi-pcap by emonti
|
13
|
+
* Using ffi_dry for common struct interface
|
14
|
+
* Redesigned the pcap-specific pcap_pkthdr struct.
|
15
|
+
* Dismantled all other network packet parsing code.
|
16
|
+
* 'Handlers' have been split out into type-specific 'Wrappers' by features.
|
17
|
+
* The namespace 'Handler' has been reused instead for pcap_handler abstraction
|
18
|
+
* Added filtering support and interfaces for compiling filters into bpf code.
|
19
|
+
* Added packet injection on Live pcap interfaces.
|
20
|
+
* Tackled some minor Jruby compatability issues.
|
21
|
+
* Lots of documentation added throughout with yardoc tags.
|
22
|
+
* Lots of misc namespace mods and such, and some general refactoring.
|
23
|
+
* Lots of other stuff I'm probably forgetting.
|
24
|
+
* specs all pass on OS X, Linux, and Win32(except 1 which is a known issue)
|
25
|
+
|
26
|
+
=== 0.1.0 / 2009-04-29 (sophsec/ffi-pcap)
|
27
|
+
* Initial release.
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
The MIT License
|
3
|
+
|
4
|
+
Copyright (c) 2009-2010 Hal Brodigan
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
'Software'), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
20
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
21
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
22
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
23
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
= ffi-pcap
|
2
|
+
|
3
|
+
* [github.com/sophsec/ffi-pcap](http://github.com/sophsec/ffi-pcap/)
|
4
|
+
* [github.com/sophsec/ffi-pcap/issues](http://github.com/sophsec/ffi-pcap/issues)
|
5
|
+
* Postmodern (postmodern.mod3 at gmail.com)
|
6
|
+
* Eric Monti (esmonti at gmail.com)
|
7
|
+
|
8
|
+
== Description
|
9
|
+
|
10
|
+
Ruby FFI bindings for libpcap.
|
11
|
+
|
12
|
+
== Features
|
13
|
+
|
14
|
+
== Examples
|
15
|
+
|
16
|
+
== Requirements
|
17
|
+
|
18
|
+
* [libpcap](http://www.tcpdump.org/) or [winpcap](http://winpcap.org/)
|
19
|
+
* [ffi](http://github.com/ffi/ffi) >= 0.5.0
|
20
|
+
* [ffi_dry](http://github.com/emonti/ffi_dry) >= 0.1.9
|
21
|
+
|
22
|
+
== Install
|
23
|
+
|
24
|
+
$ sudo gem install ffi-pcap
|
25
|
+
|
26
|
+
== License
|
27
|
+
|
28
|
+
See {file:LICENSE.txt} for license information.
|
29
|
+
|
30
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
Dir["tasks/*.rb"].each {|rt| require rt }
|
5
|
+
require 'rake/clean'
|
6
|
+
require './lib/ffi/pcap/version.rb'
|
7
|
+
|
8
|
+
# Generate a gem using jeweler
|
9
|
+
begin
|
10
|
+
require 'jeweler'
|
11
|
+
Jeweler::Tasks.new do |gemspec|
|
12
|
+
gemspec.rubyforge_project = 'ffi-pcap'
|
13
|
+
gemspec.name = "ffi-pcap"
|
14
|
+
gemspec.summary = "FFI bindings for libpcap"
|
15
|
+
gemspec.email = "postmodern.mod3@gmail.com"
|
16
|
+
gemspec.homepage = "http://github.com/sophsec/ffi-pcap"
|
17
|
+
gemspec.description = "Bindings to libpcap via FFI interface in Ruby."
|
18
|
+
gemspec.authors = ["Postmodern", "Dakrone", "Eric Monti"]
|
19
|
+
gemspec.add_dependency "ffi", ">= 0.5.0"
|
20
|
+
gemspec.add_dependency "ffi_dry", ">= 0.1.9"
|
21
|
+
end
|
22
|
+
rescue LoadError
|
23
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
24
|
+
end
|
25
|
+
|
26
|
+
# vim: syntax=Ruby
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.0
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Thanks to justfalter(Mike Ryan) for turning me onto Divert Sockets for
|
4
|
+
# this example.
|
5
|
+
#
|
6
|
+
# ipfw add tee 6666 tcp from 192.168.63.128 to any
|
7
|
+
# ipfw add tee 6666 tcp from any to 192.168.63.128
|
8
|
+
|
9
|
+
require 'ffi/pcap'
|
10
|
+
require "socket"
|
11
|
+
require 'pp'
|
12
|
+
|
13
|
+
unless Process::Sys.getuid == 0
|
14
|
+
$stderr.puts "Must run #{$0} as root."
|
15
|
+
exit!
|
16
|
+
end
|
17
|
+
|
18
|
+
IPPROTO_DIVERT = 254
|
19
|
+
|
20
|
+
outfile = ARGV.shift
|
21
|
+
#outfile = "test_#{$$}.pcap"
|
22
|
+
|
23
|
+
# create a dummy pcap handle for dumping
|
24
|
+
pcap = FFI::PCap.open_dead(:datalink => :raw)
|
25
|
+
pcap_dumper = pcap.open_dump(outfile)
|
26
|
+
|
27
|
+
begin
|
28
|
+
divert_sock = Socket.open(Socket::PF_INET, Socket::SOCK_RAW, IPPROTO_DIVERT)
|
29
|
+
sockaddr = Socket.pack_sockaddr_in( 6666, '0.0.0.0' )
|
30
|
+
divert_sock.bind(sockaddr)
|
31
|
+
|
32
|
+
puts "ready and waiting...."
|
33
|
+
|
34
|
+
while IO.select([divert_sock], nil, nil)
|
35
|
+
data = divert_sock.recv(65535) # or MTU?
|
36
|
+
pp data
|
37
|
+
pcap_dumper.write_pkt( FFI::PCap::Packet.from_string(data) )
|
38
|
+
pcap_dumper.flush
|
39
|
+
end
|
40
|
+
rescue Errno::EPERM
|
41
|
+
$stderr.puts "Must run #{$0} as root."
|
42
|
+
exit!
|
43
|
+
ensure
|
44
|
+
puts "Closing socket."
|
45
|
+
divert_sock.close
|
46
|
+
puts "Closing pcap dumper."
|
47
|
+
pcap_dumper.close
|
48
|
+
pcap.close
|
49
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'ffi/pcap'
|
5
|
+
|
6
|
+
pcap =
|
7
|
+
FFI::PCap::Live.new(:dev => 'en0',
|
8
|
+
:promisc => true,
|
9
|
+
:handler => FFI::PCap::Handler)
|
10
|
+
|
11
|
+
pcap.loop() do |this,pkt|
|
12
|
+
puts "#{pkt.time}:"
|
13
|
+
|
14
|
+
pkt.captured.times {|i| print ' %.2x' % pkt.body_ptr.get_uchar(i) }
|
15
|
+
putc "\n"
|
16
|
+
end
|
17
|
+
|
data/lib/ffi-pcap.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'ffi/pcap'
|
data/lib/ffi/pcap.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
begin; require 'rubygems'; rescue LoadError; end
|
2
|
+
|
3
|
+
require 'ffi_dry'
|
4
|
+
|
5
|
+
module FFI
|
6
|
+
module PCap
|
7
|
+
extend FFI::Library
|
8
|
+
|
9
|
+
begin
|
10
|
+
ffi_lib "wpcap"
|
11
|
+
rescue LoadError
|
12
|
+
ffi_lib "pcap"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'ffi/pcap/crt'
|
18
|
+
|
19
|
+
require 'ffi/pcap/version'
|
20
|
+
require 'ffi/pcap/exceptions'
|
21
|
+
|
22
|
+
# FFI typedefs, pointer wrappers, and struct
|
23
|
+
require 'ffi/pcap/typedefs'
|
24
|
+
require 'ffi/pcap/bsd'
|
25
|
+
require 'ffi/pcap/addr'
|
26
|
+
require 'ffi/pcap/interface'
|
27
|
+
require 'ffi/pcap/file_header'
|
28
|
+
require 'ffi/pcap/time_val'
|
29
|
+
require 'ffi/pcap/packet_header'
|
30
|
+
require 'ffi/pcap/stat'
|
31
|
+
require 'ffi/pcap/bpf'
|
32
|
+
require 'ffi/pcap/dumper'
|
33
|
+
|
34
|
+
# Ruby FFI function bindings, sugar, and misc wrappers
|
35
|
+
require 'ffi/pcap/error_buffer'
|
36
|
+
require 'ffi/pcap/pcap'
|
37
|
+
require 'ffi/pcap/data_link'
|
38
|
+
require 'ffi/pcap/packet'
|
39
|
+
require 'ffi/pcap/live'
|
40
|
+
require 'ffi/pcap/offline'
|
41
|
+
require 'ffi/pcap/dead'
|
42
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
module FFI
|
3
|
+
module PCap
|
4
|
+
|
5
|
+
# Representation of an interface address.
|
6
|
+
#
|
7
|
+
# See pcap_addr struct in pcap.h
|
8
|
+
class Addr < FFI::Struct
|
9
|
+
include FFI::DRY::StructHelper
|
10
|
+
|
11
|
+
dsl_layout do
|
12
|
+
p_struct :next, ::FFI::PCap::Addr
|
13
|
+
p_struct :addr, ::FFI::PCap::SockAddr, :desc => 'address'
|
14
|
+
p_struct :netmask, ::FFI::PCap::SockAddr, :desc => 'netmask of the address'
|
15
|
+
p_struct :broadcast, ::FFI::PCap::SockAddr, :desc => 'broadcast for the address'
|
16
|
+
p_struct :dest_addr, ::FFI::PCap::SockAddr, :desc => 'p2p destination for address'
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/ffi/pcap/bpf.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
|
2
|
+
module FFI
|
3
|
+
module PCap
|
4
|
+
|
5
|
+
# Includes structures defined in pcap-bpf.h
|
6
|
+
|
7
|
+
# Berkeley Packet Filter instruction data structure.
|
8
|
+
#
|
9
|
+
# See bpf_insn struct in pcap-bpf.h
|
10
|
+
class BPFInstruction < FFI::Struct
|
11
|
+
include FFI::DRY::StructHelper
|
12
|
+
|
13
|
+
dsl_layout do
|
14
|
+
field :code, :ushort
|
15
|
+
field :jt, :uchar
|
16
|
+
field :jf, :uchar
|
17
|
+
field :k, :bpf_int32
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
# Structure for pcap_compile(), pcap_setfilter(), etc.
|
23
|
+
#
|
24
|
+
# See bpf_program struct in pcap-bpf.h
|
25
|
+
class BPFProgram < FFI::Struct
|
26
|
+
include FFI::DRY::StructHelper
|
27
|
+
|
28
|
+
dsl_layout do
|
29
|
+
field :bf_len, :uint
|
30
|
+
field :bf_insn, :pointer
|
31
|
+
end
|
32
|
+
|
33
|
+
def instructions
|
34
|
+
i = 0
|
35
|
+
sz = BPFInstruction.size()
|
36
|
+
Array.new(self.bf_len) do
|
37
|
+
ins = BPFInstruction.new( self[:bf_insn] + i )
|
38
|
+
i += sz
|
39
|
+
ins
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def free!
|
44
|
+
unless @closed
|
45
|
+
@freed = true
|
46
|
+
FFI::PCap.pcap_freecode(self)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def freed?
|
51
|
+
return @freed == true
|
52
|
+
end
|
53
|
+
|
54
|
+
# Compiles a bpf filter without a pcap device being open. Downside is
|
55
|
+
# no error messages are available, whereas they are when you use
|
56
|
+
# open_dead() and use compile() on the resulting Dead.
|
57
|
+
#
|
58
|
+
# @param [Hash] opts
|
59
|
+
# Additional options for compile
|
60
|
+
#
|
61
|
+
# @option opts [optional, DataLink, Integer, String, Symbol] :datalink
|
62
|
+
# DataLink layer type. The argument type will be resolved to a DataLink
|
63
|
+
# value if possible. Defaults to data-link layer type NULL.
|
64
|
+
#
|
65
|
+
# @option opts [optional, Integer] :snaplen
|
66
|
+
# The snapshot length for the filter. Defaults to SNAPLEN
|
67
|
+
#
|
68
|
+
# @option opts [optional, Integer] :optimize
|
69
|
+
# Optimization flag. 0 means don't optimize. Defaults to 1.
|
70
|
+
#
|
71
|
+
# @option opts [optional, Integer] :netmask
|
72
|
+
# A 32-bit number representing the IPv4 netmask of the network on which
|
73
|
+
# packets are being captured. It is only used when checking for IPv4
|
74
|
+
# broadcast addresses in the filter program. Default: 0 (unspecified
|
75
|
+
# netmask)
|
76
|
+
#
|
77
|
+
# @return [BPFProgram]
|
78
|
+
# If no errors occur, a compiled BPFProgram is returned.
|
79
|
+
#
|
80
|
+
def self.compile(expr, opts={})
|
81
|
+
datalink = (opts[:datalink] || 1)
|
82
|
+
dl = datalink.kind_of?(DataLink) ? datalink : DataLink.new(datalink)
|
83
|
+
slen = (opts[:snaplen] || DEFAULT_SNAPLEN)
|
84
|
+
optimize = (opts[:optimize] || 1)
|
85
|
+
mask = (opts[:netmask] || 0)
|
86
|
+
code = BPFProgram.new()
|
87
|
+
r = FFI::PCap.pcap_compile_nopcap(slen, dl.value, code, expr, optimize, mask)
|
88
|
+
raise(LibError, "pcap_compile_nopcap(): unspecified error") if r < 0
|
89
|
+
return code
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
attach_function :pcap_compile_nopcap, [:int, :int, BPFProgram, :string, :int, :bpf_uint32], :int
|
96
|
+
|
97
|
+
attach_function :bpf_filter, [BPFInstruction, :pointer, :uint, :uint], :uint
|
98
|
+
attach_function :bpf_validate, [BPFInstruction, :int], :int
|
99
|
+
attach_function :bpf_image, [BPFInstruction, :int], :string
|
100
|
+
attach_function :bpf_dump, [BPFProgram, :int], :void
|
101
|
+
attach_function :pcap_freecode, [BPFProgram], :void
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
|
data/lib/ffi/pcap/bsd.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# Here's where various BSD sockets typedefs and structures go
|
2
|
+
# ... good to have around
|
3
|
+
# cribbed from dnet-ffi - EM
|
4
|
+
|
5
|
+
require 'socket'
|
6
|
+
|
7
|
+
module FFI
|
8
|
+
module PCap
|
9
|
+
typedef :uint8, :sa_family_t
|
10
|
+
typedef :uint32, :in_addr_t
|
11
|
+
typedef :uint16, :in_port_t
|
12
|
+
|
13
|
+
# contains AF_* constants culled from Ruby's ::Socket
|
14
|
+
module AF
|
15
|
+
include ::FFI::DRY::ConstMap
|
16
|
+
slurp_constants(::Socket, "AF_")
|
17
|
+
def self.list; @@list ||= super() ; end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Common abstract superclass for all sockaddr struct classes
|
21
|
+
#
|
22
|
+
class SockAddrFamily < ::FFI::Struct
|
23
|
+
include ::FFI::DRY::StructHelper
|
24
|
+
|
25
|
+
# returns an address family name for the :family struct member value
|
26
|
+
def lookup_family
|
27
|
+
AF[ self[:family] ]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# generic sockaddr, always good to have around
|
32
|
+
#
|
33
|
+
class SockAddr < SockAddrFamily
|
34
|
+
dsl_layout do
|
35
|
+
field :len, :uint8, :desc => 'total length of struct'
|
36
|
+
field :family, :sa_family_t, :desc => 'address family (AF_*)'
|
37
|
+
field :data, :char, :desc => 'variable length bound by :len'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# Used to represent a 32-bit IPv4 address in a sock_addr_in structure
|
43
|
+
#
|
44
|
+
class InAddr < ::FFI::Struct
|
45
|
+
include ::FFI::DRY::StructHelper
|
46
|
+
dsl_layout { field :in_addr, :in_addr_t, :desc => 'inet address' }
|
47
|
+
end
|
48
|
+
|
49
|
+
# sockaddr inet, always good to have around
|
50
|
+
#
|
51
|
+
class SockAddrIn < SockAddrFamily
|
52
|
+
dsl_layout do
|
53
|
+
field :len, :uint8, :desc => 'length of structure (16)'
|
54
|
+
field :family, :sa_family_t, :desc => 'address family (AF_INET)'
|
55
|
+
field :port, :in_port_t, :desc => '16-bit TCP or UDP port number'
|
56
|
+
field :addr, :in_addr_t, :desc => '32-bit IPv4 address'
|
57
|
+
array :_sa_zero, [:uint8,8], :desc => 'unused'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Used to represent an IPv6 address in a sock_addr_in6 structure
|
62
|
+
#
|
63
|
+
class In6Addr < ::FFI::Struct
|
64
|
+
include ::FFI::DRY::StructHelper
|
65
|
+
dsl_layout { array :s6_addr, [:uint8, 16], :desc => 'IPv6 address' }
|
66
|
+
end
|
67
|
+
|
68
|
+
# IPv6 socket address
|
69
|
+
#
|
70
|
+
class SockAddrIn6 < SockAddrFamily
|
71
|
+
dsl_layout do
|
72
|
+
field :len, :uint8, :desc => 'length of structure(24)'
|
73
|
+
field :family, :sa_family_t, :desc => 'address family (AF_INET6)'
|
74
|
+
field :port, :in_port_t, :desc => 'transport layer port'
|
75
|
+
field :flowinfo, :uint32, :desc => 'priority & flow label'
|
76
|
+
struct :addr, ::FFI::PCap::In6Addr, :desc => 'IPv6 address'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
# data-link socket address
|
82
|
+
#
|
83
|
+
class SockAddrDl < SockAddrFamily
|
84
|
+
dsl_layout do
|
85
|
+
field :len, :uint8, :desc => 'length of structure(variable)'
|
86
|
+
field :family, :sa_family_t, :desc => 'address family (AF_LINK)'
|
87
|
+
field :sdl_index, :uint16, :desc => 'system assigned index, if > 0'
|
88
|
+
field :dltype, :uint8, :desc => 'IFT_ETHER, etc. from net/if_types.h'
|
89
|
+
field :nlen, :uint8, :desc => 'name length, from :_data'
|
90
|
+
field :alen, :uint8, :desc => 'link-layer addres-length'
|
91
|
+
field :slen, :uint8, :desc => 'link-layer selector length'
|
92
|
+
field :_data, :char, :desc => 'minimum work area=12, can be larger'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|