139fd4ac9a867d42987008497e0fb77c1f66cb49
[strongswan.git] / Source / charon / utils / identification.c
1 /**
2 * @file identification.c
3 *
4 * @brief Implementation of identification_t.
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 <sys/socket.h>
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
26
27 #include "identification.h"
28
29 #include <utils/allocator.h>
30
31
32 /**
33 * String mappings for id_type_t.
34 */
35 mapping_t id_type_m[] = {
36 {ID_IPV4_ADDR, "ID_IPV4_ADDR"},
37 {ID_FQDN, "ID_FQDN"},
38 {ID_RFC822_ADDR, "ID_RFC822_ADDR"},
39 {ID_IPV6_ADDR, "ID_IPV6_ADDR"},
40 {ID_DER_ASN1_DN, "ID_DER_ASN1_DN"},
41 {ID_DER_ASN1_GN, "ID_DER_ASN1_GN"},
42 {ID_KEY_ID, "ID_KEY_ID"},
43 {MAPPING_END, NULL}
44 };
45
46
47
48 typedef struct private_identification_t private_identification_t;
49
50 /**
51 * Private data of an identification_t object.
52 */
53 struct private_identification_t {
54 /**
55 * Public interface.
56 */
57 identification_t public;
58
59 /**
60 * string representation of this id
61 */
62 char *string;
63
64 /**
65 * encoded representation of this id
66 */
67 chunk_t encoded;
68
69 /**
70 * type of this id
71 */
72 id_type_t type;
73 };
74
75 /**
76 * implements identification_t.get_encoding
77 */
78 static chunk_t get_encoding(private_identification_t *this)
79 {
80 return this->encoded;
81 }
82
83 /**
84 * implements identification_t.get_type
85 */
86 static id_type_t get_type(private_identification_t *this)
87 {
88 return this->type;
89 }
90
91 /**
92 * implements identification_t.get_string
93 */
94 static char *get_string(private_identification_t *this)
95 {
96 return this->string;
97 }
98
99 /**
100 * Implementation of identification_t.equals.
101 */
102 static bool equals (private_identification_t *this,private_identification_t *other)
103 {
104 if (this->type == other->type)
105 {
106 if (this->encoded.len != other->encoded.len)
107 {
108 return FALSE;
109 }
110 if (memcmp(this->encoded.ptr,other->encoded.ptr,this->encoded.len) == 0)
111 {
112 return TRUE;
113 }
114 }
115 return FALSE;
116 }
117
118 /**
119 * implements identification_t.destroy
120 */
121 static void destroy(private_identification_t *this)
122 {
123 allocator_free(this->string);
124 allocator_free(this->encoded.ptr);
125 allocator_free(this);
126 }
127
128 /**
129 * Generic constructor used for the other twos
130 */
131 static private_identification_t *identification_create()
132 {
133
134 private_identification_t *this = allocator_alloc_thing(private_identification_t);
135
136 /* assign methods */
137 this->public.equals = (bool (*) (identification_t*,identification_t*))equals;
138 this->public.get_encoding = (chunk_t (*) (identification_t*))get_encoding;
139 this->public.get_type = (id_type_t (*) (identification_t*))get_type;
140 this->public.get_string = (char* (*) (identification_t*))get_string;
141 this->public.destroy = (void (*) (identification_t*))destroy;
142
143 this->string = NULL;
144 this->encoded = CHUNK_INITIALIZER;
145
146 return this;
147 }
148
149 /*
150 * Described in header.
151 */
152 identification_t *identification_create_from_string(id_type_t type, char *string)
153 {
154 private_identification_t *this = identification_create();
155 this->type = type;
156 switch (type)
157 {
158 case ID_IPV4_ADDR:
159 {
160 /* convert string */
161 this->encoded.len = 4;
162 this->encoded.ptr = allocator_alloc(this->encoded.len);
163 if (inet_aton(string, ((struct in_addr*)(this->encoded.ptr))) == 0)
164 {
165 allocator_free(this->encoded.ptr);
166 allocator_free(this);
167 return NULL;
168 }
169 /* clone string */
170 this->string = allocator_alloc(strlen(string)+1);
171 strcpy(this->string, string);
172 return &(this->public);
173 }
174 case ID_IPV6_ADDR:
175 case ID_FQDN:
176 case ID_RFC822_ADDR:
177 case ID_DER_ASN1_DN:
178 case ID_DER_ASN1_GN:
179 case ID_KEY_ID:
180 default:
181 {
182 /* not supported */
183 allocator_free(this);
184 return NULL;
185 }
186 }
187 }
188
189 /*
190 * Described in header.
191 */
192 identification_t *identification_create_from_encoding(id_type_t type, chunk_t encoded)
193 {
194 private_identification_t *this = identification_create();
195 this->type = type;
196 switch (type)
197 {
198 case ID_IPV4_ADDR:
199 {
200 char *tmp;
201 /* clone chunk */
202 if (encoded.len != 4)
203 {
204 allocator_free(this);
205 return NULL;
206 }
207 this->encoded = allocator_clone_chunk(encoded);
208 tmp = inet_ntoa(*((struct in_addr*)(encoded.ptr)));
209 /* build string, must be cloned */
210 this->string = allocator_alloc(strlen(tmp)+1);
211 strcpy(this->string, tmp);
212 return &(this->public);
213 }
214 case ID_IPV6_ADDR:
215 case ID_FQDN:
216 case ID_RFC822_ADDR:
217 case ID_DER_ASN1_DN:
218 case ID_DER_ASN1_GN:
219 case ID_KEY_ID:
220 default:
221 {
222 /* not supported */
223 allocator_free(this);
224 return NULL;
225 }
226 }
227 }