2 * Copyright (C) 2012 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include "ip_packet.h"
20 #include <utils/debug.h>
22 #include <sys/types.h>
23 #include <netinet/in.h>
24 #include <netinet/ip.h>
25 #ifdef HAVE_NETINET_IP6_H
26 #include <netinet/ip6.h>
29 typedef struct private_ip_packet_t private_ip_packet_t
;
32 * Private additions to ip_packet_t.
34 struct private_ip_packet_t
{
62 * Protocol|Next Header field
68 METHOD(ip_packet_t
, get_version
, u_int8_t
,
69 private_ip_packet_t
*this)
74 METHOD(ip_packet_t
, get_source
, host_t
*,
75 private_ip_packet_t
*this)
80 METHOD(ip_packet_t
, get_destination
, host_t
*,
81 private_ip_packet_t
*this)
86 METHOD(ip_packet_t
, get_encoding
, chunk_t
,
87 private_ip_packet_t
*this)
92 METHOD(ip_packet_t
, get_next_header
, u_int8_t
,
93 private_ip_packet_t
*this)
95 return this->next_header
;
98 METHOD(ip_packet_t
, clone
, ip_packet_t
*,
99 private_ip_packet_t
*this)
101 return ip_packet_create(chunk_clone(this->packet
));
104 METHOD(ip_packet_t
, destroy
, void,
105 private_ip_packet_t
*this)
107 this->src
->destroy(this->src
);
108 this->dst
->destroy(this->dst
);
109 chunk_free(&this->packet
);
114 * Described in header.
116 ip_packet_t
*ip_packet_create(chunk_t packet
)
118 private_ip_packet_t
*this;
119 u_int8_t version
, next_header
;
124 DBG1(DBG_ESP
, "IP packet too short");
128 version
= (packet
.ptr
[0] & 0xf0) >> 4;
136 if (packet
.len
< sizeof(struct ip
))
138 DBG1(DBG_ESP
, "IPv4 packet too short");
141 ip
= (struct ip
*)packet
.ptr
;
142 /* remove any RFC 4303 TFC extra padding */
143 packet
.len
= min(packet
.len
, untoh16(&ip
->ip_len
));
145 src
= host_create_from_chunk(AF_INET
,
146 chunk_from_thing(ip
->ip_src
), 0);
147 dst
= host_create_from_chunk(AF_INET
,
148 chunk_from_thing(ip
->ip_dst
), 0);
149 next_header
= ip
->ip_p
;
152 #ifdef HAVE_NETINET_IP6_H
157 if (packet
.len
< sizeof(struct ip6_hdr
))
159 DBG1(DBG_ESP
, "IPv6 packet too short");
162 ip
= (struct ip6_hdr
*)packet
.ptr
;
163 /* remove any RFC 4303 TFC extra padding */
164 packet
.len
= min(packet
.len
, untoh16(&ip
->ip6_plen
));
166 src
= host_create_from_chunk(AF_INET6
,
167 chunk_from_thing(ip
->ip6_src
), 0);
168 dst
= host_create_from_chunk(AF_INET6
,
169 chunk_from_thing(ip
->ip6_dst
), 0);
170 next_header
= ip
->ip6_nxt
;
173 #endif /* HAVE_NETINET_IP6_H */
175 DBG1(DBG_ESP
, "unsupported IP version");
181 .get_version
= _get_version
,
182 .get_source
= _get_source
,
183 .get_destination
= _get_destination
,
184 .get_next_header
= _get_next_header
,
185 .get_encoding
= _get_encoding
,
193 .next_header
= next_header
,
195 return &this->public;