147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 247e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltNICTA Public Software Licence 347e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltVersion 1.0 447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 547e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltCopyright © 2004 National ICT Australia Ltd 647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 747e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltAll rights reserved. 847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 947e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltBy this licence, National ICT Australia Ltd (NICTA) grants permission, 1047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltfree of charge, to any person who obtains a copy of this software 1147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltand any associated documentation files ("the Software") to use and 1247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltdeal with the Software in source code and binary forms without 1347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltrestriction, with or without modification, and to permit persons 1447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltto whom the Software is furnished to do so, provided that the 1547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltfollowing conditions are met: 1647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 1747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt- Redistributions of source code must retain the above copyright 1847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt notice, this list of conditions and the following disclaimers. 1947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt- Redistributions in binary form must reproduce the above copyright 2047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt notice, this list of conditions and the following disclaimers in 2147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt the documentation and/or other materials provided with the 2247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt distribution. 2347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt- The name of NICTA may not be used to endorse or promote products 2447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt derived from this Software without specific prior written permission. 2547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 2647e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltEXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT 2747e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltPERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS" AND 2847e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltNICTA MAKES NO REPRESENTATIONS, WARRANTIES OR CONDITIONS OF ANY 2947e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltKIND, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY 3047e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltREPRESENTATIONS, WARRANTIES OR CONDITIONS REGARDING THE CONTENTS 3147e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltOR ACCURACY OF THE SOFTWARE, OR OF TITLE, MERCHANTABILITY, FITNESS 3247e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltFOR A PARTICULAR PURPOSE, NONINFRINGEMENT, THE ABSENCE OF LATENT 3347e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltOR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR 3447e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltNOT DISCOVERABLE. 3547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 3647e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltTO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL 3747e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltNICTA BE LIABLE ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 3847e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltNEGLIGENCE) FOR ANY LOSS OR DAMAGE WHATSOEVER, INCLUDING (WITHOUT 3947e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltLIMITATION) LOSS OF PRODUCTION OR OPERATION TIME, LOSS, DAMAGE OR 4047e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltCORRUPTION OF DATA OR RECORDS; OR LOSS OF ANTICIPATED SAVINGS, 4147e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltOPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR OTHER ECONOMIC LOSS; 4247e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltOR ANY SPECIAL, INCIDENTAL, INDIRECT, CONSEQUENTIAL, PUNITIVE OR 4347e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltEXEMPLARY DAMAGES ARISING OUT OF OR IN CONNECTION WITH THIS LICENCE, 4447e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltTHE SOFTWARE OR THE USE OF THE SOFTWARE, EVEN IF NICTA HAS BEEN 4547e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 4647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 4747e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltIf applicable legislation implies warranties or conditions, or 4847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltimposes obligations or liability on NICTA in respect of the Software 4947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltthat cannot be wholly or partly excluded, restricted or modified, 5047e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltNICTA's liability is limited, to the full extent permitted by the 5147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltapplicable legislation, at its option, to: 5247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 5347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalta. in the case of goods, any one or more of the following: 5447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt i. the replacement of the goods or the supply of equivalent goods; 5547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ii. the repair of the goods; 5647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt iii. the payment of the cost of replacing the goods or of acquiring 5747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt equivalent goods; 5847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt iv. the payment of the cost of having the goods repaired; or 5947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltb. in the case of services: 6047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt i. the supplying of the services again; or 6147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ii. the payment of the cost of having the services supplied 6247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt again. 6347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 6447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 6547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 6647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt NSSwitch Implementation of mDNS interface. 6747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 6847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Andrew White (Andrew.White@nicta.com.au) 6947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt May 2004 7047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 7147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 7247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <stdlib.h> 7347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <stdio.h> 7447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <string.h> 7547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <errno.h> 7647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <syslog.h> 7747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <pthread.h> 7847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <ctype.h> 7947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 8047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <sys/types.h> 8147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <sys/time.h> 8247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <sys/socket.h> 8347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 8447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <netinet/in.h> 8547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 8647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <arpa/inet.h> 8747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define BIND_8_COMPAT 1 8847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <arpa/nameser.h> 8947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 9047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <dns_sd.h> 9147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 9247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 9347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 9447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Public functions 9547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 9647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 9747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Count the number of dots in a name string. 9847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 9947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 10047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcount_dots (const char * name); 10147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 10247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 10347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 10447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Test whether a domain name is local. 10547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 10647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 10747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 1 if name ends with ".local" or ".local." 10847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 0 otherwise 10947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 11047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 11147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltislocal (const char * name); 11247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 11347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 11447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 11547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Format an address structure as a string appropriate for DNS reverse (PTR) 11647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt lookup, based on address type. 11747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 11847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 11947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt prefixlen 12047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Prefix length, in bits. When formatting, this will be rounded up 12147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt to the nearest appropriate size. If -1, assume maximum. 12247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt buf 12347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Output buffer. Must be long enough to hold largest possible 12447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt output. 12547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 12647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Pointer to (first character of) output buffer, 12747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt or NULL on error. 12847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 12947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltchar * 13047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltformat_reverse_addr (int af, const void * addr, int prefixlen, char * buf); 13147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 13247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 13347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 13447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Format an address structure as a string appropriate for DNS reverse (PTR) 13547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt lookup for AF_INET. Output is in .in-addr.arpa domain. 13647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 13747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 13847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt prefixlen 13947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Prefix length, in bits. When formatting, this will be rounded up 14047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt to the nearest byte (8). If -1, assume 32. 14147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt buf 14247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Output buffer. Must be long enough to hold largest possible 14347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt output. For AF_INET, this is 29 characters (including null). 14447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 14547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Pointer to (first character of) output buffer, 14647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt or NULL on error. 14747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 14847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltchar * 14947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltformat_reverse_addr_in ( 15047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const struct in_addr * addr, 15147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int prefixlen, 15247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * buf 15347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 15447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define DNS_PTR_AF_INET_SIZE 29 15547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 15647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 15747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Format an address structure as a string appropriate for DNS reverse (PTR) 15847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt lookup for AF_INET6. Output is in .ip6.arpa domain. 15947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 16047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 16147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt prefixlen 16247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Prefix length, in bits. When formatting, this will be rounded up 16347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt to the nearest nibble (4). If -1, assume 128. 16447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt buf 16547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Output buffer. Must be long enough to hold largest possible 16647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt output. For AF_INET6, this is 72 characters (including null). 16747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 16847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Pointer to (first character of) output buffer, 16947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt or NULL on error. 17047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 17147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltchar * 17247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltformat_reverse_addr_in6 ( 17347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const struct in6_addr * addr, 17447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int prefixlen, 17547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * buf 17647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 17747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define DNS_PTR_AF_INET6_SIZE 72 17847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 17947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 18047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 18147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Compare whether the given dns name has the given domain suffix. 18247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt A single leading '.' on the name or leading or trailing '.' on the 18347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domain is ignored for the purposes of the comparison. 18447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Multiple leading or trailing '.'s are an error. Other DNS syntax 18547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errors are not checked for. The comparison is case insensitive. 18647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 18747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 18847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 1 on success (match) 18947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 0 on failure (no match) 19047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt < 0 on error 19147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 19247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 19347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcmp_dns_suffix (const char * name, const char * domain); 19447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltenum 19547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 19647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt CMP_DNS_SUFFIX_SUCCESS = 1, 19747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt CMP_DNS_SUFFIX_FAILURE = 0, 19847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt CMP_DNS_SUFFIX_BAD_NAME = 1, 19947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt CMP_DNS_SUFFIX_BAD_DOMAIN = -2 20047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}; 20147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 20247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef int ns_type_t; 20347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef int ns_class_t; 20447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 20547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 20647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Convert a DNS resource record (RR) code to an address family (AF) code. 20747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 20847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 20947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rrtype 21047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt resource record type (from nameser.h) 21147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 21247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 21347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Appropriate AF code (from socket.h), or AF_UNSPEC if an appropriate 21447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mapping couldn't be determined 21547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 21647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 21747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltrr_to_af (ns_type_t rrtype); 21847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 21947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 22047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 22147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Convert an address family (AF) code to a DNS resource record (RR) code. 22247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 22347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 22447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int 22547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt address family code (from socket.h) 22647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 22747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Appropriate RR code (from nameser.h), or ns_t_invalid if an appropriate 22847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mapping couldn't be determined 22947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 23047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltns_type_t 23147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltaf_to_rr (int af); 23247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 23347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 23447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 23547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Convert a string to an address family (case insensitive). 23647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 23747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 23847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Matching AF code, or AF_UNSPEC if no match found. 23947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 24047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 24147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstr_to_af (const char * str); 24247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 24347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 24447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 24547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Convert a string to an ns_class_t (case insensitive). 24647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 24747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 24847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Matching ns_class_t, or ns_c_invalid if no match found. 24947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 25047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltns_class_t 25147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstr_to_ns_class (const char * str); 25247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 25347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 25447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 25547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Convert a string to an ns_type_t (case insensitive). 25647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 25747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 25847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Matching ns_type_t, or ns_t_invalid if no match found. 25947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 26047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltns_type_t 26147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstr_to_ns_type (const char * str); 26247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 26347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 26447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 26547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Convert an address family code to a string. 26647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 26747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 26847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt String representation of AF, 26947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt or NULL if address family unrecognised or invalid. 27047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 27147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconst char * 27247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltaf_to_str (int in); 27347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 27447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 27547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 27647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Convert an ns_class_t code to a string. 27747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 27847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 27947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt String representation of ns_class_t, 28047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt or NULL if ns_class_t unrecognised or invalid. 28147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 28247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconst char * 28347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltns_class_to_str (ns_class_t in); 28447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 28547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 28647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 28747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Convert an ns_type_t code to a string. 28847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 28947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 29047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt String representation of ns_type_t, 29147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt or NULL if ns_type_t unrecognised or invalid. 29247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 29347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconst char * 29447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltns_type_to_str (ns_type_t in); 29547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 29647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 29747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 29847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Convert DNS rdata in label format (RFC1034, RFC1035) to a name. 29947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 30047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt On error, partial data is written to name (as much as was successfully 30147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt processed) and an error code is returned. Errors include a name too 30247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt long for the buffer and a pointer in the label (which cannot be 30347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt resolved). 30447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 30547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 30647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rdata 30747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Rdata formatted as series of labels. 30847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rdlen 30947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Length of rdata buffer. 31047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name 31147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Buffer to store fully qualified result in. 31247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt By RFC1034 section 3.1, a 255 character buffer (256 characters 31347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt including null) is long enough for any legal name. 31447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name_len 31547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Number of characters available in name buffer, not including 31647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt trailing null. 31747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 31847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 31947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Length of name buffer (not including trailing null). 32047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt < 0 on error. 32147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt A return of 0 implies the empty domain. 32247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 32347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 32447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltdns_rdata_to_name (const char * rdata, int rdlen, char * name, int name_len); 32547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltenum 32647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 32747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNS_RDATA_TO_NAME_BAD_FORMAT = -1, 32847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Format is broken. Usually because we ran out of data 32947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // (according to rdata) before the labels said we should. 33047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNS_RDATA_TO_NAME_TOO_LONG = -2, 33147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // The converted rdata is longer than the name buffer. 33247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNS_RDATA_TO_NAME_PTR = -3, 33347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // The rdata contains a pointer. 33447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}; 33547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 33647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define DNS_LABEL_MAXLEN 63 33747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Maximum length of a single DNS label 33847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define DNS_NAME_MAXLEN 256 33947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Maximum length of a DNS name 34047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 34147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 34247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Public types 34347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 34447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef int errcode_t; 34547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Used for 0 = success, non-zero = error code functions 34647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 34747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 34847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 34947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Public functions 35047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 35147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 35247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Test whether a domain name is in a domain covered by nss_mdns. 35347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt The name is assumed to be fully qualified (trailing dot optional); 35447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt unqualified names will be processed but may return unusual results 35547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if the unqualified prefix happens to match a domain suffix. 35647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 35747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 35847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 1 success 35947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 0 failure 36047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt -1 error, check errno 36147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 36247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 36347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconfig_is_mdns_suffix (const char * name); 36447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 36547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 36647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 36747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Loads all relevant data from configuration file. Other code should 36847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rarely need to call this function, since all other public configuration 36947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt functions do so implicitly. Once loaded, configuration info doesn't 37047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt change. 37147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 37247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 37347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 0 configuration ready 37447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt non-zero configuration error code 37547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 37647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalterrcode_t 37747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltinit_config (); 37847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 37947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define ENTNAME hostent 38047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define DATABASE "hosts" 38147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 38247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <nss.h> 38347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // For nss_status 38447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <netdb.h> 38547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // For hostent 38647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <sys/types.h> 38747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // For size_t 38847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 38947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef enum nss_status nss_status; 39047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct hostent hostent; 39147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 39247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 39347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltgethostbyname implementation 39447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 39547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name: 39647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name to look up 39747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_buf: 39847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt resulting entry 39947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt buf: 40047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt auxillary buffer 40147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt buflen: 40247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt length of auxillary buffer 40347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errnop: 40447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt pointer to errno 40547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt h_errnop: 40647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt pointer to h_errno 40747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 40847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltnss_status 40947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_nss_mdns_gethostbyname_r ( 41047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char *name, 41147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt hostent * result_buf, 41247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char *buf, 41347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size_t buflen, 41447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *errnop, 41547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *h_errnop 41647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 41747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 41847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 41947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 42047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltgethostbyname2 implementation 42147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 42247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name: 42347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name to look up 42447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt af: 42547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt address family 42647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_buf: 42747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt resulting entry 42847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt buf: 42947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt auxillary buffer 43047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt buflen: 43147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt length of auxillary buffer 43247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errnop: 43347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt pointer to errno 43447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt h_errnop: 43547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt pointer to h_errno 43647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 43747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltnss_status 43847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_nss_mdns_gethostbyname2_r ( 43947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char *name, 44047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int af, 44147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt hostent * result_buf, 44247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char *buf, 44347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size_t buflen, 44447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *errnop, 44547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *h_errnop 44647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 44747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 44847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 44947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 45047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltgethostbyaddr implementation 45147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 45247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr: 45347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt address structure to look up 45447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt len: 45547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt length of address structure 45647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt af: 45747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt address family 45847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_buf: 45947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt resulting entry 46047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt buf: 46147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt auxillary buffer 46247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt buflen: 46347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt length of auxillary buffer 46447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errnop: 46547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt pointer to errno 46647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt h_errnop: 46747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt pointer to h_errno 46847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 46947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltnss_status 47047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_nss_mdns_gethostbyaddr_r ( 47147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const void *addr, 47247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt socklen_t len, 47347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int af, 47447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt hostent * result_buf, 47547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char *buf, 47647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size_t buflen, 47747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *errnop, 47847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *h_errnop 47947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 48047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 48147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 48247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 48347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Types and Constants 48447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 48547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconst int MDNS_VERBOSE = 0; 48647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // This enables verbose syslog messages 48747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // If zero, only "imporant" messages will appear in syslog 48847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 48947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define k_hostname_maxlen 256 49047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // As per RFC1034 and RFC1035 49147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define k_aliases_max 15 49247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define k_addrs_max 15 49347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 49447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct buf_header 49547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 49647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char hostname [k_hostname_maxlen + 1]; 49747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * aliases [k_aliases_max + 1]; 49847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * addrs [k_addrs_max + 1]; 49947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} buf_header_t; 50047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 50147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct result_map 50247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 50347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int done; 50447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt nss_status status; 50547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt hostent * hostent; 50647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt buf_header_t * header; 50747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int aliases_count; 50847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int addrs_count; 50947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * buffer; 51047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int addr_idx; 51147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Index for addresses - grow from low end 51247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Index points to first empty space 51347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int alias_idx; 51447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Index for aliases - grow from high end 51547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Index points to lowest entry 51647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int r_errno; 51747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int r_h_errno; 51847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} result_map_t; 51947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 52047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const struct timeval 52147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt k_select_time = { 0, 500000 }; 52247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // 0 seconds, 500 milliseconds 52347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 52447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 52547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Local prototypes 52647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 52747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 52847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltmdns_gethostbyname2 ( 52947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char *name, 53047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int af, 53147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt hostent * result_buf, 53247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char *buf, 53347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size_t buflen, 53447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *errnop, 53547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *h_errnop 53647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 53747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 53847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 53947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 54047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Lookup name using mDNS server 54147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 54247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 54347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltmdns_lookup_name ( 54447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * fullname, 54547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int af, 54647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t * result 54747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 54847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 54947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 55047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Lookup address using mDNS server 55147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 55247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 55347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltmdns_lookup_addr ( 55447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const void * addr, 55547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt socklen_t len, 55647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int af, 55747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * addr_str, 55847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t * result 55947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 56047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 56147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 56247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 56347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Handle incoming MDNS events 56447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 56547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 56647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalthandle_events (DNSServiceRef sdref, result_map_t * result, const char * str); 56747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 56847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 56947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Callback for mdns_lookup operations 57047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//DNSServiceQueryRecordReply mdns_lookup_callback; 57147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef void 57247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltmdns_lookup_callback_t 57347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt( 57447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceRef sdref, 57547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceFlags flags, 57647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt uint32_t interface_index, 57747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceErrorType error_code, 57847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char *fullname, 57947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt uint16_t rrtype, 58047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt uint16_t rrclass, 58147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt uint16_t rdlen, 58247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const void *rdata, 58347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt uint32_t ttl, 58447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt void *context 58547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 58647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 58747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltmdns_lookup_callback_t mdns_lookup_callback; 58847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 58947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 59047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 59147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltinit_result ( 59247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t * result, 59347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt hostent * result_buf, 59447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * buf, 59547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size_t buflen 59647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 59747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 59847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 59947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcallback_body_ptr ( 60047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * fullname, 60147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t * result, 60247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int rdlen, 60347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const void * rdata 60447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 60547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 60647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic void * 60747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltadd_address_to_buffer (result_map_t * result, const void * data, int len); 60847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic char * 60947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltadd_alias_to_buffer (result_map_t * result, const char * data, int len); 61047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic char * 61147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltadd_hostname_len (result_map_t * result, const char * fullname, int len); 61247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic char * 61347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltadd_hostname_or_alias (result_map_t * result, const char * data, int len); 61447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 61547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic void * 61647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcontains_address (result_map_t * result, const void * data, int len); 61747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic char * 61847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcontains_alias (result_map_t * result, const char * data); 61947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 62047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 62147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const char * 62247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltis_applicable_name ( 62347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t * result, 62447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * name, 62547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * lookup_name 62647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 62747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 62847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const char * 62947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltis_applicable_addr ( 63047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t * result, 63147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const void * addr, 63247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int af, 63347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * addr_str 63447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 63547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 63647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 63747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Error code functions 63847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 63947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 64047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltset_err (result_map_t * result, nss_status status, int err, int herr); 64147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 64247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status set_err_notfound (result_map_t * result); 64347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status set_err_bad_hostname (result_map_t * result); 64447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status set_err_buf_too_small (result_map_t * result); 64547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status set_err_internal_resource_full (result_map_t * result); 64647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status set_err_system (result_map_t * result); 64747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status set_err_mdns_failed (result_map_t * result); 64847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status set_err_success (result_map_t * result); 64947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 65047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 65147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 65247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Global variables 65347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 65447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 65547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 65647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// NSS functions 65747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 65847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltnss_status 65947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_nss_mdns_gethostbyname_r ( 66047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char *name, 66147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt hostent * result_buf, 66247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char *buf, 66347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size_t buflen, 66447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *errnop, 66547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *h_errnop 66647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 66747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 66847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MDNS_VERBOSE) 66947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_DEBUG, 67047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Called nss_mdns_gethostbyname with %s", 67147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name 67247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 67347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 67447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 67547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mdns_gethostbyname2 ( 67647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name, AF_INET, result_buf, buf, buflen, errnop, h_errnop 67747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 67847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 67947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 68047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 68147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltnss_status 68247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_nss_mdns_gethostbyname2_r ( 68347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char *name, 68447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int af, 68547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt hostent * result_buf, 68647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char *buf, 68747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size_t buflen, 68847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *errnop, 68947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *h_errnop 69047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 69147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 69247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MDNS_VERBOSE) 69347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_DEBUG, 69447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Called nss_mdns_gethostbyname2 with %s", 69547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name 69647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 69747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 69847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 69947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mdns_gethostbyname2 ( 70047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name, af, result_buf, buf, buflen, errnop, h_errnop 70147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 70247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 70347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 70447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 70547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltnss_status 70647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_nss_mdns_gethostbyaddr_r ( 70747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const void *addr, 70847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt socklen_t len, 70947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int af, 71047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt hostent * result_buf, 71147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char *buf, 71247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size_t buflen, 71347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *errnop, 71447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *h_errnop 71547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 71647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 71747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char addr_str [NI_MAXHOST + 1]; 71847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t result; 71947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int err_status; 72047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 72147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (inet_ntop (af, addr, addr_str, NI_MAXHOST) == NULL) 72247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 72347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * family = af_to_str (af); 72447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (family == NULL) 72547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 72647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt family = "Unknown"; 72747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 72847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 72947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 73047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Couldn't covert address, family %d (%s) in nss_mdns_gethostbyaddr: %s", 73147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt af, 73247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt family, 73347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt strerror (errno) 73447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 73547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 73647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // This address family never applicable to us, so return NOT_FOUND 73747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 73847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *errnop = ENOENT; 73947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *h_errnop = HOST_NOT_FOUND; 74047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NSS_STATUS_NOTFOUND; 74147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 74247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MDNS_VERBOSE) 74347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 74447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_DEBUG, 74547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Called nss_mdns_gethostbyaddr with %s", 74647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr_str 74747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 74847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 74947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 75047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Initialise result 75147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt err_status = init_result (&result, result_buf, buf, buflen); 75247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (err_status) 75347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 75447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *errnop = err_status; 75547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *h_errnop = NETDB_INTERNAL; 75647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NSS_STATUS_TRYAGAIN; 75747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 75847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 75947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (is_applicable_addr (&result, addr, af, addr_str)) 76047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 76147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt nss_status rv; 76247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 76347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rv = mdns_lookup_addr (addr, len, af, addr_str, &result); 76447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (rv == NSS_STATUS_SUCCESS) 76547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 76647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return rv; 76747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 76847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 76947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 77047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Return current error status (defaults to NOT_FOUND) 77147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 77247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *errnop = result.r_errno; 77347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *h_errnop = result.r_h_errno; 77447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return result.status; 77547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 77647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 77747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 77847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 77947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Local functions 78047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 78147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltnss_status 78247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltmdns_gethostbyname2 ( 78347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char *name, 78447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int af, 78547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt hostent * result_buf, 78647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char *buf, 78747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size_t buflen, 78847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *errnop, 78947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int *h_errnop 79047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 79147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 79247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char lookup_name [k_hostname_maxlen + 1]; 79347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t result; 79447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int err_status; 79547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 79647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Initialise result 79747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt err_status = init_result (&result, result_buf, buf, buflen); 79847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (err_status) 79947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 80047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *errnop = err_status; 80147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *h_errnop = NETDB_INTERNAL; 80247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NSS_STATUS_TRYAGAIN; 80347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 80447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 80547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (is_applicable_name (&result, name, lookup_name)) 80647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 80747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Try using mdns 80847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt nss_status rv; 80947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 81047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MDNS_VERBOSE) 81147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_DEBUG, 81247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Local name: %s", 81347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name 81447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 81547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 81647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rv = mdns_lookup_name (name, af, &result); 81747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (rv == NSS_STATUS_SUCCESS) 81847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 81947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return rv; 82047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 82147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 82247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 82347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Return current error status (defaults to NOT_FOUND) 82447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 82547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *errnop = result.r_errno; 82647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *h_errnop = result.r_h_errno; 82747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return result.status; 82847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 82947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 83047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 83147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 83247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Lookup a fully qualified hostname using the default record type 83347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for the specified address family. 83447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 83547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 83647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fullname 83747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Fully qualified hostname. If not fully qualified the code will 83847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt still 'work', but the lookup is unlikely to succeed. 83947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt af 84047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Either AF_INET or AF_INET6. Other families are not supported. 84147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result 84247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Initialised 'result' data structure. 84347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 84447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 84547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltmdns_lookup_name ( 84647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * fullname, 84747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int af, 84847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t * result 84947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 85047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 85147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Lookup using mDNS. 85247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceErrorType errcode; 85347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceRef sdref; 85447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ns_type_t rrtype; 85547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt nss_status status; 85647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 85747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MDNS_VERBOSE) 85847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_DEBUG, 85947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Attempting lookup of %s", 86047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fullname 86147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 86247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 86347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt switch (af) 86447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 86547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case AF_INET: 86647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rrtype = kDNSServiceType_A; 86747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->hostent->h_length = 4; 86847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Length of an A record 86947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt break; 87047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 87147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case AF_INET6: 87247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rrtype = kDNSServiceType_AAAA; 87347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->hostent->h_length = 16; 87447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Length of an AAAA record 87547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt break; 87647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 87747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt default: 87847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 87947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Unsupported address family %d", 88047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt af 88147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 88247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return set_err_bad_hostname (result); 88347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 88447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->hostent->h_addrtype = af; 88547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 88647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errcode = 88747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceQueryRecord ( 88847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt &sdref, 88947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt kDNSServiceFlagsForceMulticast, // force multicast query 89047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt kDNSServiceInterfaceIndexAny, // all interfaces 89147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fullname, // full name to query for 89247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rrtype, // resource record type 89347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt kDNSServiceClass_IN, // internet class records 89447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mdns_lookup_callback, // callback 89547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result // Context - result buffer 89647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 89747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 89847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (errcode) 89947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 90047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 90147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Failed to initialise lookup, error %d", 90247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errcode 90347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 90447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return set_err_mdns_failed (result); 90547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 90647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 90747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt status = handle_events (sdref, result, fullname); 90847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceRefDeallocate (sdref); 90947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return status; 91047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 91147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 91247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 91347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 91447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Reverse (PTR) lookup for the specified address. 91547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 91647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 91747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr 91847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Either a struct in_addr or a struct in6_addr 91947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr_len 92047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size of the address 92147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt af 92247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Either AF_INET or AF_INET6. Other families are not supported. 92347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Must match addr 92447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr_str 92547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Address in format suitable for PTR lookup. 92647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt AF_INET: a.b.c.d -> d.c.b.a.in-addr.arpa 92747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt AF_INET6: reverse nibble format, x.x.x...x.ip6.arpa 92847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result 92947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Initialised 'result' data structure. 93047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 93147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 93247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltmdns_lookup_addr ( 93347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const void * addr, 93447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt socklen_t addr_len, 93547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int af, 93647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * addr_str, 93747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t * result 93847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 93947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 94047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceErrorType errcode; 94147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceRef sdref; 94247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt nss_status status; 94347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 94447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MDNS_VERBOSE) 94547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_DEBUG, 94647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Attempting lookup of %s", 94747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr_str 94847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 94947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 95047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->hostent->h_addrtype = af; 95147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->hostent->h_length = addr_len; 95247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 95347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Query address becomes "address" in result. 95447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! add_address_to_buffer (result, addr, addr_len)) 95547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 95647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return result->status; 95747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 95847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 95947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->hostent->h_name [0] = 0; 96047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 96147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errcode = 96247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceQueryRecord ( 96347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt &sdref, 96447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt kDNSServiceFlagsForceMulticast, // force multicast query 96547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt kDNSServiceInterfaceIndexAny, // all interfaces 96647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr_str, // address string to query for 96747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt kDNSServiceType_PTR, // pointer RRs 96847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt kDNSServiceClass_IN, // internet class records 96947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mdns_lookup_callback, // callback 97047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result // Context - result buffer 97147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 97247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 97347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (errcode) 97447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 97547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 97647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Failed to initialise mdns lookup, error %d", 97747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errcode 97847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 97947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return set_err_mdns_failed (result); 98047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 98147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 98247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt status = handle_events (sdref, result, addr_str); 98347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceRefDeallocate (sdref); 98447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return status; 98547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 98647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 98747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 98847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 98947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Wait on result of callback, and process it when it arrives. 99047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 99147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 99247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt sdref 99347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt dns-sd reference 99447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result 99547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Initialised 'result' data structure. 99647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt str 99747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt lookup string, used for status/error reporting. 99847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 99947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 100047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalthandle_events (DNSServiceRef sdref, result_map_t * result, const char * str) 100147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 100247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int dns_sd_fd = DNSServiceRefSockFD(sdref); 100347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int nfds = dns_sd_fd + 1; 100447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fd_set readfds; 100547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt struct timeval tv; 100647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int select_result; 100747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 100847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (! result->done) 100947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 101047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt FD_ZERO(&readfds); 101147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt FD_SET(dns_sd_fd, &readfds); 101247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 101347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt tv = k_select_time; 101447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 101547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt select_result = 101647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt select (nfds, &readfds, (fd_set*)NULL, (fd_set*)NULL, &tv); 101747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (select_result > 0) 101847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 101947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (FD_ISSET(dns_sd_fd, &readfds)) 102047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 102147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MDNS_VERBOSE) 102247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_DEBUG, 102347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Reply received for %s", 102447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt str 102547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 102647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceProcessResult(sdref); 102747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 102847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 102947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 103047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 103147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Unexpected return from select on lookup of %s", 103247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt str 103347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 103447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 103547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 103647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 103747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 103847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Terminate loop due to timer expiry 103947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MDNS_VERBOSE) 104047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_DEBUG, 104147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: %s not found - timer expired", 104247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt str 104347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 104447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt set_err_notfound (result); 104547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt break; 104647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 104747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 104847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 104947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return result->status; 105047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 105147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 105247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 105347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 105447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Examine incoming data and add to relevant fields in result structure. 105547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt This routine is called from DNSServiceProcessResult where appropriate. 105647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 105747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid 105847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltmdns_lookup_callback 105947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt( 106047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceRef sdref, 106147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceFlags flags, 106247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt uint32_t interface_index, 106347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DNSServiceErrorType error_code, 106447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char *fullname, 106547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt uint16_t rrtype, 106647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt uint16_t rrclass, 106747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt uint16_t rdlen, 106847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const void *rdata, 106947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt uint32_t ttl, 107047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt void *context 107147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 107247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 107347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // A single record is received 107447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 107547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t * result = (result_map_t *) context; 107647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 107747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (void)sdref; // Unused 107847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (void)interface_index; // Unused 107947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (void)ttl; // Unused 108047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 108147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! (flags & kDNSServiceFlagsMoreComing) ) 108247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 108347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->done = 1; 108447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 108547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 108647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (error_code == kDNSServiceErr_NoError) 108747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 108847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ns_type_t expected_rr_type = 108947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt af_to_rr (result->hostent->h_addrtype); 109047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 109147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Idiot check class 109247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (rrclass != C_IN) 109347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 109447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 109547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Received bad RR class: expected %d (%s)," 109647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt " got %d (%s), RR type %d (%s)", 109747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt C_IN, 109847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ns_class_to_str (C_IN), 109947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rrclass, 110047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ns_class_to_str (rrclass), 110147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rrtype, 110247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ns_type_to_str (rrtype) 110347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 110447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return; 110547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 110647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 110747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // If a PTR 110847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (rrtype == kDNSServiceType_PTR) 110947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 111047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (callback_body_ptr (fullname, result, rdlen, rdata) < 0) 111147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return; 111247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 111347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else if (rrtype == expected_rr_type) 111447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 111547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! 111647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt add_hostname_or_alias ( 111747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result, 111847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fullname, 111947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt strlen (fullname) 112047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ) 112147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ) 112247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 112347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->done = 1; 112447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return; 112547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Abort on error 112647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 112747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 112847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! add_address_to_buffer (result, rdata, rdlen) ) 112947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 113047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->done = 1; 113147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return; 113247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Abort on error 113347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 113447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 113547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 113647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 113747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 113847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Received bad RR type: expected %d (%s)," 113947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt " got %d (%s)", 114047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt expected_rr_type, 114147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ns_type_to_str (expected_rr_type), 114247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rrtype, 114347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ns_type_to_str (rrtype) 114447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 114547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return; 114647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 114747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 114847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (result->status != NSS_STATUS_SUCCESS) 114947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt set_err_success (result); 115047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 115147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 115247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 115347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // For now, dump message to syslog and continue 115447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 115547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: callback returned error %d", 115647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt error_code 115747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 115847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 115947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 116047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 116147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 116247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcallback_body_ptr ( 116347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * fullname, 116447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t * result, 116547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int rdlen, 116647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const void * rdata 116747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 116847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 116947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char result_name [k_hostname_maxlen + 1]; 117047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int rv; 117147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 117247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Fullname should be .in-addr.arpa or equivalent, which we're 117347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // not interested in. Ignore it. 117447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 117547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rv = dns_rdata_to_name (rdata, rdlen, result_name, k_hostname_maxlen); 117647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (rv < 0) 117747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 117847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * errmsg; 117947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 118047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt switch (rv) 118147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 118247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case DNS_RDATA_TO_NAME_BAD_FORMAT: 118347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errmsg = "mdns: PTR '%s' result badly formatted ('%s...')"; 118447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt break; 118547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 118647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case DNS_RDATA_TO_NAME_TOO_LONG: 118747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errmsg = "mdns: PTR '%s' result too long ('%s...')"; 118847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt break; 118947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 119047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case DNS_RDATA_TO_NAME_PTR: 119147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errmsg = "mdns: PTR '%s' result contained pointer ('%s...')"; 119247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt break; 119347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 119447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt default: 119547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errmsg = "mdns: PTR '%s' result conversion failed ('%s...')"; 119647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 119747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 119847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 119947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errmsg, 120047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fullname, 120147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_name 120247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 120347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 120447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return -1; 120547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 120647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 120747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MDNS_VERBOSE) 120847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 120947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_DEBUG, 121047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: PTR '%s' resolved to '%s'", 121147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fullname, 121247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_name 121347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 121447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 121547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 121647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Data should be a hostname 121747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! 121847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt add_hostname_or_alias ( 121947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result, 122047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_name, 122147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rv 122247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ) 122347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ) 122447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 122547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->done = 1; 122647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return -1; 122747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 122847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 122947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 0; 123047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 123147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 123247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 123347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 123447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Add an address to the buffer. 123547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 123647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameter 123747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result 123847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Result structure to write to 123947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt data 124047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Incoming address data buffer 124147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Must be 'int' aligned 124247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt len 124347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Length of data buffer (in bytes) 124447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Must match data alignment 124547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 124647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Result 124747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Pointer to start of newly written data, 124847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt or NULL on error. 124947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt If address already exists in buffer, returns pointer to that instead. 125047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 125147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic void * 125247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltadd_address_to_buffer (result_map_t * result, const void * data, int len) 125347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 125447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int new_addr; 125547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt void * start; 125647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt void * temp; 125747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 125847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if ((temp = contains_address (result, data, len))) 125947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 126047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return temp; 126147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 126247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 126347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (result->addrs_count >= k_addrs_max) 126447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 126547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Not enough addr slots 126647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt set_err_internal_resource_full (result); 126747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_ERR, 126847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Internal address buffer full; increase size" 126947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 127047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 127147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 127247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 127347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Idiot check 127447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (len != result->hostent->h_length) 127547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 127647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 127747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Unexpected rdata length for address. Expected %d, got %d", 127847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->hostent->h_length, 127947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt len 128047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 128147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // XXX And continue for now. 128247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 128347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 128447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt new_addr = result->addr_idx + len; 128547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 128647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (new_addr > result->alias_idx) 128747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 128847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Not enough room 128947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt set_err_buf_too_small (result); 129047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MDNS_VERBOSE) 129147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_DEBUG, 129247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Ran out of buffer when adding address %d", 129347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->addrs_count + 1 129447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 129547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 129647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 129747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 129847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt start = result->buffer + result->addr_idx; 129947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt memcpy (start, data, len); 130047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->addr_idx = new_addr; 130147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->header->addrs [result->addrs_count] = start; 130247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->addrs_count ++; 130347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->header->addrs [result->addrs_count] = NULL; 130447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 130547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return start; 130647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 130747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 130847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 130947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic void * 131047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcontains_address (result_map_t * result, const void * data, int len) 131147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 131247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 131347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 131447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Idiot check 131547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (len != result->hostent->h_length) 131647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 131747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 131847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Unexpected rdata length for address. Expected %d, got %d", 131947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->hostent->h_length, 132047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt len 132147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 132247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // XXX And continue for now. 132347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 132447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 132547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i = 0; result->header->addrs [i]; i++) 132647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 132747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (memcmp (result->header->addrs [i], data, len) == 0) 132847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 132947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return result->header->addrs [i]; 133047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 133147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 133247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 133347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 133447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 133547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 133647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 133747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 133847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Add an alias to the buffer. 133947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 134047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameter 134147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result 134247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Result structure to write to 134347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt data 134447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Incoming alias (null terminated) 134547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt len 134647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Length of data buffer (in bytes), including trailing null 134747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 134847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Result 134947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Pointer to start of newly written data, 135047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt or NULL on error 135147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt If alias already exists in buffer, returns pointer to that instead. 135247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 135347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic char * 135447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltadd_alias_to_buffer (result_map_t * result, const char * data, int len) 135547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 135647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int new_alias; 135747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * start; 135847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * temp; 135947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 136047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if ((temp = contains_alias (result, data))) 136147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 136247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return temp; 136347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 136447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 136547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (result->aliases_count >= k_aliases_max) 136647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 136747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Not enough alias slots 136847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt set_err_internal_resource_full (result); 136947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_ERR, 137047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Internal alias buffer full; increase size" 137147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 137247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 137347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 137447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 137547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt new_alias = result->alias_idx - len; 137647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 137747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (new_alias < result->addr_idx) 137847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 137947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Not enough room 138047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt set_err_buf_too_small (result); 138147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MDNS_VERBOSE) 138247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_DEBUG, 138347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Ran out of buffer when adding alias %d", 138447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->aliases_count + 1 138547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 138647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 138747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 138847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 138947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt start = result->buffer + new_alias; 139047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt memcpy (start, data, len); 139147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->alias_idx = new_alias; 139247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->header->aliases [result->aliases_count] = start; 139347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->aliases_count ++; 139447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->header->aliases [result->aliases_count] = NULL; 139547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 139647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return start; 139747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 139847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 139947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 140047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic char * 140147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcontains_alias (result_map_t * result, const char * alias) 140247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 140347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 140447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 140547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i = 0; result->header->aliases [i]; i++) 140647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 140747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (strcmp (result->header->aliases [i], alias) == 0) 140847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 140947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return result->header->aliases [i]; 141047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 141147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 141247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 141347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 141447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 141547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 141647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 141747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 141847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Add fully qualified hostname to result. 141947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 142047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameter 142147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result 142247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Result structure to write to 142347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fullname 142447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Fully qualified hostname 142547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 142647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Result 142747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Pointer to start of hostname buffer, 142847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt or NULL on error (usually hostname too long) 142947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 143047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 143147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic char * 143247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltadd_hostname_len (result_map_t * result, const char * fullname, int len) 143347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 143447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (len >= k_hostname_maxlen) 143547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 143647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt set_err_bad_hostname (result); 143747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 143847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Hostname too long '%.*s': len %d, max %d", 143947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt len, 144047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fullname, 144147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt len, 144247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt k_hostname_maxlen 144347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 144447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 144547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 144647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 144747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->hostent->h_name = 144847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt strcpy (result->header->hostname, fullname); 144947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 145047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return result->header->hostname; 145147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 145247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 145347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 145447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 145547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Add fully qualified name as hostname or alias. 145647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 145747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt If hostname is not fully qualified this is not an error, but the data 145847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt returned may be not what the application wanted. 145947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 146047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameter 146147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result 146247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Result structure to write to 146347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt data 146447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Incoming alias (null terminated) 146547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt len 146647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Length of data buffer (in bytes), including trailing null 146747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 146847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Result 146947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Pointer to start of newly written data, 147047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt or NULL on error 147147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt If alias or hostname already exists, returns pointer to that instead. 147247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 147347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic char * 147447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltadd_hostname_or_alias (result_map_t * result, const char * data, int len) 147547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 147647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * hostname = result->hostent->h_name; 147747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 147847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (*hostname) 147947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 148047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (strcmp (hostname, data) == 0) 148147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 148247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return hostname; 148347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 148447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 148547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 148647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return add_alias_to_buffer (result, data, len); 148747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 148847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 148947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 149047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 149147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return add_hostname_len (result, data, len); 149247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 149347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 149447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 149547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 149647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 149747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltinit_result ( 149847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t * result, 149947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt hostent * result_buf, 150047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * buf, 150147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size_t buflen 150247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 150347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 150447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (buflen < sizeof (buf_header_t)) 150547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 150647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return ERANGE; 150747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 150847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 150947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->hostent = result_buf; 151047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->header = (buf_header_t *) buf; 151147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->header->hostname[0] = 0; 151247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->aliases_count = 0; 151347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->header->aliases[0] = NULL; 151447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->addrs_count = 0; 151547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->header->addrs[0] = NULL; 151647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->buffer = buf + sizeof (buf_header_t); 151747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->addr_idx = 0; 151847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->alias_idx = buflen - sizeof (buf_header_t); 151947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->done = 0; 152047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt set_err_notfound (result); 152147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 152247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Point hostent to the right buffers 152347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->hostent->h_name = result->header->hostname; 152447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->hostent->h_aliases = result->header->aliases; 152547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->hostent->h_addr_list = result->header->addrs; 152647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 152747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 0; 152847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 152947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 153047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 153147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Set the status in the result. 153247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 153347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 153447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result 153547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Result structure to update 153647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt status 153747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt New nss_status value 153847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt err 153947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt New errno value 154047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt herr 154147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt New h_errno value 154247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 154347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 154447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt New status value 154547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 154647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 154747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltset_err (result_map_t * result, nss_status status, int err, int herr) 154847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 154947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->status = status; 155047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->r_errno = err; 155147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->r_h_errno = herr; 155247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 155347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return status; 155447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 155547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 155647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 155747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltset_err_notfound (result_map_t * result) 155847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 155947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return set_err (result, NSS_STATUS_NOTFOUND, ENOENT, HOST_NOT_FOUND); 156047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 156147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 156247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 156347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltset_err_bad_hostname (result_map_t * result) 156447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 156547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return set_err (result, NSS_STATUS_TRYAGAIN, ENOENT, NO_RECOVERY); 156647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 156747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 156847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 156947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltset_err_buf_too_small (result_map_t * result) 157047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 157147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return set_err (result, NSS_STATUS_TRYAGAIN, ERANGE, NETDB_INTERNAL); 157247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 157347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 157447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 157547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltset_err_internal_resource_full (result_map_t * result) 157647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 157747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return set_err (result, NSS_STATUS_RETURN, ERANGE, NO_RECOVERY); 157847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 157947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 158047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 158147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltset_err_system (result_map_t * result) 158247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 158347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return set_err (result, NSS_STATUS_UNAVAIL, errno, NETDB_INTERNAL); 158447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 158547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 158647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 158747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltset_err_mdns_failed (result_map_t * result) 158847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 158947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return set_err (result, NSS_STATUS_TRYAGAIN, EAGAIN, TRY_AGAIN); 159047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 159147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 159247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic nss_status 159347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltset_err_success (result_map_t * result) 159447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 159547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result->status = NSS_STATUS_SUCCESS; 159647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return result->status; 159747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 159847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 159947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 160047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 160147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Test whether name is applicable for mdns to process, and if so copy into 160247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt lookup_name buffer (if non-NULL). 160347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 160447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 160547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Pointer to name to lookup up, if applicable, or NULL otherwise. 160647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 160747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const char * 160847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltis_applicable_name ( 160947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t * result, 161047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * name, 161147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * lookup_name 161247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 161347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 161447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int match = config_is_mdns_suffix (name); 161547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (match > 0) 161647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 161747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (lookup_name) 161847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 161947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt strncpy (lookup_name, name, k_hostname_maxlen + 1); 162047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return lookup_name; 162147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 162247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 162347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 162447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return name; 162547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 162647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 162747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 162847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 162947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (match < 0) 163047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 163147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt set_err_system (result); 163247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 163347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 163447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 163547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 163647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 163747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 163847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Test whether address is applicable for mdns to process, and if so copy into 163947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr_str buffer as an address suitable for ptr lookup. 164047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 164147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 164247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Pointer to name to lookup up, if applicable, or NULL otherwise. 164347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 164447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const char * 164547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltis_applicable_addr ( 164647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result_map_t * result, 164747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const void * addr, 164847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int af, 164947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * addr_str 165047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 165147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 165247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int match; 165347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 165447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! format_reverse_addr (af, addr, -1, addr_str)) 165547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 165647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MDNS_VERBOSE) 165747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_DEBUG, 165847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Failed to create reverse address" 165947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 166047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 166147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 166247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 166347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (MDNS_VERBOSE) 166447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_DEBUG, 166547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Reverse address: %s", 166647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr_str 166747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 166847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 166947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt match = config_is_mdns_suffix (addr_str); 167047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (match > 0) 167147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 167247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return addr_str; 167347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 167447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 167547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 167647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (match < 0) 167747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 167847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt set_err_system (result); 167947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 168047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 168147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 168247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 168347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 168447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 168547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Types and Constants 168647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 168747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconst char * k_conf_file = "/etc/nss_mdns.conf"; 168847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#define CONF_LINE_SIZE 1024 168947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 169047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconst char k_comment_char = '#'; 169147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 169247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconst char * k_keyword_domain = "domain"; 169347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 169447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconst char * k_default_domains [] = 169547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 169647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "local", 169747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "254.169.in-addr.arpa", 169847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "8.e.f.ip6.int", 169947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "8.e.f.ip6.arpa", 170047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "9.e.f.ip6.int", 170147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "9.e.f.ip6.arpa", 170247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "a.e.f.ip6.int", 170347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "a.e.f.ip6.arpa", 170447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "b.e.f.ip6.int", 170547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "b.e.f.ip6.arpa", 170647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt NULL 170747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Always null terminated 170847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt }; 170947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 171047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Linked list of domains 171147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct domain_entry 171247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 171347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * domain; 171447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt struct domain_entry * next; 171547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} domain_entry_t; 171647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 171747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 171847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Config 171947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct 172047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 172147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domain_entry_t * domains; 172247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} config_t; 172347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 172447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconst config_t k_empty_config = 172547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 172647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt NULL 172747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt }; 172847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 172947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 173047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Context - tracks position in config file, used for error reporting 173147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct 173247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 173347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * filename; 173447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int linenum; 173547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} config_file_context_t; 173647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 173747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 173847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 173947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Local prototypes 174047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 174147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic errcode_t 174247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltload_config (config_t * conf); 174347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 174447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic errcode_t 174547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltprocess_config_line ( 174647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt config_t * conf, 174747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * line, 174847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt config_file_context_t * context 174947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt); 175047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 175147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic char * 175247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltget_next_word (char * input, char **next); 175347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 175447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic errcode_t 175547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltdefault_config (config_t * conf); 175647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 175747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic errcode_t 175847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltadd_domain (config_t * conf, const char * domain); 175947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 176047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 176147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcontains_domain (const config_t * conf, const char * domain); 176247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 176347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 176447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcontains_domain_suffix (const config_t * conf, const char * addr); 176547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 176647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 176747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 176847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Global variables 176947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 177047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic config_t * g_config = NULL; 177147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Configuration info 177247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 177347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltpthread_mutex_t g_config_mutex = 177447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP 177547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; 177647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#else 177747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt PTHREAD_MUTEX_INITIALIZER; 177847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif 177947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 178047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 178147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 178247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Configuration functions 178347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 178447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 178547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 178647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Initialise the configuration from the config file. 178747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 178847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 178947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 0 success 179047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt non-zero error code on failure 179147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 179247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalterrcode_t 179347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltinit_config () 179447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 179547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (g_config) 179647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 179747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt /* 179847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Safe to test outside mutex. 179947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt If non-zero, initialisation is complete and g_config can be 180047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt safely used read-only. If zero, then we do proper mutex 180147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt testing before initialisation. 180247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 180347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 0; 180447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 180547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 180647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 180747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int errcode = -1; 180847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int presult; 180947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt config_t * temp_config; 181047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 181147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Acquire mutex 181247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt presult = pthread_mutex_lock (&g_config_mutex); 181347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (presult) 181447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 181547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_ERR, 181647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Fatal mutex lock error in nss_mdns:init_config, %s:%d: %d: %s", 181747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt __FILE__, __LINE__, presult, strerror (presult) 181847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 181947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return presult; 182047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 182147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 182247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Test again now we have mutex, in case initialisation occurred while 182347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // we were waiting 182447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! g_config) 182547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 182647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt temp_config = (config_t *) malloc (sizeof (config_t)); 182747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (temp_config) 182847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 182947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Note: This code will leak memory if initialisation fails 183047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // repeatedly. This should only happen in the case of a memory 183147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // error, so I'm not sure if it's a meaningful problem. - AW 183247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *temp_config = k_empty_config; 183347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errcode = load_config (temp_config); 183447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 183547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! errcode) 183647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 183747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt g_config = temp_config; 183847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 183947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 184047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 184147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 184247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_ERR, 184347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Can't allocate memory in nss_mdns:init_config, %s:%d", 184447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt __FILE__, __LINE__ 184547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 184647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errcode = errno; 184747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 184847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 184947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 185047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt presult = pthread_mutex_unlock (&g_config_mutex); 185147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (presult) 185247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 185347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_ERR, 185447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Fatal mutex unlock error in nss_mdns:init_config, %s:%d: %d: %s", 185547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt __FILE__, __LINE__, presult, strerror (presult) 185647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 185747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errcode = presult; 185847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 185947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 186047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return errcode; 186147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 186247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 186347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 186447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 186547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 186647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconfig_is_mdns_suffix (const char * name) 186747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 186847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int errcode = init_config (); 186947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! errcode) 187047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 187147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return contains_domain_suffix (g_config, name); 187247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 187347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 187447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 187547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errno = errcode; 187647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return -1; 187747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 187847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 187947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 188047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 188147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 188247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Local functions 188347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 188447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic errcode_t 188547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltload_config (config_t * conf) 188647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 188747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt FILE * cf; 188847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char line [CONF_LINE_SIZE]; 188947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt config_file_context_t context; 189047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 189147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt context.filename = k_conf_file; 189247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt context.linenum = 0; 189347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 189447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 189547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt cf = fopen (context.filename, "r"); 189647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! cf) 189747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 189847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_INFO, 189947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Couldn't open nss_mdns configuration file %s, using default.", 190047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt context.filename 190147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 190247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return default_config (conf); 190347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 190447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 190547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (fgets (line, CONF_LINE_SIZE, cf)) 190647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 190747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int errcode; 190847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt context.linenum++; 190947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt errcode = process_config_line (conf, line, &context); 191047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (errcode) 191147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 191247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Critical error, give up 191347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fclose(cf); 191447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return errcode; 191547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 191647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 191747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 191847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fclose (cf); 191947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 192047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 0; 192147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 192247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 192347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 192447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 192547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parse a line of the configuration file. 192647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt For each keyword recognised, perform appropriate handling. 192747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt If the keyword is not recognised, print a message to syslog 192847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt and continue. 192947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 193047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 193147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 0 success, or recoverable config file error 193247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt non-zero serious system error, processing aborted 193347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 193447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic errcode_t 193547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltprocess_config_line ( 193647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt config_t * conf, 193747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * line, 193847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt config_file_context_t * context 193947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 194047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 194147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * curr = line; 194247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * word; 194347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 194447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt word = get_next_word (curr, &curr); 194547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! word || word [0] == k_comment_char) 194647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 194747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Nothing interesting on this line 194847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 0; 194947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 195047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 195147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (strcmp (word, k_keyword_domain) == 0) 195247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 195347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt word = get_next_word (curr, &curr); 195447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (word) 195547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 195647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int errcode = add_domain (conf, word); 195747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (errcode) 195847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 195947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // something badly wrong, bail 196047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return errcode; 196147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 196247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 196347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (get_next_word (curr, NULL)) 196447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 196547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 196647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "%s, line %d: ignored extra text found after domain", 196747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt context->filename, 196847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt context->linenum 196947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 197047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 197147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 197247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 197347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 197447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 197547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "%s, line %d: no domain specified", 197647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt context->filename, 197747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt context->linenum 197847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 197947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 198047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 198147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 198247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 198347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_WARNING, 198447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "%s, line %d: unknown keyword %s - skipping", 198547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt context->filename, 198647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt context->linenum, 198747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt word 198847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 198947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 199047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 199147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 0; 199247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 199347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 199447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 199547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 199647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Get next word (whitespace separated) from input string. 199747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt A null character is written into the first whitespace character following 199847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt the word. 199947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 200047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 200147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt input 200247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Input string. This string is modified by get_next_word. 200347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt next 200447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt If non-NULL and the result is non-NULL, a pointer to the 200547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt character following the end of the word (after the null) 200647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt is written to 'next'. 200747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt If no word is found, the original value is unchanged. 200847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt If the word extended to the end of the string, 'next' points 200947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt to the trailling NULL. 201047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt It is safe to pass 'str' as 'input' and '&str' as 'next'. 201147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Returns 201247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Pointer to the first non-whitespace character (and thus word) found. 201347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if no word is found, returns NULL. 201447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 201547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic char * 201647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltget_next_word (char * input, char **next) 201747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 201847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * curr = input; 201947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * result; 202047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 202147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (isspace (*curr)) 202247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 202347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt curr ++; 202447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 202547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 202647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (*curr == 0) 202747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 202847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 202947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 203047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 203147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result = curr; 203247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (*curr && ! isspace (*curr)) 203347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 203447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt curr++; 203547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 203647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (*curr) 203747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 203847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *curr = 0; 203947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (next) 204047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 204147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *next = curr+1; 204247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 204347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 204447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 204547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 204647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (next) 204747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 204847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *next = curr; 204947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 205047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 205147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 205247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return result; 205347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 205447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 205547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 205647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic errcode_t 205747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltdefault_config (config_t * conf) 205847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 205947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 206047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i = 0; k_default_domains [i]; i++) 206147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 206247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int errcode = 206347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt add_domain (conf, k_default_domains [i]); 206447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (errcode) 206547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 206647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Something has gone (badly) wrong - let's bail 206747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return errcode; 206847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 206947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 207047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 207147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 0; 207247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 207347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 207447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 207547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic errcode_t 207647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltadd_domain (config_t * conf, const char * domain) 207747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 207847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! contains_domain (conf, domain)) 207947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 208047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domain_entry_t * d = 208147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (domain_entry_t *) malloc (sizeof (domain_entry_t)); 208247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! d) 208347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 208447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_ERR, 208547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Can't allocate memory in nss_mdns:init_config, %s:%d", 208647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt __FILE__, __LINE__ 208747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 208847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return ENOMEM; 208947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 209047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 209147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt d->domain = strdup (domain); 209247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (! d->domain) 209347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 209447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog (LOG_ERR, 209547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "mdns: Can't allocate memory in nss_mdns:init_config, %s:%d", 209647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt __FILE__, __LINE__ 209747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 209847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt free (d); 209947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return ENOMEM; 210047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 210147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt d->next = conf->domains; 210247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt conf->domains = d; 210347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 210447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 210547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 0; 210647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 210747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 210847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 210947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 211047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcontains_domain (const config_t * conf, const char * domain) 211147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 211247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const domain_entry_t * curr = conf->domains; 211347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 211447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (curr != NULL) 211547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 211647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (strcasecmp (curr->domain, domain) == 0) 211747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 211847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 1; 211947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 212047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 212147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt curr = curr->next; 212247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 212347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 212447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 0; 212547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 212647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 212747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 212847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 212947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcontains_domain_suffix (const config_t * conf, const char * addr) 213047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 213147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const domain_entry_t * curr = conf->domains; 213247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 213347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (curr != NULL) 213447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 213547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (cmp_dns_suffix (addr, curr->domain) > 0) 213647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 213747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 1; 213847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 213947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 214047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt curr = curr->next; 214147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 214247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 214347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 0; 214447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 214547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 214647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 214747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Types and Constants 214847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 214947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const char * k_local_suffix = "local"; 215047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const char k_dns_separator = '.'; 215147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 215247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const int k_label_maxlen = DNS_LABEL_MAXLEN; 215347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Label entries longer than this are actually pointers. 215447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 215547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttypedef struct 215647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 215747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int value; 215847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * name; 215947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * comment; 216047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} table_entry_t; 216147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 216247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const table_entry_t k_table_af [] = 216347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 216447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { AF_UNSPEC, NULL, NULL }, 216547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { AF_LOCAL, "LOCAL", NULL }, 216647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { AF_UNIX, "UNIX", NULL }, 216747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { AF_INET, "INET", NULL }, 216847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { AF_INET6, "INET6", NULL } 216947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt }; 217047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const int k_table_af_size = 217147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt sizeof (k_table_af) / sizeof (* k_table_af); 217247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 217347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const char * k_table_ns_class [] = 217447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 217547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt NULL, 217647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "IN" 217747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt }; 217847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const int k_table_ns_class_size = 217947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt sizeof (k_table_ns_class) / sizeof (* k_table_ns_class); 218047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 218147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const char * k_table_ns_type [] = 218247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 218347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt NULL, 218447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "A", 218547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "NS", 218647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "MD", 218747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "MF", 218847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "CNAME", 218947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "SOA", 219047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "MB", 219147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "MG", 219247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "MR", 219347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "NULL", 219447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "WKS", 219547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "PTR", 219647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "HINFO", 219747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "MINFO", 219847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "MX", 219947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "TXT", 220047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "RP", 220147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "AFSDB", 220247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "X25", 220347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "ISDN", 220447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "RT", 220547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "NSAP", 220647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt NULL, 220747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "SIG", 220847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "KEY", 220947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "PX", 221047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "GPOS", 221147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "AAAA", 221247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "LOC", 221347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "NXT", 221447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "EID", 221547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "NIMLOC", 221647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "SRV", 221747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "ATMA", 221847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "NAPTR", 221947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "KX", 222047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "CERT", 222147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "A6", 222247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "DNAME", 222347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "SINK", 222447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt "OPT" 222547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt }; 222647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic const int k_table_ns_type_size = 222747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt sizeof (k_table_ns_type) / sizeof (* k_table_ns_type); 222847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 222947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 223047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 223147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Local prototypes 223247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 223347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 223447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltsimple_table_index (const char * table [], int size, const char * str); 223547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 223647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 223747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttable_index_name (const table_entry_t table [], int size, const char * str); 223847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 223947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 224047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttable_index_value (const table_entry_t table [], int size, int n); 224147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 224247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 224347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 224447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Global variables 224547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 224647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 224747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 224847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Util functions 224947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 225047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 225147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcount_dots (const char * name) 225247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 225347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int count = 0; 225447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 225547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i = 0; name[i]; i++) 225647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 225747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (name [i] == k_dns_separator) 225847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt count++; 225947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 226047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 226147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return count; 226247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 226347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 226447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 226547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 226647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltislocal (const char * name) 226747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 226847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return cmp_dns_suffix (name, k_local_suffix) > 0; 226947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 227047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 227147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 227247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 227347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltrr_to_af (ns_type_t rrtype) 227447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 227547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt switch (rrtype) 227647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 227747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case kDNSServiceType_A: 227847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return AF_INET; 227947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 228047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case kDNSServiceType_AAAA: 228147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return AF_INET6; 228247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 228347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt default: 228447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return AF_UNSPEC; 228547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 228647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 228747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 228847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 228947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltns_type_t 229047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltaf_to_rr (int af) 229147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 229247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt switch (af) 229347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 229447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case AF_INET: 229547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return kDNSServiceType_A; 229647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 229747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case AF_INET6: 229847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return kDNSServiceType_AAAA; 229947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 230047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt default: 230147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt //return ns_t_invalid; 230247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 0; 230347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 230447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 230547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 230647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 230747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 230847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstr_to_af (const char * str) 230947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 231047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int result = 231147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt table_index_name (k_table_af, k_table_af_size, str); 231247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (result < 0) 231347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result = 0; 231447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 231547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return k_table_af [result].value; 231647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 231747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 231847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 231947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltns_class_t 232047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstr_to_ns_class (const char * str) 232147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 232247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return (ns_class_t) 232347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt simple_table_index (k_table_ns_class, k_table_ns_class_size, str); 232447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 232547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 232647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 232747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltns_type_t 232847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstr_to_ns_type (const char * str) 232947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 233047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return (ns_type_t) 233147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt simple_table_index (k_table_ns_type, k_table_ns_type_size, str); 233247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 233347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 233447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 233547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconst char * 233647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltaf_to_str (int in) 233747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 233847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int result = 233947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt table_index_value (k_table_af, k_table_af_size, in); 234047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (result < 0) 234147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt result = 0; 234247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 234347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return k_table_af [result].name; 234447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 234547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 234647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 234747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconst char * 234847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltns_class_to_str (ns_class_t in) 234947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 235047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (in < k_table_ns_class_size) 235147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return k_table_ns_class [in]; 235247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 235347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 235447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 235547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 235647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 235747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltconst char * 235847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltns_type_to_str (ns_type_t in) 235947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 236047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (in < k_table_ns_type_size) 236147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return k_table_ns_type [in]; 236247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 236347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 236447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 236547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 236647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 236747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltchar * 236847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltformat_reverse_addr_in ( 236947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const struct in_addr * addr, 237047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int prefixlen, 237147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * buf 237247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 237347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 237447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * curr = buf; 237547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 237647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 237747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const uint8_t * in_addr_a = (uint8_t *) addr; 237847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 237947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (prefixlen > 32) 238047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 238147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (prefixlen < 0) 238247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt prefixlen = 32; 238347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 238447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt i = (prefixlen + 7) / 8; 238547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // divide prefixlen into bytes, rounding up 238647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 238747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (i > 0) 238847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 238947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt i--; 239047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt curr += sprintf (curr, "%d.", in_addr_a [i]); 239147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 239247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt sprintf (curr, "in-addr.arpa"); 239347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 239447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return buf; 239547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 239647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 239747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 239847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltchar * 239947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltformat_reverse_addr_in6 ( 240047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const struct in6_addr * addr, 240147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int prefixlen, 240247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * buf 240347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 240447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 240547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * curr = buf; 240647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 240747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 240847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const uint8_t * in_addr_a = (uint8_t *) addr; 240947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 241047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (prefixlen > 128) 241147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 241247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (prefixlen < 0) 241347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt prefixlen = 128; 241447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 241547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt i = (prefixlen + 3) / 4; 241647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // divide prefixlen into nibbles, rounding up 241747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 241847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Special handling for first 241947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (i % 2) 242047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 242147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt curr += sprintf (curr, "%d.", (in_addr_a [i/2] >> 4) & 0x0F); 242247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 242347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt i >>= 1; 242447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Convert i to bytes (divide by 2) 242547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 242647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (i > 0) 242747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 242847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt uint8_t val; 242947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 243047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt i--; 243147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt val = in_addr_a [i]; 243247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt curr += sprintf (curr, "%x.%x.", val & 0x0F, (val >> 4) & 0x0F); 243347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 243447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt sprintf (curr, "ip6.arpa"); 243547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 243647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return buf; 243747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 243847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 243947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 244047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltchar * 244147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltformat_reverse_addr ( 244247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int af, 244347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const void * addr, 244447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int prefixlen, 244547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char * buf 244647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt) 244747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 244847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt switch (af) 244947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 245047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case AF_INET: 245147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 245247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt format_reverse_addr_in ( 245347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (struct in_addr *) addr, prefixlen, buf 245447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 245547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt break; 245647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 245747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case AF_INET6: 245847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 245947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt format_reverse_addr_in6 ( 246047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (struct in6_addr *) addr, prefixlen, buf 246147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ); 246247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt break; 246347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 246447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt default: 246547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return NULL; 246647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 246747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 246847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 246947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 247047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 247147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltcmp_dns_suffix (const char * name, const char * domain) 247247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 247347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * nametail; 247447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * domaintail; 247547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 247647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Idiot checks 247747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (*name == 0 || *name == k_dns_separator) 247847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 247947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Name can't be empty or start with separator 248047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return CMP_DNS_SUFFIX_BAD_NAME; 248147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 248247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 248347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (*domain == 0) 248447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 248547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return CMP_DNS_SUFFIX_SUCCESS; 248647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // trivially true 248747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 248847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 248947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (*domain == k_dns_separator) 249047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 249147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // drop leading separator from domain 249247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domain++; 249347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (*domain == k_dns_separator) 249447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 249547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return CMP_DNS_SUFFIX_BAD_DOMAIN; 249647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 249747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 249847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 249947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Find ends of strings 250047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (nametail = name; *nametail; nametail++) 250147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ; 250247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (domaintail = domain; *domaintail; domaintail++) 250347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ; 250447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 250547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Shuffle back to last real character, and drop any trailing '.' 250647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // while we're at it. 250747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt nametail --; 250847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (*nametail == k_dns_separator) 250947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 251047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt nametail --; 251147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (*nametail == k_dns_separator) 251247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 251347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return CMP_DNS_SUFFIX_BAD_NAME; 251447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 251547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 251647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domaintail --; 251747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (*domaintail == k_dns_separator) 251847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 251947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domaintail --; 252047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (*domaintail == k_dns_separator) 252147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 252247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return CMP_DNS_SUFFIX_BAD_DOMAIN; 252347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 252447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 252547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 252647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Compare. 252747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while ( 252847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt nametail >= name 252947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt && domaintail >= domain 253047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt && tolower(*nametail) == tolower(*domaintail)) 253147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 253247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt nametail--; 253347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domaintail--; 253447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 253547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 253647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt /* A successful finish will be one of the following: 253747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (leading and trailing . ignored) 253847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 253947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name : domain2.domain1 254047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domain: domain2.domain1 254147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ^ 254247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 254347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name : domain3.domain2.domain1 254447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domain: domain2.domain1 254547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ^ 254647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 254747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if ( 254847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt domaintail < domain 254947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt && (nametail < name || *nametail == k_dns_separator) 255047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ) 255147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 255247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return CMP_DNS_SUFFIX_SUCCESS; 255347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 255447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 255547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 255647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return CMP_DNS_SUFFIX_FAILURE; 255747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 255847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 255947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 256047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 256147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltint 256247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltdns_rdata_to_name (const char * rdata, int rdlen, char * name, int name_len) 256347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 256447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i = 0; 256547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // Index into 'name' 256647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt const char * rdata_curr = rdata; 256747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 256847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (rdlen == 0) return DNS_RDATA_TO_NAME_BAD_FORMAT; 256947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 257047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt /* 257147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt In RDATA, a DNS name is stored as a series of labels. 257247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Each label consists of a length octet (max value 63) 257347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt followed by the data for that label. 257447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt The series is terminated with a length 0 octet. 257547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt A length octet beginning with bits 11 is a pointer to 257647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt somewhere else in the payload, but we don't support these 257747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt since we don't have access to the entire payload. 257847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 257947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt See RFC1034 section 3.1 and RFC1035 section 3.1. 258047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 258147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (1) 258247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 258347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int term_len = *rdata_curr; 258447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rdata_curr++; 258547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 258647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (term_len == 0) 258747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 258847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt break; 258947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // 0 length record terminates label 259047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 259147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else if (term_len > k_label_maxlen) 259247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 259347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name [i] = 0; 259447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return DNS_RDATA_TO_NAME_PTR; 259547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 259647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else if (rdata_curr + term_len > rdata + rdlen) 259747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 259847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name [i] = 0; 259947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return DNS_RDATA_TO_NAME_BAD_FORMAT; 260047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 260147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 260247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (name_len < i + term_len + 1) 260347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // +1 is separator 260447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 260547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name [i] = 0; 260647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return DNS_RDATA_TO_NAME_TOO_LONG; 260747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 260847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 260947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt memcpy (name + i, rdata_curr, term_len); 261047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 261147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt i += term_len; 261247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt rdata_curr += term_len; 261347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 261447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name [i] = k_dns_separator; 261547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt i++; 261647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 261747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 261847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt name [i] = 0; 261947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return i; 262047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 262147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 262247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 262347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt//---------- 262447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Local functions 262547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 262647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 262747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Find the index of an string entry in a table. A case insenitive match 262847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt is performed. If no entry is found, 0 is returned. 262947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 263047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 263147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt table 263247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Lookup table 263347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Table entries may be NULL. NULL entries will never match. 263447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size 263547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt number of entries in table 263647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt str 263747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt lookup string 263847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 263947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Result 264047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt index of first matching entry, or 0 if no matches 264147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 264247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 264347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltsimple_table_index (const char * table [], int size, const char * str) 264447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 264547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 264647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i = 0; i < size; i++) 264747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 264847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if ( 264947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt table [i] 265047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt && (strcasecmp (table [i], str) == 0) 265147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ) 265247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 265347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return i; 265447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 265547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 265647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 265747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return 0; 265847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 265947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 266047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 266147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 266247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Find the index of a name in a table. 266347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 266447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 266547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt table 266647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt array of table_entry_t records. The name field is compared 266747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt (ignoring case) to the input string. 266847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size 266947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt number of entries in table 267047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt str 267147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt lookup string 267247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 267347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Result 267447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt index of first matching entry, or -1 if no matches 267547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 267647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 267747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttable_index_name (const table_entry_t table [], int size, const char * str) 267847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 267947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 268047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i = 0; i < size; i++) 268147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 268247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if ( 268347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt table [i].name 268447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt && (strcasecmp (table [i].name, str) == 0) 268547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt ) 268647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 268747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return i; 268847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 268947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 269047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 269147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return -1; 269247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 269347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 269447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 269547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* 269647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Find the index of a value a table. 269747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 269847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Parameters 269947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt table 270047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt array of table_entry_t records. The value field is compared to 270147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt the input value 270247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt size 270347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt number of entries in table 270447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt n 270547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt lookup value 270647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 270747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt Result 270847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt index of first matching entry, or -1 if no matches 270947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 271047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic int 271147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalttable_index_value (const table_entry_t table [], int size, int n) 271247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{ 271347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int i; 271447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt for (i = 0; i < size; i++) 271547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 271647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (table [i].value == n) 271747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 271847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return i; 271947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 272047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 272147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 272247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return -1; 272347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt} 2724