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 <netinet/in.h>
23 #include <netinet/ip.h>
24 #ifdef HAVE_NETINET_IP6_H
25 #include <netinet/ip6.h>
28 typedef struct private_ip_packet_t private_ip_packet_t
;
31 * Private additions to ip_packet_t.
33 struct private_ip_packet_t
{
61 * Protocol|Next Header field
67 METHOD(ip_packet_t
, get_version
, u_int8_t
,
68 private_ip_packet_t
*this)
73 METHOD(ip_packet_t
, get_source
, host_t
*,
74 private_ip_packet_t
*this)
79 METHOD(ip_packet_t
, get_destination
, host_t
*,
80 private_ip_packet_t
*this)
85 METHOD(ip_packet_t
, get_encoding
, chunk_t
,
86 private_ip_packet_t
*this)
91 METHOD(ip_packet_t
, get_next_header
, u_int8_t
,
92 private_ip_packet_t
*this)
94 return this->next_header
;
97 METHOD(ip_packet_t
, clone
, ip_packet_t
*,
98 private_ip_packet_t
*this)
100 return ip_packet_create(this->packet
);
103 METHOD(ip_packet_t
, destroy
, void,
104 private_ip_packet_t
*this)
106 this->src
->destroy(this->src
);
107 this->dst
->destroy(this->dst
);
108 chunk_free(&this->packet
);
113 * Described in header.
115 ip_packet_t
*ip_packet_create(chunk_t packet
)
117 private_ip_packet_t
*this;
118 u_int8_t version
, next_header
;
123 DBG1(DBG_ESP
, "IP packet too short");
127 version
= (packet
.ptr
[0] & 0xf0) >> 4;
135 if (packet
.len
< sizeof(struct ip
))
137 DBG1(DBG_ESP
, "IPv4 packet too short");
140 ip
= (struct ip
*)packet
.ptr
;
141 src
= host_create_from_chunk(AF_INET
,
142 chunk_from_thing(ip
->ip_src
), 0);
143 dst
= host_create_from_chunk(AF_INET
,
144 chunk_from_thing(ip
->ip_dst
), 0);
145 next_header
= ip
->ip_p
;
148 #ifdef HAVE_NETINET_IP6_H
153 if (packet
.len
< sizeof(struct ip6_hdr
))
155 DBG1(DBG_ESP
, "IPv6 packet too short");
158 ip
= (struct ip6_hdr
*)packet
.ptr
;
159 src
= host_create_from_chunk(AF_INET6
,
160 chunk_from_thing(ip
->ip6_src
), 0);
161 dst
= host_create_from_chunk(AF_INET6
,
162 chunk_from_thing(ip
->ip6_dst
), 0);
163 next_header
= ip
->ip6_nxt
;
166 #endif /* HAVE_NETINET_IP6_H */
168 DBG1(DBG_ESP
, "unsupported IP version");
174 .get_version
= _get_version
,
175 .get_source
= _get_source
,
176 .get_destination
= _get_destination
,
177 .get_next_header
= _get_next_header
,
178 .get_encoding
= _get_encoding
,
186 .next_header
= next_header
,
188 return &this->public;