Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Adam Osuchowski
Kea
Commits
edd0b062
Commit
edd0b062
authored
Apr 16, 2013
by
Marcin Siodelski
Browse files
[2902] Moved protocol utility functions to a separate file.
parent
45e29ee0
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/lib/dhcp/Makefile.am
View file @
edd0b062
...
...
@@ -33,6 +33,7 @@ libb10_dhcp___la_SOURCES += option_custom.cc option_custom.h
libb10_dhcp___la_SOURCES
+=
option_data_types.cc option_data_types.h
libb10_dhcp___la_SOURCES
+=
option_definition.cc option_definition.h
libb10_dhcp___la_SOURCES
+=
option_space.cc option_space.h
libb10_dhcp___la_SOURCES
+=
protocol_util.cc protocol_util.h
libb10_dhcp___la_SOURCES
+=
pkt6.cc pkt6.h
libb10_dhcp___la_SOURCES
+=
pkt4.cc pkt4.h
libb10_dhcp___la_SOURCES
+=
pkt_filter.h
...
...
src/lib/dhcp/pkt_filter_lpf.cc
View file @
edd0b062
...
...
@@ -16,94 +16,17 @@
#include
<dhcp/iface_mgr.h>
#include
<dhcp/pkt4.h>
#include
<dhcp/pkt_filter_lpf.h>
#include
<dhcp/protocol_util.h>
#include
<exceptions/exceptions.h>
#include
<linux/if_ether.h>
#include
<linux/if_packet.h>
#include
<netinet/ip.h>
#include
<netinet/udp.h>
using
namespace
isc
::
util
;
namespace
isc
{
namespace
dhcp
{
void
PktFilterLPF
::
assembleEthernetHeader
(
const
Iface
&
iface
,
const
Pkt4Ptr
&
pkt
,
util
::
OutputBuffer
&
out_buf
)
{
std
::
vector
<
uint8_t
>
dest_addr
=
pkt
->
getHWAddr
()
->
hwaddr_
;
if
(
dest_addr
.
empty
())
{
dest_addr
.
resize
(
HWAddr
::
ETHERNET_HWADDR_LEN
);
}
out_buf
.
writeData
(
&
dest_addr
[
0
],
dest_addr
.
size
());
out_buf
.
writeData
(
iface
.
getMac
(),
iface
.
getMacLen
());
out_buf
.
writeUint16
(
0x0800
);
}
void
PktFilterLPF
::
assembleIpUdpHeader
(
const
Pkt4Ptr
&
pkt
,
util
::
OutputBuffer
&
out_buf
)
{
struct
ip
ip_hdr
;
memset
(
&
ip_hdr
,
0
,
sizeof
(
ip_hdr
));
ip_hdr
.
ip_hl
=
(
ip_hdr
.
ip_hl
|
5
)
&
0xF
;
ip_hdr
.
ip_v
=
(
ip_hdr
.
ip_v
|
4
)
&
0xF
;
ip_hdr
.
ip_tos
=
IPTOS_LOWDELAY
;
ip_hdr
.
ip_len
=
htons
(
sizeof
(
ip
)
+
sizeof
(
udphdr
)
+
pkt
->
getBuffer
().
getLength
());
ip_hdr
.
ip_id
=
0
;
ip_hdr
.
ip_off
=
0
;
ip_hdr
.
ip_ttl
=
128
;
ip_hdr
.
ip_p
=
IPPROTO_UDP
;
ip_hdr
.
ip_src
.
s_addr
=
htonl
(
pkt
->
getLocalAddr
());
ip_hdr
.
ip_dst
.
s_addr
=
htonl
(
pkt
->
getRemoteAddr
());
ip_hdr
.
ip_sum
=
checksumFinish
(
checksum
(
reinterpret_cast
<
const
char
*>
(
&
ip_hdr
),
sizeof
(
ip_hdr
)));
out_buf
.
writeData
(
static_cast
<
void
*>
(
&
ip_hdr
),
sizeof
(
ip_hdr
));
struct
udphdr
udp_hdr
;
memset
(
&
udp_hdr
,
0
,
sizeof
(
udp_hdr
));
udp_hdr
.
source
=
htons
(
pkt
->
getLocalPort
());
udp_hdr
.
dest
=
htons
(
pkt
->
getRemotePort
());
udp_hdr
.
len
=
htons
(
sizeof
(
udp_hdr
)
+
pkt
->
getBuffer
().
getLength
());
udp_hdr
.
check
=
0
;
out_buf
.
writeData
(
static_cast
<
void
*>
(
&
udp_hdr
),
sizeof
(
udp_hdr
));
}
uint16_t
PktFilterLPF
::
checksum
(
const
char
*
buf
,
const
uint32_t
buf_size
,
uint32_t
sum
)
{
uint32_t
i
;
for
(
i
=
0
;
i
<
(
buf_size
&
~
1U
);
i
+=
2
)
{
uint16_t
chunk
=
buf
[
i
]
<<
8
|
buf
[
i
+
1
];
sum
+=
chunk
;
if
(
sum
>
0xFFFF
)
{
sum
-=
0xFFFF
;
}
}
if
(
i
<
buf_size
)
{
sum
+=
buf
[
i
]
<<
8
;
if
(
sum
>
0xFFFF
)
{
sum
-=
0xFFFF
;
}
}
return
(
sum
);
}
uint16_t
PktFilterLPF
::
checksumFinish
(
uint16_t
sum
)
{
return
(
htons
(
~
sum
));
}
int
PktFilterLPF
::
openSocket
(
const
Iface
&
iface
,
const
isc
::
asiolink
::
IOAddress
&
,
const
uint16_t
,
const
bool
,
...
...
@@ -131,9 +54,19 @@ PktFilterLPF::openSocket(const Iface& iface, const isc::asiolink::IOAddress&,
}
Pkt4Ptr
PktFilterLPF
::
receive
(
const
Iface
&
,
const
SocketInfo
&
)
{
isc_throw
(
isc
::
NotImplemented
,
"Linux Packet Filtering is not implemented yet"
);
PktFilterLPF
::
receive
(
const
Iface
&
,
const
SocketInfo
&
socket_info
)
{
// @todo: implement this function
unsigned
char
buf
[
1536
];
int
data_len
=
read
(
socket_info
.
sockfd_
,
buf
,
sizeof
(
buf
));
if
(
data_len
<=
0
)
{
return
Pkt4Ptr
();
}
// Length of the Ethernet, IP and UDP.
int
data_offset
=
42
;
Pkt4Ptr
pkt
=
Pkt4Ptr
(
new
Pkt4
(
buf
+
data_offset
,
data_len
-
data_offset
));
return
(
pkt
);
}
int
...
...
@@ -141,9 +74,17 @@ PktFilterLPF::send(const Iface& iface, uint16_t sockfd, const Pkt4Ptr& pkt) {
OutputBuffer
buf
(
14
);
assembleEthernetHeader
(
iface
,
pkt
,
buf
);
assembleIpUdpHeader
(
pkt
,
buf
);
// Ethernet frame header
std
::
vector
<
uint8_t
>
dest_addr
=
pkt
->
getHWAddr
()
->
hwaddr_
;
if
(
dest_addr
.
empty
())
{
dest_addr
.
resize
(
HWAddr
::
ETHERNET_HWADDR_LEN
);
}
writeEthernetHeader
(
iface
.
getMac
(),
&
dest_addr
[
0
],
buf
);
// IP and UDP header
writeIpUdpHeader
(
pkt
,
buf
);
// DHCPv4 message
buf
.
writeData
(
pkt
->
getBuffer
().
getData
(),
pkt
->
getBuffer
().
getLength
());
sockaddr_ll
sa
;
...
...
src/lib/dhcp/protocol_util.cc
0 → 100644
View file @
edd0b062
// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include
<protocol_util.h>
#include
<netinet/ip.h>
#include
<netinet/udp.h>
namespace
isc
{
namespace
dhcp
{
void
writeEthernetHeader
(
const
uint8_t
*
src_hw_addr
,
const
uint8_t
*
dest_hw_addr
,
util
::
OutputBuffer
&
out_buf
)
{
// Write destination and source address.
out_buf
.
writeData
(
dest_hw_addr
,
HWAddr
::
ETHERNET_HWADDR_LEN
);
out_buf
.
writeData
(
src_hw_addr
,
HWAddr
::
ETHERNET_HWADDR_LEN
);
// Type IP.
out_buf
.
writeUint16
(
0x0800
);
}
void
writeIpUdpHeader
(
const
Pkt4Ptr
&
pkt
,
util
::
OutputBuffer
&
out_buf
)
{
struct
ip
ip_hdr
;
memset
(
&
ip_hdr
,
0
,
sizeof
(
ip_hdr
));
ip_hdr
.
ip_hl
=
(
ip_hdr
.
ip_hl
|
5
)
&
0xF
;
ip_hdr
.
ip_v
=
(
ip_hdr
.
ip_v
|
4
)
&
0xF
;
ip_hdr
.
ip_tos
=
IPTOS_LOWDELAY
;
ip_hdr
.
ip_len
=
htons
(
sizeof
(
ip
)
+
sizeof
(
udphdr
)
+
pkt
->
getBuffer
().
getLength
());
ip_hdr
.
ip_id
=
0
;
ip_hdr
.
ip_off
=
0
;
ip_hdr
.
ip_ttl
=
128
;
ip_hdr
.
ip_p
=
IPPROTO_UDP
;
ip_hdr
.
ip_src
.
s_addr
=
htonl
(
pkt
->
getLocalAddr
());
ip_hdr
.
ip_dst
.
s_addr
=
htonl
(
pkt
->
getRemoteAddr
());
ip_hdr
.
ip_sum
=
wrapChecksum
(
calculateChecksum
(
reinterpret_cast
<
const
char
*>
(
&
ip_hdr
),
sizeof
(
ip_hdr
)));
out_buf
.
writeData
(
static_cast
<
void
*>
(
&
ip_hdr
),
sizeof
(
ip_hdr
));
struct
udphdr
udp_hdr
;
memset
(
&
udp_hdr
,
0
,
sizeof
(
udp_hdr
));
udp_hdr
.
source
=
htons
(
pkt
->
getLocalPort
());
udp_hdr
.
dest
=
htons
(
pkt
->
getRemotePort
());
udp_hdr
.
len
=
htons
(
sizeof
(
udp_hdr
)
+
pkt
->
getBuffer
().
getLength
());
udp_hdr
.
check
=
0
;
out_buf
.
writeData
(
static_cast
<
void
*>
(
&
udp_hdr
),
sizeof
(
udp_hdr
));
}
uint16_t
calculateChecksum
(
const
char
*
buf
,
const
uint32_t
buf_size
,
uint32_t
sum
)
{
uint32_t
i
;
for
(
i
=
0
;
i
<
(
buf_size
&
~
1U
);
i
+=
2
)
{
uint16_t
chunk
=
buf
[
i
]
<<
8
|
buf
[
i
+
1
];
sum
+=
chunk
;
if
(
sum
>
0xFFFF
)
{
sum
-=
0xFFFF
;
}
}
if
(
i
<
buf_size
)
{
sum
+=
buf
[
i
]
<<
8
;
if
(
sum
>
0xFFFF
)
{
sum
-=
0xFFFF
;
}
}
return
(
sum
);
}
uint16_t
wrapChecksum
(
uint16_t
sum
)
{
return
(
htons
(
~
sum
));
}
}
}
src/lib/dhcp/protocol_util.h
0 → 100644
View file @
edd0b062
// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef PROTOCOL_UTIL_H
#define PROTOCOL_UTIL_H
#include
<dhcp/pkt4.h>
#include
<util/buffer.h>
#include
<stdint.h>
namespace
isc
{
namespace
dhcp
{
/// @brief Writes ethernet frame header into a buffer.
///
/// @param src_hw_addr source HW address.
/// @param dst_hw_addr destination HW address.
/// @param [out] out_buf buffer where a header is written.
void
writeEthernetHeader
(
const
uint8_t
*
src_hw_addr
,
const
uint8_t
*
dest_hw_addr
,
util
::
OutputBuffer
&
out_buf
);
/// @brief Writes both IP and UDP header into output buffer
///
/// This utility function assembles IP and UDP packet headers for the
/// provided DHCPv4 message. The source and destination addreses and
/// ports stored in the Pkt4 object are copied as source and destination
/// addresses and ports into IP/UDP headers.
///
/// @param pkt DHCPv4 packet to be sent in IP packet
/// @param [out] out_buf buffer where an IP header is written
void
writeIpUdpHeader
(
const
Pkt4Ptr
&
pkt
,
util
::
OutputBuffer
&
out_buf
);
/// @brief Calculates checksum for provided buffer
///
/// @param buf buffer for which the checksum is calculated.
/// @param buf_size size of the buffer for which checksum is calculated.
/// @param sum initial checksum value.
///
/// @return calculated checksum.
uint16_t
calculateChecksum
(
const
char
*
buf
,
const
uint32_t
buf_size
,
uint32_t
sum
=
0
);
/// @brief Wraps the calculated checksum and stores it in network byte order.
///
/// @param sum calculated checksum
///
/// @return wrapped checksum value.
uint16_t
wrapChecksum
(
uint16_t
sum
);
}
}
#endif // PROTOCOL_UTIL_H
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