Statistics
| Branch: | Revision:

iof-bird / bird-2.0.1 / lib / ip.c @ 6b3f1a54

History | View | Annotate | Download (12.3 KB)

1
/*
2
 *        BIRD Library -- IP address functions
3
 *
4
 *        (c) 1998--2000 Martin Mares <mj@ucw.cz>
5
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

    
9
/**
10
 * DOC: IP addresses
11
 *
12
 * BIRD uses its own abstraction of IP address in order to share the same
13
 * code for both IPv4 and IPv6. IP addresses are represented as entities
14
 * of type &ip_addr which are never to be treated as numbers and instead
15
 * they must be manipulated using the following functions and macros.
16
 */
17

    
18
#include <stdlib.h>
19

    
20
#include "nest/bird.h"
21
#include "lib/ip.h"
22

    
23

    
24
int
25
ip6_compare(ip6_addr a, ip6_addr b)
26
{
27
  int i;
28
  for (i=0; i<4; i++)
29
    if (a.addr[i] > b.addr[i])
30
      return 1;
31
    else if (a.addr[i] < b.addr[i])
32
      return -1;
33
  return 0;
34
}
35

    
36
ip6_addr
37
ip6_mkmask(uint n)
38
{
39
  ip6_addr a;
40
  int i;
41

    
42
  for (i=0; i<4; i++)
43
  {
44
    if (!n)
45
      a.addr[i] = 0;
46
    else if (n >= 32)
47
    {
48
      a.addr[i] = ~0;
49
      n -= 32;
50
    }
51
    else
52
    {
53
      a.addr[i] = u32_mkmask(n);
54
      n = 0;
55
    }
56
  }
57

    
58
  return a;
59
}
60

    
61
uint
62
ip6_masklen(ip6_addr *a)
63
{
64
  int i, j, n;
65

    
66
  for (i=0, n=0; i<4; i++, n+=32)
67
    if (a->addr[i] != ~0U)
68
    {
69
      j = u32_masklen(a->addr[i]);
70
      if (j == 255)
71
        return j;
72
      n += j;
73
      while (++i < 4)
74
        if (a->addr[i])
75
          return 255;
76
      break;
77
    }
78

    
79
  return n;
80
}
81

    
82
int
83
ip4_classify(ip4_addr ad)
84
{
85
  u32 a = _I(ad);
86
  u32 b = a >> 24U;
87

    
88
  if (b && b <= 0xdf)
89
  {
90
    if (b == 0x7f)
91
      return IADDR_HOST | SCOPE_HOST;
92
    else if ((b == 0x0a) ||
93
             ((a & 0xffff0000) == 0xc0a80000) ||
94
             ((a & 0xfff00000) == 0xac100000))
95
      return IADDR_HOST | SCOPE_SITE;
96
    else
97
      return IADDR_HOST | SCOPE_UNIVERSE;
98
  }
99

    
100
  if (b >= 0xe0 && b <= 0xef)
101
    return IADDR_MULTICAST | SCOPE_UNIVERSE;
102

    
103
  if (a == 0xffffffff)
104
    return IADDR_BROADCAST | SCOPE_LINK;
105

    
106
  return IADDR_INVALID;
107
}
108

    
109
int
110
ip6_classify(ip6_addr *a)
111
{
112
  u32 x = a->addr[0];
113

    
114
  if ((x & 0xe0000000) == 0x20000000)                /* 2000::/3  Aggregatable Global Unicast Address */
115
    return IADDR_HOST | SCOPE_UNIVERSE;
116
  if ((x & 0xffc00000) == 0xfe800000)                /* fe80::/10 Link-Local Address */
117
    return IADDR_HOST | SCOPE_LINK;
118
  if ((x & 0xffc00000) == 0xfec00000)                /* fec0::/10 Site-Local Address */
119
    return IADDR_HOST | SCOPE_SITE;
120
  if ((x & 0xfe000000) == 0xfc000000)                /* fc00::/7  Unique Local Unicast Address (RFC 4193) */
121
    return IADDR_HOST | SCOPE_SITE;
122
  if ((x & 0xff000000) == 0xff000000)                /* ff00::/8  Multicast Address */
123
  {
124
    uint scope = (x >> 16) & 0x0f;
125
    switch (scope)
126
    {
127
    case 1:  return IADDR_MULTICAST | SCOPE_HOST;
128
    case 2:  return IADDR_MULTICAST | SCOPE_LINK;
129
    case 5:  return IADDR_MULTICAST | SCOPE_SITE;
130
    case 8:  return IADDR_MULTICAST | SCOPE_ORGANIZATION;
131
    case 14: return IADDR_MULTICAST | SCOPE_UNIVERSE;
132
    default: return IADDR_MULTICAST | SCOPE_UNDEFINED;
133
    }
134
  }
135

    
136
  if (!x && !a->addr[1])
137
  {
138
    u32 a2 = a->addr[2];
139
    u32 a3 = a->addr[3];
140

    
141
    if (a2 == 0 && a3 == 1)
142
      return IADDR_HOST | SCOPE_HOST;                /* Loopback address */
143
    if (a2 == 0)
144
      return ip4_classify(_MI4(a3));                /* IPv4 compatible addresses */
145
    if (a2 == 0xffff)
146
      return ip4_classify(_MI4(a3));                /* IPv4 mapped addresses */
147

    
148
    return IADDR_INVALID;
149
  }
150

    
151
  return IADDR_HOST | SCOPE_UNDEFINED;
152
}
153

    
154

    
155

    
156
/*
157
 *  Conversion of IPv6 address to presentation format and vice versa.
158
 *  Heavily inspired by routines written by Paul Vixie for the BIND project
159
 *  and of course by RFC 2373.
160
 */
