0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 use strict;
0011
0012 my @names = ();
0013 my @oids = ();
0014
0015 if ($#ARGV != 1) {
0016 print STDERR "Format: ", $0, " <in-h-file> <out-c-file>\n";
0017 exit(2);
0018 }
0019
0020
0021
0022
0023 open IN_FILE, "<$ARGV[0]" || die;
0024 while (<IN_FILE>) {
0025 chomp;
0026 if () {
0027 push @names, $1;
0028 push @oids, $2;
0029 }
0030 }
0031 close IN_FILE || die;
0032
0033
0034
0035
0036 open C_FILE, ">$ARGV[1]" or die;
0037 print C_FILE "/*\n";
0038 print C_FILE " * Automatically generated by ", $0, ". Do not edit\n";
0039 print C_FILE " */\n";
0040
0041
0042
0043
0044
0045 my @indices = ();
0046 my @lengths = ();
0047 my $total_length = 0;
0048
0049 for (my $i = 0; $i <= $#names; $i++) {
0050 my $name = $names[$i];
0051 my $oid = $oids[$i];
0052
0053 my @components = split(/[.]/, $oid);
0054
0055
0056 my $size = $#components;
0057 for (my $loop = 2; $loop <= $#components; $loop++) {
0058 my $c = $components[$loop];
0059
0060
0061 my $tmp = ($c == 0) ? 0 : int(log($c)/log(2));
0062 $tmp = int($tmp / 7);
0063 $size += $tmp;
0064 }
0065 push @lengths, $size;
0066 push @indices, $total_length;
0067 $total_length += $size;
0068 }
0069
0070
0071
0072
0073 print C_FILE "\n";
0074 if ($total_length <= 255) {
0075 print C_FILE "static const unsigned char oid_index[OID__NR + 1] = {\n";
0076 } else {
0077 print C_FILE "static const unsigned short oid_index[OID__NR + 1] = {\n";
0078 }
0079 for (my $i = 0; $i <= $#names; $i++) {
0080 print C_FILE "\t[OID_", $names[$i], "] = ", $indices[$i], ",\n"
0081 }
0082 print C_FILE "\t[OID__NR] = ", $total_length, "\n";
0083 print C_FILE "};\n";
0084
0085
0086
0087
0088 my @encoded_oids = ();
0089
0090 for (my $i = 0; $i <= $#names; $i++) {
0091 my @octets = ();
0092
0093 my @components = split(/[.]/, $oids[$i]);
0094
0095 push @octets, $components[0] * 40 + $components[1];
0096
0097 for (my $loop = 2; $loop <= $#components; $loop++) {
0098 my $c = $components[$loop];
0099
0100
0101 my $tmp = ($c == 0) ? 0 : int(log($c)/log(2));
0102 $tmp = int($tmp / 7);
0103
0104 for (; $tmp > 0; $tmp--) {
0105 push @octets, (($c >> $tmp * 7) & 0x7f) | 0x80;
0106 }
0107 push @octets, $c & 0x7f;
0108 }
0109
0110 push @encoded_oids, \@octets;
0111 }
0112
0113
0114
0115
0116 my @hash_values = ();
0117 for (my $i = 0; $i <= $#names; $i++) {
0118 my @octets = @{$encoded_oids[$i]};
0119
0120 my $hash = $#octets;
0121 foreach (@octets) {
0122 $hash += $_ * 33;
0123 }
0124
0125 $hash = ($hash >> 24) ^ ($hash >> 16) ^ ($hash >> 8) ^ ($hash);
0126
0127 push @hash_values, $hash & 0xff;
0128 }
0129
0130
0131
0132
0133 print C_FILE "\n";
0134 print C_FILE "static const unsigned char oid_data[", $total_length, "] = {\n";
0135 for (my $i = 0; $i <= $#names; $i++) {
0136 my @octets = @{$encoded_oids[$i]};
0137 print C_FILE "\t";
0138 print C_FILE $_, ", " foreach (@octets);
0139 print C_FILE "\t// ", $names[$i];
0140 print C_FILE "\n";
0141 }
0142 print C_FILE "};\n";
0143
0144
0145
0146
0147 my @index_table = ( 0 .. $#names );
0148
0149 @index_table = sort {
0150 my @octets_a = @{$encoded_oids[$a]};
0151 my @octets_b = @{$encoded_oids[$b]};
0152
0153 return $hash_values[$a] <=> $hash_values[$b]
0154 if ($hash_values[$a] != $hash_values[$b]);
0155 return $#octets_a <=> $#octets_b
0156 if ($#octets_a != $#octets_b);
0157 for (my $i = $#octets_a; $i >= 0; $i--) {
0158 return $octets_a[$i] <=> $octets_b[$i]
0159 if ($octets_a[$i] != $octets_b[$i]);
0160 }
0161 return 0;
0162
0163 } @index_table;
0164
0165
0166
0167
0168 print C_FILE "\n";
0169 print C_FILE "static const struct {\n";
0170 print C_FILE "\tunsigned char hash;\n";
0171 if ($#names <= 255) {
0172 print C_FILE "\tenum OID oid : 8;\n";
0173 } else {
0174 print C_FILE "\tenum OID oid : 16;\n";
0175 }
0176 print C_FILE "} oid_search_table[OID__NR] = {\n";
0177 for (my $i = 0; $i <= $#names; $i++) {
0178 my @octets = @{$encoded_oids[$index_table[$i]]};
0179 printf(C_FILE "\t[%3u] = { %3u, OID_%-35s }, // ",
0180 $i,
0181 $hash_values[$index_table[$i]],
0182 $names[$index_table[$i]]);
0183 printf C_FILE "%02x", $_ foreach (@octets);
0184 print C_FILE "\n";
0185 }
0186 print C_FILE "};\n";
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203 close C_FILE or die;