147c08596SBrooks Davis /* $OpenBSD: hash.c,v 1.9 2004/05/10 15:30:47 deraadt Exp $ */ 247c08596SBrooks Davis 347c08596SBrooks Davis /* Routines for manipulating hash tables... */ 447c08596SBrooks Davis 58a16b7a1SPedro F. Giffuni /*- 68a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 78a16b7a1SPedro F. Giffuni * 847c08596SBrooks Davis * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. 947c08596SBrooks Davis * All rights reserved. 1047c08596SBrooks Davis * 1147c08596SBrooks Davis * Redistribution and use in source and binary forms, with or without 1247c08596SBrooks Davis * modification, are permitted provided that the following conditions 1347c08596SBrooks Davis * are met: 1447c08596SBrooks Davis * 1547c08596SBrooks Davis * 1. Redistributions of source code must retain the above copyright 1647c08596SBrooks Davis * notice, this list of conditions and the following disclaimer. 1747c08596SBrooks Davis * 2. Redistributions in binary form must reproduce the above copyright 1847c08596SBrooks Davis * notice, this list of conditions and the following disclaimer in the 1947c08596SBrooks Davis * documentation and/or other materials provided with the distribution. 2047c08596SBrooks Davis * 3. Neither the name of The Internet Software Consortium nor the names 2147c08596SBrooks Davis * of its contributors may be used to endorse or promote products derived 2247c08596SBrooks Davis * from this software without specific prior written permission. 2347c08596SBrooks Davis * 2447c08596SBrooks Davis * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND 2547c08596SBrooks Davis * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 2647c08596SBrooks Davis * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 2747c08596SBrooks Davis * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 2847c08596SBrooks Davis * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR 2947c08596SBrooks Davis * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3047c08596SBrooks Davis * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3147c08596SBrooks Davis * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 3247c08596SBrooks Davis * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 3347c08596SBrooks Davis * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 3447c08596SBrooks Davis * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 3547c08596SBrooks Davis * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3647c08596SBrooks Davis * SUCH DAMAGE. 3747c08596SBrooks Davis * 3847c08596SBrooks Davis * This software has been written for the Internet Software Consortium 3947c08596SBrooks Davis * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie 4047c08596SBrooks Davis * Enterprises. To learn more about the Internet Software Consortium, 4147c08596SBrooks Davis * see ``http://www.vix.com/isc''. To learn more about Vixie 4247c08596SBrooks Davis * Enterprises, see ``http://www.vix.com''. 4347c08596SBrooks Davis */ 4447c08596SBrooks Davis 458794fdbbSBrooks Davis #include <sys/cdefs.h> 468794fdbbSBrooks Davis __FBSDID("$FreeBSD$"); 478794fdbbSBrooks Davis 4847c08596SBrooks Davis #include "dhcpd.h" 4947c08596SBrooks Davis 50*79a1d195SAlan Somers static int do_hash(const unsigned char *, int, int); 5147c08596SBrooks Davis 5247c08596SBrooks Davis struct hash_table * 5347c08596SBrooks Davis new_hash(void) 5447c08596SBrooks Davis { 5547c08596SBrooks Davis struct hash_table *rv = new_hash_table(DEFAULT_HASH_SIZE); 5647c08596SBrooks Davis 5747c08596SBrooks Davis if (!rv) 5847c08596SBrooks Davis return (rv); 5947c08596SBrooks Davis memset(&rv->buckets[0], 0, 6047c08596SBrooks Davis DEFAULT_HASH_SIZE * sizeof(struct hash_bucket *)); 6147c08596SBrooks Davis return (rv); 6247c08596SBrooks Davis } 6347c08596SBrooks Davis 6447c08596SBrooks Davis static int 65*79a1d195SAlan Somers do_hash(const unsigned char *name, int len, int size) 6647c08596SBrooks Davis { 67*79a1d195SAlan Somers const unsigned char *s = name; 6847c08596SBrooks Davis int accum = 0, i = len; 6947c08596SBrooks Davis 7047c08596SBrooks Davis while (i--) { 7147c08596SBrooks Davis /* Add the character in... */ 7247c08596SBrooks Davis accum += *s++; 7347c08596SBrooks Davis /* Add carry back in... */ 7447c08596SBrooks Davis while (accum > 255) 7547c08596SBrooks Davis accum = (accum & 255) + (accum >> 8); 7647c08596SBrooks Davis } 7747c08596SBrooks Davis return (accum % size); 7847c08596SBrooks Davis } 7947c08596SBrooks Davis 80*79a1d195SAlan Somers void add_hash(struct hash_table *table, const unsigned char *name, int len, 8147c08596SBrooks Davis unsigned char *pointer) 8247c08596SBrooks Davis { 8347c08596SBrooks Davis struct hash_bucket *bp; 8447c08596SBrooks Davis int hashno; 8547c08596SBrooks Davis 8647c08596SBrooks Davis if (!table) 8747c08596SBrooks Davis return; 8847c08596SBrooks Davis if (!len) 89*79a1d195SAlan Somers len = strlen((const char *)name); 9047c08596SBrooks Davis 9147c08596SBrooks Davis hashno = do_hash(name, len, table->hash_count); 9247c08596SBrooks Davis bp = new_hash_bucket(); 9347c08596SBrooks Davis 9447c08596SBrooks Davis if (!bp) { 9547c08596SBrooks Davis warning("Can't add %s to hash table.", name); 9647c08596SBrooks Davis return; 9747c08596SBrooks Davis } 9847c08596SBrooks Davis bp->name = name; 9947c08596SBrooks Davis bp->value = pointer; 10047c08596SBrooks Davis bp->next = table->buckets[hashno]; 10147c08596SBrooks Davis bp->len = len; 10247c08596SBrooks Davis table->buckets[hashno] = bp; 10347c08596SBrooks Davis } 10447c08596SBrooks Davis 105*79a1d195SAlan Somers void * 10647c08596SBrooks Davis hash_lookup(struct hash_table *table, unsigned char *name, int len) 10747c08596SBrooks Davis { 10847c08596SBrooks Davis struct hash_bucket *bp; 10947c08596SBrooks Davis int hashno; 11047c08596SBrooks Davis 11147c08596SBrooks Davis if (!table) 11247c08596SBrooks Davis return (NULL); 11347c08596SBrooks Davis 11447c08596SBrooks Davis if (!len) 11547c08596SBrooks Davis len = strlen((char *)name); 11647c08596SBrooks Davis 11747c08596SBrooks Davis hashno = do_hash(name, len, table->hash_count); 11847c08596SBrooks Davis 11947c08596SBrooks Davis for (bp = table->buckets[hashno]; bp; bp = bp->next) 12047c08596SBrooks Davis if (len == bp->len && !memcmp(bp->name, name, len)) 12147c08596SBrooks Davis return (bp->value); 12247c08596SBrooks Davis 12347c08596SBrooks Davis return (NULL); 12447c08596SBrooks Davis } 125