1: /* 2: * Copyright (c) 1986 Regents of the University of California. 3: * All rights reserved. 4: * 5: * Redistribution and use in source and binary forms are permitted 6: * provided that this notice is preserved and that due credit is given 7: * to the University of California at Berkeley. The name of the University 8: * may not be used to endorse or promote products derived from this 9: * software without specific prior written permission. This software 10: * is provided ``as is'' without express or implied warranty. 11: */ 12: 13: #ifndef lint 14: static char sccsid[] = "@(#)ns_sort.c 4.3 (Berkeley) 2/17/88"; 15: #endif /* not lint */ 16: 17: #include <stdio.h> 18: #include <sys/types.h> 19: #include <sys/time.h> 20: #include <sys/socket.h> 21: #include <sys/file.h> 22: #include <netinet/in.h> 23: #include <syslog.h> 24: #include <arpa/nameser.h> 25: #include "ns.h" 26: #include "db.h" 27: 28: extern char *p_type(), *p_class(); 29: 30: extern int debug; 31: extern FILE *ddt; 32: 33: struct netinfo* 34: local(from) 35: struct sockaddr_in *from; 36: { 37: extern struct netinfo *nettab, netloop; 38: struct netinfo *ntp; 39: 40: if (from->sin_addr.s_addr == netloop.my_addr.s_addr) 41: return( &netloop); 42: for (ntp = nettab; ntp != NULL; ntp = ntp->next) { 43: if (ntp->net == (from->sin_addr.s_addr & ntp->mask)) 44: return(ntp); 45: } 46: return(NULL); 47: } 48: 49: 50: sort_response(cp, ancount, lp, eom) 51: register char *cp; 52: register int ancount; 53: struct netinfo *lp; 54: u_char *eom; 55: { 56: register struct netinfo *ntp; 57: extern struct netinfo *nettab; 58: 59: #ifdef DEBUG 60: if (debug > 2) 61: fprintf(ddt,"sort_response(%d)\n", ancount); 62: #endif DEBUG 63: if (ancount > 1) { 64: if (sort_rr(cp, ancount, lp, eom)) 65: return; 66: for (ntp = nettab; ntp != NULL; ntp = ntp->next) { 67: if ((ntp->net == lp->net) && (ntp->mask == lp->mask)) 68: continue; 69: if (sort_rr(cp, ancount, ntp, eom)) 70: break; 71: } 72: } 73: } 74: 75: int 76: sort_rr(cp, count, ntp, eom) 77: register u_char *cp; 78: int count; 79: register struct netinfo *ntp; 80: u_char *eom; 81: { 82: int type, class, dlen, n, c; 83: struct in_addr inaddr; 84: u_char *rr1; 85: 86: #ifdef DEBUG 87: if (debug > 2) { 88: inaddr.s_addr = ntp->net; 89: fprintf(ddt,"sort_rr( x%x, %d, %s)\n",cp, count, 90: inet_ntoa(inaddr)); 91: } 92: #endif DEBUG 93: rr1 = NULL; 94: for (c = count; c > 0; --c) { 95: n = dn_skipname(cp, eom); 96: if (n < 0) 97: return (1); /* bogus, stop processing */ 98: cp += n; 99: if (cp + QFIXEDSZ > eom) 100: return (1); 101: GETSHORT(type, cp); 102: GETSHORT(class, cp); 103: cp += sizeof(u_long); 104: GETSHORT(dlen, cp); 105: if (dlen > eom - cp) 106: return (1); /* bogus, stop processing */ 107: switch (type) { 108: case T_A: 109: switch (class) { 110: case C_IN: 111: bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 112: if (rr1 == NULL) 113: rr1 = cp; 114: if ((ntp->mask & inaddr.s_addr) == ntp->net) { 115: #ifdef DEBUG 116: if (debug > 1) { 117: fprintf(ddt,"net %s best choice\n", 118: inet_ntoa(inaddr)); 119: } 120: #endif DEBUG 121: if (rr1 != cp) { 122: bcopy(rr1, cp, sizeof(inaddr)); 123: bcopy((char *)&inaddr, rr1, sizeof(inaddr)); 124: } 125: return(1); 126: } 127: break; 128: } 129: break; 130: } 131: cp += dlen; 132: } 133: return(0); 134: } 135: 136: #ifdef notdef 137: dump_namebuf(np) 138: register struct namebuf *np; 139: { 140: register struct databuf *dp; 141: long n; 142: u_long addr; 143: u_short i; 144: int j; 145: char *cp; 146: char *proto; 147: FILE *fp; 148: extern char *inet_ntoa(), *p_protocal(), *p_service(); 149: int found_data; 150: 151: gettime(&tt); 152: if ((fp = fopen("/usr/tmp/namebuf", "a")) == NULL) 153: return; 154: found_data = 0; 155: for (dp = np->n_data; dp != NULL; dp = dp->d_next) { 156: if (dp->d_ttl <= tt.tv_sec) 157: continue; /* Stale */ 158: if (!found_data) { 159: fprintf(fp, "%s\t", np->n_dname); 160: if (strlen(np->n_dname) < 8) 161: (void) putc('\t', fp); 162: found_data++; 163: } else 164: fprintf(fp, "\t\t"); 165: if (dp->d_zone == 0) 166: fprintf(fp, "%ld\t", dp->d_ttl - tt.tv_sec); 167: else if (dp->d_ttl > zones[dp->d_zone].z_minimum) 168: fprintf(fp, "%ld\t", dp->d_ttl); 169: fprintf(fp, "%s\t%s\t", p_class(dp->d_class), 170: p_type(dp->d_type)); 171: cp = dp->d_data; 172: /* 173: * Print type specific data 174: */ 175: switch (dp->d_type) { 176: case T_A: 177: switch (dp->d_class) { 178: case C_IN: 179: n = htonl(_getlong(cp)); 180: fprintf(fp, "%s\n", 181: inet_ntoa(*(struct in_addr *)&n)); 182: break; 183: } 184: break; 185: case T_CNAME: 186: case T_MB: 187: case T_MG: 188: case T_MR: 189: case T_PTR: 190: if (cp[0] == '\0') 191: fprintf(fp, ".\n"); 192: else 193: fprintf(fp, "%s.\n", cp); 194: break; 195: 196: case T_NS: 197: cp = dp->d_data; 198: if (cp[0] == '\0') 199: fprintf(fp, ".\t"); 200: else 201: fprintf(fp, "%s.", cp); 202: if (dp->d_nstime) 203: fprintf(fp, "\t; %ld", dp->d_nstime); 204: fprintf(fp, "\n"); 205: break; 206: 207: case T_HINFO: 208: if (n = *cp++) { 209: fprintf(fp, "\"%.*s\"", n, cp); 210: cp += n; 211: } else 212: fprintf(fp, "\"\""); 213: if (n = *cp++) 214: fprintf(fp, " \"%.*s\"", n, cp); 215: else 216: fprintf(fp, "\"\""); 217: (void) putc('\n', fp); 218: break; 219: 220: case T_SOA: 221: fprintf(fp, "%s.", cp); 222: cp += strlen(cp) + 1; 223: fprintf(fp, " %s. (\n", cp); 224: cp += strlen(cp) + 1; 225: fprintf(fp, "\t\t%ld", _getlong(cp)); 226: cp += sizeof(u_long); 227: fprintf(fp, " %ld", _getlong(cp)); 228: cp += sizeof(u_long); 229: fprintf(fp, " %ld", _getlong(cp)); 230: cp += sizeof(u_long); 231: fprintf(fp, " %ld", _getlong(cp)); 232: cp += sizeof(u_long); 233: fprintf(fp, " %ld )\n", _getlong(cp)); 234: break; 235: 236: case T_MX: 237: fprintf(fp,"%d", _getshort(cp)); 238: cp += sizeof(u_short); 239: fprintf(fp," %s.\n", cp); 240: break; 241: 242: 243: case T_UINFO: 244: fprintf(fp, "\"%s\"\n", cp); 245: break; 246: 247: case T_UID: 248: case T_GID: 249: if (dp->d_size == sizeof(u_long)) { 250: fprintf(fp, "%ld\n", _getlong(cp)); 251: cp += sizeof(u_long); 252: } 253: break; 254: 255: case T_WKS: 256: addr = htonl(_getlong(cp)); 257: fprintf(fp,"%s ", 258: inet_ntoa(*(struct in_addr *)&addr)); 259: cp += sizeof(u_long); 260: proto = p_protocal(*cp); /* protocal */ 261: cp += sizeof(char); 262: fprintf(fp, "%s ", proto); 263: i = 0; 264: while(cp < dp->d_data + dp->d_size) { 265: j = *cp++; 266: do { 267: if(j & 0200) 268: fprintf(fp," %s", 269: p_service(i, proto)); 270: j <<= 1; 271: } while(++i & 07); 272: } 273: fprintf(fp,"\n"); 274: break; 275: 276: default: 277: fprintf(fp, "???\n"); 278: } 279: } 280: (void) fclose(fp); 281: } 282: #endif notdef