]>
Commit | Line | Data |
---|---|---|
8e427c29 DL |
1 | /* |
2 | * Copyright (c) 2017-20 David Lamparter, for NetDEF, Inc. | |
3 | * | |
4 | * Permission to use, copy, modify, and distribute this software for any | |
5 | * purpose with or without fee is hereby granted, provided that the above | |
6 | * copyright notice and this permission notice appear in all copies. | |
7 | * | |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | */ | |
16 | ||
17 | #ifdef HAVE_CONFIG_H | |
18 | #include "config.h" | |
19 | #endif | |
20 | ||
21 | #include <stdlib.h> | |
22 | #include <stdarg.h> | |
23 | #include <string.h> | |
24 | #include <pthread.h> | |
25 | #include <signal.h> | |
26 | #include <inttypes.h> | |
27 | ||
28 | #include "xref.h" | |
29 | #include "vty.h" | |
30 | #include "jhash.h" | |
31 | #include "sha256.h" | |
32 | #include "memory.h" | |
33 | #include "hash.h" | |
34 | ||
35 | struct xref_block *xref_blocks; | |
36 | static struct xref_block **xref_block_last = &xref_blocks; | |
37 | ||
38 | static void base32(uint8_t **inpos, int *bitpos, | |
39 | char *out, size_t n_chars) | |
40 | { | |
41 | static const char base32ch[] = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; | |
42 | ||
43 | char *opos = out; | |
44 | uint8_t *in = *inpos; | |
45 | int bp = *bitpos; | |
46 | ||
47 | while (opos < out + n_chars) { | |
48 | uint32_t bits = in[0] | (in[1] << 8); | |
49 | ||
50 | if (bp == -1) | |
51 | bits |= 0x10; | |
52 | else | |
53 | bits >>= bp; | |
54 | ||
55 | *opos++ = base32ch[bits & 0x1f]; | |
56 | ||
57 | bp += 5; | |
58 | if (bp >= 8) | |
59 | in++, bp -= 8; | |
60 | } | |
61 | *opos = '\0'; | |
62 | *inpos = in; | |
63 | *bitpos = bp; | |
64 | } | |
65 | ||
08a73c42 DL |
66 | static void xref_add_one(const struct xref *xref) |
67 | { | |
68 | SHA256_CTX sha; | |
69 | struct xrefdata *xrefdata; | |
70 | ||
71 | const char *filename, *p, *q; | |
72 | uint8_t hash[32], *h = hash; | |
73 | uint32_t be_val; | |
74 | int bitpos; | |
75 | ||
76 | if (!xref || !xref->xrefdata) | |
77 | return; | |
78 | ||
79 | xrefdata = xref->xrefdata; | |
80 | xrefdata->xref = xref; | |
81 | ||
82 | if (!xrefdata->hashstr) | |
83 | return; | |
84 | ||
85 | /* as far as the unique ID is concerned, only use the last | |
86 | * directory name + filename, e.g. "bgpd/bgp_route.c". This | |
87 | * gives a little leeway in moving things and avoids IDs being | |
88 | * screwed up by out of tree builds or absolute pathnames. | |
89 | */ | |
90 | filename = xref->file; | |
91 | p = strrchr(filename, '/'); | |
92 | if (p) { | |
93 | q = memrchr(filename, '/', p - filename); | |
94 | if (q) | |
95 | filename = q + 1; | |
08a73c42 DL |
96 | } |
97 | ||
98 | SHA256_Init(&sha); | |
99 | SHA256_Update(&sha, filename, strlen(filename)); | |
100 | SHA256_Update(&sha, xrefdata->hashstr, | |
101 | strlen(xrefdata->hashstr)); | |
102 | be_val = htonl(xrefdata->hashu32[0]); | |
103 | SHA256_Update(&sha, &be_val, sizeof(be_val)); | |
104 | be_val = htonl(xrefdata->hashu32[1]); | |
105 | SHA256_Update(&sha, &be_val, sizeof(be_val)); | |
106 | SHA256_Final(hash, &sha); | |
107 | ||
108 | bitpos = -1; | |
109 | base32(&h, &bitpos, &xrefdata->uid[0], 5); | |
110 | xrefdata->uid[5] = '-'; | |
111 | base32(&h, &bitpos, &xrefdata->uid[6], 5); | |
112 | } | |
113 | ||
114 | void xref_gcc_workaround(const struct xref *xref) | |
115 | { | |
116 | xref_add_one(xref); | |
117 | } | |
118 | ||
8e427c29 DL |
119 | void xref_block_add(struct xref_block *block) |
120 | { | |
121 | const struct xref * const *xrefp; | |
8e427c29 DL |
122 | |
123 | *xref_block_last = block; | |
124 | xref_block_last = &block->next; | |
125 | ||
08a73c42 DL |
126 | for (xrefp = block->start; xrefp < block->stop; xrefp++) |
127 | xref_add_one(*xrefp); | |
8e427c29 | 128 | } |