The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/lib/oid_registry.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* ASN.1 Object identifier (OID) registry
    2  *
    3  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
    4  * Written by David Howells (dhowells@redhat.com)
    5  *
    6  * This program is free software; you can redistribute it and/or
    7  * modify it under the terms of the GNU General Public Licence
    8  * as published by the Free Software Foundation; either version
    9  * 2 of the Licence, or (at your option) any later version.
   10  */
   11 
   12 #include <linux/export.h>
   13 #include <linux/oid_registry.h>
   14 #include <linux/kernel.h>
   15 #include <linux/errno.h>
   16 #include <linux/bug.h>
   17 #include "oid_registry_data.c"
   18 
   19 /**
   20  * look_up_OID - Find an OID registration for the specified data
   21  * @data: Binary representation of the OID
   22  * @datasize: Size of the binary representation
   23  */
   24 enum OID look_up_OID(const void *data, size_t datasize)
   25 {
   26         const unsigned char *octets = data;
   27         enum OID oid;
   28         unsigned char xhash;
   29         unsigned i, j, k, hash;
   30         size_t len;
   31 
   32         /* Hash the OID data */
   33         hash = datasize - 1;
   34 
   35         for (i = 0; i < datasize; i++)
   36                 hash += octets[i] * 33;
   37         hash = (hash >> 24) ^ (hash >> 16) ^ (hash >> 8) ^ hash;
   38         hash &= 0xff;
   39 
   40         /* Binary search the OID registry.  OIDs are stored in ascending order
   41          * of hash value then ascending order of size and then in ascending
   42          * order of reverse value.
   43          */
   44         i = 0;
   45         k = OID__NR;
   46         while (i < k) {
   47                 j = (i + k) / 2;
   48 
   49                 xhash = oid_search_table[j].hash;
   50                 if (xhash > hash) {
   51                         k = j;
   52                         continue;
   53                 }
   54                 if (xhash < hash) {
   55                         i = j + 1;
   56                         continue;
   57                 }
   58 
   59                 oid = oid_search_table[j].oid;
   60                 len = oid_index[oid + 1] - oid_index[oid];
   61                 if (len > datasize) {
   62                         k = j;
   63                         continue;
   64                 }
   65                 if (len < datasize) {
   66                         i = j + 1;
   67                         continue;
   68                 }
   69 
   70                 /* Variation is most likely to be at the tail end of the
   71                  * OID, so do the comparison in reverse.
   72                  */
   73                 while (len > 0) {
   74                         unsigned char a = oid_data[oid_index[oid] + --len];
   75                         unsigned char b = octets[len];
   76                         if (a > b) {
   77                                 k = j;
   78                                 goto next;
   79                         }
   80                         if (a < b) {
   81                                 i = j + 1;
   82                                 goto next;
   83                         }
   84                 }
   85                 return oid;
   86         next:
   87                 ;
   88         }
   89 
   90         return OID__NR;
   91 }
   92 EXPORT_SYMBOL_GPL(look_up_OID);
   93 
   94 /*
   95  * sprint_OID - Print an Object Identifier into a buffer
   96  * @data: The encoded OID to print
   97  * @datasize: The size of the encoded OID
   98  * @buffer: The buffer to render into
   99  * @bufsize: The size of the buffer
  100  *
  101  * The OID is rendered into the buffer in "a.b.c.d" format and the number of
  102  * bytes is returned.  -EBADMSG is returned if the data could not be intepreted
  103  * and -ENOBUFS if the buffer was too small.
  104  */
  105 int sprint_oid(const void *data, size_t datasize, char *buffer, size_t bufsize)
  106 {
  107         const unsigned char *v = data, *end = v + datasize;
  108         unsigned long num;
  109         unsigned char n;
  110         size_t ret;
  111         int count;
  112 
  113         if (v >= end)
  114                 return -EBADMSG;
  115 
  116         n = *v++;
  117         ret = count = snprintf(buffer, bufsize, "%u.%u", n / 40, n % 40);
  118         buffer += count;
  119         bufsize -= count;
  120         if (bufsize == 0)
  121                 return -ENOBUFS;
  122 
  123         while (v < end) {
  124                 num = 0;
  125                 n = *v++;
  126                 if (!(n & 0x80)) {
  127                         num = n;
  128                 } else {
  129                         num = n & 0x7f;
  130                         do {
  131                                 if (v >= end)
  132                                         return -EBADMSG;
  133                                 n = *v++;
  134                                 num <<= 7;
  135                                 num |= n & 0x7f;
  136                         } while (n & 0x80);
  137                 }
  138                 ret += count = snprintf(buffer, bufsize, ".%lu", num);
  139                 buffer += count;
  140                 bufsize -= count;
  141                 if (bufsize == 0)
  142                         return -ENOBUFS;
  143         }
  144 
  145         return ret;
  146 }
  147 EXPORT_SYMBOL_GPL(sprint_oid);
  148 
  149 /**
  150  * sprint_OID - Print an Object Identifier into a buffer
  151  * @oid: The OID to print
  152  * @buffer: The buffer to render into
  153  * @bufsize: The size of the buffer
  154  *
  155  * The OID is rendered into the buffer in "a.b.c.d" format and the number of
  156  * bytes is returned.
  157  */
  158 int sprint_OID(enum OID oid, char *buffer, size_t bufsize)
  159 {
  160         int ret;
  161 
  162         BUG_ON(oid >= OID__NR);
  163 
  164         ret = sprint_oid(oid_data + oid_index[oid],
  165                          oid_index[oid + 1] - oid_index[oid],
  166                          buffer, bufsize);
  167         BUG_ON(ret == -EBADMSG);
  168         return ret;
  169 }
  170 EXPORT_SYMBOL_GPL(sprint_OID);

Cache object: 13696179ba29531f725faffb9294ba30


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.