aboutsummaryrefslogtreecommitdiffstats
path: root/lib/src/name.h
blob: 0a55fedc65ec96ce47574e9e669a2ba85abfcac6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
/*
 * Copyright (c) 2017-2019 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file name.h
 * @brief hICN name helpers.
 *
 * The purpose of the file is to offer an efficient, platform- and protocol-
 * independent way to manipulate hICN names.
 */

#ifndef HICN_NAME_H
#define HICN_NAME_H

#include <stdbool.h>
#include <netinet/in.h>		// struct sockadd

#include "common.h"

/******************************************************************************
 * IP address helpers
 ******************************************************************************/

/* Presentation format */
#define INET_ADDRSTRLEN 16
#define INET6_ADDRSTRLEN 46
//#define INET_MAX_ADDRSTRLEN INET6_ADDRSTRLEN

/* Address size */
#define bytes_to_bits(x) (x * 8)
#define IPV6_ADDR_LEN 16	/* bytes */
#define IPV4_ADDR_LEN 4		/* bytes */
#define IPV6_ADDR_LEN_BITS bytes_to_bits(IPV6_ADDR_LEN)
#define IPV4_ADDR_LEN_BITS bytes_to_bits(IPV4_ADDR_LEN)

#define IP_MAX_ADDR_LEN IPV6_ADDR_LEN
#define TCP_SEQNO_LEN 4		/* bytes */

typedef struct
{
  union
  {
    u8 buffer[IP_MAX_ADDR_LEN];
    u8 as_u8[IP_MAX_ADDR_LEN];
    u16 as_u16[IP_MAX_ADDR_LEN >> 1];
    u32 as_u32[IP_MAX_ADDR_LEN >> 2];
    u64 as_u64[IP_MAX_ADDR_LEN >> 3];
    ip4_address_t as_ip4;
    ip6_address_t as_ip6;
  };
  int family;
  unsigned short prefix_len;
} ip_address_t;

int ip_address_len (const ip_address_t * ip_address);
bool ip_address_empty (const ip_address_t * ip_address);

int hicn_ip_ntop (const ip_address_t * ip_address, char *dst,
		  const size_t len);
int hicn_ip_pton (const char *ip_address_str, ip_address_t * ip_address);
int hicn_ip_to_sockaddr_address (const ip_address_t * ip_address,
				 struct sockaddr *sockaddr_address);

/******************************************************************************
 * hICN names
 ******************************************************************************/

#define HICN_V4_PREFIX_LEN IPV4_ADDR_LEN
#define HICN_V6_PREFIX_LEN IPV6_ADDR_LEN
#define HICN_SEGMENT_LEN TCP_SEQNO_LEN
#define HICN_V6_NAME_LEN (HICN_V6_PREFIX_LEN + HICN_SEGMENT_LEN)	/* 20 bytes */
#define HICN_V4_NAME_LEN (HICN_V4_PREFIX_LEN + HICN_SEGMENT_LEN)	/*  8 bytes */

/* Prefix */

typedef u32 hicn_name_suffix_t;

typedef struct
{
  ip46_address_t name;
  u8 len;
} hicn_prefix_t;

/*
 * Name
 *
 * A name is a prefix + a segment name (suffix)
 */

typedef union
{
  struct
  {
    union
    {
      u32 prefix;
      u8 prefix_as_u8[4];
      ip4_address_t prefix_as_ip4;
    };
    hicn_name_suffix_t suffix;
  };
  u8 buffer[HICN_V4_NAME_LEN];
} hicn_v4_name_t;

typedef union
{
  struct
  {
    union
    {
      u64 prefix[2];
      u8 prefix_as_u8[16];
      ip6_address_t prefix_as_ip6;
    };
    hicn_name_suffix_t suffix;
  };
  u8 buffer[HICN_V6_NAME_LEN];
} hicn_v6_name_t;

typedef struct
{
  u8 buffer[0];
} hicn_v46_name_t;

#ifndef HICN_VPP_PLUGIN
#define HICN_NAME_COMPONENT_SIZE 2

typedef struct
{
  struct iovec buffers[HICN_NAME_COMPONENT_SIZE];
} hicn_iov_name_t;

#define UNSPEC            1 << 0
#define HNT_CONTIGUOUS    1 << 1
#define HNT_IOV           1 << 2
#define HNT_INET          1 << 3
#define HNT_INET6         1 << 4

typedef enum
{
  HNT_UNSPEC = UNSPEC,
  HNT_CONTIGUOUS_V4 = HNT_CONTIGUOUS | HNT_INET,
  HNT_CONTIGUOUS_V6 = HNT_CONTIGUOUS | HNT_INET6,
  HNT_IOV_V4 = HNT_IOV | HNT_INET,
  HNT_IOV_V6 = HNT_IOV | HNT_INET6,
} hicn_name_type_t;
#endif /* HICN_VPP_PLUGIN */

typedef struct
{
#ifndef HICN_VPP_PLUGIN
  hicn_name_type_t type;
  u8 len;
#endif				/* HICN_VPP_PLUGIN */
  union
  {
    hicn_v4_name_t ip4;
    hicn_v6_name_t ip6;
    ip46_address_t ip46;
#ifndef HICN_VPP_PLUGIN
    hicn_iov_name_t iov;
    u8 buffer[0];
#endif				/* HICN_VPP_PLUGIN */
  };
} hicn_name_t;

