Line data Source code
1 : // Copyright (c) 2019 The Bitcoin Core developers
2 : // Distributed under the MIT software license, see the accompanying
3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 :
5 : #include <vector>
6 : #include <assert.h>
7 : #include <crypto/common.h>
8 :
9 : namespace {
10 :
11 180600 : uint32_t DecodeBits(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos, uint8_t minval, const std::vector<uint8_t> &bit_sizes)
12 : {
13 180600 : uint32_t val = minval;
14 180600 : bool bit;
15 900876 : for (std::vector<uint8_t>::const_iterator bit_sizes_it = bit_sizes.begin();
16 900876 : bit_sizes_it != bit_sizes.end(); ++bit_sizes_it) {
17 900876 : if (bit_sizes_it + 1 != bit_sizes.end()) {
18 745098 : if (bitpos == endpos) break;
19 745098 : bit = *bitpos;
20 745098 : bitpos++;
21 : } else {
22 : bit = 0;
23 : }
24 745098 : if (bit) {
25 720276 : val += (1 << *bit_sizes_it);
26 : } else {
27 1012390 : for (int b = 0; b < *bit_sizes_it; b++) {
28 831786 : if (bitpos == endpos) break;
29 831786 : bit = *bitpos;
30 831786 : bitpos++;
31 831786 : val += bit << (*bit_sizes_it - 1 - b);
32 : }
33 180600 : return val;
34 : }
35 : }
36 0 : return -1;
37 : }
38 :
39 : const std::vector<uint8_t> TYPE_BIT_SIZES{0, 0, 1};
40 90300 : uint32_t DecodeType(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
41 : {
42 90300 : return DecodeBits(bitpos, endpos, 0, TYPE_BIT_SIZES);
43 : }
44 :
45 : const std::vector<uint8_t> ASN_BIT_SIZES{15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
46 5694 : uint32_t DecodeASN(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
47 : {
48 5694 : return DecodeBits(bitpos, endpos, 1, ASN_BIT_SIZES);
49 : }
50 :
51 :
52 : const std::vector<uint8_t> MATCH_BIT_SIZES{1, 2, 3, 4, 5, 6, 7, 8};
53 78081 : uint32_t DecodeMatch(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
54 : {
55 78081 : return DecodeBits(bitpos, endpos, 2, MATCH_BIT_SIZES);
56 : }
57 :
58 :
59 : const std::vector<uint8_t> JUMP_BIT_SIZES{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};
60 6525 : uint32_t DecodeJump(std::vector<bool>::const_iterator& bitpos, const std::vector<bool>::const_iterator& endpos)
61 : {
62 6525 : return DecodeBits(bitpos, endpos, 17, JUMP_BIT_SIZES);
63 : }
64 :
65 : }
66 :
67 6411 : uint32_t Interpret(const std::vector<bool> &asmap, const std::vector<bool> &ip)
68 : {
69 6411 : std::vector<bool>::const_iterator pos = asmap.begin();
70 6411 : const std::vector<bool>::const_iterator endpos = asmap.end();
71 6411 : uint8_t bits = ip.size();
72 6411 : uint32_t default_asn = 0;
73 90300 : uint32_t opcode, jump, match, matchlen;
74 90300 : while (pos != endpos) {
75 90300 : opcode = DecodeType(pos, endpos);
76 90300 : if (opcode == 0) {
77 5694 : return DecodeASN(pos, endpos);
78 84606 : } else if (opcode == 1) {
79 6525 : jump = DecodeJump(pos, endpos);
80 6525 : if (bits == 0) break;
81 6525 : if (ip[ip.size() - bits]) {
82 5703 : if (jump >= endpos - pos) break;
83 5703 : pos += jump;
84 : }
85 6525 : bits--;
86 78081 : } else if (opcode == 2) {
87 78081 : match = DecodeMatch(pos, endpos);
88 78081 : matchlen = CountBits(match) - 1;
89 699612 : for (uint32_t bit = 0; bit < matchlen; bit++) {
90 622248 : if (bits == 0) break;
91 622248 : if ((ip[ip.size() - bits]) != ((match >> (matchlen - 1 - bit)) & 1)) {
92 : return default_asn;
93 : }
94 621531 : bits--;
95 : }
96 0 : } else if (opcode == 3) {
97 0 : default_asn = DecodeASN(pos, endpos);
98 : } else {
99 : break;
100 : }
101 : }
102 : return 0; // 0 is not a valid ASN
103 : }
|