- wrote clone function for packed
[strongswan.git] / Source / charon / packet.c
1 /**
2 * @file packet.c
3 *
4 * @brief UDP-Packet, contains data, sender and receiver.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include "allocator.h"
24 #include "packet.h"
25
26
27 /**
28 * Private data of an packet_t object
29 */
30 typedef struct private_packet_s private_packet_t;
31
32 struct private_packet_s {
33
34 /**
35 * Public part of a packet_t object
36 */
37 packet_t public;
38
39 /* private functions */
40
41 /**
42 * @brief helper function to set address used by set_dest & set_source.
43 *
44 * @param this calling object_t
45 * @param family address family
46 * @param saddr source address
47 * @param address address as string
48 * @return
49 * - SUCCESS if successfuly
50 * - NOT_SUPPORTED if family is not supported
51 */
52 status_t (*set_addr) (private_packet_t *this, int family, struct sockaddr *saddr, char *address, u_int16_t port);
53 };
54
55 /**
56 * Implements packet_t's destroy function.
57 * See #packet_s.destroy for description.
58 */
59 static status_t destroy(private_packet_t *this)
60 {
61 if (this->public.data.ptr != NULL)
62 {
63 allocator_free(this->public.data.ptr);
64 }
65 allocator_free(this);
66 return SUCCESS;
67 }
68
69 /**
70 * Implements packet_t's clone function.
71 * See #packet_s.clone for description.
72 */
73 static status_t clone (private_packet_t *packet, packet_t **clone)
74 {
75 *clone = packet_create(packet->public.family);
76 if ((*clone) == NULL)
77 {
78
79 return OUT_OF_RES;
80 }
81
82
83 (*clone)->sockaddr_len = packet->public.sockaddr_len;
84 (*clone)->source = packet->public.source;
85 (*clone)->destination = packet->public.destination;
86 /* only clone existing chunks :-) */
87 if (packet->public.data.ptr != NULL)
88 {
89 (*clone)->data.ptr = allocator_clone_bytes(packet->public.data.ptr,packet->public.data.len);
90 if ((*clone)->data.ptr == NULL)
91 {
92 (*clone)->destroy((*clone));
93 return OUT_OF_RES;
94 }
95 (*clone)->data.len = packet->public.data.len;
96 }
97 return SUCCESS;
98 }
99
100 /**
101 * Implements private_packet_t's set_addr function.
102 * See #private_packet_t.set_addr for description.
103 */
104 static status_t set_addr(int family, struct sockaddr *saddr, char *address, u_int16_t port)
105 {
106 switch (family)
107 {
108 /* IPv4 */
109 case AF_INET:
110 {
111 struct sockaddr_in *sin = (struct sockaddr_in*)saddr;
112 sin->sin_family = AF_INET;
113 sin->sin_addr.s_addr = inet_addr("127.0.0.1");
114 sin->sin_port = htons(port);
115 return SUCCESS;;
116 }
117 }
118 return NOT_SUPPORTED;
119 }
120
121 /**
122 * Implements packet_t's set_destination function.
123 * See #packet_t.set_destination for description.
124 */
125 static status_t set_destination(packet_t *this, char *address, u_int16_t port)
126 {
127 struct sockaddr *saddr = &(this->destination);
128 return set_addr(this->family, saddr, address, port);
129 }
130
131 /**
132 * Implements packet_t's set_source function.
133 * See #packet_t.set_source for description.
134 */
135 static status_t set_source(packet_t *this, char *address, u_int16_t port)
136 {
137 struct sockaddr *saddr = &(this->source);
138 return set_addr(this->family, saddr, address, port);
139 }
140
141 /*
142 * Documented in header
143 */
144 packet_t *packet_create(int family)
145 {
146 private_packet_t *this = allocator_alloc_thing(private_packet_t);
147
148 this->public.destroy = (status_t(*) (packet_t *)) destroy;
149 this->public.set_destination = set_destination;
150 this->public.set_source = set_source;
151 this->public.clone = (status_t(*) (packet_t *,packet_t**))clone;
152
153 this->public.family = family;
154 switch (family)
155 {
156 case AF_INET:
157 this->public.sockaddr_len = sizeof(struct sockaddr_in);
158 break;
159 default: /* not supported */
160 allocator_free(this);
161 return NULL;
162 }
163
164 this->public.data.len = 0;
165 this->public.data.ptr = NULL;
166 return &(this->public);
167 }