#ifndef HICN_VPP_PLUGIN
#define _is_unspec(name)     ((name->type & UNSPEC))
#define _is_contiguous(name) ((name->type & HNT_CONTIGUOUS) >> 1)
#define _is_iov(name)        ((name->type & HNT_IOV) >> 2)
#define _is_inet4(name)      ((name->type & HNT_INET) >> 3)
#define _is_inet6(name)      ((name->type & HNT_INET6) >> 4)
#endif /* HICN_VPP_PLUGIN */

/**
 * @brief Create an hICN name from IP address in presentation format
 * @param [in] ip_address - IP address
 * @param [in] id - Segment identifier
 * @param [out] Resulting hICN name
 * @return hICN error code
 */
int hicn_name_create (const char *ip_address, u32 id, hicn_name_t * name);

/**
 * @brief Create an hICN name from IP address
 * @param [in] ip_address - IP address
 * @param [in] id Segment - identifier
 * @param [out] Resulting - hICN name
 * @return hICN error code
 */
int hicn_name_create_from_ip_address (const ip_address_t * ip_address, u32 id,
				      hicn_name_t * name);

/**
 * @brief Returns the length of an hICN name
 * @param [in] name - hICN name
 * @return Name length
 */
u8 hicn_name_get_length (const hicn_name_t * name);

/**
 * @brief Compare two hICN names
 * @param [in] name_1 - First name to compare
 * @param [in] name_2 - Second name to compare
 * @param [in] consider_segment - Flag indicating whether the segment part has to be
 *   considered
 * @return An integer less than, equal to, or greater than zero if name_1 is
 *   found, respectively, to be lest than, to match, or be greater than name_2
 *   based on numeric order.
 */
int hicn_name_compare (const hicn_name_t * name_1, const hicn_name_t * name_2,
		       bool consider_segment);

/**
 * @brief Provides a 32-bit hash of an hICN name
 * @param [in] name - Name to hash
 * @param [out] hash - Resulting hash
 * @return hICN error code
 */
int hicn_name_hash (const hicn_name_t * name, u32 * hash);

/**
 * @brief Test whether an hICN name is empty
 * @param [in] name - Name to test
 * @return 0 if the name is empty, any other value otherwise (implementation
 *   returns 1)
 */
int hicn_name_empty (hicn_name_t * name);

/**
 * @brief Copy an hICN name
 * @param [out] dst - Destination name
 * @param [in] src - Source name to copy
 * @return hICN error code
 */
int hicn_name_copy (hicn_name_t * dst, const hicn_name_t * src);

/**
 * @brief Copy an hICN name to a buffer
 * @param [out] dst - Destination buffer
 * @param [in] src - Source name to copy
 * @param [in] copy_suffix - Flag indicating whether the suffix has to be
 *   considered
 */
int hicn_name_copy_to_destination (u8 * dst, const hicn_name_t * src,
				   bool copy_suffix);

/**
 * @brief Sets the segment part of an hICN name
 * @param [in,out] name - hICN name to modify
 * @param [in] seq_number - Segment identifier
 * @return hICN error code
 */
int hicn_name_set_seq_number (hicn_name_t * name, u32 seq_number);

/**
 * @brief Retrieves the segment part of an hICN name
 * @param [in,out] name - hICN name
 * @param [in] seq_number - Segment identifier
 * @return hICN error code
 */
int hicn_name_get_seq_number (const hicn_name_t * name, u32 * seq_number);

/**
 * @brief Convert an hICN name to a socket address
 * @param [in] name - Name to convert
 * @param [out] ip_address - Resulting socket address
 * @return hICN error code
 */
int hicn_name_to_sockaddr_address (const hicn_name_t * name,
				   struct sockaddr *ip_address);

/**
 * @brief Convert an hICN name to an IP address
 * @param [in] name - Name to convert
 * @param [out] ip_address - Resulting IP address
 * @return hICN error code
 */
int hicn_name_to_ip_address (const hicn_name_t * name,
			     ip_address_t * ip_address);

/**
 * @brief Convert an hICN name to presentation format
 * @param [in] src - Name to convert
 * @param [out] dst - Buffer to receive the name in presentation format
 * @param [in] len - Number of bytes available in the buffer
 * @return hICN error code
 */
int hicn_name_ntop (const hicn_name_t * src, char *dst, size_t len);

/**
 * @brief Convert an hICN name from presentation format
 * @param [in] src - Name in presentation format to parse
 * @param [out] dst - Resulting name
 * @return hICN error code
 */
int hicn_name_pton (const char *src, hicn_name_t * dst);

/**
 * @brief Returns the IP address family of an hICN name
 * @param [in] name - Name to lookup
 * @param [out] family - Resulting IP address family (AF_INET or AF_INET6)
 * @return hICN error code
 */
int hicn_name_get_family (const hicn_name_t * name, int *family);

/**
 * @brief Creates an hICN prefix from an IP address
 * @param [in] ip_address - Input IP address
 * @param [out] prefix - Resulting prefix
 * @return hICN error code
 */
int hicn_prefix_create_from_ip_address (const ip_address_t * ip_address,
					hicn_prefix_t * prefix);

#endif /* HICN_NAME_H */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */