Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ITS - Intelligent Transport Systems
ITS
Commits
95494388
Commit
95494388
authored
Jun 14, 2017
by
garciay
Browse files
Layers ongoing
parent
487062a3
Changes
4
Hide whitespace changes
Inline
Side-by-side
ccsrc/Framework/Layer.hh
View file @
95494388
...
...
@@ -5,6 +5,7 @@
#include
<vector>
#include
"Params.hh"
#include
"loggers.hh"
class
OCTETSTRING
;
...
...
@@ -23,7 +24,14 @@ class Layer {
virtual
void
receiveData
(
const
OCTETSTRING
&
data
,
const
Params
&
info
)
{};
protected:
void
toAllLayers
(
std
::
vector
<
Layer
*>&
layers
,
const
OCTETSTRING
&
data
,
const
Params
&
info
)
{};
inline
void
toAllLayers
(
std
::
vector
<
Layer
*>&
layers
,
const
OCTETSTRING
&
data
,
const
Params
&
info
)
{
// loggers::loggers::log_msg(">>> Layer::toAllLayer: ", data);
loggers
::
loggers
::
log
(
">>> Layer::toAllLayer: %d"
,
layers
.
size
());
for
(
std
::
vector
<
Layer
*>::
const_iterator
it
=
layers
.
cbegin
();
it
!=
layers
.
cend
();
++
it
)
{
Layer
*
p
=
*
it
;
p
->
receiveData
(
data
,
info
);
}
// End of 'for' statement
};
inline
void
toAllUpperLayers
(
const
OCTETSTRING
&
data
,
const
Params
&
info
)
{
toAllLayers
(
upperLayers
,
data
,
info
);
}
inline
void
toAllLowerLayers
(
const
OCTETSTRING
&
data
,
const
Params
&
info
)
{
toAllLayers
(
upperLayers
,
data
,
info
);
}
inline
void
receiveToAllLayers
(
const
OCTETSTRING
&
data
,
const
Params
&
info
)
{
toAllLayers
(
upperLayers
,
data
,
info
);
}
...
...
ccsrc/Protocols/ETH/EthernetLayer.cc
View file @
95494388
...
...
@@ -13,6 +13,19 @@ void EthernetLayer::sendData(const OCTETSTRING& data, const Params& params) {
}
void
EthernetLayer
::
receiveData
(
const
OCTETSTRING
&
data
,
const
Params
&
info
)
{
loggers
::
loggers
::
log_msg
(
">>> EthernetLayer::receiveData: "
,
data
);
// Extract dest MAC Address
OCTETSTRING
dst
=
data
<<
6
;
loggers
::
loggers
::
log_msg
(
"EthernetLayer::receiveData: dst: "
,
dst
);
// Extract source MAC Address
OCTETSTRING
src
=
data
<<
6
;
loggers
::
loggers
::
log_msg
(
"EthernetLayer::receiveData: src: "
,
src
);
// Extract ethertype
OCTETSTRING
type
=
data
<<
2
;
loggers
::
loggers
::
log_msg
(
"EthernetLayer::receiveData: type: "
,
type
);
// Update params
loggers
::
loggers
::
log_msg
(
"<<< EthernetLayer::receiveData: "
,
data
);
}
class
EthernetFactory
:
public
LayerFactory
{
...
...
ccsrc/Protocols/Pcap/PcapLayer.cc
View file @
95494388
#include
"PORT.hh"
#include
<unistd.h>
#include
<fcntl.h>
#include
<sys/stat.h>
#include
<errno.h>
#include
<thread>
#include
<chrono>
#include
"Port.hh"
#include
"PcapLayer.hh"
#include
"loggers.hh"
PcapLayer
::
PcapLayer
(
const
std
::
string
&
type
,
const
std
::
string
&
param
)
:
PcapLayer
()
{
loggers
::
loggers
::
log
(
">>> PcapLayer::PcapLayer: %s, %s"
,
type
.
c_str
(),
param
.
c_str
());
// Setup parameters
Params
::
convert
(
_params
,
param
);
_params
.
log
();
// char error_buffer[64];
// pcap_if_t devices = NULL;
//
// if (pcap_findalldevs(devices, error_buffer) == -1) {
// // Add throw exception
// }
//
// _pcap_h = pcap_get_selectable(_device);
loggers
::
loggers
::
log
(
">>> PcapLayer::PcapLayer: %s, %s"
,
type
.
c_str
(),
param
.
c_str
());
// Setup parameters
Params
::
convert
(
_params
,
param
);
_params
.
log
();
// Prepare capture processing
char
error_buffer
[
PCAP_ERRBUF_SIZE
];
std
::
map
<
std
::
string
,
std
::
string
>::
const_iterator
it
=
_params
.
find
(
std
::
string
(
"nic"
));
if
((
it
!=
_params
.
end
())
&&
!
it
->
second
.
empty
())
{
// Use online capture
// Fetch the network address and network mask
/*bpf_u_int32 mask; // subnet mask
bpf_u_int32 net; // ip address
if (pcap_lookupnet(_params["nic"].c_str(), &net, &mask, error_buffer) != 0) {
loggers::loggers::error("PcapLayer::PcapLayer: PcapLayer::PcapLayer: Failed to fetch newtork address for device %s", _params["nic"].c_str());
}
loggers::loggers::log("PcapLayer::PcapLayer: Device %s Network address: %d", _params["nic"].c_str(), net);*/
// Open the device
_device
=
pcap_open_live
(
_params
[
"nic"
].
c_str
(),
65536
,
1
,
1000
,
error_buffer
);
// TODO Replace hard coded values by PcapLayer::<constants>
if
(
_device
==
NULL
)
{
loggers
::
loggers
::
error
(
"PcapLayer::PcapLayer: Failed to open device %s"
,
_params
[
"nic"
].
c_str
());
}
// else, continue
// Set non-blocking flag for the polling procedure
if
(
pcap_setnonblock
(
_device
,
1
,
error_buffer
)
!=
0
)
{
loggers
::
loggers
::
error
(
"PcapLayer::PcapLayer: Failed to set blocking mode: %s"
,
error_buffer
);
}
// Retrieve the device file handler
_pcap_h
=
pcap_get_selectable_fd
(
_device
);
if
(
_pcap_h
==
-
1
)
{
loggers
::
loggers
::
error
(
"PcapLayer::PcapLayer: Failed to get device handler"
);
}
}
else
{
// Check file name
it
=
_params
.
find
(
std
::
string
(
"file"
));
if
((
it
!=
_params
.
end
())
&&
!
it
->
second
.
empty
())
{
// Use offline capture
struct
stat
s
=
{
0
};
if
((
stat
(
_params
[
"file"
].
c_str
(),
&
s
)
!=
0
)
||
!
S_ISREG
(
s
.
st_mode
))
{
loggers
::
loggers
::
error
(
"PcapLayer::PcapLayer: Failed to acces PCAP file %s"
,
_params
[
"file"
].
c_str
());
}
// File exist, open it
_device
=
pcap_open_offline
(
_params
[
"file"
].
c_str
(),
error_buffer
);
if
(
_device
==
NULL
)
{
loggers
::
loggers
::
error
(
"PcapLayer::PcapLayer: Failed to open PCAP file %s"
,
error_buffer
);
}
// else, continue
}
else
{
loggers
::
loggers
::
error
(
"PcapLayer::PcapLayer: Failed to open PCAP file %s"
,
error_buffer
);
}
}
// Setup filter
std
::
string
filter
;
it
=
_params
.
find
(
std
::
string
(
"filter"
));
if
((
it
!=
_params
.
end
())
&&
!
it
->
second
.
empty
())
{
filter
=
_params
[
"filter"
];
}
// else nothing to do
loggers
::
loggers
::
log
(
"PcapLayer::PcapLayer: Filter: %s"
,
filter
.
c_str
());
if
(
!
filter
.
empty
())
{
struct
bpf_program
f
=
{
0
};
if
(
pcap_compile
(
_device
,
&
f
,
filter
.
c_str
(),
1
,
PCAP_NETMASK_UNKNOWN
)
!=
0
)
{
loggers
::
loggers
::
error
(
"PcapLayer::PcapLayer: Failed to compile PCAP filter"
);
}
if
(
pcap_setfilter
(
_device
,
&
f
)
!=
0
)
{
loggers
::
loggers
::
error
(
"PcapLayer::PcapLayer: Failed to set PCAP filter"
);
}
pcap_freecode
(
&
f
);
}
// Pass the device file handler to the polling procedure
if
(
_pcap_h
!=
-
1
)
{
Handler_Add_Fd_Read
(
_pcap_h
);
}
else
{
// Create a pipe
if
(
pipe2
(
_fd
,
O_NONBLOCK
)
==
-
1
)
{
loggers
::
loggers
::
error
(
"PcapLayer::PcapLayer: Failed to create a pipe: %s"
,
::
strerror
(
errno
));
}
// Pass the pipe handler to the polling procedure
loggers
::
loggers
::
log
(
"PcapLayer::PcapLayer: Call handler with descriptor %d"
,
_fd
[
0
]);
Handler_Add_Fd_Read
(
_fd
[
0
]);
if
(
pthread_create
(
&
_thread_id
,
NULL
,
&
PcapLayer
::
run
,
(
void
*
)
this
)
!=
0
)
{
loggers
::
loggers
::
error
(
"PcapLayer::PcapLayer: Failed to compile PCAP filter"
);
}
// Start a working thread to dispatch packet to a pipe
while
(
_running
==
FALSE
)
{
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
seconds
(
1
));
}
loggers
::
loggers
::
log
(
"<<< PcapLayer::PcapLayer"
);
}
}
// End of ctor
PcapLayer
::~
PcapLayer
()
{
loggers
::
loggers
::
log
(
">>> PcapLayer::~PcapLayer"
);
if
(
_device
!=
NULL
)
{
if
(
_fd
[
0
]
!=
-
1
)
{
// TODO To be refined :-(
_running
=
FALSE
;
// Wait for the working thread to terminate
pthread_join
(
_thread_id
,
NULL
);
loggers
::
loggers
::
log
(
"PcapLayer::~PcapLayer: Thread were stops"
);
// Cleanup
close
(
_fd
[
0
]);
close
(
_fd
[
1
]);
}
pcap_close
(
_device
);
}
}
// End of dtor
void
*
PcapLayer
::
run
(
void
*
p_this
)
{
loggers
::
loggers
::
log
(
">>> PcapLayer::run: Class pointer: %p"
,
p_this
);
PcapLayer
&
p
=
*
static_cast
<
PcapLayer
*>
(
p_this
);
p
.
_running
=
TRUE
;
p
.
_resume
=
TRUE
;
while
(
p
.
_running
)
{
if
(
p
.
_resume
==
TRUE
)
{
write
(
p
.
_fd
[
1
],
"
\n
"
,
1
);
p
.
_resume
=
FALSE
;
}
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
200
));
}
loggers
::
loggers
::
log
(
"<<< PcapLayer::run"
);
return
NULL
;
}
void
PcapLayer
::
sendData
(
const
OCTETSTRING
&
data
,
const
Params
&
params
)
{
loggers
::
loggers
::
log_msg
(
">>> PcapLayer::sendData: "
,
data
);
loggers
::
loggers
::
log_msg
(
">>> PcapLayer::sendData: "
,
data
);
}
void
PcapLayer
::
receiveData
(
const
OCTETSTRING
&
data
,
const
Params
&
params
)
{
//loggers::loggers::log(">>> PcapLayer::receiveData: Received %d bytes", data.lengthof());
//loggers::loggers::log_to_hexa("Packet dump", data);
// Pass the packet to the upper layers
toAllUpperLayers
(
data
,
params
);
}
void
PcapLayer
::
receiveData
(
const
OCTETSTRING
&
data
,
const
Params
&
info
)
{
void
PcapLayer
::
Handle_Fd_Event_Readable
(
int
fd
)
{
//loggers::loggers::log(">>> PcapLayer::Handle_Fd_Event_Readable: %d", fd);
struct
pcap_pkthdr
*
pkt_header
;
const
u_char
*
pkt_data
;
int
result
=
pcap_next_ex
(
_device
,
&
pkt_header
,
&
pkt_data
);
if
(
result
==
1
)
{
// Succeed
if
(
pkt_header
->
caplen
>
14
)
{
// Reject too small packet
//loggers::loggers::log("PcapLayer::Handle_Fd_Event_Readable: %.6d - %d", pkt_header->ts.tv_usec, pkt_header->len);
// Fill parameters from PCAP layer
Params
params
;
params
.
insert
(
std
::
pair
<
std
::
string
,
std
::
string
>
(
std
::
string
(
"timestamp"
),
std
::
to_string
(
pkt_header
->
ts
.
tv_usec
)));
// Process the packet at this layer
this
->
receiveData
(
OCTETSTRING
(
pkt_header
->
len
,
pkt_data
),
params
);
}
}
// else, skip the packet
// Specific to offline mode
if
(
_fd
[
0
]
!=
-
1
)
{
// Check if offline mode is used
//loggers::loggers::log("PcapLayer::Handle_Fd_Event_Readable: Read pipe");
char
c
[
2
];
read
(
_fd
[
0
],
&
c
,
1
);
if
(
result
==
-
2
)
{
// End of file, therminate worker thread
_running
=
FALSE
;
}
else
{
// Get next packet
loggers
::
loggers
::
log
(
"PcapLayer::Handle_Fd_Event_Readable: pcap_next_ex failed: result=%d"
,
result
);
_resume
=
TRUE
;
}
}
// else, nothing to do
}
class
PcapFactory
:
public
LayerFactory
{
static
PcapFactory
_f
;
static
PcapFactory
_f
;
public:
PcapFactory
();
virtual
Layer
*
createLayer
(
const
std
::
string
&
type
,
const
std
::
string
&
param
);
PcapFactory
();
virtual
Layer
*
createLayer
(
const
std
::
string
&
type
,
const
std
::
string
&
param
);
};
PcapFactory
::
PcapFactory
()
{
// register factory
loggers
::
loggers
::
log
(
">>> PcapFactory::PcapFactory"
);
LayerStackBuilder
::
RegisterLayerFactory
(
"PCAP"
,
this
);
// register factory
loggers
::
loggers
::
log
(
">>> PcapFactory::PcapFactory"
);
LayerStackBuilder
::
RegisterLayerFactory
(
"PCAP"
,
this
);
}
Layer
*
PcapFactory
::
createLayer
(
const
std
::
string
&
type
,
const
std
::
string
&
param
)
{
return
new
PcapLayer
(
type
,
param
);
return
new
PcapLayer
(
type
,
param
);
}
PcapFactory
PcapFactory
::
_f
;
ccsrc/Protocols/Pcap/PcapLayer.hh
View file @
95494388
#pragma once
//#include <pcap.h>
#include
<pthread.h>
#include
<pcap/pcap.h>
#include
"Layer.hh"
#include
"Params.hh"
...
...
@@ -8,17 +9,23 @@
class
PORT
;
class
PcapLayer
:
public
PORT
,
public
Layer
{
Params
_params
;
// pcap_t *_device;
int
_pcap_h
;
Params
_params
;
pcap_t
*
_device
;
int
_pcap_h
;
pthread_t
_thread_id
;
bool
_running
;
bool
_resume
;
int
_fd
[
2
];
virtual
void
Handle_Fd_Event_Readable
(
int
fd
)
{}
;
public:
inline
PcapLayer
()
:
PORT
(
"PcapLayer"
),
Layer
(),
_params
(),
/*
_device(NULL),
*/
_pcap_h
(
-
1
)
{}
PcapLayer
(
const
std
::
string
&
type
,
const
std
::
string
&
param
);
virtual
~
PcapLayer
()
{}
static
void
*
run
(
void
*
p_this
)
;
public:
inline
PcapLayer
()
:
PORT
(
"PcapLayer"
),
Layer
(),
_params
(),
_device
(
NULL
),
_pcap_h
(
-
1
)
,
_thread_id
(
-
1
),
_running
(
FALSE
),
_resume
(
FALSE
)
{
_fd
[
0
]
=
-
1
;
_fd
[
1
]
=
-
1
;
};
PcapLayer
(
const
std
::
string
&
type
,
const
std
::
string
&
param
);
virtual
~
PcapLayer
()
;
virtual
void
sendData
(
const
OCTETSTRING
&
data
,
const
Params
&
params
);
virtual
void
receiveData
(
const
OCTETSTRING
&
data
,
const
Params
&
info
);
virtual
void
sendData
(
const
OCTETSTRING
&
data
,
const
Params
&
params
);
virtual
void
receiveData
(
const
OCTETSTRING
&
data
,
const
Params
&
info
);
void
Handle_Fd_Event_Readable
(
int
fd
);
};
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment