xref: /386bsd/usr/src/usr.sbin/named/ns_sort.c (revision a2142627)
1 /*
2  * Copyright (c) 1986, 1990 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #ifndef lint
35 static char sccsid[] = "@(#)ns_sort.c	4.10 (Berkeley) 3/3/91";
36 #endif /* not lint */
37 
38 #include <stdio.h>
39 #include <sys/types.h>
40 #include <sys/time.h>
41 #include <sys/socket.h>
42 #include <sys/file.h>
43 #include <netinet/in.h>
44 #include <syslog.h>
45 #include <arpa/nameser.h>
46 #include <resolv.h>
47 #include "ns.h"
48 #include "db.h"
49 
50 extern	int	debug;
51 extern  FILE	*ddt;
52 
53 struct netinfo*
local(from)54 local(from)
55 	struct sockaddr_in *from;
56 {
57 	extern struct netinfo *nettab, netloop, **enettab;
58 	struct netinfo *ntp;
59 
60 	if (from->sin_addr.s_addr == netloop.my_addr.s_addr)
61 		return( &netloop);
62 	for (ntp = nettab; ntp != *enettab; ntp = ntp->next) {
63 		if (ntp->net == (from->sin_addr.s_addr & ntp->mask))
64 			return(ntp);
65 	}
66 	return(NULL);
67 }
68 
69 
sort_response(cp,ancount,lp,eom)70 sort_response(cp, ancount, lp, eom)
71 	register char *cp;
72 	register int ancount;
73 	struct netinfo *lp;
74 	u_char *eom;
75 {
76 	register struct netinfo *ntp;
77 	extern struct netinfo *nettab;
78 
79 #ifdef DEBUG
80 	if (debug > 2)
81 	    fprintf(ddt,"sort_response(%d)\n", ancount);
82 #endif DEBUG
83 	if (ancount > 1) {
84 		if (sort_rr(cp, ancount, lp, eom))
85 			return;
86 		for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
87 			if ((ntp->net == lp->net) && (ntp->mask == lp->mask))
88 				continue;
89 			if (sort_rr(cp, ancount, ntp, eom))
90 				break;
91 		}
92 	}
93 }
94 
95 int
sort_rr(cp,count,ntp,eom)96 sort_rr(cp, count, ntp, eom)
97 	register u_char *cp;
98 	int count;
99 	register struct netinfo *ntp;
100 	u_char *eom;
101 {
102 	int type, class, dlen, n, c;
103 	struct in_addr inaddr;
104 	u_char *rr1;
105 
106 #ifdef DEBUG
107 	if (debug > 2) {
108 	    inaddr.s_addr = ntp->net;
109 	    fprintf(ddt,"sort_rr( x%x, %d, %s)\n",cp, count,
110 		inet_ntoa(inaddr));
111 	}
112 #endif DEBUG
113 	rr1 = NULL;
114 	for (c = count; c > 0; --c) {
115 	    n = dn_skipname(cp, eom);
116 	    if (n < 0)
117 		return (1);		/* bogus, stop processing */
118 	    cp += n;
119 	    if (cp + QFIXEDSZ > eom)
120 		return (1);
121 	    GETSHORT(type, cp);
122 	    GETSHORT(class, cp);
123 	    cp += sizeof(u_long);
124 	    GETSHORT(dlen, cp);
125 	    if (dlen > eom - cp)
126 		return (1);		/* bogus, stop processing */
127 	    switch (type) {
128 	    case T_A:
129 	    	switch (class) {
130 	    	case C_IN:
131 	    	case C_HS:
132 	    		bcopy(cp, (char *)&inaddr, sizeof(inaddr));
133 			if (rr1 == NULL)
134 				rr1 = cp;
135 			if ((ntp->mask & inaddr.s_addr) == ntp->net) {
136 #ifdef DEBUG
137 			    if (debug > 1) {
138 	    			fprintf(ddt,"net %s best choice\n",
139 					inet_ntoa(inaddr));
140 			    }
141 #endif DEBUG
142 			    if (rr1 != cp) {
143 	    		        bcopy(rr1, cp, sizeof(inaddr));
144 	    		        bcopy((char *)&inaddr, rr1, sizeof(inaddr));
145 			    }
146 			    return(1);
147 			}
148 	    		break;
149 	    	}
150 	    	break;
151 	    }
152 	    cp += dlen;
153 	}
154 	return(0);
155 }
156