161

    
162

    
163
char *
164
ip4_ntop(ip4_addr a, char *b)
165
{
166
  u32 x = _I(a);
167
  return b + bsprintf(b, "%d.%d.%d.%d", (x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff);
168
}
169

    
170

    
171
char *
172
ip6_ntop(ip6_addr a, char *b)
173
{
174
  u16 words[8];
175
  int bestpos, bestlen, curpos, curlen, i;
176

    
177
  /* First of all, preprocess the address and find the longest run of zeros */
178
  bestlen = bestpos = curpos = curlen = 0;
179
  for (i=0; i<8; i++)
180
  {
181
    u32 x = a.addr[i/2];
182
    words[i] = ((i%2) ? x : (x >> 16)) & 0xffff;
183
    if (words[i])
184
      curlen = 0;
185
    else
186
    {
187
      if (!curlen)
188
        curpos = i;
189
      curlen++;
190
      if (curlen > bestlen)
191
      {
192
        bestpos = curpos;
193
        bestlen = curlen;
194
      }
195
    }
196
  }
197

    
198
  if (bestlen < 2)
199
    bestpos = -1;
200

    
201
  /* Is it an encapsulated IPv4 address? */
202
  if (!bestpos && ((bestlen == 5 && a.addr[2] == 0xffff) || (bestlen == 6)))
203
  {
204
    u32 x = a.addr[3];
205
    b += bsprintf(b, "::%s%d.%d.%d.%d",
206
                  a.addr[2] ? "ffff:" : "",
207
                  (x >> 24) & 0xff,
208
                  (x >> 16) & 0xff,
209
                  (x >> 8) & 0xff,
210
                  x & 0xff);
211
    return b;
212
  }
213

    
214
  /* Normal IPv6 formatting, compress the largest sequence of zeros */
215
  for (i=0; i<8; i++)
216
  {
217
    if (i == bestpos)
218
    {
219
      i += bestlen - 1;
220
      *b++ = ':';
221
      if (i == 7)
222
        *b++ = ':';
223
    }
224
    else
225
    {
226
      if (i)
227
        *b++ = ':';
228
      b += bsprintf(b, "%x", words[i]);
229
    }
230
  }
231
  *b = 0;
232
  return b;
233
}
234

    
235
int
236
ip4_pton(const char *a, ip4_addr *o)
237
{
238
  int i;
239
  unsigned long int l;
240
  u32 ia = 0;
241

    
242
  i=4;
243
  while (i--)
244
  {
245
    char *d, *c = strchr(a, '.');
246
    if (!c != !i)
247
      return 0;
248
    l = strtoul(a, &d, 10);
249
    if (((d != c) && *d) || (l > 255))
250
      return 0;
251
    ia = (ia << 8) | l;
252
    if (c)
253
      c++;
254
    a = c;
255
  }
256
  *o = ip4_from_u32(ia);
257
  return 1;
258
}
259

    
260
int
261
ip6_pton(const char *a, ip6_addr *o)
262
{
263
  u16 words[8];
264
  int i, j, k, l, hfil;
265
  const char *start;
266

    
267
  if (a[0] == ':')                        /* Leading :: */
268
  {
269
    if (a[1] != ':')
270
      return 0;
271
    a++;
272
  }
273

    
274
  hfil = -1;
275
  i = 0;
276
  while (*a)
277
  {
278
    if (*a == ':')                        /* :: */
279
    {
280
      if (hfil >= 0)
281
        return 0;
282

    
283
      hfil = i;
284
      a++;
285
      continue;
286
    }
287

    
288
    j = 0;
289
    l = 0;
290
    start = a;
291
    for (;;)
292
    {
293
      if (*a >= '0' && *a <= '9')
294
        k = *a++ - '0';
295
      else if (*a >= 'A' && *a <= 'F')
296
        k = *a++ - 'A' + 10;
297
      else if (*a >= 'a' && *a <= 'f')
298
        k = *a++ - 'a' + 10;
299
      else
300
        break;
301

    
302
      j = (j << 4) + k;
303
      if (j >= 0x10000 || ++l > 4)
304
        return 0;
305
    }
306

    
307
    if (*a == ':' && a[1])
308
      a++;
309
    else if (*a == '.' && (i == 6 || (i < 6 && hfil >= 0)))
310
    {                                /* Embedded IPv4 address */
311
      ip4_addr x;
312
      if (!ip4_pton(start, &x))
313
        return 0;
314
      words[i++] = _I(x) >> 16;
315
      words[i++] = _I(x);
316
      break;
317
    }
318
    else if (*a)
319
      return 0;
320

    
321
    if (i >= 8)
322
      return 0;
323

    
324
    words[i++] = j;
325
  }
326

    
327
  /* Replace :: with an appropriate number of zeros */
328
  if (hfil >= 0)
329
  {
330
    j = 8 - i;
331
    for (i=7; i-j >= hfil; i--)
332
      words[i] = words[i-j];
333
    for (; i>=hfil; i--)
334
      words[i] = 0;
335
  }
336

    
337
  /* Convert the address to ip6_addr format */
338
  for (i=0; i<4; i++)
339
    o->addr[i] = (words[2*i] << 16) | words[2*i+1];
340

    
341
  return 1;
342
}
343

    
344

    
345
/**
346
 * ip_scope_text - get textual representation of address scope
347
 * @scope: scope (%SCOPE_xxx)
348
 *
349
 * Returns a pointer to a textual name of the scope given.
350
 */
351
char *
352
ip_scope_text(uint scope)
353
{
354
  static char *scope_table[] = { "host", "link", "site", "org", "univ", "undef" };
355

    
356
  if (scope > SCOPE_UNDEFINED)
357
    return "?";
358
  else
359
    return scope_table[scope];
360
}
361

    
362
ip4_addr
363
ip4_class_mask(ip4_addr ad)
364
{
365
  u32 m, a = _I(ad);
366

    
367
  if (a == 0x00000000)
368
    m = 0x00000000;
369
  else if (a < 0x80000000)
370
    m = 0xff000000;
371
  else if (a < 0xc0000000)
372
    m = 0xffff0000;
373
  else
374
    m = 0xffffff00;
375
  if (a & ~m)
376
    m = 0xffffffff;
377

    
378
  return _MI4(m);
379
}
380

    
381
#if 0
382
/**
383
 * ipa_equal - compare two IP addresses for equality
384
 * @x: IP address
385
 * @y: IP address
386
 *
387
 * ipa_equal() returns 1 if @x and @y represent the same IP address, else 0.
388
 */
389
int ipa_equal(ip_addr x, ip_addr y) { DUMMY }
390

391
/**
392
 * ipa_nonzero - test if an IP address is defined
393
 * @x: IP address
394
 *
395
 * ipa_nonzero returns 1 if @x is a defined IP address (not all bits are zero),
396
 * else 0.
397
 *
398
 * The undefined all-zero address is reachable as a |IPA_NONE| macro.
399
 */
400
int ipa_nonzero(ip_addr x) { DUMMY }
401

402
/**
403
 * ipa_and - compute bitwise and of two IP addresses
404
 * @x: IP address
405
 * @y: IP address
406
 *
407
 * This function returns a bitwise and of @x and @y. It's primarily
408
 * used for network masking.
409
 */
410
ip_addr ipa_and(ip_addr x, ip_addr y) { DUMMY }
411

412
/**
413
 * ipa_or - compute bitwise or of two IP addresses
414
 * @x: IP address
415
 * @y: IP address
416
 *
417
 * This function returns a bitwise or of @x and @y.
418
 */
419
ip_addr ipa_or(ip_addr x, ip_addr y) { DUMMY }
420

421
/**
422
 * ipa_xor - compute bitwise xor of two IP addresses
423
 * @x: IP address
424
 * @y: IP address
425
 *
426
 * This function returns a bitwise xor of @x and @y.
427
 */
428
ip_addr ipa_xor(ip_addr x, ip_addr y) { DUMMY }
429

430
/**
431
 * ipa_not - compute bitwise negation of two IP addresses
432
 * @x: IP address
433
 *
434
 * This function returns a bitwise negation of @x.
435
 */
436
ip_addr ipa_not(ip_addr x) { DUMMY }
437

438
/**
439
 * ipa_mkmask - create a netmask
440
 * @x: prefix length
441
 *
442
 * This function returns an &ip_addr corresponding of a netmask
443
 * of an address prefix of size @x.
444
 */
445
ip_addr ipa_mkmask(int x) { DUMMY }
446

447
/**
448
 * ipa_masklen - calculate netmask length
449
 * @x: IP address
450
 *
451
 * This function checks whether @x represents a valid netmask and
452
 * returns the size of the associate network prefix or -1 for invalid
453
 * mask.
454
 */
455
int ipa_masklen(ip_addr x) { DUMMY }
456

457
/**
458
 * ipa_hash - hash IP addresses
459
 * @x: IP address
460
 *
461
 * ipa_hash() returns a 16-bit hash value of the IP address @x.
462
 */
463
int ipa_hash(ip_addr x) { DUMMY }
464

465
/**
466
 * ipa_hton - convert IP address to network order
467
 * @x: IP address
468
 *
469
 * Converts the IP address @x to the network byte order.
470
 *
471
 * Beware, this is a macro and it alters the argument!
472
 */
473
void ipa_hton(ip_addr x) { DUMMY }
474

475
/**
476
 * ipa_ntoh - convert IP address to host order
477
 * @x: IP address
478
 *
479
 * Converts the IP address @x from the network byte order.
480
 *
481
 * Beware, this is a macro and it alters the argument!
482
 */
483
void ipa_ntoh(ip_addr x) { DUMMY }
484

485
/**
486
 * ipa_classify - classify an IP address
487
 * @x: IP address
488
 *
489
 * ipa_classify() returns an address class of @x, that is a bitwise or
490
 * of address type (%IADDR_INVALID, %IADDR_HOST, %IADDR_BROADCAST, %IADDR_MULTICAST)
491
 * with address scope (%SCOPE_HOST to %SCOPE_UNIVERSE) or -1 (%IADDR_INVALID)
492
 * for an invalid address.
493
 */
494
int ipa_classify(ip_addr x) { DUMMY }
495

496
/**
497
 * ip4_class_mask - guess netmask according to address class
498
 * @x: IPv4 address
499
 *
500
 * This function (available in IPv4 version only) returns a
501
 * network mask according to the address class of @x. Although
502
 * classful addressing is nowadays obsolete, there still live
503
 * routing protocols transferring no prefix lengths nor netmasks
504
 * and this function could be useful to them.
505
 */
506
ip4_addr ip4_class_mask(ip4_addr x) { DUMMY }
507

508
/**
509
 * ipa_from_u32 - convert IPv4 address to an integer
510
 * @x: IP address
511
 *
512
 * This function takes an IPv4 address and returns its numeric
513
 * representation.
514
 */
515
u32 ipa_from_u32(ip_addr x) { DUMMY }
516

517
/**
518
 * ipa_to_u32 - convert integer to IPv4 address
519
 * @x: a 32-bit integer
520
 *
521
 * ipa_to_u32() takes a numeric representation of an IPv4 address
522
 * and converts it to the corresponding &ip_addr.
523
 */
524
ip_addr ipa_to_u32(u32 x) { DUMMY }
525

526
/**
527
 * ipa_compare - compare two IP addresses for order
528
 * @x: IP address
529
 * @y: IP address
530
 *
531
 * The ipa_compare() function takes two IP addresses and returns
532
 * -1 if @x is less than @y in canonical ordering (lexicographical
533
 * order of the bit strings), 1 if @x is greater than @y and 0
534
 * if they are the same.
535
 */
536
int ipa_compare(ip_addr x, ip_addr y) { DUMMY }
537

538
/**
539
 * ipa_build6 - build an IPv6 address from parts
540
 * @a1: part #1
541
 * @a2: part #2
542
 * @a3: part #3
543
 * @a4: part #4
544
 *
545
 * ipa_build() takes @a1 to @a4 and assembles them to a single IPv6
546
 * address. It's used for example when a protocol wants to bind its
547
 * socket to a hard-wired multicast address.
548
 */
549
ip_addr ipa_build6(u32 a1, u32 a2, u32 a3, u32 a4) { DUMMY }
550

551
/**
552
 * ip_ntop - convert IP address to textual representation
553
 * @a: IP address
554
 * @buf: buffer of size at least %STD_ADDRESS_P_LENGTH
555
 *
556
 * This function takes an IP address and creates its textual
557
 * representation for presenting to the user.
558
 */
559
char *ip_ntop(ip_addr a, char *buf) { DUMMY }
560

561
/**
562
 * ip_ntox - convert IP address to hexadecimal representation
563
 * @a: IP address
564
 * @buf: buffer of size at least %STD_ADDRESS_P_LENGTH
565
 *
566
 * This function takes an IP address and creates its hexadecimal
567
 * textual representation. Primary use: debugging dumps.
568
 */
569
char *ip_ntox(ip_addr a, char *buf) { DUMMY }
570

571
/**
572
 * ip_pton - parse textual representation of IP address
573
 * @a: textual representation
574
 * @o: where to put the resulting address
575
 *
576
 * This function parses a textual IP address representation and
577
 * stores the decoded address to a variable pointed to by @o.
578
 * Returns 0 if a parse error has occurred, else 0.
579
 */
580
int ip_pton(char *a, ip_addr *o) { DUMMY }
581

582
#endif